TYPO3 v15 dev-main snapshot ()

This commit is contained in:
2026-08-10 22:31:39 +02:00
commit e54ab24745
68 changed files with 3683 additions and 0 deletions
@@ -0,0 +1,9 @@
<?php
declare(strict_types=1);
return [
'seo' => [
'title' => 'LLL:EXT:seo/Resources/Private/Language/locallang_dashboard.xlf:widget.group.seo',
],
];
+38
View File
@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace TYPO3\CMS\Seo;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symfony\Component\DependencyInjection\Reference;
use TYPO3\CMS\Backend\View\BackendViewFactory;
use TYPO3\CMS\Dashboard\WidgetRegistry;
use TYPO3\CMS\Seo\Widgets\PagesWithoutDescriptionWidget;
use TYPO3\CMS\Seo\Widgets\Provider\PagesWithoutDescriptionDataProvider;
return function (ContainerConfigurator $configurator, ContainerBuilder $containerBuilder) {
$services = $configurator->services();
/**
* Check if WidgetRegistry is defined, which means that EXT:dashboard is available.
* Registration directly in Services.yaml will break without EXT:dashboard installed!
*/
if ($containerBuilder->hasDefinition(WidgetRegistry::class)) {
$services->set('dashboard.widget.pagesWithoutMetaDescription')
->class(PagesWithoutDescriptionWidget::class)
->arg('$dataProvider', new Reference(PagesWithoutDescriptionDataProvider::class))
->arg('$backendViewFactory', new Reference(BackendViewFactory::class))
->arg('$options', ['refreshAvailable' => true])
->tag('dashboard.widget', [
'identifier' => 'seo-pagesWithoutMetaDescription',
'groupNames' => 'seo',
'title' => 'LLL:EXT:seo/Resources/Private/Language/locallang_dashboard.xlf:widget.pagesWithoutMetaDescription.title',
'description' => 'LLL:EXT:seo/Resources/Private/Language/locallang_dashboard.xlf:widget.pagesWithoutMetaDescription.description',
'iconIdentifier' => 'content-widget-list',
'height' => 'large',
'width' => 'medium',
]);
}
};
+13
View File
@@ -0,0 +1,13 @@
services:
_defaults:
autowire: true
autoconfigure: true
public: false
TYPO3\CMS\Seo\:
resource: '../Classes/*'
TYPO3\CMS\Seo\Widgets\Provider\PagesWithoutDescriptionDataProvider:
arguments:
$excludedDoktypes: [ 3, 4, 6, 7, 199, 254 ]
$limit: 8
+1
View File
@@ -0,0 +1 @@
name: typo3/seo-sitemap
+35
View File
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="EXT:seo/Configuration/Sets/Sitemap/labels.xlf" date="2018-09-04T12:30:00Z" product-name="seo">
<header/>
<body>
<trans-unit id="label">
<source>SEO Sitemap</source>
</trans-unit>
<trans-unit id="categories.seo">
<source>SEO Sitemap</source>
</trans-unit>
<trans-unit id="categories.seo.templates">
<source>Template Paths</source>
</trans-unit>
<trans-unit id="settings.seo.sitemap.view.templateRootPath">
<source>Path to template root (FE)</source>
</trans-unit>
<trans-unit id="settings.seo.sitemap.view.partialRootPath">
<source>Path to template partials (FE)</source>
</trans-unit>
<trans-unit id="settings.seo.sitemap.view.layoutRootPath">
<source>Path to template layouts (FE)</source>
</trans-unit>
<trans-unit id="settings.seo.sitemap.pages.excludedDoktypes">
<source>Doktypes to exclude</source>
</trans-unit>
<trans-unit id="settings.seo.sitemap.pages.excludePagesRecursive">
<source>List of page uids which should be excluded recursive</source>
</trans-unit>
<trans-unit id="settings.seo.sitemap.pages.additionalWhere">
<source>Additional where clause</source>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,15 @@
routeEnhancers:
PageTypeSuffix:
type: PageType
map:
sitemap.xml: 1533906435
Sitemap:
type: Simple
routePath: 'sitemap-type/{sitemap}'
aspects:
sitemap:
type: StaticValueMapper
map:
pages: pages
_arguments:
sitemap: 'tx_seo/sitemap'
@@ -0,0 +1,30 @@
categories:
seo: ~
seo.templates:
parent: seo
settings:
seo.sitemap.view.templateRootPath:
default: 'EXT:seo/Resources/Private/Templates/'
type: string
category: seo.templates
seo.sitemap.view.partialRootPath:
default: 'EXT:seo/Resources/Private/Partials/'
type: string
category: seo.templates
seo.sitemap.view.layoutRootPath:
default: 'EXT:seo/Resources/Private/Layouts/'
type: string
category: seo.templates
seo.sitemap.pages.excludedDoktypes:
default: '3, 4, 6, 7, 199, 254'
type: string
category: seo
seo.sitemap.pages.excludePagesRecursive:
default: ''
type: string
category: seo
seo.sitemap.pages.additionalWhere:
default: "{#no_index} = 0 AND {#canonical_link} = ''"
type: string
category: seo
@@ -0,0 +1 @@
@import 'EXT:seo/Configuration/TypoScript/XmlSitemap/setup.typoscript'
+270
View File
@@ -0,0 +1,270 @@
<?php
defined('TYPO3') or die();
$openGraphCropConfiguration = [
'config' => [
'cropVariants' => [
'default' => [
'disabled' => true,
],
'social' => [
'title' => 'core.wizards:imwizard.crop_variant.social',
'coverAreas' => [],
'cropArea' => [
'x' => '0.0',
'y' => '0.0',
'width' => '1.0',
'height' => '1.0',
],
'allowedAspectRatios' => [
'1.91:1' => [
'title' => 'core.wizards:imwizard.ratio.191_1',
'value' => 1200 / 630,
],
'NaN' => [
'title' => 'core.wizards:imwizard.ratio.free',
'value' => 0.0,
],
],
'selectedRatio' => '1.91:1',
],
],
],
];
$tca = [
'palettes' => [
'seo' => [
'label' => 'core.form.palettes:seo',
'showitem' => 'seo_title',
],
'robots' => [
'label' => 'core.form.palettes:robots',
'showitem' => 'no_index, no_follow',
],
'canonical' => [
'label' => 'core.form.palettes:canonical',
'showitem' => 'canonical_link',
],
'sitemap' => [
'label' => 'core.form.palettes:sitemap',
'showitem' => 'sitemap_changefreq, sitemap_priority',
],
'opengraph' => [
'label' => 'core.form.palettes:opengraph',
'showitem' => 'og_title, --linebreak--, og_description, --linebreak--, og_image',
],
'twittercards' => [
'label' => 'core.form.palettes:twittercards',
'showitem' => 'twitter_title, --linebreak--, twitter_description, --linebreak--, twitter_image, --linebreak--, twitter_card',
],
],
'columns' => [
'seo_title' => [
'exclude' => true,
'l10n_mode' => 'prefixLangTitle',
'label' => 'seo.db:pages.seo_title',
'config' => [
'type' => 'input',
'size' => 40,
'max' => 255,
'eval' => 'trim',
],
],
'no_index' => [
'exclude' => true,
'l10n_mode' => 'exclude',
'onChange' => 'reload',
'label' => 'seo.db:pages.no_index_formlabel',
'config' => [
'type' => 'check',
'renderType' => 'checkboxToggle',
'items' => [
[
'label' => '',
'invertStateDisplay' => true,
],
],
],
],
'no_follow' => [
'exclude' => true,
'l10n_mode' => 'exclude',
'label' => 'seo.db:pages.no_follow_formlabel',
'config' => [
'type' => 'check',
'renderType' => 'checkboxToggle',
'items' => [
[
'label' => '',
'invertStateDisplay' => true,
],
],
],
],
'sitemap_changefreq' => [
'exclude' => true,
'label' => 'seo.db:pages.sitemap_changefreq',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'items' => [
['label' => 'seo.db:pages.sitemap_changefreq.none', 'value' => ''],
['label' => 'seo.db:pages.sitemap_changefreq.always', 'value' => 'always'],
['label' => 'seo.db:pages.sitemap_changefreq.hourly', 'value' => 'hourly'],
['label' => 'seo.db:pages.sitemap_changefreq.daily', 'value' => 'daily'],
['label' => 'seo.db:pages.sitemap_changefreq.weekly', 'value' => 'weekly'],
['label' => 'seo.db:pages.sitemap_changefreq.monthly', 'value' => 'monthly'],
['label' => 'seo.db:pages.sitemap_changefreq.yearly', 'value' => 'yearly'],
['label' => 'seo.db:pages.sitemap_changefreq.never', 'value' => 'never'],
],
'dbFieldLength' => 10,
],
],
'sitemap_priority' => [
'exclude' => true,
'label' => 'seo.db:pages.sitemap_priority',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'default' => '0.5',
'items' => [
['label' => '0.0', 'value' => '0.0'],
['label' => '0.1', 'value' => '0.1'],
['label' => '0.2', 'value' => '0.2'],
['label' => '0.3', 'value' => '0.3'],
['label' => '0.4', 'value' => '0.4'],
['label' => '0.5', 'value' => '0.5'],
['label' => '0.6', 'value' => '0.6'],
['label' => '0.7', 'value' => '0.7'],
['label' => '0.8', 'value' => '0.8'],
['label' => '0.9', 'value' => '0.9'],
['label' => '1.0', 'value' => '1.0'],
],
],
],
'canonical_link' => [
'exclude' => true,
'label' => 'seo.db:pages.canonical_link',
'description' => 'seo.db:pages.canonical_link.description',
'displayCond' => 'FIELD:no_index:=:0',
'config' => [
'type' => 'link',
'allowedTypes' => ['page', 'url', 'record'],
'size' => 50,
'appearance' => [
'browserTitle' => 'seo.db:pages.canonical_link',
'allowedOptions' => ['params'],
],
],
],
'og_title' => [
'exclude' => true,
'l10n_mode' => 'prefixLangTitle',
'label' => 'seo.db:pages.og_title',
'config' => [
'type' => 'input',
'size' => 40,
'max' => 255,
'eval' => 'trim',
],
],
'og_description' => [
'exclude' => true,
'l10n_mode' => 'prefixLangTitle',
'label' => 'seo.db:pages.og_description',
'config' => [
'type' => 'text',
'cols' => 40,
'rows' => 3,
],
],
'og_image' => [
'exclude' => true,
'label' => 'seo.db:pages.og_image',
'config' => [
'type' => 'file',
'allowed' => 'common-image-types',
'behaviour' => [
'allowLanguageSynchronization' => true,
],
'overrideChildTca' => [
'columns' => [
'crop' => $openGraphCropConfiguration,
],
],
],
],
'twitter_title' => [
'exclude' => true,
'l10n_mode' => 'prefixLangTitle',
'label' => 'seo.db:pages.twitter_title',
'config' => [
'type' => 'input',
'size' => 40,
'max' => 255,
'eval' => 'trim',
],
],
'twitter_description' => [
'exclude' => true,
'l10n_mode' => 'prefixLangTitle',
'label' => 'seo.db:pages.twitter_description',
'config' => [
'type' => 'text',
'cols' => 40,
'rows' => 3,
],
],
'twitter_image' => [
'exclude' => true,
'label' => 'seo.db:pages.twitter_image',
'config' => [
'type' => 'file',
'allowed' => 'common-image-types',
'behaviour' => [
'allowLanguageSynchronization' => true,
],
'overrideChildTca' => [
'columns' => [
'crop' => $openGraphCropConfiguration,
],
],
],
],
'twitter_card' => [
'exclude' => true,
'label' => 'seo.db:pages.twitter_card',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'default' => '',
'items' => [
['label' => '', 'value' => ''],
['label' => 'seo.db:pages.twitter_card.summary', 'value' => 'summary'],
['label' => 'seo.db:pages.twitter_card.summary_large_image', 'value' => 'summary_large_image'],
],
'dbFieldLength' => 255,
],
],
],
];
$GLOBALS['TCA']['pages'] = array_replace_recursive($GLOBALS['TCA']['pages'], $tca);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes(
'pages',
'
--div--;core.form.tabs:seo,
--palette--;;seo,
--palette--;;robots,
--palette--;;canonical,
--palette--;;sitemap,
--div--;core.form.tabs:socialmedia,
--palette--;;opengraph,
--palette--;;twittercards',
(string)\TYPO3\CMS\Core\Domain\Repository\PageRepository::DOKTYPE_DEFAULT,
'after:title'
);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addFieldsToPalette('pages', 'seo', '--linebreak--, description', 'after:seo_title');
@@ -0,0 +1,9 @@
<?php
defined('TYPO3') or die();
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile(
'seo',
'Configuration/TypoScript/XmlSitemap',
'XML Sitemap'
);
@@ -0,0 +1,27 @@
# customsubcategory=sitemap=XML Sitemap
plugin.tx_seo {
view {
# cat=plugin.tx_seo/file; type=string; label=Path to template root (FE)
templateRootPath = EXT:seo/Resources/Private/Templates/
# cat=plugin.tx_seo/file; type=string; label=Path to template partials (FE)
partialRootPath = EXT:seo/Resources/Private/Partials/
# cat=plugin.tx_seo/file; type=string; label=Path to template layouts (FE)
layoutRootPath = EXT:seo/Resources/Private/Layouts/
}
settings {
xmlSitemap {
sitemaps {
pages {
# cat=plugin.tx_seo/sitemap; type=string; label=Doktypes to exclude
excludedDoktypes = 3, 4, 6, 7, 199, 254
# cat=plugin.tx_seo/sitemap; type=string; label=List of page uids which should be excluded recursive
excludePagesRecursive =
# cat=plugin.tx_seo/sitemap; type=string; label=Additional where clause
additionalWhere = {#no_index} = 0 AND {#canonical_link} = ''
}
}
}
}
}
@@ -0,0 +1,60 @@
seo_sitemap = PAGE
seo_sitemap {
typeNum = 1533906435
config {
cache_period = 900
disableAllHeaderCode = 1
admPanel = 0
removeDefaultJS = 1
removeDefaultCss = 1
additionalHeaders {
10.header = Content-Type:application/xml;charset=utf-8
20.header = X-Robots-Tag:noindex
}
# Prevent sitemap.xml from appearing in the search results of EXT:indexed_search
index_enable = 0
}
10 = USER
10.userFunc = TYPO3\CMS\Seo\XmlSitemap\XmlSitemapRenderer->render
}
plugin.tx_seo {
view {
templateRootPaths {
0 = EXT:seo/Resources/Private/Templates/XmlSitemap
10 = {$plugin.tx_seo.view.templateRootPath ?? $seo.sitemap.view.templateRootPath}
}
partialRootPaths {
0 = EXT:seo/Resources/Private/Partials/XmlSitemap
10 = {$plugin.tx_seo.view.partialRootPath ?? $seo.sitemap.view.partialRootPath}
}
layoutRootPaths {
0 = EXT:seo/Resources/Private/Layouts/XmlSitemap
10 = {$plugin.tx_seo.view.layoutRootPath ?? $seo.sitemap.view.layoutRootPath}
}
}
config {
# Here you can override the xslFile for all sitemaps
# xslFile = EXT:seo/Resources/Public/CSS/Sitemap.xsl
xmlSitemap {
sitemaps {
# Here you can override the xslFile for all sitemaps of a certain sitemapType
# xslFile = EXT:seo/Resources/Public/CSS/Sitemap.xsl
pages {
provider = TYPO3\CMS\Seo\XmlSitemap\PagesXmlSitemapDataProvider
config {
# Here you can override the xslFile for a single sitemap
# xslFile = EXT:seo/Resources/Public/CSS/Sitemap.xsl
excludedDoktypes = {$plugin.tx_seo.settings.xmlSitemap.sitemaps.pages.excludedDoktypes ?? $seo.sitemap.pages.excludedDoktypes}
# comma-separated list of page uids which should be excluded recursive
excludePagesRecursive = {$plugin.tx_seo.settings.xmlSitemap.sitemaps.pages.excludePagesRecursive ?? $seo.sitemap.pages.excludePagesRecursive}
additionalWhere = {$plugin.tx_seo.settings.xmlSitemap.sitemaps.pages.additionalWhere ?? $seo.sitemap.pages.additionalWhere}
}
}
}
}
}
}
+10
View File
@@ -0,0 +1,10 @@
mod.web_info.fieldDefinitions {
seo {
label = LLL:EXT:seo/Resources/Private/Language/locallang_webinfo.xlf:seo
fields = title,uid,slug,seo_title,description,no_index,no_follow,canonical_link,sitemap_changefreq,sitemap_priority
}
social_media {
label = LLL:EXT:seo/Resources/Private/Language/locallang_webinfo.xlf:social_media
fields = title,uid,og_title,og_description,twitter_title,twitter_description
}
}