Record types 

A types section is mandatory in all table definitions.

The types section is an array of types $GLOBALS['TCA'][$table]['types'] each containing a showitem key which determines which fields will be displayed in the backend form for the record. Most TCA tables will only contain one type.

However, it is possible to have many types in the same table with different fields being displayed depending on the type. Then a new database field needs to be created to save the type with the data. This field is set in $GLOBALS['TCA'][$table]['ctrl']['type'].

Defining multiple types in one table is similar to Single Table Inheritance in Object-orientated programming.

Changed in version 13.3

Creating content elements has been simplified by removing the need to define the system fields for each element again and again. This shrinks down a content element's showitem to just the element specific fields. See also the automatically added system fields.

A basic table without distinct types 

A table record supporting only one type defines which fields should be displayed in the backend form for the default type.

As an example, the comments of the conference extension have only one type:

EXT:my_extension/Configuration/TCA/tx_myextension_comment.php
<?php

use MyVendor\MyExtension\Backend\CommentLabel;

return [
  'ctrl' => [
    'title' => 'my_extension.db:comment',
    'label' => 'name',
    'label_userFunc' => CommentLabel::class . '->getLabel',
    'default_sortby' => 'crdate DESC',
    'hideTable' => true,
    'adminOnly' => true,
    'crdate' => 'crdate',
    'delete' => 'deleted',
    'enablecolumns' => [
      'disabled' => 'hidden',
    ],
    'versioningWS' => true,
    'iconfile' => 'EXT:my_extension/Resources/Public/Icons/Comment.svg',
  ],
  'columns' => [
    'name' => [
      'label' => 'my_extension.db:comment.name',
      'config' => [
        'type' => 'input',
        'required' => true,
      ],
    ],
  ],
  'types' => [
    '0' => [
      'showitem' => 'name, hidden',
    ],
  ],
];
Copied!

The types section is mandatory.

Supporting multiple record types in the same table 

If a table supports multiple record types, the type of the record must be saved in a dedicated database field, commonly named record_type or just type. Usually a select field is used for that purpose.

The name of this field is registered in the ctrl section via property type.

As an example, a talk can be a talk, a workshop, or a keynote:

EXT:my_extension/Configuration/TCA/tx_myextension_talk.php
<?php

return [
  'ctrl' => [
    'title' => 'my_extension.db:talk',
    'label' => 'title',
    'type' => 'talk_type',
    'typeicon_column' => 'talk_type',
    'typeicon_classes' => [
      'default' => 'my-extension-talk',
      'workshop' => 'my-extension-talk-workshop',
      'keynote' => 'my-extension-talk-keynote',
    ],
    'sortby' => 'sorting',
    'useColumnsForDefaultValues' => 'talk_type,room',
    'hideTable' => true,
    'tstamp' => 'tstamp',
    'crdate' => 'crdate',
    'delete' => 'deleted',
    'enablecolumns' => [
      'disabled' => 'hidden',
    ],
    'languageField' => 'sys_language_uid',
    'transOrigPointerField' => 'l10n_parent',
    'versioningWS' => true,
  ],
  'columns' => [
    'talk_type' => [
      'label' => 'my_extension.db:talk.talk_type',
      'config' => [
        'type' => 'select',
        'renderType' => 'selectSingle',
        'items' => [
          [
            'label' => 'my_extension.db:talk.talk_type.talk',
            'value' => 'talk',
          ],
          [
            'label' => 'my_extension.db:talk.talk_type.workshop',
            'value' => 'workshop',
          ],
          [
            'label' => 'my_extension.db:talk.talk_type.keynote',
            'value' => 'keynote',
          ],
        ],
        'default' => 'talk',
      ],
    ],
    'title' => [
      'label' => 'my_extension.db:talk.title',
      'config' => [
        'type' => 'input',
        'required' => true,
      ],
    ],
    'room' => [
      'label' => 'my_extension.db:talk.room',
      'config' => [
        'type' => 'input',
        'valuePicker' => [
          'items' => [
            ['label' => 'Main hall', 'value' => 'Main hall'],
            ['label' => 'Room A', 'value' => 'Room A'],
            ['label' => 'Room B', 'value' => 'Room B'],
          ],
        ],
      ],
    ],
  ],
  'types' => [
    'talk' => [
      'showitem' => '
        talk_type, title, room,
        --div--;core.form.tabs:access, hidden,
      ',
    ],
    'workshop' => [
      'showitem' => '
        talk_type, title, room,
        --div--;core.form.tabs:access, hidden,
      ',
    ],
    'keynote' => [
      'showitem' => '
        talk_type, title, room,
        --div--;core.form.tabs:access, hidden,
      ',
    ],
  ],
];
Copied!

For each record type you can define additional creationOptions and change field display definitions via columnsOverrides.

It is also possible to define previewRenderers.

You can also define icons for each type using the property ctrl -> typeicon_classes.

Properties of types section of TCA 

Name Type Scope
array of table names or ['*']
array (columns fields overrides) Display
list of options
array
bool
bool
string | language reference
boolean
string, name of a field Display
string, comma separated list of fields Display
bool Display
string Display
string (list of field configuration sets)
plain text label or label reference Display
array Display
allowedRecordTypes
Type
array of table names or ['*']
Default
['pages', 'sys_category', 'sys_file_reference', 'sys_file_collection']
TCA path
$GLOBALS['TCA'][$table]['types'][$type]['allowedRecordTypes']

New in version 14.2 Deprecation: #108557 - TCA option allowedRecordTypes for Page Types

This property replaces the now deprecated method PageDoktypeRegistry->addAllowedRecordTypes() .

The array can contain a list of table names or a single entry with an asterisk * to allow all types within a page type.

See TYPO3 Explained: Create new Page Type for a complete example.

columnsOverrides
Type
array (columns fields overrides)
TCA path
$GLOBALS['TCA'][$table]['types'][$type]['columnsOverrides']
Scope
Display
Examples
Examples for columnsOverrides

Changed or added ['columns'] field display definitions.

This allows different field column definitions to be applied when a record of this type is edited. Currently, only the display of form fields is affected, not data handling.

A typical property that can be changed is renderType.

The core uses this property to override the "bodytext" field config of table "tt_content". If a record of type "text" is edited, it adds "enableRichtext = 1" to trigger an RTE to the default "bodytext" configuration, and if a type "table" is edited, it adds "renderType = textTable" and "wrap = off" to "bodytext".

The FormEngine basically merges "columnsOverrides" over the default "columns" field after the record type has been determined.

creationOptions
Type
list of options
TCA path
$GLOBALS['TCA'][$table]['types'][$type]['creationOptions']
defaultValues
Type
array
TCA path
$GLOBALS['TCA'][$table]['types'][$type]['creationOptions']['defaultValues']
Examples
the example that creates the blog plugin at once

Default values inserted into the fields of the tt_content record on creation via the "New Content Element" wizard

Can be overridden with page TSconfig option tt_content_defValues.

enableDirectRecordTypeCreation
Type
bool
Default
true
TCA path
$GLOBALS['TCA'][$table]['types'][$type]['creationOptions']['enableDirectRecordTypeCreation']
Added
14.0

Record types registered via TCA are automatically displayed in the "Create new record" component in the backend module Content > Records.

A record type can be removed from that component. The type of a partnership comes from the partner conference, so the component shows no link for the types of a partnership:

EXT:my_extension/Configuration/TCA/Overrides/910-tx_myextension_partnership-type.php
<?php

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

// The type of a partnership is the format of the partner conference:
// the field "partner" points to the conference, and its field
// "event_format" holds the type
$GLOBALS['TCA']['tx_myextension_partnership']['ctrl']['type'] = 'partner:event_format';

// Another partner conference can have another format
$GLOBALS['TCA']['tx_myextension_partnership']['columns']['partner']['onChange'] = 'reload';

ExtensionManagementUtility::addTCAcolumns('tx_myextension_partnership', [
  'shared_livestream' => [
    'label' => 'my_extension.db:partnership.shared_livestream',
    'config' => [
      'type' => 'check',
      'renderType' => 'checkboxToggle',
    ],
  ],
]);

// An online partner conference shares its live stream instead of a
// discount. On-site and hybrid partner conferences fall back to type 0.
$GLOBALS['TCA']['tx_myextension_partnership']['types']['online'] = [
  'showitem' => 'conference, partner, shared_livestream',
];

// The partner conference decides the type, so the "Create new record"
// dialog shows no link of its own for each type
$GLOBALS['TCA']['tx_myextension_partnership']['types']['0']['creationOptions']['enableDirectRecordTypeCreation'] = false;
$GLOBALS['TCA']['tx_myextension_partnership']['types']['online']['creationOptions']['enableDirectRecordTypeCreation'] = false;
Copied!

Event \TYPO3\CMS\Backend\Controller\Event\ModifyNewRecordCreationLinksEvent can be used for more sophisticated modification of the dialogue.

saveAndClose
Type
bool
Default
false
TCA path
$GLOBALS['TCA'][$table]['types'][$type]['creationOptions']['saveAndClose']
Examples
the example that creates the blog plugin at once

If true, clicking on the new element wizard will take the user directly to the Content > Layout module, rather than showing the edit form from the form engine.

Can be overridden with page TSconfig option saveAndClose.

title
Type
string | language reference
TCA path
$GLOBALS['TCA'][$table]['types'][$type]['creationOptions']['title']
Added
14.0

The title of the content element in the "New content element" wizard. By default, the wizard shows the label of the item in the field CType. This option only takes effect in the table tt_content. The "Create new record" component takes the label of a record type from title.

A site package can give a content element of an extension another title in the wizard:

EXT:my_sitepackage/Configuration/TCA/Overrides/tt_content.php
<?php

defined('TYPO3') or die();

// The translators of this site write the headers of content elements
// themselves, so a translation starts with an unchanged copy of the header
$GLOBALS['TCA']['tt_content']['columns']['header']['l10n_mode'] = '';

// The editors of this site call a conference an event. The "New content
// element" wizard shows the teaser of the conference extension with the
// title they know.
$GLOBALS['TCA']['tt_content']['types']['myextension_conferenceteaser']['creationOptions']['title']
  = 'my_sitepackage.db:tt_content.conference_teaser.wizard_title';

// The layout of this site has room for wide and square images only
$GLOBALS['TCA']['tt_content']['columns']['image']['config']
  ['overrideChildTca']['columns']['crop']['config']['cropVariants'] = [
    'default' => [
      'title' => 'core.wizards:imwizard.crop_variant.default',
      'allowedAspectRatios' => [
        '16:9' => [
          'title' => 'core.wizards:imwizard.ratio.16_9',
          'value' => 16 / 9,
        ],
        '1:1' => [
          'title' => 'core.wizards:imwizard.ratio.1_1',
          'value' => 1.0,
        ],
      ],
    ],
  ];

// "Text and images" also shows its images on mobile devices, initially the
// middle of the image
$GLOBALS['TCA']['tt_content']['types']['textpic']['columnsOverrides']
  ['image']['config']['overrideChildTca']['columns']['crop']['config']
  ['cropVariants']['mobile'] = [
    'title' => 'my_sitepackage.db:crop_variant.mobile',
    'allowedAspectRatios' => [
      '4:3' => [
        'title' => 'core.wizards:imwizard.ratio.4_3',
        'value' => 4 / 3,
      ],
    ],
    'cropArea' => [
      'x' => 0.1,
      'y' => 0.1,
      'width' => 0.8,
      'height' => 0.8,
    ],
  ];
Copied!
isViewable
Type
boolean
Default
true
TCA path
$GLOBALS['TCA'][$table]['types'][$type]['isViewable']
Added
14.2, Feature: #97898 - TCA option isViewable for page types

Defines whether a page of this page type can be viewed in the frontend. A page type that is not viewable:

  • cannot be linked, neither in the link browser nor by a TypoLink in the frontend,
  • answers a direct call in the frontend with a 404 error,
  • has no preview button in the backend.

TYPO3 sets this to false for the page types spacer (199) and folder (254). All other page types are viewable as long as the option is not set.

EXT:my_extension/Configuration/TCA/Overrides/pages.php
$GLOBALS['TCA']['pages']['types']['116']['isViewable'] = false;
Copied!

In the backend, the page TSconfig setting TCEMAIN.preview.disableButtonForDokType decides instead: as soon as it is set for a page, the preview button and the link browser follow that list of page types and isViewable is not considered for them. The frontend always follows isViewable.

label
Type
string, name of a field
TCA path
$GLOBALS['TCA'][$table]['types'][$recordType]['label']
Scope
Display
Added
14.2, Feature: #108581 - Record type specific label configuration

Defines the primary field used as a type-specific label for a record type, overriding the label defined in $GLOBALS['TCA'][$table]['ctrl']['label'].

All places in TYPO3 that use BackendUtility::getRecordTitle() automatically benefit from this feature without any code changes. This includes record lists, page trees, history views, workspaces, and similar backend modules.

This is especially useful for tables like tt_content where different content element types may benefit from showing different fields. For example, an "Image" content element could display the image caption, while a "Text" element shows the header field.

EXT:my_extension/Configuration/TCA/Overrides/201-tx_myextension_talk-types.php
<?php

defined('TYPO3') or die();

// The title of the record type in the "Create new record" dialog
$GLOBALS['TCA']['tx_myextension_talk']['types']['workshop']['title'] = 'my_extension.db:talk.talk_type.workshop';
$GLOBALS['TCA']['tx_myextension_talk']['types']['keynote']['title'] = 'my_extension.db:talk.talk_type.keynote';

// A keynote is known by its speaker, a workshop by its room
$GLOBALS['TCA']['tx_myextension_talk']['types']['keynote']['label_alt'] = 'speaker';
$GLOBALS['TCA']['tx_myextension_talk']['types']['keynote']['label_alt_force'] = true;
$GLOBALS['TCA']['tx_myextension_talk']['types']['workshop']['label_alt'] = 'room';
$GLOBALS['TCA']['tx_myextension_talk']['types']['workshop']['label_alt_force'] = true;
Copied!

In this example:

  • All types of talks use title as the primary label field (from label in the ctrl section).
  • A keynote shows its speaker together with its title.
  • A workshop shows its room together with its title.
The related talks of a talk with the room of the workshop and the speaker of the keynote

The related talks of a talk with the room of the workshop and the speaker of the keynote

label_alt
Type
string, comma separated list of fields
TCA path
$GLOBALS['TCA'][$table]['types'][$recordType]['label_alt']
Scope
Display
Added
14.2, Feature: #108581 - Record type specific label configuration

Alternative field(s) used when label is empty (or as additional fields)

label_alt_force
Type
bool
Default
false
TCA path
$GLOBALS['TCA'][$table]['types'][$recordType]['label_alt_force']
Scope
Display
Added
14.2, Feature: #108581 - Record type specific label configuration

Force display of alternative fields alongside the primary label

previewRenderer
Type
string
TCA path
$GLOBALS['TCA'][$table]['types'][$type]['previewRenderer']
Scope
Display
Examples
PreviewRenderer examples

To configure a preview renderer for the whole table see previewRenderer.

Configures a backend preview for a content element.

Have also a look at configure a custom backend preview for more details.

Use property previewRenderer of section ctrl to configure the preview globally for the whole table.

showitem
Type
string (list of field configuration sets)
Required

true

TCA path
$GLOBALS['TCA'][$table]['types'][$type]['showitem']
Examples
Display all fields on one page of the form

Configuration of the displayed order of fields in FormEngine and their tab alignment.

The whole string is a comma , separated list of tokens. Each token can have keywords separated by semicolon ;.

Each comma separated token is one of the following:

fieldName;fieldLabel
Name of a field to show. Optionally an alternative label (plain text label or label reference) to override the default label from columns section.
--palette--;paletteLabel;paletteName

Name of a palette to show. The label (plain text label or label reference) is optional. If set, it is shown above the single palette fields. The palette name is required and must reference a palette from the palette section.

--palette--;;caching // Show palette "caching" without additional label
--palette--;Caching;caching // Show palette "caching" with label "Caching"
Copied!
--div--;tabLabel
Put all fields after this token onto a new tab and name the tab as given in "tabLabel" (plain text label or label reference).

Extensions can also modify showitem values by utilizing ExtensionManagementUtility::addToAllTCAtypes() . See customization examples for details.

title
Type
plain text label or label reference
TCA path
$GLOBALS['TCA'][$table]['types'][$recordType]['title']
Scope
Display

New in version 14.0 Feature: #108027 - Type-specific title in TCA types section

It is now possible to define a type-specific title in the TCA types section.

The title in the TCA types section defines a type specific title that is displayed in the backend when creating or editing a record of that type.

The value is also available in the Schema API ( \TYPO3\CMS\Core\Schema\TcaSchemaFactory ), making type-specific titles available when using $schema->getTitle() and in the FormEngine ( TcaTypesCtrlOverrides data provider).

EXT:my_extension/Configuration/TCA/Overrides/201-tx_myextension_talk-types.php
<?php

defined('TYPO3') or die();

// The title of the record type in the "Create new record" dialog
$GLOBALS['TCA']['tx_myextension_talk']['types']['workshop']['title'] = 'my_extension.db:talk.talk_type.workshop';
$GLOBALS['TCA']['tx_myextension_talk']['types']['keynote']['title'] = 'my_extension.db:talk.talk_type.keynote';

// A keynote is known by its speaker, a workshop by its room
$GLOBALS['TCA']['tx_myextension_talk']['types']['keynote']['label_alt'] = 'speaker';
$GLOBALS['TCA']['tx_myextension_talk']['types']['keynote']['label_alt_force'] = true;
$GLOBALS['TCA']['tx_myextension_talk']['types']['workshop']['label_alt'] = 'room';
$GLOBALS['TCA']['tx_myextension_talk']['types']['workshop']['label_alt_force'] = true;
Copied!

It is possible to insert plain text values here, however it is recommended to keep all labels in a translation file and reference the label with the special syntax shown above.

See also TYPO3 Explained: Label references / LLL strings

wizardSteps
Type
array
TCA path
$GLOBALS['TCA'][$table]['types'][$recordType]['wizardSteps']
Scope
Display

New in version 14.2 Feature: #109271 - Add TCA configuration for page creation wizard steps

It is possible to configure fields, steps (and their order) in the page creation wizard using TCA.

Defines the steps shown in the page creation wizard for the pages table.

Each step is identified by a unique key and contains a localized title and a list of fields to display in that step. The configured steps are sorted and may be positioned relative to other steps by using the before or after options.

The configuration can be defined per page type, allowing different wizard steps and field assignments depending on the selected page type.

Required fields that are not assigned to any configured wizard step are added automatically to a fallback step, which is appended at the end of the wizard.

The site package adds a step to the wizard of standard pages. The step follows the step setup of the Core:

EXT:my_sitepackage/Configuration/TCA/Overrides/pages.php
<?php

use TYPO3\CMS\Core\Domain\Repository\PageRepository;

defined('TYPO3') or die();

// The page lists of this site show the summary of each page, so the page
// wizard asks for it right after the title
$GLOBALS['TCA']['pages']['types'][(string)PageRepository::DOKTYPE_DEFAULT]['wizardSteps']['summary'] = [
  'title' => 'my_sitepackage.db:pages.wizard_step.summary',
  'fields' => ['abstract'],
  'after' => ['setup'],
];
Copied!

For a complete example see TYPO3 Explained, Create new page type.

Changed in version 13.0

The properties bitmask_excludelist_bits and bitmask_excludelist_bits have been removed, it is not considered anymore when rendering records in the backend record editing interface.

Extensions still using this setting should switch to casual $GLOBALS['TCA']['someTable']['ctrl']['type'] fields instead, which can be powered by columns based on string values.

Extended examples for using the types section of TCA 

Display all fields on one page of the form 

The table of the comments does not contain many fields. So they can all be displayed on one page of the backend form without using tabs:

EXT:my_extension/Configuration/TCA/tx_myextension_comment.php
<?php

use MyVendor\MyExtension\Backend\CommentLabel;

return [
  'ctrl' => [
    'title' => 'my_extension.db:comment',
    'label' => 'name',
    'label_userFunc' => CommentLabel::class . '->getLabel',
    'default_sortby' => 'crdate DESC',
    'hideTable' => true,
    'adminOnly' => true,
    'crdate' => 'crdate',
    'delete' => 'deleted',
    'enablecolumns' => [
      'disabled' => 'hidden',
    ],
    'versioningWS' => true,
    'iconfile' => 'EXT:my_extension/Resources/Public/Icons/Comment.svg',
  ],
  'columns' => [
    'name' => [
      'label' => 'my_extension.db:comment.name',
      'config' => [
        'type' => 'input',
        'required' => true,
      ],
    ],
  ],
  'types' => [
    '0' => [
      'showitem' => 'name, hidden',
    ],
  ],
];
Copied!

Group fields using tabs and use palettes 

If a table has a larger number of fields, grouping them into tabs and palettes can improve the backend user experience. Palettes have the additional value that they can be reused across different record types.

A conference has many fields, so its record type groups them in tabs:

The tab bar of a conference with the tabs General, Program, Registrations, Details, Categories, Access, Language, Comments, and Notes

The tabs of a conference

The showitem of the type names the tabs. The overrides of the extension add the fields of each tab. One of them also adds the tab Registrations:

EXT:my_extension/Configuration/TCA/tx_myextension_conference.php
<?php

return [
  'ctrl' => [
    'title' => 'my_extension.db:conference',
    'label' => 'title',
    'descriptionColumn' => 'internal_notes',
    'default_sortby' => 'conference_date DESC',
    'tstamp' => 'tstamp',
    'crdate' => 'crdate',
    'delete' => 'deleted',
    'editlock' => 'editlock',
    'enablecolumns' => [
      'disabled' => 'hidden',
      'starttime' => 'starttime',
      'endtime' => 'endtime',
      'fe_group' => 'fe_group',
    ],
    'languageField' => 'sys_language_uid',
    'transOrigPointerField' => 'l10n_parent',
    'transOrigDiffSourceField' => 'l10n_diffsource',
    'translationSource' => 'l10n_source',
    'versioningWS' => true,
    'origUid' => 't3_origuid',
    'iconfile' => 'EXT:my_extension/Resources/Public/Icons/Conference.svg',
    'security' => [
      'ignorePageTypeRestriction' => true,
    ],
  ],
  'columns' => [
    'title' => [
      'label' => 'my_extension.db:conference.title',
      'config' => [
        'type' => 'input',
        'required' => true,
        'max' => 255,
        'eval' => 'trim',
      ],
    ],
    'conference_date' => [
      'label' => 'my_extension.db:conference.conference_date',
      'config' => [
        'type' => 'datetime',
        'format' => 'date',
        'required' => true,
      ],
    ],
    'internal_notes' => [
      'label' => 'my_extension.db:conference.internal_notes',
      'config' => [
        'type' => 'text',
        'rows' => 3,
      ],
    ],
  ],
  // The fields of the other tabs are added in Configuration/TCA/Overrides/
  'types' => [
    '0' => [
      'showitem' => '
        title, conference_date,
        --div--;my_extension.db:tab.program,
        --div--;my_extension.db:tab.details,
        --div--;core.form.tabs:categories,
        --div--;core.form.tabs:access,
          hidden, --palette--;;access, fe_group, editlock,
        --div--;core.form.tabs:language,
          --palette--;;language,
        --div--;my_extension.db:tab.comments,
        --div--;core.form.tabs:notes,
          internal_notes,
      ',
    ],
  ],
  'palettes' => [
    'access' => [
      'label' => 'core.form.palettes:access',
      // The labels of the fields tell the editors what the dates are for
      'showitem' => '
        starttime;my_extension.db:conference.starttime,
        endtime;my_extension.db:conference.endtime,
      ',
    ],
    'language' => [
      'showitem' => 'sys_language_uid, l10n_parent',
    ],
  ],
];
Copied!

The syntax for tabs is:

--div--;<label>

Where label can be plain text label or label reference (preferred).

The syntax to insert a palette is:

--palette--;<label>;<paletteName>

The label can be omitted.

Examples for columnsOverrides in type section of TCA 

Demonstrates property: columnsOverrides.

For example a keynote requires a speaker, unlike the other types of talks:

EXT:my_extension/Configuration/TCA/Overrides/210-tx_myextension_talk-speaker.php
<?php

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

ExtensionManagementUtility::addTCAcolumns('tx_myextension_talk', [
  'speaker' => [
    'label' => 'my_extension.db:talk.speaker',
    'config' => [
      'type' => 'group',
      'allowed' => 'tx_myextension_speaker',
      'maxitems' => 1,
      'relationship' => 'manyToOne',
      // The speakers are stored in the same folder as the talks
      'elementBrowserEntryPoints' => [
        'tx_myextension_speaker' => '###CURRENT_PID###',
      ],
      'fieldControl' => [
        'editPopup' => [
          'disabled' => false,
        ],
        'addRecord' => [
          'disabled' => false,
        ],
        'listModule' => [
          'disabled' => false,
        ],
      ],
      'behaviour' => [
        'allowLanguageSynchronization' => true,
      ],
    ],
  ],
]);
$GLOBALS['TCA']['tx_myextension_talk']['types']['keynote']['columnsOverrides']['speaker']['config']['minitems'] = 1;
ExtensionManagementUtility::addToAllTCAtypes(
  'tx_myextension_talk',
  'speaker',
  '',
  'after:slug',
);
Copied!

While the field type type cannot be changed in the columnsOverrides the render type renderType can be changed.

Override default values by type 

A new conference list plugin hides its header by default:

EXT:my_extension/Configuration/TCA/Overrides/600-tt_content-conference_list.php
<?php

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Extbase\Utility\ExtensionUtility;

defined('TYPO3') or die();

// A group of its own in the content element wizard and the type select
ExtensionManagementUtility::addTcaSelectItemGroup(
  'tt_content',
  'CType',
  'conference',
  'my_extension.db:tt_content.group.conference',
  'after:plugins',
);

ExtensionUtility::registerPlugin(
  'MyExtension',
  'ConferenceList',
  'my_extension.db:plugin.conferencelist.title',
  'my-extension-conference-list',
  'conference',
  'my_extension.db:plugin.conferencelist.description',
  'FILE:EXT:my_extension/Configuration/FlexForms/ConferenceList.xml',
);

// The plugin lists the upcoming conferences without further settings, so
// a new plugin is saved at once, with its header hidden
$GLOBALS['TCA']['tt_content']['types']['myextension_conferencelist']['creationOptions'] = [
  'defaultValues' => [
    'header_layout' => '100',
  ],
  'saveAndClose' => true,
];
Copied!

PreviewRenderer examples 

Demonstrates property: previewRenderer.

In the Content > Layout module, a conference teaser shows the teased conference and the link text:

The preview of a conference teaser in the page module

The preview of a conference teaser in the page module

The record type myextension_conferenceteaser of the table tt_content gets its own preview renderer:

EXT:my_extension/Configuration/TCA/Overrides/615-tt_content-conference_teaser.php
<?php

use MyVendor\MyExtension\Preview\ConferenceTeaserPreviewRenderer;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

// The fields of the teaser
ExtensionManagementUtility::addTCAcolumns('tt_content', [
  'tx_myextension_teaser_conference' => [
    'label' => 'my_extension.db:tt_content.tx_myextension_teaser_conference',
    'config' => [
      'type' => 'select',
      'renderType' => 'selectSingle',
      'foreign_table' => 'tx_myextension_conference',
      'foreign_table_where' => 'AND {#tx_myextension_conference}.{#sys_language_uid} IN (-1, 0)',
      'relationship' => 'manyToOne',
    ],
  ],
  'tx_myextension_teaser_link_text' => [
    'label' => 'my_extension.db:tt_content.tx_myextension_teaser_link_text',
    'config' => [
      'type' => 'input',
    ],
  ],
  'tx_myextension_teaser_note' => [
    'label' => 'my_extension.db:tt_content.tx_myextension_teaser_note',
    'config' => [
      'type' => 'input',
    ],
  ],
]);

// Add the content element to the "Type" dropdown, after the call for papers.
// Predefined and own fields on the "General" tab and a tab of its own.
// addRecordType() adds the "Extended" tab at the end.
ExtensionManagementUtility::addRecordType(
  [
    'label' => 'my_extension.db:tt_content.conference_teaser',
    'value' => 'myextension_conferenceteaser',
    'icon' => 'my-extension-conference-list',
    'group' => 'conference',
    'description' => 'my_extension.db:tt_content.conference_teaser.description',
  ],
  '
    --palette--;;headers,
    tx_myextension_teaser_conference,
    --div--;my_extension.db:tab.teaser,
      tx_myextension_teaser_link_text,
  ',
  [
    // The page module shows the teased conference
    'previewRenderer' => ConferenceTeaserPreviewRenderer::class,
  ],
  'after:myextension_callforpapers',
);

// Added without a position, so the field is shown on the "Extended" tab
ExtensionManagementUtility::addToAllTCAtypes(
  'tt_content',
  'tx_myextension_teaser_note',
  'myextension_conferenceteaser',
);
Copied!

The preview renderer shows the content of the preview itself. The standard preview renderer of the Core renders the header, the footer, and the wrap:

EXT:my_extension/Classes/Preview/ConferenceTeaserPreviewRenderer.php
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\Preview;

use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;
use TYPO3\CMS\Backend\Preview\PreviewRendererInterface;
use TYPO3\CMS\Backend\Preview\StandardContentPreviewRenderer;
use TYPO3\CMS\Backend\View\BackendLayout\Grid\GridColumnItem;
use TYPO3\CMS\Core\Domain\RecordInterface;

/**
 * Shows the teased conference and the link text of a conference teaser
 * in the page module. The header, the footer and the wrap of the preview
 * stay the same as for the other content elements.
 */
#[Autoconfigure(public: true)]
final readonly class ConferenceTeaserPreviewRenderer implements PreviewRendererInterface
{
  public function __construct(
    private StandardContentPreviewRenderer $standardContentPreviewRenderer,
  ) {}

  public function renderPageModulePreviewHeader(GridColumnItem $item): string
  {
    return $this->standardContentPreviewRenderer->renderPageModulePreviewHeader($item);
  }

  public function renderPageModulePreviewContent(GridColumnItem $item): string
  {
    $record = $item->getRecord();
    $conference = $record->get('tx_myextension_teaser_conference');
    if (!$conference instanceof RecordInterface) {
      return '';
    }
    return sprintf(
      '<p><strong>%s</strong></p><p>%s</p>',
      htmlspecialchars((string)$conference->get('title')),
      htmlspecialchars((string)$record->get('tx_myextension_teaser_link_text')),
    );
  }

  public function renderPageModulePreviewFooter(GridColumnItem $item): string
  {
    return $this->standardContentPreviewRenderer->renderPageModulePreviewFooter($item);
  }

  public function wrapPageModulePreview(string $previewHeader, string $previewContent, GridColumnItem $item): string
  {
    return $this->standardContentPreviewRenderer->wrapPageModulePreview($previewHeader, $previewContent, $item);
  }
}
Copied!

Example: Create the conference list plugin at once 

Demonstrates property: saveAndClose.

The conference list plugin shows the upcoming conferences without further settings. When editors create a new conference list plugin, it is automatically saved and the user returned to the Content > Layout module:

EXT:my_extension/Configuration/TCA/Overrides/600-tt_content-conference_list.php
<?php

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Extbase\Utility\ExtensionUtility;

defined('TYPO3') or die();

// A group of its own in the content element wizard and the type select
ExtensionManagementUtility::addTcaSelectItemGroup(
  'tt_content',
  'CType',
  'conference',
  'my_extension.db:tt_content.group.conference',
  'after:plugins',
);

ExtensionUtility::registerPlugin(
  'MyExtension',
  'ConferenceList',
  'my_extension.db:plugin.conferencelist.title',
  'my-extension-conference-list',
  'conference',
  'my_extension.db:plugin.conferencelist.description',
  'FILE:EXT:my_extension/Configuration/FlexForms/ConferenceList.xml',
);

// The plugin lists the upcoming conferences without further settings, so
// a new plugin is saved at once, with its header hidden
$GLOBALS['TCA']['tt_content']['types']['myextension_conferencelist']['creationOptions'] = [
  'defaultValues' => [
    'header_layout' => '100',
  ],
  'saveAndClose' => true,
];
Copied!