Templating · Creating templates · Content element

3.2.3 Creating Content Elements

Content elements are defined similar to page templates and consist of a layout and a template file. Typically the layout simply renders the main section of the template and is shared with several content elements:

<f:layout name="Content" />

<f:render section="Main" />

All magic happens in the content element's template file which in its basic structure looks like this:

<div xmlns="http://www.w3.org/1999/xhtml" lang="en"
      xmlns:f="http://typo3.org/ns/TYPO3/Fluid/ViewHelpers"
      xmlns:flux="http://typo3.org/ns/FluidTYPO3/Flux/ViewHelpers"
      xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers">

<f:layout name="Content" />

<f:section name="Configuration" />

<f:section name="Preview" />

<f:section name="Main" />

</div>

As you can see we connect the template to the above layout via <f:layout name="Content" />, add a section named Configuration that will contain our flexform, a Section named Preview that will get rendered in the backend and the Main section as found in the layout that will contain the rendered frontend content.

Now, let's create a content element for a typical use case: a teaserbox consisting of an image, a headline, some teaser text and an optional link in typo3conf/ext/myextensionkey/Resources/Private/Templates/Content/Teaser.html:

<div xmlns="http://www.w3.org/1999/xhtml" lang="en"
      xmlns:f="http://typo3.org/ns/TYPO3/Fluid/ViewHelpers"
      xmlns:flux="http://typo3.org/ns/FluidTYPO3/Flux/ViewHelpers"
      xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers">

<f:layout name="Content"/>

<f:section name="Configuration">
    <flux:form id="teaser">
        <flux:field.file name="image" allowed="jpg" uploadFolder="uploads/tx_quickstart" minItems="1" maxItems="1" size="1" />
        <flux:field.input name="headline" />
        <flux:field.text name="teasertext" rows="5" cols="30" required="TRUE" />
        <flux:field.input name="link">
            <flux:wizard.link activeTab="page"/>
        </flux:field.input>
    </flux:form>
</f:section>

<f:section name="Preview">
    <table width="100%">
        <tr>
            <td width="50%"><v:media.image src="uploads/tx_quickstart/{image}" alt="{headline}" width="100" /></td>
            <td width="50%">
                <f:format.crop maxCharacters="50">{teasertext}</f:format.crop>
                <f:if condition="{link}">
                    <strong>Link:</strong> {link}
                </f:if>
            </td>
        </tr>
    </table>
</f:section>

<f:section name="Main">
    <div class="quickstart-teaser">
        <article>
        <h1>{headline}</h1>
        <div class="image-wrapper">
            <v:media.image src="uploads/tx_quickstart/{image}" alt="{headline}" width="200" />
        </div>
        <div class="text-wrapper">
            <f:format.nl2br>{teasertext}</f:format.nl2br>
            <f:if condition="{link}">
                <f:link.page pageUid="{link}" title="{headline}" class="readmore">read more</f:link.page>
            </f:if>
        </div>
        </article>
    </div>
</f:section>

</div>

Let's have a look at the three sections:

Configuration contains the flexform that defines the content element's fields which are wrapped in an outer <flux:form /> viewhelper. id is a required argument for this viewhelper and used to generate the translation key for the element's label (flux.teaser in this case) in TYPO3's New Content Element Wizard. By default a new tab labelled FCE is created which can be overridden with the viewhelper argument wizardTab.

There's nothing special about the flexform's fields in this example so to avoid duplicate content please take a look at the reference guide on fluidtypo3.org where you can find all required information about their functionality and arguments. One thing to take a closer look at though is the link wizard that is implemented by making it a child of the according input field.

The fields' values are accessible as equally named variables in sections Preview and Main.

Preview contains some real oldschool table layout to be rendered in the backend and which may look familiar if you worked with Templavoilà before. Note the usage of <v:media.image /> to avoid issues with displaying images in the backend due to relative paths.

Main finally contains the output to be rendered in the frontend and makes use of some fluid viewhelpers you certainly know already.

After clearing caches you should now see a new tab FCE in the New Content Element Wizard that makes our new content element selectable.

Jump to...