config { # EXT:solr indexes pages only when indexing is explicitly enabled index_enable = 1 pageTitleProviders { vitec { provider = Evomedien\Vitec\PageTitle\ProductPageTitleProvider before = record before = seo } vitecUsecase { provider = Evomedien\Vitec\PageTitle\UsecasePageTitleProvider before = record before = seo } } } @import 'EXT:headless/Configuration/TypoScript/ContentElement/*.typoscript' # ============================================================================= # header_layout 100 = "Hidden" (decision 2026-09-04): such headers stay OUT of # the JSON - header, subheader and headerLink render empty. headerLayout (100) # stays in the payload so the front end could still tell why. Placed BEFORE # the `< lib.contentElementWithHeader` copies below, which snapshot this lib. # The content-blocks `data` path gets the same rule via HiddenHeaderProcessor. # ============================================================================= lib.contentElementWithHeader.fields.content.fields { header.stdWrap.if { value = 100 equals.field = header_layout negate = 1 } subheader.stdWrap.if { value = 100 equals.field = header_layout negate = 1 } headerLink.stdWrap.if { value = 100 equals.field = header_layout negate = 1 } } lib.contentBlock.fields.data.dataProcessing.20 = Evomedien\Vitec\DataProcessing\HiddenHeaderProcessor # ============================================================================= # 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.`), 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 } } } } # Featured product card (sub-market template section 5): one referenced # product as a full product card under `productfeature` - same shape as # the list items, serialization shared with ProductListJsonRenderer. vitec_productfeature < lib.contentElementWithHeader vitec_productfeature { fields { content { fields { productfeature = USER productfeature.userFunc = Evomedien\Vitec\UserFunc\ProductFeatureJsonRenderer->render # No product selected/visible -> real JSON null, not # the string "null" (ticket 0068-FE). productfeature.ifEmptyReturnNull = 1 } } } } # Product Finder - only the category hierarchy for the filter selects. # Placed once above the product lists; the front end filters the products # those lists already delivered, client side, via ?cat= and ?subcat=. vitec_productfinder < lib.contentElementWithHeader vitec_productfinder { fields { content { fields { productfinder = USER productfinder.userFunc = Evomedien\Vitec\UserFunc\ProductFinderJsonRenderer->render } } } } # Product Content Check - the product audit table as data (page # /products/product-check). Always USER_INT, see ProductCheckJsonRenderer. vitec_productcheck < lib.contentElementWithHeader vitec_productcheck { fields { content { fields { productcheck = USER productcheck.userFunc = Evomedien\Vitec\UserFunc\ProductCheckJsonRenderer->render } } } } # EXT:solr search results as JSON - the search endpoint for the React frontend solr_pi_results < lib.contentElementWithHeader solr_pi_results { fields { content { fields { search = USER search.userFunc = Evomedien\Vitec\UserFunc\SearchJsonRenderer->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 #