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:
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);
|
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
|
type: Select
|
||||||
renderType: selectSingle
|
renderType: selectSingle
|
||||||
default: vertical
|
default: vertical
|
||||||
|
# displayCond of the card-back fields depends on this value
|
||||||
|
onChange: reload
|
||||||
items:
|
items:
|
||||||
- label: Vertical (image top, content below)
|
- label: Vertical (image top, content below)
|
||||||
value: vertical
|
value: vertical
|
||||||
@@ -116,6 +118,27 @@ fields:
|
|||||||
value: feature
|
value: feature
|
||||||
- label: Compact (small card, tight spacing)
|
- label: Compact (small card, tight spacing)
|
||||||
value: compact
|
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
|
- identifier: background_variant
|
||||||
type: Select
|
type: Select
|
||||||
|
|||||||
@@ -54,6 +54,19 @@
|
|||||||
<source>If set, the whole card becomes clickable. Overrides individual CTAs visually in the frontend.</source>
|
<source>If set, the whole card becomes clickable. Overrides individual CTAs visually in the frontend.</source>
|
||||||
</trans-unit>
|
</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 -->
|
<!-- layout_variant -->
|
||||||
<!-- ============================================================== -->
|
<!-- ============================================================== -->
|
||||||
@@ -84,6 +97,9 @@
|
|||||||
<trans-unit id="layout_variant.items.compact.label">
|
<trans-unit id="layout_variant.items.compact.label">
|
||||||
<source>Compact (small card, tight spacing)</source>
|
<source>Compact (small card, tight spacing)</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="layout_variant.items.flipcard.label">
|
||||||
|
<source>Flip Card (front / back)</source>
|
||||||
|
</trans-unit>
|
||||||
|
|
||||||
<!-- ============================================================== -->
|
<!-- ============================================================== -->
|
||||||
<!-- background_variant -->
|
<!-- background_variant -->
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
<f:case value="icon_card">✦</f:case>
|
<f:case value="icon_card">✦</f:case>
|
||||||
<f:case value="feature">⭐</f:case>
|
<f:case value="feature">⭐</f:case>
|
||||||
<f:case value="compact">▫</f:case>
|
<f:case value="compact">▫</f:case>
|
||||||
|
<f:case value="flipcard">🔄</f:case>
|
||||||
<f:defaultCase>▢</f:defaultCase>
|
<f:defaultCase>▢</f:defaultCase>
|
||||||
</f:switch>
|
</f:switch>
|
||||||
</div>
|
</div>
|
||||||
@@ -65,6 +66,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</f:if>
|
</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">
|
<div class="vitec-preview__ctas">
|
||||||
<f:if condition="{data.primary_cta_label}">
|
<f:if condition="{data.primary_cta_label}">
|
||||||
<span class="vitec-preview__cta-btn">{data.primary_cta_label} →</span>
|
<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="icon_card">✦ Icon Card</f:case>
|
||||||
<f:case value="feature">⭐ Feature</f:case>
|
<f:case value="feature">⭐ Feature</f:case>
|
||||||
<f:case value="compact">▫ Compact</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:defaultCase>{data.layout_variant}</f:defaultCase>
|
||||||
</f:switch>
|
</f:switch>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
| | |
|
| | |
|
||||||
|---|---|
|
|---|---|
|
||||||
| **Document identifier** | EVO‑VITEC‑HL‑001 |
|
| **Document identifier** | EVO‑VITEC‑HL‑001 |
|
||||||
| **Version** | 1.17 |
|
| **Version** | 1.19 |
|
||||||
| **Status** | Released |
|
| **Status** | Released |
|
||||||
| **Date** | 2026‑09‑11 |
|
| **Date** | 2026‑09‑25 |
|
||||||
| **Applies to** | `evomedien/vitec` on TYPO3 v14.3 (headless) |
|
| **Applies to** | `evomedien/vitec` on TYPO3 v14.3 (headless) |
|
||||||
| **Owner** | evomedien — VITEC relaunch |
|
| **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.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.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.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,
|
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
|
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
|
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.
|
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 Forms
|
||||||
|
|
||||||
#### 7.8.1 Form plugin payload
|
#### 7.8.1 Form plugin payload
|
||||||
@@ -1478,4 +1500,4 @@ remediation.
|
|||||||
- Header convention — the uniform header section across CEs, plugins and containers.
|
- Header convention — the uniform header section across CEs, plugins and containers.
|
||||||
- `Configuration/Sets/Vitecset/setup.typoscript` — the single TypoScript entry point.
|
- `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.*
|
||||||
Reference in new issue
Block a user