Examples
Note
Inline fields should not be used to handle files. Use the TCA column type file instead.
Simple 1:n relation
A conference has talks, and each talk belongs to one conference:
The talks of a conference
<?php
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
defined('TYPO3') or die();
ExtensionManagementUtility::addTCAcolumns('tx_myextension_conference', [
'talks' => [
'label' => 'my_extension.db:conference.talks',
'config' => [
'type' => 'inline',
'foreign_table' => 'tx_myextension_talk',
'foreign_field' => 'conference',
'foreign_sortby' => 'sorting',
'appearance' => [
'collapseAll' => true,
'useSortable' => true,
'showPossibleLocalizationRecords' => true,
'showAllLocalizationLink' => true,
'showSynchronizationLink' => true,
],
],
],
]);
ExtensionManagementUtility::addToAllTCAtypes(
'tx_myextension_conference',
'talks',
'',
'before:--div--;my_extension.db:tab.details',
);
// An inline field has no fieldInformation of its own. The container of all
// inline fields of the table shows it, see TalkOrderInformation.
$GLOBALS['TCA']['tx_myextension_conference']['ctrl']['container']['inline']
['fieldInformation']['talkOrder'] = [
'renderType' => 'talkOrderInformation',
];
Attributes on anti-symmetric intermediate table
The registrations of a conference
This example combines conferences with frontend users, using the
intermediate table tx_. Each registration has an
attribute of its own: the ticket of the attendee.
The conference contains the following column:
<?php
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
defined('TYPO3') or die();
ExtensionManagementUtility::addTCAcolumns('tx_myextension_conference', [
'registrations' => [
'label' => 'my_extension.db:conference.registrations',
'config' => [
'type' => 'inline',
'foreign_table' => 'tx_myextension_registration',
'foreign_field' => 'conference',
'foreign_selector' => 'attendee',
'foreign_unique' => 'attendee',
'foreign_match_fields' => [
'status' => 'confirmed',
],
'appearance' => [
'useCombination' => true,
'overwriteCombinationWarningMessage' => 'my_extension.db:conference.registrations.combinationWarning',
],
'overrideChildTca' => [
'columns' => [
'attendee' => [
'config' => [
// The frontend users are stored in the same folder as the conferences
'elementBrowserEntryPoints' => [
'fe_users' => '###CURRENT_PID###',
],
],
],
],
],
],
],
]);
ExtensionManagementUtility::addToAllTCAtypes(
'tx_myextension_conference',
'--div--;my_extension.db:tab.registrations, registrations',
'',
'before:--div--;my_extension.db:tab.details',
);
The intermediate table tx_ defines the following
fields:
<?php
return [
'ctrl' => [
'title' => 'my_extension.db:registration',
'label' => 'attendee',
'label_alt' => 'ticket',
'label_alt_force' => true,
'hideTable' => true,
'tstamp' => 'tstamp',
'crdate' => 'crdate',
'delete' => 'deleted',
'versioningWS' => true,
'iconfile' => 'EXT:my_extension/Resources/Public/Icons/Registration.svg',
],
'columns' => [
'attendee' => [
'label' => 'my_extension.db:registration.attendee',
'config' => [
'type' => 'group',
'allowed' => 'fe_users',
'minitems' => 1,
'maxitems' => 1,
],
],
'ticket' => [
'label' => 'my_extension.db:registration.ticket',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'items' => [
['label' => 'my_extension.db:registration.ticket.regular', 'value' => 'regular'],
['label' => 'my_extension.db:registration.ticket.student', 'value' => 'student'],
['label' => 'my_extension.db:registration.ticket.speaker', 'value' => 'speaker'],
],
],
],
],
'types' => [
'0' => [
'showitem' => 'attendee, ticket',
],
],
];
Attributes on symmetric intermediate table
The partner conferences of a conference
This example combines records of the same table with each other: a conference has partner conferences, whose attendees get a discount. Symmetric relations combine records of one table with each other. If record A is related to record B, then record B is also related to record A. However, the records are not stored in groups. If record A is related to B and C, B does not have to be related to C.
The conference has a field storing the inline relation, here: partners.
<?php
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
defined('TYPO3') or die();
ExtensionManagementUtility::addTCAcolumns('tx_myextension_conference', [
'partners' => [
'label' => 'my_extension.db:conference.partners',
'config' => [
'type' => 'inline',
'foreign_table' => 'tx_myextension_partnership',
'foreign_field' => 'conference',
'foreign_sortby' => 'conference_sorting',
'foreign_label' => 'partner',
'symmetric_field' => 'partner',
'symmetric_sortby' => 'partner_sorting',
'symmetric_label' => 'conference',
],
],
]);
ExtensionManagementUtility::addToAllTCAtypes(
'tx_myextension_conference',
'partners',
'',
'after:speakers',
);
The conferences are related to each other with the intermediate table
tx_. It stores the uids of both sides of the
relation in conference and partner:
<?php
return [
'ctrl' => [
'title' => 'my_extension.db:partnership',
'label' => 'partner',
'hideTable' => true,
'tstamp' => 'tstamp',
'crdate' => 'crdate',
'delete' => 'deleted',
'versioningWS' => true,
'iconfile' => 'EXT:my_extension/Resources/Public/Icons/Partnership.svg',
],
'columns' => [
'conference' => [
'label' => 'my_extension.db:partnership.conference',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'foreign_table' => 'tx_myextension_conference',
'foreign_table_where' => 'AND {#tx_myextension_conference}.{#sys_language_uid} IN (-1, 0)',
],
],
'partner' => [
'label' => 'my_extension.db:partnership.partner',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'foreign_table' => 'tx_myextension_conference',
'foreign_table_where' => 'AND {#tx_myextension_conference}.{#sys_language_uid} IN (-1, 0)',
],
],
],
'types' => [
'0' => [
'showitem' => 'conference, partner',
],
],
];
Each side of the relation has its own sorting. TYPO3 does not create the
columns of foreign_ and symmetric_, so they are defined in
the ext_tables.sql file:
-- The sorting of each side of a partnership. TYPO3 creates all other
-- columns from the TCA.
CREATE TABLE tx_myextension_partnership (
conference_sorting int(11) unsigned DEFAULT '0' NOT NULL,
partner_sorting int(11) unsigned DEFAULT '0' NOT NULL
);
-- TYPO3 does not create columns for fields of type user
CREATE TABLE fe_users (
tx_myextension_badge_name varchar(255) DEFAULT '' NOT NULL
);
-- TYPO3 does not create columns for fields of type none
CREATE TABLE tx_myextension_talk (
feedback_opened int(11) DEFAULT '0' NOT NULL,
rating decimal(2,1) DEFAULT '0.0' NOT NULL,
feedback_count int(11) unsigned DEFAULT '0' NOT NULL
);
Note
TCAdefaults.<table>. can be used to define the pid of new child records. Thus, it's possible to
have special storage folders on a per-table-basis. See the TSconfig reference.
With a combination box
The registrations of a conference show the registration and the frontend user together. A message warns that changes to the frontend user apply to all registrations of this user:
A registration with its frontend user
<?php
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
defined('TYPO3') or die();
ExtensionManagementUtility::addTCAcolumns('tx_myextension_conference', [
'registrations' => [
'label' => 'my_extension.db:conference.registrations',
'config' => [
'type' => 'inline',
'foreign_table' => 'tx_myextension_registration',
'foreign_field' => 'conference',
'foreign_selector' => 'attendee',
'foreign_unique' => 'attendee',
'foreign_match_fields' => [
'status' => 'confirmed',
],
'appearance' => [
'useCombination' => true,
'overwriteCombinationWarningMessage' => 'my_extension.db:conference.registrations.combinationWarning',
],
'overrideChildTca' => [
'columns' => [
'attendee' => [
'config' => [
// The frontend users are stored in the same folder as the conferences
'elementBrowserEntryPoints' => [
'fe_users' => '###CURRENT_PID###',
],
],
],
],
],
],
],
]);
ExtensionManagementUtility::addToAllTCAtypes(
'tx_myextension_conference',
'--div--;my_extension.db:tab.registrations, registrations',
'',
'before:--div--;my_extension.db:tab.details',
);
Add a custom fieldInformation
The following example adds a custom fieldInformation above the talks of a conference. Adding a fieldWizard is done in a similar way.
The talks of a conference with the information about their order
As explained in the description, field
or field must be configured within the ctrl for the field
type inline - as it is a container.
-
Create a custom fieldInformation
EXT:my_extension/Classes/Form/FieldInformation/TalkOrderInformation.php<?php declare(strict_types=1); namespace MyVendor\MyExtension\Form\FieldInformation; use TYPO3\CMS\Backend\Form\AbstractNode; use TYPO3\CMS\Core\Localization\LanguageService; /** * Explains above the talks of a conference how to change the program */ final class TalkOrderInformation extends AbstractNode { public function render(): array { $result = $this->initializeResultArray(); // The container shows this information for every inline field of the table if ($this->data['fieldName'] !== 'talks') { return $result; } $result['html'] = '<p class="text-body-secondary">' . htmlspecialchars( $this->getLanguageService()->sL('my_extension.db:conference.talks.order'), ) . '</p>'; return $result; } private function getLanguageService(): LanguageService { return $GLOBALS['LANG']; } } -
Register this node type
EXT:my_extension/ext_localconf.php<?php use MyVendor\MyExtension\Controller\ConferenceController; use MyVendor\MyExtension\Evaluation\AbstractEvaluation; use MyVendor\MyExtension\Evaluation\HashtagEvaluation; use MyVendor\MyExtension\Form\Element\BadgeNameElement; use MyVendor\MyExtension\Form\FieldInformation\InformationText; use MyVendor\MyExtension\Form\FieldInformation\TalkOrderInformation; use MyVendor\MyExtension\Form\FieldWizard\ReferencesToThisRecordWizard; use TYPO3\CMS\Core\PasswordPolicy\Generator\PasswordGenerator; use TYPO3\CMS\Extbase\Utility\ExtensionUtility; defined('TYPO3') or die(); ExtensionUtility::configurePlugin( 'MyExtension', 'ConferenceList', [ConferenceController::class => ['list', 'show']], ); // Classes that TCA fields name in 'eval' $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tce']['formevals'][HashtagEvaluation::class] = ''; $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tce']['formevals'][AbstractEvaluation::class] = ''; // The information above the talks of a conference, see // Configuration/TCA/Overrides/120-tx_myextension_conference-talks.php $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'][1791234567] = [ 'nodeName' => 'talkOrderInformation', 'priority' => 30, 'class' => TalkOrderInformation::class, ]; // The badge name of a frontend user, see // Configuration/TCA/Overrides/650-fe_users-tx_myextension_badge_name.php $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'][1791300000] = [ 'nodeName' => 'badgeName', 'priority' => 40, 'class' => BadgeNameElement::class, ]; // The information text of fields, see for example // Configuration/TCA/Overrides/310-tx_myextension_speaker-email.php $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'][1791310000] = [ 'nodeName' => 'informationText', 'priority' => 30, 'class' => InformationText::class, ]; // The references to a conference above its form, see // Configuration/TCA/Overrides/101-tx_myextension_conference-references.php $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'][1791320000] = [ 'nodeName' => 'referencesToThisRecord', 'priority' => 30, 'class' => ReferencesToThisRecordWizard::class, ]; // The password policies of the password generators, see // Configuration/TCA/Overrides/445-tx_myextension_location-door_code.php and // Configuration/TCA/Overrides/345-tx_myextension_speaker-upload_token.php $GLOBALS['TYPO3_CONF_VARS']['SYS']['passwordPolicies']['myExtensionDigits'] = [ 'generator' => [ 'className' => PasswordGenerator::class, 'options' => [ 'length' => 8, 'lowerCaseCharacters' => false, 'upperCaseCharacters' => false, 'digitCharacters' => true, ], ], 'validators' => [], ]; $GLOBALS['TYPO3_CONF_VARS']['SYS']['passwordPolicies']['myExtensionBase64'] = [ 'generator' => [ 'className' => PasswordGenerator::class, 'options' => [ 'length' => 35, 'random' => 'base64', ], ], 'validators' => [], ]; -
Add the fieldInformation to the container for containerRenderType inline
EXT:my_extension/Configuration/TCA/Overrides/120-tx_myextension_conference-talks.php<?php use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; defined('TYPO3') or die(); ExtensionManagementUtility::addTCAcolumns('tx_myextension_conference', [ 'talks' => [ 'label' => 'my_extension.db:conference.talks', 'config' => [ 'type' => 'inline', 'foreign_table' => 'tx_myextension_talk', 'foreign_field' => 'conference', 'foreign_sortby' => 'sorting', 'appearance' => [ 'collapseAll' => true, 'useSortable' => true, 'showPossibleLocalizationRecords' => true, 'showAllLocalizationLink' => true, 'showSynchronizationLink' => true, ], ], ], ]); ExtensionManagementUtility::addToAllTCAtypes( 'tx_myextension_conference', 'talks', '', 'before:--div--;my_extension.db:tab.details', ); // An inline field has no fieldInformation of its own. The container of all // inline fields of the table shows it, see TalkOrderInformation. $GLOBALS['TCA']['tx_myextension_conference']['ctrl']['container']['inline'] ['fieldInformation']['talkOrder'] = [ 'renderType' => 'talkOrderInformation', ];
See also
- ['ctrl']['container']
- How to create custom fieldInformation, fieldControl or fieldWizard in FormEngine chapter (TYPO3 Explained)
- fieldInformation property
Examples with overrideChildTca
Overrides the crop variants
This example overrides the crop variants of the photo of a speaker. The photo can only be cropped to a square:
<?php
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
defined('TYPO3') or die();
ExtensionManagementUtility::addTCAcolumns('tx_myextension_speaker', [
'photo' => [
'label' => 'my_extension.db:speaker.photo',
'config' => [
'type' => 'file',
'maxitems' => 1,
'allowed' => 'common-image-types',
'relationship' => 'manyToOne',
'overrideChildTca' => [
'columns' => [
'crop' => [
'config' => [
'cropVariants' => [
'default' => [
'title' => 'my_extension.db:speaker.photo.square',
'allowedAspectRatios' => [
'1:1' => [
'title' => 'core.wizards:imwizard.ratio.1_1',
'value' => 1.0,
],
],
// The face of the speaker, initially in the middle
'focusArea' => [
'x' => 1 / 3,
'y' => 1 / 3,
'width' => 1 / 3,
'height' => 1 / 3,
],
],
],
],
],
],
],
],
],
]);
ExtensionManagementUtility::addToAllTCAtypes(
'tx_myextension_speaker',
'photo',
'',
'before:--div--;my_extension.db:tab.integration',
);
Define which fields to show in the child table
This example overrides the showitem field of the child table TCA:
The content elements of a conference
<?php
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
defined('TYPO3') or die();
ExtensionManagementUtility::addTCAcolumns('tx_myextension_conference', [
'content_elements' => [
'label' => 'my_extension.db:conference.content_elements',
'config' => [
'type' => 'inline',
'foreign_table' => 'tt_content',
'foreign_field' => 'tx_myextension_conference',
'behaviour' => [
'allowLanguageSynchronization' => true,
],
'overrideChildTca' => [
'columns' => [
'CType' => [
'config' => [
'default' => 'text',
],
],
],
'types' => [
'text' => [
'showitem' => 'CType, header, bodytext',
],
],
],
],
],
]);
ExtensionManagementUtility::addToAllTCAtypes(
'tx_myextension_conference',
'content_elements',
'',
'before:--div--;core.form.tabs:categories',
);
Override the default value of a child tables field
This overrides the default columns property of a child field in an inline relation from within
the parent if a new child is created:
<?php
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
defined('TYPO3') or die();
ExtensionManagementUtility::addTCAcolumns('tx_myextension_conference', [
'content_elements' => [
'label' => 'my_extension.db:conference.content_elements',
'config' => [
'type' => 'inline',
'foreign_table' => 'tt_content',
'foreign_field' => 'tx_myextension_conference',
'behaviour' => [
'allowLanguageSynchronization' => true,
],
'overrideChildTca' => [
'columns' => [
'CType' => [
'config' => [
'default' => 'text',
],
],
],
'types' => [
'text' => [
'showitem' => 'CType, header, bodytext',
],
],
],
],
],
]);
ExtensionManagementUtility::addToAllTCAtypes(
'tx_myextension_conference',
'content_elements',
'',
'before:--div--;core.form.tabs:categories',
);
Override the foreign_selector field target
This overrides the configuration of the field the foreign_selector property points to. Here, the element browser of the attendees of a conference opens on the folder of the conference:
<?php
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
defined('TYPO3') or die();
ExtensionManagementUtility::addTCAcolumns('tx_myextension_conference', [
'registrations' => [
'label' => 'my_extension.db:conference.registrations',
'config' => [
'type' => 'inline',
'foreign_table' => 'tx_myextension_registration',
'foreign_field' => 'conference',
'foreign_selector' => 'attendee',
'foreign_unique' => 'attendee',
'foreign_match_fields' => [
'status' => 'confirmed',
],
'appearance' => [
'useCombination' => true,
'overwriteCombinationWarningMessage' => 'my_extension.db:conference.registrations.combinationWarning',
],
'overrideChildTca' => [
'columns' => [
'attendee' => [
'config' => [
// The frontend users are stored in the same folder as the conferences
'elementBrowserEntryPoints' => [
'fe_users' => '###CURRENT_PID###',
],
],
],
],
],
],
],
]);
ExtensionManagementUtility::addToAllTCAtypes(
'tx_myextension_conference',
'--div--;my_extension.db:tab.registrations, registrations',
'',
'before:--div--;my_extension.db:tab.details',
);
Note
It is allowed to use this property within the columnsOverrides property
of an inline parent in the ['types'] section.
Example: Override by type
A record type can change the override of an inline field with
columnsOverrides. Here, the
editors cannot change the text of a comment on a talk of the record type
keynote:
<?php
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
defined('TYPO3') or die();
ExtensionManagementUtility::addTCAcolumns('tx_myextension_talk', [
'comments' => [
'label' => 'my_extension.db:talk.comments',
'config' => [
'type' => 'inline',
'foreign_table' => 'tx_myextension_comment',
'foreign_field' => 'parent',
'foreign_table_field' => 'parent_table',
'appearance' => [
'enabledControls' => [
'new' => false,
],
],
],
],
]);
// The website quotes the comments on a keynote: the editors approve them,
// but they cannot change their text
$GLOBALS['TCA']['tx_myextension_talk']['types']['keynote']['columnsOverrides']['comments']['config']['overrideChildTca']['columns']['content']['config']['readOnly'] = true;
ExtensionManagementUtility::addToAllTCAtypes(
'tx_myextension_talk',
'comments',
'',
'before:--div--;core.form.tabs:access',
);