Commit Graph
16 Commits
Author SHA1 Message Date
orasche 90ae6803a4 Backend of the sub-market template (spec agreed section by section with
the customer workflow in mind: the customer fills one XLSX per sub-market,
an importer builds the page).

- Frontend layout 21 'Sub-Market Page' in the existing
  BackendLayoutDataProvider: six zones, one per Figma section, emitted as
  colPos110..colPos160 - the JSON groups plus appearance.layout are the
  front-end contract (spec clause 7.17). A first attempt via page-TSconfig
  BackendLayouts was the wrong mechanism next to the provider and was
  removed again
- New Content Blocks vitec_markethero, vitec_marketintro,
  vitec_marketinsights (field bags, serialized unprefixed under data);
  the workflow section reuses intro-paragraph + vitec_card flip cards
- Stories gained quote/quote_person/quote_role (Testimonial tab),
  maintained once per story, emitted on every story card; usecaselist
  gained the layout value 'testimonials'
- New plugin vitec_productfeature: one referenced product as a full
  product card, serialisation shared with the product list (cObj made
  protected for the subclass)
- vitec_productlist gained hand-picked product selection: exactly the
  chosen products in the editor's order, category filter ignored,
  visibility filters kept - closes the long-standing single-select gap
- New CLI vitec:generate-submarket-workbooks: one protected customer
  XLSX per sub-market (9 main markets, 25 sub-markets from the Market
  category tree) - dropdowns filled live from the database, named ranges
  as the importer contract, hidden Meta sheet pinning submarket/group/
  record uid, soft character-limit warnings, asset URL fields

Verified end to end on Broadcast & Media: layout-21 payload with colPos110
carrying the hero element and its subline. Spec raised to v1.20.
2026-10-02 10:18:36 +02:00
orascheandClaude Fable 5 6db2234851 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>
2026-09-25 12:16:16 +02:00
orascheandClaude Fable 5 6811463343 Product texts: mapping completed; product model: solutions + resources
Two work packages, one deploy.

Workbook field mapping completed (2026-09-18)
- highlights <- g:Technical Highlight (new spec-row component of the
  full agency delivery; composeGroup() is generic, no change needed)
- applications <- g:Why Choose Card (benefit cards as one block)
- seometa <- new composed source x:seometa (Introduction body trimmed
  at a word boundary to ~155 chars - the SEO sheet ships no meta
  description, a trimmed intro beats an empty tag)
- teaser stays the hero one-liner, settling the varchar(255) question
- fix: "Save mapping" now merges over the stored mapping instead of
  overwriting it - an empty dropdown no longer wipes a stored selector

Product model: solutions relation and Resources tab (2026-09-24)
- closes the gaps the full workbook walkthrough exposed (rows the
  import deliberately skips because the model had no place for them)
- solutions: MM multi select to tx_vitec_domain_model_solution
  (tx_vitec_product_solution_mm, relatedprodukt pattern), emitted by
  both product renderers as solution cards in the shared shape
- Resources tab: inline child table tx_vitec_product_resource - per
  entry a type (documentation/support), an editable card title/text,
  an icon (free text with a value-picker seed set) and one link
  (page/url/file/record via the link wizard). Deliberately no Extbase
  model: only the UserFunc path reads the rows.
- datasheets: own MM selection of download records below the resource
  list (tx_vitec_product_datasheet_mm); emitted into the SAME
  resources envelope as ready-made type=datasheet cards (title/teaser/
  icon from the record, url = the public /download/<slug> route, uid
  fallback - private/hidden downloads 404 as everywhere)
- JSON `resources` (detail payload only, like heroimage): list envelope
  {layout, items[]}; a hand-written card whose link is empty or
  unresolvable is not emitted; layout switches to carousel above three
  cards in total
- solutions hybrid (same day, after analysing all 100 workbooks: their
  Solution Cards reference the 8 GROUPS in 98% of cases): new is_group
  flag on the solution model, new idempotent CLI
  vitec:create-solution-groups (8 group records; title source is
  AlignSolutionsCommand::TARGET - now public -, category = the group's
  own category, detail_page = the /solutions group page with -N
  disambiguation). Group records are invisible to the solution list
  and to vitec:align-solutions and only selectable in the product
  relation; product solution cards carry isGroup
- spec raised to v1.18 (7.15 member table, 7.13.3 note, revision row;
  the footer had been stuck at v1.15 since 1.16/1.17)

Requires on the server:
    vendor/bin/typo3 database:updateschema "*.add,*.change"
    vendor/bin/typo3 cache:flush

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-24 14:47:04 +02:00
orascheandClaude Fable 5 3df66b1353 Product texts: mapping completed; product model: solutions + resources
Two work packages, one deploy.

Workbook field mapping completed (2026-09-18)
- highlights <- g:Technical Highlight (new spec-row component of the
  full agency delivery; composeGroup() is generic, no change needed)
- applications <- g:Why Choose Card (benefit cards as one block)
- seometa <- new composed source x:seometa (Introduction body trimmed
  at a word boundary to ~155 chars - the SEO sheet ships no meta
  description, a trimmed intro beats an empty tag)
- teaser stays the hero one-liner, settling the varchar(255) question
- fix: "Save mapping" now merges over the stored mapping instead of
  overwriting it - an empty dropdown no longer wipes a stored selector

Product model: solutions relation and Resources tab (2026-09-24)
- closes the gaps the full workbook walkthrough exposed (rows the
  import deliberately skips because the model had no place for them)
- solutions: MM multi select to tx_vitec_domain_model_solution
  (tx_vitec_product_solution_mm, relatedprodukt pattern), emitted by
  both product renderers as solution cards in the shared shape
- Resources tab: inline child table tx_vitec_product_resource - per
  entry a type (documentation/support/datasheet), editable card title
  and text, an icon (free text with a value-picker seed set) and one
  link (page/url/file/record via the link wizard, so the Download tab
  works too). Deliberately no Extbase model: only the UserFunc path
  reads the rows.
- JSON `resources` (detail payload only, like heroimage): list envelope
  {layout, items[]}; a card whose link is empty or unresolvable is not
  emitted; layout switches to carousel above three cards
- spec raised to v1.18 (7.15 member table, revision row; the footer had
  been stuck at v1.15 since 1.16/1.17)

Requires on the server:
    vendor/bin/typo3 database:updateschema "*.add,*.change"
    vendor/bin/typo3 cache:flush

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-24 14:15:43 +02:00
orasche 55f7f82a42 Show success stories below the product lists, linked on the category
sys_category gains a story selection and a layout (Options tab, alongside
the images field EXT:news puts there), so one editorial decision serves
every product list that renders the category. ProductListJsonRenderer emits
them beside the products in the 7.3 list envelope; each card carries
forCategories - the product categories it came from - so the front end hides
it with the same ?cat=/?subcat= filter it applies to the products. Stories
are collected over the category and its descendants and deduplicated.

Story links follow the existing rule (detail page's parent path plus slug,
which SuccessStoryPathRewrite maps back), taking the page from the element's
FlexForm or the new site setting vitec.storyDetailPid.

Spec raised to 1.17 with clause 7.15.2.1; the header had been left at 1.12
although entries up to 1.15 already existed, so today's two entries were
renumbered to 1.16 and 1.17.
2026-09-11 15:28:32 +02:00
orasche 8c881d153c Index PDF and Office file contents via Apache Tika
Solr 10 dropped the ExtractingRequestHandler, so a dedicated Tika
container on the Solr VPS (Caddy route /tika/*, own basic-auth
credential; Tika itself has no auth) extracts file text during
indexing: TikaDownloadContentIndexer listens on
BeforeDocumentIsProcessedForIndexingEvent, resolves the file through
the existing DownloadFileResolver and appends the text (mime
whitelist, 30 MB cap, 100k chars, fail-soft) to the document's content
field. Extractions are cached in var/tika-cache keyed on
path+size+mtime - a full re-index of 177 downloads drops from 2:12 min
to 27 s, replacing a file re-extracts naturally. Datasheet
specifications ("625i", "genlock") are now searchable. Spec v1.15.
2026-09-11 13:15:05 +02:00
orascheandClaude Fable 5 fc3799c791 Add autocomplete endpoint via EXT:solr suggest page type
GET /search?type=7384&tx_solr[queryString]=<input> answers term
completions from the index (spell field) with document counts as lean
JSON - no page envelope, synonyms apply automatically. Two deliberate
deviations from the shipped example, which predates TYPO3 v14: the
plugin runs as USER_INT (config.no_cache is gone, and a cached USER
would pin the first query's suggestions for every later request), and
showTopResults is off (the top-result shape is hardcoded upstream with
the raw document type and full indexed content). Documented in spec
v1.12 clause 7.16.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-24 16:02:52 +02:00
orascheandClaude Fable 5 083f0937e2 Add type filter and facet counts to the search endpoint
The search JSON gains tab support: the new `filter` GET parameter
restricts results to one document type (product, news, download, story,
page, market); the response carries `filter` (active value or null) and
`facets.type` with per-type counts and active flags. Counts stay
complete while a filter is active (keepAllFacetsOnSelection), so tabs
never collapse - except on an empty filtered result, documented in spec
v1.12 clause 7.16.

The parameter is named `filter` because `type` is TYPO3's reserved
page-type parameter and crashes page resolution; like q and page it is
excluded from cHash validation. Facets come from EXT:solr's native
faceting, serialized generically by SearchJsonRenderer - a future
category facet only needs TypoScript.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-24 15:51:26 +02:00
orasche 7bd1161abf Product text import from agency XLSX workbooks
VITEC Import module: Products tab is now a searchable/sortable product
overview. "Edit Product" opens an XLSX upload with per-field source
mapping (component + cell), old/new preview and checkbox apply via
DataHandler; the mapping and manual matches are persisted and preselect
the next workbook. Category workbooks are detected and rejected.

- new: ProductXlsxReader (PhpSpreadsheet), ProductTextImportController,
  Products/ProductTexts templates, 4 module routes
- related products: per-pair card text in new side table
  tx_vitec_product_related_text (survives MM rewrites), emitted as
  `cardtext` in the product JSON; missing MM relations added add-only
- card copy read from Body Copy (D) with fallback to CTA/Card Copy (E) -
  the workbooks fill either depending on row type
- product detail page <title> now uses seotitle with title fallback
  (provider made singleton and fed from the JSON renderer)
- per-user recent-search badges; last loaded workbook stored per product
  (tx_vitec_product_workbook), Edit Product reopens on it
- composer: add phpoffice/phpspreadsheet ^5.9
- diagnostics: migrations/check_workbook.php
2026-08-21 11:00:45 +02:00
orascheandClaude Opus 5 12eb40614b 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>
2026-08-17 16:29:06 +02:00
orasche f515de54ad News und News-Pages Importer 2026-08-13 17:00:53 +02:00
orascheandClaude Opus 5 baa0fdd331 Import old-site downloads and add a type taxonomy
New CLI command vitec:import-downloads: reads the JSON export of the
old site (www.vitec.com/import), cuts it out of the surrounding page
template by brace counting, and imports the downloads idempotently by
slug. Scope is deliberately narrow: only files under
/fileadmin/downloads/Collateral/, records without title or file are
skipped, records sharing one file_url are merged. Files are fetched
resumably into fileadmin/downloads/Collateral/ and stored on pid 29.

Legacy filenames are normalized on fetch so every imported file
matches the <prefix>__<filetype>__<NN>-<letter> version convention:
__NN_A -> __NN-A, ___NN -> __NN, __NNA -> __NN-A, and a bare __NN
gets -A appended as its initial revision. Verified against the full
export: all 179 names match afterwards, none of the already-correct
ones change.

tx_vitec_domain_model_download gains a second category field "type"
(display taxonomy: Datasheet, Success Story, Brochure, Software) next
to the filename-driven filetype categories. No SQL change needed -
the core generates columns for category fields. The three download
renderers emit the field as a string analogous to filetype; MM rows
are distinguished by fieldname, existing queries filter on it and
remain unaffected.

Import values are matched via the custom columns sys_category.filetype
and .type (falling back to title); missing categories are created
(filetype under --category-parent, default 4; type under a "Download
Type" parent).

getDownloadFile() in the three download renderers gains a filepath
fallback (FAL -> convention -> filepath) as a safety net for any
future filename that escapes the convention - previously such records
emitted file: null.

Architecture spec bumped to v1.7.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 12:08:48 +02:00
orasche 27cc22dc69 Markets List and Detail Plugin 2026-08-05 16:53:02 +02:00
khaccount de8e3f55df Dev Commit 2026-07-09 10:10:05 +02:00
o-rascheandClaude Opus 4.8 bb7c03235d 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>
2026-07-09 10:01:56 +02:00
khaccount b6d2142214 Initial Commit 2026-05-18 14:46:25 +02:00