Render image in fluid template if it exists? - typo3

How can I use f:ifto see if an image exists before trying to render it?
I have tried the following without success:
{f:if(condition: page.files.0, then: ' style="background-image:url({f:uri.image(image:page.files.0, width:300c, height:200c)}"')}
<f:if condition="{page.files.0}">
style="background-image:url({f:uri.image(image:page.files.0, width:300c, height:200c)}"
</f:if>
It works if there is an image but breaks the element when there is not.

When I want to add an image url to the style attribute, I usually do something like this:
<f:if condition="{page.files.0}">
<f:variable name="imageUri" value="{f:uri.image(
image: page.files.0,
width: '300c',
height: '200c')}"/>
</f:if>
<div style="background-image: url('{imageUri}');">
...
</div>
That would simply leave it empty in case the image does not exist. Though I often have an "else" case, where I use one of my custom viewhelpers to generate a placeholder image.

Related

Check if linked page with typolink is hidden or not

<f:link.typolink parameter="{mylink"> links to a internal page- when this page is hidden / not visible in backend no is set.
This breaks my html:
Instead of
<div class="mylink">
my text
</div>
I get
<div class="mylink">my text/div>
Is there a way to check if the linked page is visible / not hidden?
You can use the f:uri.typolink viewhelper to check if the resulting URI is empty or not and then generate the link with f:typolink as normal:
<f:if condition="{f:uri.typolink(parameter: mylink)}">
<f:link.typolink parameter="{mylink}">my text</f:link.typolink>
</f:if>
If you do not care about attributes set in {mylink}, e.g. class or target you can reuse the already generated URI:
<f:alias map="{uri: '{f:uri.typolink(parameter: mylink)}'}">
<f:if condition="{uri}">
my text
</f:if>
</f:alias>

Want to change a logo with an if/then condition

I want to select a logo depending on a check box of a page property I have added via extension. The variable selectcompany is shown correctly when dumping the variables.
I am running Typo3 8 LTS.
obj.logo {
<f:if condition="{field:selectcompany}==1">
<f:then>
file = fileadmin/template/private/images/Logo1.png
</f:then>
<f:else>
file = fileadmin/template/private/images/Logo0.png
</f:else>
</f:if>
}
Although the variable is set correctly, always Logo0.png is displayed. When the variable is set to 1, I expected Logo1.png.
If this is a TypoScript snippet, you can not fill in a Fluid condition there, but have to make use of the TypoScript variant of an if condition.
https://docs.typo3.org/m/typo3/reference-typoscript/master/en-us/Functions/If.html
On TypoScript, it is possible to use a condition (TYPO3 9.5.x syntax):
[page["selectcompany"] == 1]
obj.logo.file= fileadmin/Images/logo1.png
[GLOBAL]
Else, you could solve with fluid templating; it should be just:
<f:if condition="{data.selectcompany}">
<f:then>
<f:image src="fileadmin/template/private/images/Logo1.png" alt="" />
</f:then>
<f:else>
<f:image src="fileadmin/template/private/images/Logo0.png" alt="" />
</f:else>
</f:if>
I used <f:image> but I guess you could also go with a plain <img> tag, too.

TYPO3 <f:image /> nest viewhelper or use the processed image somehow for lazyload

I'm trying to imply lazyload with a specific slider, it requests the src of the image to be entered twice, once as src and second as data-lazy like this:
<img src="domain.com/image.png" data-lazy="domain.com/image.png">
with <f:image /> I can use data="{lazy: 'domain.com/image.png'}" and should repeat the src of the image created with the viewhelper ... (typo3 documentation and the inline use of f:uri.image)
i have actually two questions:
how do I nest f:uri.image ? this gives an error <f:image src="{image.uid}" treatIdAsReference="1" data="{lazy: '{f:uri.image(src: {image.uid})}'}"/>
it should actually be the refference to the same
image, if I nest f:uri.image would I create a second rendered image ?
(especially because I also set width and height, but I wanted to keep the snippets simple)
the solution should work for TYPO3 v7 and v8
Try this
<img src="{f:uri.image(src : image.uid)}" data-lazy="{f:uri.image(src : image.uid)}" />
You don't have to use the <f:image ..> tag for creating the <f:uri.image ..> returns the same processed resource.
In loop:
<f:for each="{MARKER}" as="file">
<img class="lazy" src=".../blank.gif" data-lazy="{f:uri.image(image: file, width:'XXXc', height:'XXXc', treatIdAsReference:1)}" alt="{file.alternative}" title="{file.title}">
</f:for>

Use v:content.render in a Contentelement

I try to render some Elements from another page via fluid in a Partial and try to use v:content.render. As you can see in the code I want to render 3 elements from the page with the Uid 9. But as soon as I have the v:content.render element in it I just get a blank page.
So my question is how to use v:content.render or what alternative I have? Or do I still need to use Typoscript for that?
{namespace v=FluidTYPO3\Vhs\ViewHelpers}
<div class="footer2">
<v:content.render column="0" limit="3" pageUid="9" as="contentElements">
<f:for each="{contentElements}" as="contentElement" iteration="footerIteration">
<f:format.html>{contentElement.bodytext}</f:format.html>
</f:for>
</v:content.render>
</div>
I am not sure if it is important, but the elements on the Page 9 are also fluid content elements.
I found a solution that works:
<v:variable.set name="contentElements" value="{v:content.get(column:'0', limit:'3', pageUid:'9', render:'FALSE')}" />
<f:for each="{contentElements}" as="contentElement" iteration="footerIteration">
<v:content.render contentUids="{0:contentElement.uid}" />
<f:format.html>{contentElement.bodytext}</f:format.html>
</f:for>
I think your first attempt was more readable. {contentElement} already had what you needed, there is no property bodytext if you leave render to its default true.
<v:content.render column="0" pageUid="9" limit:"3" as="contentElements">
<f:for each="{contentElements}" as="contentElement">
<f:format.raw>{contentElement}</f:format.raw>
</f:for>
</v:content.render>
If you don't know what you get back in as="" to work with, just try a debug:
<v:content.render column="0" pageUid="9" limit:"3" as="contentElements">
<f:for each="{contentElements}" as="contentElement">
<f:debug inline="true">{contentElement}</f:debug>
</f:for>
</v:content.render>
And I replaced <f:format.html> with <f:format.raw> so prevent some unwanted <p></p>

TYPO3 + DCE - display image thumbnail in backend

I am using TYPO3 6.2 and the extension DCE (dynamic content elements).
Everything works fine, except that I wasn't able to display a thumbnail for the custom content elements in the backend.
For the frontend I use this fluid template:
<f:for each="{dce:fal(field:'image', contentObject:contentObject)}" as="fileReference" iteration="iterator">
<f:if condition="{iterator.isFirst}">
<f:image src="{fileReference.uid}" alt="" treatIdAsReference="1" width="140px"/>
</f:if>
</f:for>
It works fine. But if i use the same code for the backend (in the field "Bodytext preview template (fluid)") it doesn't output anything. What could be the reason for this?
By the way, what is a more elegant way to output just the first image? I guess I wouldn't have to use this for loop then?
For some reason you need to refer to "fields" instead of "field" in the backend previews
<f:if condition="{fields.image}">
<f:for each="{fields.image}" as="fileReference">
<f:image src="{fileReference.uid}" alt="" treatIdAsReference="1" width="140px"/>
</f:for>
</f:if>