3

Using the extension DCE elements, I created a fluid template generating a li item for every item created. Now I would like to have every first to second item a wrapper. So that:

<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>

Becomes:

<ul>
    <li>item 1</li>
    <li>item 2</li>
</ul>
<ul>
    <li>item 3</li>
    <li>item 4</li>
</ul>
<ul>
    <li>item 5</li>
</ul>

Is this possible in a fluid template? Perhaps in combination with Typoscript?

Stefan Zobel
  • 3,182
  • 7
  • 28
  • 38
Scopestyle
  • 643
  • 5
  • 18

5 Answers5

6

Solution

This is what I ended up with using {cycle} to iterate trough every 2 items, and then closing and opening the tag. As well as making sure the last item does not end with an opening tag:

<ul>
    <f:for each="{field.item}" as="item" iteration="iterator">

        <f:if condition="{iterator.cycle} % 2">
            <f:then>
                <li>item {iterator.cycle}</li>
            </f:then>
            <f:else>
                <li>item {iterator.cycle}</li>
                <f:if condition="{iterator.isLast} != 1">
                    <f:then>
                        </ul><ul>
                    </f:then>
                </f:if>
            </f:else>
        </f:if>

    </f:for>
</ul>

Note

I understand that with the power of VHS v:iterator.chunk would probably solve this with a little less code, but I could not get it to work how I wanted to. If anyone would be willing to provide a working example to compare the 2 options I would be grateful.

With VHS

Update: 21.12.2017

So revisited the chunk option, and the same code is achieved with the following snippet using VHS iterator.chunk:

<f:for each="{field.item -> v:iterator.chunk(count: 2)}" as="col" iteration="cycle">
    <ul>
        <f:for each="{col}" as="item">
            <li>
                test
            </li>
        </f:for>
    </ul>
</f:for>                

Perhaps this helps someone out there!

Scopestyle
  • 643
  • 5
  • 18
2

If you are using the VHS view helpers collection extension, then you can also use the Iterator\Chunked view helper:

<v:iterator.chunk count="4" subject="{menu}" as="entries">
     <f:for each="{entries}" as="row">
          <f:for each="{row}" as="page">
          [...]
          </f:for>
     </f:for>
</v:iterator>
Andreas Wolf
  • 995
  • 6
  • 19
1

This is possible with regular Fluid, using the iterator of the for view helper.

<f:for each="{items}" as="item" iteration="itemIterator">
    <f:if condition="{itemIterator.isOdd}">
        <ul>
    </f:if>
    <li>{item.name}</li>
    <f:if condition="{itemIterator.isOdd}">
        <f:then>
            <f:if condition="{itemIterator.isLast}">
                </ul>
            </f:if>
        </f:then>
        <f:else>
            </ul>
        </f:else>
    </f:if>
</f:for> 

The tricky part is the closing </ul> which is covered with the Fluid above.

0

Sure, you need the for viewhelper in addition to its counters/iterators. The you can use the if viewhelper to check for your condition. The API has some examples: http://api.typo3.org/typo3cms/current/html/class_t_y_p_o3_1_1_c_m_s_1_1_fluid_1_1_view_helpers_1_1_for_view_helper.html#details

https://docs.typo3.org/typo3cms/ExtbaseGuide/Fluid/ViewHelper/For.html

pgampe
  • 4,531
  • 1
  • 20
  • 31
0

I have one more solution, As for me - more native

<f:for each="{items}" as="item" iteration="itemIterator">
    <f:cycle values="{0:'left', 1:'right', 3:'center'}" as="order">
            <f:switch expression="{order}">
                <f:case value="left">
                       <div class="left">Conetnt</div>
                </f:case>
                <f:case value="right">
                       <div class="right">Conetnt</div>
                </f:case>
                <f:case value="center">
                       <div class="center">Conetnt</div>
                </f:case> 
            </f:switch>  
    </f:cycle> 
</f:for> 
Oleg V Karun
  • 726
  • 1
  • 6
  • 29