Checkpoint: headless JSON architecture documented + cleanup (Stufe 1+2)

Restore point before Stufe 3 (central resolver-service refactoring).

Includes this session's work:
- Success Story (usecase) rebuild: new fields/tabs, UsecaseSerializer,
  thin List/Show renderers, MM relations, inline content elements.
- vitec_columns content block (two-column layout with per-item content)
  incl. unified header section; special-cased JSON resolution.
- Container per-column flex (items[].config align/justify) + gap on parent.
- Unified header section across CEs/plugins/containers; header fields in JSON.
- ISO-style architecture spec: Documentation/Headless-JSON-Architecture.md.
- Cleanup: removed local scratch + verified .bak backups.
- Fixes: B-6 (undefined thumbnail variable in Downloadcardcollection image
  resolver), B-7 (unsatisfiable legacy CType OR branch in Downloadcard/Datasheets).

Rollback: git reset --hard snapshot-2026-07-09-pre-stufe3

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
o-rascheandClaude Opus 4.8 committed 2026-07-09 10:01:56 +02:00
1 parent c6759186cb
commit bb7c03235d
237 files changed
+6698 -1749

No files matched your search

View File
File mode changed.
@@ -34,6 +34,7 @@ use TYPO3\CMS\Extbase\Utility\ExtensionUtility;
$registerPluginWithFlexForm('Downloadcard', 'Download Card', 'FILE:EXT:vitec/Configuration/FlexForms/Downloadcard.xml', 'vitec-plugin-downloadcard');
$registerPluginWithFlexForm('Downloadcardcollection', 'Download Card Collection', 'FILE:EXT:vitec/Configuration/FlexForms/Downloadcardcollection.xml', 'vitec-plugin-downloadcardcollection');
$registerPluginWithFlexForm('Datasheets', 'Datasheets', 'FILE:EXT:vitec/Configuration/FlexForms/Datasheets.xml');
$registerPluginWithFlexForm('Eventlist', 'Event List', 'FILE:EXT:vitec/Configuration/FlexForms/Eventlist.xml', 'vitec-plugin-eventlist');
// Change frame_class to allow multiple selections.
$GLOBALS['TCA']['tt_content']['columns']['frame_class']['config']['renderType'] = 'selectCheckBox';
@@ -50,4 +51,9 @@ use TYPO3\CMS\Extbase\Utility\ExtensionUtility;
['label' => 'Vitec: Highlight Box', 'value' => 'vitec-highlight'],
]
);
// Inline parent pointer: content elements owned by a Success Story record.
$GLOBALS['TCA']['tt_content']['columns']['tx_vitec_usecase_content'] = [
'config' => ['type' => 'passthrough'],
];
})();
@@ -0,0 +1,63 @@
<?php
declare(strict_types=1);
defined('TYPO3') or die();
use B13\Container\Tca\ContainerConfiguration;
use B13\Container\Tca\Registry;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
(static function (): void {
$l = 'LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:';
/** @var Registry $registry */
$registry = GeneralUtility::makeInstance(Registry::class);
$registry->configureContainer(
(new ContainerConfiguration(
'vitec_cards_carousel',
$l . 'cards_carousel.title',
$l . 'cards_carousel.description',
[
[
['name' => $l . 'cards_carousel.column', 'colPos' => 260],
],
]
))
->setIcon('EXT:vitec/Resources/Public/Icons/vitec-cards-carousel.svg')
->setGroup('vitec_custom_components')
->setSaveAndCloseInNewContentElementWizard(true)
);
$GLOBALS['TCA']['tt_content']['types']['vitec_cards_carousel']['showitem'] =
'--palette--;;general,
--palette--;;headers,
tx_vitec_bg_variant,
pi_flexform;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:cards_carousel.flexform.label,
--div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.appearance,
--palette--;;frames,
--palette--;;appearanceLinks,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language,
--palette--;;language,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access,
--palette--;;hidden,
--palette--;;access';
ExtensionManagementUtility::addPiFlexFormValue(
'*',
'FILE:EXT:vitec/Configuration/FlexForms/CardsCarousel.xml',
'vitec_cards_carousel'
);
$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'] = ($GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'] ?? '') . "\n" . <<<'TSCONFIG'
mod.wizards.newContentElement.wizardItems.vitec_custom_components.elements.vitec_cards_carousel {
iconIdentifier = vitec-cards-carousel
title = LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:cards_carousel.title
description = LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:cards_carousel.description
tt_content_defValues {
CType = vitec_cards_carousel
}
}
TSCONFIG;
})();
@@ -35,10 +35,14 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
$GLOBALS['TCA']['tt_content']['types']['vitec_cols_25_25_25_25']['showitem'] =
'--palette--;;general,
header;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:section.heading,
subheader;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:section.subline,
--palette--;;headers,
tx_vitec_bg_variant,
--div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.appearance,
--palette--;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:palette.grid;vitec_grid,
--palette--;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:column.1;vitec_col1_flex,
--palette--;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:column.2;vitec_col2_flex,
--palette--;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:column.3;vitec_col3_flex,
--palette--;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:column.4;vitec_col4_flex,
--palette--;;frames,
--palette--;;appearanceLinks,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language,
+5 -2
View File
@@ -34,10 +34,13 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
$GLOBALS['TCA']['tt_content']['types']['vitec_cols_33_33_33']['showitem'] =
'--palette--;;general,
header;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:section.heading,
subheader;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:section.subline,
--palette--;;headers,
tx_vitec_bg_variant,
--div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.appearance,
--palette--;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:palette.grid;vitec_grid,
--palette--;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:column.1;vitec_col1_flex,
--palette--;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:column.2;vitec_col2_flex,
--palette--;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:column.3;vitec_col3_flex,
--palette--;;frames,
--palette--;;appearanceLinks,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language,
+4 -2
View File
@@ -33,10 +33,12 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
$GLOBALS['TCA']['tt_content']['types']['vitec_cols_33_66']['showitem'] =
'--palette--;;general,
header;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:section.heading,
subheader;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:section.subline,
--palette--;;headers,
tx_vitec_bg_variant,
--div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.appearance,
--palette--;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:palette.grid;vitec_grid,
--palette--;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:column.sidebar_33;vitec_col1_flex,
--palette--;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:column.main_66;vitec_col2_flex,
--palette--;;frames,
--palette--;;appearanceLinks,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language,
+4 -2
View File
@@ -33,10 +33,12 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
$GLOBALS['TCA']['tt_content']['types']['vitec_cols_50_50']['showitem'] =
'--palette--;;general,
header;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:section.heading,
subheader;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:section.subline,
--palette--;;headers,
tx_vitec_bg_variant,
--div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.appearance,
--palette--;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:palette.grid;vitec_grid,
--palette--;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:column.1;vitec_col1_flex,
--palette--;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:column.2;vitec_col2_flex,
--palette--;;frames,
--palette--;;appearanceLinks,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language,
+4 -2
View File
@@ -33,10 +33,12 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
$GLOBALS['TCA']['tt_content']['types']['vitec_cols_66_33']['showitem'] =
'--palette--;;general,
header;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:section.heading,
subheader;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:section.subline,
--palette--;;headers,
tx_vitec_bg_variant,
--div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.appearance,
--palette--;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:palette.grid;vitec_grid,
--palette--;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:column.main_66;vitec_col1_flex,
--palette--;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:column.sidebar_33;vitec_col2_flex,
--palette--;;frames,
--palette--;;appearanceLinks,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language,
+1 -2
View File
@@ -32,8 +32,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
$GLOBALS['TCA']['tt_content']['types']['vitec_container']['showitem'] =
'--palette--;;general,
header;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:section.heading,
subheader;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:section.subline,
--palette--;;headers,
tx_vitec_bg_variant,
pi_flexform;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:container.flexform.label,
--div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.appearance,
+81
View File
@@ -27,6 +27,87 @@ use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
],
]);
// -------------------------------------------------------------------------
// Shared parent-level setting: column gap scale (1–5) for the whole grid.
// Concerns the container itself (not a single column); maps to a spacing
// token in the React frontend. Rendered in the "Grid" palette on top of the
// Appearance tab, above the per-column rows.
// -------------------------------------------------------------------------
ExtensionManagementUtility::addTCAcolumns('tt_content', [
'tx_vitec_gap' => [
'label' => $l . 'gap.label',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'items' => [
['label' => $l . 'gap.option.1', 'value' => '1'],
['label' => $l . 'gap.option.2', 'value' => '2'],
['label' => $l . 'gap.option.3', 'value' => '3'],
['label' => $l . 'gap.option.4', 'value' => '4'],
['label' => $l . 'gap.option.5', 'value' => '5'],
],
'default' => '3',
],
],
]);
// Parent-element palette: settings that concern the whole grid, not a column.
$GLOBALS['TCA']['tt_content']['palettes']['vitec_grid'] = [
'showitem' => 'tx_vitec_gap',
];
// -------------------------------------------------------------------------
// Shared per-column flex alignment fields for the X-column containers.
// Positional: col1 = first column, col2 = second, ... (max 4 columns).
// "Align" -> CSS align-items (cross-axis alignment of the column's items)
// "Justify" -> CSS justify-content (main-axis distribution within the column)
// Reused across vitec_cols_50_50 / 33_66 / 66_33 / 33_33_33 / 25_25_25_25.
// -------------------------------------------------------------------------
$alignItems = [
['label' => $l . 'flex.align.flex_start', 'value' => 'flex-start'],
['label' => $l . 'flex.align.center', 'value' => 'center'],
['label' => $l . 'flex.align.flex_end', 'value' => 'flex-end'],
['label' => $l . 'flex.align.stretch', 'value' => 'stretch'],
];
$justifyItems = [
['label' => $l . 'flex.justify.flex_start', 'value' => 'flex-start'],
['label' => $l . 'flex.justify.center', 'value' => 'center'],
['label' => $l . 'flex.justify.space_between', 'value' => 'space-between'],
['label' => $l . 'flex.justify.space_around', 'value' => 'space-around'],
['label' => $l . 'flex.justify.space_evenly', 'value' => 'space-evenly'],
];
$columnFields = [];
for ($i = 1; $i <= 4; $i++) {
$columnFields['tx_vitec_col' . $i . '_align'] = [
'label' => $l . 'flex.align.label',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'items' => $alignItems,
'default' => 'stretch',
],
];
$columnFields['tx_vitec_col' . $i . '_justify'] = [
'label' => $l . 'flex.justify.label',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'items' => $justifyItems,
'default' => 'flex-start',
],
];
}
ExtensionManagementUtility::addTCAcolumns('tt_content', $columnFields);
// One palette per column: Align + Justify on a single row. The visible row
// label is overridden per container in its showitem (--palette--;<colLabel>;<palette>).
for ($i = 1; $i <= 4; $i++) {
$GLOBALS['TCA']['tt_content']['palettes']['vitec_col' . $i . '_flex'] = [
'showitem' => 'tx_vitec_col' . $i . '_align, tx_vitec_col' . $i . '_justify',
];
}
// Register VITEC wizard group header
$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'] = ($GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'] ?? '') . "\n" . <<<'TSCONFIG'
mod.wizards.newContentElement.wizardItems.vitec {