Display the content elements on your page

In step Move the content into a section we moved the part of our template, that will contain the content, into its own section. This section is however still filled with dummy content:

Resources/Private/PageView/Pages/Default.html
<f:layout name="Layout"/>
<f:section name="Main">
    <f:render partial="Stage" arguments="{_all}"/>
    <div class="container">
        <h2>Start page content</h2>
        <p>The content of the start page is displayed here. [...] </p>
    </div>
</f:section>
Copied!

Include the site sets of fluid-styled-content as dependency

In step Minimal site package - Create a basic site set we created a basic site set for our site package.

Add a dependency to the sets provided by the system extension typo3/cms-fluid-styled-content . This step is a prerequisite to display the content in the next steps.

Your site set configuration should now look like this:

packages/my_site_package/Configuration/Sets/SitePackage/config.yaml
name: my-vendor/my-site-package
label: 'My Site Package'
dependencies:
  - typo3/fluid-styled-content
  - typo3/fluid-styled-content-css
Copied!

Create a default page layout with page TSconfig

In order to map the content from the backend to the frontend we create a new file Configuration/Sets/SitePackage/page.tsconfig containing page TSconfig.

By placing the file within the site set, you created in step Create a basic site set, the newly created file is loaded within the page tree of your site automatically:

packages/my_site_package/Configuration/Sets/SitePackage/page.tsconfig
@import './PageTsConfig/'
@import './PageTsConfig/BackendLayouts/'
Copied!

This file automatically includes all .tsconfig files from the designated folder in which we will store the page layouts.

We now create a default page layout with two areas: One for the main content and one for the stage.

packages/my_site_package/Configuration/TsConfig/Page/PageLayout/Default.tsconfig
mod.web_layout.BackendLayouts {
  Default {
    title = Standard
    icon = EXT:my_site_package/Resources/Public/Icons/BackendLayouts/default.svg
    config {
      backend_layout {
        colCount = 1
        rowCount = 3
        rows {
          1 {
            columns {
              1 {
                name = Stage
                colPos = 1
                identifier = stage
                slideMode = slide
              }
            }
          }

          2 {
            columns {
              1 {
                name = Main Content
                colPos = 0
                identifier = main
              }
            }
          }
        }
      }
    }
  }
}
Copied!

Changed in version TYPO3 13

Each area in the page layout becomes an identifier that can be used during content mapping. If no content element is added in the backend of that page and the slide mode is activated, content from the parent page is displayed. This is useful for design elements like side bars, jumbotrons or banners that should be the same for a page and its subpage. You can find all details of the Page / backend layouts in the TSconfig reference.

When you make changes to the files of an extension it is usually necessary to flush all caches by hitting the button.

Flush all caches

After flushing the all caches the new backend layout is available in the page properties at Appearance > Page Layout > Backend Layout.

Choose the backend layout

Choose the page layout in the page properties

Switch to the new backend layout and save the page properties. In the Page module you will see two areas called "Stage" and "Main Content" now.

If you followed step Load the example data automatically the areas "Stage" and "Main" should already contain some example content.

Create new content element

In the database each content element record is stored in the table tt_content. This table has a column called colPos. If the value stored in column colPos is the same as defined in the page layout in page TSconfig the content element is displayed in the according area of the page layout.

It is considered best practice to store the main content in an area with colPos=0. This makes switching between different layouts easier.

Content rendering via page-content data processor

New in version TYPO3 13

The TypoScript object PAGEVIEW, that we defined in step Fluid version of the minimal site package enables us to introduce a data processor to facilitate content mapping.

Edit the TypoScript configuration of the PAGEVIEW object to define a data processor of type page-content:

Configuration/Sets/SitePackage/setup.typoscript (diff)
 page {
   10 {
     paths {
       100 = EXT:my_site_package/Resources/Private/PageView/
     }

+    dataProcessing {
+      # makes content elements available as {content} in Fluid template
+      10 = page-content
+    }
   }
 }
Copied!

This data processor provides the variable content to your Fluid template.

You can debug this variable in the main section of your template using the Debug ViewHelper <f:debug>:

Resources/Private/PageView/Pages/Default.html
 <f:layout name="Layout"/>
 <f:section name="Main">
     <f:render partial="Stage" arguments="{_all}"/>
+    <f:debug>{content}</f:debug>
     <div class="container">
         <h2>Start page content</h2>
         <p>The content of the start page is displayed here. [...] </p>
     </div>
 </f:section>
Copied!

The debug output after clearing all caches and previewing the page should look like this:

Screenshot of the debug output of {content}

The debug output should contain sections "stage" and "main"

TypoScript mapping in Fluid template

Open the file Resources/Private/PageView/Page/Default.html and locate the main content area. It contains a headline (look for the <h2>-tags) and some dummy content (look for the <p>-tags).

Replace these lines with a Fluid for-loop, rendering each content element using the CObject ViewHelper <f:cObject>:

Resources/Private/PageView/Pages/Default.html (diff)
 <f:layout name="Layout"/>
 <f:section name="Main">
     <f:render partial="Stage" arguments="{_all}"/>
-    <f:debug>{content}</f:debug>
         <div class="container">
-            <h2>Start page content</h2>
-            <p>The content of the start page is displayed here. [...] </p>
+            <f:for each="{content.main.records}" as="record">
+                <f:cObject
+                     typoscriptObjectPath="{record.mainType}"
+                     data="{record.rawRecord}"
+                     table="{record.mainType}"
+                  />
+            </f:for>
         </div>
 </f:section>
Copied!

For content elements the main type is always tt_content. Therefore we include the TypoScript object tt_content here. It is defined in the TypoScript of the system extension typo3/cms-fluid-styled-content . We included the site set of that extension in step Include the site sets of fluid-styled-content as dependency.

fluid-styled-content internally uses Fluid templates and TypoScript with data processors just like the ones we were defining above. If you desire to change the output of these content elements you could override the Fluid templates of the extension typo3/cms-fluid-styled-content .

Extract the content element rendering to a partial

As we want to reuse the Fluid part about rendering content elements in the next steps, we extract it into a partial, like we did with the menu in step Extract the menu into a partial.

We want to be able to render content elements of any content area. Therefore pass the records of the page layout area to be rendered as variable records to the partial:

Resources/Private/PageView/Pages/Default.html (diff)
 <f:layout name="Layout"/>
 <f:section name="Main">
     <f:render partial="Stage" arguments="{_all}"/>
     <div class="container">
-        <f:for each="{content.main.records}" as="record">...</f:for>
+        <f:render partial="Content" arguments="{records: content.main.records}"/>
     </div>
 </f:section>
Copied!

The partial then looks like this:

packages/my_site_package/Resources/Private/PageView/Partials/Content.html
<f:for each="{records}" as="record">
    <f:cObject
        typoscriptObjectPath="{record.mainType}"
        data="{record}"
        table="{record.mainType}"
    />
</f:for>
Copied!

Splitting up the TypoScript into files

At this point the file packages/my_site_package/Configuration/Sets/SitePackage/setup.typoscript has started to have several lines. When we start rendering the Menues, make more sophisticated Settings etc the TypoScript configuration file is going to grow more. We therefore suggest, to use TypoScript imports and structure your TypoScript in different files that are then combined at this point.

The rest of the Tutorial will assume that your files are in the directory packages/my_site_package/Configuration/Sets/SitePackage/TypoScript/ and imported as described in TypoScript imports.

Next steps