Flexforms can be used to store data within an XML structure inside a single DB column.

Flexforms can be used to configure content elements (CE) or plugins, but they are optional so you can create plugins or content elements without using Flexforms.

Most of the configuration below is the same, whether you are adding configuration for a plugin or content element. The main difference is how addPiFlexFormValue() is used.

You may want to configure individual plugins or content elements differently, depending on where they are added. The configuration set via the Flexform mechanism applies to only the content record it has been configured for. The Flexforms configuration for a plugin or CE can be changed by editors in the backend. This gives editors more control over plugin features and what is to be rendered.

Using Flexforms you have all the features of TCA, so it is possible to use input fields, select lists, show options conditionally and more.

Example use cases

The bootstrap_package uses Flexforms to configure rendering options, e.g. a transition interval and transition type (slide, fade) for the carousel content element.


The carousel content element of EXT:bootstrap_package

Another extensions that utilize FlexForms and can be used as example is:

How it works

  1. In the extension, a configuration schema is defined and attached to one or more content elements or plugins.
  2. When the CE or plugin is added to a page, it can be configured as defined by the configuration schema.
  3. The configuration for this content element is automatically saved to tt_content.pi_flexform.
  4. The extension can read current configuration and act according to the configuration.

Steps to perform (Extension developer)

  1. Create configuration schema in T3DataStructure format (XML)

    Example: Configuration/FlexForms/Registration.xml.

    <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
                        <!-- Add settings here ... -->
                        <!-- Example setting: input field with name settings.includeCategories -->
                                    <items type="array">
                                        <numIndex index="0" type="array">
                                            <numIndex index="0">LLL:EXT:example/Resources/Private/Language/Backend.xlf:setting.registration.includeCategories.title</numIndex>
                        <!-- end of settings -->
  2. The configuration schema is attached to one or more plugins

    The vendor name is Myvendor, the extension key is example and the plugin name is Registration.

    In Configuration/TCA/Overrides/tt_content.php add the following:

    // plugin signature: <extension key without underscores> '_' <plugin name in lowercase>
    $pluginSignature = 'example_registration';
    $GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist'][$pluginSignature] = 'pi_flexform';
        // Flexform configuration schema file


    The plugin signature is used in the database field tt_content.list_type as well, when the tt_content record is saved. If you are confused about how to handle underscores and upper / lowercase, check there to see what your plugin signature is.

    New in version 12.0: The method ExtensionUtility::registerPlugin() returns the plugin signature.

    Also look on the page Naming conventions.

    If you are using a content element instead of a plugin, the example will look like this:

    Add in file EXT:your_extension/Configuration/TCA/Overrides/tt_content.php
       // 'list_type' does not apply here
       // Flexform configuration schema file
       // ctype

    Finally, according to “Configuration of the displayed order of fields in FormEngine and their tab alignment.” the field containing the FlexForm still needs to be added to the showitem directive. The following example shows line from the accordion element of the Bootstrap Package.

    Add in file EXT:your_extension/Configuration/TCA/Overrides/tt_content.php
    // Configure element type
    $GLOBALS['TCA']['tt_content']['types']['accordion'] = array_replace_recursive(
          'showitem' => '
  3. Access the settings in your extension:

    The settings can be read using one of the methods described below, e.g. from an Extbase controller action, from a PHP function (without using the Extbase framework), from TypoScript or from within a Fluid template.

More examples

The definition of the data types and parameters used complies to the column types defined by TCA.

The settings must be added within the <el> element in the Flexform configuration schema file.

Select field

                <numIndex index="0">
                    <numIndex index="0">LLL:EXT:example/Resources/Private/Language/Backend.xlf:settings.registration.orderBy.crdate</numIndex>
                    <numIndex index="1">crdate</numIndex>
                <numIndex index="1">
                    <numIndex index="0">LLL:EXT:example/Resources/Private/Language/Backend.xlf:settings.registration.orderBy.title</numIndex>
                    <numIndex index="1">title</numIndex>

See also

Populate a select Field with a PHP Function (itemsProcFunc)

                <!-- empty by default -->

The function user_orderBy populates the select field in BackendItemsProcFunc.php:

class ItemsProcFunc
     * Modifies the select box of orderBy-options.
     * @param array &$config configuration array
    public function user_orderBy(array &$config)
        // simple and stupid example
        // change this to dynamically populate the list!
        $config['items'] = [
            // label, value
            ['Timestamp', 'timestamp'],
            ['Title', 'title']

    // ...

How this looks when configuring the plugin:


See also

Display fields conditionally (displayCond)

Some settings may only make sense, depending on other settings. For example in one setting you define a sorting order (by date, title etc.) and all sort orders except “title” have additional settings. These should only be visible, if sort order “title” was not selected.

You can define conditions using displayCond. This dynamically defines whether a setting should be displayed when the plugin is configured. The conditions may for example depend on one or more other settings in the Flexform, on database fields of current record or be defined by a user function.

<!-- Hide field if value of neighbour field "settings.orderBy" on same sheet is not "title" -->

Again, the syntax and available fields and comparison operators is documented in the TCA reference:

See also

Reload on change

Especially in combination with conditionally displaying settings with displayCond, you may want to trigger a reloading of the form when specific settings are changed. You can do that with:

    <!-- ... -->

The onChange element is optional and must be placed on the same level as the <config> element.

How to read flexforms from an Extbase controller action

The settings can be read using $this->settings in an Extbase controller.

$includeCategories = (bool) ($this->settings['includeCategories'] ?? false);


If you wish to access a setting from your controller via $this->settings, the name of the setting must be prefixed with settings., so literally settings directly followed by a dot (.).

How to read and write flexforms from PHP

Some situation make it necessary to access Flexforms via PHP. The following APIs are available to work with Flexforms from within PHP:

In order to convert a Flexform to a PHP array, the xml2array method can be used:

$flexFormArray = \TYPO3\CMS\Core\Utility\GeneralUtility::xml2array($flexFormString);

In order to convert an PHP array into an Flexform, the :php`flexArray2Xml` method can be used:

$flexFormTools = new \TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools();
$flexFormString = $flexFormTools->flexArray2Xml($flexFormArray, true);

How to access flexforms From TypoScript

New in version 8.4: It is now possible to read Flexform properties from TypoScript, see Feature: #17309 - Access flexform value via TS.

lib.flexformContent = CONTENT
lib.flexformContent {
    table = tt_content
    select {
        pidInList = this

    renderObj = COA
    renderObj {
        10 = TEXT
        10 {
            data = flexform: pi_flexform:settings.categories

The key flexform is followed by the field which holds the Flexform data (pi_flexform) and the name of the property whose content should be retrieved (settings.categories).

How to access flexForms from Fluid

If you are using an Extbase controller, FlexForm settings can be read from within a Fluid template using {settings}. See the note on naming restrictions in How to Read Flexforms From an Extbase Controller Action.

If you defined your FLUIDTEMPLATE in TypoScript, you can assign single variables like that:

my_content = FLUIDTEMPLATE
my_content {
  variables {
    categories = TEXT
    categories.data = flexform: pi_flexform:categories

In order to have all FlexForm fields available, you can use the FlexFormProcessor. See also FlexFormProcessor in the TypoScript Reference. This example would make your FlexForm data available as Fluid variable {flexform}:

my_content = FLUIDTEMPLATE
my_content {
  dataProcessing {
    10 = TYPO3\CMS\Frontend\DataProcessing\FlexFormProcessor
    10.fieldName = my_flexform_field
    10.as = myOutputVariable

See also


Steps to Perform (Editor)

After inserting a plugin, the editor can configure this plugin by switching to the tab “Plugin” or whatever string you defined to replace this.



Some of the examples were taken from the extensions :t3ext:`news/` (by Georg Ringer) and :t3ext:`bootstrap_package/` (by Benjamin Kott).

Further enhancements by the TYPO3 community are welcome!