Ekvivalent twigoveho batch

vladimir.biro
Člen | 163
+
0
-

Zdravim.

Prosim vas, existuje v latte nieco podobne, ako v twigu batch?

https://twig.symfony.com/…s/batch.html

Chcel by som iterovat vysledky s tym, ze by mali byt vykreslovane v akychsi skupinach.

Dakujem za pripadne info.

F.Vesely
Člen | 368
+
+2
-

Latte nic takoveho nema, ale na toto pouzivam https://www.php.net/…ay-chunk.php

David Grudl
Nette Core | 8129
+
+2
-

V Latte se to dá myslím udělat takto (píšu z hlavy):

<table>
{foreach $items as $item}
    {if $iterator->isFirst(3)}<tr>{/if}
        <td>{$item}</td>
    {if $iterator->isLast(3)}</tr>{/if}
{/foreach}
</table>
David Grudl
Nette Core | 8129
+
+5
-

Ale přímo ten batch by vlastně mohl jít napsat takto:

<table>
{foreach array_chunk($items, 3) as $row}
    <tr>
        {foreach $row as $column}
            <td>{$column}</td>
        {/foreach}
    </tr>
{/foreach}
</table>
Polki
Člen | 553
+
+6
-

když si zaregistruješ tento filter, tak mít bude:

$this->template->addFilter('batch', function ($array, $size = 1, $fill = '', $preserve_keys = false) {
    $chunkedArray = array_chunk($array, $size, $preserve_keys);
    $chunkedArraySize = count($chunkedArray);
    $lastArray = $chunkedArray[$chunkedArraySize - 1];
    if (($lastArraySize = count($lastArray)) < $size) {
        for ($i = $lastArraySize; $i < $size; $i++) {
            $lastArray[] = $fill;
        }
        $chunkedArray[$chunkedArraySize - 1] = $lastArray;
    }
    return $chunkedArray;
});

použití je pak podobné tomu v případě twigového:

{var $items = ['a', 'b', 'c', 'd', 'e', 'f', 'g']}
<table>
{foreach ($items|batch:3:'No item') as $row}
    <tr>
        {foreach $row as $column}
            <td>{$column}</td>
        {/foreach}
    </tr>
{/foreach}
</table>

vygeneruje:

<table>
    <tr>
        <td>a</td>
        <td>b</td>
        <td>c</td>
    </tr>
    <tr>
        <td>d</td>
        <td>e</td>
        <td>f</td>
    </tr>
    <tr>
        <td>g</td>
        <td>No item</td>
        <td>No item</td>
    </tr>
</table>

EDIT:
Po zkrácení by mohl vypadat filtr i takto:

$this->template->addFilter('batch', function ($array, $size = 1, $fill = '', $preserve_keys = false) {
    $chunkedArray = array_chunk($array, $size, $preserve_keys);
    $chunkedArrayLastIndex = count($chunkedArray) - 1;
    for ($i = count($chunkedArray[$chunkedArrayLastIndex]); $i < $size; $i++) {
        $chunkedArray[$chunkedArrayLastIndex][] = $fill;
    }
    return $chunkedArray;
});

Editoval Polki (26. 1. 2020 17:19)

vladimir.biro
Člen | 163
+
0
-

To je super, dakujem vsetkym … dnes to vyskusam pouzit. A tym filtrom mi to pride velmi elegantne riesenie.

array_chunk mi vobec nenapadlo v tejto suvislosti :(

vladimir.biro
Člen | 163
+
0
-

David Grudl napsal(a):

V Latte se to dá myslím udělat takto (píšu z hlavy):

<table>
{foreach $items as $item}
    {if $iterator->isFirst(3)}<tr>{/if}
        <td>{$item}</td>
    {if $iterator->isLast(3)}</tr>{/if}
{/foreach}
</table>

Ano, toto viem ze sa da, len to mi neprislo ako uplne stastne, vzhladom k tomu, ze nie je uplne jasne, pri pohlade do kodu, ze co sa tam vlastne deje (obzvlast, ked je ten kod trochu zlozitejsi).
Ale riesenie s array_chunk je presne to, co som hladal :)

David Grudl
Nette Core | 8129
+
+7
-

Ono je to celkem užitečné, přidám to do Latte.