Create custom content elements in TYPO3 part 1

In this series of blog posts, I explain how to create custom "Fluid Styled Content" based content elements in TYPO3.

This article is part of a series on content elements in TYPO3, here are links to other parts of this series.

  1. Creating a basic content element(this article)
  2. Adding more fields to the content element
  3. creating inline records (coming soon)

The five steps to a custom content element:

To create a basic content element, the following five steps are necessary.

  1. Add the content element in “new content element” wizard.
  2. Add the content element in “Type” drop-down
  3. Define the fields your content element need (for example a slider may need a header and one or more images).
  4. Add the TypoScript for frontend rendering.
  5. Add a fluid template.

Let’s create a content element.

Let’s say we have an extension named my_extension and we want to create a slider(content element) called my_slider. We write the above five steps for our slider content element.

Add the content element to “new content element” wizard.

We want to add our content element to this list.

Anywhere in the PageTS, add the snippet below.

mod.wizards.newContentElement.wizardItems.common {
    elements {
        my_extension_my_slider {
            iconIdentifier = content-carousel-image
            title = My Slider
            description = A content element to add one or more images
            tt_content_defValues.CType = my_extension_my_slider
        }
    }
    show := addToList(my_extension_my_slider)
}

Let’s see what the snippet above mean:

First two lines tell TYPO3 that you want to add a new item to “new content element ” wizard in the common category.

In line three my_extension_my_slider is the identifier for the content element. It should be unique across your website.

Line four defines icon for the content element. You can either choose one from TYPO3 icons or define your own icon using Icons API.

Lines 5 and 6 define the title and description of the content element.

Line 7 defines the CType (content type) of the content element (my_extension_my_slider in this example), we need the CType when defining frontend rendering in TypoScript.

Line 10 appends the content element to the content elements list.

Add the content element to the “Type” drop-down.

Now we want to add the content element to the “Type” drop-down.

Add the snippet below to the Configuration/TCA/Overrides/tt_content.php file.

<?php
defined('TYPO3_MODE') || die();

\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPlugin(
    array(
        'My slider',
        'my_extension_my_slider',
        'EXT:core/Resources/Public/Icons/T3Icons/content/content-carousel-image.svg'
    ),
    'CType',
    'my_extension'
);

Line 3 is the label shown to the editors. Line 4 is the identifier of the content element. Line 5 defines the path of an image which should be used as the icon for the “type” drop down. Line 8 is the extension key.

Define content element fields using TCA

Each content element is defined in a php file in Configuration/TCA/Overrides/ folder. Name of the file should start with tt_content and can contain any other name after it. Now lets create tt_content_my_extension_my_slider.php in Configuration/TCA/Overrides/ folder.

This file defines what fields the content element have (For our slider we define a header and unlimited number of images) .

\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTcaSelectItem(
    'tt_content',
    'CType',
    [
        0 => 'My slider',
        1 => 'my_extension_my_slider',
        2 => 'my-extension-my-slider'
    ]
);

$GLOBALS['TCA']['tt_content']['types']['my_extension_my_slider'] = [
    'showitem' => '
         --palette--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xml:palette.general;general,
         --palette--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xml:palette.header;header,
      --div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.media,assets,
      --div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.appearance,
        --palette--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:palette.frames;frames,
        --palette--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:palette.appearanceLinks;appearanceLinks,
      --div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xml:tabs.access,
         --palette--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xml:palette.visibility;visibility,
         --palette--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xml:palette.access;access,
      --div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xml:tabs.extended'
];

The lines 1 to 9 adds a new TCA item and the lines 12 to line 22 defines the fields for TCA.

The TCA definition (lines 12 to 22 ) has a special syntax. In the second part of this series, I will explain it in more details.

Add the snippet below in your TypoScript.

tt_content {
    my_extension_my_slider < lib.contentElement
    my_extension_my_slider {
        templateName = MySlider
        dataProcessing {
            10 = TYPO3\CMS\Frontend\DataProcessing\FilesProcessor
            10.references.fieldName = assets
        }
    }
}

On line 3 we copied TypoScript definition from lib.contentElement (defined in fluid_styled_content core extension).

Line 4 defines the template name for the content element.

Line 5 to 8 defines data processors for the content element, it is only necessary if you have images or videos in your content element(for example). typo3wrox has a good tutorial on data processors.

Add the HTML for the content element:

Create a file called MySlider.html in Resources/Private/Template/Content folder (This folder may be different if you have chosen a different folder for content element templates).

You have access to all data in this template.

<html data-namespace-typo3-fluid="true"
      xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers">
<f:debug>{_all}</f:debug>
</html>

Something is not clear or not working?

Contact me, I would be happy to help. It also helps me understand which part of this article is difficult to understand and improve it accordingly.

Further reading:

To keep things simple I have hard-coded labels. While it does work perfectly, but it is better to write them in language files. Read more about internationalization in TYPO3 in official docs.