Table properties (ctrl) 

The ctrl section contains properties for a database table in general.

These properties are basically divided into two main categories:

  • Properties which affect how a table is displayed and handled in the backend. This includes which icon is shown and which name is given for a record. It defines which column contains the title value, which column contains the type value etc.
  • Properties which determine how entries in the backend interface are processed by the system (TCE). This includes the publishing control, the "deleted" flag, whether a table can only be edited by admin-users, whether a table may only exist in the tree root etc.

Example: Common table control configuration 

For advanced examples see ctrl examples.

The conferences in the Records module, with a German translation

The conferences in the Records module, with a German translation

The ctrl section of the conference table:

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!

Properties of the TCA ctrl section 

Name Type Scope
boolean Display / Proc.
array Display
string (list of field names) Proc.
string (field name) Proc.
string Display
string (field name) Display / Proc.
string (field name) Display
string (field name) Display / Proc.
array Display / Proc.
array Special
string (user function reference) Display
array Display
string Special
boolean Proc.
boolean Display
string Display
string (field name) Display
string (comma-separated list of field names) Display
boolean Display
string (user function reference) Display
array Display
string (field name of type language) Display / Proc.
string (field name) Proc.
plain text label or label reference Proc.
string (class name) Display
boolean Display / Proc.
[0, 1, -1] Display / Proc.
string (comma-separated list of field names) Search
array Display
string (field name) Display
string (field name) Display / Proc.
plain text label or label reference Display
string (field name) Display / Proc.
string (field name) Display / Proc.
string (field name) Display / Proc.
string (field name) Proc.
string (field name, or relation_field:foreign_type_field) Display / Proc.
array Display
string (field name) Display
string (list of field names) Proc.
boolean Proc.
boolean Special
adminOnly
Type
boolean
TCA path
$GLOBALS['TCA'][$table]['ctrl']['adminOnly']
Scope
Display / Proc.

Records can be changed only by "admin"-users (having the "admin" flag set).

Example: Only admins moderate the comments
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!
container
Type
array
TCA path
$GLOBALS['TCA'][$table]['ctrl']['container']
Scope
Display
Examples
extended container examples

Array to configure additional items in render containers of FormEngine, see section Node expansion.

As well as single elements, some render containers can be "enriched" with additional information via the "node expansion" API. Currently, the FormWrapContainer implements fieldWizard and fieldInformation. InlineControlContainer implements fieldWizard and comes with the default wizard localizationStateSelector. Custom containers may implement expansion nodes, too, and if implemented correctly will automatically have their configuration merged with the definition provided in this TCA array.

The form of a conference shows above its fields how many records refer to it. A field wizard of the formWrapContainer adds this:

EXT:my_extension/Configuration/TCA/Overrides/101-tx_myextension_conference-references.php
<?php

defined('TYPO3') or die();

// Above the form of a conference, show how many records refer to it
$GLOBALS['TCA']['tx_myextension_conference']['ctrl']['container']['formWrapContainer']
  ['fieldWizard']['referencesToThisRecord'] = [
    // Registered in ext_localconf.php
    'renderType' => 'referencesToThisRecord',
  ];
Copied!

The path is container.<containerRenderType>.fieldWizard.<aName>, with these keys:

<containerRenderType>

should be a defined container render type. You can find more about the formWrapContainer and inlineControlContainer in the FormEngine documentation section on rendering. Valid types are for example:

  • formWrapContainer type which corresponds to the FormWrapContainer class.
  • inlineControlContainer type which corresponds to the InlineControlContainer class
  • inline type which corresponds to the InlineControlContainer class.
renderType
refers to a registered node name from NodeFactory
before, after
can be set to sort single wizards relative to each other.
disabled
can be used to disable built in default wizards.
options
Some wizards may support additional "options".

Note, next to "fieldWizard", some containers may also implement "fieldInformation", which can be manipulated the same way.

See also extended container examples.

copyAfterDuplFields
Type
string (list of field names)
TCA path
$GLOBALS['TCA'][$table]['ctrl']['copyAfterDuplFields']
Scope
Proc.

The fields in this list will automatically have the value of the same field from the "previous" record transferred when they are copied to the position after another record from same table.

Changed in version 15.0 Important: #110864 - Copying records no longer inherits their language

The table tt_content no longer lists sys_language_uid. A copy keeps its own language.

The table tt_content lists colPos, so a content element that is copied after another one is placed in the same column.

Example: A copied talk takes over the room
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',
    'copyAfterDuplFields' => '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!
crdate
Type
string (field name)
TCA path
$GLOBALS['TCA'][$table]['ctrl']['crdate']
Scope
Proc.

Field name, which is automatically set to the current timestamp when the record is created. Is never modified again.

By convention the name crdate is used for that field.

Example

The following fields are set by the DataHandler automatically on creating or updating records, if they are configured in the ctrl section of the TCA:

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!
default_sortby
Type
string
TCA path
$GLOBALS['TCA'][$table]['ctrl']['default_sortby']
Scope
Display

If a field name for sortby is defined, then this is ignored.

Otherwise this is used as the 'ORDER BY' statement to sort the records in the table when listed in the TYPO3 backend. It is possible to have multiple field names in here, and each can have an ASC or DESC keyword. Note that the value should not be prefixed with 'ORDER BY' in itself.

Example: Sort speakers by name
EXT:my_extension/Configuration/TCA/tx_myextension_speaker.php
<?php

return [
  'ctrl' => [
    'title' => 'my_extension.db:speaker',
    'label' => 'name',
    'label_alt' => 'company',
    'default_sortby' => 'name',
    'tstamp' => 'tstamp',
    'crdate' => 'crdate',
    'delete' => 'deleted',
    'enablecolumns' => [
      'disabled' => 'hidden',
    ],
    'languageField' => 'sys_language_uid',
    'transOrigPointerField' => 'l10n_parent',
    'iconfile' => 'EXT:my_extension/Resources/Public/Icons/Speaker.svg',
  ],
  'columns' => [
    'name' => [
      'label' => 'my_extension.db:speaker.name',
      'config' => [
        'type' => 'input',
        'required' => true,
      ],
    ],
    'company' => [
      'label' => 'my_extension.db:speaker.company',
      'config' => [
        'type' => 'input',
      ],
    ],
  ],
  // The fields of the other tabs are added in Configuration/TCA/Overrides/
  'types' => [
    '0' => [
      'showitem' => '
        name, company,
        --div--;my_extension.db:tab.integration,
        --div--;core.form.tabs:access, hidden,
        --div--;core.form.tabs:language, sys_language_uid, l10n_parent,
      ',
    ],
  ],
];
Copied!
Example: Sort conferences by date, newest first
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!
delete
Type
string (field name)
TCA path
$GLOBALS['TCA'][$table]['ctrl']['delete']
Scope
Display / Proc.

Field name, which indicates if a record is considered deleted or not.

If this "soft delete" feature is used, then records are not really deleted, but just marked as 'deleted' by setting the value of the field name to "1". In turn, the whole system must strictly respect the record as deleted. This means that any SQL query must exclude records where this field is true.

This is a very common feature. Most tables use it throughout the TYPO3 Core. The core extension "recycler" can be used to "revive" those deleted records again.

Example: Enable soft delete for the following table
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!
descriptionColumn
Type
string (field name)
TCA path
$GLOBALS['TCA'][$table]['ctrl']['descriptionColumn']
Scope
Display

Changed in version 13.3

Field name where description of a record is stored in. This description is only displayed in the backend to guide editors and admins and should never be shown in the frontend. If filled, the content of this column is displayed in the Content > Page and Content > List module, and shown above the field list if editing a record. It is meant as a note field to give editors important additional information on single records. The TYPO3 Core sets this property for a series of main tables like be_users, be_groups and tt_content.

Example: Create a table that has a description column
The internal notes of a conference, shown above the form

The internal notes of a conference, shown above the form

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!
editlock
Type
string (field name)
TCA path
$GLOBALS['TCA'][$table]['ctrl']['editlock']
Scope
Display / Proc.

Changed in version 13.3

Field name, which – if set – will prevent all editing of the record for non-admin users.

The field should be configured as a checkbox type. Non-admins could be allowed to edit the checkbox but if they set it, they will effectively lock the record so they cannot edit it again – and they need an Admin-user to remove the lock.

Note that this flag is cleared when a new copy or version of the record is created.

This feature is used on the pages table, where it also prevents editing of records on that page (except other pages)! Also, no new records (including pages) can be created on the page.

Example: A table with editlock

If the checkbox is set, the affected record can only be edited by admins.

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!
enablecolumns
Type
array
TCA path
$GLOBALS['TCA'][$table]['ctrl']['enablecolumns']
Scope
Display / Proc.

Changed in version 13.3

The column definitions for these settings are auto-created.

Specifies which publishing control features are automatically implemented for the table.

This includes that records can be "disabled" or "hidden", have a starting and/or ending time and be access controlled so only a certain front end user group can access them. This property is used by the RestrictionBuilder to create SQL fragments.

These are the keys in the array you can use. Each of the values must be a field name in the table which should be used for the feature:

disabled
Defines which field serves as hidden/disabled flag.
starttime
Defines which field contains the starting time.
endtime
Defines which field contains the ending time.
fe_group
Defines which field is used for access control via a selection of FE user groups.
The enable columns of a conference in the Access tab

The enable columns of a conference in the Access tab

See also the delete and editlock features which are related, but are active for both frontend and backend.

EXT
Type
array
TCA path
$GLOBALS['TCA'][$table]['ctrl']['EXT']
Scope
Special

User-defined content for extensions. You can use this as you like.

Let's say that you have an extension with the key "myext", then it is ok to define properties for:

['ctrl']['EXT']['myext'] = ... (whatever you define)
Copied!

Note this is just a convention. You can use some other syntax but with the risk that it conflicts with some other extension or future changes in the TYPO3 Core.

formattedLabel_userFunc
Type
string (user function reference)
TCA path
$GLOBALS['TCA'][$table]['ctrl']['formattedLabel_userFunc']
Scope
Display

Similar to label_userFunc but allows to return formatted HTML for the label and is used only for the labels of inline (IRRE) records. The referenced user function may receive optional arguments using the formattedLabel_userFunc_options property.

formattedLabel_userFunc_options
Type
array
TCA path
$GLOBALS['TCA'][$table]['ctrl']['formattedLabel_userFunc_options']
Scope
Display

Options for formattedLabel_userFunc. The array of options is passed to the user function in the parameters array with key "options".

groupName
Type
string
TCA path
$GLOBALS['TCA'][$table]['ctrl']['groupName']
Scope
Special

This option can be used to group records in the new record wizard. If you define a new table and set its "groupName" to the key of another extension, the table will appear in the list of records from that other extension in the new record wizard.

hideAtCopy
Type
boolean
TCA path
$GLOBALS['TCA'][$table]['ctrl']['hideAtCopy']
Scope
Proc.

If set, and the "disabled" field from enablecolumns is specified, then records will be disabled/hidden when they are copied.

hideTable
Type
boolean
TCA path
$GLOBALS['TCA'][$table]['ctrl']['hideTable']
Scope
Display

Hide this table in record listings, especially the Content > Records module.

iconfile
Type
string
TCA path
$GLOBALS['TCA'][$table]['ctrl']['iconfile']
Scope
Display

Pointing to the icon file to use for the table. Icons should be square SVGs. In case you cannot supply a SVG you can still use a PNG file of 64x64 pixels in dimension.

Example: Icon of the conference table
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!
label
Type
string (field name)
TCA path
$GLOBALS['TCA'][$table]['ctrl']['label']
Scope
Display

Required!

Points to the field name of the table which should be used as the "title" when the record is displayed in the system.

A simple example
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!
label_alt
Type
string (comma-separated list of field names)
TCA path
$GLOBALS['TCA'][$table]['ctrl']['label_alt']
Scope
Display

Comma-separated list of field names, which are holding alternative values to the value from the field pointed to by "label" (see above) if that value is empty. May not be used consistently in the system, but should apply in most cases.

Example: Show the city next to the name of a location
EXT:my_extension/Configuration/TCA/tx_myextension_location.php
<?php

return [
  'ctrl' => [
    'title' => 'my_extension.db:location',
    'label' => 'name',
    'label_alt' => 'city',
    'label_alt_force' => true,
    'selicon_field' => 'image',
    'default_sortby' => 'name',
    'rootLevel' => -1,
    'security' => [
      'ignoreRootLevelRestriction' => true,
    ],
    'tstamp' => 'tstamp',
    'crdate' => 'crdate',
    'delete' => 'deleted',
    'iconfile' => 'EXT:my_extension/Resources/Public/Icons/Location.svg',
  ],
  'columns' => [
    'name' => [
      'label' => 'my_extension.db:location.name',
      'config' => [
        'type' => 'input',
        'required' => true,
      ],
    ],
    'city' => [
      'label' => 'my_extension.db:location.city',
      'config' => [
        'type' => 'input',
      ],
    ],
    'image' => [
      'label' => 'my_extension.db:location.image',
      'config' => [
        'type' => 'file',
        'maxitems' => 1,
        'allowed' => 'common-image-types',
        'relationship' => 'manyToOne',
      ],
    ],
  ],
  'types' => [
    '0' => [
      'showitem' => 'name, city, image',
    ],
  ],
];
Copied!
label_alt_force
Type
boolean
TCA path
$GLOBALS['TCA'][$table]['ctrl']['label_alt_force']
Scope
Display

If set, then the label field and the label_alt fields are shown in the title separated by comma.

label_userFunc
Type
string (user function reference)
TCA path
$GLOBALS['TCA'][$table]['ctrl']['label_userFunc']
Scope
Display

Function or method reference. This can be used whenever the label or label_alt options don't offer enough flexibility, e.g. when you want to look up another table to create your label. The result of this function overrules the label, label_alt and label_alt_force settings.

When calling a method from a class, enter [classname]->[methodname] . The passed argument is an array which contains the following information about the record for which to get the title:

$parameters['table'] = $table;
$parameters['row'] = $row;
Copied!

The resulting title must be written to $parameters['title'], which is passed by reference.

Example

Comments are listed with the name of the commenter and the date of the comment. The TCA of the comment table calls the user function:

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 class contains the code itself:

EXT:my_extension/Classes/Backend/CommentLabel.php
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\Backend;

final class CommentLabel
{
  /**
   * Shows the name of the commenter and the date of the comment,
   * for example "Jane Doe (2026-06-12)"
   */
  public function getLabel(array &$parameters): void
  {
    $name = (string)($parameters['row']['name'] ?? '');
    $created = (int)($parameters['row']['crdate'] ?? 0);
    $parameters['title'] = $created > 0
      ? sprintf('%s (%s)', $name, date('Y-m-d', $created))
      : $name;
  }
}
Copied!
label_userFunc_options
Type
array
TCA path
$GLOBALS['TCA'][$table]['ctrl']['label_userFunc_options']
Scope
Display

Options for label_userFunc. The array of options is passed to the user function in the parameters array with key "options".

languageField
Type
string (field name of type language)
TCA path
$GLOBALS['TCA'][$table]['ctrl']['languageField']
Scope
Display / Proc.

Changed in version 13.3

This property contains the column name of the column which contains the identifier language of the record. The column definition is auto-created. If it is overridden it must still be of type language fields.

The column is called sys_language_uid by convention.

Backend users can be limited to have edit access for only certain of these languages and if this option is set, edit access for languages will be enforced for this table.

Also see the Frontend Localization Guide for a discussion about the effects of this property (and other TCA properties) on the localization process.

Example: A table with localization support
The language field of a conference

The language field of a conference

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!
origUid
Type
string (field name)
TCA path
$GLOBALS['TCA'][$table]['ctrl']['origUid']
Scope
Proc.

Field name, which will contain the UID of the original record in case a record is created as a copy or new version of another record.

Is used when new versions are created from elements and enables the backend to display a visual comparison between a new version and its original.

By convention the name t3_origuid is used for that field.

Example

The following fields are set by the DataHandler automatically on creating or updating records, if they are configured in the ctrl section of the TCA:

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!
prependAtCopy
Type
plain text label or label reference
TCA path
$GLOBALS['TCA'][$table]['ctrl']['prependAtCopy']
Scope
Proc.

This string will be appended (not prepended, contrary to the name of this option) to the title of a record copy when it is inserted on the same PID as the original record to distinguish them.

Usually the value is something like (copy %s) which signifies that it was a copy that was just inserted (The token %s will be replaced by the copy number).

Note it is possible to disable this feature on a page and user or group level using the Page TSconfig option disablePrependAtCopy.

previewRenderer
Type
string (class name)
TCA path
$GLOBALS['TCA'][$table]['ctrl']['previewRenderer']
Scope
Display

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 types to configure the preview for a certain type only.

The Content > Layout module renders the previews, so the option only takes effect in the table tt_content. The Core sets the standard preview renderer for all content elements:

EXT:frontend/Configuration/TCA/tt_content.php (excerpt)
'ctrl' => [
  'previewRenderer' => \TYPO3\CMS\Backend\Preview\StandardContentPreviewRenderer::class,
],
Copied!

The conference teaser of the example extension has a preview renderer of its own.

readOnly
Type
boolean
TCA path
$GLOBALS['TCA'][$table]['ctrl']['readOnly']
Scope
Display / Proc.

Records from this table may not be edited in the TYPO3 backend. Such tables are usually called "static". If set, this property is often combined with a ext_tables_static+adt.sql file to automatically populate the table with rows.

rootLevel
Type
[0, 1, -1]
TCA path
$GLOBALS['TCA'][$table]['ctrl']['rootLevel']
Scope
Display / Proc.

Determines where a record may exist in the page tree. There are three options depending on the value:

  • 0 (false): Default. Can only exist in the page tree. Records from this table must belong to a page (i.e. have a positive "pid" field value). Thus records cannot be created in the root of the page tree (where "admin" users are the only ones allowed to create records anyways). This is the default behavior.
  • 1 (true): Can only exist in the root. Records must have a "pid"-field value equal to zero. The consequence is that only admin can edit this record.
  • -1: Can exist in both page tree and root. Records can belong either to a page (positive "pid" field value) or exist in the root of the page tree (where the "pid" field value will be 0 (zero)). Note: the -1 value will still select foreign_table records for selector boxes only from root (pid=0)
searchFields
Type
string (comma-separated list of field names)
TCA path
$GLOBALS['TCA'][$table]['ctrl']['searchFields']
Scope
Search

Changed in version 14.0

TYPO3 now automatically includes all fields of suitable types in backend search operations in the Content > Records module.

Therefore this option has been removed.

Fields can be removed from the search by setting searchable to false.

If $GLOBALS['TCA'][$table]['ctrl']['searchFields'] is set an automatic TCA migration sets all suitable fields, which are not included in the searchFields configuration, to searchable => false to keep current behavior.

Migration

If your extension previously relied on the searchFields TCA option, remove it from the ctrl section and instead define 'searchable' => false on fields that should be excluded from search results.

No action is needed if the default behavior (search all suitable fields) is acceptable.

security
Type
array
TCA path
$GLOBALS['TCA'][$table]['ctrl']['security']
Scope
Display

Array of sub-properties. Conferences may also be stored on standard pages:

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 locations are shared by all sites and are stored on the root page, so non-admin users need ignoreRootLevelRestriction to edit them:

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

return [
  'ctrl' => [
    'title' => 'my_extension.db:location',
    'label' => 'name',
    'label_alt' => 'city',
    'label_alt_force' => true,
    'selicon_field' => 'image',
    'default_sortby' => 'name',
    'rootLevel' => -1,
    'security' => [
      'ignoreRootLevelRestriction' => true,
    ],
    'tstamp' => 'tstamp',
    'crdate' => 'crdate',
    'delete' => 'deleted',
    'iconfile' => 'EXT:my_extension/Resources/Public/Icons/Location.svg',
  ],
  'columns' => [
    'name' => [
      'label' => 'my_extension.db:location.name',
      'config' => [
        'type' => 'input',
        'required' => true,
      ],
    ],
    'city' => [
      'label' => 'my_extension.db:location.city',
      'config' => [
        'type' => 'input',
      ],
    ],
    'image' => [
      'label' => 'my_extension.db:location.image',
      'config' => [
        'type' => 'file',
        'maxitems' => 1,
        'allowed' => 'common-image-types',
        'relationship' => 'manyToOne',
      ],
    ],
  ],
  'types' => [
    '0' => [
      'showitem' => 'name, city, image',
    ],
  ],
];
Copied!

A site package can set the sub-properties for a table of another extension in an override file:

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

defined('TYPO3') or die();

// The hotels of this site are stored in one folder outside of the web
// mounts of the editors, who still add the hotels to their conferences
$GLOBALS['TCA']['tx_myextension_hotel']['ctrl']['security']['ignoreWebMountRestriction'] = true;
Copied!
ignoreWebMountRestriction
Allows users to access records that are not in their defined web-mount, thus bypassing this restriction.
ignoreRootLevelRestriction
Allows non-admin users to access records that are on the root-level (page ID 0), thus bypassing this usual restriction.
ignorePageTypeRestriction
Allows to use a TCA table on any kind of page doktype unless a doktype has a restriction set in the PageDoktypeRegistry API class.
selicon_field
Type
string (field name)
TCA path
$GLOBALS['TCA'][$table]['ctrl']['selicon_field']
Scope
Display

Field name, which contains the thumbnail image used to represent the record visually whenever it is shown in FormEngine as a foreign reference selectable from a selector box.

This field must be a File field where icon files are selected. Since only the first icon file will be used, the maxitems option should be used to allow only selecting a single icon file.

You should consider this a feature where you can attach an "icon" to a record which is typically selected as a reference in other records, for example a "category". In such a case this field points out the icon image which will then be shown. This feature can thus enrich the visual experience of selecting the relation in other forms.

Example: Show the image of a location when selecting it
The images of the locations below the location field of a conference

The images of the locations below the location field of a conference

The location table names its field image as selicon_field:

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

return [
  'ctrl' => [
    'title' => 'my_extension.db:location',
    'label' => 'name',
    'label_alt' => 'city',
    'label_alt_force' => true,
    'selicon_field' => 'image',
    'default_sortby' => 'name',
    'rootLevel' => -1,
    'security' => [
      'ignoreRootLevelRestriction' => true,
    ],
    'tstamp' => 'tstamp',
    'crdate' => 'crdate',
    'delete' => 'deleted',
    'iconfile' => 'EXT:my_extension/Resources/Public/Icons/Location.svg',
  ],
  'columns' => [
    'name' => [
      'label' => 'my_extension.db:location.name',
      'config' => [
        'type' => 'input',
        'required' => true,
      ],
    ],
    'city' => [
      'label' => 'my_extension.db:location.city',
      'config' => [
        'type' => 'input',
      ],
    ],
    'image' => [
      'label' => 'my_extension.db:location.image',
      'config' => [
        'type' => 'file',
        'maxitems' => 1,
        'allowed' => 'common-image-types',
        'relationship' => 'manyToOne',
      ],
    ],
  ],
  'types' => [
    '0' => [
      'showitem' => 'name, city, image',
    ],
  ],
];
Copied!

The field image allows a single image:

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

return [
  'ctrl' => [
    'title' => 'my_extension.db:location',
    'label' => 'name',
    'label_alt' => 'city',
    'label_alt_force' => true,
    'selicon_field' => 'image',
    'default_sortby' => 'name',
    'rootLevel' => -1,
    'security' => [
      'ignoreRootLevelRestriction' => true,
    ],
    'tstamp' => 'tstamp',
    'crdate' => 'crdate',
    'delete' => 'deleted',
    'iconfile' => 'EXT:my_extension/Resources/Public/Icons/Location.svg',
  ],
  'columns' => [
    'name' => [
      'label' => 'my_extension.db:location.name',
      'config' => [
        'type' => 'input',
        'required' => true,
      ],
    ],
    'city' => [
      'label' => 'my_extension.db:location.city',
      'config' => [
        'type' => 'input',
      ],
    ],
    'image' => [
      'label' => 'my_extension.db:location.image',
      'config' => [
        'type' => 'file',
        'maxitems' => 1,
        'allowed' => 'common-image-types',
        'relationship' => 'manyToOne',
      ],
    ],
  ],
  'types' => [
    '0' => [
      'showitem' => 'name, city, image',
    ],
  ],
];
Copied!

The conference table selects its location with render type selectSingle. The field wizard selectIcons shows the images of the locations below the drop-down:

EXT:my_extension/Configuration/TCA/Overrides/110-tx_myextension_conference-location.php
<?php

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

ExtensionManagementUtility::addTCAcolumns('tx_myextension_conference', [
  'location' => [
    'label' => 'my_extension.db:conference.location',
    'config' => [
      'type' => 'select',
      'renderType' => 'selectSingle',
      'foreign_table' => 'tx_myextension_location',
      'items' => [
        ['label' => '', 'value' => 0],
      ],
      'fieldWizard' => [
        'selectIcons' => [
          'disabled' => false,
        ],
      ],
      'relationship' => 'manyToOne',
      // Venues only, not their halls
      'foreign_table_where' => 'AND {#tx_myextension_location}.{#parent} = 0 ORDER BY tx_myextension_location.name',
    ],
  ],
]);
ExtensionManagementUtility::addToAllTCAtypes(
  'tx_myextension_conference',
  'location',
  '',
  'after:conference_date',
);
Copied!
sortby
Type
string (field name)
TCA path
$GLOBALS['TCA'][$table]['ctrl']['sortby']
Scope
Display / Proc.

Field name, which is used to manage the order of the records when displayed.

The field contains an integer value which positions it at the correct position between other records from the same table on the current page. It should not be made editable by the user since the DataHandler will manage the content automatically.

This feature is used by e.g. the "pages" table and "tt_content" table (Content Elements) in order to output the pages or the content elements in the order expected by the editors. Extensions are expected to respect this field.

Typically the field name sorting is dedicated to this feature.

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',
    'copyAfterDuplFields' => '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!
title
Type
plain text label or label reference
TCA path
$GLOBALS['TCA'][$table]['ctrl']['title']
Scope
Display

Contains the system name of the table. Is used for display in the backend.

For instance the "tt_content" table is named "tt_content" technically. However in the backend display it will be shown as "Page Content" when the backend language is English. When another language is chosen, like Danish, then the label "Sideindhold" is shown instead. This value is managed by the "title" value.

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!

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

translationSource
Type
string (field name)
TCA path
$GLOBALS['TCA'][$table]['ctrl']['translationSource']
Scope
Display / Proc.

Changed in version 13.3

Name of the field, by convention l10n_source is used by translations to point back to the original record (i.e. the record in any language from which they are a translated).

This property is similar to transOrigPointerField. Both fields only contain valid record uids (and not 0), if the record is a translation (connected mode), and not a copy (free mode). In connected mode, while transOrigPointerField always contains the uid of the default language record, this field contains the uid of the record the translation was created from.

For example, if a tt_content record in default language English with uid 13 exists, this record is translated to French with uid 17, and the Danish translation is later created based on the French translation, then the Danish translation has uid 13 set as l10n_parent and 17 as l10n_source.

The column in the database is auto created. If you ever override it, it should be at least a large text field (clob/blob). If you do not define the field in the file ext_tables.sql it is automatically created with the correct type.

Example: Keep track of the translation origin in connected mode translations
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!
transOrigDiffSourceField
Type
string (field name)
TCA path
$GLOBALS['TCA'][$table]['ctrl']['transOrigDiffSourceField']
Scope
Display / Proc.

Changed in version 13.3

Column name, by convention l10n_diffsource, which will be updated with the value of the original language record whenever the translation record is updated. This information is later used to compare the current values of the default record with those stored in this field. If they differ, there will be a display in the form of the difference visually. This is a big help for translators so they can quickly grasp the changes that happened to the default language text.

The column in the database is auto created. If you ever override it, it should be at least a large text field (clob/blob). If you do not define the field in the file ext_tables.sql it is automatically created with the correct type.

The column definition is auto-created. If it is overridden it must still be of type passthrough.

Example: Display changes from the original language
The tracks of a translated conference with the track that was added to the default language

The track "Community" was added to the default language after the translation

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!
transOrigPointerField
Type
string (field name)
TCA path
$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']
Scope
Display / Proc.

Changed in version 13.3

Name of the column, by convention l10n_parent, used by translations to point back to the original record, the record in the default language of which they are a translation.

If this value is found being set together with the languageField then the FormEngine will show the default translation value under the fields in the main form. This is very neat if translators are to see what they are translating.

The column definition is auto-created. If it is overridden it must still be of type passthrough.

Example: Define a translation origin
A translated title, with the title of the original record below

A translated title, with the title of the original record below

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!
tstamp
Type
string (field name)
TCA path
$GLOBALS['TCA'][$table]['ctrl']['tstamp']
Scope
Proc.

Field name, which is automatically updated to the current timestamp (UNIX-time in seconds) each time the record is updated/saved in the system.

By convention the name tstamp is used for that field.

Examples

The following fields are set by the DataHandler automatically on creating or updating records, if they are configured in the ctrl section of the TCA:

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!
type
Type
string (field name, or relation_field:foreign_type_field)
TCA path
$GLOBALS['TCA'][$table]['ctrl']['type']
Scope
Display / Proc.

Field name, which defines the "record type".

The value of this field determines which one of the types configurations are used for displaying the fields in the FormEngine. It will probably also affect how the record is used in the context where it belongs.

The most widely known usage of this feature is the case of Content Elements where the Type: selector is defined as the "CType" field and when you change that selector you will also get another rendering of the form:

The type field of a content element

The type field of a content element

It is used for example by the "doktype" field in the "pages" table.

On changing the value of the field defined in type the user gets prompted to reload the record.

Changing the type asks to save the record and reload the form

Changing the type asks to save the record and reload the form

Only one type field can be defined. If you need to reload the record on changing another field, see property onchange.

It is also possible to make the type depend on the value of a related record, for example to switch using the type field of a foreign table. The syntax is relation_field:foreign_type_field. For example the sys_file_metadata table takes its type from the sys_file table.

Examples 

The type stored in a field 

A talk of the type workshop

A talk of the type workshop

A talk of the conference extension can be a regular talk, a workshop or a keynote. The field talk_type stores which one it is, so the ctrl section of the talk table names it as type:

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',
    'copyAfterDuplFields' => '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!

Each value of talk_type has its own entry in the types section, which defines the fields shown in the backend form. All three types start with the same fields:

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',
    'copyAfterDuplFields' => '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!

A field that only some types show is added to those types alone: the third argument of ExtensionManagementUtility::addToAllTCAtypes() lists them. Only a workshop asks for the maximum number of participants:

EXT:my_extension/Configuration/TCA/Overrides/245-tx_myextension_talk-max_participants.php
<?php

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

ExtensionManagementUtility::addTCAcolumns('tx_myextension_talk', [
  'max_participants' => [
    'label' => 'my_extension.db:talk.max_participants',
    'config' => [
      'type' => 'number',
      'nullable' => true,
      'range' => [
        'lower' => 1,
      ],
    ],
  ],
]);
ExtensionManagementUtility::addToAllTCAtypes(
  'tx_myextension_talk',
  'max_participants',
  'workshop',
  'before:--div--;core.form.tabs:access',
);
Copied!

See the section about types for more details.

Type in relation to a foreign table's field 

Two partnerships of a conference, each with other fields

The partnership with an online conference shows other fields

A partnership relates a conference to a partner conference. The format of the partner conference decides which fields the partnership shows. An on-site partner conference gives a discount. An online partner conference shares its live stream.

The select field partner points to the partner conference. The type in the ctrl section names this field and the field event_format of the conference, separated by a colon:

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!

The field that points to the other record must be of the type select, category, or group. A group field takes the first table of its allowed list.

The value online has its own entry in the types section. On-site and hybrid partner conferences have no entry of their own, so these partnerships use the type 0. When an editor selects another partner conference, the form reloads and shows the fields of the new type.

typeicon_classes
Type
array
TCA path
$GLOBALS['TCA'][$table]['ctrl']['typeicon_classes']
Scope
Display

Array of icon identifiers to use for the records. The keys must correspond to the values found in the column referenced in the typeicon_column property. The values correspond to icons registered in the Icon API. With the key default, a default icon is defined, which is used when no matching key is found. The default icon is also used in the "Create new record" dialog from the Content > Records module. For using and configuring typeicon_classes for custom page types, please see Create a new Page Type.

Example: Icons for the types of talks
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',
    'copyAfterDuplFields' => '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!
typeicon_column
Type
string (field name)
TCA path
$GLOBALS['TCA'][$table]['ctrl']['typeicon_column']
Scope
Display

Field name, whose value decides alternative icons for the table records.

The values in the field referenced by this property must match entries in the array defined in typeicon_classes properties. If no match is found, the default icon is used. See example in the related typeicon_classes property.

If used, the value of this property is often set to the same field name as type.

useColumnsForDefaultValues
Type
string (list of field names)
TCA path
$GLOBALS['TCA'][$table]['ctrl']['useColumnsForDefaultValues']
Scope
Proc.

When a new record is created, this defines the fields from the 'previous' record that should be used as default values.

What is considered the 'previous' record depends on how the record is created. For example, if TSconfig options.saveDocNew is enabled, you can create a new record from an existing one using the "New" button.

This may still get overridden by the default values for the record. When assigning values to a new record the following are used (applied in that order, e.g. Page TSconfig will override User TSconfig):

  1. User TSconfig
  2. Page TSconfig
  3. From 'previous' record
  4. Default values
  5. From 'inline' relations

See \TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseRowInitializeNew->DatabaseRowInitializeNew()

Example: New talks take over the type and the room
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',
    'copyAfterDuplFields' => '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!
versioningWS
Type
boolean
TCA path
$GLOBALS['TCA'][$table]['ctrl']['versioningWS']
Scope
Proc.

If set, versioning is enabled for this table.

Versioning in TYPO3 is based on this scheme:

[Online version, pid>=0] 1- * [Offline versions, pid==1]
Copied!

Offline versions are identified by having a pid value = -1 and they refer to their online version by the field t3ver_oid. Offline versions of the "Page" and "Branch" types (contrary to "Element" type) can have child records which points to the uid of their offline "root" version with their pid fields (as usual). These children records are typically copies of child elements of the online version of the offline root version, but are not considered "versions" of them in a technical sense, hence they don't point to them with their t3ver_oid field (and shouldn't).

In the backend "Offline" is labeled "Draft" while "Online" is labeled "Live".

In order for versioning to work on a table there are certain requirements; Tables supporting versioning must have these fields:

t3ver_oid
For offline versions; pointing back to online version uid. For online: 0 (zero)
t3ver_wsid
For offline versions: Workspace ID of version. For all workspace Ids apart from 0 (zero) there can be only one version of an element per ID. For online: 0 (zero) unless t3ver_state is set in which case it plays a role for previews in the backend (to no de-select placeholders for workspaces, see \TYPO3\CMS\Backend\Utility\BackendUtility::versioningPlaceholderClause()) and for publishing of move-to-actions (see \TYPO3\CMS\Backend\Utility\BackendUtility::getMovePlaceholder() ).
t3ver_state

Contains special states of a version used when new, deleted, moved content requires versioning.

  • For an online version:

    • "1" or "2" means that it is a temporary placeholder for a new element (which is the offline version of this record)
    • If "t3ver_state" has a value >0 it should never be shown in Live workspace.
  • For an offline version:

    • "1" or "2" means that when published, the element must be deleted (placeholder for delete-action).
    • "-1" means it is just an indication that the online version has the flag set to "1" (is a placeholder for new records.). This only affects display, not processing anywhere.
t3ver_stage
Contains the ID of the stage at which the record is. Special values are "0" which still refers to "edit", "-10" refers to "ready to publish".
t3ver_count
0/offline=draft/never published, 0/online=current, 1/offline=archive, 1+=multiple online/offline occurrences (incrementation happens when versions are swapped offline.)
t3ver_tstamp
Timestamp of last swap/publish action.

Changed in version 10.0

Field t3ver_move_id is not evaluated anymore. It can be safely dropped after the upgrade wizard has been executed.

Corresponding SQL definitions:

t3ver_oid int(11) DEFAULT '0' NOT NULL,
t3ver_wsid int(11) DEFAULT '0' NOT NULL,
t3ver_state tinyint(4) DEFAULT '0' NOT NULL,
t3ver_stage int(11) DEFAULT '0' NOT NULL,
Copied!

Special `t3ver_swapmode` field for pages

When pages are versioned it is an option whether content and even the branch of the page is versioned. This is determined by the parameter treeLevels set when the page is versioned. -1 means swap only record, 0 means record and content and '> 0' means full branch. When the version is later published the swapping will happen accordingly.

versioningWS_alwaysAllowLiveEdit
Type
boolean
TCA path
$GLOBALS['TCA'][$table]['ctrl']['versioningWS_alwaysAllowLiveEdit']
Scope
Special

If set, this table can always be edited live even in a workspace and even if "live editing" is not enabled in a custom workspace. For instance this is set by default for Backend user and group records since it is assumed that administrators like the flexibility of editing backend users without having to go to the Live workspace.