Skip to content

Commit

Permalink
x
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed May 14, 2024
1 parent c8faa54 commit d65728d
Showing 1 changed file with 52 additions and 59 deletions.
111 changes: 52 additions & 59 deletions latte/cs/cookbook/grouping.texy
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Filtr a funkce `|group` umožňují efektivní seskupení dat podle zadaného kr
Každá z těchto značek nabízí specifické možnosti pro práci s daty, čímž se stávají nepostradatelnými nástroji pro dynamické a strukturované zobrazení informací v Latte šablonách.


Filtr a funkce `group`
----------------------
Filtr a funkce `group` .{data-version:3.0.16}
=============================================

Dejme tomu, že máme následující databázovou tabulku, kde jsou položky rozdělené do kategorií:

Expand Down Expand Up @@ -51,55 +51,21 @@ Ale co kdybychom chtěli, aby každá kategorie byla v samostatném seznamu? Jin
</ul>
```

Rovnou si ukážeme, jak snadno a elegantně se dá úkol vyřešit pomocí `|group`:
Úkol se dá snadno a elegantně vyřešit pomocí `|group`:

```latte
{foreach ($items|group: categoryId) as $categoryId => $items}
{foreach ($items|group: categoryId) as $categoryId => $categoryItems}
<ul>
{foreach $items as $item}
{foreach $categoryItems as $item}
<li>{$item->name}</li>
{/foreach}
</ul>
{/foreach}
```

Vnější `{foreach}` seskupí položky do pro každou kategorii a pak nad nimi iteruje vnitřní `{foreach}`.
Filtr `|group` položky seskupí do menších polí podle kategorie. Protože je dostupný i jako funkce, šlo by použít i `{foreach group($items, categoryId) ...}`.


```latte
{foreach $items as $item}
<ul>
{iterateWhile}
<li>{$item->name}
{/iterateWhile true}
</ul>
{/foreach}
```

Výsledek bude vypadat takto:

```latte
<ul>
<li>Apple</li>
<li>Banana</li>
<li>PHP</li>
<li>Green</li>
<li>Red</li>
<li>Blue</li>
</ul>
```


```latte
{foreach ($items|group: categoryId) as $categoryId => $items}
<h1>{($items|first)->name}</h1>
<ul>
{foreach $items as $item}
<li>{$item->name}</li>
{/foreach}
</ul>
{/foreach}
```
V proměnné `$items` není přímo pole, ale objekt iterátoru. Pro získání první položky použijte funkci [`first()`|latte:functions#first].


Vnořené smyčky
Expand All @@ -110,11 +76,11 @@ V rámci jednoho cyklu můžeme vytvářet více vnitřních smyček a dokonce j
Dejme tomu, že v tabulce bude ještě další sloupec `subcategoryId` a kromě toho, že každá kategorie bude v samostatném `<ul>`, každá každý podkategorie samostatném `<ol>`:

```latte
{foreach ($items|group: categoryId) as $items1}
{foreach ($items|group: categoryId) as $categoryItems}
<ul>
{foreach ($items1|group: subcategoryId) as $items2}
{foreach ($categoryItems|group: subcategoryId) as $subcategoryItems}
<ol>
{foreach $items2 as $item}
{foreach $subcategoryItems as $item}
<li>{$item->name}
{/foreach}
</ol>
Expand All @@ -124,36 +90,63 @@ Dejme tomu, že v tabulce bude ještě další sloupec `subcategoryId` a kromě
```


Filtr |batch
------------
Spojení s Nette Database
------------------------

Pojďme si ukázat, jak efektivně využít seskupování dat v kombinaci s Nette Database. Předpokládejme, že pracujeme s tabulkou `things`, která obsahuje informace jako v našem úvodním příkladu, a je spojená s tabulkou `categories` prostřednictvím sloupce `categoryId`:

Seskupování lineárních položek obstarává také filtr `batch`, a to do dávek s pevným počtem prvků:
| categoryId | name |
|------------|------------|
| 1 | Fruits |
| 2 | Languages |
| 3 | Colors |

Data z tabulky `things` načteme pomocí Nette Database Explorer příkazem `$things = $db->table('things')`. Během iterace nad těmito daty máme možnost přistupovat nejen k atributům jako `$item->name` a `$item->categoryId`, ale díky propojení s tabulkou `categories` také k souvisejícímu řádku v ní přes `$item->category`. Na tomto propojení lze demonstrovat praktické využití seskupení:

```latte
<ul>
{foreach ($items|batch:3) as $batch}
{foreach $batch as $item}
<li>{$item->name}</li>
{/foreach}
{foreach $things|group: 'category' as $category => $items}
<h1>{$category->name}</h1>
<ul>
{foreach $items as $item}
<li>{$item->name}</li>
{/foreach}
</ul>
{/foreach}
</ul>
```

Lze jej nahradit za iterateWhile tímto způsobem:
V tomto případě používáme filtr `|group` na propojený řádek `$item->category`, nikoliv jen na jednoduchý sloupec `categoryId`. Díky tomu v proměnné `$category` nepracujeme s číselným identifikátorem, ale přímo s `ActiveRow` kategorie, což nám umožňuje přímo vypisovat její název pomocí `{$category->name}`. Toto je praktický příklad, jak může seskupování zpřehlednit šablony a usnadnit práci s daty.


Filtr `|batch`
==============

Filtr umožňuje rozdělit seznam prvků do skupin s předem určeným počtem prvků. Tento filtr je ideální pro situace, kdy chcete data prezentovat ve více menších skupinách, například pro lepší přehlednost nebo vizuální uspořádání na stránce.

Představme si, že máme seznam položek a chceme je zobrazit v seznamech, kde každý obsahuje maximálně tři položky. Použití filtru `|batch` je v takovém případě velmi praktické:

```latte
<ul>
{foreach $items as $item}
{iterateWhile}
<li>{$item->name}</li>
{/iterateWhile $iterator->counter0 % 3}
{foreach ($items|batch: 3) as $batch}
{foreach $batch as $item}
<li>{$item->name}</li>
{/foreach}
{/foreach}
</ul>
```

V tomto příkladu je seznam `$items` rozdělen do menších skupin, přičemž každá skupina (`$batch`) obsahuje až tři položky. Každá skupina je poté zobrazena v samostatném `<ul>` seznamu.

Pokud poslední skupina neobsahuje dostatek prvků k dosažení požadovaného počtu, druhý parametr filtru umožňuje definovat, čím bude tato skupina doplněna. To je ideální pro estetické zarovnání prvků, zejména na webových stránkách, kde by neúplná řada mohla působit neuspořádaně.

```latte
{foreach ($items|batch: 3, '—') as $batch}
...
</ul>
```


Značka `{iterateWhile}`
-----------------------
=======================

Stejné úkoly, jako jsme řešili s filtrem `|group`, si ukážeme s použitím značky `{iterateWhile}`. Hlavní rozdíl mezi oběma přístupy je v tom, že `group` nejprve zpracuje a seskupí všechny vstupní data, zatímco `{iterateWhile}` řídí průběhu cyklů s podmínkami, takže iterace probíhá postupně.

Expand Down

0 comments on commit d65728d

Please sign in to comment.