vitec_card: flipcard layout + card-back fields; shared-column repair

- layout_variant gains the value "flipcard" (onChange: reload)
- "Card Back" palette in the Layout tab directly below layout_variant:
  back_headline (Text, max 100) and back_text (Textarea, richtext),
  displayCond-gated on the flipcard layout; serialised unconditionally -
  the frontend keys the back face on layout_variant, not on field
  presence (spec 7.7)
- backend preview: flipcard badge + back-headline line
- repair "[ Missing label ]" in the card selects: layout_variant /
  background_variant are columns SHARED with vitec_ctabanner, and the
  index-wise Content Blocks merge dropped four card-only values from
  the base item list. Overrides/tt_content.php now pins the base column
  to the cta-banner lists and hands vitec_card its full lists via
  columnsOverrides (respected by FormEngine and DataHandler; an items
  override can only extend, never shorten - array_replace_recursive)
- spec v1.19 incl. head-matter fix (version table was stuck at 1.17)

Server follow-up: database:updateschema "*.add,*.change" + cache:flush

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
orascheandClaude Fable 5 committed 2026-09-25 12:16:16 +02:00
1 parent 43519505bc
commit 6db2234851
5 files changed
+123 -3

No files matched your search

@@ -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'],
];
})();
@@ -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
@@ -54,6 +54,19 @@
<source>If set, the whole card becomes clickable. Overrides individual CTAs visually in the frontend.</source>
</trans-unit>
<trans-unit id="back_headline.label">
<source>Back Headline</source>
</trans-unit>
<trans-unit id="back_headline.description">
<source>Headline on the reverse side of the card. Only used by the Flip Card layout.</source>
</trans-unit>
<trans-unit id="back_text.label">
<source>Back Text</source>
</trans-unit>
<trans-unit id="back_text.description">
<source>Text on the reverse side of the card. Only used by the Flip Card layout.</source>
</trans-unit>
<!-- ============================================================== -->
<!-- layout_variant -->
<!-- ============================================================== -->
@@ -84,6 +97,9 @@
<trans-unit id="layout_variant.items.compact.label">
<source>Compact (small card, tight spacing)</source>
</trans-unit>
<trans-unit id="layout_variant.items.flipcard.label">
<source>Flip Card (front / back)</source>
</trans-unit>
<!-- ============================================================== -->
<!-- background_variant -->
@@ -31,6 +31,7 @@
<f:case value="icon_card">✦</f:case>
<f:case value="feature">⭐</f:case>
<f:case value="compact">▫</f:case>
<f:case value="flipcard">🔄</f:case>
<f:defaultCase>▢</f:defaultCase>
</f:switch>
</div>
@@ -65,6 +66,10 @@
</div>
</f:if>
<f:if condition="{data.back_headline}">
<div class="vitec-preview__body-text">🔄 Back: {data.back_headline}</div>
</f:if>
<div class="vitec-preview__ctas">
<f:if condition="{data.primary_cta_label}">
<span class="vitec-preview__cta-btn">{data.primary_cta_label} →</span>
@@ -90,6 +95,7 @@
<f:case value="icon_card">✦ Icon Card</f:case>
<f:case value="feature">⭐ Feature</f:case>
<f:case value="compact">▫ Compact</f:case>
<f:case value="flipcard">🔄 Flip Card</f:case>
<f:defaultCase>{data.layout_variant}</f:defaultCase>
</f:switch>
</span>
@@ -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.*