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
281 lines
8.2 KiB
Plaintext
Executable File
281 lines
8.2 KiB
Plaintext
Executable File
config {
|
|
pageTitleProviders {
|
|
vitec {
|
|
provider = Evomedien\Vitec\PageTitle\ProductPageTitleProvider
|
|
before = record
|
|
before = seo
|
|
}
|
|
}
|
|
}
|
|
|
|
@import 'EXT:headless/Configuration/TypoScript/ContentElement/*.typoscript'
|
|
|
|
# =============================================================================
|
|
# Headless list-plugin JSON renderers (TYPO3 v14: each plugin is its own CType)
|
|
#
|
|
# For every VITEC plugin the renderer's USER output is exposed as a sub-field
|
|
# of the standard content-element envelope (`content.<key>`), inheriting all
|
|
# default fields (id, type, colPos, categories, appearance, …) from
|
|
# lib.contentElement provided by friendsoftypo3/headless.
|
|
# =============================================================================
|
|
|
|
tt_content {
|
|
vitec_productlist < lib.contentElementWithHeader
|
|
vitec_productlist {
|
|
fields {
|
|
content {
|
|
fields {
|
|
products = USER
|
|
products.userFunc = Evomedien\Vitec\UserFunc\ProductListJsonRenderer->render
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
news_pi1 < lib.contentElementWithHeader
|
|
news_pi1 {
|
|
fields {
|
|
content {
|
|
fields {
|
|
news = USER
|
|
news.userFunc = Evomedien\Vitec\UserFunc\NewsJsonRenderer->render
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
news_newsliststicky < tt_content.news_pi1
|
|
news_newsselectedlist < tt_content.news_pi1
|
|
news_newsdetail < tt_content.news_pi1
|
|
news_newsdatemenu < tt_content.news_pi1
|
|
news_categorylist < tt_content.news_pi1
|
|
news_newssearchform < tt_content.news_pi1
|
|
news_newssearchresult < tt_content.news_pi1
|
|
news_taglist < tt_content.news_pi1
|
|
|
|
vitec_productshow < lib.contentElementWithHeader
|
|
vitec_productshow {
|
|
fields {
|
|
content {
|
|
fields {
|
|
product = USER
|
|
product.userFunc = Evomedien\Vitec\UserFunc\ProductShowJsonRenderer->render
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
vitec_usecaselist < lib.contentElementWithHeader
|
|
vitec_usecaselist {
|
|
fields {
|
|
content {
|
|
fields {
|
|
usecases = USER
|
|
usecases.userFunc = Evomedien\Vitec\UserFunc\UsecaseListJsonRenderer->render
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
vitec_usecaseshow < lib.contentElementWithHeader
|
|
vitec_usecaseshow {
|
|
fields {
|
|
content {
|
|
fields {
|
|
usecase = USER
|
|
usecase.userFunc = Evomedien\Vitec\UserFunc\UsecaseShowJsonRenderer->render
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
vitec_marketshow < lib.contentElementWithHeader
|
|
vitec_marketshow {
|
|
fields {
|
|
content {
|
|
fields {
|
|
market = USER
|
|
market.userFunc = Evomedien\Vitec\UserFunc\MarketShowJsonRenderer->render
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
vitec_marketlist < lib.contentElementWithHeader
|
|
vitec_marketlist {
|
|
fields {
|
|
content {
|
|
fields {
|
|
markets = USER
|
|
markets.userFunc = Evomedien\Vitec\UserFunc\MarketListJsonRenderer->render
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
vitec_solutionlist < lib.contentElementWithHeader
|
|
vitec_solutionlist {
|
|
fields {
|
|
content {
|
|
fields {
|
|
solutions = USER
|
|
solutions.userFunc = Evomedien\Vitec\UserFunc\SolutionListJsonRenderer->render
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
vitec_solutionshow < lib.contentElementWithHeader
|
|
vitec_solutionshow {
|
|
fields {
|
|
content {
|
|
fields {
|
|
solution = USER
|
|
solution.userFunc = Evomedien\Vitec\UserFunc\SolutionShowJsonRenderer->render
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
vitec_downloadcard < lib.contentElementWithHeader
|
|
vitec_downloadcard {
|
|
fields {
|
|
content {
|
|
fields {
|
|
downloadcard = USER
|
|
downloadcard.userFunc = Evomedien\Vitec\UserFunc\DownloadcardJsonRenderer->render
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
vitec_downloadcardcollection < lib.contentElementWithHeader
|
|
vitec_downloadcardcollection {
|
|
fields {
|
|
content {
|
|
fields {
|
|
downloadcardcollection = USER
|
|
downloadcardcollection.userFunc = Evomedien\Vitec\UserFunc\DownloadcardcollectionJsonRenderer->render
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
vitec_datasheets < lib.contentElementWithHeader
|
|
vitec_datasheets {
|
|
fields {
|
|
content {
|
|
fields {
|
|
datasheets = USER
|
|
datasheets.userFunc = Evomedien\Vitec\UserFunc\DatasheetsJsonRenderer->render
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
vitec_eventlist =< lib.contentElementWithHeader
|
|
vitec_eventlist {
|
|
fields {
|
|
content {
|
|
fields {
|
|
eventlist = USER
|
|
eventlist.userFunc = Evomedien\Vitec\UserFunc\EventlistJsonRenderer->render
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
vitec_contactform < lib.contentElementWithHeader
|
|
vitec_contactform {
|
|
fields {
|
|
content {
|
|
fields {
|
|
form = USER
|
|
form.userFunc = Evomedien\Vitec\UserFunc\FormsJsonRenderer->render
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
vitec_demoform < tt_content.vitec_contactform
|
|
vitec_helpdeskform < tt_content.vitec_contactform
|
|
|
|
vitec_modelcard < lib.contentElementWithHeader
|
|
vitec_modelcard {
|
|
fields {
|
|
content {
|
|
fields {
|
|
card = USER
|
|
card.userFunc = Evomedien\Vitec\UserFunc\ModelcardJsonRenderer->render
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
vitec_customerlogos < lib.contentElementWithHeader
|
|
vitec_customerlogos {
|
|
fields {
|
|
content {
|
|
fields {
|
|
customerlogos = USER
|
|
customerlogos.userFunc = Evomedien\Vitec\UserFunc\CustomerlogosJsonRenderer->render
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
vitec_locationlist < lib.contentElementWithHeader
|
|
vitec_locationlist {
|
|
fields {
|
|
content {
|
|
fields {
|
|
locations = USER
|
|
locations.userFunc = Evomedien\Vitec\UserFunc\LocationsJsonRenderer->render
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# Include container (layout) rendering definitions
|
|
@import 'EXT:vitec/Configuration/TypoScript/Headless/vitec_containers.typoscript'
|
|
|
|
# Include menu (navigation) JSON definitions
|
|
@import 'EXT:vitec/Configuration/TypoScript/Headless/vitec_menus.typoscript'
|
|
|
|
# =============================================================================
|
|
# Page-level structured data (schema.org JSON-LD @graph)
|
|
#
|
|
# Organization + WebSite + BreadcrumbList + NewsArticle, auto-generated server
|
|
# side from page/site data. The headless frontend wraps the returned string in
|
|
# <script type="application/ld+json"> inside the page <head>.
|
|
# =============================================================================
|
|
page.10.fields.jsonLd = USER
|
|
page.10.fields.jsonLd.userFunc = Evomedien\Vitec\UserFunc\PageJsonLdRenderer->render
|
|
|
|
############################################################
|
|
# Frontend resolution for the record links from the link
|
|
# browser (page.tsconfig TCEMAIN.linkHandler):
|
|
# download -> forced download endpoint (DownloadFileMiddleware)
|
|
# product -> detail view, same /product/<slug> convention as
|
|
# the `link` field in the product JSON (page 10)
|
|
# A hidden or deleted target makes the typolink fail -> null.
|
|
############################################################
|
|
|
|
config.recordLinks {
|
|
download {
|
|
forceLink = 1
|
|
typolink {
|
|
parameter.cObject = TEXT
|
|
parameter.cObject.dataWrap = /download/file/{field:uid}
|
|
}
|
|
}
|
|
product {
|
|
forceLink = 1
|
|
typolink {
|
|
parameter.cObject = TEXT
|
|
parameter.cObject.dataWrap = /product/{field:slug}
|
|
}
|
|
}
|
|
}
|