Unify list plugins, add solution list and per-story detail page

- vitec_usecaselist: layout + record selection like marketlist
- new plugin vitec_solutionlist (spec 7.13.3, key "solutions")
- tx_vitec_domain_model_usecase: detail_page -> resolved detailUrl
  (also gives story cards in vitec_modelcard a link for the first time)
- "Show Toolbar" checkbox on product/market/solution/usecase lists
- spec bumped to v1.9

BREAKING: vitec_productlist and vitec_usecaselist now emit an object
instead of a bare array. Consumers must read products.products and
usecases.usecases. Also found: productlist had a configurable layout
that was never serialised; it is emitted now, but keeps its own 0-3
vocabulary instead of grid/list/carousel.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-17 16:29:06 +02:00
parent 4ef3ad0026
commit 12eb40614b
23 changed files with 559 additions and 28 deletions

View File

@@ -3,9 +3,9 @@
| | |
|---|---|
| **Document identifier** | EVOVITECHL001 |
| **Version** | 1.8 |
| **Version** | 1.9 |
| **Status** | Released |
| **Date** | 20260813 |
| **Date** | 20260815 |
| **Applies to** | `evomedien/vitec` on TYPO3 v14.3 (headless) |
| **Owner** | evomedien — VITEC relaunch |
@@ -22,6 +22,7 @@
| 1.6 | 20260806 | **Interface change (additive):** `tx_vitec_domain_model_download` gained a second category field `type` (display taxonomy; MM rows distinguished by `fieldname`), emitted as the string `type` in the downloadcard, downloadcardcollection and datasheets payloads — analogous to `filetype`. New CLI command `vitec:import-downloads` migrates the oldsite downloads (Collateral directory only; idempotent by slug; files fetched resumably; duplicate `file_url`s merged). |
| 1.7 | 20260806 | **Robustness:** the import normalizes legacy filenames on fetch so every imported file matches the version convention (`__NN_A``__NN-A`, `___NN``__NN`, `__NNA``__NN-A`, bare `__NN``__NN-A` as initial revision), and the three download renderers gained a `filepath` fallback in `getDownloadFile()` (FAL → convention → filepath) as a safety net for anything that still escapes it. Extends the B4 duplication (three copies of the fallback) — consolidation target remains a shared fileresolver service (10.2). |
| 1.8 | 20260813 | **Defect fix and interface change (additive).** Content Blocks never carried the Core *Appearance* tab: `layout`, `frame_class` — including the VITEC frame classes — `space_before_class`, `space_after_class`, `sectionIndex` and `linkToTop` were unreachable for editors on all nine blocks. Added centrally for every `vitec_*` type (7.7); the `appearance` envelope is unchanged, its values were merely always default. Side effect: those six columns now also appear raw inside `data` on toplevel blocks (B13), and `appearance.layout` is represented differently on the two envelope paths (B14). `intro-paragraph` gained `background_color` (7.7). `vitec_eventlist` gained the layout `regions`, emitting a `regions` array built from the region categories below parent 104; the event payload is specified for the first time (7.14). B11 and B12 recorded as resolved. |
| 1.9 | 20260815 | **Interface change, partly breaking.** The four list plugins were unified: every one of them now emits an object carrying `layout`, the new `showToolbar` flag and its payload array. `vitec_usecaselist` and `vitec_productlist` previously emitted a **bare array** — front ends reading them have to move one level down (7.3, 7.14, 8). New plugin **`vitec_solutionlist`** (`SolutionListJsonRenderer`, key `solutions`), the counterpart 7.13.2 had been asking for since v1.2. `tx_vitec_domain_model_usecase` gained `detail_page`, emitted as the resolved `detailUrl` in the story card shape and therefore also in the `vitec_modelcard` story branch, which had carried no link at all until now. Noted: `vitec_productlist` had a configurable `layout` that was never serialised, and its vocabulary (`0``3`) differs from the other lists. |
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
@@ -383,10 +384,27 @@ a lean variant of the envelope:
### 7.3 Payload keys
| Kind | Key | Cardinality |
|---|---|---|
| List plugin | plural noun (`products`, `usecases`, `news → items`) | array |
| List plugin | plural noun (`products`, `usecases`, `markets`, `solutions`, `news → items`) | **object** (see below) |
| Detail plugin | singular noun (`product`, `usecase`, `market`, `solution`) | object |
| Container | `items` | array of `{config, contentElements}` |
**List envelope (since v1.9).** The four record list plugins — `vitec_productlist`,
`vitec_usecaselist`, `vitec_marketlist`, `vitec_solutionlist` — share one shape:
```jsonc
{ "layout": "grid", // display variant, see the note below
"showToolbar": false, // render the toolbar above the list
"<plural>": [ ] } // products | usecases | markets | solutions
```
`vitec_usecaselist` and `vitec_productlist` emitted a bare array before v1.9; a consumer has
to read `<key>.<key>` now. `layout` uses `grid | list | carousel | 50-50` everywhere **except**
`vitec_productlist`, which keeps its own `0``3` ("Default", "Variation 13") — unifying it
would move existing content onto a different layout and needs a migration, so it was left
alone.
`news_*` is not part of this: it keeps its own `{mode, items|news, settings}` envelope (7.6).
### 7.4 Container payload
```jsonc
{
@@ -761,8 +779,23 @@ in v1.3 on the assumption that lists only need `teaser`, which turned out to be
practice. Image resolution is delegated to `UsecaseSerializer::image()` per 9.2; this
renderer duplicates no FAL logic.
A Solution list counterpart does not exist yet. When it is added it **should** reuse this
shape under `content.solutions`.
#### 7.13.3 Solution list payload (`vitec_solutionlist`)
Added in v1.9, and deliberately the same shape as 7.13.2 — `SolutionListJsonRenderer` emits
under `content.solutions`:
```jsonc
{ "layout": "grid", "showToolbar": false,
"solutions": [
{ "uid": 7, "title": "…", "slug": "…", "subtitle": "…", "teaser": "…",
"description": "<p>…</p>", // RTE HTML, resolved per 9.11
"detailUrl": "/solutions/iptv/", // from the record's detail_page; null when unset
"image": { "url": "…", "srcset": [ ] } } ] }
```
Selection and ordering follow 7.13.2 exactly: nothing selected means all visible solutions
alphabetically, a selection means precisely those in the arranged order.
`tx_vitec_domain_model_solution` has **no `sorting` column** either, which is why the
unselected case falls back to alphabetical rather than to a backenddefined order.
### 7.14 Event list payload (`vitec_eventlist`)
`EventlistJsonRenderer` emits, under `content.eventlist`:
@@ -834,6 +867,7 @@ remaining present in `events`.
| `vitec_usecaselist` | `< lib.…WithHeader` | UsecaseListJsonRenderer → **UsecaseSerializer** | `usecases` | list |
| `vitec_usecaseshow` | `< lib.…WithHeader` | UsecaseShowJsonRenderer → **UsecaseSerializer** | `usecase` | detail |
| `vitec_marketlist` | `< lib.…WithHeader` | MarketListJsonRenderer | `markets` | list (global) |
| `vitec_solutionlist` | `< lib.…WithHeader` | SolutionListJsonRenderer | `solutions` | list (global) |
| `vitec_marketshow` | `< lib.…WithHeader` | MarketShowJsonRenderer | `market` | detail |
| `vitec_solutionshow` | `< lib.…WithHeader` | SolutionShowJsonRenderer | `solution` | detail |
| `vitec_downloadcard` | `< lib.…WithHeader` | DownloadcardJsonRenderer | `downloadcard` | detail |