Files
VITEC-website/packages/vitec/Configuration/TCA/Overrides/tt_content_vitec_shared.php
2026-08-14 11:07:55 +02:00

238 lines
11 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
defined('TYPO3') or die();
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
(static function (): void {
$l = 'LLL:EXT:vitec/Resources/Private/Language/locallang_containers.xlf:';
// Shared field: Background Variant for all VITEC containers
ExtensionManagementUtility::addTCAcolumns('tt_content', [
'tx_vitec_bg_variant' => [
'label' => $l . 'bg_variant.label',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'items' => [
['label' => $l . 'bg_variant.option.none', 'value' => 'none'],
['label' => $l . 'bg_variant.option.orange', 'value' => 'orange'],
['label' => $l . 'bg_variant.option.blue', 'value' => 'blue'],
['label' => $l . 'bg_variant.option.graphite', 'value' => 'graphite'],
['label' => $l . 'bg_variant.option.midnight', 'value' => 'midnight'],
],
'default' => 'none',
],
],
]);
// -------------------------------------------------------------------------
// Shared background image for the VITEC containers, with the two settings a
// background actually needs: how it scales and where it sits.
//
// Deliberately no crop variants (Clause 9.9): a background is framed by
// background-size / background-position in CSS, not by cropping the file.
// Cropping here would fight the two selects below.
//
// The values are written so the front end can hand them straight to CSS.
// `stretch` is the one exception - it has no CSS keyword and maps to
// `100% 100%`; spelled out here because "stretch" is what an editor looks
// for, not "100% 100%".
// -------------------------------------------------------------------------
ExtensionManagementUtility::addTCAcolumns('tt_content', [
'tx_vitec_bg_image' => [
'label' => $l . 'bg_image.label',
'description' => $l . 'bg_image.description',
'config' => [
'type' => 'file',
'maxitems' => 1,
'allowed' => 'common-image-types',
],
],
'tx_vitec_bg_size' => [
'label' => $l . 'bg_size.label',
// Re-renders the form when the value changes, so the "Size %" field
// below appears the moment "Custom" is picked instead of only after
// a save. FormEngine keeps the current form state across the reload
// (SingleFieldContainer -> ReloadOnFieldChange); whether it asks
// first is the editor's own "verify on change" preference.
'onChange' => 'reload',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'items' => [
['label' => $l . 'bg_size.option.cover', 'value' => 'cover'],
['label' => $l . 'bg_size.option.contain', 'value' => 'contain'],
['label' => $l . 'bg_size.option.stretch', 'value' => 'stretch'],
['label' => $l . 'bg_size.option.auto', 'value' => 'auto'],
['label' => $l . 'bg_size.option.custom', 'value' => 'custom'],
],
'default' => 'cover',
],
],
// Only meaningful together with bg_size = custom, and hidden otherwise
// so the form never shows a percentage that has no effect. The renderer
// resolves it into the emitted `size` (e.g. "80%"), so the front end
// keeps getting one CSS-ready value instead of a second special case.
'tx_vitec_bg_size_percent' => [
'label' => $l . 'bg_size_percent.label',
'description' => $l . 'bg_size_percent.description',
'displayCond' => 'FIELD:tx_vitec_bg_size:=:custom',
'config' => [
'type' => 'number',
'size' => 6,
'default' => 100,
'range' => [
'lower' => 1,
'upper' => 500,
],
],
],
'tx_vitec_bg_position' => [
'label' => $l . 'bg_position.label',
// Same reason as on bg_size: reveal the custom fields immediately.
'onChange' => 'reload',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'items' => [
['label' => $l . 'bg_position.option.top_left', 'value' => 'left top'],
['label' => $l . 'bg_position.option.top_center', 'value' => 'center top'],
['label' => $l . 'bg_position.option.top_right', 'value' => 'right top'],
['label' => $l . 'bg_position.option.center_left', 'value' => 'left center'],
['label' => $l . 'bg_position.option.centered', 'value' => 'center center'],
['label' => $l . 'bg_position.option.center_right', 'value' => 'right center'],
['label' => $l . 'bg_position.option.bottom_left', 'value' => 'left bottom'],
['label' => $l . 'bg_position.option.bottom_center', 'value' => 'center bottom'],
['label' => $l . 'bg_position.option.bottom_right', 'value' => 'right bottom'],
['label' => $l . 'bg_position.option.custom', 'value' => 'custom'],
],
'default' => 'center center',
],
],
]);
// Custom position: four edge offsets in percent, shown only when the select
// is on "custom". `nullable` matters here - an empty field has to stay
// distinguishable from an explicit 0, which is a valid offset (flush against
// that edge). Empty means "centred on this axis".
//
// CSS cannot take a top AND a bottom offset at once, so these four are not
// written out literally; ContainerBackgroundRenderer folds them into the
// percentage form, where "10% from the right" is simply 90%.
$positionOffsets = [];
foreach (['top', 'bottom', 'left', 'right'] as $edge) {
$positionOffsets['tx_vitec_bg_pos_' . $edge] = [
'label' => $l . 'bg_pos.' . $edge,
'description' => $l . 'bg_pos.description',
'displayCond' => 'FIELD:tx_vitec_bg_position:=:custom',
'config' => [
'type' => 'number',
'size' => 5,
'nullable' => true,
// No range on purpose: background-position accepts values below
// 0 and above 100, which is how you push an image partly out of
// its container. Capping at 0..100 would forbid exactly the
// layouts these free offsets exist for.
],
];
}
ExtensionManagementUtility::addTCAcolumns('tt_content', $positionOffsets);
// One palette, so size and position sit on a single row under the image.
$GLOBALS['TCA']['tt_content']['palettes']['vitec_background'] = [
'showitem' => 'tx_vitec_bg_image, --linebreak--, tx_vitec_bg_size, tx_vitec_bg_size_percent, tx_vitec_bg_position,'
. ' --linebreak--, tx_vitec_bg_pos_top, tx_vitec_bg_pos_bottom, tx_vitec_bg_pos_left, tx_vitec_bg_pos_right',
];
// -------------------------------------------------------------------------
// Shared parent-level setting: column gap scale (15) for the whole grid.
// Concerns the container itself (not a single column); maps to a spacing
// token in the React frontend. Rendered in the "Grid" palette on top of the
// Appearance tab, above the per-column rows.
// -------------------------------------------------------------------------
ExtensionManagementUtility::addTCAcolumns('tt_content', [
'tx_vitec_gap' => [
'label' => $l . 'gap.label',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'items' => [
['label' => $l . 'gap.option.1', 'value' => '1'],
['label' => $l . 'gap.option.2', 'value' => '2'],
['label' => $l . 'gap.option.3', 'value' => '3'],
['label' => $l . 'gap.option.4', 'value' => '4'],
['label' => $l . 'gap.option.5', 'value' => '5'],
],
'default' => '3',
],
],
]);
// Parent-element palette: settings that concern the whole grid, not a column.
$GLOBALS['TCA']['tt_content']['palettes']['vitec_grid'] = [
'showitem' => 'tx_vitec_gap',
];
// -------------------------------------------------------------------------
// Shared per-column flex alignment fields for the X-column containers.
// Positional: col1 = first column, col2 = second, ... (max 4 columns).
// "Align" -> CSS align-items (cross-axis alignment of the column's items)
// "Justify" -> CSS justify-content (main-axis distribution within the column)
// Reused across vitec_cols_50_50 / 33_66 / 66_33 / 33_33_33 / 25_25_25_25.
// -------------------------------------------------------------------------
$alignItems = [
['label' => $l . 'flex.align.flex_start', 'value' => 'flex-start'],
['label' => $l . 'flex.align.center', 'value' => 'center'],
['label' => $l . 'flex.align.flex_end', 'value' => 'flex-end'],
['label' => $l . 'flex.align.stretch', 'value' => 'stretch'],
];
$justifyItems = [
['label' => $l . 'flex.justify.flex_start', 'value' => 'flex-start'],
['label' => $l . 'flex.justify.center', 'value' => 'center'],
['label' => $l . 'flex.justify.space_between', 'value' => 'space-between'],
['label' => $l . 'flex.justify.space_around', 'value' => 'space-around'],
['label' => $l . 'flex.justify.space_evenly', 'value' => 'space-evenly'],
];
$columnFields = [];
for ($i = 1; $i <= 4; $i++) {
$columnFields['tx_vitec_col' . $i . '_align'] = [
'label' => $l . 'flex.align.label',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'items' => $alignItems,
'default' => 'stretch',
],
];
$columnFields['tx_vitec_col' . $i . '_justify'] = [
'label' => $l . 'flex.justify.label',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'items' => $justifyItems,
'default' => 'flex-start',
],
];
}
ExtensionManagementUtility::addTCAcolumns('tt_content', $columnFields);
// One palette per column: Align + Justify on a single row. The visible row
// label is overridden per container in its showitem (--palette--;<colLabel>;<palette>).
for ($i = 1; $i <= 4; $i++) {
$GLOBALS['TCA']['tt_content']['palettes']['vitec_col' . $i . '_flex'] = [
'showitem' => 'tx_vitec_col' . $i . '_align, tx_vitec_col' . $i . '_justify',
];
}
// Register VITEC wizard group header
$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;
})();