'Vitec: Full Width', 'value' => 'vitec-full-width'], ['label' => 'Vitec: Centered Container', 'value' => 'vitec-centered'], ['label' => 'Vitec: Card Style', 'value' => 'vitec-card'], ['label' => 'Vitec: Dark Background', 'value' => 'vitec-dark'], ['label' => 'Vitec: Highlight Box', 'value' => 'vitec-highlight'], // Background variants, ordered light to dark. Mutually exclusive by // intent, but frame_class is a multi-select here (selectCheckBox, // see above) and stays that way on purpose -- a restriction would // have to be built for every other class too. If an editor ticks two // backgrounds, both end up comma-separated in the JSON `frameClass` // and the frontend decides which one wins. // // `vitec-bg-graphite`, `-blue` and `-midnight` were already styled in // the frontend bundle but had no backend option; `-white` and // `-light-grey` still need their CSS. // // The older 'Vitec: Dark Background' (vitec-dark) above stays as it // is: existing content depends on it, and it is the most heavily // styled class of them all. ['label' => 'Vitec: White Background', 'value' => 'vitec-bg-white'], ['label' => 'Vitec: Light-Grey Background', 'value' => 'vitec-bg-light-grey'], ['label' => 'Vitec: VITEC-Graphite Background', 'value' => 'vitec-bg-graphite'], ['label' => 'Vitec: VITEC-Blue Background', 'value' => 'vitec-bg-blue'], ['label' => 'Vitec: VITEC-Midnight Background', 'value' => 'vitec-bg-midnight'], ] ); // Inline parent pointer: content elements owned by a Success Story record. $GLOBALS['TCA']['tt_content']['columns']['tx_vitec_usecase_content'] = [ 'config' => ['type' => 'passthrough'], ]; // The standard TYPO3 "Appearance" tab for the Content Blocks elements. // // Content Blocks builds each element's showitem itself // (TcaGenerator::getContentElementStandardShowItem) and appends only the // "Extended" tab -- Appearance is never part of it. The Extbase plugins are // unaffected: ExtensionManagementUtility::addPlugin() seeds their type from // tt_content types['header'], which carries the tab already. // // Until now that meant an editor could not reach layout, frame_class // (including the Vitec classes registered above), spaceBefore/spaceAfter, // sectionIndex or linkToTop on a Content Block at all. // // Deliberately NOT declared as a palette in every config.yaml: palettes live // in TCA under a global identifier, so a second definition of `frames` would // collide with the Core one -- the same trap that took the page module down // on 2026-08-10. Pointing at the Core palettes keeps a single definition. // // This file runs after Content Blocks, which generates its TCA on // BeforeTcaOverridesEvent. $appearanceTab = '--div--;core.form.tabs:appearance,' . '--palette--;;frames,' . '--palette--;;appearanceLinks'; $extendedTab = '--div--;core.form.tabs:extended'; foreach ($GLOBALS['TCA']['tt_content']['types'] as $cType => &$typeConfig) { // Own elements only, and only those still missing the tab -- that skips // the plugins and makes a repeated run a no-op. if (!str_starts_with((string)$cType, 'vitec_') || !isset($typeConfig['showitem']) || str_contains($typeConfig['showitem'], '--palette--;;frames') ) { continue; } // Content Blocks puts "Extended" last, so Appearance goes in front of it // and the tab order matches the Core content elements. Should a future // version drop that marker, append rather than silently do nothing. if (str_contains($typeConfig['showitem'], $extendedTab)) { $typeConfig['showitem'] = str_replace( $extendedTab, $appearanceTab . ',' . $extendedTab, $typeConfig['showitem'] ); } else { $typeConfig['showitem'] = rtrim($typeConfig['showitem'], ", \t\n\r") . ',' . $appearanceTab; } } unset($typeConfig); })();