diff --git a/packages/vitec/Configuration/TCA/Overrides/tt_content.php b/packages/vitec/Configuration/TCA/Overrides/tt_content.php
index 9333e7b..6cf163a 100644
--- a/packages/vitec/Configuration/TCA/Overrides/tt_content.php
+++ b/packages/vitec/Configuration/TCA/Overrides/tt_content.php
@@ -212,4 +212,57 @@ use TYPO3\CMS\Extbase\Utility\ExtensionUtility;
}
}
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'],
+ ];
})();
diff --git a/packages/vitec/ContentBlocks/ContentElements/card/config.yaml b/packages/vitec/ContentBlocks/ContentElements/card/config.yaml
index f275f16..5e263b6 100755
--- a/packages/vitec/ContentBlocks/ContentElements/card/config.yaml
+++ b/packages/vitec/ContentBlocks/ContentElements/card/config.yaml
@@ -99,6 +99,8 @@ fields:
type: Select
renderType: selectSingle
default: vertical
+ # displayCond of the card-back fields depends on this value
+ onChange: reload
items:
- label: Vertical (image top, content below)
value: vertical
@@ -116,6 +118,27 @@ fields:
value: feature
- label: Compact (small card, tight spacing)
value: compact
+ - label: Flip Card (front / back)
+ value: flipcard
+
+ # Card back - only shown when layout_variant = flipcard. displayCond needs
+ # the storage column (vitec_ vendor prefix); the JSON keys stay the plain
+ # identifiers back_headline / back_text and are emitted on EVERY card
+ # (empty when unset) - the frontend keys the back face on layout_variant.
+ - identifier: card_back
+ type: Palette
+ label: Card Back
+ description: Reverse side of the card. Only used (and only shown) when the layout variant is "Flip Card".
+ fields:
+ - identifier: back_headline
+ type: Text
+ max: 100
+ displayCond: 'FIELD:vitec_layout_variant:=:flipcard'
+ - type: Linebreak
+ - identifier: back_text
+ type: Textarea
+ enableRichtext: true
+ displayCond: 'FIELD:vitec_layout_variant:=:flipcard'
- identifier: background_variant
type: Select
diff --git a/packages/vitec/ContentBlocks/ContentElements/card/language/labels.xlf b/packages/vitec/ContentBlocks/ContentElements/card/language/labels.xlf
index 58b954d..d466654 100755
--- a/packages/vitec/ContentBlocks/ContentElements/card/language/labels.xlf
+++ b/packages/vitec/ContentBlocks/ContentElements/card/language/labels.xlf
@@ -54,6 +54,19 @@
If set, the whole card becomes clickable. Overrides individual CTAs visually in the frontend.
+
+ Back Headline
+
+
+ Headline on the reverse side of the card. Only used by the Flip Card layout.
+
+
+ Back Text
+
+
+ Text on the reverse side of the card. Only used by the Flip Card layout.
+
+
@@ -84,6 +97,9 @@
Compact (small card, tight spacing)
+
+ Flip Card (front / back)
+
diff --git a/packages/vitec/ContentBlocks/ContentElements/card/templates/backend-preview.html b/packages/vitec/ContentBlocks/ContentElements/card/templates/backend-preview.html
index 7160094..55636c9 100755
--- a/packages/vitec/ContentBlocks/ContentElements/card/templates/backend-preview.html
+++ b/packages/vitec/ContentBlocks/ContentElements/card/templates/backend-preview.html
@@ -31,6 +31,7 @@
✦⭐▫
+ 🔄▢
@@ -65,6 +66,10 @@
+
+
🔄 Back: {data.back_headline}
+
+
{data.primary_cta_label} →
@@ -90,6 +95,7 @@
✦ Icon Card⭐ Feature▫ Compact
+ 🔄 Flip Card{data.layout_variant}
diff --git a/packages/vitec/Documentation/Headless-JSON-Architecture.md b/packages/vitec/Documentation/Headless-JSON-Architecture.md
index b885fea..8265b94 100755
--- a/packages/vitec/Documentation/Headless-JSON-Architecture.md
+++ b/packages/vitec/Documentation/Headless-JSON-Architecture.md
@@ -3,9 +3,9 @@
| | |
|---|---|
| **Document identifier** | EVO‑VITEC‑HL‑001 |
-| **Version** | 1.17 |
+| **Version** | 1.19 |
| **Status** | Released |
-| **Date** | 2026‑09‑11 |
+| **Date** | 2026‑09‑25 |
| **Applies to** | `evomedien/vitec` on TYPO3 v14.3 (headless) |
| **Owner** | evomedien — VITEC relaunch |
@@ -31,6 +31,7 @@
| 1.16 | 2026‑09‑11 | **New plugin** `vitec_productfinder` (`ProductFinderJsonRenderer`, payload key `productfinder`): the product category hierarchy on its own, as the data source for the filter selects above the product lists (7.15.3, 8). No change to `vitec_productlist` — filtering happens client side over the products already delivered, keyed on the category uids this payload carries. |
| 1.17 | 2026‑09‑11 | **Interface change (additive).** The product list payload gained `successStories` (7.15.2.1): stories an editor attaches to a `sys_category` (tab *Options*, with its own layout), emitted in the list envelope beside `products`. Each card carries `forCategories` — the product categories it came from — so the front end can hide it with the same `?cat=`/`?subcat=` filter it applies to the products. Story links reuse the 7.5 rule, with the detail page taken from the element or the new site setting `vitec.storyDetailPid`. |
| 1.18 | 2026‑09‑24 | **Interface change (additive).** Products gained `solutions` — an MM relation to solutions, emitted as solution cards in both product payloads — and a **Resources tab**: child table `tx_vitec_product_resource` with documentation / support cards (editable title, text and icon around one link, resolved per 9.12; cards without a resolvable link are not emitted) plus a `datasheets` MM selection of download records rendered into the same envelope as `type: datasheet` cards, delivered detail‑only as the `resources` list envelope whose `layout` switches to `carousel` above three cards in total (7.15). The `solutions` relation accepts group‑level records: the eight groups exist as `is_group = 1` solutions (created by `vitec:create-solution-groups`, excluded from lists and from `vitec:align-solutions`) because the agency workbooks reference the group level. Editorial: the footer had been stuck at v1.15 since 1.16/1.17 (2026‑09‑11). |
+| 1.19 | 2026‑09‑25 | **Interface change (additive).** The `vitec_card` Content Block gained the `layout_variant` value `flipcard` and a *Card Back* palette: `back_headline` (string, max 100) and `back_text` (richtext → HTML). The two fields are `displayCond`‑gated on the flipcard layout in the backend but serialised unconditionally (7.7) — the front end **shall** key the back face on `layout_variant`, never on field presence, because stored back values persist when an editor switches the layout away. Backend repair: `vitec_layout_variant` / `vitec_background_variant` are shared with `vitec_ctabanner`, and the index‑wise Content‑Blocks merge had dropped four card‑only select values (“Missing label”) — per‑type item lists now come from `columnsOverrides` (7.7); the Card‑Back palette lives in the Layout tab below the variant select. Editorial: the head‑matter version had been stuck at v1.17 since 1.18. |
This document is drafted in the style of, and adopts the terminology conventions of,
ISO/IEC/IEEE 42010 (architecture description), ISO/IEC/IEEE 26514 (information for
@@ -564,6 +565,27 @@ upper‑case preset would store one colour under two spellings. A block can ther
a background by **two** mechanisms — this field and the `vitec-bg-*` frame classes. The
precedence between them is a front‑end decision and is deliberately not fixed here.
+**Card flip layout (since v1.19).** `vitec_card` carries the additional `layout_variant`
+value `flipcard` together with a *Card Back* palette: `back_headline` (string, max 100)
+and `back_text` (richtext → HTML per 9.11). Both fields are serialised by the
+auto‑serialiser on **every** card — empty strings when unset — so a front end **shall**
+render the back face only when `layout_variant` equals `flipcard`, never keyed on the
+mere presence of the fields: an editor may switch a filled flip card to another layout,
+and the stored back values persist. In the backend the two fields are gated by
+`displayCond` on the flipcard layout (the select reloads the form via `onChange`);
+the palette sits in the **Layout** tab directly below `layout_variant`.
+
+Beware: `layout_variant` and `background_variant` are **columns shared with
+`vitec_ctabanner`** (same identifier under the vendor prefix). Content Blocks merges
+diverging item lists of such a shared select **index‑wise** into the base column —
+four card‑only values simply did not exist as items (“[ Missing label ]” in the
+backend). Since v1.19 `Configuration/TCA/Overrides/tt_content.php` pins the base
+column to the shorter cta‑banner lists and hands `vitec_card` its full lists through
+`columnsOverrides`, honoured by FormEngine **and** DataHandler. Because that per‑type
+merge is `array_replace_recursive`, an items override **shall** be at least as long as
+the base list — and a new block **shall not** reuse these identifiers with diverging
+items; prefix instead, as `hero_layout_variant` / `intro_layout_variant` already do.
+
### 7.8 Forms
#### 7.8.1 Form plugin payload
@@ -1478,4 +1500,4 @@ remediation.
- Header convention — the uniform header section across CEs, plugins and containers.
- `Configuration/Sets/Vitecset/setup.typoscript` — the single TypoScript entry point.
-*End of document EVO‑VITEC‑HL‑001 v1.18.*
+*End of document EVO‑VITEC‑HL‑001 v1.19.*