I'm a bit new to fluid and I want to make a the following php statement in Fluid.
if ($var == 'something') {
// do something
} elseif ($other-var == 'something else') {
// do something else
} else {
// do then the other thin
}
How can I make this in Fluid? I don't see the elseif statement in the documentation.
Since TYPO3 8LTS
Since version 8 TYPO3 uses the standalone version of fluid, that was heavily developed and got tons of new features like elseif:
<f:if condition="{var} == 'something'">
<f:then>do something</f:then>
<f:else if="{other-var} == 'something else'">do something else</f:else>
<f:else>do the other thing</f:else>
</f:if>
In addition there is support for syntax like this:
<f:if condition="{something} || {someOtherThing}">
Something or someOtherThing
</f:if>
Until and including TYPO3 7LTS
With Plain Fluid you can nest two if ViewHelper:
<f:if condition="{var} == 'something'">
<f:then>
// do something
</f:then>
<f:else>
<f:if condition="{other-var} == 'something else'">
<f:then>
// do something else
</f:then>
<f:else>
// do then the other thing
</f:else>
</f:if>
</f:else>
</f:if>
Or you could implement your own ViewHelper or use a ViewHelper Library like VHS that have a ViewHelper that does this more elegant.
There's a possibility for AND and OR in Typo3 7 LTS:
http://typo3blogger.de/fluid-ifviewhelper-conditions-verknupfen/
AND:
<f:if condition="{0: value1, 1: value2} == {0: myValue1, 2: myValue2}">
<!-- your code-->
</f:if>
OR (in the example for checking that at least one variable is not null):
<f:if condition="{0: value1, 1: value2} != {0: 0, 2: 0}">
<!-- your code-->
</f:if>
Hope that helps someone.
Is there an inline notation für 'else if'?
This one is not working:
{f:if(condition: '{value} == 1', then: 'Value is 1', else if: '{value} == 2', then:'Value is 2')}
Related
I have a TYPO3 9.5.0LTS and use the bootstrap package theme. It seems to be all working ... except ... when I add a link (internal or external) to a carousel item ... nothing gets rendered. The other elements come out fine.
I looked in the CalltoAction.html ... and found out that pageUid of f:link.page is not reading t3://page?uid=80.
When I {records} ... I get link => 't3://page?uid=80' (16 chars)
And when I test in CalltoAction.html:
<p>{item.data.link}</p>
<f:if condition="{item.data.link}">
<f:link.page pageUid="1" class="carousel-item-button btn btn-primary" additionalAttributes="{draggable:'false'}">
<f:if condition="{item.data.button_text}">
<f:then>
<span>{item.data.button_text}</span>
</f:then>
<f:else>
<span><f:translate key="readmore" extensionName="bootstrap_package" /></span>
</f:else>
</f:if>
</f:link.page>
</f:if>
<f:if condition="{item.data.link}">
<f:link.page pageUid="{item.data.link}" class="carousel-item-button btn btn-primary" additionalAttributes="{draggable:'false'}">
<f:if condition="{item.data.button_text}">
<f:then>
<span>{item.data.button_text}</span>
</f:then>
<f:else>
<span><f:translate key="readmore" extensionName="bootstrap_package" /></span>
</f:else>
</f:if>
</f:link.page>
</f:if>
I get the following result in the FE:
<p>t3://page?uid=80</p>
<a draggable="false" class="carousel-item-button btn btn-primary" href="/"><span>Read more</span></a>
<span>Read more</span>
So pageUid of f:link.page not reading t3://page?uid=80
How can I solve this?
the f:link.page-VH expects an integer (uid) in the parameter pageUid.
t3://page?uid=80 by way is no integer but a string. A special string which can be handled by the f:link.typo3link-VH
Currently I have this code that wraps every 2 items with <li></li>
<f:for each="{modules}" as="module" iteration="loop">
<f:cycle values="{0: 1, 1: 0}" as="header">
<li>
</f:cycle>
...stuff here...
<f:cycle values="{0: 0, 1: 1}" as="footer">
</li>
</f:cycle>
</f:for>
Lets say {modules} = [A,B,C,D] and output is something like this:
<li>AB</li>
<li>CD</li>
What I need to do is add custom html to the second position. So my desired output is:
<li>AX</li>
<li>BC</li>
<li>D</li>
How can I do this?
To your updated question I would say, you may want to solve this issue with your own Helper class before adding modules to the View through the Controller.
It is however possible to build it simple in the template:
Here is the documentation about the for ViewHelper.
For simplicity I would do the following:
<f:for each="{modules}" as="module" iteration="loop">
<f:if condition="{loop.isFirst}">
<f:then>
<li>
{module}
##extra_code##
</li>
</f:then>
<f:else>
<f:if condition="{loop.isEven}">
<li>
</f:if>
...stuff here...
<f:if condition="{loop.isOdd} || {loop.isLast}">
</li>
</f:if>
</f:else>
</f:if>
</f:for>
Note: The first element will be "odd" because isOdd takes the current interation (based on "cycle"), which starts with 1.
For the first element there is your own block. You can take the first module and write your own code. It will run only once.
From the second element to the last it will use the 2 element in one li logic. Here is only one interesting thing, that we need take isOdd OR isLast to always close the last li, even if you have an even number of elements.
You can do this like below.
<f:for each="{modules}" as="module" iteration="iteration">
<f:if condition="{iteration.isFirst}">
<f:then>
<li>
</f:then>
<f:else>
<f:if condition="{iteration.index}%2">
<f:then></f:then>
<f:else><li></f:else>
</f:if>
</f:else>
</f:if>
<!--
Here Your Content
-->
<f:if condition="{iteration.isLast}">
<f:then>
</li>
</f:then>
<f:else>
<f:if condition="{iteration.cycle}%2">
<f:then></f:then>
<f:else></li></f:else>
</f:if>
</f:else>
</f:if>
</f:for>
How can I check if a page has a specific ID, and if true output a text?
I thought about something like this (pseudocode):
<f:if condition="{current.page.uid}=='78'">
<p>I am Page 78</p>
</f:if>
If you want to use this in an FLUIDTEMPLATE (page.10 = FLUIDTEMPLATE as example) you can access the page data with {data.uid}.
<f:if condition="{data.uid} == 78">
<p>I am Page 78</p>
</f:if>
In an extbase Extension you can make it like #dimitri-l says.
You can fetch current page ID via typoscript object
typoscript:
lib.currentPageId = TEXT
lib.currentPageId.data = TSFE:id
FLUID:
<f:if condition="{f:cObject(typoscriptObjectPath:'lib.currentPageId')}==78">
<p>I am Page 78</p>
</f:if>
You can make a variable into your "page TS setup" like here :
variables {
pageUid = TEXT
pageUid.field = uid
...
}
So you can make your fluid condition as here :
<f:if condition="{pageUid}=={settings.homepid}">
<p>I am Page 78</p>
</f:if>
for exemple...
You would need to pass the page id to the fluid template. If you are using an Extbase controller you can pass $GLOBALS['TSFE']->id to your view and then use an if condition as you did.
$this->view->assign('pageId', $GLOBALS['TSFE']->id);
I am not sure if it is already possible to do string comparison in Typo3 6.2, if not, you have to compare it that way:
<f:if condition="{0:pageId} == {0:'78'}>
...
</f:if>
Otherwise this is a clean solution for current versions
<f:if condition="{pageId} == '78'>
...
</f:if>
With the VHS viewhelper you can do it with fluid only, no need for a Typoscript helper:
{namespace v=FluidTYPO3\Vhs\ViewHelpers}
<f:if condition="{v:page.info(field: 'uid')} == '21'">
<f:then>
Shows only if page ID equals 21.
</f:then>
</f:if>
Sometimes you need to give a link a class when the link target is the current page (here: uid=1). The inline version helps:
<f:link.page pageUid="1"
class="{f:if(condition: '{data.uid} == 1', then: ' current')}">
Link
</f:link.page>
I have a typoscript TEXT object:
lib.myid = TEXT
lib.myid.value = 1413
And want to use it in a fluid template (for tx_news):
<f:for each="{newsItem.categories}" as="category">
<f:if condition="{category.uid} == {lib.myid}">
Category ID is the same as myid
</f:if>
</f:for>
How can I do this?
You can use the ViewHelper f:cObject. It would look like this:
<f:for each="{newsItem.categories}" as="category">
<f:if condition="{category.uid} == {f:cObject(typoscriptObjectPath: 'lib.myid')}">
Category ID is the same as myid
</f:if>
</f:for>
Alternatively, you can make the value a setting of the news plugin, by setting
plugin.tx_news {
settings {
valuefromlibrary < lib.myid
}
}
Afterwards, you can access the value using {settings.valuefromlibrary} in your template. But beware that the settings are not automatically passed on to partials, so in a partial the value might not be defined. This restriction is circumvented in the default template of EXT:news by passing the settings-variable to partials.
I define an array in my extensions setup.txt typoscript like so:
settings{
halls {
0 = Default
1 = Mississauga
2 = Halifax
3 = Niagara Falls
4 = Oakville
5 = Pickering
}}
how in my fluid template can I find the length of the halls array? I want an if condition to do one thing if length is greater than 1 and another if not.
I am using typo3 v4.5.32 with extbase 1.3.
Thank you.
I tried this but it puts out two <th> tags instead of just one. The first if is meant to prove that there is more than one element, the next is meant to print out a <th> only if it is the first element.
<f:for each="{settings.halls}" as="hall" key="number" iteration="itemIteration">
<f:if condition="{itemIteration.isFirst != itemIteration.isLast}">
<f:if condition="{itemIteration.index == 0}">
<th>
<f:translate key="tx_bpscoupons_domain_model_coupon.hall" />
</th>
</f:if>
</f:if>
</f:for>
Why?
UPDATE: here is my work around for a lack of "is array length > 1" ferature in fluid
<f:for each="{settings.halls}" as="hall" key="number" iteration="itemIteration">
<f:if condition="{itemIteration.isFirst}">
<f:then>
<f:if condition="{itemIteration.isLast}">
// if both first and last there is only one so skip
</f:if>
</f:then>
<f:else>
<f:if condition="{itemIteration.isLast}">
//if there is more than one element in halls then eventually you'll get here once so print out th tags
<th>
<f:translate key="tx_bpscoupons_domain_model_coupon.hall" />
</th>
</f:if>
</f:else>
</f:if>
</f:for>
and to print out data:
<f:for each="{settings.halls}" as="hall" key="number" iteration="itemIteration">
<f:if condition="{itemIteration.isFirst}">
<f:then>
<f:if condition="{itemIteration.isLast}">
<f:then>
</f:then>
<f:else>
<f:if condition="{number} == {coupon.hall}">
<td>{hall}</td>
</f:if>
</f:else>
</f:if>
</f:then>
<f:else>
<f:if condition="{number} == {coupon.hall}">
<td>{hall}</td>
</f:if>
</f:else>
</f:if>
</f:for>
ugly but seems to work.
UPDATE 2 :
DOH!!! I missed total, just what I needed but I was looking for length or count, so this code is what I want:
<f:for each="{settings.halls}" as="hall" key="number" iteration="itemIteration">
<f:if condition="{itemIteration.total} > 1">
<f:if condition="{itemIteration.isLast}">
<th><f:translate key="tx_bpscoupons_domain_model_coupon.hall" /></th>
</f:if>
</f:if>
</f:for>
You can find a length of an array with the f:count ViewHelper. Just like other ViewHelper it can be used as an inline notation (You can find more here)
The correct code would be:
<f:if condition="{settings.halls -> f.count()} > 1">
<f:then>
//your code for then
</f:then>
<f:else>
//your code for else
</f:else>
</f:if>
<f:if condition="{f:count(subject: settings.halls)} > 1"> do something </f:if>
see update#2 above for the answer. to reiterate:
<f:for each="{settings.halls}" as="hall" key="number" iteration="itemIteration">
<f:if condition="{itemIteration.total} > 1">
<f:if condition="{itemIteration.isLast}">
<th><f:translate key="tx_bpscoupons_domain_model_coupon.hall" /></th>
</f:if>
</f:if>
</f:for>
For those of you who are looking for a custom viewhelper for this:
class ArrayCountViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
/**
* Get array count
*
* #param mixed $array
* #return string
*/
public function render($array) {
if (!is_array($array))
return 0;
return count($array);
}
}