26 Commits

Author SHA1 Message Date
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
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
5499ca54af Align product records with sitemap V2; product family model; CLI workbook import
- vitec:migrate-product-structure: exact V2 titles, Milestone typo fix (incl.
  slug), QTX100 stray VSN category removed, Aligo record moved to its own
  category with slug /product/aligo, new Aligo Workstation record takes over
  /product/aligo-workstation
- product families (sitemap column K) are ordinary content pages now:
  vitec:remove-family-records deletes the interim landing records again,
  reset_subproduct_flags.php clears the misused subproduct flag (the list
  renderer has always excluded subproduct=1)
- vitec:import-product-workbook: non-interactive counterpart of the module
  import (same reader, mapping and DataHandler path); Arqa imported, Aligo
  re-applied with the corrected capabilities markup
- ProductXlsxReader: new :copy cell selector (Body Copy with CTA fallback)
  absorbs the agency's column drift; default teaser mapping uses it
- ProductListJsonRenderer: selected categories now match their whole subtree,
  results ordered by category tree position, sheet order within a category
- read-only diagnostics: check_product_structure.php, check_productlist_ces.php
2026-09-04 12:59:17 +02:00
7442d10e68 SEO record links; story markets repair; story page titles
Kev's keyword CSV and TYPO3 hold the same solutions under slightly
different names, so the structure check filed them as missing/extra.
Matching is now slug -> normalized title -> record alias, using the
per-model alias store the import tabs got on 2026-08-18
(tx_vitec_import_mapping.record_aliases, key = lowercased CSV name).
One link therefore serves the import union list, the structure check
and vitec:create-markets (same service - linked rows are no longer
proposed as new records).

- every "Missing in TYPO3" row carries a select of all records the
  direct match did not claim; "Save record links" persists per model
- alias-matched rows show under "Both" with a "linked" badge and the
  same select; option 0 removes the link
- SeoResearchService::recordsCheck() additionally returns `linkable`
  (the select options) and flags alias matches with via=link
- new backend POST route seo_aliases

Success stories: --markets-only repair mode
- /success-stories emitted empty `markets` for all 48 stories - a data
  problem (code and TCA untouched since 17.08.); read-only diagnosis
  script migrations/check_usecase_markets.php added
- vitec:import-success-stories --markets-only re-derives each story's
  industries from the export exactly like the full import and rewrites
  ONLY the markets MM relation of the existing record via DataHandler;
  nothing else is touched, no usecase created or deleted, unresolved
  stories keep their current relations
- decision: industries are translated onto the nine main markets of
  the current taxonomy (INDUSTRY_TO_MARKET) instead of recreating the
  seven deleted industry markets; the repair mode never creates
  market records (root cause: those industry markets were deleted
  after the 07.08. taxonomy import, orphaning all story relations)
- ensureMarkets() gained a $create flag for reuse by the full import

Story detail pages: real page title
- every story page answered with the generic page title "Story"; same
  defect and same fix as the product pages on 21.08.: new
  UsecasePageTitleProvider (singleton), registered as vitecUsecase in
  config.pageTitleProviders, fed from UsecaseShowJsonRenderer with
  seo_title falling back to title

Requires on the server:
    vendor/bin/typo3 cache:flush
2026-08-26 19:48:43 +02:00
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
cf7a04ea15 Added Downloads to search index. 2026-08-21 15:44:03 +02:00
710f95794c Add Solr search: EXT:solr 14 integration and JSON search endpoint
Apache Solr 10 runs on a dedicated VPS behind a Caddy HTTPS proxy
(vitecsolr.evomedien.de) because the managed webserver only allows
outgoing standard ports. Credentials stay out of git: the site config
carries %env()% placeholders resolved via putenv() in the git-ignored
config/system/additional.php.

- composer: apache-solr-for-typo3/solr 14.0.0-RC1 (the only line
  compatible with TYPO3 14; final 14.0.0 will arrive via composer update)
- config.yaml: read connection https/443, core_en per language,
  env placeholder credentials; .gitignore covers additional.php
- setup.typoscript: config.index_enable = 1 (page indexing silently
  refuses without it), solr_pi_results JSON renderer registration,
  results highlighting, and content field extraction from tt_content
  rows - the headless JSON output has no TYPO3SEARCH markers, so the
  default page content extraction indexed an empty content field
- SearchJsonRenderer (renderer #27): JSON output for the search plugin
  on /search. GET q/page in; { query, page, resultsPerPage, numFound,
  totalPages, results[], suggestions } out. Disables the page cache per
  request: config.no_cache is gone in TYPO3 v14, and q/page are
  excluded from cHash, so cached variants would collide
- ext_localconf.php: q and page added to cacheHash excludedParameters
- SolrIndexCommand (vitec:solr-index): works the index queue from the
  CLI with connection diagnostics and a --debug single-step mode -
  EXT:solr 14 ships no console commands and the backend button indexes
  one item per click
2026-08-21 14:43:44 +02:00
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
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
58990ebe8d Add BG offset 2026-08-14 10:59:22 +02:00
c720696781 Add Container Options 2026-08-14 10:36:36 +02:00
8d3ac08a37 Updates 2026-08-13 12:49:10 +02:00
48da8bccd8 Solution detail page and a single LinkResolver
Closes two annex items that turned out to be the same defect seen from two
sides: markets could link to a detail page, solutions could not, and the code
that turns a page uid into a URL existed four times over.

detail_page for Solution (B-11)
- ext_tables.sql, TCA (group on pages, maxitems 1, in showitem behind slug)
  and Domain\Model\Solution mirror the Market field exactly
- SolutionShowJsonRenderer emits detailUrl
- ModelcardJsonRenderer serialized no detailUrl at all: its shared
  market|solution branch never carried the field. Market modelcards therefore
  gain a link here too, not just solutions.

Service\LinkResolver (B-12)
- one implementation replaces four private copies (Market list/show, Usecase
  list/show). The copies had drifted: Market returned null on failure, Usecase
  an empty string. The contract is now explicit -- null means "no link".
- Usecase keeps a thin resolvePageUrl() wrapper appending ?? '', because it
  concatenates paths and a null would tear the strings apart.
- LocationsJsonRenderer and NewsJsonRenderer stay out on purpose: they resolve
  a full parameter construct resp. slug paths plus canonical, which is not
  page-uid-to-URL and does not fit the same contract.

Requires on the server, the column exists in code only:
    vendor/bin/typo3 database:updateschema "*.add,*.change"
    vendor/bin/typo3 cache:flush
2026-08-10 15:27:16 +02:00
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
27cc22dc69 Markets List and Detail Plugin 2026-08-05 16:53:02 +02:00
a739dd8fe3 Formular-Infrastruktur: Contact/Demo/Helpdesk mit E-Mail- und Salesforce-Delivery, JSON-Renderer-Erweiterungen, Crop-Variants
Build-Artefakte in public/_frontend/assets nicht enthalten.
2026-07-30 13:12:45 +02:00
khaccount
eae40f4286 Success-story migration + new plugins + JSON/UX polish
- Success Stories: full migration from old site (48/48, audited),
  markets n:n, quotation content block, columns content block,
  pretty SEO detail URLs via SuccessStoryPathRewrite middleware,
  list/detail split (list page 4 / story page), detailUrl/backUrl
- New plugins: VITEC Locations (grid/list/map + RTE map text),
  VITEC Customer Logos (color/bw logic, only-show-selected),
  VITEC Card (one plugin for product/story/market/solution
  with reloading FlexForm + custom backend preview renderer)
- Eventlist: layout dropdown (list/grid/teaserbar) in settings
- Hero section CB: Images/Video tabs, background video + overlay
- Product JSON: full category rootline (parents), fixed missing
  ConnectionPool import (all-products crash), category tree map
- Backend preview CSS: container-query responsive (narrow columns)
- Docs: ISO architecture spec, root + extension READMEs

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 09:53:33 +02:00
khaccount
de8e3f55df Dev Commit 2026-07-09 10:10:05 +02:00
o-rasche
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
c6759186cb DEV CommiDEV Committ 2026-07-01 10:34:48 +02:00
khaccount
4541c58fe7 VITEC headless v14: 5-bug fix unifies plugin renderers + cleanup
Resolves a cascade of TYPO3 v14 breaking changes that left every VITEC
plugin's JSON output silently empty:

1. `list_type` column dropped — all renderer page-discovery queries now
   filter by `CType = 'vitec_X'`.
2. `#[AsAllowedCallable]` attribute added to every public render() —
   without it v14 throws AllowedCallableException, which headless
   silently filters via its "Oops, an error occurred!" guard.
3. `$GLOBALS['TSFE']->id` is null inside JSON cObj context — page id
   now read from the `frontend.page.information` request attribute
   (TSFE fallback kept for legacy entry points).
4. page.tsconfig wizard items migrated to `CType = vitec_X` directly
   (legacy `CType=list, list_type=...` no longer exists in v14).
5. ContainerChildrenProcessor + ContentElementResolver dispatch the
   PLUGIN_RENDERERS map by CType (primary) with list_type fallback.

Beyond the bug fix this commit also contains:
- Datasheets renderer rewritten to "products with newest datasheet"
  semantics (filtered via Download.hideondatasheets).
- New vitec/card content block — multi-purpose card with backend
  preview and layout/background/aspect/alignment/border/shadow options.
- New vitec_container CType (b13 single-column container, FlexForm
  cssClass propagated into the JSON envelope).
- ContentElementResolver service for contentelement/contentelementcta
  link resolution; ContainerChildrenProcessor for nested plugin
  resolution inside b13 containers.
- Vitecset setup.typoscript: ContentElement import moved to top so
  lib.contentElement is defined before VITEC's tt_content blocks.
- Cleanup: 98 .bak.<timestamp> debugging backups removed; *.bak.* and
  /public/_assets_install/ added to .gitignore.
2026-06-15 14:42:33 +02:00
o-rasche
3aaf8fdad5 VITEC headless v14: 5-bug fix unifies plugin renderers + cleanup
Resolves a cascade of TYPO3 v14 breaking changes that left every VITEC
plugin's JSON output silently empty:

1. `list_type` column dropped — all renderer page-discovery queries now
   filter by `CType = 'vitec_X'`.
2. `#[AsAllowedCallable]` attribute added to every public render() —
   without it v14 throws AllowedCallableException, which headless
   silently filters via its "Oops, an error occurred!" guard.
3. `$GLOBALS['TSFE']->id` is null inside JSON cObj context — page id
   now read from the `frontend.page.information` request attribute
   (TSFE fallback kept for legacy entry points).
4. page.tsconfig wizard items migrated to `CType = vitec_X` directly
   (legacy `CType=list, list_type=...` no longer exists in v14).
5. ContainerChildrenProcessor + ContentElementResolver dispatch the
   PLUGIN_RENDERERS map by CType (primary) with list_type fallback.

Beyond the bug fix this commit also contains:
- Datasheets renderer rewritten to "products with newest datasheet"
  semantics (filtered via Download.hideondatasheets).
- New vitec/card content block — multi-purpose card with backend
  preview and layout/background/aspect/alignment/border/shadow options.
- New vitec_container CType (b13 single-column container, FlexForm
  cssClass propagated into the JSON envelope).
- ContentElementResolver service for contentelement/contentelementcta
  link resolution; ContainerChildrenProcessor for nested plugin
  resolution inside b13 containers.
- Vitecset setup.typoscript: ContentElement import moved to top so
  lib.contentElement is defined before VITEC's tt_content blocks.
- Cleanup: 98 .bak.<timestamp> debugging backups removed; *.bak.* and
  /public/_assets_install/ added to .gitignore.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-15 14:29:17 +02:00
khaccount
64ea55d29d Work-Commit 2026-06-05 10:37:21 +02:00
o-rasche
409afc2433 VITEC headless: ContentElementResolver, Product fields (videofile, showdatapath)
- New Classes/Service/ContentElementResolver.php: parses TYPO3 typolink
  (t3://record?identifier=tt_content&uid=N, t3://page?uid=P#N, plain numeric)
  to a normalised tt_content envelope ({id,type,colPos,sorting,appearance,
  data}), recursively resolving any nested VITEC list-plugin children.
- ProductListJsonRenderer / ProductShowJsonRenderer: contentelement and
  contentelementcta now emit the resolved object instead of the raw
  typolink string (breaking change at those two keys).
- Product model: new field videofile (FAL, single video upload in tab
  Images and Videos, mp4/webm/ogv/mov/m4v); new bool field showdatapath
  (toggle at end of General tab, controls the "Datapath is now Vitec"
  graphic in the frontend). ext_tables.sql, TCA, model property +
  getter/setter, and both renderers updated accordingly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-05 10:34:49 +02:00
khaccount
dba154e572 Zwischenstand vom 29.05.2026 2026-05-29 11:14:02 +02:00
khaccount
b6d2142214 Initial Commit 2026-05-18 14:46:25 +02:00