Group fields 

New in version 13.0

The group element ( type' => 'group' ) in TYPO3 makes it possible to create references from a record of one table to many records from multiple tables in the system. The foreign tables can be the table itself (thus a self-reference) or any other table. This is especially useful (compared to the "select" type) when records are scattered over the page tree and require the Element Browser to select records for adding them to the group field.

For database relations however, the group field is the right and powerful choice, especially if dealing with lots of re-usable child records, and if type='inline' is not suitable.

This type is very flexible in its display options with all its different fieldControl and fieldWizard options. A lot of them are available by default, however they must be enabled: 'disabled' => 'false'

Most common usage is to model database relations (n:1 or n:m). The property allowed is required, to define allowed relation tables.

The group field uses either the CSV format to store uids of related records or an intermediate mm table (in this case MM property is required).

You can read more on how data is structured in the stored data values chapter.

The according database field is generated automatically.

Table of contents:

Properties of the TCA column type group 

Name Type Scope
string (list) Display / Proc.
boolean Proc.
integer Display
string Display / Proc.
string (list of tables) Proc.
array Display
array Display
string
array Display
string
array Display
string
array Display
string
array Display
string
array Display
array Display
array Display / Proc.
boolean Display
boolean Display
boolean Display
boolean Proc.
integer > 0 Display / Proc.
integer > 0 Display
string (table name) Proc.
array Display / Proc.
string (field name) Proc.
array Proc.
string (SQL WHERE) Proc.
boolean Display / Proc.
boolean Proc.
boolean Display
string Proc.
integer Display
array Display
allowed
Type
string (list)
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['allowed']
Scope
Display / Proc.

A comma list of tables from $GLOBALS['TCA'] , for example "pages,be_users".

Example: Group relation to pages and content elements
The related pages and content of a conference

The related pages and content of a conference

EXT:my_extension/Configuration/TCA/Overrides/157-tx_myextension_conference-related_content.php
<?php

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

ExtensionManagementUtility::addTCAcolumns('tx_myextension_conference', [
  'related_content' => [
    'label' => 'my_extension.db:conference.related_content',
    'config' => [
      'type' => 'group',
      'allowed' => 'pages,tt_content',
      'elementBrowserEntryPoints' => [
        '_default' => '###SITEROOT###',
      ],
      'suggestOptions' => [
        'default' => [
          'searchWholePhrase' => true,
        ],
        // Only standard pages
        'pages' => [
          'searchCondition' => 'doktype = 1',
        ],
        'tt_content' => [
          'additionalSearchFields' => 'bodytext',
        ],
      ],
    ],
  ],
]);
ExtensionManagementUtility::addToAllTCAtypes(
  'tx_myextension_conference',
  'related_content',
  '',
  'before:--div--;core.form.tabs:categories',
);
Copied!
behaviour
allowLanguageSynchronization
Type
boolean
Default
false
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['behaviour']['allowLanguageSynchronization']
Scope
Proc.

Allows an editor to select in a localized record whether the value is copied over from default or source language record, or if the field has an own value in the localization. If set to true and if the table supports localization and if a localized record is edited, this setting enables FieldWizard LocalizationStateSelector: Two or three radio buttons shown below the field input. The state of this is stored in a json encoded array in the database table called l10n_state. It tells the DataHandler which fields of the localization records should be kept in sync if the underlying default or source record changes.

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

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

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

The maximum size (height) of the select field.

The size of the select field will be automatically adjusted based on the number of selected items. The select field will never be smaller than the specified size and never larger than the value of autoSizeMax.

default
Type
string
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['default']
Scope
Display / Proc.

Default value set if a new record is created. If empty, the first element in the items array is selected.

dontRemapTablesOnCopy
Type
string (list of tables)
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['dontRemapTablesOnCopy']
Scope
Proc.
Types
Description

A list of tables which should not be remapped to the new element uids if the field holds elements that are copied in the session.

elementBrowserEntryPoints
Type
array
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['elementBrowserEntryPoints']
Scope
Display

By default, the last selected page is used when opening the element browser. Setting this configuration value changes this behaviour.

This configuration value is a PHP array , containing table => id pairs. When opening the element browser for a specific table (buttons below the group field), the defined page is then always selected by default. There is also the special _default key, used for the general element browser button (on the right side of the group field), which is not dedicated to a specific table.

This configuration value also supports the known markers ###SITEROOT###, ###CURRENT_PID### and ###PAGE_TSCONFIG_<key>###.

Each table => id pair can also be overridden via page TSconfig.

Example: Open the element browser on the folder of the talk for speakers
EXT:my_extension/Configuration/TCA/Overrides/210-tx_myextension_talk-speaker.php
<?php

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

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

This could then be overridden via page TSconfig:

TCEFORM.tx_myextension_talk.speaker.config.elementBrowserEntryPoints.tx_myextension_speaker = 321
Copied!

Since only one table is allowed, the defined entry point is also automatically used for the general element browser button.

Example: Open the element browser on the root page of the site for pages and content elements

In case the group field allows more than one table, the _default key has to be set:

EXT:my_extension/Configuration/TCA/Overrides/157-tx_myextension_conference-related_content.php
<?php

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

ExtensionManagementUtility::addTCAcolumns('tx_myextension_conference', [
  'related_content' => [
    'label' => 'my_extension.db:conference.related_content',
    'config' => [
      'type' => 'group',
      'allowed' => 'pages,tt_content',
      'elementBrowserEntryPoints' => [
        '_default' => '###SITEROOT###',
      ],
      'suggestOptions' => [
        'default' => [
          'searchWholePhrase' => true,
        ],
        // Only standard pages
        'pages' => [
          'searchCondition' => 'doktype = 1',
        ],
        'tt_content' => [
          'additionalSearchFields' => 'bodytext',
        ],
      ],
    ],
  ],
]);
ExtensionManagementUtility::addToAllTCAtypes(
  'tx_myextension_conference',
  'related_content',
  '',
  'before:--div--;core.form.tabs:categories',
);
Copied!

The _default key can also be overridden via page TSconfig:

TCEFORM.tx_myextension_conference.related_content.config.elementBrowserEntryPoints._default = 122
Copied!
fieldControl

The field of type group can enable all common field control options. Furthermore the following are available:

addRecord
Type
array
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['fieldControl']['addRecord']
Scope
Display
Types
group

Control button to directly add a related record. Leaves the current view and opens a new form to add a new record. On 'Save and close', the record is directly selected as referenced element in the type='group' field. If multiple tables are allowed, the first table from the allowed list is selected, if no specific table option is given.

Example: Group field with add popup enabled
The speaker of a talk with field controls

The speaker of a talk with field controls

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

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

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

true

Default
addRecord
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['fieldControl']['addRecord']['renderType']

Use a render type from core or your own. Custom render types can be registered with the NodeFactory.

editPopup
Type
array
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['fieldControl']['editPopup']
Scope
Display
Types
group

The edit popup field control shows a pencil icon to edit an element directly in a popup window. When a record is selected and the edit button is clicked, that record opens in a new window for modification.

For details see editPopup.

Example: Group field with edit popup enabled
The speaker of a talk with field controls

The speaker of a talk with field controls

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

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

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

true

Default
editPopup
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['fieldControl']['editPopup']['renderType']

Use a render type from core or your own. Custom render types can be registered with the NodeFactory.

listModule
Type
array
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['fieldControl']['listModule']
Scope
Display
Types
group

The list module control button opens the Content > Records module for only one table and allows the user to manipulate stuff there.

For details see listModule.

Example: Group field with the list module enabled
The speaker of a talk with field controls

The speaker of a talk with field controls

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

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

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

true

Default
listModule
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['fieldControl']['listModule']['renderType']

Use a render type from core or your own. Custom render types can be registered with the NodeFactory.

elementBrowser
Type
array
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['fieldControl']['elementBrowser']
Scope
Display
Types
group

The element browser field control used in type='group' renders a button to open an element browser. It is enabled by default if rendering a group element.

renderType
Type
string
Required

true

Default
elementBrowser
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['fieldControl']['elementBrowser']['renderType']

Use a render type from the Core or an Extension. Custom render types can be registered with the NodeFactory.

insertClipboard
Type
array
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['fieldControl']['insertClipboard']
Scope
Display
Types
group
renderType
Type
string
Required

true

Default
insertClipboard
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['fieldControl']['insertClipboard']['renderType']

Use a render type from core or your own. Custom render types can be registered with the NodeFactory.

The clipboard control adds a control button for type='group' to paste records from a users clipboard into the selection. It is enabled by default for type='group' and shown below the element browser if the order has not been changed using the before and after keywords. It can be turned off by setting disabled to true, just like any other fieldControl.

Example: Group field with element browser enabled

The element browser is enabled by default. The speaker of a talk shows it as the folder button:

The speaker of a talk with the element browser button

The speaker of a talk with the element browser button

Example: Group field with element browser disabled

The element browser control can be disabled by setting disabled = true . The element browser does not list the records of a table with hideTable, such as the talks. A related talk is found with the search field instead:

The related talks of a talk without the element browser button

The related talks of a talk without the element browser button

EXT:my_extension/Configuration/TCA/Overrides/275-tx_myextension_talk-related_talks.php
<?php

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

ExtensionManagementUtility::addTCAcolumns('tx_myextension_talk', [
  'related_talks' => [
    'label' => 'my_extension.db:talk.related_talks',
    'config' => [
      'type' => 'group',
      'allowed' => 'tx_myextension_talk',
      'MM' => 'tx_myextension_talk_related_mm',
      'fieldControl' => [
        // The element browser does not list talks, because their table is
        // hidden. Editors find a talk with the search field instead.
        'elementBrowser' => [
          'disabled' => true,
        ],
      ],
    ],
  ],
]);
ExtensionManagementUtility::addToAllTCAtypes(
  'tx_myextension_talk',
  'related_talks',
  '',
  'before:--div--;core.form.tabs:access',
);
Copied!
fieldInformation

For details see fieldInformation.

fieldWizard

For general fieldWizard documentation see here.

recordsOverview
Type
array
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['fieldWizard']['recordsOverview']
Scope
Display

Render an overview of the selected records with correct icon and click menu and title. Allows to perform actions on the selected records directly. Links the record title to a direct editing form.

tableList
Type
array
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['fieldWizard']['tableList']
Scope
Display

Render a list of allowed tables and link to element browser. This field wizard is enabled by default. This wizard lets you select records from a popup.

filter
Type
array
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['filter']
Scope
Display / Proc.

Define filters for item values. Doesn't work in combination with a wizard.

This is useful when only foreign records matching certain criteria should be allowed to be used as values in the group field. The values are filtered in the Element Browser as well as during processing in DataHandler. Filter userFuncs should have two input arguments ($parameters and $parentObject). The first argument ($parameters) is an array with the parameters of the filter as configured in the TCA, but with the additional parameter "values", which contains the array of values which should be filtered by the userFunc. The function must return the filtered array of values.

filter is a list of filters. Each filter has a userFunc and optional parameters. The filters are applied one after the other.

Example: Only gold sponsors as main sponsor

The main sponsor of a conference is one of the sponsors of the tier "gold". The filter checks the tier of each selected sponsor:

EXT:my_extension/Configuration/TCA/Overrides/156-tx_myextension_conference-main_sponsor.php
<?php

use MyVendor\MyExtension\Backend\Filter\SponsorTierFilter;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

ExtensionManagementUtility::addTCAcolumns('tx_myextension_conference', [
  'main_sponsor' => [
    'label' => 'my_extension.db:conference.main_sponsor',
    'config' => [
      'type' => 'group',
      'allowed' => 'tx_myextension_sponsor',
      'relationship' => 'manyToOne',
      // The element browser lists the few sponsors
      'hideSuggest' => true,
      'filter' => [
        [
          'userFunc' => SponsorTierFilter::class . '->filter',
          'parameters' => [
            'tier' => 'gold',
          ],
        ],
      ],
    ],
  ],
]);
ExtensionManagementUtility::addToAllTCAtypes(
  'tx_myextension_conference',
  'main_sponsor',
  '',
  'before:--div--;core.form.tabs:categories',
);
Copied!

The filter receives the selected values as <table>_<uid> strings in $parameters['values'] and returns the ones to keep:

EXT:my_extension/Classes/Backend/Filter/SponsorTierFilter.php
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\Backend\Filter;

use TYPO3\CMS\Backend\Utility\BackendUtility;

/**
 * Keeps the sponsors of the tier given in the parameter "tier"
 */
final class SponsorTierFilter
{
  /**
   * @param array{values: list<string>, tier?: string} $parameters
   * @return list<string>
   */
  public function filter(array $parameters, object $parentObject): array
  {
    $tier = $parameters['tier'] ?? 'gold';
    return array_values(array_filter(
      $parameters['values'],
      static function (string $value) use ($tier): bool {
        // A value is the table name and the uid: tx_myextension_sponsor_42
        $uid = (int)substr($value, strrpos($value, '_') + 1);
        $sponsor = BackendUtility::getRecord('tx_myextension_sponsor', $uid);
        return ($sponsor['tier'] ?? '') === $tier;
      },
    ));
  }
}
Copied!
hideDeleteIcon
Type
boolean
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['hideDeleteIcon']
Scope
Display

Removes the delete icon next to the selector box.

hideMoveIcons
Type
boolean
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['hideMoveIcons']
Scope
Display

Removes the move icons next to the selector box.

hideSuggest
Type
boolean
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['hideSuggest']
Scope
Display

The "suggest wizard" is added by default to all database relation group fields. After a couple of characters have been typed into this field, an ajax based search starts and shows a list of records matching the search word.

The syntax for the search is: "multiple words" something, so you can enclose words you want to find next to each other in double quotes.

A set of options is available to configure search details.

Setting this property to true disables the suggest wizard.

Example: Suggest wizard is hidden

There are only a few sponsors, so the main sponsor of a conference is selected in the element browser:

The main sponsor of a conference without a search field

The main sponsor of a conference without a search field

EXT:my_extension/Configuration/TCA/Overrides/156-tx_myextension_conference-main_sponsor.php
<?php

use MyVendor\MyExtension\Backend\Filter\SponsorTierFilter;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

ExtensionManagementUtility::addTCAcolumns('tx_myextension_conference', [
  'main_sponsor' => [
    'label' => 'my_extension.db:conference.main_sponsor',
    'config' => [
      'type' => 'group',
      'allowed' => 'tx_myextension_sponsor',
      'relationship' => 'manyToOne',
      // The element browser lists the few sponsors
      'hideSuggest' => true,
      'filter' => [
        [
          'userFunc' => SponsorTierFilter::class . '->filter',
          'parameters' => [
            'tier' => 'gold',
          ],
        ],
      ],
    ],
  ],
]);
ExtensionManagementUtility::addToAllTCAtypes(
  'tx_myextension_conference',
  'main_sponsor',
  '',
  'before:--div--;core.form.tabs:categories',
);
Copied!
Example: Suggest wizard is shown

The speaker of a talk has no hideSuggest. The search field above the field finds speakers by their name:

The speaker of a talk with a search field

The speaker of a talk with a search field

localizeReferencesAtParentLocalization
Type
boolean
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['localizeReferencesAtParentLocalization']
Scope
Proc.

Defines whether referenced records should be localized when the current record gets localized. This only applies if references are not stored using MM tables.

maxitems
Type
integer > 0
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['maxitems']
Scope
Display / Proc.

Maximum number of child items. Defaults to a high value. JavaScript record validation prevents the record from being saved if the limit is not satisfied.

minitems
Type
integer > 0
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['minitems']
Scope
Display

Minimum number of child items. Defaults to 0. JavaScript record validation prevents the record from being saved if the limit is not satisfied.

MM
Type
string (table name)
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['MM']
Scope
Proc.

This value contains the name of the table in which to store a MM relation. It is used together with allowed (group). If you use Extbase, foreign_table has to contain the same table name additionally.

The database field with a MM property only stores the number of records in the relation.

Please have a look into the additional information in the MM common property description.

The table name used in the field MM should be unique. It must be a valid SQL table name. It is best practise to use the name of both referenced tables and of the field in which the reference is saved on local side. See also naming conventions for mm tables. This way uniqueness can be ensured and it is possible to find the field where the table is used quickly.

Example: Related talks in an intermediate table
EXT:my_extension/Configuration/TCA/Overrides/275-tx_myextension_talk-related_talks.php
<?php

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

ExtensionManagementUtility::addTCAcolumns('tx_myextension_talk', [
  'related_talks' => [
    'label' => 'my_extension.db:talk.related_talks',
    'config' => [
      'type' => 'group',
      'allowed' => 'tx_myextension_talk',
      'MM' => 'tx_myextension_talk_related_mm',
      'fieldControl' => [
        // The element browser does not list talks, because their table is
        // hidden. Editors find a talk with the search field instead.
        'elementBrowser' => [
          'disabled' => true,
        ],
      ],
    ],
  ],
]);
ExtensionManagementUtility::addToAllTCAtypes(
  'tx_myextension_talk',
  'related_talks',
  '',
  'before:--div--;core.form.tabs:access',
);
Copied!
MM_match_fields
Type
array
Scope
Display / Proc.

Array of field => value pairs to both insert and match against when writing/reading MM relations.

MM_opposite_field
Type
string (field name)
Scope
Proc.

If you want to make a MM relation editable from the foreign side (bidirectional) of the relation as well, you need to set MM_opposite_field on the foreign side to the field name on the local side.

For example, if the field companies.employees is your local side and you want to make the same relation editable from the foreign side of the relation in a field called persons.employers, you would need to set the MM_opposite_field value of the TCA configuration of the persons.employers field to the string "employees".

MM_oppositeUsage
Type
array
Scope
Proc.

In a MM bidirectional relation using group match fields the opposite side needs to know about the match fields for certain operations (for example, when a copy is created in a workspace) so that relations are carried over with the correct information.

MM_oppositeUsage is an array which references which fields contain the references to the opposite side, so that they can be queried for match field configuration.

MM_table_where
Type
string (SQL WHERE)
Scope
Proc.

Additional where clause used when reading MM relations.

Example:

{#uid_local} = ###THIS_UID###
Copied!

The above example uses the special field quoting syntax {#...} around identifiers to be as DBAL-compatible as possible.

multiple
Type
boolean
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['multiple']
Scope
Display / Proc.

Allows the same item more than once in a list.

If used with bidirectional MM relations it must be set for both the native and foreign field configuration.

prepend_tname
Type
boolean
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['prepend_tname']
Scope
Proc.

Will prepend the table name to the stored relations (so instead of storing "23" you will store e.g. "tt_content_23"). This is automatically turned on if multiple different tables are allowed for one relation.

readOnly
Type
boolean
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['readOnly']
Scope
Display

Renders the field in a way that the user can see the value but cannot edit it.

relationship
Type
string
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['relationship']
Scope
Proc.
Added
13.3

Defines whether the field holds one related record or several. This decides which value a Record object provides for this field, for example in a Fluid template.

oneToOne, manyToOne
The field provides a single Record object, or null if no record is related. maxitems is set to 1 automatically, overriding any other value.
oneToMany
The field provides a LazyRecordCollection of Record objects.

If relationship is not set, the field also provides a collection. So does a field with MM, whatever relationship says. Any other value, including manyToMany, throws an exception unless MM is set.

maxitems does not change the result the other way round: a field without relationship still provides a collection, even if maxitems is 1.

In the following example, each talk has one speaker:

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

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

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

The speaker can then be output without a loop:

EXT:my_extension/Resources/Private/Templates/Talk.html
Speaker: {talk.speaker.name}
Copied!
size
Type
integer
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['size']
Scope
Display

The minimum size (height) of the select field.

The size of the select field will be automatically adjusted based on the number of selected items. The select field will never be smaller than the specified size and never larger than the value of autoSizeMax.

suggestOptions
Type
array
TCA path
$GLOBALS['TCA'][$table]['columns'][$field]['config']['suggestOptions']
Scope
Display

Optional, additional suggest options used if the suggest wizard is not hidden. The suggest wizard options can also be overriden on a page TSconfig level.

Suggestions can be configured differently for each table. Settings in "default" are applied to all tables. In the example below, there is a special setting for the "pages" table to search only standard pages.

EXT:my_extension/Configuration/TCA/Overrides/157-tx_myextension_conference-related_content.php
<?php

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

ExtensionManagementUtility::addTCAcolumns('tx_myextension_conference', [
  'related_content' => [
    'label' => 'my_extension.db:conference.related_content',
    'config' => [
      'type' => 'group',
      'allowed' => 'pages,tt_content',
      'elementBrowserEntryPoints' => [
        '_default' => '###SITEROOT###',
      ],
      'suggestOptions' => [
        'default' => [
          'searchWholePhrase' => true,
        ],
        // Only standard pages
        'pages' => [
          'searchCondition' => 'doktype = 1',
        ],
        'tt_content' => [
          'additionalSearchFields' => 'bodytext',
        ],
      ],
    ],
  ],
]);
ExtensionManagementUtility::addToAllTCAtypes(
  'tx_myextension_conference',
  'related_content',
  '',
  'before:--div--;core.form.tabs:categories',
);
Copied!
additionalSearchFields (string)

Comma-separated list of fields the suggest wizard should also search in. By default the wizard looks only in the fields listed in the label and label_alt of TCA ctrl properties.

Example

EXT:my_extension/Configuration/TCA/Overrides/157-tx_myextension_conference-related_content.php
<?php

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

ExtensionManagementUtility::addTCAcolumns('tx_myextension_conference', [
  'related_content' => [
    'label' => 'my_extension.db:conference.related_content',
    'config' => [
      'type' => 'group',
      'allowed' => 'pages,tt_content',
      'elementBrowserEntryPoints' => [
        '_default' => '###SITEROOT###',
      ],
      'suggestOptions' => [
        'default' => [
          'searchWholePhrase' => true,
        ],
        // Only standard pages
        'pages' => [
          'searchCondition' => 'doktype = 1',
        ],
        'tt_content' => [
          'additionalSearchFields' => 'bodytext',
        ],
      ],
    ],
  ],
]);
ExtensionManagementUtility::addToAllTCAtypes(
  'tx_myextension_conference',
  'related_content',
  '',
  'before:--div--;core.form.tabs:categories',
);
Copied!
addWhere (string)

Allows to define an additional where clause for the searchquery. It supplies a marker for ###THIS_UID### which is useful to exclude the current record.

cssClass (string)
Add a CSS class to every list item of the result list.
maxItemsInResultList (integer)
Maximum number of results to display, default is 10.
maxPathTitleLength (integer)
Maximum number of characters to display when a path element is too long.
minimumCharacters (integer)
Minimum number of characters needed to start the search. Works only in "default" configuration array.
orderBy (string)
Allows to add an ORDER BY part to the search query.
pidList (list of values)

Limit the search to certain pages (and their sub pages). When pidList is empty all pages will be included in the search (as long as the be_user is allowed to see them).

The page IDs differ from one installation to the next. An extension therefore does not set them. The site package of the installation can set them in its TCA overrides:

Example

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

defined('TYPO3') or die();

// The suggest wizard of the related content searches only the pages
// "Program" (6) and "News" (7) of this site, and four levels below them
$GLOBALS['TCA']['tx_myextension_conference']['columns']['related_content']['config']['suggestOptions']['default']['pidList'] = '6,7';
$GLOBALS['TCA']['tx_myextension_conference']['columns']['related_content']['config']['suggestOptions']['default']['pidDepth'] = 4;

// The layout of this site shows the impressions of a conference in 16:9
// only, so the free ratio of the extension is not available
$GLOBALS['TCA']['tx_myextension_conference']['columns']['impressions']['config']
  ['overrideChildTca']['columns']['crop']['config']['cropVariants']['desktop']
  ['allowedAspectRatios']['NaN']['disabled'] = true;
Copied!
pidDepth (integer)
Expand pidList by this number of levels. Has an effect only if pidList has a value. See the example of pidList.
receiverClass (string)
PHP class alternative receiver class, default is \TYPO3\CMS\Backend\Form\Wizard\SuggestWizardDefaultReceiver . Can be used to implement an own search strategy.
renderFunc (string)
User function to manipulate the displayed records in the results.
searchCondition (string)

Additional WHERE clause (not prepended with AND ).

Example

EXT:my_extension/Configuration/TCA/Overrides/157-tx_myextension_conference-related_content.php
<?php

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

ExtensionManagementUtility::addTCAcolumns('tx_myextension_conference', [
  'related_content' => [
    'label' => 'my_extension.db:conference.related_content',
    'config' => [
      'type' => 'group',
      'allowed' => 'pages,tt_content',
      'elementBrowserEntryPoints' => [
        '_default' => '###SITEROOT###',
      ],
      'suggestOptions' => [
        'default' => [
          'searchWholePhrase' => true,
        ],
        // Only standard pages
        'pages' => [
          'searchCondition' => 'doktype = 1',
        ],
        'tt_content' => [
          'additionalSearchFields' => 'bodytext',
        ],
      ],
    ],
  ],
]);
ExtensionManagementUtility::addToAllTCAtypes(
  'tx_myextension_conference',
  'related_content',
  '',
  'before:--div--;core.form.tabs:categories',
);
Copied!
searchWholePhrase (boolean)

Whether to do a LIKE=%mystring% (searchWholePhrase = 1) or a LIKE=mystring% (to do a real find as you type), default is 0.

Example

EXT:my_extension/Configuration/TCA/Overrides/157-tx_myextension_conference-related_content.php
<?php

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

ExtensionManagementUtility::addTCAcolumns('tx_myextension_conference', [
  'related_content' => [
    'label' => 'my_extension.db:conference.related_content',
    'config' => [
      'type' => 'group',
      'allowed' => 'pages,tt_content',
      'elementBrowserEntryPoints' => [
        '_default' => '###SITEROOT###',
      ],
      'suggestOptions' => [
        'default' => [
          'searchWholePhrase' => true,
        ],
        // Only standard pages
        'pages' => [
          'searchCondition' => 'doktype = 1',
        ],
        'tt_content' => [
          'additionalSearchFields' => 'bodytext',
        ],
      ],
    ],
  ],
]);
ExtensionManagementUtility::addToAllTCAtypes(
  'tx_myextension_conference',
  'related_content',
  '',
  'before:--div--;core.form.tabs:categories',
);
Copied!
Example: Only show pages with doktype=1 in the suggest options
The related pages and content of a conference

The related pages and content of a conference

EXT:my_extension/Configuration/TCA/Overrides/157-tx_myextension_conference-related_content.php
<?php

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

ExtensionManagementUtility::addTCAcolumns('tx_myextension_conference', [
  'related_content' => [
    'label' => 'my_extension.db:conference.related_content',
    'config' => [
      'type' => 'group',
      'allowed' => 'pages,tt_content',
      'elementBrowserEntryPoints' => [
        '_default' => '###SITEROOT###',
      ],
      'suggestOptions' => [
        'default' => [
          'searchWholePhrase' => true,
        ],
        // Only standard pages
        'pages' => [
          'searchCondition' => 'doktype = 1',
        ],
        'tt_content' => [
          'additionalSearchFields' => 'bodytext',
        ],
      ],
    ],
  ],
]);
ExtensionManagementUtility::addToAllTCAtypes(
  'tx_myextension_conference',
  'related_content',
  '',
  'before:--div--;core.form.tabs:categories',
);
Copied!