Examples: TCA column type category 

Simple category field 

In the following example a category tree is displayed and multiple categories can be selected.

The categories of a conference

The categories of a conference

EXT:my_extension/Configuration/TCA/Overrides/160-tx_myextension_conference-categories.php
<?php

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

ExtensionManagementUtility::addTCAcolumns('tx_myextension_conference', [
  'categories' => [
    'label' => 'my_extension.db:conference.categories',
    'config' => [
      'type' => 'category',
    ],
  ],
]);
ExtensionManagementUtility::addToAllTCAtypes(
  'tx_myextension_conference',
  'categories',
  '',
  'before:--div--;core.form.tabs:access',
);
Copied!

The relationship gets stored in the intermediate table sys_category_record_mm. Category counts are only stored on the local side.

One to one relation category field 

In the following example a category tree is displayed, but only one category can be selected.

The topic of a talk

The topic of a talk

EXT:my_extension/Configuration/TCA/Overrides/285-tx_myextension_talk-topic.php
<?php

use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

defined('TYPO3') or die();

ExtensionManagementUtility::addTCAcolumns('tx_myextension_talk', [
  'topic' => [
    'label' => 'my_extension.db:talk.topic',
    'config' => [
      'type' => 'category',
      'relationship' => 'oneToOne',
      'treeConfig' => [
        // The root category is set in the site configuration
        'startingPoints' => '###SITE:categories.root###',
      ],
    ],
  ],
]);
ExtensionManagementUtility::addToAllTCAtypes(
  'tx_myextension_talk',
  'topic',
  '',
  'before:--div--;core.form.tabs:access',
);
Copied!

Category field used in FlexForm 

It is possible to use the type category in FlexForm data structures. Due to some limitations in FlexForm, the manyToMany relationship is not supported. Therefore, the default relationship - used if none is defined - is oneToMany.

The plugin of the conference extension uses the "oneToMany" use case. It lists only the conferences of the selected categories:

EXT:my_extension/Configuration/FlexForms/ConferenceList.xml
<T3DataStructure>
  <sheets>
    <sDEF>
      <ROOT>
        <sheetTitle>my_extension.db:plugin.conferencelist.sheet.general</sheetTitle>
        <type>array</type>
        <el>
          <settings.mode>
            <label>my_extension.db:plugin.conferencelist.mode</label>
            <onChange>reload</onChange>
            <config>
              <type>select</type>
              <renderType>selectSingle</renderType>
              <items>
                <numIndex index="0">
                  <label>my_extension.db:plugin.conferencelist.mode.upcoming</label>
                  <value>upcoming</value>
                </numIndex>
                <numIndex index="1">
                  <label>my_extension.db:plugin.conferencelist.mode.past</label>
                  <value>past</value>
                </numIndex>
                <numIndex index="2">
                  <label>my_extension.db:plugin.conferencelist.mode.selected</label>
                  <value>selected</value>
                </numIndex>
              </items>
            </config>
          </settings.mode>
          <settings.conferences>
            <label>my_extension.db:plugin.conferencelist.conferences</label>
            <displayCond>FIELD:settings.mode:=:selected</displayCond>
            <config>
              <type>group</type>
              <allowed>tx_myextension_conference</allowed>
            </config>
          </settings.conferences>
          <settings.categories>
            <label>my_extension.db:plugin.conferencelist.categories</label>
            <config>
              <type>category</type>
            </config>
          </settings.categories>
          <settings.display>
            <label>my_extension.db:plugin.conferencelist.display</label>
            <config>
              <type>check</type>
              <items>
                <numIndex index="0">
                  <label>my_extension.db:plugin.conferencelist.display.logo</label>
                </numIndex>
                <numIndex index="1">
                  <label>my_extension.db:plugin.conferencelist.display.location</label>
                </numIndex>
                <numIndex index="2">
                  <label>my_extension.db:plugin.conferencelist.display.speakers</label>
                </numIndex>
                <numIndex index="3">
                  <label>my_extension.db:plugin.conferencelist.display.date</label>
                </numIndex>
              </items>
              <cols>3</cols>
              <default>15</default>
            </config>
          </settings.display>
          <settings.limit>
            <label>my_extension.db:plugin.conferencelist.limit</label>
            <displayCond>
              <or>
                <value1>FIELD:settings.mode:=:upcoming</value1>
                <value2>FIELD:settings.mode:=:past</value2>
              </or>
            </displayCond>
            <config>
              <type>number</type>
              <default>10</default>
            </config>
          </settings.limit>
          <settings.country>
            <label>my_extension.db:plugin.conferencelist.country</label>
            <config>
              <type>country</type>
              <labelField>localizedName</labelField>
              <size>4</size>
              <prioritizedCountries>
                <numIndex index="0">CH</numIndex>
                <numIndex index="1">DE</numIndex>
                <numIndex index="2">AT</numIndex>
              </prioritizedCountries>
            </config>
          </settings.country>
          <settings.timezone>
            <label>my_extension.db:plugin.conferencelist.timezone</label>
            <config>
              <type>select</type>
              <renderType>selectSingle</renderType>
              <items>
                <numIndex index="0">
                  <label></label>
                  <value></value>
                </numIndex>
              </items>
              <itemsProcessors>
                <numIndex index="100">
                  <class>MyVendor\MyExtension\Backend\ItemsProcessor\TimezoneItemsProcessor</class>
                  <parameters>
                    <regions>Europe</regions>
                  </parameters>
                </numIndex>
              </itemsProcessors>
            </config>
          </settings.timezone>
        </el>
      </ROOT>
    </sDEF>
    <sHighlights>
      <ROOT>
        <sheetTitle>my_extension.db:plugin.conferencelist.sheet.highlights</sheetTitle>
        <sheetDescription>my_extension.db:plugin.conferencelist.sheet.highlights.description</sheetDescription>
        <type>array</type>
        <el>
          <settings.introduction>
            <label>my_extension.db:plugin.conferencelist.introduction</label>
            <config>
              <type>text</type>
              <enableRichtext>1</enableRichtext>
            </config>
          </settings.introduction>
          <settings.highlights>
            <title>my_extension.db:plugin.conferencelist.highlights</title>
            <type>array</type>
            <section>1</section>
            <el>
              <highlight>
                <title>my_extension.db:plugin.conferencelist.highlight</title>
                <type>array</type>
                <el>
                  <title>
                    <label>my_extension.db:plugin.conferencelist.highlight.title</label>
                    <config>
                      <type>input</type>
                    </config>
                  </title>
                  <link>
                    <label>my_extension.db:plugin.conferencelist.highlight.link</label>
                    <config>
                      <type>link</type>
                    </config>
                  </link>
                </el>
              </highlight>
            </el>
          </settings.highlights>
        </el>
      </ROOT>
    </sHighlights>
  </sheets>
</T3DataStructure>
Copied!