You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: latte/cs/cookbook/grouping.texy
+28-26Lines changed: 28 additions & 26 deletions
Original file line number
Diff line number
Diff line change
@@ -2,15 +2,17 @@ Všechno, co jste kdy chtěli vědět o seskupování
2
2
***********************************************
3
3
4
4
.[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.
6
6
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.
8
8
9
9
10
10
Filtr a funkce `group` .{data-version:3.0.16}
11
11
=============================================
12
12
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í:
14
16
15
17
| id | categoryId | name
16
18
|------------------
@@ -62,19 +64,17 @@ Pokud bychom ale chtěli, aby položky byly uspořádány do skupin podle katego
62
64
{/foreach}
63
65
```
64
66
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ů:
68
68
69
69
```latte
70
-
{foreach ($items|group: fn($item) => strlen($item->name)) as $items}
70
+
{foreach ($items|group: fn($item) => strlen($item->name)) as $length => $group}
71
71
...
72
72
{/foreach}
73
73
```
74
74
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].
76
76
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.
78
78
79
79
80
80
Vnořené smyčky
@@ -97,8 +97,8 @@ Představme si, že máme databázovou tabulku s dalším sloupcem `subcategoryI
97
97
```
98
98
99
99
100
-
Spojení s Nette Database
101
-
------------------------
100
+
Společně s Nette Database
101
+
-------------------------
102
102
103
103
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`:
104
104
@@ -121,24 +121,24 @@ Data z tabulky `items` načteme pomocí Nette Database Explorer příkazem `$ite
121
121
{/foreach}
122
122
```
123
123
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`.
125
125
126
126
127
127
Filtr `|batch`
128
128
==============
129
129
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í.
131
131
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:
133
133
134
134
```latte
135
-
<ul>
136
135
{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>
140
141
{/foreach}
141
-
</ul>
142
142
```
143
143
144
144
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
155
155
Značka `{iterateWhile}`
156
156
=======================
157
157
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ě.
159
159
160
-
Nejprve vykreslíme tabulku s kategoriemi pomocí iterateWhile:
160
+
Nejprve vykreslíme tabulku s kategoriemi pomocí `{iterateWhile}`:
161
161
162
162
```latte
163
163
{foreach $items as $item}
@@ -169,7 +169,7 @@ Nejprve vykreslíme tabulku s kategoriemi pomocí iterateWhile:
169
169
{/foreach}
170
170
```
171
171
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čí).
173
173
174
174
Kdyby podmínka byla splněná vždy, tak se ve vnitřním cyklu vykreslí všechny prvky:
175
175
@@ -196,11 +196,11 @@ Výsledek bude vypadat takto:
196
196
</ul>
197
197
```
198
198
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}`.
200
200
201
201
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.
202
202
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:
204
204
205
205
```latte
206
206
<h1>Apple</h1>
@@ -219,6 +219,8 @@ Což se hodí například v situaci, kdy budeme chtít první prvek v každé ka
219
219
</ul>
220
220
```
221
221
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
+
222
224
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:
223
225
224
226
```latte
@@ -232,9 +234,9 @@ Původní kód upravíme tak, že nejprve vykreslíme první položku a poté ve
232
234
{/foreach}
233
235
```
234
236
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.
236
238
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>`:
0 commit comments