- Site set Vitecset: new bool setting vitec.ssr.enabled (default off,
backend switch under Site Management > Settings > VITEC Settings)
- SsrFlagService derives var/vitec-ssr-on.flag from the setting;
SyncSsrFlag middleware (frontend + backend) re-syncs per request
because TYPO3 v14 fires no event on site settings save;
vitec:ssr-flag CLI command for status/--sync
- public/.htaccess: flag-gated block proxies page requests [P] to
https://vitec-ssr.evomedien.de (mod_proxy incl. https target verified
on this host 2026-11-09), same exclusions as the SPA fallback block;
completely inert while the flag file is absent
- Emergency off without TYPO3: delete var/vitec-ssr-on.flag
- Tested end to end: flag on -> pages proxied to VPS Caddy (502 while
the SSR node is not deployed yet), /_json untouched; flag off ->
SPA shell exactly as before
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The 2026-11-02 menu build created the 3 categories and 9 sub-categories
as sysfolders (labels); every level must be a clickable page.
- build-product-overviews: six sub-categories adopt the 2026-10 category
pages (Joe's workbooks; content, slug and SEO kept, sitemap name as
nav_title), the remaining folders become pages with generated content,
Capture & Graphics gets the main column of Graphics & Multi-Display and
Video Capture copied in. Pages move/convert by direct UPDATE (the
redirects slug hook would rewrite the flat child slugs); three 2026-10
pages leave the menus but stay reachable. Warns about a sys_redirect
on a target slug.
- ProvideProductCatalog: categories[].link and groups[].link (additive),
menu title = nav_title when set, only filled groups/categories count.
The menu search reads both levels as pages too.
- build-why-vitec-bands: band at the top of the main column; on pages
with an existing "Why VITEC?" section the context's icons go onto the
cards whose title matches the icon theme (16 icons on 4 pages).
- No browser cache headers on the page JSON: headless enables
sendCacheHeaders and TYPO3 14 caches pages for a year by default, so
every /_json/ response carried max-age=~31536000.
- Spec v1.32.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Megamenu entries with the catalog or spotlight layout get two editor
fields, "Data source folders" (source_pages) and "Data source
categories" (source_categories); the extension stores them, the site
package's listener reads them from the entry row.
- ProvideInsightsSpotlight reads its news from those folders (empty =
11 + 442; the newer posts live in 442, the query only read 11) and,
when set, only from those categories (Insights: Blog Post + Press
Release). Newest datetime first, three cards.
- Pages carrying the menu are tagged with the news and event tables, so
saving such a record refreshes the menu without a cache flush.
- VITEC field descriptions via a TCA override; spec v1.31, README.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- new migration fix_why_band_position.php: on the 7 overview pages the
band (Why VITEC? intro + icon cards) had landed between the "Product
range" heading and its product cards; reorders the top-level column
to hero -> band -> Product range -> cards (ticket 0042-FE section 3)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- new "Features" column: check with cards-and-icons count per product
(e.g. "5·4i"), header carries the filled total like the other columns
- detail pane lists every feature card with icon thumbnail (click to
enlarge), title and text; cards without an icon show a red cross on
the icon slot - the missing agency icon sets are visible at a glance
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- token-containment pass: theme words inside the card title
(ManagementFoundation -> "Aetria management foundation")
- last-pair rule: a complete set (#icons == #cards) with exactly one
icon and one card left over pairs them (FlexibleConnection,
EndToEndEncryption, HighPerformance, 4KSourcetoDisplays, AVoverIP)
- genuine mismatches (aligo-workstation, EZ-TV Platform, AvediaPlatform
Artio icons) still stay unmatched for the editors
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- new inline table tx_vitec_product_feature (title, cardtext, FAL icon)
+ `features` field on the product record; ProductShowJsonRenderer
emits product.features {heading, items[{title, text, icon}]} and null
while a product has no cards, so the front end keeps its
applications-HTML fallback
- new vitec:seed-product-features: seeds the cards from the
applications <p><strong> pairs and matches the staged agency icons by
normalised title (camelCase split, stop words, Levenshtein <= 3 typo
tolerance); products with existing cards are never touched
- new vitec:build-why-vitec-bands: "Why VITEC?" intro + icon_card band
on the 7 overview pages with a staged icon set (the contract's
"centered" variant does not exist - documented in ticket 0039-BE);
vision/visionav sub-group sets stay unassigned
- product-check page: sortable title column and an Open Product button
- new migration fix_colombia_quote.php: stray quote element #12037
removed, quote_role set (ticket 0038-FE)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The agency "Products Hero page" delivery (banners, product photos) is
staged per product slug under migrations/product_images_in2/ and
imported with the existing vitec:import-product-images command;
the staging directory stays out of the repo like product_images_in/.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Standalone PHP page (public/product-check/index.php), deliberately NOT a
plugin so the React front end needs no counterpart. Reads fresh from the
DB on every request (settings.php PDO pattern):
- alphabetical table of all products, header row with 14 field columns
(hero/photos/og/video, the text fields, resources/datasheets/solutions),
green check with count / red cross per cell, filled-count per column
- every row expands to a detail pane: all texts rendered, all images as
thumbnails with a click-to-enlarge lightbox, relations resolved
(inline resources, datasheet/solution MM), flags, detail page link
- refresh button reloads with a cache buster; noindex + no-store;
refuses to serve on www.vitec.com
The static badge view (migrations/build_product_audit.php ->
/product-audit/) stays as is.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Standalone PHP page (public/product-check/index.php), deliberately NOT a
plugin so the React front end needs no counterpart. Reads fresh from the
DB on every request (settings.php PDO pattern):
- alphabetical table of all products, header row with 14 field columns
(hero/photos/og/video, the text fields, resources/datasheets/solutions),
green check with count / red cross per cell, filled-count per column
- every row expands to a detail pane: all texts rendered, all images as
thumbnails with a click-to-enlarge lightbox, relations resolved
(inline resources, datasheet/solution MM), flags, detail page link
- refresh button reloads with a cache buster; noindex + no-store;
refuses to serve on www.vitec.com
The static badge view (migrations/build_product_audit.php ->
/product-audit/) stays as is.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The vitec/herosection content block has prefixFields - the real column
and sys_file_reference fieldname is vitec_hero_bgimage; the JSON merely
strips the prefix. The first apply wrote the 20 references with the bare
name, so they existed but never rendered (no herosection anywhere had an
image, so there was no working example to catch it against).
- BuildProductOverviews: attach/backfill/skip-check now use
vitec_hero_bgimage
- new migration fix_overview_hero_refs.php: renames the existing 20
references in place (no re-attach) and sets the counter column
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Page-tree entries get a "Page tree display" field (columns | rail |
rail-compact), emitted as display + cardSize: Markets and Solutions
show their main pages as a list and the sub-pages as image cards on
hover. Page-tree items carry image (page media) and teaser (abstract)
from stage 2. Additive; front ends ignoring display render columns.
- vitec:attach-page-media gains --depth=2 and falls back to the page's
hero background before the grey placeholder; the 39 sub-solution
pages got their hero image as page media.
- MegamenuJsonRenderer tags every page carrying the menu with the menu
tables and tt_content_<uid>, so saving menu records refreshes all
pages instead of waiting for a full flush.
- Products catalog: drop catalog.news; both promo boxes ("Product
highlight", "Product news") are the entry's editorial teaser cards.
ProvideInsightsSpotlight back to its previous state.
- Spec v1.29 and v1.30 (header version corrected), README.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rebuild the product section after the agency sitemap and menu prototype
of 2026-11-02:
- vitec:build-product-overviews builds sysfolder labels (3 categories,
9 groups) below /products with 20 overview pages /products/<slug>
(layout 9: hero, intro per group, product cards, contact CTA) and two
menu shortcuts. Dry-run by default, idempotent, explicit sorting.
- ProvideProductCatalog reads that page tree and emits catalog version 2:
categories[].groups[].items[] of type page (productCount, products,
image) or shortcut (target indices), plus viewAll, news and search.
- Transitional v1 fields (groups[].products/link/uid, categories[].uid/
link, product teaser) keep the deployed front end alive; it read the
v1 shape and rendered a white page without them. Remove once the
front end reads items.
- ProvideInsightsSpotlight::latestNews() is public with a count.
- Product type-ahead (type 7385) adds matching overview pages and a
per-product overview with its menu path.
- Spec v1.28.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The Resources Section Layout select gained a third value, hardware
("Layout 3 - Hardware option"): Technical Highlights spread over two
columns, no resource cards
- ProductShowJsonRenderer::resourcesBand() emits the same envelope with
items: [] for hardware even when cards are maintained, so the cards
stay on the product and reappear when switching back to layout 1 or 2
- Spec v1.27 (resources.sectionLayout values)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- comparison report migrations/check_product_downloads.php (kept,
read-only): download records vs. the delivered product workbooks -
34 of 74 workbook products have a datasheet, the entire Datapath
line has none in the pool (import came from vitec.com; queued for
Joe), ~35 orphan datasheets belong to products without records;
a vitec:link-product-downloads re-run added seven clean links
(Artio x2, Diamond-H, the three TOUGH records, X-View)
- RTE resolution fixed at the root: ContentElementResolver and
ContainerChildrenProcessor passed bodytext RAW into the payload, so
t3:// links leaked unresolved; both now run RTE columns (bodytext,
vitec_quote) through RteResolver::html()
- the imported "Download Success Story" RTE buttons carried the wrong
link identifier (tx_vitec_download -> download, one-time migration
fix_download_record_links.php) AND old-site uids - missing here or,
worse, accidentally pointing at foreign PDFs. New
vitec:convert-story-download-buttons replaces them with real
vitec_downloadcard plugins: the download is resolved by STORY title
(manual map for ISR / "Okada Manilla", exact-title fallback for
suffixless PDFs like "Lord's Cricket Ground"); 29 converted, 4
stories without a delivered PDF have their button hidden. New
FlexForm layout "Success Story Download" (story_download) applied
everywhere; the FE renders it as the previous centered button
- the ADIB "Featured Products" text section (the only one site-wide,
verified by scan_story_headers.php) is now ONE vitec_productlist
with hand-picked products via old-name aliases and the new FlexForm
layout "Success Story Products" (story_products); the four text
elements are deleted. vitec:convert-story-product-sections stays
re-runnable for future imports
- the productlist envelope additionally carries "columns" (= number
of products, capped at 4) so the story grid renders as many columns
as it has products - additive key, available to every product list;
and hand-picked lists now ship successStories as an empty array (the
empty category selection used to aggregate stories over the WHOLE
tree, leaking story cards into the section)
- the story downloadcards carry header "Downloads" (set on convert
and backfilled): the front end builds the story anchor nav from
element headers, so the section now appears there
- diagnosis scripts kept: check_download_record, check_story_elements,
scan_story_headers; verified live on the ADIB payload (structured
download object, productlist [5,18,6], texts 10 -> 5)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- diagnosis first (migrations/check_old_stubs.php, kept): the six
old-taxonomy pages (#451-454, #456, #458) were completely empty - no
content elements and NO family child pages (the family workbooks were
deliberately never imported), so nothing needed moving
- migrations/retire_old_category_stubs.php (dry-run by default, guards
against children/content) soft-deletes each stub and queues a 301
sys_redirect onto its new-taxonomy equivalent; existing redirects for
a path are kept
- applied and verified live: all six old paths answer with the 301
redirect envelope onto the correct new category page, and the main
navigation now shows exactly the nine new categories in sitemap order
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the freshly attached card images did not show: text_only is the
explicit no-image variant, so vitec:attach-card-images now flips a
card to "vertical" whenever it carries (or receives) an image; and
the new placeholder PNGs sat in the sshfs 770 trap - fix-asset-perms
covers them, with public/product-audit added to its targets
- new generic vitec:wrap-cards-grid --page=<slug>: wraps a page's cards
into vitec_cols_33_33_33 containers (b13 columns 221/222/223), three
per container, section-aware - every top-level intro paragraph starts
a section, other element types close it, so the category headings on
/products keep their grids beneath them. Existing grid containers are
pooled and reused, surplus ones hidden
- the first apply aborted mid-move and left a half state (15 empty
shells, three cards moved; diagnosis migrations/check_grid_447.php,
kept) - v2 repairs such states by design: global container pool,
hard asserts after the create pass, try/catch around the move pass,
and a final "no card left top-level" verification
- applied on /products and verified live: 38 cards in 15 grids
(sections 5/7/3/6/2/4/2/6/3 -> 2/3/1/2/1/2/1/2/1 containers), order
intro -> grids -> banner -> faq intact, children delivered in the
known items/contentElements shape
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- new vitec:attach-card-images (dry-run by default) for the ~145
vitec_card elements the 2026-10-27 workbook imports created across
/products, /insights, /support and /contact: a card linking
/product/<slug> gets the record's first product photo (hero banner
as fallback), every other card gets the numbered placeholder
placeholders/pages/<pid>-NN.png counted from slot 10 in card order
per page (slots 01-04 and 08 are taken by the page conventions; the
number doubles as the image wish list towards the agency). 110
placeholder PNGs (640x480) were generated from the live payloads so
the numbering is deterministic; cards that already carry an image are
never touched but keep advancing the counter, so re-runs stay stable
- container children are included: the editor had arranged the /support
cards into a grid container (colPos 221-223/251), which the first
top-level-only query skipped
- applied and verified live: 42 product photos, 110 numbered
placeholders, 18 generic grey cards - the grey ones map the records
without any image at all (ArtioSign, ArtioView, Arqa, the Aetria
family, Wall Control 10, X-Series; all Datapath software without an
image delivery, queued for Joe)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- new vitec:build-product-portfolio (dry-run by default): hero, nine
category sections (intro paragraphs with the exact sitemap H2s and
Learn-more buttons onto the new category pages), 38 product cards
with record-first link resolution (30 resolved; the 8 open record
gaps stay reported), a Case Studies & Events banner (midnight,
success stories / events), ONE vitec_faq accordion whose four
questions are created as vitec_faq_items collection children
(field names probed against the schema at runtime), and the orange
prefooter banner (contact / solutions); full page properties and
page layout 0 -> 1 "Index Page"
- diagnosis first (new read-only migrations/check_products_page.php
and check_products_page2.php): the dry run reported zero legacy
elements although the payload rendered ~40 - every own element of
page 447 was already soft-deleted, the visible rendering came from
the "Collection Product Infos" compose page. Building in place was
therefore safe; unconsumed visible legacy would have been hidden,
not deleted
- side finding, left open on purpose: six old-taxonomy category stubs
(#451-454, #456, #458) still sit visible under /products with the
family pages beneath them - hide/move/redirect is an editorial
decision queued for Olli
- applied and verified live (hero, 9 category buttons, 30 card links,
4 FAQ items, both banner CTA pairs, meta)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- new vitec:create-missing-products: MGW Diamond TOUGH, MGW Pico TOUGH,
MGW Pico+ TOUGH and X-View Integrated Displays as visible records
(teaser drafts, pid and sys_category assignments copied from the
sibling product; titles equal the Dropbox folder names so the image
importer matches immediately). IQS4 stays out - its delivery folder
is empty, question to Joe
- asset re-run via vitec:import-product-images after re-staging the
Dropbox delivery (the misfiled Diamond-OG banner corrected into the
OG inbox folder again): new photos for 95-Series, Avedia chassis,
SFF PRISM and the new TOUGH/X-View records
- new migrations/build_product_audit.php: generates the internal
product-asset audit at /product-audit/ (same basic auth, same-origin
thumbnails) - one row per record with thumbnail, detail link, badges
for hero/photos/texts/resources/datasheets/solutions, flags, stats
and client-side filters; re-run any time
- new vitec:import-product-category-pages: builds the nine
/products/<category> pages (frontend layout 9, hero/main/preFooter)
from the agency "Product Category Pages" workbooks - intro
paragraphs, Why-VITEC / product / solution cards, the comparison
rows as ONE text element with a plain table (no comparison CType
exists; FE styles it), prefooter banner to /contact, full page
properties, page sorting per sitemap 3.1-3.9; the empty shells #455
and #457 are reused. Product card links resolve record-first (exact
title, stripped parenthesis, family alias, unique slug prefix);
ProductFamilyAliases gains ten category-level family labels. Solution
cards tolerate US/UK spelling (center/centre, visualization/
visualisation). Applied and verified live (nine routes, links,
tables, meta)
- known gaps reported, queued for Joe: IQS4, Media Players (93/94),
Chassis Systems, Express Backplanes, Accessories & Cables, PCIe
Encoders, VMS Plugins & Integrations; the Vision family card awaits
a flagship decision
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- getMenu() treats hidden/time/fe_group as enable fields but NOT
nav_hide - the treeColumns doc comment claimed otherwise, and the
news detail page ("article") stayed in the new spotlight rail after
the editor hid it in menus. All three getMenu() calls (spotlight nav,
pagetree columns and their items) now pass 'AND nav_hide = 0';
verified live (6 rail items)
- all four tx_evomegamenujson_* tables get
security.ignorePageTypeRestriction: they are inline children of the
menu plugin and live on whatever page the plugin sits on - creating
a new entry on the standard page failed with "table is not allowed"
- new vitec:attach-page-media --root=<slug> (dry-run by default):
attaches the numbered placeholder pages/<pid>-08.png (slot 08 = page
media / menu tile, the number doubles as the image wish list) as page
media to every child page without one; existing media is never
touched. Run for /support (8 pages) so the planned Support menu entry
renders as two 4-tile rows via the pagetree layout's column images
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- customer wish (via Olli, 2026-10-27): a more visual main menu in the
style of rossvideo.com - image cards instead of plain link lists; for
Insights a left-rail submenu whose hover swaps a visual area showing
the latest news and the next events
- new entry layout "spotlight" in evo_megamenu_json, built strictly on
the catalog pattern so the extension stays project-neutral: `nav` is
a flat rail from the linked page's live children (abstract as teaser,
first page media as 640px-webp image from stage 2 - the hover swap
material), `spotlight` is emitted verbatim from the new
BuildSpotlightEvent (null without a listener); curated columns are
ignored like on pagetree
- new vitec listener ProvideInsightsSpotlight supplies the cards: the
three latest news (storage pid 11, type 0 - the Solr convention;
link /news/article/<path_segment> per the NewsDetail route enhancer;
fal_media as processed 640px webp) and the next two events
(hideonwebsite = 0, upcoming by eventstart/eventend; link = eventurl
or the events page)
- pagetree columns can now carry an image (stage 2+, first page media
of the column's page): attach images in the page properties and the
markets/solutions panels turn into image cards without further code
- TCA select and label extended; README brought up to date (the
pagetree layout had never been documented) with the spotlight JSON
contract, reference mirror synced; frontend briefing updated
- activation is editorial: switch the Insights menu entry to the
spotlight layout and link it to the Insights page
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- vitec:align-market-records gains --delete-dropped: soft-deletes the
records the agency dropped from the taxonomy, including their MM rows
(DataHandler does not clean the foreign side on delete). Decision:
all nine legacy records go, including Healthcare #42 - the Overlake
story loses its badge on purpose and reports as unresolved on future
importer runs
- the run exposed a regression: the RENAME_MAP entries Government ->
Government & Agencies and Education -> Education Communications are
not idempotent because both old names double as NEW main-market
names. The re-run hijacked the main records (stories and teaser
travelled along), created empty replacements and deleted the real
sub-market records as unclaimed
- repair: migrations/fix_market_rename_regression.php (dry-run default,
guarded) swaps the pairs back - main records keep their stories and
workbook teasers, the fresh empties take over the sub-market roles;
applied and verified live (marketlist 11/11 with main detail pages,
badge distribution back to 20/9/9/8/6/4/1, no legacy names left)
- the two non-idempotent entries are removed from RENAME_MAP with a
comment: a rename mapping whose old name is reused by the new
taxonomy must not survive its one-time run
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- new vitec:build-content-pages (dry-run by default, --branch filter,
--publish): fills all 21 content-page workbooks (Insights 7, Support 9,
Contact 5, agency status "Draft for review") with embedded copy -
the workbooks' instruction rows are deliberately not imported; two
DataHandler passes (pages first, element links need real uids),
explicit page sorting and element sequencing
- /insights became a hero page (layout 1) with six navigation cards;
the news plugin moved onto the new /insights/news (layout 12); the
standalone /events page moved under /insights (slug /insights/events,
layout 19, redirect queued - note below)
- NEW /support branch (layout 11) with eight layout-16 subpages:
HelpDesk login (external link + vitec_helpdeskform for access
requests), support plans (Silver/Gold/Platinum cards), training plus
the Aetria/VSN course pages, commissioning, supported devices,
materials compliance (no dedicated form yet - routes to /contact)
- /contact became a hero page with six route cards; the form container
(vitec_contactform) moved onto the new /contact/contact-form; new
/contact/request-a-demo (vitec_demoform), /contact/locations
(vitec_locationlist; three Datapath offices as HIDDEN location
records pending confirmation) and /contact/showrooms (16 venues)
- unverifiable sections (sustainability claims, careers vacancies)
are hidden editorial shells; full page-properties set everywhere
- applied with --publish and verified live (all 21 routes, forms,
lists, moved plugins). Known follow-ups: /events answers 307 - an
auto-created redirect row shadows the command's 301
(migrations/fix_events_redirect.php shows and repairs it); the
"Get Support" meta-nav page still points at /components-showcase;
two CTA targets (support-plans datasheet, careers vacancies) are
editorial
- Datapath stories stay parked ("do not infer records" per the
Success Stories workbook) - documented, questions queued for Joe
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- new vitec:import-markets-main (dry-run by default): one page with
fixed approved copy, so the workbook content is embedded in the
command instead of parsed at runtime; every target is resolved at
runtime (pages by slug, elements by CType/colPos/container, market
records by normalised title) and the command aborts on an unexpected
structure
- the page already had the workbook structure (template vitec__2), so
this updates the hero, the 50/50 markets intro (CTA -> /solutions)
and the overview header in place
- the marketlist flexform selection moves from the old 9-record set
(which still included the dropped "Security & Surveillance") to the
11 main-market records in workbook order
- the 11 market card bodies land in the market records' teaser field
(all were empty; the marketlist cards render from the records -
frontend briefing asks for teaser on the cards)
- the old single-button prefooter container is hidden, replaced by a
vitec_ctabanner (centered/orange, as on the 11 market hero pages)
with both workbook CTAs: "Talk to our team" -> /contact and
"Explore solutions" -> /solutions; explicit sorting after DataHandler
- page properties per the established set: seo/og/twitter title and
description, canonical, abstract, curated keywords
- applied and verified live in the JSON (cards, order, teasers, CTA
targets, meta tags); no spec bump - no new JSON keys involved
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- customer change request (2026-10-26): Resources = Downloads, the
detail band is simplified - capabilities leave the section, Technical
Highlights move left, the resource cards into the right column
(frontend already built on dev.vitec.com)
- TCA: capabilities, datasheets and downloads moved to the Misc tab -
parked, not removed; their JSON keys are unchanged. The planned
automatic newest-datasheet/documentation cards stay deferred by
request (the download route already serves the newest file per
Collateral convention, so the foundation is there)
- new resources_layout select on the Resources tab, English label and
description: Layout 1 = 50-50 (default, highlights left / cards
right), Layout 2 = 33-33-33 (highlights over two columns, cards in
the third); ext_tables.sql column added
- the manual resource card restype vocabulary gains Datasheet and
Brochure (select items plus icon picker seeds, no code change - the
renderer passes restype through as type): an editor can pin a single
datasheet card by linking the download record, which stays current
because the download route always serves the newest file
- ProductShowJsonRenderer: the resources envelope gains sectionLayout
('50-50'|'33-33-33'); verified live - Diamond-H delivers 33-33-33,
untouched products the 50-50 default, layout/items unchanged
- spec bumped to v1.26 (additive revision row, field table 7.15.1),
mirrored; frontend briefing notes the new key
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- new vitec:align-market-records: the visible /markets page tree is the
target (it implements the agreed agency taxonomy). RENAME_MAP carries
16 records - story relations included - onto the new names, exact
matches get their detail_page wired, 10 records are created (CNI,
Government, Public Safety and seven sub-markets). Records the agency
dropped are never touched: they are reported with their attached
stories as the editorial decision list - which turned out empty, all
nine carried zero stories
- INDUSTRY_TO_MARKET of the story importer moved to the new names. The
old combined defense market split cleanly: the Government industry now
maps to its own market, Military stays on Defense and Security, so the
--markets-only re-run redistributed those stories by their original
industry. Healthcare deliberately lost its target (market dropped) and
surfaces as unresolved from now on
- re-run applied: 48/48 stories relinked, badges verified live (no old
names left), Solr reindex queued - the market facet now speaks the new
taxonomy
Open: Overlake Medical Center still points at the dropped Healthcare
record (title-match fallback), the nine orphaned old records await
deletion, Public Safety has no stories yet.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- new generic vitec:rename-page --page=<uid|slug> --title="...": renames
a page, recalculates its own slug from the parent slug plus the new
title and cascades every descendant slug - the gap a backend rename
leaves open. Used to fix the "Engagament" page (#465): title, own
slug and five child slugs in one run, verified live (zero occurrences
left in the JSON)
- SubsolutionWorkbookImporter::norm() tolerates the engagament spelling:
the 39 delivered workbook metas carry the old page title, re-imports
keep matching (verified)
- typo3/cms-redirects installed - it had NEVER been installed, so every
"redirect follows" of the 10-23 renames was wishful thinking and all
old URLs answered 404. Backend slug changes now auto-create redirects
- EXT:redirects' auto-creation does not fire for CLI DataHandler runs,
so vitec:rename-page, vitec:normalize-slugs and
vitec:align-market-pages now queue their 301 sys_redirect rows
themselves in the same DataHandler run
- new one-off vitec:backfill-redirects: the 28 paths vacated on
2026-10-23/26, reconstructed from the command protocols, guarded
against existing redirects and live slugs; applied and verified.
Note the headless semantics: a redirect arrives as the JSON envelope
{"redirectUrl": ..., "statusCode": 301} with HTTP 200 - the front end
must act on redirectUrl (briefing updated)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- new generic vitec:rename-page --page=<uid|slug> --title="...": renames
a page, recalculates its own slug from the parent slug plus the new
title and cascades every descendant slug - the gap a backend rename
leaves open. Used to fix the "Engagament" page (#465): title, own
slug and five child slugs in one run, verified live (zero occurrences
left in the JSON)
- SubsolutionWorkbookImporter::norm() tolerates the engagament spelling:
the 39 delivered workbook metas carry the old page title, re-imports
keep matching (verified)
- typo3/cms-redirects installed - it had NEVER been installed, so every
"redirect follows" of the 10-23 renames was wishful thinking and all
old URLs answered 404. Backend slug changes now auto-create redirects
- EXT:redirects' auto-creation does not fire for CLI DataHandler runs,
so vitec:rename-page, vitec:normalize-slugs and
vitec:align-market-pages now queue their 301 sys_redirect rows
themselves in the same DataHandler run
- new one-off vitec:backfill-redirects: the 28 paths vacated on
2026-10-23/26, reconstructed from the command protocols, guarded
against existing redirects and live slugs; applied and verified.
Note the headless semantics: a redirect arrives as the JSON envelope
{"redirectUrl": ..., "statusCode": 301} with HTTP 200 - the front end
must act on redirectUrl (briefing updated)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
MenuBuilder::image() returned getPublicUrl() of the ORIGINAL upload, so
the Success Stories teaser cards (and item/featured images) carried
multi-MB files into every page payload. All menu images now go through
the ImageService (maxWidth 640, webp - the search-tile convention);
width/height report the processed size, and the original URL remains
the fallback when processing fails so the menu never loses an image.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- evo_megamenu_json: new entry layout "pagetree" - the panel columns
mirror the live subtree of the page the entry links to (one child per
column, grandchildren as items, getMenu() restrictions apply), so the
menu can never age against the page structure again. The stale
9-market panel after the markets realign was the trigger. Curated
columns are ignored on this layout; teasers and the featured slot
stay editorial. Same columns shape in the payload - front ends need
no change beyond knowing the new layout string
- new vitec:normalize-slugs --root=<slug> [--style=plain|and]:
recursively realigns every slug below a root to
<parent-slug>/<slugified-title>, cascading, with a sibling-collision
warning; EXT:redirects covers the old URLs. TYPO3's slug generator
keeps slashes from page titles (third hit: rtcc-/-rtic), this sweeps
a whole tree. Run on /solutions: four fixes, including the
long-standing passenger page and solution page 467. The misspelled
"engagament" slug stays deliberately - it follows the page title and
is fixed in the coordinated typo task
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Structure per the agency agreement (Joe/Christina, confirmed 2026-10-23):
/markets -> eleven market hero pages -> their sub-market pages; the
use-case level stays sections on the sub-market pages.
- new vitec:align-market-pages: renames 8 main market pages onto the
agency names (slug change -> EXT:redirects), creates the 3 new markets,
hides the dropped "Security & Surveillance" (records/stories
untouched), reports unknown children. A child-slug pass realigns every
child to <parent-slug>/<slugified-title> (DataHandler does not cascade
slug changes; this also repaired the third embedded-slash slug,
rtcc-/-rtic). --publish unhides the tree (dev convenience; element
shells stay hidden)
- sub-market import: all 24 agency workbooks applied (4 existing pages,
20 created) - their Meta sheets were clones of Corporate Environments
(record_uid 32) and were repaired beforehand (market/sub-market set,
record_uid 0; the record taxonomy alignment is a separate step)
- SubmarketWorkbookImporter: page-properties parity (og/twitter titles
and descriptions, canonical, abstract from the intro copy) and a
placeholder upgrade pass - pages created in the same run only get the
generic grey (their uid is still NEW), the re-run swaps it for the
numbered per-page placeholder
- new market hero pipeline: frontend layout 23 "Market Hero Page"
(zones hero=colPos1, main=colPos0), Import\MarketHeroPageImporter +
vitec:import-market-hero-workbooks (inbox migrations/markethero_xlsx_in,
gitignored). Hero H1 travels on the introparagraph header (markethero
has no headline field), the hero CTA anchors #submarkets, sub-market
cards link their child page via t3://page, customerlogos and
usecaselist ship hidden until filled editorially, prefooter ctabanner;
full page-properties set with 11 curated keyword sets
- applied end to end and live-verified (layout 23 heroes with linked
cards, layout 21 sub pages with all six colPos groups, clean slugs)
- spec v1.25
Open: market RECORD taxonomy (story badges / Solr facets still use the
old 9 mains), featured product "ISR Video Mission Commander" has no
record, the /markets main page workbook (template 2) is a separate flow.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- new command attaching the agency asset delivery (one Dropbox folder
per product) to the product records: files containing "banner" go to
heroimage (first reference reused/swapped), every other jpg/png -
carousel subfolders included - is APPENDED to productimage with the
full reference list, so the live-site images from 2026-09-04 stay
- folder -> record matching: normalised title, title without the
parenthetical, slug, then IMAGE_ALIASES (Joe's "+1" Vision folder
names map onto the existing records - their banner files still carry
the old product names; 95-Series -> avedia-end-points)
- uploads land in fileadmin/product_import/<slug>/ with REPLACE, so
re-runs are idempotent; inbox migrations/product_images_in/ gitignored
- applied: 39 banners + 14 photos across 42 products, 0 errors,
live-verified (srcset/webp processing included)
- the "MGW Diamond (SDI encoder)" Dropbox folder held the OG blade's
banner (image inspected): moved to the OG product in the inbox, the
appliance deliberately keeps no hero; the Dropbox source still has it
in the wrong folder
- still without records: MGW Diamond/Pico/Pico+ TOUGH and X-View - their
assets wait in the inbox, a re-run attaches them once records exist
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- new frontend layout 22 "Solution Group Page" (provider LAYOUT_MAP,
TCA layout item, locallang_pages.xlf; zones hero=colPos1, main=colPos0
like layout 5 so the front end reuses its components)
- new pipeline Import\SolutionGroupPageImporter +
vitec:import-solution-group-workbooks (inbox
migrations/solutiongroups_xlsx_in/, gitignored): reads the agency
"Template 06" group workbooks by column-A label scan, resolves the
group via "Hero H1" -> is_group record -> detail_page (pages must
exist), cursor-based slotNext() allows repeated CTypes per column
- element plan per page: markethero (+#capabilities CTA anchor) + hero
intro paragraph; intro + supporting 50/50; challenges header + 4
text_only cards; capabilities header + 4 alternating horizontal cards
(bullets as <ul>); usecaselist shipped HIDDEN (an empty selection
would list ALL stories - editors pick, then unhide); marketinsights;
prefooter ctabanner. Page properties as on the sub-solution pages,
8 curated keyword sets
- 56 numbered grey placeholders for pages 459-466 (7 slots per page)
- applied to all 8 group pages, live-verified on 459/465; the solutions
branch is now content-complete (groups + 39 details)
- spec v1.24 (revision row, head/footer)
Found on the way: the "Engagament" typo lives in page 465's title AND
slug; the record is spelled correctly. Fix needs coordination with the
sub-solution workbook metas - own task, not done here.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Joe's 39 "- Completed" workbooks applied to all 39 sub-solution pages
(#467-#515); both workbook inboxes are now gitignored and the tracked
test workbooks untracked - filled deliveries live in the Nextcloud
- new Import\ProductFamilyAliases: the workbooks reference product
FAMILIES in the product slots; 11 labels map to a representative
product, consulted by BOTH importers after the exact title match and
reported as "-> family alias"
- flip-card icons: dummy SVGs fileadmin/icons/flow/<name>.svg for Joe's
10-name vocabulary, attached by the new attachIconFile() through the
shared idempotent attachFalFile() (extracted from attachUrlFile);
real icons later REPLACE those files in the Filelist (same sys_file
uid), every card follows without a re-import
- image slots: numbered grey placeholders per page and slot
(fileadmin/placeholders/pages/<pid>-NN.png, the id rendered into the
image; generic grey as fallback). An existing reference is never
overwritten; a real URL on re-import swaps the placeholder away
- page properties per sub-solution: og/twitter title + description
mirror the SEO fields, canonical_link points at the page itself,
abstract derived from the intro copy (~300 chars, word boundary),
keywords from the curated PAGE_KEYWORDS set
- spec head-matter fix rides along (version table was stuck at 1.21,
real state 1.23)
Open afterwards: 3 missing Datapath stories + re-apply, quotes on 16
story records (list to Joe), slug slash on page 467.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- The selectable recipients are no longer a hand-maintained setting but
every active frontend user of the feedback group (feUserGroup) with a
valid e-mail address; the id is the fe_users uid, so a stored selection
survives users joining or leaving. The `recipients` setting is marked
unused
- Each recipient in the state payload carries label, email and selected
(the stored choice), for a checkbox list with "select all" above the
submit button
- submit accepts the checked ids directly ({"recipients": [uids]}),
validates them against the group, stores and uses them, and reports
the addresses used as sentTo; no selection falls back to mailTo
- migrations/check_fecomment_user.php: all summaries and items of one
user incl. deleted ones, for diagnosis
- New content element "Feedback Overview" (CType fecomment_overview):
the current FE user's feedback state under content.feedbackOverview,
so the overview page renders like any other page instead of a
front-end special case
- Rendered as USER_INT inside the cached page JSON (EXT:headless replaces
the field per request): data is per user, visitors without a session
get {"allowed": false} - verified that nothing leaks from the cache
- One implementation for both consumers: the new FeedbackState service
builds the state payload; the API middleware delegates to it
- State payload (API and element) gained canSubmit and actions (all
write endpoints with method and URL), so the front end needs no
hard-coded endpoints for the submit button below the ticket list
- New site set evomedien/fe-comment carries the TypoScript, added to the
site configuration; icon fecomment-overview
- evo_megamenu_json stays project-neutral: new panel layout "catalog";
for such entries the MenuBuilder dispatches the new PSR-14 event
BuildCatalogEvent and emits whatever a listener sets as `catalog`
(null without a listener). The entry's teaser cards serve as the
featured tiles; the teaser inline field now also shows for "catalog",
and the entry form reloads when the layout changes. README section
"Layout catalog"
- VITEC listener ProvideProductCatalog fills it, modelled on the Ross
Video products menu: main categories below the "Product" root, their
subcategories as groups, products with a plain-text one-line teaser;
same visibility rules as the product list, Product Finder links
(/products?cat=&subcat=), empty categories and groups left out, three
queries for the whole catalog
- Product type-ahead GET /_json/?type=7385&q= (USER_INT page type,
ProductMenuSearchJsonRenderer): Solr restricted to products, last term
completed as a prefix, up to six product cards plus their titles as
autocomplete suggestions; endpoint announced in catalog.search
- Spec v1.23 (clause 7.16: product type-ahead)
The teaser cards field depends on the layout via displayCond; it now appears right after switching to catalog/teasers instead of only after saving.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
daten.md holds credentials and must never be versioned; 91ad5e6 committed it together with the search cards.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- New record type tx_vitec_domain_model_searchcard ("best bets"):
keyword list, priority, optional referenced record (page, product,
story, solution, market, news) and overridable title/teaser/image/link;
hidden/start/end time allow timed campaigns
- SearchCardService delivers content.search.cards on page 1: max. 3,
priority-ordered, deduplicated by URL, independent of filter, facets
and result count. Keywords match as whole words/phrases, case- and
punctuation-insensitive, including one level of the Solr managed
synonyms in both directions (cached for an hour, fail-soft). Record
cards read the record's indexed Solr document, so a card always
matches the record's own search result
- Index fallback for markets and solutions: when the record carries no
image or text, the document takes the intro image (then the hero
background) and the hero subline, intro headline and intro text from
the content blocks of its detail page - selected by CType, so it works
for layout 21 and layout 5 alike; improves results and cards
- Fix: a search request without q returned an empty body instead of the
documented empty shape (stdClass resolved inside the renderer namespace)
- migrations/check_solution_fields.php: shows live/workspace versions of
solution records
- Spec v1.22 (clause 7.16: cards)
List all indexed types (markets and solutions were missing), the PDF
datasheet text extracted through Apache Tika, the /_json/search
endpoint and the current feature set (facets, tile images,
autocomplete).
- Index the text columns of the market/solution Content Blocks and the
vitec_items/vitec_faq_items collection children; story documents now
include their body (inline tt_content children via
tx_vitec_usecase_content, same per-element extraction as pages) -
stories were indexed with subtitle and teaser only until now
- Upgrade EXT:solr 14.0.0-RC1 -> 14.0.2 final (the Solr image moved to a
fresh volume because the configset changed; synonyms restored via REST)
- News decay with age by publication date: crdate is the import date, so
news map datetime to created; boost function gated to news only
- Results carry `image`: processed 640px tile image per type,
root-relative, null for pages and downloads
- Spec v1.21: 7.16 states the /_json prefix and lists `solution` in the
type vocabulary; footer had been stuck at v1.19
- suggest-demo.html fetches through /_json after the URL swap
- New, deliberately separate pipeline for sub-solutions (markets and
solutions must never break each other): generator
vitec:generate-subsolution-workbooks (list from the page tree below
/solutions, 39 workbooks, every sub-solution matched to its record),
SubsolutionWorkbookImporter + CLI vitec:import-subsolution-workbooks,
and a "Sub-Solutions" tab in the VITEC Import module with its own
inbox migrations/subsolutions_xlsx_in/
- Targets the existing template 5 "Solution Detail" without changing
it: hero element in colPos 1, the remaining sections in fixed order in
colPos 0, found again by CType on re-import; existing empty sub-solution
pages are switched to layout 5, missing ones created hidden;
detail_page set on the solution record
- Workbook per the Figma "07 Solution Detail page": hero without video
teaser, intro with headline and without learn-more/portfolio, extended
icon list, own page-layout reference image
- Shared content elements: market hero/intro/insights relabelled
"Market/Solution", market intro gains the optional intro_headline
field (new column, requires extension:setup)
- Fix: DataHandler puts every NEW record with a positive pid at the top
of its column, so pages built in one run came out reversed. Both
importers now track the page order per colPos and write
tt_content.sorting explicitly after the DataHandler run; re-applying
repairs pages imported earlier (verified on the control-room
sub-solution and sub-market page 443)
- migrations/fill_test_subsolution.php: realistic test content from
vitec.com copy and images for the control-room sub-solution
- Docs section 5z
- Extract the complete import logic (label-scan reading, page
find-or-create, slot filling, content-idempotent image attach) from
ImportSubmarketWorkbooksCommand into the shared service
SubmarketWorkbookImporter; the CLI command and the new controller are
thin shells around importFile(), so both entry points cannot drift.
CLI regression verified: identical dry-run report for the reference
workbook (12 elements, page 443)
- New "Sub-Markets" tab in the VITEC Import module
(SubmarketImportController + Import/Submarkets.html): upload multiple
filled workbooks into the SAME inbox the CLI uses
(migrations/submarkets_xlsx_in/), per-file checkboxes, dry-run and
apply buttons, result cards with the familiar report and a direct
link into the page module; backend dry-run verified against the CLI
- Submitted filenames are whitelisted against the actual directory
listing (no path traversal); uploads restricted to sanitized .xlsx
basenames
- Routes submarkets/submarket_upload/submarket_process in Modules.php,
Sub-Markets tab link in the sibling module views, ok/danger badge
colors in backend-import.css
- Docs section 5y (incl. operations note: apply in small batches in the
module, mass runs via CLI - image downloads run inside the web
request)
- Rebuild the widget server-backed: it renders only when GET state
allows (logged-in FE user of the configured group), so the script
tag is safe on public pages; form with mini rich text (bold/italic/
list), file attachment chips and Ctrl+V image paste - a paste lazily
creates the draft feedback, uploads and inserts the image inline
- Note pad badge mirrors the server item count; the pad button links
to the overview page via new extension setting overviewPid, exposed
as overviewUrl in GET state (slug lookup)
- Embed /fileadmin images of notes into the feedback mail as CID
parts: relative srcs are dead in mail clients and dev sits behind
basic auth; attachment links stay absolute URLs
- public/widget-test.html: dev test page, doubles as the reference
implementation of the React login flow (fetch felogin JSON form
incl. __RequestToken, urlencoded POST to /_json + form.action)
- Docs section 5x (fe_comment v2 incl. CSRF login lesson,
templateRootPaths.10 collision, cache:flush before extension:setup)
- Replace the v1 submit endpoint with a full JSON API under
/api/fe-comment/ (state, feedback create/update/delete, uploads,
summary notes/recipients, submit), guarded by frontend login and a
configurable FE user group; unauthorized callers get {"allowed":false}
- New models: tx_fecomment_summary (one open ticket per user, status
open/sent) and tx_fecomment_feedback (url, RTE note, FAL attachments),
both editable in the backend on the ticket storage page
- FeedbackApiMiddleware registered after frontend authentication (the
frontend.user attribute does not exist earlier); uploads land in
fileadmin/fe_comment/summary-<uid>/ with mime/extension check, 20 MB cap
- Submit sends one HTML mail (author block, items with attachment links,
reply-to = FE user mail) to selected recipients with mailTo fallback,
then closes the summary
- felogin wired React-compatible: felogin.pid=520 plus headless FeLogin
JSON templates via site settings - felogin v14 and EXT:headless both
claim templateRootPaths.10, the felogin.view.* settings feed exactly
that index, so the structured JSON form (incl. __RequestToken) wins
- Read the sys_file_reference insert id before syncAttachmentCount():
DBAL throws "no identity value" once the count UPDATE has run
- migrations: drop_fecomment_tables.php (repairs the no-uid tables,
only drops when empty), check_feuser.php (login diagnosis),
fec_login_test.sh / fec_api_test.sh (curl chains incl. CSRF token flow)
thumbnail of the actual image (hero background, intro image, insights
cover), key copy in the summary line, full details expanded; card and
intro-paragraph previews are wrapped in the same mechanism
- New SubmarketPluginPreview for vitec_usecaselist / vitec_productfeature /
vitec_productlist: instead of bare standard boxes they now list the
selected story titles (flagging stories that still lack a quote), the
featured product and the hand-picked products in order
- Container-style collapse for whole page-module COLUMNS: a chevron at the
right of every column header folds a section down to its title row,
state kept per page and colPos in localStorage - the slot view of a
sub-market page folds to six slim bands
- Previews sit under the page module's pointer-events lock and its
click-to-edit layer: pointer events are re-enabled inside the collapse
markup and the toggle runs on pointerdown in the capture phase
- Two more v14 removals fixed on the way, both latent in the OLDER preview
classes too (Usecaseshow, Modelcard would have crashed the page module):
GridColumnItem::getRecord() now returns a Domain\Record object, and
StandaloneView is gone - previews normalize the record via a shared
helper and render through the ViewFactory
frame 'Sub-Market Page' does not contain the Industry Insights band or the
footer, they live as siblings inside the surrounding section. The asset is
now rendered from the section (contentsOnly), so the customer sees the
complete page including Insights and footer; the section label rows fit
unchanged.