Sharing and switching design elements

Our single column page design processed a Fluid template in a Templates folder; and our double column page design processed a Fluid template in a Layouts folder. The two designs had some identical elements, including page-header and page-footer.

We can apply Fluid techniques to build more efficient and more flexible designs.

A design using Fluid partials

This design produces a single column web page and a double column web page that share one header and one footer.

In the TYPO3 CMS backend, create a standard page named PartialSingleColumn just under (inside) the Home page. On the PartialSingleColumn standard page, create a TypoScript extension template. In the TypoScript template Setup field, write the following lines:

page = PAGE
page.1 = FLUIDTEMPLATE
page.1 {
   templateName = Partial1Column
   templateRootPaths.1 = fileadmin/sitedesign/Resources/Private/Templates
   partialRootPath = fileadmin/sitedesign/Resources/Private/Partials
   variables {
      contentNormal < styles.content.get
   }
}

Notice the new partialRootPath instruction.

Create a file named Partial1Column.html in the fileadmin/sitedesign/Resources/Private/Templates folder, and write the following lines in the file:

<div id="page">
   <f:render partial="PageHeader" />
   <div id="page-body">
      <div id="page-title">{data.title}</div>
      <div id="whole-content">
         <f:format.raw>{contentNormal}</f:format.raw>
      </div>
      <div id="page-body-end">&nbsp;</div>
   </div>
   <f:render partial="PageFooter" />
</div>

Notice the new <f:render partial="…" /> elements.

In the TYPO3 CMS backend, create a standard page named PartialDoubleColumn just under (inside) the Home page. On the PartialDoubleColumn standard page, create a TypoScript extension template record. In the TypoScript template Setup field, write the following lines:

page = PAGE
page.1 = FLUIDTEMPLATE
page.1 {
   templateName = Partial2ColumnPage
   templateRootPaths.1 = fileadmin/sitedesign/Resources/Private/Layouts
   partialRootPath = fileadmin/sitedesign/Resources/Private/Partials
   variables {
      contentNormal < styles.content.get
      contentRight < styles.content.get
      contentRight.select.where = {#colPos}=2
   }
}

Create a file named Partial2ColumnPage.html in the fileadmin/sitedesign/Resources/Private/Layouts folder, and write the following lines in the file:

<div id="page">
   <f:render partial="PageHeader" />
   <div id="page-body">
      <div id="page-title">{data.title}</div>
      <div id="main-content">
         <f:format.htmlentitiesDecode>{contentNormal}</f:format.htmlentitiesDecode>
      </div>
      <div id="side-content">
         <f:format.htmlentitiesDecode>{contentRight}</f:format.htmlentitiesDecode>
      </div>
      <div id="page-body-end">&nbsp;</div>
   </div>
   <f:render partial="PageFooter" />
</div>

Create a file named PageHeader.html in a fileadmin/sitedesign/Resources/Private/Partials folder, and write the following lines in the file:

<div id="page-header">
   <div id="navigation-top-level"><f:cObject typoscriptObjectPath="lib.topNavigation" /></div>
   <div id="navigation-trail">{f:cObject(typoscriptObjectPath:'lib.breadcrumbTrail')->f:format.raw()}</div>
</div>

Create a file named PageFooter.html in the fileadmin/sitedesign/Resources/Private/Partials folder, and write the following lines in the file:

<div id="page-footer">
   <div id="footer-notice">
      <p>This is the page footer area.</p>
   </div>
</div>

The combination of the <f:render partial="…" /> element and the partial’s file name tells the TYPO3 CMS renderer which content goes where in a web page.

This design puts each common partial element into its own file, making editing more efficient and allowing more flexible editing access controls.

A design using Fluid sections

This design produces a single column web page having a header and footer, but using a different technique than earlier.

In the TYPO3 CMS backend, create a standard page named SectionSingleColumn just under (inside) the Home page. On the SectionSingleColumn standard page, create a TypoScript extension template. In the TypoScript template Setup field, write the following lines:

page = PAGE
page.1 = FLUIDTEMPLATE
page.1 {
   templateName = Section1Column
   templateRootPaths.1 = fileadmin/sitedesign/Resources/Private/Templates
   variables {
      contentNormal < styles.content.get
   }
}

Notice the lack of a partialRootPath instruction.

Create a file named Section1Column.html in the fileadmin/sitedesign/Resources/Private/Templates folder, and write the following lines in the file:

<div id="page">
   <f:render section="PageHeader" />
   <div id="page-body">
      <div id="page-title">{data.title}</div>
      <div id="whole-content">
         <f:format.raw>{contentNormal}</f:format.raw>
      </div>
      <div id="page-body-end">&nbsp;</div>
   </div>
   <f:render section="PageHeader" />
   <f:render section="PageFooter" />
</div>
<f:section name="PageHeader">
   <div id="page-header">
      <div id="navigation-top-level"><f:cObject typoscriptObjectPath="lib.topNavigation" /></div>
      <div id="navigation-trail">{f:cObject(typoscriptObjectPath:'lib.breadcrumbTrail')->f:format.raw()}</div>
   </div>
</f:section>
<f:section name="PageFooter">
   <div id="page-footer">
      <div id="footer-notice"> <p>This is the page footer area.</p> </div>
   </div>
</f:section>

Notice the <f:render section="…" /> and <f:section> elements. The <f:section> element contains the content; but the <f:render section="…" /> element tells the TYPO3 CMS renderer where to render that content. We purposely included a second <f:render section="PageHeader" /> element to illustrate the capability for multiple appearances.

This design places common elements and unique elements into one file, thus reducing the processing time required to produce a web page.

A design using Fluid layouts

This design produces a single column web page having a header and footer, but using yet another different technique than earlier.

In the TYPO3 CMS backend, create a standard page named LayoutSingleColumn just under (inside) the Home page. On the LayoutSingleColumn standard page, create a TypoScript extension template. In the TypoScript template Setup field, write the following lines:

page = PAGE
page.1 = FLUIDTEMPLATE
page.1 {
   templateName = ForLayouts
   templateRootPaths.1 = fileadmin/sitedesign/Resources/Private/Templates
   layoutRootPath = fileadmin/sitedesign/Resources/Private/Layouts
   variables {
      contentNormal < styles.content.get
   }
}

Notice the new layoutRootPath instruction.

Create a file named ForLayouts.html in the fileadmin/sitedesign/Resources/Private/Templates folder, and write the following lines in the file:

<f:layout name="Layout1ColumnPage" />

<f:section name="WholeContent">
   <div id="whole-content">
      <f:format.raw>{contentNormal}</f:format.raw>
   </div>
</f:section>

<f:section name="MainContent">
   <div id="main-content">
      <f:format.htmlentitiesDecode>{contentNormal}</f:format.htmlentitiesDecode>
   </div>
</f:section>

<f:section name="SideContent">
   <div id="side-content">
      <f:format.htmlentitiesDecode>{contentRight}</f:format.htmlentitiesDecode>
   </div>
</f:section>

<f:section name="PageHeader">
   <div id="page-header">
      <div id="navigation-top-level"><f:cObject typoscriptObjectPath="lib.topNavigation" /></div>
      <div id="navigation-trail">{f:cObject(typoscriptObjectPath:'lib.breadcrumbTrail')->f:format.raw()}</div>
   </div>
</f:section>

<f:section name="PageFooter">
   <div id="page-footer">
      <div id="footer-notice"> <p>This is the page footer area.</p> </div>
   </div>
</f:section>

Notice the <f:layout> element, which specifies which Fluid layout to use with this Fluid template. The remaining elements in this file are <f:section> elements, not all of which will be used in this design.

Create a file named Layout1ColumnPage.html in the fileadmin/sitedesign/Resources/Private/Layouts folder, and write the following lines in the file:

<div id="page">
   <f:render section="PageHeader" />
   <div id="page-body">
      <div id="page-title">{data.title}</div>
      <f:render section="WholeContent" />
      <div id="page-body-end">&nbsp;</div>
   </div>
   <f:render section="PageFooter" />
</div>

This design places subordinate elements into one Fluid template file, and places overall layout elements into another file. Doing so allows editing and access control advantages similar to the Fluid partials technique, but limits potential file loading and processing times.

Switching Fluid layouts

This design switches between a single column layout and a double column layout.

In the TYPO3 CMS backend, create a standard page named LayoutDoubleColumn just under (inside) the Home page. On the LayoutDoubleColumn standard page, create a TypoScript extension template. In the TypoScript template Setup field, write the following lines:

page = PAGE
page.1 = FLUIDTEMPLATE
page.1 {
   templateName = ForLayouts
   templateRootPaths.1 = fileadmin/sitedesign/Resources/Private/Templates
   layoutRootPath = fileadmin/sitedesign/Resources/Private/Layouts
   variables {
      contentNormal < styles.content.get
      contentRight < styles.content.get
      contentRight.select.where = {#colPos}=2
   }
}

Notice the additional contentRight element, which obtains content elements from the default named “Right” column position (#2) in a TYPO3 CMS backend page. Also, notice that the Fluid template name has not changed.

Create a file named Layout2ColumnPage.html in the fileadmin/sitedesign/Resources/Private/Layouts folder, and write the following lines in the file:

<div id="page">
   <f:render section="PageHeader" />
   <div id="page-body">
      <div id="page-title">{data.title}</div>
      <f:render section="MainContent" />
      <f:render section="SideContent" />
      <div id="page-body-end">&nbsp;</div>
   </div>
   <f:render section="PageFooter" />
</div>

Compare this layout to Layout1ColumnPage.html. A couple <f:section> elements differ, but the overall design structure is similar.

Now, edit the Templates/ForLayouts.html file. Replace its <f:layout name="Layout1ColumnPage" /> line with the following line.

<f:layout name="{settings.layout}" />

Edit the LayoutSingleColumn page TypoScript template in the TYPO3 CMS backend. Replace or edit its Setup field content to become the following:

page = PAGE
page.1 = FLUIDTEMPLATE
page.1 {
   templateName = ForLayouts
   templateRootPaths.1 = fileadmin/sitedesign/Resources/Private/Templates
   layoutRootPath = fileadmin/sitedesign/Resources/Private/Layouts
   variables {
      contentNormal < styles.content.get
   }
   settings.layout = Layout1ColumnPage
}

We only added a new settings.layout instruction.

Edit the LayoutDoubleColumn page TypoScript template in the TYPO3 CMS backend. Replace or edit its Setup field content to become the following:

page = PAGE
page.1 = FLUIDTEMPLATE
page.1 {
   templateName = ForLayouts
   templateRootPaths.1 = fileadmin/sitedesign/Resources/Private/Templates
   layoutRootPath = fileadmin/sitedesign/Resources/Private/Layouts
   variables {
      contentNormal < styles.content.get
      contentRight < styles.content.get
      contentRight.select.where = {#colPos}=2
   }
   settings.layout = Layout2ColumnPage
}

Here, too, we only added a new settings.layout instruction.

We now control which layout the ForLayouts.html template uses through a settings.layout element in the applicable TypoScript templates.

Alternatively, we could remove the settings.layout instruction from the LayoutSingleColumn and LayoutDoubleColumn page TypoScript templates, and add the following lines to the Home page TypoScript template Setup field. Keep the previously prepared library objects, topNavigation and breadcrumbTrail, in place:

page = PAGE
page.1 = FLUIDTEMPLATE
page.1.settings.layout = Layout1ColumnPage

We now need change only this one settings.layout value in this one TypoScript template to affect all the subordinate pages.

If we wanted one design for a few pages and the other design for the rest, we could modify the Home page TypoScript template Setup field again. Edit or add the following lines. Insert your own page UID values:

page = PAGE
page.1 = FLUIDTEMPLATE
[page["uid"] in [2,4]]
   page.1.settings.layout = Layout2ColumnPage
[ELSE]
   page.1.settings.layout = Layout1ColumnPage
[END]

This TypoScript template condition snippet applies the double column page layout if the current page has identifier 2 or 4, and applies the single column page layout for any other current page.

A flexible page column design

Alternatively, we may want to use the double column page layout only if there is side content to show. To do so, modify both the Home page TypoScript template and the Templates/ForLayouts.html Fluid template.

In the Home page TypoScript template Setup field, keep the previously prepared library objects, topNavigation and breadcrumbTrail, in place. However, remove any other instructions you may have added. Then, add the following lines at the bottom of the Setup field:

lib.contentTest = TEXT
lib.contentTest.value = 1
lib.contentTest.if.isTrue.numRows {
   table = tt_content
   select {
      orderBy = sorting
      where = {#colPos}=2
   }
}

In the Templates/ForLayouts.html file, replace its <f:layout name="Layout1ColumnPage" /> line with the following line.

<f:layout name="{f:if(condition: '{f:cObject(typoscriptObjectPath:\'lib.contentTest\')} == 1', then: 'Layout2ColumnPage', else: 'Layout1ColumnPage')}" />

This design tests for content in the TYPO3 backend page Right (#2) column position; and if it finds such content, uses the double column layout. Otherwise, it uses the single column layout.

Finally, make the design more efficient.

Delete the TypoScript template records from the LayoutSingleColumn and LayoutDoubleColumn pages in the TYPO3 CMS backend. Edit the Home page TypoScript template by replacing all its Setup field content with the following instructions:

lib {
   topNavigation = HMENU
   topNavigation {
      1 = TMENU
      1.NO.linkWrap = | |*| &nbsp;&nbsp;&nbsp; |*|
   }
   breadcrumbTrail = HMENU
   breadcrumbTrail {
      special = rootline
      special.range = 0|-1
      1 = TMENU
      1.NO {
         stdWrap.field = nav_title // title
         ATagTitle.field = nav_title // title
         linkWrap = | |*| &nbsp;&raquo;&nbsp; |*|
      }
      1.CUR = 1
      1.CUR {
         doNotLinkIt = 1
         stdWrap.field = nav_title // title
         linkWrap = | |*| &nbsp;&raquo;&nbsp;<em>|</em>|
      }
   }
   contentTest = TEXT
   contentTest.value = 1
   contentTest.if.isTrue.numRows {
      table = tt_content
      select {
         orderBy = sorting
         where = {#colPos}=2
      }
   }
}

page = PAGE
page.1 = FLUIDTEMPLATE
page.1 {
   templateName = ForLayouts
   templateRootPaths.1 = fileadmin/sitedesign/Resources/Private/Templates
   layoutRootPath = fileadmin/sitedesign/Resources/Private/Layouts
   variables {
      contentNormal < styles.content.get
      contentRight < styles.content.get
      contentRight.select.where = {#colPos}=2
   }
}

This design has one TypoScript template, one static TypoScript template, and three Fluid files. The TypoScript template is on the Home page. The static template is Fluid Content Elements (fluid_styled_content). The Fluid files are: Templates/ForLayouts.html, Layouts/Layout1ColumnPage.html, and Layouts/Layout2ColumnPage.html.

This is an efficient, flexible design. The Home page TypoScript template sets up library objects and page parameters unlikely to change often. The Templates/ForLayouts.html Fluid template file chooses a page layout and provides content sections for the layout. The resulting web page will show side content if there is side content to be shown.