picea/docs/02-control-structure-loops.md

194 lines
4.4 KiB
Markdown

# Control structure - Loops
Picea's loop works the same as PHP original alternative syntax.
There is, however, some minors improvments and a new `{% or %}` clause working much like the `{% else %}` clause in a comparison.
## Loop using `for` / `or` / `continue` / `break` / `endfor`
The simplest of sequence loop, `for` / `endfor` simply iterate over a given counter (or whatever your needs).
**[PICEA]** So, using this code:
```html
{% php $users = array_slice([ 'Tom', 'Sam', 'Mario', 'Steve' ], 0, random_int(0, 4)) %}
<h1>User list</h1>
<ul>
{% for $i = 0; $i < count($users); $i++ %}
{% if $users[$i] === 'Steve' %}
{# Will leave the loop if user's name is Steve #}
{% break %}
{% else %}
<li>{{ $users[$i] }}</li>
{% endif %}
{% or %}
<li class="empty">Given user list was empty</li>
{% endfor %}
</ul>
```
**[PHP]** Would compile like :
```php
<?php $users = array_slice([ 'Tom', 'Sam', 'Mario', 'Steve' ], 0, random_int(0, 4)) ?>
<h1>User list</h1>
<ul>
<?php for($i = 0; $i < count($users); $i++): ?><?php $for_a1kro2k2o = true;
<?php if ($users[$i] === 'Steve'): ?>
<?php break ?>
<?php else: ?>
<li><?php echo htmlspecialchars((string) $users[$i], 3, 'UTF-8', true) ?></li>
<?php endif ?>
<?php endfor ?><?php if (empty($for_a1kro2k2o)): ?><li class="empty">Given user list was empty</li><?php endif ?>
</ul>
```
**[HTML]** And would render as such given random_int() returns a **3**:
```html
<h1>User list</h1>
<ul>
<li>Tom</li>
<li>Sam</li>
<li>Mario</li>
</ul>
```
**[HTML]** Or would render as such given random_int() returns a **0**:
```html
<h1>User list</h1>
<ul>
<li class="empty">Tom</li>
</ul>
```
## Loop using `foreach` / `or` / `continue` / `break` / `endforeach`
The more complex `foreach` / `endforeach` allows to iterate over keys and values of an array.
**[PICEA]** So, using this code:
```html
{# Generate a random list of 0 to 4 names #}
{% php $users = array_slice([ 'Tom', 'Sam', 'Mario', 'Steve', 'Joan' ], 0, random_int(0, 5)) %}
<h1>Random User list</h1>
<ul>
{% foreach $users as $index => $name %}
{% if $name === 'Steve' %}
{# We skip Steve, but allows Joan #}
{% continue %}
{% endif %}
<li>{{ $name }}</li>
{% or %}
<li class="empty">Given user list was empty</li>
{% endforeach %}
</ul>
```
**[HTML]** Could render as such if prior random_int() returns '**2**':
```html
<h1>User list</h1>
<ul>
<li>Tom</li>
<li>Sam</li>
</ul>
```
**[HTML]** Could render as such given random_int() returns '**0**':
```html
<h1>User list</h1>
<ul></ul>
```
## Loop using `while` / `or` / `continue` / `break` / `endwhile`
This syntax allows to loop on a computed iteration count.
**[PICEA]** So, using this code:
```html
{% php $fruits = [ 'apple', 'pear', 'banana', 'tomato' ] %}
<h1>Grocery list</h1>
<ul>
{% while $item = array_pop($fruits) %}
<li>{{ ucfirst($item) }}</li>
{% or %}
<li class="empty">We should never see this, since the list is always populated !</li>
{% endwhile %}
</ul>
```
**[HTML]** Would render as such:
```html
<h1>Grocery list</h1>
<ul>
<li>Apple</li>
<li>Pear</li>
<li>Banana</li>
<li>Tomato</li>
</ul>
```
## Loop using `do` / `continue` / `break` / `while`
This syntax do not have an alternative syntax in vanilla PHP.
Picea allows for this unusual syntax to be used the same way you would with any other control structure.
There is, however, no support for the `or` clause for this structure since it will iterate at least once.
**[PICEA]** So, using this code:
```html
<h1>Random number generator</h1>
<ul>
{% do %}
{% php $number = random_int(1, 25); %}
{% if $number === 10 %}
{# For a reason I'm not entirely sure why, 10 must not be displayed ! #}
{% continue %}
{% endif %}
<li>{{ str_pad($number, 2, '0' ,STR_PAD_LEFT) }}</li>
{% while $number !== 15 %} {# Loop stops whenever $number is equal to 15 #}
</ul>
```
**[HTML]** Could render as such:
```html
<h1>Random number generator</h1>
<ul>
<li>02</li>
<li>12</li>
<li>07</li>
<li>13</li>
<li>04</li>
<li>07</li>
<li>01</li>
<li>16</li>
<li>14</li>
<li>24</li>
<li>14</li>
<li>01</li>
<li>15</li>
</ul>
```