Skip to content

Commit d974627

Browse files
committed
latte: improve and clarify the grouping cookbook
1 parent 2770467 commit d974627

2 files changed

Lines changed: 56 additions & 52 deletions

File tree

latte/cs/cookbook/grouping.texy

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@ Všechno, co jste kdy chtěli vědět o seskupování
22
***********************************************
33

44
.[perex]
5-
Při práci s daty ve šablonách můžete často narazit na potřebu jejich seskupování nebo specifického zobrazení podle určitých kritérií. Latte pro tento účel nabízí hned několik silných nástrojů.
5+
Při práci s daty ve šablonách často potřebujete položky seskupit, rozdělit do dávek nebo je procházet podle podmínky. Latte k tomu nabízí tři nástroje, z nichž každý se hodí na trochu jinou situaci.
66

7-
Filtr a funkce `|group` umožňují efektivní seskupení dat podle zadaného kritéria, filtr `|batch` zase usnadňuje rozdělení dat do pevně daných dávek a značka `{iterateWhile}` poskytuje možnost složitějšího řízení průběhu cyklů s podmínkami. 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.
7+
Filtr `|group` a funkce `group()` seskupí položky podle zadaného kritéria, filtr `|batch` je rozdělí do dávek pevné velikosti a značka `{iterateWhile}` prochází data postupně a sama si určuje, kdy přerušit vnitřní smyčku. V textu si je postupně projdeme.
88

99

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

13-
Představte si databázovou tabulku `items` s položkami rozdělenou do kategorií:
13+
Nástroj lze používat ve dvou tvarech: jako filtr `$items|group: …` nebo jako funkci `group($items, …)`. Sémanticky jsou ekvivalentní, vyberte si podle čitelnosti.
14+
15+
Představte si databázovou tabulku `items`, jejíž položky patří do různých kategorií:
1416

1517
| id | categoryId | name
1618
|------------------
@@ -62,19 +64,17 @@ Pokud bychom ale chtěli, aby položky byly uspořádány do skupin podle katego
6264
{/foreach}
6365
```
6466

65-
Filtr lze v Latte použít i jako funkci, což nám dává alternativní syntaxi: `{foreach group($items, categoryId) ...}`.
66-
67-
Chcete-li seskupovat položky podle složitějších kritérií, můžete v parametru filtru použít funkci. Například, seskupení položek podle délky názvu by vypadalo takto:
67+
Chcete-li seskupovat položky podle složitějších kritérií, můžete v parametru filtru použít funkci. Klíčem každé skupiny pak bude návratová hodnota funkce — například při seskupení podle délky názvu to bude počet znaků:
6868

6969
```latte
70-
{foreach ($items|group: fn($item) => strlen($item->name)) as $items}
70+
{foreach ($items|group: fn($item) => strlen($item->name)) as $length => $group}
7171
...
7272
{/foreach}
7373
```
7474

75-
Je důležité si uvědomit, že `$categoryItems` není běžné pole, ale objekt, který se chová jako iterátor. Pro přístup k první položce skupiny můžete použít funkci [`first()` |latte:functions#first].
75+
Je důležité si uvědomit, že každá skupina (tedy i `$categoryItems`) není běžné pole, ale objekt chovající se jako iterátor — nelze proto použít `$categoryItems[0]` ani `count($categoryItems)`. Pro přístup k první položce skupiny použijte funkci [`first()` |latte:functions#first].
7676

77-
Tato flexibilita v seskupování dat činí `group` výjimečně užitečným nástrojem pro prezentaci dat v šablonách Latte.
77+
Tato flexibilita činí `|group` výjimečně užitečným nástrojem pro prezentaci dat.
7878

7979

8080
Vnořené smyčky
@@ -97,8 +97,8 @@ Představme si, že máme databázovou tabulku s dalším sloupcem `subcategoryI
9797
```
9898

9999

100-
Spojení s Nette Database
101-
------------------------
100+
Společně s Nette Database
101+
-------------------------
102102

103103
Pojďme si ukázat, jak efektivně využít seskupování dat v kombinaci s Nette Database. Předpokládejme, že pracujeme s tabulkou `items` z úvodního příkladu, která je prostřednictvím sloupce `categoryId` spojená s touto tabulkou `categories`:
104104

@@ -121,24 +121,24 @@ Data z tabulky `items` načteme pomocí Nette Database Explorer příkazem `$ite
121121
{/foreach}
122122
```
123123

124-
V tomto případě používáme filtr `|group` k seskupení podle propojeného řádku `$item->category`, nikoliv jen dle sloupce `categoryId`. Díky tomu v proměnné klíči přímo `ActiveRow` dané 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.
124+
V tomto případě používáme filtr `|group` k seskupení podle propojeného řádku `$item->category`, nikoliv jen dle sloupce `categoryId`. Díky tomu je v klíči (`$category`) rovnou `ActiveRow` dané kategorie, což nám umožňuje vypisovat její název pomocí `{$category->name}` a přistupovat k libovolnému dalšímu sloupci, aniž bychom museli dělat zvláštní dotaz na `categories`.
125125

126126

127127
Filtr `|batch`
128128
==============
129129

130-
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.
130+
Filtr rozdělí seznam prvků do dávek o pevně daném počtu. Hodí se třeba pro grid layout, sloupcové rozložení nebo jakékoli vizuální seskupení.
131131

132-
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é:
132+
Představme si, že chceme zobrazit položky v seznamech, kde každý obsahuje maximálně tři položky:
133133

134134
```latte
135-
<ul>
136135
{foreach ($items|batch: 3) as $batch}
137-
{foreach $batch as $item}
138-
<li>{$item->name}</li>
139-
{/foreach}
136+
<ul>
137+
{foreach $batch as $item}
138+
<li>{$item->name}</li>
139+
{/foreach}
140+
</ul>
140141
{/foreach}
141-
</ul>
142142
```
143143

144144
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.
@@ -155,9 +155,9 @@ Pokud poslední skupina neobsahuje dostatek prvků k dosažení požadovaného p
155155
Značka `{iterateWhile}`
156156
=======================
157157

158-
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šechna vstupní data, zatímco `{iterateWhile}` řídí průběhu cyklů s podmínkami, takže iterace probíhá postupně.
158+
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šechna vstupní data, zatímco `{iterateWhile}` řídí průběh cyklu pomocí podmínky a iterace probíhá postupně.
159159

160-
Nejprve vykreslíme tabulku s kategoriemi pomocí iterateWhile:
160+
Nejprve vykreslíme tabulku s kategoriemi pomocí `{iterateWhile}`:
161161

162162
```latte
163163
{foreach $items as $item}
@@ -169,7 +169,7 @@ Nejprve vykreslíme tabulku s kategoriemi pomocí iterateWhile:
169169
{/foreach}
170170
```
171171

172-
Zatímco `{foreach}` označuje vnější část cyklu, tedy vykreslování seznamů pro každou kategorii, tak značka `{iterateWhile}` označuje vnitřní část, tedy jednotlivé položky. Podmínka v koncové značce říká, že opakování bude probíhat do té doby, dokud aktuální i následující prvek patří do stejné kategorie (`$iterator->nextValue` je [následující položka |/tags#iterator]).
172+
Zatímco `{foreach}` označuje vnější část cyklu, tedy vykreslování seznamů pro každou kategorii, tak značka `{iterateWhile}` označuje vnitřní část, tedy jednotlivé položky. Podmínka v koncové značce říká, že opakování bude probíhat do té doby, dokud aktuální i následující prvek patří do stejné kategorie (`$iterator->nextValue` je [následující položka |/tags#iterator]; u posledního prvku je `null` a porovnání pak vyjde false, takže vnitřní cyklus přirozeně skončí).
173173

174174
Kdyby podmínka byla splněná vždy, tak se ve vnitřním cyklu vykreslí všechny prvky:
175175

@@ -196,11 +196,11 @@ Výsledek bude vypadat takto:
196196
</ul>
197197
```
198198

199-
K čemu je takové použití iterateWhile dobré? Když bude tabulka prázdná a nebude obsahovat žádné prvky, nevypíše se prázdné `<ul></ul>`.
199+
K čemu je takové použití `{iterateWhile}` dobré? Tím, že je `<ul>` uvnitř vnějšího `{foreach}`, se při prázdném vstupu nevykreslí vůbec nic — žádný osamělý `<ul></ul>`. Bez `{iterateWhile}` byste totéž museli ošetřit `{if}` před otevřením tagu nebo přes `{foreachelse}`.
200200

201201
Pokud uvedeme podmínku v otevírací značce `{iterateWhile}`, tak se chování změní: podmínka (a přechod na další prvek) se vykoná už na začátku vnitřního cyklu, nikoliv na konci. Tedy zatímco do `{iterateWhile}` bez podmínky se vstoupí vždy, do `{iterateWhile $cond}` jen při splnění podmínky `$cond`. A zároveň se s tím do `$item` zapíše následující prvek.
202202

203-
Což se hodí například v situaci, kdy budeme chtít první prvek v každé kategorii vykreslit jiným způsobem, například takto:
203+
Hodí se to v situaci, kdy chceme první prvek v každé kategorii vykreslit jiným způsobem než ty ostatní, například takto:
204204

205205
```latte
206206
<h1>Apple</h1>
@@ -219,6 +219,8 @@ Což se hodí například v situaci, kdy budeme chtít první prvek v každé ka
219219
</ul>
220220
```
221221

222+
(Prázdné `<ul></ul>` u kategorie PHP je tu jen ilustrací mechaniky — v reálném kódu byste vykreslení `<ul>` ošetřili `{if}`.)
223+
222224
Původní kód upravíme tak, že nejprve vykreslíme první položku a poté ve vnitřním cyklu `{iterateWhile}` vykreslíme další položky ze stejné kategorie:
223225

224226
```latte
@@ -232,9 +234,9 @@ Původní kód upravíme tak, že nejprve vykreslíme první položku a poté ve
232234
{/foreach}
233235
```
234236

235-
V rámci jednoho cyklu můžeme vytvářet více vnitřních smyček a dokonce je zanořovat. Takto by se daly seskupovat třeba podkategorie atd.
237+
V rámci jednoho cyklu můžeme vytvářet více vnitřních smyček a dokonce je zanořovat. Tímto způsobem lze seskupovat na více úrovních současně — třeba podkategorie pod kategoriemi.
236238

237-
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>`:
239+
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á podkategorie bude v samostatném `<ol>`:
238240

239241
```latte
240242
{foreach $items as $item}

0 commit comments

Comments
 (0)