'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); // Shared Content-Block select columns (fix 2026-09-25). // // `layout_variant` and `background_variant` are defined by BOTH vitec/card // and vitec/cta-banner - same identifier under the vendor prefix, so both // blocks write the same tt_content columns. Content Blocks merges such // diverging item lists INDEX-wise into the base column and generates no // per-type items override: the card-only values `vertical`, `horizontal`, // `horizontal_reverse` and background `none` did not exist as items at // all, and FormEngine showed "[ Missing label ]" for exactly those stored // values (hero-section / intro-paragraph dodged the trap long ago with // `hero_` / `intro_` prefixes). // // Fixed here WITHOUT renaming columns (existing data and the JSON keys // `layout_variant` / `background_variant` stay): the base column carries // the short cta-banner lists, vitec_card gets its full lists through // columnsOverrides. FormEngine and the DataHandler both respect // columnsOverrides; the per-type merge is array_replace_recursive, so an // items override can only EXTEND the base list, never shorten it - which // holds (9/7 items over 3/5). New blocks must not reuse these identifiers // with diverging items; prefix them instead. $GLOBALS['TCA']['tt_content']['columns']['vitec_layout_variant']['config']['items'] = [ ['label' => 'Centered (text over background)', 'value' => 'centered'], ['label' => 'Split (text left, CTAs right)', 'value' => 'split'], ['label' => 'Stacked (text top, CTAs below)', 'value' => 'stacked'], ]; $GLOBALS['TCA']['tt_content']['columns']['vitec_background_variant']['config']['items'] = [ ['label' => 'Orange', 'value' => 'orange'], ['label' => 'Blue', 'value' => 'blue'], ['label' => 'Graphite', 'value' => 'graphite'], ['label' => 'Midnight', 'value' => 'midnight'], ['label' => 'Light (neutral)', 'value' => 'light'], ]; $GLOBALS['TCA']['tt_content']['types']['vitec_card']['columnsOverrides']['vitec_layout_variant']['config']['items'] = [ ['label' => 'Vertical (image top, content below)', 'value' => 'vertical'], ['label' => 'Horizontal (image left, content right)', 'value' => 'horizontal'], ['label' => 'Horizontal Reverse (content left, image right)', 'value' => 'horizontal_reverse'], ['label' => 'Image Overlay (text over image)', 'value' => 'image_overlay'], ['label' => 'Text Only (no image)', 'value' => 'text_only'], ['label' => 'Icon Card (icon focused, text below)', 'value' => 'icon_card'], ['label' => 'Feature (large highlighted card)', 'value' => 'feature'], ['label' => 'Compact (small card, tight spacing)', 'value' => 'compact'], ['label' => 'Flip Card (front / back)', 'value' => 'flipcard'], ]; $GLOBALS['TCA']['tt_content']['types']['vitec_card']['columnsOverrides']['vitec_background_variant']['config']['items'] = [ ['label' => 'None', 'value' => 'none'], ['label' => 'Orange', 'value' => 'orange'], ['label' => 'Blue', 'value' => 'blue'], ['label' => 'Graphite', 'value' => 'graphite'], ['label' => 'Midnight', 'value' => 'midnight'], ['label' => 'Light (neutral)', 'value' => 'light'], ['label' => 'Dark (neutral)', 'value' => 'dark'], ]; })();