TYPO3 Logo
TYPO3 site package tutorial
Options
Give feedback View source How to edit Edit on GitHub Full documentation (single file)

TYPO3 site package tutorial

  • Prerequisites
  • Generate a site package
  • Create initial pages
  • Assets
  • Fluid Templates
    • Fluid from the scratch
  • Content mapping
    • TypoScript imports
    • Stage
    • Subpage layout
    • Adding content
  • Menus
    • Breadcrumb
    • Breadcrumb
  • Settings
    • Usage in Fluid
  • Content Element rendering
  • Custom Content Blocks
    • Carousel
  • FAQ
  • Next Steps
  • Sitemap
  1. TYPO3 site package tutorial
  2. Custom Content Blocks
  3. Carousel
Give feedback Edit on GitHub

Carousel Content Block example

This content block demonstrates some additional features of friendsoftypo3/content-blocks . We assume that you are already familiar with the concepts described in chapter Custom Content Blocks.

Table of contents

  • Directory structure of the carousel content element
  • The carousel: A Content Block containing a collection of elements
  • Frontend template: Fluid template for a Content Block with a Collection
  • Content Block with backend template
  • Content Block specific assets

Directory structure of the carousel content element

Additionally to the files that the jumbotron provides (compare Directory structure of a Content Block), the carousel comes with special CSS and JavaScript needed for this element only.

Additionally it supplies a template for its display in the backend.

  • packages/my_site_package/ContentBlocks/ContentElements/carousel

    • assets

      • frontend.css
      • frontend.js
      • icon.svg
    • language

      • labels.xlf
    • templates

      • backend-preview.html
      • frontend.html
    • config.yaml

The carousel: A Content Block containing a collection of elements

The carousel can contain one or several items, each of which has an image, header, and description:

packages/my_site_package/ContentBlocks/ContentElements/carousel/config.yaml
name: my-site-package/carousel
typeName: my_site_package_carousel
group: my_site_package
prefixFields: true
prefixType: full
fields:
  - identifier: carousel_items
    type: Collection
    minitems: 1
    appearance:
      collapseAll: true
      levelLinksPosition: both
    fields:
      - identifier: image
        type: File
        allowed: common-image-types
        minitems: 1
        relationship: manyToOne
      - identifier: header
        type: Text
      - identifier: description
        type: Textarea
        enableRichtext: true
Copied!

Line 8: We use a field of type Collection to contain the items to be displayed in the carousel. This field type expects an array of fields (line 10ff).

Line 15: We use the type File to reference the image for the carousel item. We allow images only (line 16) and require exactly one image (lines 17 and 18).

Line 20: The title should be one line of text. We use the type Text.

Line 22: The description may contain rich text. Therefore, we use the type Textarea and enable the Rich-Text Editor (line 23).

Frontend template: Fluid template for a Content Block with a Collection

packages/my_site_package/ContentBlocks/ContentElements/carousel/templates/frontend.html
<f:asset.css identifier="content-block-css-t3docs-t3docs/carousel" href="{cb:assetPath()}/frontend.css"/>
<f:asset.script identifier="content-block-js-t3docs-t3docs/carousel" src="{cb:assetPath()}/frontend.js"/>

<div id="carousel{data.uid}" class="carousel slide" data-bs-ride="carousel">
    <div class="carousel-indicators">
        <f:for each="{data.carousel_items}" as="item" iteration="iteration">
            <button type="button" data-bs-target="#carousel{data.uid}" data-bs-slide-to="{iteration.index}" class="{f:if(condition: '{iteration.isFirst}', then:' active')}" aria-current="true" aria-label="{item.header}"></button>
        </f:for>
    </div>
    <div class="carousel-inner">
        <f:for each="{data.carousel_items}" as="item" iteration="iteration">
            <div class="carousel-item{f:if(condition: '{iteration.isFirst}', then:' active')}">
                <f:image image="{item.image}" class="d-block w-100"/>
                <div class="carousel-caption d-none d-md-block">
                    <h5>{item.header}</h5>
                    <f:format.html>{item.description}</f:format.html>
                </div>
            </div>
        </f:for>
    </div>
    <button class="carousel-control-prev" type="button" data-bs-target="#carousel{data.uid}" data-bs-slide="prev">
        <span class="carousel-control-prev-icon" aria-hidden="true"></span>
        <span class="visually-hidden"><f:translate key="{cb:languagePath()}:previous.label"/></span>
    </button>
    <button class="carousel-control-next" type="button" data-bs-target="#carousel{data.uid}" data-bs-slide="next">
        <span class="carousel-control-next-icon" aria-hidden="true"></span>
        <span class="visually-hidden"><f:translate key="{cb:languagePath()}:next.label"/></span>
    </button>
</div>
Copied!

Line 1: We use Asset.css ViewHelper <f:asset.css> to load the provided CSS file only if a carousel is displayed on that page. The Asset collector takes care that the file is not loaded more then once per page. All Fluid ViewHelpers prefixed with cb: are provided by friendsoftypo3/content-blocks they are therefore not listed in the official View Helper reference. The inline ViewHelper cb:assetPath() resolves paths to the asset folder of the current content block.

Line 2: We use the Asset.script ViewHelper <f:asset.script> to load the JavaScript file the same way.

Line 6: We use the For ViewHelper <f:for> to loop through each item. We then render a button for each carousel item.

Line 11: We loop the items a second time to now display all carousel slides.

Line 13: The field image was defined with option relationship: manyToOne in the config.yaml it can therefore only contain one image at maximum. As supplying an image is also mandatory minitems: 1 we can be sure there is always exactly one image. And just use the Image ViewHelper <f:image> to display the image.

Line 16: As the field {item.description} is of type Textarea with rich-text enabled we have to use the Format.html ViewHelper <f:format.html> to properly display it.

Line 23, 27: The previous and next buttons use localized text for their labels. We use the Translate ViewHelper <f:translate> to translate these labels and a view helper provided by the Content Block extension to determine the path to the language file.

Content Block with backend template

This Content Block contains a template to influence how the content elements should be displayed in the TYPO3 backend in the Page module:

packages/my_site_package/ContentBlocks/ContentElements/carousel/templates/backend-preview.html
<f:layout name="Preview"/>

<f:section name="Header">
    <f:variable name="itemCount"><f:count subject="{data.carousel_items}" /></f:variable>
    <div>{f:translate(key: '{cb:languagePath()}:backend.itemCount', arguments: {0: '{itemCount}'})}</div>
</f:section>

<f:section name="Content">
    <div class="row">
        <f:for each="{data.carousel_items}" as="item" iteration="iteration">
            <div class="col">
                <f:image image="{item.image}" width="100"/><br/>
                {item.header}
            </div>
        </f:for>
    </div>
</f:section>

<f:section name="Footer">
    <f:variable name="lastUpdated"><f:format.date>{data.rawRecord.crdate}</f:format.date></f:variable>
    <div>{f:translate(key: '{cb:languagePath()}:backend.lastUpdated', arguments: {0: '{lastUpdated}'})}</div>
</f:section>
Copied!

The same fields like for the frontend template are available and the same ViewHelpers can be used. However we display them in a simplified form.

Line 1: We are using the layout Preview, which already gives some structure to the display of the backend element:

Screenshot of a Content Block in the TYPO3 Backend, demonstrating the sections of the layout

The sections of a content element backend layout: (1) Header, (2) Content, (3) Footer

The line on the very top with the name of the content element, the icon and the edit buttons is generated by TYPO3 automatically and cannot be influenced by a backend template. It uses the label title defined in language/labels.xlf and the icon assets/icon.svg.

As always we use the Layout ViewHelper <f:layout> to select the Preview layout.

Each section is declared using the Section ViewHelper <f:section>.

Line 10: We once more use the For ViewHelper <f:for> to loop through all items of the slider and display them one by one.

Line 21: Labels can and should also be localized in the backend. To not lose context we prefixed all labels to be used in the backend with backend..

Tip

See also chapter Backend Preview in the Content Blocks manual.

Content Block specific assets

The assets in folder assets can be loaded in the Frontend Template. They will only be loaded when the Content Block is loaded on the current page. If compression (config.compressCss, config.compressJs) and concatenation (config.concatenateCss, concatenateJs) are enabled all assets are compressed and concatenated into as few as possible small asset files.

This also has the advantage that your JavaScript is only loaded if needed.

  • Previous
  • Next
Reference to the headline

Copy and freely share the link

This link target has no permanent anchor assigned. You can make a pull request on GitHub to suggest an anchor. The link below can be used, but is prone to change if the page gets moved.

Copy this link into your TYPO3 manual.

  • Home
  • Contact
  • Issues
  • Repository

Last rendered: May 01, 2025 06:47

© since 2017 by the TYPO3 contributors
  • Legal Notice
  • Privacy Policy