For coders TYPO3 Tech Corner

b13/container: Add and modify child elements in edit view

b13/container: Add and modify child elements in edit view

Edit children elements directly

In general, I think it's good that the b13/container extension is slim and doesn't have any unnecessary features. However, in a special project we need containers within news and calendar records. However, it is now very difficult for the editors to add child elements (e.g. textmedia).

If you want to quickly get this started again in your SitePackage, I'll show you a few code snippets. The examples refer to TYPO3 12 and container 2.3.6.

1. First you have to make sure that your SitePackage is loaded after the extension container. You can do this quickly using the composer.json in your SitePackage:

{ "name": "in2code/in2template", "description": "Theme and configuration for project", "type": "typo3-cms-extension", "homepage": "https://www.in2code.de", "license": "GPL-2.0-or-later", "require": { "typo3/cms-core": "^12.4", "b13/container": "^2.3" }, "autoload": { "psr-4": { "In2code\\In2template\\": "Classes/" } }, "extra": { "typo3/cms": { "extension-key": "in2template" } } }

2. Extends the TCA of the tt_content table to provide a new field for the child elements in a Configuration/TCA/Overrides/tt_content.php:

<?php use In2code\In2template\Utility\TcaUtility; \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns( 'tt_content', [ 'container_children' => [ 'exclude' => true, 'label' => 'Children elements', 'config' => [ 'type' => 'inline', 'foreign_table' => 'tt_content', 'foreign_table_where' => 'AND tt_content.deleted = 0 ' . 'and tt_content.hidden = 0 ' . 'and tt_content.sys_language_uid in (-1,0)', 'foreign_field' => 'tx_container_parent', 'foreign_sortby' => 'sorting', 'maxitems' => 1000, 'appearance' => [ 'expandSingle' => 1, 'useSortable' => 1, 'newRecordLinkAddTitle' => 1, 'levelLinksPosition' => 'top', 'showSynchronizationLink' => 0, 'showAllLocalizationLink' => 1, 'showPossibleLocalizationRecords' => 1, ], 'overrideChildTca' => [ 'columns' => [ 'CType' => [ 'config' => [ 'itemsProcFunc' => \In2code\In2template\Tca\ChildrenContentElements::class . '->allowedContentTypesContainer', 'default' => \In2code\In2template\Tca\ChildrenContentElements::getDefaultCtype(), ], ], 'colPos' => [ 'config' => [ 'itemsProcFunc' => \In2code\In2template\Tca\ChildrenContentElements::class . '->allowedColPosContainer', 'default' => \In2code\In2template\Tca\ChildrenContentElements::getDefaultColPosContainer(), ], ], ], ], ], ], ], );

3. We put the configuration for the TCA in the file under Classes/Tca/ChildrenContentElements.php:

<?php declare(strict_types=1); namespace In2code\In2template\Tca; use TYPO3\CMS\Backend\Utility\BackendUtility; class ChildrenContentElements { protected static string $defaultContentType = 'textmedia'; protected static int $defaultColPosContainer = 51; protected static array $contentTypesContainer = [ [ 'Text & Media', 'textmedia', 'mimetypes-x-content-text-media', ], ]; public static function getDefaultColPosContainer(): int { return self::$defaultColPosContainer; } public static function getDefaultCtype(): string { return self::$defaultContentType; } public function allowedContentTypesContainer(array &$parameters): void { $parameters['items'] = self::$contentTypesContainer; } /** * Set values for $parameters['items'] like: * [ * [ * 'Column 1', * 123, * ], * [ * 'Column 2', * 124, * ], * ]; * * @param array $parameters * @return void */ public function allowedColPosContainer(array &$parameters): void { $parameters['items'][] = ['Error: Could not get colPos from container configuration', 0]; $parentIdentifier = (int)($parameters['inlineParentUid'] ?? 0); if ($parentIdentifier > 0) { $row = BackendUtility::getRecord('tt_content', $parentIdentifier); if ($row['CType'] ?? false) { $parameters['items'] = $this->getColPosForContentType($row['CType']); } } } protected function getColPosForContentType(string $cType): array { $configuration = []; foreach ($GLOBALS['TCA']['tt_content']['containerConfiguration'][$cType]['grid'] ?? [] as $items) { foreach ($items as $item) { if (isset($item['name']) && isset($item['colPos'])) { $configuration[] = [$item['name'], $item['colPos']]; } } } return $configuration; } }

4. The ext_tables.sql still needs to be expanded to include the new field for tt_content:

CREATE TABLE tt_content ( container_children int(11) unsigned DEFAULT '0' NOT NULL, );

5. Prevent double copying by children

If you add child elements via TCA, TYPO3 automatically ensures that the child elements are copied when the parent element is copied. However, since EXT:container does not have this field by default, a hook is used to copy the child elements. We need to deactivate this hook quickly so that there are no duplicate entries. This can be done in ext_localconf.php:

if ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processCmdmapClass']['tx_container-post-process'] ?? false) { unset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processCmdmapClass']['tx_container-post-process']); }

I hope that the snippet helps you :)

Back

"Code faster, look at the time" - does this sound familiar to you?

How about time and respect for code quality? Working in a team? Automated tests?

Join us