Nette Documentation Preview

syntax
iterateWhile} Hakkında Her Zaman Bilmek İstediğiniz Her Şey
***********************************************************

.[perex]
`{iterateWhile}` etiketi foreach döngülerinde çeşitli hileler için uygundur.

Öğelerin kategorilere ayrıldığı aşağıdaki veritabanı tablosuna sahip olduğumuzu varsayalım:

| id  |  catId  |  name
|------------------
| 1   |      1  | Apple
| 2   |      1  | Banana
| 3   |      2  | PHP
| 4   |      3  | Green
| 5   |      3  | Red
| 6   |      3  | Blue

Elbette, bir foreach döngüsündeki öğeleri liste olarak çizmek kolaydır:

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

Ancak her kategoriyi ayrı bir listede işlemek istiyorsanız ne yapmalısınız? Başka bir deyişle, doğrusal bir listedeki öğeleri bir foreach döngüsü içinde gruplama görevi nasıl çözülür? Çıktı şöyle görünmelidir:

```latte
<ul>
	<li>Apple</li>
	<li>Banana</li>
</ul>

<ul>
	<li>PHP</li>
</ul>

<ul>
	<li>Green</li>
	<li>Red</li>
	<li>Blue</li>
</ul>
```

iterateWhile ile bu görevin ne kadar kolay ve zarif bir şekilde çözülebileceğini göstereceğiz:

```latte
{foreach $items as $item}
	<ul>
		{iterateWhile}
			<li>{$item->name}</li>
		{/iterateWhile $item->catId === $iterator->nextValue->catId}
	</ul>
{/foreach}
```

`{foreach}` döngünün dış kısmını, yani her kategori için listelerin çizilmesini işaret ederken, `{iterateWhile}` etiketleri iç kısmı, yani tek tek öğeleri gösterir.
Bitiş etiketindeki koşul, mevcut ve bir sonraki [öğe |/tags#$iterator] aynı kategoriye ait olduğu sürece tekrarın devam edeceğini söyler (`$iterator->nextValue` bir sonraki öğedir).

Koşul her zaman karşılanırsa, tüm öğeler iç döngüde çizilir:

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

Sonuç şu şekilde görünecektir:

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

iterateWhile'ın böyle bir kullanımı ne işe yarar? Bu eğitimin en başında gösterdiğimiz çözümden ne farkı var? Aradaki fark, tablo boşsa ve herhangi bir öğe içermiyorsa, boş olarak işlenmeyecektir `<ul></ul>`.


`{iterateWhile}` Olmadan Çözüm .[#toc-solution-without-iteratewhile]
--------------------------------------------------------------------

Aynı görevi şablon sistemlerinin tamamen temel yapılarıyla, örneğin Twig, Blade veya saf PHP ile çözmüş olsaydık, çözüm şuna benzer bir şey olurdu:

```latte
{var $prevCatId = null}
{foreach $items as $item}
	{if $item->catId !== $prevCatId}
		{* kategori değişti *}

		{* <ul> ilk öğe değilse</ul>bir öncekini kapatıyoruz <ul>*}
		{if $prevCatId !== null}
			</ul>
		{/if}

		{* we will open a new list *}
		<ul>

		{do $prevCatId = $item->catId}
	{/if}

	<li>{$item->name}</li>
{/foreach}

{if $prevCatId !== null}
	{* we close the last list *}
	</ul>
{/if}
```

Ancak, bu kod anlaşılmaz ve sezgisel değildir. Açılış ve kapanış HTML etiketleri arasındaki bağlantı hiç açık değildir. Bir hata olup olmadığı ilk bakışta anlaşılmıyor. Ve `$prevCatId` gibi yardımcı değişkenler gerektirir.

Buna karşılık, `{iterateWhile}` ile çözüm temiz, net, yardımcı değişkenlere ihtiyaç duymaz ve hatasızdır.


Kapanış Etiketindeki Koşul .[#toc-condition-in-the-closing-tag]
---------------------------------------------------------------

Açılış etiketinde bir koşul belirtirsek `{iterateWhile}`, davranış değişir: koşul (ve bir sonraki öğeye ilerleme) iç döngünün sonunda değil başında yürütülür.
Böylece, koşul olmadan `{iterateWhile}` her zaman girilirken, `{iterateWhile $cond}` yalnızca `$cond` koşulu karşılandığında girilir. Aynı zamanda, aşağıdaki eleman `$item` adresine yazılır.

Bu, örneğin, her kategorideki ilk öğeyi farklı bir şekilde oluşturmak istediğiniz bir durumda kullanışlıdır:

```latte
<h1>Apple</h1>
<ul>
	<li>Banana</li>
</ul>

<h1>PHP</h1>
<ul>
</ul>

<h1>Green</h1>
<ul>
	<li>Red</li>
	<li>Blue</li>
</ul>
```

Orijinal kodu değiştirelim, `{iterateWhile}` iç döngüsünde ilk öğeyi ve ardından aynı kategoriden ek öğeleri çizelim:

```latte
{foreach $items as $item}
	<h1>{$item->name}</h1>
	<ul>
		{iterateWhile $item->catId === $iterator->nextValue->catId}
			<li>{$item->name}</li>
		{/iterateWhile}
	</ul>
{/foreach}
```


İç İçe Döngüler .[#toc-nested-loops]
------------------------------------

Bir döngüde birden fazla iç döngü oluşturabilir ve hatta bunları iç içe yerleştirebiliriz. Bu şekilde, örneğin alt kategoriler gruplandırılabilir.

Tabloda başka bir sütun olduğunu varsayalım `subCatId` ve her kategorinin ayrı bir kategoride olmasına ek olarak `<ul>`her bir alt kategori ayrı bir `<ol>`:

```latte
{foreach $items as $item}
	<ul>
		{iterateWhile}
			<ol>
				{iterateWhile}
					<li>{$item->name}
				{/iterateWhile $item->subCatId === $iterator->nextValue->subCatId}
			</ol>
		{/iterateWhile $item->catId === $iterator->nextValue->catId}
	</ul>
{/foreach}
```


Filtre | yığın .[#toc-filter-batch]
-----------------------------------

Doğrusal öğelerin gruplandırılması da bir filtre tarafından sağlanır `batch`, sabit sayıda öğeye sahip gruplar halinde:

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

Aşağıdaki gibi iterateWhile ile değiştirilebilir:

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

{{leftbar: /@left-menu}}

iterateWhile} Hakkında Her Zaman Bilmek İstediğiniz Her Şey

{iterateWhile} etiketi foreach döngülerinde çeşitli hileler için uygundur.

Öğelerin kategorilere ayrıldığı aşağıdaki veritabanı tablosuna sahip olduğumuzu varsayalım:

id catId name
1 1 Apple
2 1 Banana
3 2 PHP
4 3 Green
5 3 Red
6 3 Blue

Elbette, bir foreach döngüsündeki öğeleri liste olarak çizmek kolaydır:

<ul>
{foreach $items as $item}
	<li>{$item->name}</li>
{/foreach}
</ul>

Ancak her kategoriyi ayrı bir listede işlemek istiyorsanız ne yapmalısınız? Başka bir deyişle, doğrusal bir listedeki öğeleri bir foreach döngüsü içinde gruplama görevi nasıl çözülür? Çıktı şöyle görünmelidir:

<ul>
	<li>Apple</li>
	<li>Banana</li>
</ul>

<ul>
	<li>PHP</li>
</ul>

<ul>
	<li>Green</li>
	<li>Red</li>
	<li>Blue</li>
</ul>

iterateWhile ile bu görevin ne kadar kolay ve zarif bir şekilde çözülebileceğini göstereceğiz:

{foreach $items as $item}
	<ul>
		{iterateWhile}
			<li>{$item->name}</li>
		{/iterateWhile $item->catId === $iterator->nextValue->catId}
	</ul>
{/foreach}

{foreach} döngünün dış kısmını, yani her kategori için listelerin çizilmesini işaret ederken, {iterateWhile} etiketleri iç kısmı, yani tek tek öğeleri gösterir. Bitiş etiketindeki koşul, mevcut ve bir sonraki öğe aynı kategoriye ait olduğu sürece tekrarın devam edeceğini söyler ($iterator->nextValue bir sonraki öğedir).

Koşul her zaman karşılanırsa, tüm öğeler iç döngüde çizilir:

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

Sonuç şu şekilde görünecektir:

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

iterateWhile'ın böyle bir kullanımı ne işe yarar? Bu eğitimin en başında gösterdiğimiz çözümden ne farkı var? Aradaki fark, tablo boşsa ve herhangi bir öğe içermiyorsa, boş olarak işlenmeyecektir <ul></ul>.

{iterateWhile} Olmadan Çözüm

Aynı görevi şablon sistemlerinin tamamen temel yapılarıyla, örneğin Twig, Blade veya saf PHP ile çözmüş olsaydık, çözüm şuna benzer bir şey olurdu:

{var $prevCatId = null}
{foreach $items as $item}
	{if $item->catId !== $prevCatId}
		{* kategori değişti *}

		{* <ul> ilk öğe değilse</ul>bir öncekini kapatıyoruz <ul>*}
		{if $prevCatId !== null}
			</ul>
		{/if}

		{* we will open a new list *}
		<ul>

		{do $prevCatId = $item->catId}
	{/if}

	<li>{$item->name}</li>
{/foreach}

{if $prevCatId !== null}
	{* we close the last list *}
	</ul>
{/if}

Ancak, bu kod anlaşılmaz ve sezgisel değildir. Açılış ve kapanış HTML etiketleri arasındaki bağlantı hiç açık değildir. Bir hata olup olmadığı ilk bakışta anlaşılmıyor. Ve $prevCatId gibi yardımcı değişkenler gerektirir.

Buna karşılık, {iterateWhile} ile çözüm temiz, net, yardımcı değişkenlere ihtiyaç duymaz ve hatasızdır.

Kapanış Etiketindeki Koşul

Açılış etiketinde bir koşul belirtirsek {iterateWhile}, davranış değişir: koşul (ve bir sonraki öğeye ilerleme) iç döngünün sonunda değil başında yürütülür. Böylece, koşul olmadan {iterateWhile} her zaman girilirken, {iterateWhile $cond} yalnızca $cond koşulu karşılandığında girilir. Aynı zamanda, aşağıdaki eleman $item adresine yazılır.

Bu, örneğin, her kategorideki ilk öğeyi farklı bir şekilde oluşturmak istediğiniz bir durumda kullanışlıdır:

<h1>Apple</h1>
<ul>
	<li>Banana</li>
</ul>

<h1>PHP</h1>
<ul>
</ul>

<h1>Green</h1>
<ul>
	<li>Red</li>
	<li>Blue</li>
</ul>

Orijinal kodu değiştirelim, {iterateWhile} iç döngüsünde ilk öğeyi ve ardından aynı kategoriden ek öğeleri çizelim:

{foreach $items as $item}
	<h1>{$item->name}</h1>
	<ul>
		{iterateWhile $item->catId === $iterator->nextValue->catId}
			<li>{$item->name}</li>
		{/iterateWhile}
	</ul>
{/foreach}

İç İçe Döngüler

Bir döngüde birden fazla iç döngü oluşturabilir ve hatta bunları iç içe yerleştirebiliriz. Bu şekilde, örneğin alt kategoriler gruplandırılabilir.

Tabloda başka bir sütun olduğunu varsayalım subCatId ve her kategorinin ayrı bir kategoride olmasına ek olarak <ul>her bir alt kategori ayrı bir <ol>:

{foreach $items as $item}
	<ul>
		{iterateWhile}
			<ol>
				{iterateWhile}
					<li>{$item->name}
				{/iterateWhile $item->subCatId === $iterator->nextValue->subCatId}
			</ol>
		{/iterateWhile $item->catId === $iterator->nextValue->catId}
	</ul>
{/foreach}

Filtre | yığın

Doğrusal öğelerin gruplandırılması da bir filtre tarafından sağlanır batch, sabit sayıda öğeye sahip gruplar halinde:

<ul>
{foreach ($items|batch:3) as $batch}
	{foreach $batch as $item}
		<li>{$item->name}</li>
	{/foreach}
{/foreach}
</ul>

Aşağıdaki gibi iterateWhile ile değiştirilebilir:

<ul>
{foreach $items as $item}
	{iterateWhile}
		<li>{$item->name}</li>
	{/iterateWhile $iterator->counter0 % 3}
{/foreach}
</ul>