TypoScript Conditions with Literals - typo3

I am experiencing a strange behaviour. I have a TYPO3 7.6.18 and a TS condition like shown on https://docs.typo3.org/typo3cms/TyposcriptReference/Conditions/Reference/Index.html#id45
Constants:
testswitch = 1
Setup:
testvar = {$testswitch}
[globalVar = LIT:1 = {$testswitch}]
testvar = 99
[global]
I expect testvar to be 99, but instead it is 1 (checked via TypoScript Object Browser). Any explanation? What am I doing wrong? Is this a TYPO3 bug?

In the TypoScript Object Browser is a list of conditions at the bottom. You have to actually activate the specific condition, for it to take effect, otherwise it won't show up as expected in the tree.
Edit addition: That also means that testing conditions in the Object Browser does not necessarily help. Setting the checkbox will evaluate the condition as true, regardless of whether the condition would actually be true if evaluated normally in frontend.

Related

Typo3 v10: Fix Translated ContentElements within Gridelements with language=all

I'm using Typo3 10.4.28 with gridelements 10.4.3 (not w/DataProcessing)
To minimize redundancy in a Multilanguage-Site I set Content Elements (CE) without own Text-Content to language=all and translate only CEs with Text.
It feels very logical and useful to me, to set language=all on gridcontainers (where I'm not using its title or other own text-fields), to be able to set contained Plugins, Menu-Elements and Images to Language=all, even if it also includes a translated Text-CE
(and I have seen this done in a Typo3 with gridelements where I have only regular backend access and don't know exactly how they achieved that).
But when translating CEs within language=all gridelements, this is not rendered correctly in the frontend on the translated page.
Translated CEs are either rendered twice (fallbacktype: strict/fallback) or all language versions are rendered (fallbacktype: free).
According to gridelements maintainer #Jo Hasenau, putting translated elements into language=all containers is not supported directly with unmodified gridelements.
Thanks to his comments I found a setup which (while hacky) works more or less:
fallbacktype: free
[siteLanguage("languageId") == 1]
lib.gridelements.defaultGridSetup.columns.default.renderObj.20.stdWrap.if {
isInList.field = sys_language_uid
# -1 is language=all
value = -1,1
}
[GLOBAL]
# allows only content in the correct language or "all"
# repeat for each other languageId
I found a problem with this setup though: in free-mode, translated elements get ordered in frontend based on their own "sorting" instead of their original element's. This means, translated elements might switch places with Language=all elements, compared to the default language. Fixing this in (translated) content would be a big hassle on a large site.
So I tried to find a fix for fallbacktype: strict
(where "you get the original element with a translation overlay and after that the translation itself")
lib.gridelements.defaultGridSetup.columns.default.renderObj.20.stdWrap.if {
isFalse.field = l18n_parent
}
I hoped this would exclude only "the translation itself", but sadly it also excluded the "translation overlay". In fact both seem to be identical to typoscript at this point.
Update:
A pure TS-Solution for strict and fallback is found, and my above solution for free technically works as well (free is just not suitable), so this case seems closed.
A small word of warning for anyone who wants to use this structure, though:
sys_language_uid -1, aka Language All might be removed from Typo3 in upcoming versions:
https://decisions.typo3.org/t/rethinking-translation-handling-based-on-a-session-of-t3cmd-2022/734/16
As discussed in the Gridelements issue tracker, you should go for strict or fallback mode, since free can not work by definition.
Still your approach with strict is wrong, since you don't have to include the target language records, but only default language records or those that got language all but after the translation overlay.
This overlay will add a virtual field named _LOCALIZED_UID
Reason: Both strict and fallback use overlays to render their content, and since there always is a record of the default language available, this will be the one to fetch, while the content will then be overlaid.
So the solution should be:
[siteLanguage("languageId") > 0]
lib.gridelements.defaultGridSetup.columns.default.renderObj.20.stdWrap.if {
isFalse.field = _LOCALIZED_UID
value = -1
isGreaterThan.field = sys_language_uid
negate = 1
}
[GLOBAL]
Without additional conditions, since it will be the same for any target language.
To explain the Syntax you need to know, that the TypoScript if-conditions only know AND but not OR, so if you want the result of an OR condition you need to negate the opposite AND condition, which is what the snippet does.
It checks for a non existing _LOCALIZED_UID and the language of the record being greater than -1 - and if this is both true, it will negate the result. If any of the conditions is false, the negated result will be true.
Basically this is the same behaviour as with pages, which are kind of top level containers themselves.
If you want just one single element of that page to be translated, you need to create a translated page record before. So having a page with the "language => all" behaviour will only work together with a properly configured fallback, if there is no translated content on that page at all.
So you don't have to switch the frontend rendering TS template, but just follow the rule you already described.
I set Content Elements (CE) without own Text-Content to language=all
and translate only CEs with Text
Since a Gridelements container is a CE and the child elements are basically content of that CE, just as with pages you always have to translate a container element as soon as it contains at least one translated element.
So language "all" should only be applied to containers that don't contain any translated child element at all.

TYPO3, news: change sort order and direction via get parameter

in a list view of extension news we need links which change the sort order and the sort direction. Is there a possibility to change both via get parameters?
I unchecked the option "Disable override demand" and tried some combinations like
?tx_news_pi1[orderDirection]=asc
?tx_news_pi1[settings][orderDirection]=asc
but this doesnt work.
Thanks!
tx_news_pi1[overwriteDemand][order]=title desc works for me
Maybe try:
tx_news_pi1[overwriteDemand][orderDirection]=asc
(while i am not really sure if orderDirection is correct, mayb check manual/code of that)
As far as I see there is no intuitive option to include sorting in the fluid-templates as all sorting is done on the level of TypoScript respectively FlexForm.
There are different options to enable sorting from frontend nevertheless:
In TypoScript you set the sorting-parameters depending on the current URL-parameters, the easiest way would be to solve it by conditions, also you'd be free to define own parameters without sticking to the news-API.
The URLs for sorting you should create in any case with a viewHelper that the cHash is always appended and calculated correct.
TypoScript:
#######
## Here you transfer the URL-parameters for sorting to the TypoScript-settings
## and also assure that only predefined values are accepted
#######
[globalVar = _GET|tx_news_pi1|orderBy = title]
plugin.tx_news.settings.orderBy = title
[globalVar = _GET|tx_news_pi1|orderBy = datetime]
plugin.tx_news.settings.orderBy = datetime
[globalVar = _GET|tx_news_pi1|orderBy = tstamp]
plugin.tx_news.settings.orderBy = tstamp
[globalVar = _GET|tx_news_pi1|orderBy = crdate]
plugin.tx_news.settings.orderBy = crdate
[global]
[globalVar = _GET|tx_news_pi1|sort = desc]
plugin.tx_news.settings.orderDirection = desc
[else]
plugin.tx_news.settings.orderDirection = asc
[global]
Fluid:
<f:link.action action="list" addQueryString="&tx_news_pi1[orderBy]=title&tx_news_pi1[sort]=asc">Sort by title: asc</f:link.action>
<f:link.action action="list" addQueryString="&tx_news_pi1[orderBy]=title&tx_news_pi1[sort]=desc">Sort by title: desc</f:link.action>
This solution is not tested and it might be required still to adjust some things but in general it should be working.
Cache-related issues are considered the same as with news-records in general, at least related to any required settings.
Sorting by further fields requires further steps as stated here:
https://docs.typo3.org/typo3cms/extensions/news/DeveloperManual/ExtendNews/ExtendFlexforms/Index.html#selectbox-sort-by
Other individual solutions require programming in PHP and can base on hooks as well as on signals, the news-manual includes several chapters that might be useful:
Signals
Hooks
Extension based on EXT:news
Furthermore it might be possible that there exist extensions that solve the sorting-job already but I'm not aware of it. You could search for news-related extensions. I could imagine that eventnews or dataviewer could be useful perhaps but I never checked that out and these extensions never might be useful at all for it.
Also it's possible that you discover another useful extension on further search. If so, let us know ;-)
Then there is still the option that somehow the desired behavior can be solved different, perhaps it's not or bad documented or I missed it.
Consider that you probably still have to tweak a bit if you use pagination and especially AJAX based pagination.
I found the reason for the problem and a work around.
the reason is the default sorting in the flexform: sorting by title. The GET-Parameter orderBy cannot overwrite the default sorting in the flexform. If you choose a default sorting in the flexform the orderBy parameter ist ignored but the orderDirection parameter works as expected. The result is confusing but consistent: the content ist always sorted by the default sorting but with different sortOrders.
After deleting the default sorting in the flexform all works as expected.
I presume this is a kind of a bug; i will post a question in the bug tracker of news.

Prevent TypoScript from cascading?

I have this in nearly every project: TypoScript cascades to child nodes in the pagetree by default. If you want to prevent it from being applied to child nodes, one solution is to create an extra TS template that undoes it and include it as "template on next level".
E.g. you want to apply some TS to a specific parent page, but not it's children:
temp.somemenu.wrap = **|**
Apart from the "template on next level" approach, solutions/hacks include:
if you know which level you start from:
[treeLevel = 2]
temp.somemenu.wrap = **|**
[global]
If you have the pid and want to wire it in a constant:
[page|uid = {$targetPagePid}]
temp.somemenu.wrap = **|**
[global]
EDIT: adapted to constant – this is quite a robust solution!
Isn't there some switch to make a TS setting NOT cascade? Or define the number of levels it can cascade to?
Something like
<INCLUDE_TYPOSCRIPT: source="path/to/my.ts" treeLevelsDown="0">
or
[global treeLevelsDown = 0]
temp.somemenu.wrap = **|**
[global]
This would mean that the TS is kind of self-aware, knowing on which tree level it has been set. Not sure if that's even possible.
Does it make sense?
Or am I missing some existing solution?
No, this does not work any other way than those you already mentioned in your question. The reason for this is, that TYPO3 start from a page and the looks upwards the page tree, until it finds a TypoScript template. (It collects all extension templates on the way and applies them on top of the first found root template).
Therefore it never goes down, but only up. If it would stop cascading after a certain level, what should be used as TypoScript template for those sites? It still needs a configuration to render the page.
The question is theoretical, and #pgampe answers it.
About my use case, here's the solution from #bernd-wilke-πφ, which works just fine
// just apply to page references
[page|uid = {$pidReferencesList}]
// add some additional js (a list filter)
page.includeJSFooter {
refs = {$templatePath}/Resources/Public/additional_js/references.js
}
// add some markup
lib.thecontent.wrap = <div id="items-list-wrapper">|</div>
[global]

Typoscript Condition: backend_layout (with slide)

I use this condition
[globalVar = GP:colPos==0]&&[page|backend_layout = pagets__MainTemplate]
My problem is that my „subpage“ has no backend_layout selected because the parent pages "Backend Layout (subpages of this page)“ is set. So the condition does not work on subpages.
Can create a condition like that?
lib.backendLayout = TEXT
lib.backendLayout {
data = levelfield:-1, backend_layout_next_level, slide
override.data = TSFE:page|backend_layout
}
I want do white/blacklist CTypes in BE Columns in this way:
[globalVar = GP:colPos==0]&&[page|backend_layout = pagets__MainTemplate]
TCEFORM.tt_content.CType.keepItems := addToList(header)
[end]
Not as far as I know, as you can only access the current page record with the "page" condition.
Instead you could
a) Write your own condition (see https://docs.typo3.org/typo3cms/TyposcriptReference/8.7/Conditions/Reference/Index.html#custom-conditions or starting with version 9 https://docs.typo3.org/typo3cms/TyposcriptReference/Conditions/Reference.html#extending-the-expression-language-with-own-functions-like-old-userfunc)
b) Use a userFunc (like "a" only older and less fancy ;)) - see https://docs.typo3.org/typo3cms/TyposcriptReference/8.7/Conditions/Reference/Index.html#userfunc
new c) follow Jigals suggestion (or use a similar extension - there are a few - but they mostly do a lot more than what you need)
--- EDIT after question update ---
As you want it working in TSConfig c) is actually not an option.
c) depending on what you actually want to achieve with your condition use if and data (like in your description) directly at the TS objects that should have different behavior if your condition is true.
For reference:
Differences between TSConfig Conditions and TS Conditions:
https://docs.typo3.org/typo3cms/TSconfigReference/8.7/Conditions/Index.html#differences-to-conditions-in-typoscript-templates
As an alternative to Susi's solutions you could use Gridelements. This extension has the feature that you can set inside each block in a backend layout which CEs are allowed.

TYPO3 V7.6, default value for Number of Columns

How is it possible to set in Page TSConfig the default value for "Number of Columns" in TYPO3 V7.6? In erlier versions it was possible with TCEFORM.tt_content.imagecols = 1. If I set in V7.6 TCEFORM.tt_content.imagecols = 1 it makes no different which value is set. There is always imagecols = 2 set.
I have PHP 7.0.7 and use the rendering extension fluid_styled_content (not css_styled_content). Is there something I am missing?
Thanks in advance for your help.
TCAdefaults.tt_content.imagecols = 1
works for me in TYPO3 7.6.11
TCEFORM.tt_content.imagecols.config.default = 1 is not working, as described op.
Be aware: This config never works if you switch content type after saving a content:
https://forge.typo3.org/issues/75233