feat: ep_products plugins are content element types of their own
Preparation for TYPO3 14, which drops list_type. The plugins are registered as CTypes named like their former list_type values (epproducts_product_detail etc.); the form keeps the fields of the "list" type, with the plugin options in place of the plugin selector. As content element types they show the E&P logo of the extension manager (icon ep-products-plugin) instead of the generic plugin icon. The upgrade wizard epProductsPluginListTypeToCType moves the elements and the tt_content:list_type permissions of backend groups. Until it has run, list_type elements render through the new types (alias block in ext_localconf.php), so the deploy alone changes nothing. Retired plugins stay "list" elements. The content-only page type, the content manifest and the two container columns limited to "list" now treat the epproducts_* types as plugins. Crawl of 1,912 URLs identical for old code and new code before and after the wizard; rehearsed again on the prod dump of 2026-11-01 (1,924 URLs, API snapshot identical). Rollout and rollback SQL: .ddev/plans/PLUGINS-CTYPE-ROLLOUT.md. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
518f29b160
commit
81a8013e8a
7 files changed
+238
-160
No files matched your search
@@ -254,7 +254,7 @@ class ManifestBuilder
|
||||
'pid',
|
||||
'sys_language_uid',
|
||||
'MAX(tstamp) AS tstamp',
|
||||
"SUM(CASE WHEN deleted = 0 AND hidden = 0 AND CType <> 'list' THEN 1 ELSE 0 END) AS text_elements"
|
||||
"SUM(CASE WHEN deleted = 0 AND hidden = 0 AND CType <> 'list' AND CType NOT LIKE 'epproducts\\_%' THEN 1 ELSE 0 END) AS text_elements"
|
||||
)
|
||||
->from('tt_content')->groupBy('pid', 'sys_language_uid')->executeQuery()
|
||||
->fetchAllAssociative()
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace EP\EpProducts\Upgrades;
|
||||
|
||||
use TYPO3\CMS\Install\Attribute\UpgradeWizard;
|
||||
use TYPO3\CMS\Install\Updates\AbstractListTypeToCTypeUpdate;
|
||||
|
||||
/**
|
||||
* Turns the ep_products plugin elements (CType "list") into content elements of their own type, as TYPO3 14
|
||||
* no longer knows list_type. The types keep the plugin signatures as names. Also rewrites the
|
||||
* tt_content:list_type permissions of backend groups. Retired plugins stay "list" elements.
|
||||
*/
|
||||
#[UpgradeWizard('epProductsPluginListTypeToCType')]
|
||||
final class PluginListTypeToCTypeUpdate extends AbstractListTypeToCTypeUpdate
|
||||
{
|
||||
private const array PLUGINS = [
|
||||
'epproducts_searchresult',
|
||||
'epproducts_travelinfo',
|
||||
'epproducts_watchlist',
|
||||
'epproducts_product_detail',
|
||||
'epproducts_product_teasergroup',
|
||||
'epproducts_product_pricetable',
|
||||
'epproducts_snowreport_list',
|
||||
'epproducts_country_detail',
|
||||
'epproducts_region_teasergroup',
|
||||
'epproducts_region_detail',
|
||||
'epproducts_city_teasergroup',
|
||||
'epproducts_city_detail',
|
||||
'epproducts_hotel_teasergroup',
|
||||
'epproducts_hotel_teasergroup_nodate',
|
||||
'epproducts_hotel_detail',
|
||||
'epproducts_hotel_detail_event',
|
||||
'epproducts_concept_teasergroup',
|
||||
'epproducts_concept_detail',
|
||||
'epproducts_teammembers',
|
||||
'epproducts_faq',
|
||||
'epproducts_newsletter_subscription',
|
||||
'epproducts_maps',
|
||||
'epproducts_pricetable',
|
||||
];
|
||||
|
||||
protected function getListTypeToCTypeMapping(): array
|
||||
{
|
||||
return array_combine(self::PLUGINS, self::PLUGINS);
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'E&P Produkte: Plugins als eigene Inhaltstypen';
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Migrates the ep_products plugin elements from list_type to CType, including backend group permissions.';
|
||||
}
|
||||
}
|
||||
@@ -9,4 +9,9 @@ return [
|
||||
'provider' => SvgIconProvider::class,
|
||||
'source' => 'EXT:ep_products/Resources/Public/Icons/logo.svg',
|
||||
],
|
||||
// Content element types of the plugins, the logo of the extension manager
|
||||
'ep-products-plugin' => [
|
||||
'provider' => SvgIconProvider::class,
|
||||
'source' => 'EXT:ep_products/Resources/Public/Icons/Extension.svg',
|
||||
],
|
||||
];
|
||||
@@ -12,247 +12,199 @@ call_user_func(function (): void {
|
||||
ExtensionUtility::registerPlugin(
|
||||
'EpProducts',
|
||||
'searchresult',
|
||||
'Suchergebnis'
|
||||
'Suchergebnis',
|
||||
'ep-products-plugin'
|
||||
);
|
||||
|
||||
ExtensionUtility::registerPlugin(
|
||||
'EpProducts',
|
||||
'travelinfo',
|
||||
'Reiseinformationen'
|
||||
'Reiseinformationen',
|
||||
'ep-products-plugin'
|
||||
);
|
||||
|
||||
ExtensionUtility::registerPlugin(
|
||||
'EpProducts',
|
||||
'watchlist',
|
||||
'Merkliste'
|
||||
'Merkliste',
|
||||
'ep-products-plugin'
|
||||
);
|
||||
|
||||
ExtensionUtility::registerPlugin(
|
||||
'EpProducts',
|
||||
'product_detail',
|
||||
'Produkt: Details'
|
||||
'Produkt: Details',
|
||||
'ep-products-plugin'
|
||||
);
|
||||
|
||||
ExtensionUtility::registerPlugin(
|
||||
'EpProducts',
|
||||
'product_teasergroup',
|
||||
'Produkt: Teaser'
|
||||
'Produkt: Teaser',
|
||||
'ep-products-plugin'
|
||||
);
|
||||
|
||||
ExtensionUtility::registerPlugin(
|
||||
'EpProducts',
|
||||
'product_pricetable',
|
||||
'Buchungstabelle'
|
||||
'Buchungstabelle',
|
||||
'ep-products-plugin'
|
||||
);
|
||||
|
||||
ExtensionUtility::registerPlugin(
|
||||
'EpProducts',
|
||||
'snowreport_list',
|
||||
'Schneehöhen'
|
||||
'Schneehöhen',
|
||||
'ep-products-plugin'
|
||||
);
|
||||
|
||||
ExtensionUtility::registerPlugin(
|
||||
'EpProducts',
|
||||
'country_detail',
|
||||
'Land'
|
||||
'Land',
|
||||
'ep-products-plugin'
|
||||
);
|
||||
|
||||
ExtensionUtility::registerPlugin(
|
||||
'EpProducts',
|
||||
'region_teasergroup',
|
||||
'Gebiet: Teaser'
|
||||
'Gebiet: Teaser',
|
||||
'ep-products-plugin'
|
||||
);
|
||||
|
||||
ExtensionUtility::registerPlugin(
|
||||
'EpProducts',
|
||||
'region_detail',
|
||||
'Gebiet: Details'
|
||||
'Gebiet: Details',
|
||||
'ep-products-plugin'
|
||||
);
|
||||
|
||||
ExtensionUtility::registerPlugin(
|
||||
'EpProducts',
|
||||
'city_teasergroup',
|
||||
'Ort: Teaser'
|
||||
'Ort: Teaser',
|
||||
'ep-products-plugin'
|
||||
);
|
||||
|
||||
ExtensionUtility::registerPlugin(
|
||||
'EpProducts',
|
||||
'city_detail',
|
||||
'Ort: Details'
|
||||
'Ort: Details',
|
||||
'ep-products-plugin'
|
||||
);
|
||||
|
||||
ExtensionUtility::registerPlugin(
|
||||
'EpProducts',
|
||||
'hotel_teasergroup',
|
||||
'Hotel: Teaser'
|
||||
'Hotel: Teaser',
|
||||
'ep-products-plugin'
|
||||
);
|
||||
|
||||
ExtensionUtility::registerPlugin(
|
||||
'EpProducts',
|
||||
'hotel_teasergroup_nodate',
|
||||
'Hotel: Teaser (terminunabhängig)'
|
||||
'Hotel: Teaser (terminunabhängig)',
|
||||
'ep-products-plugin'
|
||||
);
|
||||
|
||||
ExtensionUtility::registerPlugin(
|
||||
'EpProducts',
|
||||
'hotel_detail',
|
||||
'Hotel: Details'
|
||||
'Hotel: Details',
|
||||
'ep-products-plugin'
|
||||
);
|
||||
|
||||
ExtensionUtility::registerPlugin(
|
||||
'EpProducts',
|
||||
'hotel_detail_event',
|
||||
'Hotel: Details (Event)'
|
||||
'Hotel: Details (Event)',
|
||||
'ep-products-plugin'
|
||||
);
|
||||
|
||||
ExtensionUtility::registerPlugin(
|
||||
'EpProducts',
|
||||
'concept_teasergroup',
|
||||
'Konzept: Teaser'
|
||||
'Konzept: Teaser',
|
||||
'ep-products-plugin'
|
||||
);
|
||||
|
||||
ExtensionUtility::registerPlugin(
|
||||
'EpProducts',
|
||||
'concept_detail',
|
||||
'Konzept: Details'
|
||||
'Konzept: Details',
|
||||
'ep-products-plugin'
|
||||
);
|
||||
|
||||
ExtensionUtility::registerPlugin(
|
||||
'EpProducts',
|
||||
'teammembers',
|
||||
'Team'
|
||||
'Team',
|
||||
'ep-products-plugin'
|
||||
);
|
||||
|
||||
ExtensionUtility::registerPlugin(
|
||||
'EpProducts',
|
||||
'faq',
|
||||
'FAQ'
|
||||
'FAQ',
|
||||
'ep-products-plugin'
|
||||
);
|
||||
|
||||
ExtensionUtility::registerPlugin(
|
||||
'EpProducts',
|
||||
'newsletter_subscription',
|
||||
'Newsletter-/RA-Registrierung'
|
||||
'Newsletter-/RA-Registrierung',
|
||||
'ep-products-plugin'
|
||||
);
|
||||
|
||||
ExtensionUtility::registerPlugin(
|
||||
'EpProducts',
|
||||
'maps',
|
||||
'Übersichtskarte Hotels/Produkte'
|
||||
'Übersichtskarte Hotels/Produkte',
|
||||
'ep-products-plugin'
|
||||
);
|
||||
|
||||
ExtensionUtility::registerPlugin(
|
||||
'EpProducts',
|
||||
'pricetable',
|
||||
'Preistabelle'
|
||||
'Preistabelle',
|
||||
'ep-products-plugin'
|
||||
);
|
||||
|
||||
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['epproducts_product_detail'] = 'pi_flexform';
|
||||
ExtensionManagementUtility::addPiFlexFormValue(
|
||||
'epproducts_product_detail',
|
||||
'FILE:EXT:ep_products/Configuration/FlexForms/flexform_product_detail.xml'
|
||||
);
|
||||
|
||||
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['epproducts_product_teasergroup'] = 'pi_flexform';
|
||||
ExtensionManagementUtility::addPiFlexFormValue(
|
||||
'epproducts_product_teasergroup',
|
||||
'FILE:EXT:ep_products/Configuration/FlexForms/flexform_product_teaser.xml'
|
||||
);
|
||||
|
||||
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['epproducts_product_pricetable'] = 'pi_flexform';
|
||||
ExtensionManagementUtility::addPiFlexFormValue(
|
||||
'epproducts_product_pricetable',
|
||||
'FILE:EXT:ep_products/Configuration/FlexForms/flexform_product_pricetable.xml'
|
||||
);
|
||||
|
||||
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['epproducts_snowreport_list'] = 'pi_flexform';
|
||||
ExtensionManagementUtility::addPiFlexFormValue(
|
||||
'epproducts_snowreport_list',
|
||||
'FILE:EXT:ep_products/Configuration/FlexForms/flexform_snowreport.xml'
|
||||
);
|
||||
|
||||
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['epproducts_country_detail'] = 'pi_flexform';
|
||||
ExtensionManagementUtility::addPiFlexFormValue(
|
||||
'epproducts_country_detail',
|
||||
'FILE:EXT:ep_products/Configuration/FlexForms/flexform_country.xml'
|
||||
);
|
||||
|
||||
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['epproducts_region_teasergroup'] = 'pi_flexform';
|
||||
ExtensionManagementUtility::addPiFlexFormValue(
|
||||
'epproducts_region_teasergroup',
|
||||
'FILE:EXT:ep_products/Configuration/FlexForms/flexform_region_teaser.xml'
|
||||
);
|
||||
|
||||
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['epproducts_region_detail'] = 'pi_flexform';
|
||||
ExtensionManagementUtility::addPiFlexFormValue(
|
||||
'epproducts_region_detail',
|
||||
'FILE:EXT:ep_products/Configuration/FlexForms/flexform_region_detail.xml'
|
||||
);
|
||||
|
||||
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['epproducts_city_teasergroup'] = 'pi_flexform';
|
||||
ExtensionManagementUtility::addPiFlexFormValue(
|
||||
'epproducts_city_teasergroup',
|
||||
'FILE:EXT:ep_products/Configuration/FlexForms/flexform_city_teaser.xml'
|
||||
);
|
||||
|
||||
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['epproducts_city_detail'] = 'pi_flexform';
|
||||
ExtensionManagementUtility::addPiFlexFormValue(
|
||||
'epproducts_city_detail',
|
||||
'FILE:EXT:ep_products/Configuration/FlexForms/flexform_city_detail.xml'
|
||||
);
|
||||
|
||||
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['epproducts_hotel_teasergroup'] = 'pi_flexform';
|
||||
ExtensionManagementUtility::addPiFlexFormValue(
|
||||
'epproducts_hotel_teasergroup',
|
||||
'FILE:EXT:ep_products/Configuration/FlexForms/flexform_hotel_teaser.xml'
|
||||
);
|
||||
|
||||
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['epproducts_hotel_teasergroup_nodate'] = 'pi_flexform';
|
||||
ExtensionManagementUtility::addPiFlexFormValue(
|
||||
'epproducts_hotel_teasergroup_nodate',
|
||||
'FILE:EXT:ep_products/Configuration/FlexForms/flexform_hotel_teaser_date_independent.xml'
|
||||
);
|
||||
|
||||
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['epproducts_hotel_detail'] = 'pi_flexform';
|
||||
ExtensionManagementUtility::addPiFlexFormValue(
|
||||
'epproducts_hotel_detail',
|
||||
'FILE:EXT:ep_products/Configuration/FlexForms/flexform_hotel_detail.xml'
|
||||
);
|
||||
|
||||
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['epproducts_hotel_detail_event'] = 'pi_flexform';
|
||||
ExtensionManagementUtility::addPiFlexFormValue(
|
||||
'epproducts_hotel_detail_event',
|
||||
'FILE:EXT:ep_products/Configuration/FlexForms/flexform_hotel_detail_event.xml'
|
||||
);
|
||||
|
||||
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['epproducts_concept_detail'] = 'pi_flexform';
|
||||
ExtensionManagementUtility::addPiFlexFormValue(
|
||||
'epproducts_concept_detail',
|
||||
'FILE:EXT:ep_products/Configuration/FlexForms/flexform_concept_detail.xml'
|
||||
);
|
||||
|
||||
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['epproducts_faq'] = 'pi_flexform';
|
||||
ExtensionManagementUtility::addPiFlexFormValue(
|
||||
'epproducts_faq',
|
||||
'FILE:EXT:ep_products/Configuration/FlexForms/flexform_faq.xml'
|
||||
);
|
||||
|
||||
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['epproducts_maps'] = 'pi_flexform';
|
||||
ExtensionManagementUtility::addPiFlexFormValue(
|
||||
'epproducts_maps',
|
||||
'FILE:EXT:ep_products/Configuration/FlexForms/flexform_maps.xml'
|
||||
);
|
||||
|
||||
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['epproducts_pricetable'] = 'pi_flexform';
|
||||
ExtensionManagementUtility::addPiFlexFormValue(
|
||||
'epproducts_pricetable',
|
||||
'FILE:EXT:ep_products/Configuration/FlexForms/flexform_pricetable.xml'
|
||||
);
|
||||
|
||||
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['epproducts_teammembers'] = 'pi_flexform';
|
||||
ExtensionManagementUtility::addPiFlexFormValue(
|
||||
'epproducts_teammembers',
|
||||
'FILE:EXT:ep_products/Configuration/FlexForms/flexform_teammembers.xml'
|
||||
);
|
||||
// Content element types since 2026-10 (upgrade wizard epProductsPluginListTypeToCType); the form keeps the
|
||||
// fields of the former "list" type, with the plugin options in place of the plugin selector
|
||||
$flexForms = [
|
||||
'epproducts_product_detail' => 'FILE:EXT:ep_products/Configuration/FlexForms/flexform_product_detail.xml',
|
||||
'epproducts_product_teasergroup' => 'FILE:EXT:ep_products/Configuration/FlexForms/flexform_product_teaser.xml',
|
||||
'epproducts_product_pricetable' => 'FILE:EXT:ep_products/Configuration/FlexForms/flexform_product_pricetable.xml',
|
||||
'epproducts_snowreport_list' => 'FILE:EXT:ep_products/Configuration/FlexForms/flexform_snowreport.xml',
|
||||
'epproducts_country_detail' => 'FILE:EXT:ep_products/Configuration/FlexForms/flexform_country.xml',
|
||||
'epproducts_region_teasergroup' => 'FILE:EXT:ep_products/Configuration/FlexForms/flexform_region_teaser.xml',
|
||||
'epproducts_region_detail' => 'FILE:EXT:ep_products/Configuration/FlexForms/flexform_region_detail.xml',
|
||||
'epproducts_city_teasergroup' => 'FILE:EXT:ep_products/Configuration/FlexForms/flexform_city_teaser.xml',
|
||||
'epproducts_city_detail' => 'FILE:EXT:ep_products/Configuration/FlexForms/flexform_city_detail.xml',
|
||||
'epproducts_hotel_teasergroup' => 'FILE:EXT:ep_products/Configuration/FlexForms/flexform_hotel_teaser.xml',
|
||||
'epproducts_hotel_teasergroup_nodate' => 'FILE:EXT:ep_products/Configuration/FlexForms/flexform_hotel_teaser_date_independent.xml',
|
||||
'epproducts_hotel_detail' => 'FILE:EXT:ep_products/Configuration/FlexForms/flexform_hotel_detail.xml',
|
||||
'epproducts_hotel_detail_event' => 'FILE:EXT:ep_products/Configuration/FlexForms/flexform_hotel_detail_event.xml',
|
||||
'epproducts_concept_detail' => 'FILE:EXT:ep_products/Configuration/FlexForms/flexform_concept_detail.xml',
|
||||
'epproducts_faq' => 'FILE:EXT:ep_products/Configuration/FlexForms/flexform_faq.xml',
|
||||
'epproducts_maps' => 'FILE:EXT:ep_products/Configuration/FlexForms/flexform_maps.xml',
|
||||
'epproducts_pricetable' => 'FILE:EXT:ep_products/Configuration/FlexForms/flexform_pricetable.xml',
|
||||
'epproducts_teammembers' => 'FILE:EXT:ep_products/Configuration/FlexForms/flexform_teammembers.xml',
|
||||
];
|
||||
foreach ($GLOBALS['TCA']['tt_content']['columns']['CType']['config']['items'] as $item) {
|
||||
$cType = (string)($item['value'] ?? '');
|
||||
if (!str_starts_with($cType, 'epproducts_')) {
|
||||
continue;
|
||||
}
|
||||
$GLOBALS['TCA']['tt_content']['types'][$cType]['showitem'] = str_replace(
|
||||
'list_type;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:list_type_formlabel,',
|
||||
isset($flexForms[$cType]) ? 'pi_flexform,' : '',
|
||||
$GLOBALS['TCA']['tt_content']['types']['list']['showitem']
|
||||
);
|
||||
if (isset($flexForms[$cType])) {
|
||||
ExtensionManagementUtility::addPiFlexFormValue('*', $flexForms[$cType], $cType);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
use TYPO3\CMS\Scheduler\Task\TableGarbageCollectionTask;
|
||||
use TYPO3\CMS\Extbase\Utility\ExtensionUtility;
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
use EP\EpProducts\Controller\ProductController;
|
||||
use EP\EpProducts\Controller\CityController;
|
||||
use EP\EpProducts\Controller\ConceptController;
|
||||
@@ -54,7 +55,9 @@ $boot = function (): void {
|
||||
'product_detail',
|
||||
[
|
||||
ProductController::class => 'detail,hotelList',
|
||||
]
|
||||
],
|
||||
[],
|
||||
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
ExtensionUtility::configurePlugin(
|
||||
@@ -62,7 +65,9 @@ $boot = function (): void {
|
||||
'product_teasergroup',
|
||||
[
|
||||
ProductController::class => 'teasergroup',
|
||||
]
|
||||
],
|
||||
[],
|
||||
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
ExtensionUtility::configurePlugin(
|
||||
@@ -70,7 +75,9 @@ $boot = function (): void {
|
||||
'product_pricetable',
|
||||
[
|
||||
ProductController::class => 'pricetable',
|
||||
]
|
||||
],
|
||||
[],
|
||||
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
ExtensionUtility::configurePlugin(
|
||||
@@ -78,7 +85,9 @@ $boot = function (): void {
|
||||
'country_detail',
|
||||
[
|
||||
CountryController::class => 'detail',
|
||||
]
|
||||
],
|
||||
[],
|
||||
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
ExtensionUtility::configurePlugin(
|
||||
@@ -86,7 +95,9 @@ $boot = function (): void {
|
||||
'region_teasergroup',
|
||||
[
|
||||
RegionController::class => 'teasergroup',
|
||||
]
|
||||
],
|
||||
[],
|
||||
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
ExtensionUtility::configurePlugin(
|
||||
@@ -94,7 +105,9 @@ $boot = function (): void {
|
||||
'region_detail',
|
||||
[
|
||||
RegionController::class => 'detail',
|
||||
]
|
||||
],
|
||||
[],
|
||||
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
ExtensionUtility::configurePlugin(
|
||||
@@ -102,7 +115,9 @@ $boot = function (): void {
|
||||
'city_teasergroup',
|
||||
[
|
||||
CityController::class => 'teasergroup',
|
||||
]
|
||||
],
|
||||
[],
|
||||
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
ExtensionUtility::configurePlugin(
|
||||
@@ -110,7 +125,9 @@ $boot = function (): void {
|
||||
'city_detail',
|
||||
[
|
||||
CityController::class => 'detail',
|
||||
]
|
||||
],
|
||||
[],
|
||||
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
ExtensionUtility::configurePlugin(
|
||||
@@ -118,7 +135,9 @@ $boot = function (): void {
|
||||
'hotel_teasergroup',
|
||||
[
|
||||
HotelController::class => 'teasergroup',
|
||||
]
|
||||
],
|
||||
[],
|
||||
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
ExtensionUtility::configurePlugin(
|
||||
@@ -126,7 +145,9 @@ $boot = function (): void {
|
||||
'hotel_teasergroup_nodate',
|
||||
[
|
||||
HotelController::class => 'dateIndependentTeasergroup',
|
||||
]
|
||||
],
|
||||
[],
|
||||
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
ExtensionUtility::configurePlugin(
|
||||
@@ -134,7 +155,9 @@ $boot = function (): void {
|
||||
'hotel_detail',
|
||||
[
|
||||
HotelController::class => 'detail',
|
||||
]
|
||||
],
|
||||
[],
|
||||
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
ExtensionUtility::configurePlugin(
|
||||
@@ -142,7 +165,9 @@ $boot = function (): void {
|
||||
'hotel_detail_event',
|
||||
[
|
||||
HotelController::class => 'detailEvent',
|
||||
]
|
||||
],
|
||||
[],
|
||||
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
ExtensionUtility::configurePlugin(
|
||||
@@ -150,7 +175,9 @@ $boot = function (): void {
|
||||
'faq',
|
||||
[
|
||||
FaqController::class => 'detail',
|
||||
]
|
||||
],
|
||||
[],
|
||||
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
ExtensionUtility::configurePlugin(
|
||||
@@ -158,7 +185,9 @@ $boot = function (): void {
|
||||
'concept_teasergroup',
|
||||
[
|
||||
ConceptController::class => 'teasergroup',
|
||||
]
|
||||
],
|
||||
[],
|
||||
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
ExtensionUtility::configurePlugin(
|
||||
@@ -166,7 +195,9 @@ $boot = function (): void {
|
||||
'concept_detail',
|
||||
[
|
||||
ConceptController::class => 'detail',
|
||||
]
|
||||
],
|
||||
[],
|
||||
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
ExtensionUtility::configurePlugin(
|
||||
@@ -174,7 +205,9 @@ $boot = function (): void {
|
||||
'teammembers',
|
||||
[
|
||||
TeamController::class => 'list,show',
|
||||
]
|
||||
],
|
||||
[],
|
||||
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
ExtensionUtility::configurePlugin(
|
||||
@@ -185,7 +218,8 @@ $boot = function (): void {
|
||||
],
|
||||
[
|
||||
NewsletterController::class => 'subscriptionForm,subscriptionFormSubmit',
|
||||
]
|
||||
],
|
||||
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
ExtensionUtility::configurePlugin(
|
||||
@@ -193,7 +227,9 @@ $boot = function (): void {
|
||||
'maps',
|
||||
[
|
||||
MapController::class => 'general',
|
||||
]
|
||||
],
|
||||
[],
|
||||
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
ExtensionUtility::configurePlugin(
|
||||
@@ -201,7 +237,9 @@ $boot = function (): void {
|
||||
'pricetable',
|
||||
[
|
||||
PricetableController::class => 'event',
|
||||
]
|
||||
],
|
||||
[],
|
||||
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
ExtensionUtility::configurePlugin(
|
||||
@@ -223,7 +261,8 @@ $boot = function (): void {
|
||||
],
|
||||
[
|
||||
SearchController::class => 'searchresult',
|
||||
]
|
||||
],
|
||||
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
// The search bar in the page header (lib.searchBar), not a content element
|
||||
@@ -232,7 +271,9 @@ $boot = function (): void {
|
||||
'searchbar',
|
||||
[
|
||||
SearchbarController::class => 'index',
|
||||
]
|
||||
],
|
||||
[],
|
||||
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
ExtensionUtility::configurePlugin(
|
||||
@@ -240,7 +281,9 @@ $boot = function (): void {
|
||||
'watchlist',
|
||||
[
|
||||
WatchlistController::class => 'list',
|
||||
]
|
||||
],
|
||||
[],
|
||||
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
ExtensionUtility::configurePlugin(
|
||||
@@ -248,7 +291,9 @@ $boot = function (): void {
|
||||
'travelinfo',
|
||||
[
|
||||
TravelinfoController::class => 'travelInfo,travelCode',
|
||||
]
|
||||
],
|
||||
[],
|
||||
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
ExtensionUtility::configurePlugin(
|
||||
@@ -256,7 +301,9 @@ $boot = function (): void {
|
||||
'snowreport_list',
|
||||
[
|
||||
SnowreportController::class => 'list',
|
||||
]
|
||||
],
|
||||
[],
|
||||
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
ExtensionUtility::configurePlugin(
|
||||
@@ -276,9 +323,19 @@ $boot = function (): void {
|
||||
AjaxWatchlistController::class => 'list',
|
||||
AjaxTableController::class => 'datestable,pricetable,pricetableHtml,eventPricetable',
|
||||
AjaxTeaserPopupController::class => 'concept',
|
||||
]
|
||||
],
|
||||
ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
// Elements not yet migrated by the upgrade wizard epProductsPluginListTypeToCType (deploy first, then run
|
||||
// the wizard) still render: list_type plugin => content element type of the same name
|
||||
$listTypeAliases = '';
|
||||
foreach (array_keys($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions']['EpProducts']['plugins']) as $pluginName) {
|
||||
$signature = 'epproducts_' . strtolower((string)$pluginName);
|
||||
$listTypeAliases .= 'tt_content.list.20.' . $signature . ' < tt_content.' . $signature . ".20\n";
|
||||
}
|
||||
ExtensionManagementUtility::addTypoScript('ep_products', 'setup', $listTypeAliases, 'defaultContentRendering');
|
||||
|
||||
$GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'][] = '_gl';
|
||||
$GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'][] = 'gclid';
|
||||
$GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'][] = 'ref';
|
||||
|
||||
@@ -32,13 +32,18 @@ call_user_func(function (): void {
|
||||
);
|
||||
|
||||
// Column layouts, migrated from gridelements in 2026 (commit 4172ed9). colPos = 200 + 10 × layout + column
|
||||
// ep_products plugins are content element types of their own since 2026-10; "list" stays for retired plugins
|
||||
$plugins = implode(',', array_filter(
|
||||
array_map(static fn(array $item): string => (string)($item['value'] ?? ''), $GLOBALS['TCA']['tt_content']['columns']['CType']['config']['items']),
|
||||
static fn(string $cType): bool => str_starts_with($cType, 'epproducts_')
|
||||
));
|
||||
$menus = 'menu_abstract,menu_categorized_content,menu_categorized_pages,menu_recently_updated,menu_related_pages,menu_section_pages,menu_sitemap,menu_sitemap_pages';
|
||||
$columnContainers = [
|
||||
'ep_container_halves' => ['Spalten 50/50', 'Zwei gleich breite Spalten', 'halves', [[201], [202]]],
|
||||
'ep_container_thirds' => ['Spalten 33/33/33', 'Drei gleich breite Spalten', 'thirds', [[211], [212], [213]]],
|
||||
'ep_container_columns_quarters' => ['Spalten 25/25/25/25', 'Vier gleich breite Spalten', 'quarters', [[221], [222], [223], [224]]],
|
||||
'ep_container_half_and_two_quarters' => ['Spalten 50/25/25', 'Eine breite und zwei schmale Spalten', 'half_and_two_quarters', [[231, 'textmedia,teaser,list,form_formframework'], [232], [233]]],
|
||||
'ep_container_two_quarters_and_half' => ['Spalten 25/25/50', 'Zwei schmale und eine breite Spalte', 'two_quarters_and_half', [[241], [242], [243, 'textmedia,teaser,list,gmap,nlform,form_formframework,menu_pages,menu_subpages,menu_section']]],
|
||||
'ep_container_half_and_two_quarters' => ['Spalten 50/25/25', 'Eine breite und zwei schmale Spalten', 'half_and_two_quarters', [[231, 'textmedia,teaser,list,form_formframework,' . $plugins], [232], [233]]],
|
||||
'ep_container_two_quarters_and_half' => ['Spalten 25/25/50', 'Zwei schmale und eine breite Spalte', 'two_quarters_and_half', [[241], [242], [243, 'textmedia,teaser,list,gmap,nlform,form_formframework,menu_pages,menu_subpages,menu_section,' . $plugins]]],
|
||||
];
|
||||
// No container inside these columns (topLevelLayout of the gridelements configuration)
|
||||
$containers = implode(',', array_merge(['ep_container_quarters', 'ep_container_teasergroup'], array_keys($columnContainers)));
|
||||
|
||||
@@ -6,9 +6,10 @@
|
||||
# Plugins (the booking widget on product detail pages), forms, sub-page menus and teaser cards
|
||||
# are left out: MyE&P has trip data first-hand, and the pages and records the cards link to are
|
||||
# in the feed in their own right. The filter applies to top-level elements only; a plugin nested
|
||||
# in a grid or container element is still rendered by its parent.
|
||||
# in a grid or container element is still rendered by its parent. The ep_products plugins are content
|
||||
# element types of their own (epproducts_*); "list" in the setting covers the retired plugins.
|
||||
lib.contentOnly < lib.dynamicContent
|
||||
lib.contentOnly.20.select.where = colPos={register:colPos} AND CType NOT IN ({$plugin.tx_eptheme.settings.contentOnlyExcludedCTypes})
|
||||
lib.contentOnly.20.select.where = colPos={register:colPos} AND CType NOT IN ({$plugin.tx_eptheme.settings.contentOnlyExcludedCTypes}) AND CType NOT LIKE 'epproducts_%'
|
||||
|
||||
tx_eptheme_content_only = PAGE
|
||||
tx_eptheme_content_only {
|
||||
|
||||
Reference in new issue
Block a user