Using FlexForms 

Basically the configuration of a FlexForm field is all about pointing to a data structure which contains the form rendering information.

For general information about the backbone of a Data Structure, please refer to the "<T3DataStructure>" chapter in the Core API manual.

Using FlexForms to configure plugins 

FlexForms are commonly used in the tt_content table to register plugins.

Deprecated since version 14.0

Using ExtensionManagementUtility::addPiFlexFormValue() has been deprecated, use the 7th parameter of ExtensionUtility::registerPlugin() instead.

New in version 14.0

FlexForm definitions can be passed as the 7th parameter to ExtensionUtility::registerPlugin() when registering Extbase.

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

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

defined('TYPO3') or die();

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

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

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

Configuring a table with a FlexForm 

Changed in version 14.0 Breaking: #107047 - Remove pointer field functionality of TCA flex

The changelog entry describes the migration.

Use configuration option ds to either pass a file reference to the XML file containing the FlexForm or a string containing the FlexForm's XML. The live stream player of a conference has its two settings as a string:

EXT:my_extension/Configuration/TCA/Overrides/122-tx_myextension_conference-livestream_player.php
<?php

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

ExtensionManagementUtility::addTCAcolumns('tx_myextension_conference', [
  'livestream_player' => [
    'label' => 'my_extension.db:conference.livestream_player',
    'displayCond' => 'FIELD:event_format:IN:online,hybrid',
    'config' => [
      'type' => 'flex',
      // Two settings of the player do not need a file of their own
      'ds' => '
        <T3DataStructure>
          <ROOT>
            <type>array</type>
            <el>
              <autoplay>
                <label>my_extension.db:conference.livestream_player.autoplay</label>
                <config>
                  <type>check</type>
                  <renderType>checkboxToggle</renderType>
                </config>
              </autoplay>
              <muted>
                <label>my_extension.db:conference.livestream_player.muted</label>
                <config>
                  <type>check</type>
                  <renderType>checkboxToggle</renderType>
                </config>
              </muted>
            </el>
          </ROOT>
        </T3DataStructure>
      ',
      // The two toggles hold no text to search for
      'searchable' => false,
      // Translations play the stream like the default language, unless the
      // editors change the settings of a translation
      'behaviour' => [
        'allowLanguageSynchronization' => true,
      ],
    ],
  ],
]);
ExtensionManagementUtility::addToAllTCAtypes(
  'tx_myextension_conference',
  'livestream_player',
  '',
  'after:livestream_password',
);
Copied!

When a record with this field is edited, the backend parses the data structure and shows the form that it defines.

Individual FlexForms by type 

Changed in version 14.0 Breaking: #107047 - Remove pointer field functionality of TCA flex

The changelog entry describes the migration.

If the table has $GLOBALS['TCA'][$table]['ctrl']['type'] set, you can use columnsOverrides to set different FlexForms by type.

The room setup of a talk uses the FlexForm file RoomSetup.xml for all record types. A workshop overrides it with WorkshopRoomSetup.xml:

EXT:my_extension/Configuration/TCA/Overrides/296-tx_myextension_talk-room_setup.php
<?php

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

ExtensionManagementUtility::addTCAcolumns('tx_myextension_talk', [
  'room_setup' => [
    'label' => 'my_extension.db:talk.room_setup',
    'config' => [
      'type' => 'flex',
      // Used by all record types that do not override it
      'ds' => 'FILE:EXT:my_extension/Configuration/FlexForms/RoomSetup.xml',
    ],
  ],
]);
// The participants of a workshop sit at tables in groups and need power
// for their laptops
$GLOBALS['TCA']['tx_myextension_talk']['types']['workshop']['columnsOverrides']['room_setup']['config']['ds'] = 'FILE:EXT:my_extension/Configuration/FlexForms/WorkshopRoomSetup.xml';
ExtensionManagementUtility::addToAllTCAtypes(
  'tx_myextension_talk',
  'room_setup',
  '',
  'after:room',
);
Copied!

The talks of the types talk and keynote show the seating and the lectern:

EXT:my_extension/Configuration/FlexForms/RoomSetup.xml
<T3DataStructure>
  <ROOT>
    <type>array</type>
    <el>
      <seating>
        <label>my_extension.db:talk.room_setup.seating</label>
        <config>
          <type>select</type>
          <renderType>selectSingle</renderType>
          <items>
            <numIndex index="0">
              <label>my_extension.db:talk.room_setup.seating.theatre</label>
              <value>theatre</value>
            </numIndex>
            <numIndex index="1">
              <label>my_extension.db:talk.room_setup.seating.classroom</label>
              <value>classroom</value>
            </numIndex>
          </items>
        </config>
      </seating>
      <lectern>
        <label>my_extension.db:talk.room_setup.lectern</label>
        <config>
          <type>check</type>
          <renderType>checkboxToggle</renderType>
        </config>
      </lectern>
    </el>
  </ROOT>
</T3DataStructure>
Copied!

A workshop shows the size of the groups and the power outlets instead:

EXT:my_extension/Configuration/FlexForms/WorkshopRoomSetup.xml
<T3DataStructure>
  <ROOT>
    <type>array</type>
    <el>
      <group_size>
        <label>my_extension.db:talk.room_setup.group_size</label>
        <config>
          <type>number</type>
          <range>
            <lower>1</lower>
            <upper>10</upper>
          </range>
          <default>4</default>
        </config>
      </group_size>
      <power_outlets>
        <label>my_extension.db:talk.room_setup.power_outlets</label>
        <config>
          <type>check</type>
          <renderType>checkboxToggle</renderType>
          <default>1</default>
        </config>
      </power_outlets>
    </el>
  </ROOT>
</T3DataStructure>
Copied!