2
votes

I'd like to change the way elements are rendered depending on the page's backend layout.
Changing the fluid styled content template depending on the backend layout works as following:

[globalVar = TSFE:page|backend_layout = 1][globalVar = TSFE:page|backend_layout = 2]
lib.fluidContent.templateRootPaths.10 = EXT:ds_res/Resources/Private/Templates/ContentTemplates/
[global]

If it's 1 or 2, then use the other templates.

However, this only works if the BE layout is set directly at the page and not when it's inherited from its parent.
How to fix this?

Running TYPO3 7.6.15
Thanks.

5
Have a look at this Question: stackoverflow.com/questions/39614470/…bschauer
@bschauer I've also seen that post, but how do I use the lib.backendLayout inside a condition? [lib.xx = 1] doesn't seem to work...Norman

5 Answers

6
votes

In TYPO3 7.5 "Backend Layout"-Conditions has been simplified with "pagelayout" in Typoscript. Example:

page.10 = FLUIDTEMPLATE
page.10 {
  file.stdWrap.cObject = CASE
  file.stdWrap.cObject {
    key.data = pagelayout
    default = TEXT
    default.value = EXT:sitepackage/Resources/Private/Templates/Home.html
    3 = TEXT
    3.value = EXT:sitepackage/Resources/Private/Templates/1-col.html
    4 = TEXT
    4.value = EXT:sitepackage/Resources/Private/Templates/2-col.html
  }
}

Instead of:

field = backend_layout
ifEmpty.data = levelfield:-2,backend_layout_next_level,slide
ifEmpty.ifEmpty = default

Maybe this also works in your conditions like this:

[globalVar = TSFE:page|pagelayout = 1]

However, you should not change the used template file with [xy]-conditions and prefer using a CASE shown in the example above. Each number is the UID of a backend_layout by the way.

1
votes

We use this solution

page = PAGE
page.10 = FLUIDTEMPLATE
page.10 {

templateName = TEXT
templateName.stdWrap {
    cObject = TEXT
    cObject {
        data = levelfield:-2,backend_layout_next_level,slide
        override.field = backend_layout
        split {
            token = pagets__
            1.current = 1
            1.wrap = |
        }
    }
    ifEmpty = Index
        }
        layoutRootPaths {
            10 = EXT:yourext/Resources/Private/Layouts
        }
        partialRootPaths {
            10 = EXT:yourext/Resources/Private/Partials
        }
        templateRootPaths {
            10 = EXT:yourext/Resources/Private/Templates
        }
}

This approach is when u do not have the Backendlayouts in the DB (made through the backend) but include them from files. As there is no uid then you go by the templatename.

Example: If you use this PageTS:

mod.web_layout.BackendLayouts {
    Blankpage {
        title = Blankpage
        name = Blankpage
        icon = EXT:yourext/Resources/Public/Icons/BackendLayouts/Blankpage.jpg
    config {
        backend_layout {
            colCount = 1
            rowCount = 2
            rows {
                1 {
                    columns {
                        1 {
                            name = Nameofthecolumn
                            colPos = 0
                            colspan = 1
                        }
                    }
                }
                2 {
                    columns {
                        1 {
                            name = Nameofthesecondcolumn
                            colPos = 1
                            colspan = 1
                        }
                    }
                }

            }
        }
    }
}

You will need a Template.html with the name Blankpage.html within your EXT-Templates.

So you can add more Templates and Backendlayouts without touching the TS again. Simply add PageTS and a html-template.

1
votes

There is a feature available which avoids having that code duplicated

page.10 = FLUIDTEMPLATE
page.10 {
    templateName = TEXT
    templateName.stdWrap.cObject = CASE
    templateName.stdWrap.cObject {
        key.data = pagelayout
        ....
1
votes

As you can not handle the inherited layouts in conditions you need to use typoscript. My solution is this:

page.10 = FLUIDTEMPLATE
page.10 {
    templateRootPaths.1 = {$resDir}/Private/Templates
    partialRootPaths.1 = {$resDir}/Private/Partials
    layoutRootPaths.1 = {$resDir}/Private/Layouts

    templateName = TEXT
    templateName.cObject = CASE
    templateName.cObject {
        key.data = levelfield:-1, backend_layout_next_level, slide
        key.override.field = backend_layout

        #Default Template
        default = TEXT
        default.value = subpage

        # homepage 
        pagets__homepage = TEXT
        pagets__homepage.value = homepage

        pagets__subpage = TEXT
        pagets__subpage.value = subpage
    }
    variables {
        :

        pageLayout = TEXT
        pageLayout.data = levelfield:-1, backend_layout_next_level, slide
        pageLayout.override.field = backend_layout

        // since TYPO3 7 this already is computed by the core and this gives the same:
        pageLayout = TEXT
        pageLayout.data = pagelayout

        :
    }
}

Avoid using file for better implementation with ..RootPaths.

As we use backendlayouts defined in files (which gets included in the pageTSconfig) the key names starting with pagets__, you also might use the numbers of backend_layout records.

I use the constant {$resDir} to define the root of resources which can be changed in an easy way. In a siteextension this could be:

resDir = EXT:site_project1/Resources

I also define a fluid variable with the currently active page layout for further differentiation in the templates.

If you want the ...RootPaths to be different for each layout you need to build cObject with a CASE obejct similar to my selection of the template name.

In general: all this could be handled in the fluid templates if you have the backend layout available in your variables: you only need to have one starting template, which calls a layout where all further calls to partials are individualized by the current layout like

<f:render partial="{pageLayout}/header" arguments="{_all}" />
1
votes

In TYPO3 9.5+ you can use typoscript conditions like:

[page["backend_layout"] == 'pagets__2']
    page.bodyTagCObject.value.wrap = <body id="uid|" class="fullpage">
[end]

Edit:

As Bernd has mentioned use backend_layout only if you need the real defined field. If you need the computed value (e.g. for a sub page getting its layout from the backend_layout_next_level from a parent page) use pagelayout with a case like:

bodyTagCObject = TEXT
bodyTagCObject.value.field = uid
bodyTagCObject.value.wrap.cObject = CASE
bodyTagCObject.value.wrap.cObject{
    
    key.data = pagelayout

    default = TEXT
    default.value = <body id="uid|" class="standard">
    
    pagets__2 = TEXT
    pagets__2.value = <body id="uid|" class="fullpage">
    
}