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>
This commit is contained in:
o-rasche
2026-06-15 14:29:17 +02:00
parent 64ea55d29d
commit 3aaf8fdad5
98 changed files with 5650 additions and 10154 deletions

0
packages/vitec/Configuration/FlexForms/Container.xml Executable file → Normal file
View File

View File

@@ -6,60 +6,42 @@
<sheets>
<sDEF>
<ROOT>
<TCEforms>
<sheetTitle>General Settings</sheetTitle>
</TCEforms>
<sheetTitle>General Settings</sheetTitle>
<type>array</type>
<el>
<settings.showFilter>
<TCEforms>
<label>Show Filter</label>
<config>
<type>check</type>
<default>1</default>
</config>
</TCEforms>
<label>Show Filter</label>
<config>
<type>check</type>
<default>1</default>
</config>
</settings.showFilter>
<settings.showSearch>
<TCEforms>
<label>Show Search</label>
<config>
<type>check</type>
<default>1</default>
</config>
</TCEforms>
<label>Show Search</label>
<config>
<type>check</type>
<default>1</default>
</config>
</settings.showSearch>
<settings.itemsPerPage>
<TCEforms>
<label>Items per Page</label>
<config>
<type>number</type>
<default>20</default>
</config>
</TCEforms>
<label>Items per Page</label>
<config>
<type>number</type>
<default>20</default>
</config>
</settings.itemsPerPage>
<settings.defaultCategory>
<TCEforms>
<label>Default Category</label>
<config>
<type>select</type>
<renderType>selectSingle</renderType>
<foreign_table>tx_vitec_domain_model_downloadcategory</foreign_table>
<foreign_table_where>ORDER BY title</foreign_table_where>
<items>
<numIndex index="0">
<label>All Categories</label>
<value>0</value>
</numIndex>
</items>
</config>
</TCEforms>
</settings.defaultCategory>
<settings.debug>
<label>Allow Debug Output</label>
<config>
<type>check</type>
<default>0</default>
</config>
</settings.debug>
</el>
</ROOT>
</sDEF>
</sheets>
</T3DataStructure>
</T3DataStructure>

View File

@@ -1,29 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<T3DataStructure>
<sheets>
<sDEF>
<ROOT>
<sheetTitle>
Select Usecase
</sheetTitle>
<type>array</type>
<el>
<settings.usecase>
<label>
Usecase
</label>
<config>
<type>select</type>
<renderType>selectSingle</renderType>
<foreign_table>tx_vitec_domain_model_usecase</foreign_table>
<foreign_table_where>AND tx_vitec_domain_model_usecase.hidden = 0 AND tx_vitec_domain_model_usecase.deleted = 0 ORDER BY tx_vitec_domain_model_usecase.title</foreign_table_where>
<size>1</size>
<minitems>0</minitems>
<maxitems>1</maxitems>
</config>
</settings.usecase>
</el>
</ROOT>
</sDEF>
</sheets>
</T3DataStructure>

44
packages/vitec/Configuration/Icons.php Executable file → Normal file
View File

@@ -4,6 +4,46 @@ declare(strict_types=1);
use TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider;
return [
'vitec-plugin-productlist' => [
'provider' => SvgIconProvider::class,
'source' => 'EXT:vitec/Resources/Public/Icons/vitec-plugin-productlist.svg',
],
'vitec-plugin-simplecard' => [
'provider' => SvgIconProvider::class,
'source' => 'EXT:vitec/Resources/Public/Icons/vitec-plugin-simplecard.svg',
],
'vitec-plugin-productshow' => [
'provider' => SvgIconProvider::class,
'source' => 'EXT:vitec/Resources/Public/Icons/vitec-plugin-productshow.svg',
],
'vitec-plugin-usecaseshow' => [
'provider' => SvgIconProvider::class,
'source' => 'EXT:vitec/Resources/Public/Icons/vitec-plugin-usecaseshow.svg',
],
'vitec-plugin-marketshow' => [
'provider' => SvgIconProvider::class,
'source' => 'EXT:vitec/Resources/Public/Icons/vitec-plugin-marketshow.svg',
],
'vitec-plugin-solutionshow' => [
'provider' => SvgIconProvider::class,
'source' => 'EXT:vitec/Resources/Public/Icons/vitec-plugin-solutionshow.svg',
],
'vitec-plugin-usecaselist' => [
'provider' => SvgIconProvider::class,
'source' => 'EXT:vitec/Resources/Public/Icons/vitec-plugin-usecaselist.svg',
],
'vitec-plugin-downloadcard' => [
'provider' => SvgIconProvider::class,
'source' => 'EXT:vitec/Resources/Public/Icons/vitec-plugin-downloadcard.svg',
],
'vitec-plugin-downloadcardcollection' => [
'provider' => SvgIconProvider::class,
'source' => 'EXT:vitec/Resources/Public/Icons/vitec-plugin-downloadcardcollection.svg',
],
'vitec-plugin-datasheets' => [
'provider' => SvgIconProvider::class,
'source' => 'EXT:vitec/Resources/Public/Icons/vitec-plugin-datasheets.svg',
],
'vitec-cols-50-50' => [
'provider' => SvgIconProvider::class,
'source' => 'EXT:vitec/Resources/Public/Icons/vitec-cols-50-50.svg',
@@ -24,6 +64,10 @@ return [
'provider' => SvgIconProvider::class,
'source' => 'EXT:vitec/Resources/Public/Icons/vitec-cols-33-66.svg',
],
'vitec-container' => [
'provider' => SvgIconProvider::class,
'source' => 'EXT:vitec/Resources/Public/Icons/vitec-container.svg',
],
'vitec-ogimage' => [
'provider' => SvgIconProvider::class,
'source' => 'EXT:vitec/Resources/Public/Icons/vitec-ogimage.svg',

View File

@@ -7,5 +7,4 @@ settings:
dependencies:
- typo3/fluid-styled-content
- friendsoftypo3/headless
- itplusx/headless-container
- nb-headless-content-blocks/headless-content-blocks

View File

@@ -8,91 +8,129 @@ config {
}
}
@import 'EXT:headless/Configuration/TypoScript/ContentElement/*.typoscript'
# =============================================================================
# Headless list-plugin JSON renderers
# Headless list-plugin JSON renderers (TYPO3 v14: each plugin is its own CType)
#
# `tt_content.list.20.<list_type>` renders the element body for that subtype
# (only ever invoked for the matching list_type — safe as-is).
#
# `tt_content.list.fields.content.fields.<key>` is GLOBAL: without scoping it
# would inject <key> into EVERY list plugin's content. Each such field is
# therefore guarded with:
# stdWrap.if { equals.field = list_type ... } -> empty for other plugins
# ifEmptyUnsetKey = 1 -> empty key removed entirely
# (headless JsonContentObject honours ifEmptyUnsetKey: '' / false => unset).
# 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.
# =============================================================================
# --- vitec_productlist --------------------------------------------------------
tt_content.list.20.vitec_productlist = USER
tt_content.list.20.vitec_productlist {
userFunc = Evomedien\Vitec\UserFunc\ProductListJsonRenderer->render
}
tt_content.list.fields.content.fields.products = USER
tt_content.list.fields.content.fields.products {
userFunc = Evomedien\Vitec\UserFunc\ProductListJsonRenderer->render
stdWrap.if {
value = vitec_productlist
equals.field = list_type
tt_content {
vitec_productlist < lib.contentElement
vitec_productlist {
fields {
content {
fields {
products = USER
products.userFunc = Evomedien\Vitec\UserFunc\ProductListJsonRenderer->render
}
}
}
}
ifEmptyUnsetKey = 1
}
# --- vitec_productshow --------------------------------------------------------
tt_content.list.20.vitec_productshow = USER
tt_content.list.20.vitec_productshow {
userFunc = Evomedien\Vitec\UserFunc\ProductShowJsonRenderer->render
}
tt_content.list.fields.content.fields.product = USER
tt_content.list.fields.content.fields.product {
userFunc = Evomedien\Vitec\UserFunc\ProductShowJsonRenderer->render
stdWrap.if {
value = vitec_productshow
equals.field = list_type
vitec_productshow < lib.contentElement
vitec_productshow {
fields {
content {
fields {
product = USER
product.userFunc = Evomedien\Vitec\UserFunc\ProductShowJsonRenderer->render
}
}
}
}
ifEmptyUnsetKey = 1
}
# --- vitec_usecaselist --------------------------------------------------------
tt_content.list.20.vitec_usecaselist = USER
tt_content.list.20.vitec_usecaselist {
userFunc = Evomedien\Vitec\UserFunc\UsecaseListJsonRenderer->render
}
tt_content.list.fields.content.fields.usecases = USER
tt_content.list.fields.content.fields.usecases {
userFunc = Evomedien\Vitec\UserFunc\UsecaseListJsonRenderer->render
stdWrap.if {
value = vitec_usecaselist
equals.field = list_type
vitec_usecaselist < lib.contentElement
vitec_usecaselist {
fields {
content {
fields {
usecases = USER
usecases.userFunc = Evomedien\Vitec\UserFunc\UsecaseListJsonRenderer->render
}
}
}
}
ifEmptyUnsetKey = 1
}
# --- vitec_usecaseshow --------------------------------------------------------
tt_content.list.20.vitec_usecaseshow = USER
tt_content.list.20.vitec_usecaseshow {
userFunc = Evomedien\Vitec\UserFunc\UsecaseShowJsonRenderer->render
}
tt_content.list.fields.content.fields.usecase = USER
tt_content.list.fields.content.fields.usecase {
userFunc = Evomedien\Vitec\UserFunc\UsecaseShowJsonRenderer->render
stdWrap.if {
value = vitec_usecaseshow
equals.field = list_type
vitec_usecaseshow < lib.contentElement
vitec_usecaseshow {
fields {
content {
fields {
usecase = USER
usecase.userFunc = Evomedien\Vitec\UserFunc\UsecaseShowJsonRenderer->render
}
}
}
}
vitec_marketshow < lib.contentElement
vitec_marketshow {
fields {
content {
fields {
market = USER
market.userFunc = Evomedien\Vitec\UserFunc\MarketShowJsonRenderer->render
}
}
}
}
vitec_solutionshow < lib.contentElement
vitec_solutionshow {
fields {
content {
fields {
solution = USER
solution.userFunc = Evomedien\Vitec\UserFunc\SolutionShowJsonRenderer->render
}
}
}
}
vitec_downloadcard < lib.contentElement
vitec_downloadcard {
fields {
content {
fields {
downloadcard = USER
downloadcard.userFunc = Evomedien\Vitec\UserFunc\DownloadcardJsonRenderer->render
}
}
}
}
vitec_downloadcardcollection < lib.contentElement
vitec_downloadcardcollection {
fields {
content {
fields {
downloadcardcollection = USER
downloadcardcollection.userFunc = Evomedien\Vitec\UserFunc\DownloadcardcollectionJsonRenderer->render
}
}
}
}
vitec_datasheets < lib.contentElement
vitec_datasheets {
fields {
content {
fields {
datasheets = USER
datasheets.userFunc = Evomedien\Vitec\UserFunc\DatasheetsJsonRenderer->render
}
}
}
}
ifEmptyUnsetKey = 1
}
# Include container (layout) rendering definitions
@import 'EXT:vitec/Configuration/TypoScript/Headless/vitec_containers.typoscript'
# Ensure headless's content element JSON definitions take precedence over
# fluid_styled_content's HTML definitions. This is loaded at the end of the
# Vitecset to guarantee winning load order.
@import 'EXT:headless/Configuration/TypoScript/ContentElement/*.typoscript'
# Include menu (navigation) JSON definitions
@import 'EXT:vitec/Configuration/TypoScript/Headless/vitec_menus.typoscript'

View File

@@ -1,44 +0,0 @@
config {
pageTitleProviders {
vitec {
provider = Evomedien\Vitec\PageTitle\ProductPageTitleProvider
before = record
before = seo
}
}
}
# Headless: Add products field to vitec_productlist
tt_content.list.20.vitec_productlist = USER
tt_content.list.20.vitec_productlist {
userFunc = Evomedien\Vitec\UserFunc\ProductListJsonRenderer->render
}
# Override the JSON structure for vitec_productlist
tt_content.list.fields.content.fields.products = USER
tt_content.list.fields.content.fields.products {
userFunc = Evomedien\Vitec\UserFunc\ProductListJsonRenderer->render
}
# Headless: Add product field to vitec_productshow
tt_content.list.20.vitec_productshow = USER
tt_content.list.20.vitec_productshow {
userFunc = Evomedien\Vitec\UserFunc\ProductShowJsonRenderer->render
}
# Override the JSON structure for vitec_productshow
tt_content.list.fields.content.fields.product = USER
tt_content.list.fields.content.fields.product {
userFunc = Evomedien\Vitec\UserFunc\ProductShowJsonRenderer->render
}
# Include container (layout) rendering definitions
@import 'EXT:vitec/Configuration/TypoScript/Headless/vitec_containers.typoscript'
# Ensure headless's content element JSON definitions take precedence over
# fluid_styled_content's HTML definitions. This is loaded at the end of the
# Vitecset to guarantee winning load order.
@import 'EXT:headless/Configuration/TypoScript/ContentElement/*.typoscript'
# Include menu (navigation) JSON definitions
@import 'EXT:vitec/Configuration/TypoScript/Headless/vitec_menus.typoscript'

View File

@@ -1,82 +0,0 @@
config {
pageTitleProviders {
vitec {
provider = Evomedien\Vitec\PageTitle\ProductPageTitleProvider
before = record
before = seo
}
}
}
# =============================================================================
# Headless list-plugin JSON renderers
#
# `tt_content.list.20.<list_type>` renders the element body for that subtype
# (only ever invoked for the matching list_type — safe as-is).
#
# `tt_content.list.fields.content.fields.<key>` is GLOBAL: without scoping it
# would inject <key> into EVERY list plugin's content. Each such field is
# therefore guarded with:
# stdWrap.if { equals.field = list_type ... } -> empty for other plugins
# ifEmptyUnsetKey = 1 -> empty key removed entirely
# (headless JsonContentObject honours ifEmptyUnsetKey: '' / false => unset).
# =============================================================================
# --- vitec_productlist --------------------------------------------------------
tt_content.list.20.vitec_productlist = USER
tt_content.list.20.vitec_productlist {
userFunc = Evomedien\Vitec\UserFunc\ProductListJsonRenderer->render
}
tt_content.list.fields.content.fields.products = USER
tt_content.list.fields.content.fields.products {
userFunc = Evomedien\Vitec\UserFunc\ProductListJsonRenderer->render
stdWrap.if {
value = vitec_productlist
equals.field = list_type
}
ifEmptyUnsetKey = 1
}
# --- vitec_productshow --------------------------------------------------------
tt_content.list.20.vitec_productshow = USER
tt_content.list.20.vitec_productshow {
userFunc = Evomedien\Vitec\UserFunc\ProductShowJsonRenderer->render
}
tt_content.list.fields.content.fields.product = USER
tt_content.list.fields.content.fields.product {
userFunc = Evomedien\Vitec\UserFunc\ProductShowJsonRenderer->render
stdWrap.if {
value = vitec_productshow
equals.field = list_type
}
ifEmptyUnsetKey = 1
}
# --- vitec_usecaselist --------------------------------------------------------
tt_content.list.20.vitec_usecaselist = USER
tt_content.list.20.vitec_usecaselist {
userFunc = Evomedien\Vitec\UserFunc\UsecaseListJsonRenderer->render
}
tt_content.list.fields.content.fields.usecases = USER
tt_content.list.fields.content.fields.usecases {
userFunc = Evomedien\Vitec\UserFunc\UsecaseListJsonRenderer->render
stdWrap.if {
value = vitec_usecaselist
equals.field = list_type
}
ifEmptyUnsetKey = 1
}
# Include container (layout) rendering definitions
@import 'EXT:vitec/Configuration/TypoScript/Headless/vitec_containers.typoscript'
# Ensure headless's content element JSON definitions take precedence over
# fluid_styled_content's HTML definitions. This is loaded at the end of the
# Vitecset to guarantee winning load order.
@import 'EXT:headless/Configuration/TypoScript/ContentElement/*.typoscript'
# Include menu (navigation) JSON definitions
@import 'EXT:vitec/Configuration/TypoScript/Headless/vitec_menus.typoscript'

0
packages/vitec/Configuration/TCA/Overrides/pages.php Executable file → Normal file
View File

View File

@@ -1,120 +1,53 @@
<?php
declare(strict_types=1);
defined('TYPO3') or die();
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Extbase\Utility\ExtensionUtility;
// Register the Simple Card plugin
$simplecardPluginSignature = \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
'Vitec',
'Simplecard',
'Simple Card'
);
(static function (): void {
$registerPluginWithFlexForm = static function (
string $pluginName,
string $pluginTitle,
string $flexFormFile,
?string $iconIdentifier = null
): void {
ExtensionUtility::registerPlugin(
'Vitec',
$pluginName,
$pluginTitle,
$iconIdentifier ?? 'content-plugin',
'plugins',
'',
$flexFormFile
);
};
// Register the "Single Success Story" plugin
$usecaseShowPluginSignature = \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
'Vitec',
'Usecaseshow',
'Single Success Story'
);
$registerPluginWithFlexForm('Productlist', 'Show Products by Category', 'FILE:EXT:vitec/Configuration/FlexForms/Productlist.xml', 'vitec-plugin-productlist');
$registerPluginWithFlexForm('Simplecard', 'Simple Card', 'FILE:EXT:vitec/Configuration/FlexForms/Simplecard.xml', 'vitec-plugin-simplecard');
$registerPluginWithFlexForm('Productshow', 'Show Single Product', 'FILE:EXT:vitec/Configuration/FlexForms/Productshow.xml', 'vitec-plugin-productshow');
$registerPluginWithFlexForm('Usecaseshow', 'Single Success Story', 'FILE:EXT:vitec/Configuration/FlexForms/Usecase.xml', 'vitec-plugin-usecaseshow');
$registerPluginWithFlexForm('Marketshow', 'Show Single Market', 'FILE:EXT:vitec/Configuration/FlexForms/Market.xml', 'vitec-plugin-marketshow');
$registerPluginWithFlexForm('Solutionshow', 'Show Single Solution', 'FILE:EXT:vitec/Configuration/FlexForms/Solution.xml', 'vitec-plugin-solutionshow');
$registerPluginWithFlexForm('Usecaselist', 'Shows List of all Success Stories', 'FILE:EXT:vitec/Configuration/FlexForms/Usecaselist.xml', 'vitec-plugin-usecaselist');
$registerPluginWithFlexForm('Downloadcard', 'Download Card', 'FILE:EXT:vitec/Configuration/FlexForms/Downloadcard.xml', 'vitec-plugin-downloadcard');
$registerPluginWithFlexForm('Downloadcardcollection', 'Download Card Collection', 'FILE:EXT:vitec/Configuration/FlexForms/Downloadcardcollection.xml', 'vitec-plugin-downloadcardcollection');
$registerPluginWithFlexForm('Datasheets', 'Datasheets', 'FILE:EXT:vitec/Configuration/FlexForms/Datasheets.xml');
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist'][$usecaseShowPluginSignature] = 'pi_flexform';
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPiFlexFormValue(
$usecaseShowPluginSignature,
'FILE:EXT:vitec/Configuration/FlexForms/Usecase.xml'
);
// Change frame_class to allow multiple selections.
$GLOBALS['TCA']['tt_content']['columns']['frame_class']['config']['renderType'] = 'selectCheckBox';
$GLOBALS['TCA']['tt_content']['columns']['frame_class']['config']['maxitems'] = 999;
// Register the "Show Single Market" plugin
$marketShowPluginSignature = \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
'Vitec',
'Marketshow',
'Show Single Market'
);
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist'][$marketShowPluginSignature] = 'pi_flexform';
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPiFlexFormValue(
$marketShowPluginSignature,
'FILE:EXT:vitec/Configuration/FlexForms/Market.xml'
);
// Register the "Show Single Solution" plugin
$solutionShowPluginSignature = \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
'Vitec',
'Solutionshow',
'Show Single Solution'
);
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist'][$solutionShowPluginSignature] = 'pi_flexform';
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPiFlexFormValue(
$solutionShowPluginSignature,
'FILE:EXT:vitec/Configuration/FlexForms/Solution.xml'
);
// Register the "Show Products by Category" plugin
$productListPluginSignature = \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
'Vitec',
'Productlist',
'Show Products by Category'
);
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist'][$productListPluginSignature] = 'pi_flexform';
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPiFlexFormValue(
$productListPluginSignature,
'FILE:EXT:vitec/Configuration/FlexForms/Productlist.xml'
);
// Register the "Show Single Product" plugin
$productShowPluginSignature = \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
'Vitec',
'Productshow',
'Show Single Product'
);
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist'][$productShowPluginSignature] = 'pi_flexform';
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPiFlexFormValue(
$productShowPluginSignature,
'FILE:EXT:vitec/Configuration/FlexForms/Productshow.xml'
);
// Register the "Shows List of all Success Stories" plugin
$usecaseListPluginSignature = \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
'Vitec',
'Usecaselist',
'Shows List of all Success Stories'
);
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist'][$usecaseListPluginSignature] = 'pi_flexform';
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPiFlexFormValue(
$usecaseListPluginSignature,
'FILE:EXT:vitec/Configuration/FlexForms/Usecaselist.xml'
);
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist'][$simplecardPluginSignature] = 'pi_flexform';
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPiFlexFormValue(
$simplecardPluginSignature,
'FILE:EXT:vitec/Configuration/FlexForms/Simplecard.xml'
);
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_excludelist']['vitec_datasheets'] = 'recursive,select_key,pages';
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['vitec_datasheets'] = 'pi_flexform';
ExtensionManagementUtility::addPiFlexFormValue(
'vitec_datasheets',
'FILE:EXT:vitec/Configuration/FlexForms/Datasheets.xml'
);
// Change frame_class to allow multiple selections
$GLOBALS['TCA']['tt_content']['columns']['frame_class']['config']['renderType'] = 'selectCheckBox';
$GLOBALS['TCA']['tt_content']['columns']['frame_class']['config']['maxitems'] = 999;
// Add custom frame_class options for Vitec
$GLOBALS['TCA']['tt_content']['columns']['frame_class']['config']['items'] = array_merge(
$GLOBALS['TCA']['tt_content']['columns']['frame_class']['config']['items'],
[
['label' => 'Vitec: Full Width', 'value' => 'vitec-full-width'],
['label' => 'Vitec: Centered Container', 'value' => 'vitec-centered'],
['label' => 'Vitec: Card Style', 'value' => 'vitec-card'],
['label' => 'Vitec: Dark Background', 'value' => 'vitec-dark'],
['label' => 'Vitec: Highlight Box', 'value' => 'vitec-highlight'],
]
);
// Add custom frame_class options for Vitec.
$GLOBALS['TCA']['tt_content']['columns']['frame_class']['config']['items'] = array_merge(
$GLOBALS['TCA']['tt_content']['columns']['frame_class']['config']['items'],
[
['label' => 'Vitec: Full Width', 'value' => 'vitec-full-width'],
['label' => 'Vitec: Centered Container', 'value' => 'vitec-centered'],
['label' => 'Vitec: Card Style', 'value' => 'vitec-card'],
['label' => 'Vitec: Dark Background', 'value' => 'vitec-dark'],
['label' => 'Vitec: Highlight Box', 'value' => 'vitec-highlight'],
]
);
})();

View File

@@ -47,7 +47,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
--palette--;;hidden,
--palette--;;access';
ExtensionManagementUtility::addPageTSConfig(<<<TSCONFIG
$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'] = ($GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'] ?? '') . "\n" . <<<'TSCONFIG'
mod.wizards.newContentElement.wizardItems.vitec.elements.vitec_cols_25_25_25_25 {
iconIdentifier = vitec-cols-25-25-25-25
title = LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:cols_25_25_25_25.title
@@ -56,5 +56,5 @@ mod.wizards.newContentElement.wizardItems.vitec.elements.vitec_cols_25_25_25_25
CType = vitec_cols_25_25_25_25
}
}
TSCONFIG);
TSCONFIG;
})();

View File

@@ -46,7 +46,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
--palette--;;hidden,
--palette--;;access';
ExtensionManagementUtility::addPageTSConfig(<<<TSCONFIG
$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'] = ($GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'] ?? '') . "\n" . <<<'TSCONFIG'
mod.wizards.newContentElement.wizardItems.vitec.elements.vitec_cols_33_33_33 {
iconIdentifier = vitec-cols-33-33-33
title = LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:cols_33_33_33.title
@@ -55,5 +55,5 @@ mod.wizards.newContentElement.wizardItems.vitec.elements.vitec_cols_33_33_33 {
CType = vitec_cols_33_33_33
}
}
TSCONFIG);
TSCONFIG;
})();

View File

@@ -45,7 +45,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
--palette--;;hidden,
--palette--;;access';
ExtensionManagementUtility::addPageTSConfig(<<<TSCONFIG
$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'] = ($GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'] ?? '') . "\n" . <<<'TSCONFIG'
mod.wizards.newContentElement.wizardItems.vitec.elements.vitec_cols_33_66 {
iconIdentifier = vitec-cols-33-66
title = LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:cols_33_66.title
@@ -54,5 +54,5 @@ mod.wizards.newContentElement.wizardItems.vitec.elements.vitec_cols_33_66 {
CType = vitec_cols_33_66
}
}
TSCONFIG);
TSCONFIG;
})();

View File

@@ -45,7 +45,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
--palette--;;hidden,
--palette--;;access';
ExtensionManagementUtility::addPageTSConfig(<<<TSCONFIG
$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'] = ($GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'] ?? '') . "\n" . <<<'TSCONFIG'
mod.wizards.newContentElement.wizardItems.vitec.elements.vitec_cols_50_50 {
iconIdentifier = vitec-cols-50-50
title = LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:cols_50_50.title
@@ -54,5 +54,5 @@ mod.wizards.newContentElement.wizardItems.vitec.elements.vitec_cols_50_50 {
CType = vitec_cols_50_50
}
}
TSCONFIG);
TSCONFIG;
})();

View File

@@ -45,7 +45,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
--palette--;;hidden,
--palette--;;access';
ExtensionManagementUtility::addPageTSConfig(<<<TSCONFIG
$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'] = ($GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'] ?? '') . "\n" . <<<'TSCONFIG'
mod.wizards.newContentElement.wizardItems.vitec.elements.vitec_cols_66_33 {
iconIdentifier = vitec-cols-66-33
title = LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:cols_66_33.title
@@ -54,5 +54,5 @@ mod.wizards.newContentElement.wizardItems.vitec.elements.vitec_cols_66_33 {
CType = vitec_cols_66_33
}
}
TSCONFIG);
TSCONFIG;
})();

View File

@@ -56,7 +56,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
'vitec_container'
);
ExtensionManagementUtility::addPageTSConfig(<<<TSCONFIG
$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'] = ($GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'] ?? '') . "\n" . <<<'TSCONFIG'
mod.wizards.newContentElement.wizardItems.vitec.elements.vitec_container {
iconIdentifier = vitec-container
title = LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:container.title
@@ -65,5 +65,5 @@ mod.wizards.newContentElement.wizardItems.vitec.elements.vitec_container {
CType = vitec_container
}
}
TSCONFIG);
TSCONFIG;
})();

View File

@@ -1,64 +0,0 @@
<?php
declare(strict_types=1);
defined('TYPO3') or die();
use B13\Container\Tca\ContainerConfiguration;
use B13\Container\Tca\Registry;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
(static function (): void {
$l = 'LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:';
/** @var Registry $registry */
$registry = GeneralUtility::makeInstance(Registry::class);
$registry->configureContainer(
(new ContainerConfiguration(
'vitec_container',
$l . 'container.title',
$l . 'container.description',
[
[
['name' => $l . 'container.column', 'colPos' => 220],
],
]
))
->setIcon('EXT:vitec/Resources/Public/Icons/vitec-container.svg')
->setGroup('vitec')
->setSaveAndCloseInNewContentElementWizard(true)
);
$GLOBALS['TCA']['tt_content']['types']['vitec_container']['showitem'] =
'--palette--;;general,
header;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:section.heading,
subheader;LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:section.subline,
tx_vitec_bg_variant,
pi_flexform,
--div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.appearance,
--palette--;;frames,
--palette--;;appearanceLinks,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language,
--palette--;;language,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access,
--palette--;;hidden,
--palette--;;access';
// Bind the Container FlexForm to this CType.
// Core tt_content.pi_flexform uses ds_pointerField = 'list_type,CType',
// so the CType value is a valid data-structure key.
$GLOBALS['TCA']['tt_content']['columns']['pi_flexform']['config']['ds']['vitec_container'] =
'FILE:EXT:vitec/Configuration/FlexForms/Container.xml';
ExtensionManagementUtility::addPageTSConfig(<<<TSCONFIG
mod.wizards.newContentElement.wizardItems.vitec.elements.vitec_container {
iconIdentifier = vitec-container
title = LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:container.title
description = LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:container.description
tt_content_defValues {
CType = vitec_container
}
}
TSCONFIG);
})();

View File

@@ -28,10 +28,10 @@ use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
]);
// Register VITEC wizard group header
ExtensionManagementUtility::addPageTSConfig(<<<TSCONFIG
$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'] = ($GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'] ?? '') . "\n" . <<<'TSCONFIG'
mod.wizards.newContentElement.wizardItems.vitec {
header = LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:group.header
show = *
}
TSCONFIG);
TSCONFIG;
})();

View File

@@ -192,27 +192,27 @@ return [
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_TEXT => [
\TYPO3\CMS\Core\Resource\FileType::TEXT->value => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_IMAGE => [
\TYPO3\CMS\Core\Resource\FileType::IMAGE->value => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_AUDIO => [
\TYPO3\CMS\Core\Resource\FileType::AUDIO->value => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_VIDEO => [
\TYPO3\CMS\Core\Resource\FileType::VIDEO->value => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_APPLICATION => [
\TYPO3\CMS\Core\Resource\FileType::APPLICATION->value => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
--palette--;;filePalette'

View File

View File

@@ -1,541 +0,0 @@
<?php
return [
'ctrl' => [
'title' => 'VITEC Product',
'label' => 'title',
'tstamp' => 'tstamp',
'crdate' => 'crdate',
'cruser_id' => 'cruser_id',
'versioningWS' => true,
'languageField' => 'sys_language_uid',
'transOrigPointerField' => 'l10n_parent',
'transOrigDiffSourceField' => 'l10n_diffsource',
'delete' => 'deleted',
'enablecolumns' => [
'disabled' => 'hidden',
'starttime' => 'starttime',
'endtime' => 'endtime',
],
'searchFields' => 'title,slug',
'iconfile' => 'EXT:vitec/Resources/Public/Icons/tx_vitec_domain_model_product.gif',
'security' => [
'ignorePageTypeRestriction' => true,
],
],
'types' => [
'1' => ['showitem' => 'title, subtitle, slug, teaser, description, applications, highlights, contentelement, contentelementcta, downloads,
--div--;SEO, seotitle, urltitle, seometa, keywords, structureddata,
--div--;Images and Videos, productimage, ogimage, video,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:categories, categories,
--div--;Visibility, hideonapp, hideonwebsite, hideondatasheets, hideonproducts, shortcut, shortcutpid,
--div--;Misc, legacy, supportproduct, subproduct, relatedprodukt,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access, hidden, starttime, endtime'],
],
'columns' => [
'sys_language_uid' => [
'exclude' => true,
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
'config' => [
'type' => 'language',
],
],
'l10n_parent' => [
'displayCond' => 'FIELD:sys_language_uid:>:0',
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'default' => 0,
'items' => [
['', 0],
],
'foreign_table' => 'tx_vitec_domain_model_product',
'foreign_table_where' => 'AND {#tx_vitec_domain_model_product}.{#pid}=###CURRENT_PID### AND {#tx_vitec_domain_model_product}.{#sys_language_uid} IN (-1,0)',
],
],
'l10n_diffsource' => [
'config' => [
'type' => 'passthrough',
],
],
'hidden' => [
'exclude' => true,
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.visible',
'config' => [
'type' => 'check',
'renderType' => 'checkboxToggle',
'items' => [
[
0 => '',
1 => '',
'invertStateDisplay' => true
]
],
],
],
'starttime' => [
'exclude' => true,
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.starttime',
'config' => [
'type' => 'input',
'renderType' => 'inputDateTime',
'eval' => 'datetime,int',
'default' => 0,
'behaviour' => [
'allowLanguageSynchronization' => true
]
],
],
'endtime' => [
'exclude' => true,
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.endtime',
'config' => [
'type' => 'input',
'renderType' => 'inputDateTime',
'eval' => 'datetime,int',
'default' => 0,
'range' => [
'upper' => mktime(0, 0, 0, 1, 1, 2038)
],
'behaviour' => [
'allowLanguageSynchronization' => true
]
],
],
'categories' => [
'config' => [
'type' => 'category'
]
],
'title' => [
'exclude' => false,
'label' => 'LLL:EXT:vitec/Resources/Private/Language/locallang_db.xlf:tx_vitec_domain_model_product.title',
'description' => 'LLL:EXT:vitec/Resources/Private/Language/locallang_db.xlf:tx_vitec_domain_model_product.title.description',
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
'required' => true,
'default' => ''
],
],
'slug' => [
'exclude' => false,
'label' => 'LLL:EXT:vitec/Resources/Private/Language/locallang_db.xlf:tx_vitec_domain_model_product.slug',
'description' => 'LLL:EXT:vitec/Resources/Private/Language/locallang_db.xlf:tx_vitec_domain_model_product.slug.description',
'config' => [
'type' => 'slug',
'size' => 50,
'generatorOptions' => [
'fields' => ['title'], // TODO: adjust this field to the one you want to use
'fieldSeparator' => '-',
'replacements' => [
'/' => '',
],
],
'fallbackCharacter' => '-',
'eval' => 'uniqueInPid',
],
],
'seotitle' => [
'exclude' => false,
'label' => 'SEO-Title',
'description' => 'SEO specific title, used for sharing options',
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
'default' => ''
],
],
'urltitle' => [
'exclude' => false,
'label' => 'URL-Title',
'description' => 'LLL:EXT:vitec/Resources/Private/Language/locallang_db.xlf:tx_vitec_domain_model_product.urltitle.description',
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
'default' => ''
],
],
'video' => [
'exclude' => false,
'label' => 'Product Video - just the Youtube Clip ID',
'description' => 'Product Video - just the Youtube Clip ID',
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
'default' => ''
],
],
'downloads' => [
'exclude' => true,
'label' => 'Downloads',
'config' => [
'type' => 'select',
'renderType' => 'selectMultipleSideBySide',
'foreign_table' => 'tx_vitec_domain_model_download',
'MM' => 'tx_vitec_product_download_mm', // Define the MM table for the relation
'size' => 10,
'maxitems' => 9999,
'minitems' => 0,
'enableMultiSelectFilterTextfield' => true, // Optional: Adds a search box for filtering
],
],
'structureddata' => [
'exclude' => true,
'label' => 'Structured Data in JSON Format',
'config' => [
'type' => 'text',
'cols' => 40,
'rows' => 15,
'eval' => 'trim'
]
],
'keywords' => [
'exclude' => true,
'label' => 'Keywords',
'description' => 'Keywords for SEO, separated by commas',
'config' => [
'type' => 'text',
'cols' => 40,
'rows' => 15,
'eval' => 'trim'
]
],
'seometa' => [
'exclude' => true,
'label' => 'SEO Meta Description',
'description' => 'SEO specific meta description, used for sharing options',
'config' => [
'type' => 'text',
'cols' => 40,
'rows' => 15,
'eval' => 'trim'
]
],
'teaser' => [
'exclude' => true,
'label' => 'Short Teaser (optional)',
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
'default' => ''
],
],
'subtitle' => [
'exclude' => true,
'label' => 'Subtitle',
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
'default' => ''
],
],
'hideonapp' => [
'exclude' => true,
'label' => 'If checked - Product will not be shown on App',
'config' => [
'type' => 'check',
'renderType' => 'checkboxToggle',
'items' => [
[
0 => '',
1 => '',
'invertStateDisplay' => false
]
],
],
],
'hideonwebsite' => [
'exclude' => true,
'label' => 'If checked - Product will not be shown on Website',
'config' => [
'type' => 'check',
'renderType' => 'checkboxToggle',
'items' => [
[
0 => '',
1 => '',
'invertStateDisplay' => false
]
],
],
],
'hideonproducts' => [
'exclude' => true,
'label' => 'If checked - Product will not be shown on Product Section',
'config' => [
'type' => 'check',
'renderType' => 'checkboxToggle',
'items' => [
[
0 => '',
1 => '',
'invertStateDisplay' => false
]
],
],
],
'hideondatasheets' => [
'exclude' => true,
'label' => 'If checked - Product will not be shown on Datasheets Page',
'config' => [
'type' => 'check',
'renderType' => 'checkboxToggle',
'items' => [
[
0 => '',
1 => '',
'invertStateDisplay' => false
]
],
],
],
'applications' => [
'exclude' => true,
'label' => 'Applications',
'config' => [
'type' => 'text',
'enableRichtext' => 'true',
'eval' => 'trim',
'default' => ''
],
'defaultExtras' => 'richtext:rte_transform[mode=ts_css]'
],
'description' => [
'exclude' => true,
'label' => 'Description',
'config' => [
'type' => 'text',
'enableRichtext' => 'true',
'eval' => 'trim',
'default' => ''
],
'defaultExtras' => 'richtext:rte_transform[mode=ts_css]'
],
'highlights' => [
'exclude' => true,
'label' => 'Highlights',
'config' => [
'type' => 'text',
'enableRichtext' => 'true',
'eval' => 'trim',
'default' => ''
],
'defaultExtras' => 'richtext:rte_transform[mode=ts_css]'
],
'shortcut' => [
'exclude' => true,
'label' => 'Does this Product have a custom Page',
'config' => [
'type' => 'check',
'renderType' => 'checkboxToggle',
'items' => [
[
0 => '',
1 => '',
'invertStateDisplay' => false
]
],
],
],
'shortcutpid' => [
'exclude' => false,
'label' => 'Page ID',
'description' => 'PID of the custom page',
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
'default' => ''
],
],
'legacy' => [
'exclude' => true,
'label' => 'Is this a legacy produc?',
'config' => [
'type' => 'check',
'renderType' => 'checkboxToggle',
'items' => [
[
0 => '',
1 => '',
'invertStateDisplay' => false
]
],
],
],
'supportproduct' => [
'exclude' => true,
'label' => 'Is this a support product?',
'config' => [
'type' => 'check',
'renderType' => 'checkboxToggle',
'items' => [
[
0 => '',
1 => '',
'invertStateDisplay' => false
]
],
],
],
'subproduct' => [
'exclude' => true,
'label' => 'Product is a sub-products',
'description' => 'This Product will not be shown as a main product',
'config' => [
'type' => 'check',
'renderType' => 'checkboxToggle',
'items' => [
[
0 => '',
1 => '',
'invertStateDisplay' => false
]
],
],
],
'relatedprodukt' => [
'exclude' => true,
'label' => 'Related Products',
'description' => 'Select related products for this product',
'config' => [
'type' => 'select',
'renderType' => 'selectMultipleSideBySide',
'foreign_table' => 'tx_vitec_domain_model_product', // Reference the same table
'MM' => 'tx_vitec_product_related_mm', // Define the MM table for the relation
'size' => 10,
'maxitems' => 9999,
'minitems' => 0,
'enableMultiSelectFilterTextfield' => true, // Optional: Adds a search box for filtering
],
],
'productimage' => [
'exclude' => true,
'label' => 'Product Image(s)',
'config' => [
'type' => 'inline',
'foreign_table' => 'sys_file_reference',
'foreign_field' => 'uid_foreign',
'foreign_sortby' => 'sorting_foreign',
'foreign_table_field' => 'tablenames',
'foreign_match_fields' => [
'fieldname' => 'productimage',
],
'appearance' => [
'collapseAll' => true,
'levelLinksPosition' => 'top',
'showSynchronizationLink' => true,
'showPossibleLocalizationRecords' => true,
'showAllLocalizationLink' => true,
],
'behaviour' => [
'allowLanguageSynchronization' => true,
],
'filter' => [
[
'userFunc' => \TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter::class . '->filterInlineChildren',
'parameters' => [
'allowedFileExtensions' => 'jpg,jpeg,png,gif',
],
],
],
'maxitems' => 10,
'minitems' => 0,
],
],
'ogimage' => [
'exclude' => true,
'label' => 'Open Graph Image',
'config' => [
'type' => 'inline',
'foreign_table' => 'sys_file_reference',
'foreign_field' => 'uid_foreign',
'foreign_sortby' => 'sorting_foreign',
'foreign_table_field' => 'tablenames',
'foreign_match_fields' => [
'fieldname' => 'ogimage',
],
'appearance' => [
'collapseAll' => true,
'levelLinksPosition' => 'top',
'showSynchronizationLink' => true,
'showPossibleLocalizationRecords' => true,
'showAllLocalizationLink' => true,
],
'behaviour' => [
'allowLanguageSynchronization' => true,
],
'filter' => [
[
'userFunc' => \TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter::class . '->filterInlineChildren',
'parameters' => [
'allowedFileExtensions' => 'jpg,jpeg,png,gif,webp',
],
],
],
'maxitems' => 1, // Allow only one image
'minitems' => 0,
],
],
'contentelement' => [
'exclude' => true,
'label' => 'Select Content Element for Key Features Section',
'config' => [
'type' => 'input',
'renderType' => 'inputLink',
'softref' => 'typolink',
'eval' => 'trim',
'fieldControl' => [
'linkPopup' => [
'options' => [
'title' => 'Select Content Element',
'blindLinkOptions' => 'mail,folder,url', // Disable unnecessary link types
'blindLinkFields' => 'class,params', // Disable unnecessary fields
],
],
],
],
],
'contentelementcta' => [
'exclude' => true,
'label' => 'Select Content Element for CTA Section',
'config' => [
'type' => 'input',
'renderType' => 'inputLink',
'softref' => 'typolink',
'eval' => 'trim',
'fieldControl' => [
'linkPopup' => [
'options' => [
'title' => 'Select Content Element',
'blindLinkOptions' => 'mail,folder,url', // Disable unnecessary link types
'blindLinkFields' => 'class,params', // Disable unnecessary fields
],
],
],
],
],
/* ----------------------------------------------------- */
],
];

View File

@@ -1,576 +0,0 @@
<?php
return [
'ctrl' => [
'title' => 'VITEC Product',
'label' => 'title',
'tstamp' => 'tstamp',
'crdate' => 'crdate',
'cruser_id' => 'cruser_id',
'versioningWS' => true,
'languageField' => 'sys_language_uid',
'transOrigPointerField' => 'l10n_parent',
'transOrigDiffSourceField' => 'l10n_diffsource',
'delete' => 'deleted',
'enablecolumns' => [
'disabled' => 'hidden',
'starttime' => 'starttime',
'endtime' => 'endtime',
],
'searchFields' => 'title,slug',
'iconfile' => 'EXT:vitec/Resources/Public/Icons/tx_vitec_domain_model_product.gif',
'security' => [
'ignorePageTypeRestriction' => true,
],
],
'types' => [
'1' => ['showitem' => 'title, subtitle, slug, teaser, description, applications, highlights, contentelement, contentelementcta, downloads,
--div--;SEO, seotitle, urltitle, seometa, keywords, structureddata,
--div--;Images and Videos, productimage, ogimage, video, videofile,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:categories, categories,
--div--;Visibility, hideonapp, hideonwebsite, hideondatasheets, hideonproducts, shortcut, shortcutpid,
--div--;Misc, legacy, supportproduct, subproduct, relatedprodukt,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access, hidden, starttime, endtime'],
],
'columns' => [
'sys_language_uid' => [
'exclude' => true,
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
'config' => [
'type' => 'language',
],
],
'l10n_parent' => [
'displayCond' => 'FIELD:sys_language_uid:>:0',
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'default' => 0,
'items' => [
['', 0],
],
'foreign_table' => 'tx_vitec_domain_model_product',
'foreign_table_where' => 'AND {#tx_vitec_domain_model_product}.{#pid}=###CURRENT_PID### AND {#tx_vitec_domain_model_product}.{#sys_language_uid} IN (-1,0)',
],
],
'l10n_diffsource' => [
'config' => [
'type' => 'passthrough',
],
],
'hidden' => [
'exclude' => true,
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.visible',
'config' => [
'type' => 'check',
'renderType' => 'checkboxToggle',
'items' => [
[
0 => '',
1 => '',
'invertStateDisplay' => true
]
],
],
],
'starttime' => [
'exclude' => true,
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.starttime',
'config' => [
'type' => 'input',
'renderType' => 'inputDateTime',
'eval' => 'datetime,int',
'default' => 0,
'behaviour' => [
'allowLanguageSynchronization' => true
]
],
],
'endtime' => [
'exclude' => true,
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.endtime',
'config' => [
'type' => 'input',
'renderType' => 'inputDateTime',
'eval' => 'datetime,int',
'default' => 0,
'range' => [
'upper' => mktime(0, 0, 0, 1, 1, 2038)
],
'behaviour' => [
'allowLanguageSynchronization' => true
]
],
],
'categories' => [
'config' => [
'type' => 'category'
]
],
'title' => [
'exclude' => false,
'label' => 'LLL:EXT:vitec/Resources/Private/Language/locallang_db.xlf:tx_vitec_domain_model_product.title',
'description' => 'LLL:EXT:vitec/Resources/Private/Language/locallang_db.xlf:tx_vitec_domain_model_product.title.description',
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
'required' => true,
'default' => ''
],
],
'slug' => [
'exclude' => false,
'label' => 'LLL:EXT:vitec/Resources/Private/Language/locallang_db.xlf:tx_vitec_domain_model_product.slug',
'description' => 'LLL:EXT:vitec/Resources/Private/Language/locallang_db.xlf:tx_vitec_domain_model_product.slug.description',
'config' => [
'type' => 'slug',
'size' => 50,
'generatorOptions' => [
'fields' => ['title'], // TODO: adjust this field to the one you want to use
'fieldSeparator' => '-',
'replacements' => [
'/' => '',
],
],
'fallbackCharacter' => '-',
'eval' => 'uniqueInPid',
],
],
'seotitle' => [
'exclude' => false,
'label' => 'SEO-Title',
'description' => 'SEO specific title, used for sharing options',
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
'default' => ''
],
],
'urltitle' => [
'exclude' => false,
'label' => 'URL-Title',
'description' => 'LLL:EXT:vitec/Resources/Private/Language/locallang_db.xlf:tx_vitec_domain_model_product.urltitle.description',
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
'default' => ''
],
],
'video' => [
'exclude' => false,
'label' => 'Product Video - just the Youtube Clip ID',
'description' => 'Product Video - just the Youtube Clip ID',
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
'default' => ''
],
],
'downloads' => [
'exclude' => true,
'label' => 'Downloads',
'config' => [
'type' => 'select',
'renderType' => 'selectMultipleSideBySide',
'foreign_table' => 'tx_vitec_domain_model_download',
'MM' => 'tx_vitec_product_download_mm', // Define the MM table for the relation
'size' => 10,
'maxitems' => 9999,
'minitems' => 0,
'enableMultiSelectFilterTextfield' => true, // Optional: Adds a search box for filtering
],
],
'structureddata' => [
'exclude' => true,
'label' => 'Structured Data in JSON Format',
'config' => [
'type' => 'text',
'cols' => 40,
'rows' => 15,
'eval' => 'trim'
]
],
'keywords' => [
'exclude' => true,
'label' => 'Keywords',
'description' => 'Keywords for SEO, separated by commas',
'config' => [
'type' => 'text',
'cols' => 40,
'rows' => 15,
'eval' => 'trim'
]
],
'seometa' => [
'exclude' => true,
'label' => 'SEO Meta Description',
'description' => 'SEO specific meta description, used for sharing options',
'config' => [
'type' => 'text',
'cols' => 40,
'rows' => 15,
'eval' => 'trim'
]
],
'teaser' => [
'exclude' => true,
'label' => 'Short Teaser (optional)',
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
'default' => ''
],
],
'subtitle' => [
'exclude' => true,
'label' => 'Subtitle',
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
'default' => ''
],
],
'hideonapp' => [
'exclude' => true,
'label' => 'If checked - Product will not be shown on App',
'config' => [
'type' => 'check',
'renderType' => 'checkboxToggle',
'items' => [
[
0 => '',
1 => '',
'invertStateDisplay' => false
]
],
],
],
'hideonwebsite' => [
'exclude' => true,
'label' => 'If checked - Product will not be shown on Website',
'config' => [
'type' => 'check',
'renderType' => 'checkboxToggle',
'items' => [
[
0 => '',
1 => '',
'invertStateDisplay' => false
]
],
],
],
'hideonproducts' => [
'exclude' => true,
'label' => 'If checked - Product will not be shown on Product Section',
'config' => [
'type' => 'check',
'renderType' => 'checkboxToggle',
'items' => [
[
0 => '',
1 => '',
'invertStateDisplay' => false
]
],
],
],
'hideondatasheets' => [
'exclude' => true,
'label' => 'If checked - Product will not be shown on Datasheets Page',
'config' => [
'type' => 'check',
'renderType' => 'checkboxToggle',
'items' => [
[
0 => '',
1 => '',
'invertStateDisplay' => false
]
],
],
],
'applications' => [
'exclude' => true,
'label' => 'Applications',
'config' => [
'type' => 'text',
'enableRichtext' => 'true',
'eval' => 'trim',
'default' => ''
],
'defaultExtras' => 'richtext:rte_transform[mode=ts_css]'
],
'description' => [
'exclude' => true,
'label' => 'Description',
'config' => [
'type' => 'text',
'enableRichtext' => 'true',
'eval' => 'trim',
'default' => ''
],
'defaultExtras' => 'richtext:rte_transform[mode=ts_css]'
],
'highlights' => [
'exclude' => true,
'label' => 'Highlights',
'config' => [
'type' => 'text',
'enableRichtext' => 'true',
'eval' => 'trim',
'default' => ''
],
'defaultExtras' => 'richtext:rte_transform[mode=ts_css]'
],
'shortcut' => [
'exclude' => true,
'label' => 'Does this Product have a custom Page',
'config' => [
'type' => 'check',
'renderType' => 'checkboxToggle',
'items' => [
[
0 => '',
1 => '',
'invertStateDisplay' => false
]
],
],
],
'shortcutpid' => [
'exclude' => false,
'label' => 'Page ID',
'description' => 'PID of the custom page',
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
'default' => ''
],
],
'legacy' => [
'exclude' => true,
'label' => 'Is this a legacy produc?',
'config' => [
'type' => 'check',
'renderType' => 'checkboxToggle',
'items' => [
[
0 => '',
1 => '',
'invertStateDisplay' => false
]
],
],
],
'supportproduct' => [
'exclude' => true,
'label' => 'Is this a support product?',
'config' => [
'type' => 'check',
'renderType' => 'checkboxToggle',
'items' => [
[
0 => '',
1 => '',
'invertStateDisplay' => false
]
],
],
],
'subproduct' => [
'exclude' => true,
'label' => 'Product is a sub-products',
'description' => 'This Product will not be shown as a main product',
'config' => [
'type' => 'check',
'renderType' => 'checkboxToggle',
'items' => [
[
0 => '',
1 => '',
'invertStateDisplay' => false
]
],
],
],
'relatedprodukt' => [
'exclude' => true,
'label' => 'Related Products',
'description' => 'Select related products for this product',
'config' => [
'type' => 'select',
'renderType' => 'selectMultipleSideBySide',
'foreign_table' => 'tx_vitec_domain_model_product', // Reference the same table
'MM' => 'tx_vitec_product_related_mm', // Define the MM table for the relation
'size' => 10,
'maxitems' => 9999,
'minitems' => 0,
'enableMultiSelectFilterTextfield' => true, // Optional: Adds a search box for filtering
],
],
'productimage' => [
'exclude' => true,
'label' => 'Product Image(s)',
'config' => [
'type' => 'inline',
'foreign_table' => 'sys_file_reference',
'foreign_field' => 'uid_foreign',
'foreign_sortby' => 'sorting_foreign',
'foreign_table_field' => 'tablenames',
'foreign_match_fields' => [
'fieldname' => 'productimage',
],
'appearance' => [
'collapseAll' => true,
'levelLinksPosition' => 'top',
'showSynchronizationLink' => true,
'showPossibleLocalizationRecords' => true,
'showAllLocalizationLink' => true,
],
'behaviour' => [
'allowLanguageSynchronization' => true,
],
'filter' => [
[
'userFunc' => \TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter::class . '->filterInlineChildren',
'parameters' => [
'allowedFileExtensions' => 'jpg,jpeg,png,gif',
],
],
],
'maxitems' => 10,
'minitems' => 0,
],
],
'ogimage' => [
'exclude' => true,
'label' => 'Open Graph Image',
'config' => [
'type' => 'inline',
'foreign_table' => 'sys_file_reference',
'foreign_field' => 'uid_foreign',
'foreign_sortby' => 'sorting_foreign',
'foreign_table_field' => 'tablenames',
'foreign_match_fields' => [
'fieldname' => 'ogimage',
],
'appearance' => [
'collapseAll' => true,
'levelLinksPosition' => 'top',
'showSynchronizationLink' => true,
'showPossibleLocalizationRecords' => true,
'showAllLocalizationLink' => true,
],
'behaviour' => [
'allowLanguageSynchronization' => true,
],
'filter' => [
[
'userFunc' => \TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter::class . '->filterInlineChildren',
'parameters' => [
'allowedFileExtensions' => 'jpg,jpeg,png,gif,webp',
],
],
],
'maxitems' => 1, // Allow only one image
'minitems' => 0,
],
],
'videofile' => [
'exclude' => true,
'label' => 'Video File (Upload or Local)',
'config' => [
'type' => 'inline',
'foreign_table' => 'sys_file_reference',
'foreign_field' => 'uid_foreign',
'foreign_sortby' => 'sorting_foreign',
'foreign_table_field' => 'tablenames',
'foreign_match_fields' => [
'fieldname' => 'videofile',
],
'appearance' => [
'collapseAll' => true,
'levelLinksPosition' => 'top',
'showSynchronizationLink' => true,
'showPossibleLocalizationRecords' => true,
'showAllLocalizationLink' => true,
],
'behaviour' => [
'allowLanguageSynchronization' => true,
],
'filter' => [
[
'userFunc' => \TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter::class . '->filterInlineChildren',
'parameters' => [
'allowedFileExtensions' => 'mp4,webm,ogv,mov,m4v',
],
],
],
'maxitems' => 1,
'minitems' => 0,
],
],
'contentelement' => [
'exclude' => true,
'label' => 'Select Content Element for Key Features Section',
'config' => [
'type' => 'input',
'renderType' => 'inputLink',
'softref' => 'typolink',
'eval' => 'trim',
'fieldControl' => [
'linkPopup' => [
'options' => [
'title' => 'Select Content Element',
'blindLinkOptions' => 'mail,folder,url', // Disable unnecessary link types
'blindLinkFields' => 'class,params', // Disable unnecessary fields
],
],
],
],
],
'contentelementcta' => [
'exclude' => true,
'label' => 'Select Content Element for CTA Section',
'config' => [
'type' => 'input',
'renderType' => 'inputLink',
'softref' => 'typolink',
'eval' => 'trim',
'fieldControl' => [
'linkPopup' => [
'options' => [
'title' => 'Select Content Element',
'blindLinkOptions' => 'mail,folder,url', // Disable unnecessary link types
'blindLinkFields' => 'class,params', // Disable unnecessary fields
],
],
],
],
],
/* ----------------------------------------------------- */
],
];

View File

@@ -1,89 +0,0 @@
# =============================================================================
# VITEC container content elements — self-contained JSON rendering
# Children collected via Evomedien\Vitec\DataProcessing\ContainerChildrenProcessor
# (exception-safe; returns [] on any error, never crashes the outer CE).
# =============================================================================
tt_content.vitec_cols_50_50 = JSON
tt_content.vitec_cols_50_50 {
fields {
id = INT
id.field = uid
type = TEXT
type.field = CType
colPos = INT
colPos.field = colPos
categories = COA
categories {
10 = CONTENT
10 {
table = sys_category
select {
pidInList = root
selectFields = sys_category.title
join = sys_category_record_mm on sys_category_record_mm.uid_local = sys_category.uid
where {
field = uid
wrap = AND sys_category_record_mm.tablenames = 'tt_content' AND sys_category_record_mm.uid_foreign=|
}
}
renderObj = TEXT
renderObj {
field = title
wrap = |###BREAK###
}
}
stdWrap.split {
token = ###BREAK###
cObjNum = 1 |*|2|*| 3
1 {
current = 1
stdWrap.wrap = |
}
2 {
current = 1
stdWrap.wrap = ,|
}
3 {
current = 1
stdWrap.wrap = |
}
}
}
appearance = JSON
appearance {
fields {
layout = TEXT
layout.field = layout
frameClass = TEXT
frameClass.field = frame_class
spaceBefore = TEXT
spaceBefore.field = space_before_class
spaceAfter = TEXT
spaceAfter.field = space_after_class
}
}
header = TEXT
header.field = header
subheader = TEXT
subheader.field = subheader
tx_vitec_bg_variant = TEXT
tx_vitec_bg_variant.field = tx_vitec_bg_variant
items = JSON
items {
dataProcessing {
10 = Evomedien\Vitec\DataProcessing\ContainerChildrenProcessor
10.as = items
}
}
}
}
tt_content.vitec_cols_33_33_33 =< tt_content.vitec_cols_50_50
tt_content.vitec_cols_25_25_25_25 =< tt_content.vitec_cols_50_50
tt_content.vitec_cols_66_33 =< tt_content.vitec_cols_50_50
tt_content.vitec_cols_33_66 =< tt_content.vitec_cols_50_50

View File

@@ -13,8 +13,7 @@ mod {
title = List of VITEC Products
description = LLL:EXT:vitec/Resources/Private/Language/locallang_db.xlf:tx_vitec_productlist.description
tt_content_defValues {
CType = list
list_type = vitec_productlist
CType = vitec_productlist
}
}
productshow {
@@ -22,8 +21,7 @@ mod {
title = Show single VITEC Product
description = Either show a single product coming from a list, OR select a specific product in flexform
tt_content_defValues {
CType = list
list_type = vitec_productshow
CType = vitec_productshow
}
}
usecaseshow {
@@ -31,8 +29,7 @@ mod {
title = Show single VITEC Success Story
description = Shows a selected Success Story in a Card with different layouts
tt_content_defValues {
CType = list
list_type = vitec_usecaseshow
CType = vitec_usecaseshow
}
}
marketshow {
@@ -40,8 +37,7 @@ mod {
title = Show single VITEC Market
description = Shows a selected Market in a Card with different layouts
tt_content_defValues {
CType = list
list_type = vitec_marketshow
CType = vitec_marketshow
}
}
solutionshow {
@@ -49,8 +45,7 @@ mod {
title = Show single VITEC Solution
description = Shows a selected Solution in a Card with different layouts
tt_content_defValues {
CType = list
list_type = vitec_solutionshow
CType = vitec_solutionshow
}
}
usecaselist {
@@ -58,8 +53,7 @@ mod {
title = Show all VITEC Success Stories
description = LLL:EXT:vitec/Resources/Private/Language/locallang_db.xlf:tx_vitec_usecaselist.description
tt_content_defValues {
CType = list
list_type = vitec_usecaselist
CType = vitec_usecaselist
}
}
downloadcard {
@@ -67,8 +61,7 @@ mod {
title = Downloadcard for single Download
description = LLL:EXT:vitec/Resources/Private/Language/locallang_db.xlf:tx_vitec_usecaselist.description
tt_content_defValues {
CType = list
list_type = vitec_downloadcard
CType = vitec_downloadcard
}
}
downloadcardcollection {
@@ -76,8 +69,7 @@ mod {
title = Downloadcard Collection
description = Multiple Downloads in one Card
tt_content_defValues {
CType = list
list_type = vitec_downloadcardcollection
CType = vitec_downloadcardcollection
}
}
datasheets {
@@ -85,8 +77,7 @@ mod {
title = VITEC Datasheets
description = Interactive datasheets with filtering and download functionality
tt_content_defValues {
CType = list
list_type = vitec_datasheets
CType = vitec_datasheets
}
}
simplecard {
@@ -94,8 +85,7 @@ mod {
title = Simple Card
description = Simple Card (Image, Title, Text, Link)
tt_content_defValues {
CType = list
list_type = vitec_simplecard
CType = vitec_simplecard
}
}