TYPO3 - how to properly define constant, store it into variable and use inside of fluid template - typo3

In the Fluid template of plugin I am working on, some things are hardcoded. For instance:
<f:else>
<li>
<v:page.link pageUid="114" />
</li>
</f:else>
Since pageUid values are not same on test and production server I would like to make this more dynamic.
I would like to store this somehow in variable and then use the variable in the fluid template.
I just dont know hot to make this and where in TYPO3.
Thanks in advance!

Because it is an setting do it like this:
Constants:
plugin.myext.settings.detailPid = 123
Setup:
plugin.myext.settings.detailPid = {$plugin.myext.settings.detailPid}
Variables are for variable content. If you have the same PID using variables with TEXT or similiar is overdressed and settings are the correct way.
Also variables are only accessable for FLUID_TEMPLATE content element, not for plugins!
Also in your extbase controller you can access these settings by simple access $this->settings['detailPid']without to render the cObjects first.
In your fluid you can access settings by {settings.detailPid}.

In typoscript template for your content object FLUIDTEMPLATE:
Typoscript setup/configuration:
10 = FLUIDTEMPLATE
10 {
variables {
pageUid = TEXT
pageUid.value = 114
}
}
or using constants
Typoscript constants:
pageUid = 114
Typoscript setup/configuration:
10 = FLUIDTEMPLATE
10 {
variables {
pageUid = TEXT
pageUid.value = {$pageUid}
}
}
Then you can fetch pageUid in your Fluid HTML
<f:else>
<li>
<v:page.link pageUid="{pageUid}" />
</li>
</f:else>
To use variables in a Fluid partial, make sure to pass these along, e.g. by providing _all:
<f:render partial="fluid_part_header" arguments="{_all}" />

If you use EXT:vhs anyways, you can do the following to:
TS-Constants:
pageUid=114
TS-Setup:
settings.pageUid = {$pageUid}
Template (Fluid)
<f:else>
<li>
<v:page.link pageUid="{v:variable.typoscript(path: 'settings.pageUid')}" />
</li>
</f:else>
This will make it available for all FLUID Templates.

Please consider using jokumer's solution.
randomresult's solution would work, but I wouldn't suggest it. You don't need vhs to pass variables.
Not talking about Paul Beck`s solution, because it wouldn't work at all. Not anymore at least. (See TYPO3\CMS\Fluid\ViewHelpers\CObjectViewHelper, https://docs.typo3.org/typo3cms/ExtbaseGuide/Fluid/ViewHelper/CObject.html). It accepts only content objects.
Set your Pid in constants like PID_SOME_PAGE = 123 and set a variable in your plugins settings. Like this:
plugin.tx_yourplugin {
...
settings{
somePage = {$PID_SOME_PAGE}
}
...
}
You can bypass that constants version if you want and set your page id in settings directly. It's just a cleaner way in my opinion, especially for larger websites.
Then you can use that variable in your template, like this <f:link.page pageUid="{settings.somePage}">Go to Page</f:link.page>. More options for f:link.page here: https://docs.typo3.org/typo3cms/ExtbaseGuide/Fluid/ViewHelper/Link/Page.html

Related

news: Different settings via typoscript for multiple listviews on one page

Using the extension news I implemented three list views on one page with different colPos. Now I need to make some different settings for each list view. I would prefer doing this via TypoScript.
Is there a solution for this?
Many thanks and best regards!
It really depends which settings you need. One easy solution could be something like thins
plugin.tx_news.settings {
mainCol {
setting = abc
}
leftCol {
setting = def
}
}
and in the fluid templates
<f:if condition="{contentObjectData.colPos} == 3">
<f:then><f:variable name="mySettings">{settings.mainCol}</f:then>
<f:else><f:variable name="mySettings">{settings.leftCol}</f:else>
</f:if>
<f:render section="list" arguments="{_all}" />
<f:section name="list">
... do your stuff here
{mySettings -> f:debug(inline:1)}
</f:section>

Render overridden fluid template

I want to override an extension's fluid template in Typo3 with my own template. My own template contains an if-condition. If not met, I want to include/render the extension's template (i.e. the overridden template) instead.
The actual case: I'm using the Typo3 News Extension which allows custom "template layouts". I want to add my custom template layout but also keep the News Extension's default template:
<!-- my_site_package/Resources/Private/Extensions/News/Templates/News/List.html -->
<f:if condition="{settings.templateLayout} == 2">
<f:then>
My specific list view for news entries
<ul>
<li>
...
</li>
</ul>
</f:then>
<f:else>
<!--
Include the original template here, e.g.
EXT:news/Resources/Private/Templates/Styles/Twb5/Templates/News/List.html
-->
</f:else>
</f:if>
How can I include / render the overridden template itself?
Fluid Is not able to Render the "Original Template" as there might be any number of TemplateRootpaths providing the Template. what you could do:
if the original Template is Part of an extension you controll, best to move the "Repeating" parts to an Partial. and let the Original Template use this partial as well.
if the original template is part of an extension you do not controll. (eg by a third party) you should copy the orignal template as partial in your Extension and then render this Partial. maybe ad a comment that this is an 1:1 copy of the original and shoud not be modified.
You can create another template layouts using page TSConfig, Define this TS in your root Page TSconfig (inside Resources) Tab.
plugin.tx_news {
templateLayouts {
1 = Homepage
2 = Specific list
}
}
then in your template you will get selected template value here in case 1 or 2.
You will find more help here.
https://docs.typo3.org/p/georgringer/news/main/en-us/Reference/TsConfig/General.html#confval-templateLayouts

Display full name of logged in TYPO3 frontend user in Fluid

The task is pretty simple: I want to display the full name (first- and lastname) of the current TYPO3 frontend user in Fluid. But somehow, TYPO3 (version 9.5) or Fluid seems to cache data, so a logged in frontend user sometimes sees the name of other another logged user.
Current implementation:
TypoScript:
lib.username = USER_INT
lib.username.userFunc = Vendor\Extension\UserFunc\Username->getUsername
This is a USER_INT, so the output should always be uncached.
Fluid Layout - Default.html:
<f:render partial="Header" section="Top" />
Fluid Partial - Header.html:
<f:section name="Top">
<img src="logo.png">
<f:render partial="Navigation" />
</f:section>
Fluid Partial - Navigation.html
<f:security.ifAuthenticated>
<f:then>
<p>Logged in as: <f:cObject typoscriptObjectPath="lib.username" /></p>
</f:then>
<f:else>
<p>Not logged in</p>
<f:else>
</f:security.ifAuthenticated>
Why does the result of the cObject get cached? Should'nt this always be calculated per request, because lib.username is a USER_INT? I also tried to add a f:cache.disable ViewHelper to the template with no success.
In order to resolve the problem I refactored it to fetch the full name of the fe_user using a JavaScript XHR request to a simple PSR-15 middleware. Is this really the only suitable solution or am I missing something?
Update 17.12.2020
This all works fine. I just spotted a typo in my userFunc, which resulted in the unexpected behavior.
This happens because TYPO3 cache works with frontend user groups, not frontend users. So you will see results cached for the list of user's groups rather than the current user.
Use <v:render.uncache> ... </v:render.uncache> from EXT:vhs to render that part of code uncached. Alternatively you can modify TYPO3 caching to use the current user but this may decrease cache performance and seriously increase amount of cached items.
Beware, that there is a caching problem even with USER_INT and COA_Int see https://forge.typo3.org/issues/37988
You could use only TypoScript for that like:
lib.username = COA_INT
lib.username {
10 = TEXT
10.data = TSFE:fe_user|user|first_name
10.wrap = |
20 = TEXT
20.data = TSFE:fe_user|user|lastname_name
}
Why use TypoScript? It is very limited on what it can bring back. I just finished a tutorial where you can use a ViewHelper to add an ExtBase variable which assigns the whole user object in the FrontEnd and you can use it wherever you want with all it's relations, even the image, which is difficult to get via TypoScript.
TYPO3 tutorial
Best regards
share edit delete flag

How to implement multilingual labels in tx:mask (TYPO3)?

I would like implement multilingual labels in TYPO3 mask. After implementing with the following FLUID-code the label does not change based on the chosen language:
<f:link.page pageUid="{data.tx_mask_inhalt_text_link}">
<f:if condition="{TSFE.sys_language_uid} == 1">
<f:then>
enter code here`Read more
</f:then>
<f:else>
Weiterlesen
</f:else>
</f:if>
</f:link.page>
I solved the issue with:
MASK-Template:
<f:translate key="label" />
TYPO3-Setup:
plugin.tx_mask._LOCAL_LANG.de.label = Weiterlesen
plugin.tx_mask._LOCAL_LANG.en.label = Read more
Works like a charm.
You can use XLIFF files to localize values in TYPO3. This is neither limited to nor different for mask templates (as these are common Fluid templates).
A locallang.xlf contains entries like:
<trans-unit id="readmore">
<source>Read more</source>
<target>weiterlesen</target>
</trans-unit>
In the HTML template you can use the f:translate viewhelper:
<f:translate key="LLL:EXT:your_extension/Resources/Private/Language/locallang.xlf:readmore" />
This will render the value depending on the current frontend language.
This is the usual way of translating in TYPO3. Please refer to these official documentations for all details:
XLIFF | TYPO3 documentation
f:translate | Fluid guide

Is it possible to set by fluid a argument that the typo3 backend uses as input

In the typo3 template I'm using the following line to get the last 5 added items from the backend and this works.
<f:cObject typoscriptObjectPath="lib.lastaddeditmes" />
Only the number of item I want to have it flexible and set in the fluid template. So for example like below where the qty is set to three, is this possible?
<f:cObject typoscriptObjectPath="lib.lastaddeditmes(3)" />
You can't do that in the view, instead you can make a copy of lib.lastaddeditmes in TypoScript and then use it in other place like:
lib.lastaddeditmesOnlyThree < lib.lastaddeditmes
lib.lastaddeditmesOnlyThree.someSetting.items = 3
and in view:
<f:cObject typoscriptObjectPath="lib.lastaddeditmesOnlyThree" />
Remember that TypoScript is just a configuration syntax (not programming language) so it shouldn't give you any huge performance drop.