---
title: "TCA, DataHandler and FormEngine"
manual: "Frontend Localization Guide"
version: "14.3"
permalink: "https://docs.typo3.org/permalink/t3translate:core-support-tca@14.3"
source: "CoreSupport/Tca/Index.rst"
rendered: "2026-09-24T14:54:21+00:00"
---

# TCA, DataHandler and FormEngine {#core-support-tca}

The support for localization in the Core of TYPO3 is based around a scheme where
a record in the default language (id "0") can have other records pointing to it,
offering a translation of its content. This implies some requirements for the
structure of any database tables which we want to be available for translation:

1.  A field holding the reference to the language defined in the
    [site configuration](https://docs.typo3.org/m/typo3/reference-coreapi/14.3/en-us/ApiOverview/SiteHandling/Index.html#sitehandling) must be defined.
1.  A field holding the reference to the default language record must be
    defined.
1.  Optionally, a field holding the reference to the record it was translated
    from can be defined.

These fields are declared in the ["\[ctrl\]" section](https://docs.typo3.org/m/typo3/reference-tca/14.3/en-us/Ctrl/Index.html#ctrl)
of the TCA for the table.

****Content****

-   [[languageField]](https://docs.typo3.org/permalink/t3translate:languagefield@14.3)
-   [[transOrigPointerField]](https://docs.typo3.org/permalink/t3translate:transorigpointerfield@14.3)
-   [[transOrigDiffSourceField]](https://docs.typo3.org/permalink/t3translate:transorigdiffsourcefield@14.3)
-   [[translationSource]](https://docs.typo3.org/permalink/t3translate:translationsource@14.3)
-   [DataHandler commands for localization](https://docs.typo3.org/permalink/t3translate:datahandler-commands-for-localization@14.3)

## \[languageField\] {#core-support-tca-languagefield}

The first field is defined by the
"[languageField](https://docs.typo3.org/m/typo3/reference-tca/14.3/en-us/Ctrl/Index.html#ctrl-reference-languagefield)" property
and contains a reference to the language the record is in.

Here is how such a field is configured (example from the `tt_content`
table):

**EXT:frontend/Configuration/TCA/tt_content.php**

```php
'sys_language_uid' => [
    'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
    'config' => [
        'type' => 'language'
    ]
]
```

The entry for the **\[All\]** language gets automatically added with the
TCA type [language](https://docs.typo3.org/m/typo3/reference-tca/14.3/en-us/ColumnsConfig/Type/Language/Index.html#columns-language).

> [!NOTE]
> This field is traditionally named `sys_language_uid`, but any name can
> be used since it is registered with the `languageField` property in the
> ctrl section.

<!-- TODO: no Markdown rendering for "deprecated" -->

This field can only be used with the TCA type "language". All other field
types will be automatically migrated on-the-fly possibly losing configurations.
See Migration to the language type.

## \[transOrigPointerField\] {#core-support-tca-transorigpointerfield}

The first field is defined by the
"[transOrigPointerField](https://docs.typo3.org/m/typo3/reference-tca/14.3/en-us/Ctrl/Index.html#ctrl-reference-transorigpointerfield)"
property and contains a reference to the record in the default language.

Here is how such a field is configured (example from the `tt_content`
table):

**EXT:frontend/Configuration/TCA/tt_content.php**

```php
'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' => [
            ['', 0]
        ],
        'foreign_table' => 'tt_content',
        'foreign_table_where' => 'AND {#tt_content}.{#pid}=###CURRENT_PID### AND {#tt_content}.{#sys_language_uid} IN (-1,0)',
        'default' => 0,
    ],
],
```

> [!NOTE]
> This field is traditionally named `l10n_parent`, but any name can be
> used since it is registered with the `transOrigPointerField` property.
>
> The `l18n_parent` name used in table `tt_content` is a historical
> mistake.

Obviously, the table name has to be adapted in properties `foreign_table`
and `foreign_table_where` for each table.

Notice the display condition set on the field, which will check the value of
the `sys_language_uid` and display the `l18n_parent` field only when
it is greater than zero (that means, it is a translation).

Another interesting point is that it will only look for a default language
record in the current pid. This means that a
**default language record and all its translations must be on the same page!**
This principle is also respected by the API function
`TYPO3CMSCoreDomainRepositoryPageRepository::getLanguageOverlay()`
which fetches translations of records for the frontend display.

When the `transOrigPointerField` and `languageField` are defined for a
table you will see references to the content of the default language
record when editing the translation:

![Original content in the Form Engine](../../Images/ManualScreenshots/Record/CoreSupportFormEngine.png)

> [!WARNING]
> The configured `$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']`
> cannot be excluded as this leads to inconsistent data stored in the database.
> This happens when a non-admin user creates a localization while not having
> the permission to edit the `transOrigPointerField`. Remove
> `exclude => true` from TCA, if set.

## \[transOrigDiffSourceField\] {#core-support-tca-transorigdiffsourcefield}

There is one more field which can be used on a translatable table, defined by
the property "[languageField](https://docs.typo3.org/m/typo3/reference-tca/14.3/en-us/Ctrl/Index.html#ctrl-reference-transorigdiffsourcefield)".
It is optional. It points to a blob database field which will store the content
of the default language record as it was when the translation was made. Then
this is used to display any changes that have occurred in the default record
since translation happened. For example, in the `tt_content` table, it may
look like this for the header field:

![Changes in original content](../../Images/ManualScreenshots/Record/CoreSupportFormEngineViewDifference.png)

This allows a translator to spot easily what has changed in order to adjust the
translation accordingly.

## \[translationSource\] {#core-support-tca-translationsource}

The "[translationSource](https://docs.typo3.org/m/typo3/reference-tca/14.3/en-us/Ctrl/Index.html#ctrl-reference-translationSource)" property
defines a name of the field used by translations to point back to the original
record (that means, the record in any language of which they are a translation).
This property is often set to `l10n_source` in Core tables.

This property is similar to
[transOrigPointerField](https://docs.typo3.org/permalink/t3translate:core-support-tca-transorigpointerfield@14.3).
In [connected mode](https://docs.typo3.org/permalink/t3translate:localized-content@14.3), 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`.

## DataHandler commands for localization {#core-support-tca-localization-command}

Localizing a record can be done by the
["localize" command](https://docs.typo3.org/m/typo3/reference-coreapi/14.3/en-us/ApiOverview/DataHandler/Database/Index.html#tce-command-keywords) of the
[DataHandler](https://docs.typo3.org/m/typo3/reference-coreapi/14.3/en-us/ApiOverview/DataHandler/Database/Index.html#datahandler-basics). This is the command that is sent
when you press the translate buttons in **Content > List** or
**Content > Page** for an element.

When this command is issued an ordinary copy is made but the fields
[languageField](https://docs.typo3.org/permalink/t3translate:core-support-tca-languagefield@14.3) and
[transOrigPointerField](https://docs.typo3.org/permalink/t3translate:core-support-tca-transorigpointerfield@14.3) are
updated accordingly.

You can only localize a record which is not already localized and which is in
"default" or "All" language (a record in "All" language is supposed to be
somehow valid for any language, but can still be translated if needed).

It is possible to manually create two or more translations of the
same record but this is considered an error in the system, although
not fatal, yet producing unpredictable results.

### Localization command options per field {#core-support-tca-localization-command-options}

Each field may contain special instructions which will affect the "localize"
command. Most important is the
["l10n_mode" field](https://docs.typo3.org/m/typo3/reference-tca/14.3/en-us/Columns/Index.html#columns-properties-l10n-mode) with which,
for example, a field can be entirely excluded from the translation process.
