I have the following problem:
I am using typo3 4.7.7 and I am adding custom columns in the Backend. I am able to do taht by place a configuration array in the /typo3conf/extTables.php
$TCA["tt_content"]["columns"]["colPos"]["config"]["items"] = array (
"3" => array ("Border,"3"),
"2" => array ("Right","2"),
"1" => array ("Left","1"),
"0" => array ("Normal","0"),
"5" => array ("Central","5"),
"6" => array ("Border","6"),
"4" => array ("Footer","4")
);
Then set:
mod.SHARED.colPos_list=0,1,2,3,4,5,6
in the TSconfig.
It is working, I enjoy my new columns :), but there is a problem. I want to be able to use the css_styled_content to map my new columns to my html template. This is not possible, because the "get" constants of css_styled_content are hard coded and I am not able to use something like "content.getFooter". At the moment the only way I can get my content is like this:
...
page.10 = CONTENT
page.10.table = tt_content
page.10.select {
orderBy = sorting
where = colPos = 4
}
page.10.renderObj = COA
page.10.renderObj {
10 = TEXT
10.field = header
20 = TEXT
20.field = bodytext
}
...
This is a lot of code, so I was wondering if there is a way to "make" CSC recognize my new columns, so that I would be able to use "content.getMYCUSTOM_COLUMN_NAME".
P.S. I do not want to use templavoila and I found something in the source of CSC under /static/setup.txt :
# Clear out any constants in this reserved room!
styles.content >
# get content
styles.content.get = CONTENT
styles.content.get {
table = tt_content
select.orderBy = sorting
select.where = colPos=0
select.languageField = sys_language_uid
}
# get content, left
styles.content.getLeft < styles.content.get
styles.content.getLeft.select.where = colPos=1
# get content, right
styles.content.getRight < styles.content.get
styles.content.getRight.select.where = colPos=2
# get content, margin
styles.content.getBorder < styles.content.get
styles.content.getBorder.select.where = colPos=3
# get news
styles.content.getNews < styles.content.get
styles.content.getNews.select.pidInList = {$styles.content.getNews.newsPid}
# Edit page object:
styles.content.editPanelPage = COA
styles.content.editPanelPage {
10 = EDITPANEL
10 {
allow = toolbar,move,hide
label.data = LLL:EXT:css_styled_content/pi1/locallang.xml:eIcon.page
label.wrap = | <b>%s</b>
}
}
I then tried to add:
# get content, footer
styles.content.getFooter < styles.content.get
styles.content.getFooter.select.where = colPos=4
But it did not work.
you are on the right track. try to create your own Content Object:
temp.footer < styles.content.get
temp.footer.select.where = colPos=4
page = PAGE
page.100 < temp.footer
Related
I generate an lib.content with the current content but i want to add it only if the following if statement will be true, otherwise not/empty:
lib.content = COA
lib.content{
10 < styles.content.get
10.stdWrap.cObject.if{
value.data = DB:pages:{page:uid}:nav_hide
value.data.insertData = 1
equals = 1
}
}
is this possible or where's the error in the syntax?
Version of Typo3 is 10.4
You need to use "insertData" twice, because it replaces {page:uid} with the UID (e.g. 5), but it keeps the rest DB:pages:5:nav_hide.
The rest DB:pages:5:nav_hide needs to be "data inserted" again, so the trick is to use wrap3.
Solution:
lib.content = COA
lib.content {
10 < styles.content.get
10.stdWrap.cObject.if {
// Replaces page:uid
value.dataWrap = DB:pages:{page:uid}:nav_hide
// Wraps curly brackets around DB:pages:5:nav_hide
value.wrap3 = {|}
// Replaces DB:pages:5:nav_hide with the nav_hide value
value.insertData = 1
equals = 1
}
}
The official TYPO3 Documentation explains how to create (or copy) and use a lib.dynamicContent to render columns into a Fluidtemplate.
I do not understand exactly whats going on in this example.
The TypoScript there is:
lib.dynamicContent = COA
lib.dynamicContent {
10 = LOAD_REGISTER
10.colPos.cObject = TEXT
10.colPos.cObject {
field = colPos
ifEmpty.cObject = TEXT
ifEmpty.cObject {
value.current = 1
ifEmpty = 0
}
}
20 = CONTENT
20 {
table = tt_content
select {
orderBy = sorting
where = colPos={register:colPos}
where.insertData = 1
}
}
90 = RESTORE_REGISTER
}
I use this snippet in a ton of TYPO3 projects and often had asked myself whats going on there.
I have changed this by experimenting a bit and ended with:
lib {
dynamicContent = COA
dynamicContent {
10 = CONTENT
10 {
table = tt_content
select {
orderBy = sorting
where {
data = field:colPos
wrap = colPos=|
}
}
}
}
}
That seems to do "exactly the same" thing - it outputs my content when called via cObject ViewHelper.
Can somebody explain if or why this is the worse way to render Content?
Here's the link to the lib.dynamicContent-doc: https://docs.typo3.org/c/typo3/cms-fluid-styled-content/master/en-us/Installation/InsertingContentPageTemplate/Index.html#based-on-the-fluidtemplate-content-object-cobj
Here you go!
you can try this,
# Clear out any constants in this reserved room!
styles.content >
# get content
styles.content.get = CONTENT
styles.content.get {
table = tt_content
select.orderBy = sorting
select.where = colPos=0
}
# Left Column
styles.content.getLeft < styles.content.get
styles.content.getLeft.select.where = colPos=1
# Right content
styles.content.getRight < styles.content.get
styles.content.getRight.select.where = colPos=2
Also, you can use variable in the fluid page object, check this out:
lib.pageTemplate = FLUIDTEMPLATE
lib.pageTemplate {
variables {
content = CONTENT
content {
table = tt_content
select.orderBy = sorting
select.where = colPos=0
}
contentRight = CONTENT
contentRight {
table = tt_content
slide = -1
select.orderBy = sorting
select.where = colPos=2
}
}
}
You can find out more here:
Adding the page content to a fluid template
Typo3 7.6 typoscript problems with markers
Hope this make sense, Cheer...!
You should look at this snippet together with some information about the Fluid view helper <f:cObject> which can be found here: https://docs.typo3.org/other/typo3/view-helper-reference/9.5/en-us/typo3/fluid/latest/CObject.html
As you can see there are the parameters data, currentValueKey and table that will be handed over to the typoscriptObjectPath, which is why the snippet makes perfect sense. The reason is, that it's a bit hard to put the different options into the where clause of the CONTENT object. So it increases readability and those registers can be easily extended.
So the register in this example is used to put in either the value of the data field colPos or if that is empty it will take the current value from the currentValueKey and if that is empty too it will fall back to a value of 0 to make sure the query won't produce an exception.
lib.dynamicContent = COA
lib.dynamicContent {
10 = LOAD_REGISTER
10.colPos.cObject = TEXT
10.colPos.cObject {
field = colPos
ifEmpty.cObject = TEXT
ifEmpty.cObject {
value.current = 1
ifEmpty = 0
}
}
20 = CONTENT
20 {
table = tt_content
select {
orderBy = sorting
where = colPos={register:colPos}
where.insertData = 1
}
}
90 = RESTORE_REGISTER
}
We used a modified version of that snippet to sneak in some more parameter values for the CONTENT object.
So we can hand over a data field pageUid, if that is not set we will use the uid of the current page. This will be overriden if the current or the target page is configured to show content from another page and finally we can trigger a slide with another data field.
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
}
}
20 = CONTENT
20 {
table = tt_content
slide = -1
slide.if.isTrue.field = slide
select {
includeRecordsWithoutDefaultTranslation = 1
orderBy = sorting
where = {#colPos}={register:colPos}
where.insertData = 1
pidInList.data = register:pageUid
pidInList.override.data = register:contentFromPid
}
}
90 = RESTORE_REGISTER
}
This enables us to make use of the <f:cObject> view helper while triggering additional parameters just by handing over some more values within the data array.
Although it seems so simple I only get one template in my FE. While the BE-layouts are working fine, I do not get any of my other FE-templates. Only the DefaultTemplate is popping up every time. After trying all kind of samples/ topics read, etc, I’m stuck on this. Here is my set-up.
The TSconfig and PageTS all other files are stored in the extension.
# Layout Select box for the FE templates
TCEFORM.pages {
layout.altLabels.3 = NewsLetterTemplate
layout.altLabels.2 = RedFooterTemplate
layout.altLabels.1 = DefaultTemplate
layout.altLabels.0 = DefaultTemplate
removeItems = 4,5,6,7,9,10
}
###########################################
# Config Fluid Template
page = PAGE
page.typeNum = 0
page.10 = FLUIDTEMPLATE
page.10{
#Path to the template files stored extension
partialRootPath = {$resDir}/Private/Partials
layoutRootPath = {$resDir}/Private/Layouts
file = {$resDir}/Private/Templates/DefaultTemplate.html
templateName = TEXT
templateName.stdWrap.cObject = CASE
templateName.stdWrap.cObject {
key.data = pagelayout
default = TEXT
default.value = {$resDir}/Private/Templates/DefaultTemplate.html
#Default template
pagets__DefaultTemplate = TEXT
pagets__DefaultTemplate.value = {$resDir}/Private/Templates/DefaultTemplate.html
#Second template
pagets__RedFooterTemplate = TEXT
pagets__RedFooterTemplate.value = {$resDir}/Private/Templates/RedFooterTemplate.html
#Third template
pagets__NewsLetterTemplate = TEXT
pagets__NewsLetterTemplate.value = {$resDir}/Private/Templates/NewsLetterTemplate.html
}
#Here some variables for use in the template by using {}
variables {
siteName = TEXT
siteName.value = PIZZAWORKSHOP.nl
pageTitle = TEXT
pageTitle.data = page:title
#get the content into the template:
content < styles.content.get
#Maincontent
content_main < styles.content.get
content_main.select.where = colPos = 0
#Content Colom 1
content_column_1 < styles.content.get
content_column_1.select.where = colPos = 1
#Content Colom 2
content_column_2 < styles.content.get
content_column_2.select.where = colPos = 2
}
}
https://pastebin.com/9TLytchv
Maybe one of you can point me into the right direction here? Thanks.
W.
You can add this typoscript Page TSConfig on resource tabe in page properties. For this typoscript you can rename defult frontend layout name.
TCEFORM.pages {
layout.altLabels.3 = NewsLetterTemplate
layout.altLabels.2 = RedFooterTemplate
layout.altLabels.1 = DefaultTemplate
layout.altLabels.0 = DefaultTemplate
}
For use different frontend layout like this.
[globalVar=TSFE:page|layout=3]
page.10.template.file = fileadmin/template/shinynewtemplate.html
page.includeCSS.screen = fileadmin/template/css/style.css
page.includeCSS.screen.media = screen
[global]
I'm building a site with Fluid Template. I have created two different front-end layouts and two different back-end layout but I always get this error #1288085266: No template has been specified. Use either setTemplateSource() or setTemplatePathAndFilename(). Accordingly to Typo3 Wiki this should be a solution Exception/CMS/1288085266
but not in my case. This is my code:
config.doctype = html5
page = PAGE
page {
includeCSSLibs.bootstrap = https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css
includeCSS.style = fileadmin/templates/rka2015/css/style.css
includeJSlibs.jquery = https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js
includeJSlibs.bootstrap = https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js
includeJS.custom = fileadmin/templates/rka2015/js/custom.js
}
page.10 = FLUIDTEMPLATE
page.10 {
file = fileadmin/templates/rka2015/layouts/main_layout.html
layoutRootPath = fileadmin/templates/rka2015/layouts/
patialRootPath = fileadmin/templates/rka2015/partials/
variables {
siteName = TEXT
siteName.value = rka2015
contentMain < styles.content.get
contentMain.select.where = colPos = 0
content_column_1 < styles.content.get
content_column_1.select.where = colPos = 1
content_column_2 < styles.content.get
content_column_2.select.where = colPos = 2
}
}
page.10.file.stdWrap.cObject = CASE
page.10.file.stdWrap.cObject
{
key.data = levelfield:-1, backend_layout_next_level, slide
key.override.field = backend_layout
default = TEXT
default.value = fileadmin/templates/rka2015/main_1_column.html
1 = TEXT
1.value = fileadmin/templates/rka2015/main_1_column.html
2 = TEXT
2.value = fileadmin/templates/rka2015/main_2_column.html
}
I have already checked all; section name is OK, ID for back-end layouts are ok, template is defined, everything seem to be as it should be. I really don't have a clue where else to search.
UPDATE!!!
Seems like there is a problem with a file path. I am running my site on a subdomain and it looks like that ts doesn't find the file paths if they are defined only as fileadmin/... Any thoughts? Thanks
SOLUTION!
page {
includeCSSLibs.bootstrap = https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css
includeCSS.style = fileadmin/templates/rka2015/css/style.css
includeJSlibs.jquery = https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js
includeJSlibs.jquery.external = 1
includeJSlibs.bootstrap = https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js
includeJS.custom = fileadmin/templates/rka2015/js/custom.js
}
page.10 = FLUIDTEMPLATE
page.10 {
template = CASE
template {
key.data = levelfield:-1,backend_layout_next_level,slide
key.override.field = backend_layout
1 = FILE
1.file = fileadmin/templates/rka2015/main_1_column.html
2 = FILE
2.file = fileadmin/templates/rka2015/main_2_column.html
}
partialRootPath = fileadmin/templates/rka2015/partials/
layoutRootPath = fileadmin/templates/rka2015/layouts/
variables {
siteName = TEXT
siteName.value = rka2015
contentMain < styles.content.get
contentMain.select.where = colPos = 0
content_column_1 < styles.content.get
content_column_1.select.where = colPos = 1
content_column_2 < styles.content.get
content_column_2.select.where = colPos = 2
}
}
First, check out if TYPO3 can read the file by overwriting the page object by appending this to the end of your template:
page.10 >
page.10 = FILE
page.10.file = fileadmin/templates/rka2015/layouts/main_layout.html
If that doesn't generate a page with the raw, uninterpreted output of your template file, then theres something wrong with either the file path or file permissions.
Secondly, in Fluid, Templates and Layouts are different things with different uses and should propably not be put into the same directory.
Most importantly, theres something wrong with the backend layout switch you're trying to build with the CASE in page.10.file.stdWrap.cObject . You see, the stdWrap object actually wraps around the text you've already set. If stdWrap cant find a pipe to figure out how to wrap, it just appends instead. Remove the line where you set the file in the top part and only leave the stdWrap case and you should be good to go.
at the first look it looks right... but check your file paths, maybe they are wrong as "Jost" commented.
i'm not sure but i think the problem is that the template path (file = ...) is the same as layout root path...
by the way... if you include external styles and javascripts you need to set something like the follows i think...
includeJSlibs.jquery = https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js
includeJSlibs.jquery.external = 1
This is what I want to do: on a given page, I want to display all content elements of the first child page of a given page. I cannot simply use a shortcut page, because I need to display other content elements after the ones from the sub-page. How can I do this?
Here is a snippet of how I think I could do it, but I don't know how to build the select. Is there a better way?
# save current content
tmp.pagecontent < page.10.subparts.main-content
# clear the content of the main column
page.10.subparts.main-content >
# build a new object for this column as content-object-array
page.10.subparts.main-content = COA
page.10.subparts.main-content {
10 = CONTENT
10.table = tt_content
10.select {
# what should I put here?
}
# re-insert the normal pagecontent to the page
20 < tmp.pagecontent
Just add answer for other people.
First : specify the first sub page of current page.
Second : get content elements that you want of that sub page.
temp.content = COA
temp.content {
10 = CONTENT
10 {
table = pages
select {
pidInList.field = uid
orderBy = sorting ASC
max = 1
begin = 0
}
renderObj = COA
renderObj {
10 = CONTENT
10 {
table = tt_content
select {
languageField = sys_language_uid
pidInList.field = uid
orderBy = sorting
#where = colPos = 10
}
stdWrap.wrap = |
}
}
}
}
I finally succeed! Not sure though it is the best way. What do you think about it? Should I put the second select into userFunc too?
fileadmin/userfunc/mailArchive.php
<?php
class user_mailArchive {
function getFirstChild($content, $conf) {
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'uid', // SELECT ...
'pages', // FROM ...
'pid='.intval($conf['pid']), // WHERE...
'', // GROUP BY...
'sorting', // ORDER BY...
'1' // LIMIT ...
);
$row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
if ($row) {
return $row['uid'];
}
else {
return '';
}
}
}
TS template
# fill the content of the main-column to a tmp.object
tmp.pagecontent < page.10.subparts.main-content
# clear the content of the main column
page.10.subparts.main-content >
includeLibs.mailArchive= fileadmin/userfunc/mailArchive.php
# build a new object for this column as content-object-array
page.10.subparts.main-content = COA
page.10.subparts.main-content {
10 = CONTENT
10 {
table = tt_content
select {
pidInList.cObject = USER
pidInList.cObject {
userFunc = user_mailArchive->getFirstChild
# parent page ID
pid = 139
}
orderBy = sorting
}
}
# re-insert the normal pagecontent to the page
20 < tmp.pagecontent
}