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
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
field.data = levelfield:-2,backend_layout_next_level,slide
field.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.
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">
}
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.
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
....
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}" />
TYPO3 11.x:
[tree.pagelayout == 2]
...
[global]
https://docs.typo3.org/c/typo3/cms-core/main/en-us/Changelog/11.0/Feature-88276-TypoScriptConditionForPageLayout.html
Related
I am currently facing the issue, that when I fetch content from a specific page via typoscript, I only get the full content after the second pageload if I have deleted all caches before. The first content element is not rendered at all (seems to be ignored).
Here is my Typoscript:
lib.dynamicContent = COA
lib.dynamicContent {
5 = LOAD_REGISTER
5 {
colPos.cObject = TEXT
colPos.cObject {
field = colPos
ifEmpty.cObject = TEXT
ifEmpty.cObject {
value.current = 1
ifEmpty = 0
}
}
pageUid.cObject = TEXT
pageUid.cObject {
field = pageUid
ifEmpty.data = TSFE:id
}
contentFromPid.cObject = TEXT
contentFromPid.cObject {
data = DB:pages:{register:pageUid}:content_from_pid
data.insertData = 1
}
wrap.cObject = TEXT
wrap.cObject {
field = wrap
}
}
20 = CONTENT
20 {
table = tt_content
select {
includeRecordsWithoutDefaultTranslation = 1
orderBy = sorting
where = {#colPos}={register:colPos}
where.insertData = 1
pidInList.data = register:pageUid
pidInList.override.data = register:contentFromPid
}
stdWrap {
dataWrap = {register:wrap}
required = 1
}
}
90 = RESTORE_REGISTER
}
This is how I render the content in fluid:
<f:cObject typoscriptObjectPath="lib.dynamicContent" data="{pageUid: '41', colPos: '1'}" />
The output from the first content element after clearing the cache is on the first pageload: <div />. When I reload the page, I get the full content from the page.
I already checked the database queries which are executed, but they are always the same and return the correct results.
System:
TYPO3 10.4.8
PHP 7.3
You should remove the stdWrap part, which contains a wrap, that should be created via plain HTML in your Fluid template instead.
Im not 100% sure, but I guess the required check within that stdWrap section disables the content as well, since it might be checked before the actual content has been rendered.
I'm running a Typo3 v9.5.4 Onepager style Website. The content is loaded directly from the tt_content. The Website has two FE languages (German/English).
I have a CTA button which has an anchorlink. The button is create with typoscript. I created one button for the German version and one for the English verson bc they have another value and another ancorlink.
I'm not sure if I can access a tt_content field directly from a fluid viewhelper. This is my code i've tried
<f:if condition="{tt_content.sys_language_uid} == 1">
<f:then>
<f:format.raw>{buttonEn}</f:format.raw>
</f:then>
<f:else>
<f:format.raw>{buttonDe}</f:format.raw>
</f:else>
</f:if>
This is my Typoscript for the two button Objects
lib.buttonDe = TEXT
lib.buttonDe {
value = German Text
stdWrap.typolink.parameter = #anchorlinkDE
stdWrap.typolink.ATagParams = class="button"
}
lib.buttonEn = TEXT
lib.buttonEn {
value = English Text
stdWrap.typolink.parameter = #anchorlinkEN
stdWrap.typolink.ATagParams = class="button"
}
And this is the typoscript that loads the Content, the Languages Menu and the Fluidtemplate (the Onepager Content is loaded without a Fluidtemplate, it loads the content directly from tt_content):
//--------------------- One Pager Content
lib.sectionContent = HMENU
lib.sectionContent {
excludeUidList = 12,13,16,17,29
1 = TMENU
1 {
NO = 1
NO {
doNotLinkIt = 1
stdWrap >
stdWrap {
cObject = COA
cObject {
if.value = 4
if.equals.field = doktype
if.negate = 1
10 < temp.titleSectionId
10.wrap = <section id="|">
20 = CONTENT
20 {
table = tt_content
select {
pidInList.field = uid
orderBy = colPos,sorting
# Only selects Content where CE Layout is 0
where = (tt_content.layout = "0")
}
wrap = <div class="container">|</div>
renderObj < tt_content
}
30 = TEXT
30 {
wrap = </section>
}
}
}
}
}
}
//---------------------
// Language Selector
lib.langmenu = HMENU
lib.langmenu {
special = language
addQueryString = 1
special.value = {$config.language.uids}
1 = TMENU
1 {
wrap = <ul class="dg-langmenu row">|</ul>
NO = 1
NO {
stdWrap.current = 1
stdWrap.setCurrent = {$config.language.labels}
allWrap = <li class="col s6">|</li>
}
ACT < .NO
ACT.doNotLinkIt = 1
ACT.allWrap = <li class="act col s6">|</li>
}
}
page = PAGE
page{
10 = FLUIDTEMPLATE
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 = onePager
}
templateRootPaths {
10 = {$path.privat}Templates/
}
layoutRootPaths {
10 = {$path.privat}Layouts/
}
partialRootPaths {
10 = {$path.privat}Partials/
}
variables{
buttonDe < lib.buttonDe
buttonEnd< lib.buttonEn
}
}
So I'd like to load the buttonEn if the content has the sys_language_uid 1 (English) else I want it to load the buttonDe.
Do I need to create an Typoscript Object and then load this Object into the f:if viewhelper? If so how do I create this Typoscript Object.
Thanks for your help!
The easy way (pure typoscript)
lib.button = TEXT
lib.button {
value = English text
lang.de = Deutscher Text
stdWrap.typolink.parameter = #anchorlinkDE
stdWrap.typolink.ATagParams = class="button"
}
[siteLanguage("locale") == "en_EN.UTF-8"]
lib.buton.stdWrap.typolink.parameter = #anchorlinkEN
[global]
but the professional solution is configuring your labels in a language file (see answer from Thomas Löffler) and use:
lib.button = TEXT
lib.button {
lib.button.data = LLL:EXT:site_extension/Resources/Private/Language/locallang.xlf:button_label
stdWrap.typolink.parameter = #anchorlinkEN
stdWrap.typolink.ATagParams = class="button"
}
[siteLanguage("locale") == "de_DE.UTF-8"]
lib.buton.stdWrap.typolink.parameter = #anchorlinkDE
[global]
For language dependent constant data you might use typoscript conditions to redefine a value for your non default languages. (or define a fallback and conditions for each language.)
You should use a locallang file and refer to it in TypoScript.
Create a locallang file (copy an existing and remove all values) named locallang.xlf
Add your english label in there
Create a locallang file in the same folder with prepending de. in the filename (de.locallang.xlf) and add the german label
Refer to it in the TypoScript by using lib.button.data = LLL:EXT:your_ext/path/to/locallang/locallang.xlf:buttonLabel, see https://docs.typo3.org/typo3cms/TyposcriptReference/DataTypes/Index.html#lll
This TS getText function gets the label depending on the set language ID automatically and you only need one TS for the button.
Example: https://docs.typo3.org/typo3cms/TyposcriptIn45MinutesTutorial/UsingGetText/Index.html
I have a finished static HTML Template. I need to map it to typo3 so the content is dynamic. I followed following tutorial: https://docs.typo3.org/typo3cms/SitePackageTutorial/FluidTemplates/Index.html
This works perfectly, but now I wonder how I can change the template per site? I made template for each site i.e Gallerie.html, Contact.html and they are linked to the same Layout as Header and Footer is always the same.
How do I now tell the page About us to use the Gallerie.html?
My setup.typoscript:
page = PAGE
page {
typeNum = 0
// Part 1: Fluid template section
10 = FLUIDTEMPLATE
10 {
templateName = TEXT
templateName.stdWrap.cObject = CASE
templateName.stdWrap.cObject {
key.data = pagelayout
pagets__default = TEXT
pagets__default.value = Default
default = TEXT
default.value = Default
}
templateRootPaths {
0 = EXT:eventmanagement/Resources/Private/Templates/Page/
1 = {$page.fluidtemplate.templateRootPath}
}
partialRootPaths {
0 = EXT:eventmanagement/Resources/Private/Partials/Page/
1 = {$page.fluidtemplate.partialRootPath}
}
layoutRootPaths {
0 = EXT:eventmanagement/Resources/Private/Layouts/Page/
1 = {$page.fluidtemplate.layoutRootPath}
}
dataProcessing {
10 = TYPO3\CMS\Frontend\DataProcessing\MenuProcessor
10 {
levels = 1
includeSpacer = 1
as = mainnavigation
}
}
}
At the Moment it loads the Default.html Template from eventmanagement/Resources/Private/Templates/Page/ on every page. I created now a second Template called Gallerie.html in eventmanagement/Resources/Private/Templates/Page/ how do I add this now to the page Gallerie in the Backend?
I don't know if it's very useful to have for (nearly) every page another template but in general that's possible. Just consider that in the root-line always that template is used that is defined on the current level or - if not existing - that, that is found first while going up the root-line.
For every additional template you've to add a section inside this snippet from above:
templateName.stdWrap.cObject {
key.data = pagelayout
pagets__default = TEXT
pagets__default.value = Default
default = TEXT
default.value = Default
}
So including the option about us the snippet could look like this:
templateName.stdWrap.cObject {
key.data = pagelayout
pagets__default = TEXT
pagets__default.value = Default
default = TEXT
default.value = Default
pagets__aboutus = TEXT
pagets__aboutus.value = AboutUs
aboutus = TEXT
aboutus.value = AboutUs
}
Additional you still have to change the TCA probably to include the options in the drop-down-button.
I'am new to typo3 and I want to integrate my HTML template in it. but I can't add my content to the pages threw the dashboard all I get is a blank page.
I'am using TYPO3 v8
Greetings!
The steps you need to do for template integration in TYPO3 8
TYPOSCRIPT
Tell TYPO3 by where the templates should be get.
page = PAGE
page.10 {
templateRootPaths {
10 = PATH TO YOUR TEMPLATES
}
layoutRootPaths {
10 = PATH TO YOUR LAYOUTS
}
partialRootPaths {
10 = PATH TO YOUR PARTIALS
}
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 = Home
}
}
LAYOUTS
It's not required to create a layout, but i suggest to do it, also if you have just one type of template.
The layouts ( in TYPO3 called Backend Layouts ) can be created in TYPO3 backend and the backend layouts are saved in database. But you can save the backend layouts configuration in a file.
Hint: Try save the backend layouts configuration in files so you can add to
git
Example of backend layout configuration:
mod.web_layout.BackendLayouts {
Home # identified by this name {
title = Home # this is shown in backend when you select the layout
icon = EXT:example_extension/Resources/Public/Images/BackendLayouts/default.gif
config {
backend_layout {
colCount = 1
rowCount = 1
rows {
1 {
columns {
1 {
name = Content
colPos = 1 # this is important, i'm talking about colPos below
}
}
}
}
}
}
}
}
ColPos meaning: you can have multiple columns in a layout, and the colPos is used to render the content in frontend. This is what will be used later in template <f:cObject typoscriptObjectPath="lib.dynamicContent" data="{colPos: 1}" />
The above configuration should be included in PageTs. This is found if you edit a page and go to Resources tab.
Typoscript configuration of lib.dynamicContent
lib.dynamicContent = COA
lib.dynamicContent {
5 = LOAD_REGISTER
5 {
colPos.cObject = TEXT
colPos.cObject {
field = colPos
ifEmpty.cObject = TEXT
ifEmpty.cObject {
value.current = 1
ifEmpty = 0
}
}
pageUid.cObject = TEXT
pageUid.cObject {
field = pageUid
ifEmpty.data = TSFE:id
}
contentFromPid.cObject = TEXT
contentFromPid.cObject {
data = DB:pages:{register:pageUid}:content_from_pid
data.insertData = 1
}
wrap.cObject = TEXT
wrap.cObject {
field = wrap
}
maxItems.cObject = TEXT
maxItems.cObject {
field = maxItems
ifEmpty =
}
}
20 = CONTENT
20 {
table = tt_content
select {
includeRecordsWithoutDefaultTranslation = 1
orderBy = sorting
where = {#colPos}={register:colPos}
where.insertData = 1
pidInList.data = register:pageUid
pidInList.override.data = register:contentFromPid
max.data = register:maxItems
// select.languageField setting is needed if you use this typoscript in TYPO3 < v7
// languageField = sys_language_uid
}
stdWrap {
dataWrap = {register:wrap}
required = 1
}
}
90 = RESTORE_REGISTER
}
lib.dynamicContentSlide < lib.dynamicContent
lib.dynamicContentSlide.20.slide = -1
lib.dynamicContentFirst < lib.dynamicContent
lib.dynamicContentFirst.20.select.max = 1
Home layout html integration
<f:render section="main" />
Home template integration
<f:layout name="Home" />
<f:section name="content">
// content
<f:cObject typoscriptObjectPath="lib.dynamicContent" data="{colPos: 1}" />
</f:section>
Now we have the setup of layouts and templates. Hope that you have a basic setup of TYPO3 ( a root page at least and a template setup )
If you don't have this setup already, follow the next steps:
Create a root page
Go with list on root page
Create a Template record - go in Options tab and check Clear -> Constants and Clear -> setup and check also Rootlevel
Go in Includes tab and select from the multiple selectbox fluid_styled_content
Paste the TYPOSCRIPT configuration in the created template ( check General Tab )
Edit Root page and go to the Appearance tab to select the Backend Layout.
After update from TYPO3 7.6.16 to 8.7 in my navigation (TMENU) the target _blank is no longer output for pages of typ external URL. In page properties the target flag _blank is entered. Any hints?
Try this, working for me:
lib.mainmenuu = HMENU
lib.mainmenuu {
special = directory
special.value = 1
1=TMENU
1.wrap=<ul>|</ul>
1.NO {
# do not create a link here else there are double <a> tags
doNotLinkIt = 1
wrapItemAndSub=<li>|</li>
stdWrap.cObject = CASE
stdWrap.cObject {
key.field = doktype
default = TEXT
default {
field = title
typolink.parameter.field = uid
stdWrap.htmlSpecialChars = 1
}
# 3 = external url
3 = TEXT
3 {
field = title
typolink.parameter.field = url
typolink.extTarget = _blank
}
}
}
}
Here, use your news detail page id instead of 27. this will override default page title with current detail news title.