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 interface. 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 Examples demonstrating the ctrl section of TCA.

A common example of the control section
EXT:styleguide/Configuration/TCA/tx_styleguide_ctrl_common.php
[
    'ctrl' => [
        'title' => 'Form engine - Common table control',
        'label' => 'title',
        'descriptionColumn' => 'description',
        'tstamp' => 'tstamp',
        'crdate' => 'crdate',
        'delete' => 'deleted',
        'sortby' => 'sorting',
        'default_sortby' => 'title',
        'versioningWS' => true,
        'rootLevel' => -1,
        'iconfile' => 'EXT:styleguide/Resources/Public/Icons/tx_styleguide.svg',
        'origUid' => 't3_origuid',
        'languageField' => 'sys_language_uid',
        'transOrigPointerField' => 'l10n_parent',
        'transOrigDiffSourceField' => 'l10n_diffsource',
        'translationSource' => 'l10n_source',
        'searchFields' => 'title,description',
        'enablecolumns' => [
            'disabled' => 'hidden',
            'starttime' => 'starttime',
            'endtime' => 'endtime',
        ],
        'security' => [
            'ignorePageTypeRestriction' => true,
        ],
    ],
]
Copied!

Properties of the TCA ctrl section

Name Type Scope
boolean Proc. / Display
array Display
string (list of field names) Proc.
string (field name) Proc.
string Display
string (field name) Proc. / Display
string (field name) Display
string (field name) Proc. / Display
array Proc. / Display
array (variable, depends on extension)
string Display
array Display
string Special
boolean Proc.
boolean Display
string Display
boolean Used by import/export
string (field name) Display
String (comma-separated list of field names) Display
boolean Display
string Display
array Display
string (field name of type language) Proc. / Display
string (field name) Proc.
string or LLL reference Proc.
string Display
boolean Proc. / Display
[0, 1, -1] Proc. / Display
string Search
array Display
string (field name) Proc. / Display
string or LLL reference Display
string (field name) Proc. / Display
string (field name) Proc. / Display
string (field name) Proc. / Display
string (field name) Proc.
string (field name) Display / Proc.
array Display
string (field name) Display
string (list of field names) Proc.
boolean Proc.
boolean Special

adminOnly

adminOnly
Type
boolean
Path
$GLOBALS['TCA'][$table]['ctrl']
Scope
Proc. / Display

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

Example: Table my_table is only editable by admin users:
EXT:my_sitepackage/Configuration/TCA/my_table.php
'ctrl' => [
    'adminOnly' => 1,
    ...
],
Copied!

container

container
Type
array
Path
$GLOBALS['TCA'][$table]['ctrl']
Scope
Display
Examples
Extended container examples

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

Next to single elements, some render container allow to be "enriched" with additional information via the "node expansion" API. Currently, the OuterWrapContainer 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 basic array looks like:

'ctrl' => [
    'container' => [
        '<containerRenderType>' => [
            'fieldWizard' => [
                '<aName>' => [
                    'renderType' => '<aRenderType>',
                    'before' => ['<anotherName>'],
                    'after' => ['<yetAnotherName>'],
                    'disabled' => false,
                    'options' => [],
                ],
            ],
        ],
    ],
],
Copied!
<containerRenderType>

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

  • outerWrapContainer type which corresponds to the OuterWrapContainer (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

copyAfterDuplFields
Type
string (list of field names)
Path
$GLOBALS['TCA'][$table]['ctrl']
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.

Example from tt_content table:

crdate

crdate
Type
string (field name)
Path
$GLOBALS['TCA'][$table]['ctrl']
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_domain_model_something.php
<?php

return [
    'ctrl' => [
        'tstamp' => 'tstamp',
        'crdate' => 'crdate',
        'origUid' => 't3_origuid',
        // ...
    ],
];
Copied!

default_sortby

default_sortby
Type
string
Path
$GLOBALS['TCA'][$table]['ctrl']
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 by title
'ctrl' => [
    'default_sortby' => 'title',
    ...
],
Copied!
Example: by title and then by creation date
'ctrl' => [
    'default_sortby' => 'title ASC, crdate DESC',
    ...
],
Copied!

delete

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

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
<?php

return [
    'ctrl' => [
        'delete' => 'deleted',
        // ...
    ],
];
Copied!

descriptionColumn

descriptionColumn
Type
string (field name)
Path
$GLOBALS['TCA'][$table]['ctrl']
Scope
Display

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 field is displayed in the page and 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
Record information shown editing an example record
EXT:styleguide/Configuration/TCA/tx_styleguide_ctrl_common.php
[
    'ctrl' => [
        'title' => 'Form engine - Common table control',
        'label' => 'title',
        'descriptionColumn' => 'description',
        'tstamp' => 'tstamp',
        'crdate' => 'crdate',
        'delete' => 'deleted',
        'sortby' => 'sorting',
        'default_sortby' => 'title',
        'versioningWS' => true,
        'rootLevel' => -1,
        'iconfile' => 'EXT:styleguide/Resources/Public/Icons/tx_styleguide.svg',
        'origUid' => 't3_origuid',
        'languageField' => 'sys_language_uid',
        'transOrigPointerField' => 'l10n_parent',
        'transOrigDiffSourceField' => 'l10n_diffsource',
        'translationSource' => 'l10n_source',
        'searchFields' => 'title,description',
        'enablecolumns' => [
            'disabled' => 'hidden',
            'starttime' => 'starttime',
            'endtime' => 'endtime',
        ],
        'security' => [
            'ignorePageTypeRestriction' => true,
        ],
    ],
]
Copied!

editlock

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

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.

<?php

return [
    'ctrl' => [
        'enablecolumns' => [
            'editlock' => 'editlock',
        ],
        // ...
    ],
    'columns' => [
        'editlock' => [
            'displayCond' => 'HIDE_FOR_NON_ADMINS',
            'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:editlock',
            'config' => [
                'type' => 'check',
                'renderType' => 'checkboxToggle',
            ],
        ],
        // ...
    ],
    'palettes' => [
        'access' => [
            'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:palette.access',
            'showitem' => '
                editlock
            ',
        ],
    ],
    'types' => [
        0 => [
            'showitem' => '
                --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general,
                    [...],
                --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access,
                    --palette--;;access,
            ',
        ],
    ],
];
Copied!

enablecolumns

enablecolumns
Type
array
Path
$GLOBALS['TCA'][$table]['ctrl']
Scope
Proc. / Display

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.
Record information shown editing an example record

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

EXT

EXT
Type
array
Path
$GLOBALS['TCA'][$table]['ctrl']
Scope
(variable, depends on extension)

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

formattedLabel_userFunc
Type
string
Path
$GLOBALS['TCA'][$table]['ctrl']
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

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

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

groupName

groupName
Type
string
Path
$GLOBALS['TCA'][$table]['ctrl']
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.

We really appreciate you setting the ctrl property title to a localized value (LLL:EXT:), otherwise it may happen that TYPO3 cannot extract the correct extension key from your table name, resulting in wrong icons in list of new record wizard. This only happens if your extension key contains underscores _, but the second part of your table name does not. For example: If your extension key is my_extension the table names will normally start with tx_myextension. Since myextension does not match the real extension key my_extension, the icon of your extension cannot be retrieved from your extension. Instead of a localized title, you can also set groupName to your real extension key: my_extension.

hideAtCopy

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

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

hideTable

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

Hide this table in record listings, especially the list module.

iconfile

iconfile
Type
string
Path
$GLOBALS['TCA'][$table]['ctrl']
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 usage from the "examples" extension
'ctrl' => [
    'iconfile' => 'EXT:examples/Resources/Public/Images/Haiku.svg',
    ...
],
Copied!

is_static

is_static
Type
boolean
Path
$GLOBALS['TCA'][$table]['ctrl']
Scope
Used by import/export

This marks a table to be "static".

A "static table" means that it should not be updated for individual databases because it is meant to be centrally updated and distributed. For instance static tables could contain country-codes used in many systems.

The foremost property of a static table is that the uid's used are the SAME across systems. Import/Export of records expect static records to be common for two systems.

label

label
Type
string (field name)
Path
$GLOBALS['TCA'][$table]['ctrl']
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
A minimal example of the control section
EXT:styleguide/Configuration/TCA/tx_styleguide_ctrl_minimal.php
[
    'ctrl' => [
        'title' => 'LLL:EXT:styleguide/Resources/Private/Language/locallang.xlf:minimalTableTitle',
        'label' => 'title',
        'iconfile' => 'EXT:styleguide/Resources/Public/Icons/tx_styleguide.svg',
        'security' => [
            'ignorePageTypeRestriction' => true,
        ],
    ],
    'columns' => [
        'title' => [
            'label' => 'LLL:EXT:styleguide/Resources/Private/Language/locallang.xlf:minimalTableTitleField',
            'config' => [
                'type' => 'input',
            ],
        ],
    ],
    'types' => [
        [
            'showitem' => 'title',
        ],
    ],
]
Copied!

label_alt

label_alt
Type
String (comma-separated list of field names)
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 for table tt_content
'ctrl' => [
    'label' => 'header',
    'label_alt' => 'subheader,bodytext',
],
Copied!

label_alt_force

label_alt_force
Type
boolean
Scope
Display

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

label_userFunc

label_userFunc
Type
string
Path
$GLOBALS['TCA'][$table]['ctrl']
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:

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

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

Example

Let's look at what is done for the "haiku" table of the "examples" extension. The call to the user function appears in the EXT:examples/Configuration/TCA/tx_examples_haiku.php file:

'ctrl' => [
    'label' => 'title',
    'label_userFunc' => \Documentation\Examples\Userfuncs\Tca::class . '->haikuTitle',
],
Copied!

Class Documentation\Examples\Userfuncs\Tca contains the code itself:

public function haikuTitle(&$parameters)
{
    $record = BackendUtility::getRecord($parameters['table'], $parameters['row']['uid']);
    $newTitle = $record['title'];
    $newTitle .= ' (' . substr(strip_tags($record['poem']), 0, 10) . '...)';
    $parameters['title'] = $newTitle;
}
Copied!

label_userFunc_options

label_userFunc_options
Type
array
Scope
Display

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

languageField

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

Deprecated since version 11.2

This property contains the field name of the field which contains a pointer to the language of the record. The field should have the type language. The field is called sys_language_uid by convention.

This TCA type automatically displays all available languages for the current context (the corresponding site configuration) and also automatically adds the special -1 language (meaning all languages) for all record types, except pages.

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
A typical sys_language_uid field
EXT:my_extension/Configuration/TCA/tx_myextension_domain_model_something.php
<?php

return [
    'ctrl' => [
        'transOrigPointerField' => 'l10n_parent',
        'transOrigDiffSourceField' => 'l10n_diffsource',
        'languageField' => 'sys_language_uid',
        'translationSource' => 'l10n_source',
        // ...
    ],
    'columns' => [
        'sys_language_uid' => [
            'exclude' => true,
            'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
            'config' => [
                'type' => 'language',
            ],
        ],
        'l10n_parent' => [
            'displayCond' => 'FIELD:sys_language_uid:>:0',
            'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
            'config' => [
                'type' => 'select',
                'renderType' => 'selectSingle',
                'items' => [
                    [
                        'label' => '',
                        'value' => 0,
                    ],
                ],
                'foreign_table' => 'tx_myextension_domain_model_something',
                'foreign_table_where' =>
                    'AND {#tx_myextension_domain_model_something}.{#pid}=###CURRENT_PID###'
                    . ' AND {#tx_myextension_domain_model_something}.{#sys_language_uid} IN (-1,0)',
                'default' => 0,
            ],
        ],
        'l10n_source' => [
            'config' => [
                'type' => 'passthrough',
            ],
        ],
        'l10n_diffsource' => [
            'config' => [
                'type' => 'passthrough',
                'default' => '',
            ],
        ],
        // ...
    ],
    'palettes' => [
        'language' => [
            'showitem' => '
                sys_language_uid,l10n_parent,
            ',
        ],
    ],
    'types' => [
        0 => [
            'showitem' => '
                --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general,
                    [...],
                --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language,
                    --palette--;;language,
            ',
        ],
    ],
];
Copied!

origUid

origUid
Type
string (field name)
Path
$GLOBALS['TCA'][$table]['ctrl']
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_domain_model_something.php
<?php

return [
    'ctrl' => [
        'tstamp' => 'tstamp',
        'crdate' => 'crdate',
        'origUid' => 't3_origuid',
        // ...
    ],
];
Copied!

prependAtCopy

prependAtCopy
Type
string or LLL reference
Path
$GLOBALS['TCA'][$table]['ctrl']
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

previewRenderer
Type
string
Path
$GLOBALS['TCA'][$table]['ctrl']
Scope
Display

Configures a backend preview for a content element.

Have also a look at Configure custom backend preview for content element for more details.

Use property previewRenderer of section types to configure the preview for a certain type or subtype only.

Example: Use for any record in a table

This specifies the preview renderer to be used for any record in tx_myextension_domain_model_mytable:

$GLOBALS['TCA']['tx_myextension_domain_model_mytable']['ctrl']['previewRenderer']
    = \MyVendor\MyExtension\Preview\PreviewRenderer::class;
Copied!

readOnly

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

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

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

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

searchFields
Type
string
Path
$GLOBALS['TCA'][$table]['ctrl']
Scope
Search

Comma-separated list of fields from the table that will be included when searching for records in the TYPO3 backend. No record from a table will ever be found if that table does not have searchFields defined. Only fields of the following TCA types are searchable:

Adding fields of different types to searchFields has no effect.

There are more fine grained controls per column, see the documentation of the "search" key of any type in Field types (config > type).

Example from "tt_content" table
'ctrl' => [
    'searchFields' => 'header,header_link,subheader,bodytext,pi_flexform',
    ...
],
Copied!

security

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

Array of sub-properties. This is used, for example, in the Core for the sys_file table:

EXT:core/Configuration/TCA/sys_file.php
return [
    'ctrl' => [
        // ...
        'security' => [
            'ignoreWebMountRestriction' => true,
            'ignoreRootLevelRestriction' => true,
        ],
        // ...
    ],
];
Copied!

And ignorePageTypeRestriction is used for the sys_note table:

EXT:sys_note/Configuration/TCA/sys_note.php
return [
    'ctrl' => [
        // ...
        'security' => [
            'ignorePageTypeRestriction' => true,
        ],
        // ...
    ],
];
Copied!

You can also use it in an override file:

EXT:my_extension/Configuration/TCA/Overrides/my_table.php
$GLOBALS['TCA']['my_table']['ctrl']['security']['ignoreWebMountRestriction'] = true;
$GLOBALS['TCA']['my_table']['ctrl']['security']['ignoreRootLevelRestriction'] = true;
$GLOBALS['TCA']['my_table']['ctrl']['security']['ignorePageTypeRestriction'] = 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

New in version 12.0

This is a replacement for the previous PHP API call ExtensionManagementUtility::allowTableOnStandardPages() which was found in ext_tables.php files.

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

selicon_field
Path

$GLOBALS['TCA'][$table]['ctrl']

type

string (field name)

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 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: Select foreign records from a drop-down using selicon

The table tx_styleguide_elements_select_single_12_foreign is defined as follows:

[
   'ctrl' => [
      'title' => 'Form engine elements - select foreign single_12',
      'label' => 'fal_1',
      'selicon_field' => 'fal_1',
      // ...
   ],

   'columns' => [
      // ...
      'fal_1' => [
         'label' => 'fal_1 selicon_field',
         'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
            'fal_1',
            [
               'maxitems' => 1,
            ],
            $GLOBALS['TYPO3_CONF_VARS']['SYS']['mediafile_ext']
         ),
      ],
   ],
   // ...

];
Copied!

It can be used in another table as a foreign relation, for example in a field with render type singleSelect:

EXT:styleguide/Configuration/TCA/tx_styleguide_elements_select.php
[
    'columns' => [
        'select_single_12' => [
            'label' => 'select_single_12 foreign_table selicon_field',
            'config' => [
                'type' => 'select',
                'renderType' => 'selectSingle',
                'foreign_table' => 'tx_styleguide_elements_select_single_12_foreign',
                'fieldWizard' => [
                    'selectIcons' => [
                        'disabled' => false,
                    ],
                ],
            ],
        ],
    ],
]
Copied!

You can find this example in the extension styleguide.

sortby

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

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_domain_model_something.php
<?php

return [
    'ctrl' => [
        'sortby' => 'sorting',
    ],
];
Copied!

title

title
Type
string or LLL reference
Path
$GLOBALS['TCA'][$table]['ctrl']
Scope
Display

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

For instance the "tt_content" table is of course 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.

You can insert plain text values, but the preferred way is to enter a reference to a localized string. Refer to the Localization section for more details.

Example for table sys_template
'ctrl' => [
    'title' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:sys_template',
],
Copied!

In the above example the LLL: prefix tells the system to look up a label from a localized file. The next prefix code:EXT:frontend will look for the data in the extension with the key "frontend". In that extension the file locallang_tca.xlf contains a XML structure inside of which one label tag has an index attribute named "sys_template". This tag contains the value to display in the default language. Other languages are provided by the language packs.

transOrigDiffSourceField

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

Field name, by convention 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 field type in the database should be 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.

This field needs no configuration in $GLOBALS['TCA'][<table>]['columns'] , but if you do, select the passthrough type. That will enable the undo function to also work on this field.

Example: Display changes in from the original language
Header field showing values from two other languages

Header field showing values from two other languages

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

return [
    'ctrl' => [
        'transOrigPointerField' => 'l10n_parent',
        'transOrigDiffSourceField' => 'l10n_diffsource',
        'languageField' => 'sys_language_uid',
        'translationSource' => 'l10n_source',
        // ...
    ],
    'columns' => [
        'sys_language_uid' => [
            'exclude' => true,
            'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
            'config' => [
                'type' => 'language',
            ],
        ],
        'l10n_parent' => [
            'displayCond' => 'FIELD:sys_language_uid:>:0',
            'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
            'config' => [
                'type' => 'select',
                'renderType' => 'selectSingle',
                'items' => [
                    [
                        'label' => '',
                        'value' => 0,
                    ],
                ],
                'foreign_table' => 'tx_myextension_domain_model_something',
                'foreign_table_where' =>
                    'AND {#tx_myextension_domain_model_something}.{#pid}=###CURRENT_PID###'
                    . ' AND {#tx_myextension_domain_model_something}.{#sys_language_uid} IN (-1,0)',
                'default' => 0,
            ],
        ],
        'l10n_source' => [
            'config' => [
                'type' => 'passthrough',
            ],
        ],
        'l10n_diffsource' => [
            'config' => [
                'type' => 'passthrough',
                'default' => '',
            ],
        ],
        // ...
    ],
    'palettes' => [
        'language' => [
            'showitem' => '
                sys_language_uid,l10n_parent,
            ',
        ],
    ],
    'types' => [
        0 => [
            'showitem' => '
                --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general,
                    [...],
                --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language,
                    --palette--;;language,
            ',
        ],
    ],
];
Copied!

transOrigPointerField

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

Name of the field, 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 languageField then 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 target field must be configured in $GLOBALS['TCA'][<table>]['columns'] , at least as a passthrough type.

Example: Define a translation origin
EXT:my_extension/Configuration/TCA/tx_myextension_domain_model_something.php
<?php

return [
    'ctrl' => [
        'transOrigPointerField' => 'l10n_parent',
        'transOrigDiffSourceField' => 'l10n_diffsource',
        'languageField' => 'sys_language_uid',
        'translationSource' => 'l10n_source',
        // ...
    ],
    'columns' => [
        'sys_language_uid' => [
            'exclude' => true,
            'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
            'config' => [
                'type' => 'language',
            ],
        ],
        'l10n_parent' => [
            'displayCond' => 'FIELD:sys_language_uid:>:0',
            'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
            'config' => [
                'type' => 'select',
                'renderType' => 'selectSingle',
                'items' => [
                    [
                        'label' => '',
                        'value' => 0,
                    ],
                ],
                'foreign_table' => 'tx_myextension_domain_model_something',
                'foreign_table_where' =>
                    'AND {#tx_myextension_domain_model_something}.{#pid}=###CURRENT_PID###'
                    . ' AND {#tx_myextension_domain_model_something}.{#sys_language_uid} IN (-1,0)',
                'default' => 0,
            ],
        ],
        'l10n_source' => [
            'config' => [
                'type' => 'passthrough',
            ],
        ],
        'l10n_diffsource' => [
            'config' => [
                'type' => 'passthrough',
                'default' => '',
            ],
        ],
        // ...
    ],
    'palettes' => [
        'language' => [
            'showitem' => '
                sys_language_uid,l10n_parent,
            ',
        ],
    ],
    'types' => [
        0 => [
            'showitem' => '
                --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general,
                    [...],
                --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language,
                    --palette--;;language,
            ',
        ],
    ],
];
Copied!

translationSource

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

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.

Example: Keep track of the translation origin in connected mode translations
EXT:my_extension/Configuration/TCA/tx_myextension_domain_model_something.php
<?php

return [
    'ctrl' => [
        'transOrigPointerField' => 'l10n_parent',
        'transOrigDiffSourceField' => 'l10n_diffsource',
        'languageField' => 'sys_language_uid',
        'translationSource' => 'l10n_source',
        // ...
    ],
    'columns' => [
        'sys_language_uid' => [
            'exclude' => true,
            'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
            'config' => [
                'type' => 'language',
            ],
        ],
        'l10n_parent' => [
            'displayCond' => 'FIELD:sys_language_uid:>:0',
            'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
            'config' => [
                'type' => 'select',
                'renderType' => 'selectSingle',
                'items' => [
                    [
                        'label' => '',
                        'value' => 0,
                    ],
                ],
                'foreign_table' => 'tx_myextension_domain_model_something',
                'foreign_table_where' =>
                    'AND {#tx_myextension_domain_model_something}.{#pid}=###CURRENT_PID###'
                    . ' AND {#tx_myextension_domain_model_something}.{#sys_language_uid} IN (-1,0)',
                'default' => 0,
            ],
        ],
        'l10n_source' => [
            'config' => [
                'type' => 'passthrough',
            ],
        ],
        'l10n_diffsource' => [
            'config' => [
                'type' => 'passthrough',
                'default' => '',
            ],
        ],
        // ...
    ],
    'palettes' => [
        'language' => [
            'showitem' => '
                sys_language_uid,l10n_parent,
            ',
        ],
    ],
    'types' => [
        0 => [
            'showitem' => '
                --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general,
                    [...],
                --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language,
                    --palette--;;language,
            ',
        ],
    ],
];
Copied!

tstamp

tstamp
Type
string (field name)
Path
$GLOBALS['TCA'][$table]['ctrl']
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_domain_model_something.php
<?php

return [
    'ctrl' => [
        'tstamp' => 'tstamp',
        'crdate' => 'crdate',
        'origUid' => 't3_origuid',
        // ...
    ],
];
Copied!

type

type
Type
string (field name)
Path
$GLOBALS['TCA'][$table]['ctrl']
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 selector of a content elements

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.

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 --------------------------

The table tx_styleguide_type table from the "examples" extension defines different types. The field used for differentiating the types is the "record_type" field. Hence we have the following in the ['ctrl'] section of the tx_examples_dummy table:

EXT:styleguide/Configuration/TCA/tx_styleguide_type.php
[
    'ctrl' => [
        'title' => 'Form engine - type',
        'label' => 'input_1',
        'tstamp' => 'tstamp',
        'crdate' => 'crdate',
        'delete' => 'deleted',
        'sortby' => 'sorting',
        'iconfile' => 'EXT:styleguide/Resources/Public/Icons/tx_styleguide.svg',
        'versioningWS' => true,
        'origUid' => 't3_origuid',
        'languageField' => 'sys_language_uid',
        'transOrigPointerField' => 'l10n_parent',
        'transOrigDiffSourceField' => 'l10n_diffsource',
        'translationSource' => 'l10n_source',
        'enablecolumns' => [
            'disabled' => 'hidden',
        ],
        'type' => 'record_type',
        'security' => [
            'ignorePageTypeRestriction' => true,
        ],
    ],
]
Copied!

The "record_type" field can take values ranging from 0 to 2. Accordingly we define types for the same values. Each type defines which fields will be displayed in the BE form:

EXT:styleguide/Configuration/TCA/tx_styleguide_type.php
[
    'types' => [
        0 => [
            'showitem' => 'record_type, input_1, text_1',
        ],
        'withChangedFields' => [
            'showitem' => 'record_type, input_1, color_1, text_1',
        ],
        'withColumnsOverrides' => [
            'showitem' => 'record_type, input_1, color_1, text_1',
            'columnsOverrides' => [
                'color_1' => [
                    'label' => 'color_1, readOnly, size=10',
                    'config' => [
                        'readOnly' => true,
                        'size' => 10,
                    ],
                ],
                'text_1' => [
                    'config' => [
                        'renderType' => 't3editor',
                        'format' => 'html',
                    ],
                ],
            ],
        ],
    ],
]
Copied!

See the section about types for more details.

Type in relation to a foreign table's field

The type of the record is fetched from the record specified in field `foreign_table`

The following table tx_styleguide_type_foreign stores its relation to the table tx_styleguide_type in the field foreign_table.

The type of the table tx_styleguide_type_foreign comes from the content of the field tx_styleguide_type:record_type of the related field.

The type is therefore defined via type = 'foreign_table:record_type'.

The control section of the table tx_styleguide_type_foreign looks like this:

EXT:styleguide/Configuration/TCA/tx_styleguide_typeforeign.php
[
    'ctrl' => [
        'title' => 'Form engine - type from foreign table',
        'label' => 'input_1',
        'tstamp' => 'tstamp',
        'crdate' => 'crdate',
        'delete' => 'deleted',
        'sortby' => 'sorting',
        'iconfile' => 'EXT:styleguide/Resources/Public/Icons/tx_styleguide.svg',
        'versioningWS' => true,
        'origUid' => 't3_origuid',
        'languageField' => 'sys_language_uid',
        'transOrigPointerField' => 'l10n_parent',
        'transOrigDiffSourceField' => 'l10n_diffsource',
        'translationSource' => 'l10n_source',
        'enablecolumns' => [
            'disabled' => 'hidden',
        ],
        'type' => 'foreign_table:record_type',
        'security' => [
            'ignorePageTypeRestriction' => true,
        ],
    ],
]
Copied!

The field foreign_table in the same table is a normal singleSelect field. It can be any kind of 1 - 1 or 1 - n relation.

EXT:styleguide/Configuration/TCA/tx_styleguide_typeforeign.php
[
    'columns' => [
        'foreign_table' => [
            'label' => 'type from foreign table',
            'config' => [
                'type' => 'select',
                'renderType' => 'selectSingle',
                'foreign_table' => 'tx_styleguide_type',
                'minitems' => 1,
                'maxitems' => 1,
                'size' => 1,
            ],
        ],
    ],
]
Copied!

typeicon_classes

typeicon_classes
Type
array
Path
$GLOBALS['TCA'][$table]['ctrl']
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 List module. For using and configuring typeicon_classes for custom page types, please see Create a new Page Type.

Example from the tt_content table:
'typeicon_classes' => [
    'default' => 'mimetypes-x-content-text',
    'header' => 'mimetypes-x-content-header',
    ...
],
Copied!

typeicon_column

typeicon_column
Type
string (field name)
Path
$GLOBALS['TCA'][$table]['ctrl']
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

useColumnsForDefaultValues
Type
string (list of field names)
Path
$GLOBALS['TCA'][$table]['ctrl']
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 from "pages" table
'ctrl' => [
    'useColumnsForDefaultValues' => 'doktype,fe_group,hidden',
    // ...
],
Copied!

versioningWS

versioningWS
Type
boolean
Path
$GLOBALS['TCA'][$table]['ctrl']
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

versioningWS_alwaysAllowLiveEdit
Type
boolean
Path
$GLOBALS['TCA'][$table]['ctrl']
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.