TYPO3 Flux - getting content of grid returns nothing - typo3

I have a flux-grid that looks like this:
<flux:grid>
<flux:grid.row>
<flux:grid.column name="content" label="Content"/>
</flux:grid.row>
</flux:grid>
It's a wrapper for other content-elements (namely elements of a slider).
Now I need to wrap each of the elements in a <li>-Tag.
So I thought I get the content as an array and render it in an each-loop.
<flux:content.render area="content" as="slides" render="1" />
I thought I'd have the elements in a variable called slides now. But that doesn't seem to be the case. When I use <f:debug>{slides}</f:debug> I get just an empty variable...
Thus, this fails:
<f:for each="{slides}" as="slide">
<f:debug>{slide}</f:debug>
</f:for>
Just outputting the content like this works, though:
<flux:content.render area="content"/>
What am I doing wrong?
[Edit]
I'm one step further...
<v:variable.set name="contentElements" value="{flux:content.get(area:'content', render:'FALSE')}" />
Does indeed return an array with the elements.
But when I try to render the elements, they're empty:
<f:for each="{contentElements}" as="contentElement">
UID: {contentElement.uid}<br />
<v:content.render contentUids="{0:contentElement.uid}" />
</f:for>
the UID is correctly outputted - the v:content.render fails

Seems like I was just using an old Vhs-Version.
Saw in the Extensions that it had an update (to 4.3.3) and now it's working...

Related

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>

How to correctly configure a fluidcontent accordion element in TYPO3 8LTS

I am updating a project to TYPO3 8LTS and I am using the latest version of flux and fluidcontent. It works most of the time. However I have an issue that I could not solve without digging too deep into flux and core. So maybe sombody here can spot the issue on my part and save me some debugging.
I have a fluidcontent element with expandable objects. It is an accordion where the editor can add as many panels as needed. The configuration looks like this:
<f:section name="Configuration">
<flux:form id="accordion">
<flux:form.option name="group" value="Container" />
<flux:form.option name="icon" value="EXT:my_ext/Resources/Public/Images/ContentIcons/Accordion.jpg" />
<flux:form.section name="panels">
<flux:form.object name="panel">
<flux:field.input name="title" />
<flux:field.checkbox name="active" />
</flux:form.object>
</flux:form.section>
</flux:form>
<flux:grid>
<f:for each="{panels}" as="panel" iteration="iteration">
<flux:grid.row>
<flux:grid.column name="column.{iteration.index}"
label="{f:if(condition: panel.panel.title, then: panel.panel.title, else: 'Panel {iteration.cycle}')}" />
</flux:grid.row>
</f:for>
</flux:grid>
</f:section>
This works like intended. It is possible to add and remove panels. However if I create a new content element and add some panels and then save&close the content element for the first time I get a core error message, telling me
"_1: Attempt to insert record on page '[root-level]' (0) where this
table, tt_content, is not allowed_".
The created content element was stored correctly in the database with all fields but the pi_flexform field where the configuration of the panels is stored. That field is empty. I can now edit the element and create panels and the configuration is saved successfuly.
The error only occurs the first time a new content element is saved.
The issue was identified as core regression in the meantime. A fix will (hopefully) be included in one of the next LTS releases.
https://forge.typo3.org/issues/80825

Inserting news teaser inside FalMediaContainer template

Is it possible to insert {newsItem.teaser} into FalMediaContainer.html? Do I need to insert something more to fluid template to see on output news teaser?
Thanks for any help
This is of course possible, however you need to change the Detail.html as well.
Please change the line
<f:render partial="Detail/FalMediaContainer" arguments="{media: newsItem.falMedia, settings:settings}" />
into
<f:render partial="Detail/FalMediaContainer" arguments="{newsItem:newsItem, media: newsItem.falMedia, settings:settings}" />
afterwards you can use any property of the {newsItem}also in the partial!

How to make circle with break in fluid?

I want to stop my circle after output first element.
<f:for each="{errors}" as="error">
<f:switch expression="{error.code}">
<f:comment>The given subject was not a valid email address</f:comment>
<f:case value="1221559976">
<f:translate extensionName="helper" key="validator.emailaddress.notvalid" />
</f:case>
...
</f:switch>
BREAK????
</f:for>
Is it possible with fluid? Regards, Anton
You don't even need to iterate the collection, what for? Instead you can just fetch first element like: {errors.0}
Additionally if you want to fetch i.e. first 3 elements, you can prepare $limitedErrors (or smth) in your PHP controller and then assign it into the view.
It will be still more comfortable than manipulating within the template engine.
You can make you for each loop with additional argument iteration=""
add below code
<f:for each="{errors}" as="error" iteration="errorIterator">
and add condition
<f:if condition="{errorIterator.index} = 0">
or
<f:if condition="{errorIterator.isFirst}">
May you can use vhs viewhelper
<v:switch value="{variable}">
<v:case case="someValue" break="TRUE">
<!-- do whatever, if {variable} == 'someValue' -->
</v:case>
<v:case case="default">
<!-- the case "default" is a reserved keyword which acts as the default case. -->
</v:case>
</v:switch>
break > boolean

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>