PHP counter Twig equivalent - php

Hello I would like do something like that with my Twig template
<?php
for( $i = 0; $i <= 5; $i++ ) {
// Not display the first number
if( $i <= 1 ) {
continue;
}
// Displaying numbers from 2 to 5
echo $i ,'<br/>';
}
?>
How can I do that ?
Thanks for your help.

From the documentation you can use this to iterate numbers
{% for i in 0..10 %}
* {{ i }}
{% endfor %}
Also from the documentation you can add conditions like this
<ul>
{% for user in users if user.active %}
<li>{{ user.username|e }}</li>
{% endfor %}
</ul>
So if you combine the two you end up with something like this.
{% for i in 0..5 if i<= 1 %}
* {{ i }}
{% endfor %}
Untested but should work.
THe documentation : http://twig.sensiolabs.org/doc/tags/for.html

If you literally just want to skip the first iteration, you can just do
{% for i in 1..5 %}
or
{% for i in 0..5 if loop.index0 %}
But assuming you want to actually do something more useful like some processing on the first iteration, then just only echo $i on subsequent iterations, this should work:
{% for i in 0..5 %}
This is printed every time...
{% if (loop.index0) %}
...but this is only printed when $i > 0: {{ i }}<br />
{% endif %}
{% endfor %}
There's not a "continue" keyword or any equivalent in Twig as far as I know.

Related

Print Twig variable x times based upon randomized range

I am using Twig and Timber for a WordPress project. I have the following loop in my template that prints my custom post type titles into a HTML structure.
{% for company in companies %}
{% set dot = "<div class='company-dot'></div>" %}
{% set range = range(10, 20) %}
{{dot}}
{{random(range)}}
<div class="company">
<div class="company-dot dot-active"></div>
<p class="dot-caption">{{ company.title }}</p>
</div>
{% endfor %}
I would like to print my {{dot}} variable x amount of times based upon the number that is generated by {{random(range)}}. How can I do this?
The simplest solution would be to iterate random(range) times with a for loop:
{% for i in 0..random(range(10, 20)) %}
{{ dot }}
{% endfor %}
I don't really know Twig but my guess is that you could to the following:
{% for i in random(range) %}
{{dot}}
{% endfor %}
You already know how to use range, just use it again :
{% set dots_count = random(range) %}
{% for dot_index in range(1,dots_count) %}
{{dot}}
{% endfor %}
{{dots_count}}
Here is a fiddle : https://twigfiddle.com/ko595z

Looping on number value TWIG

I would like to loop on this variable that I have created before :
{% set divisionElement = (elementsLength/2)|round|number_format(0) %}
The output of this is a number.
After that I would like to create a loop with this value like that :
{% for i in divisionElement %}
{{dump(i}}
{% endfor %}
When I tried to dump i in my loop I have nothing result.
Try using range, If divisionElement is > 0
{% for i in range(1, divisionElement ) %}
{{ i }},
{% endfor %}

How do I make a simple count loop in Wordpress Timber(Twigg)?

How do I make a simple count loop in Wordpress Timber(Twigg)?
So basically just a loop like this:
($i = 0;0 < 3;i++){
echo $test[i];
}
You could use
{% for value in test %}
{{ value }}
{% endfor %}
that is safer than
{% for i in 0..2 %}
{{ test[i] }}
{% endfor %}
because in second version you have to care about index (is setted? and so on) whereas in the first you don't.
Of course if your final goal is to print only three elements from the array you should consider slice filter
{% for value in test|slice(0, 3) %}
{{ value }}
{% endfor %}

numeric loop in volt

I have read the volt documentation in phalcon page and i cant find any example for this...
You can make easy loops in objects, for example, in php:
foreach($pages as $page){
echo $page->title;
}
in volts would be ...
{% for page in pages %}
{{ page.title }}
{% endfor %}
My question is, how i can make a normal numerical loop in volt? For example:
for($n=1;$n<10;$n++){
echo $n;
}
Thanks.
This will count from 1 to 10
{% for i in 1..10 %}
{{ i }}
{% endfor %}

How can I use break or continue within for loop in Twig template?

I try to use a simple loop, in my real code this loop is more complex, and I need to break this iteration like:
{% for post in posts %}
{% if post.id == 10 %}
{# break #}
{% endif %}
<h2>{{ post.heading }}</h2>
{% endfor %}
How can I use behavior of break or continue of PHP control structures in Twig?
This can be nearly done by setting a new variable as a flag to break iterating:
{% set break = false %}
{% for post in posts if not break %}
<h2>{{ post.heading }}</h2>
{% if post.id == 10 %}
{% set break = true %}
{% endif %}
{% endfor %}
An uglier, but working example for continue:
{% set continue = false %}
{% for post in posts %}
{% if post.id == 10 %}
{% set continue = true %}
{% endif %}
{% if not continue %}
<h2>{{ post.heading }}</h2>
{% endif %}
{% if continue %}
{% set continue = false %}
{% endif %}
{% endfor %}
But there is no performance profit, only similar behaviour to the built-in break and continue statements like in flat PHP.
From docs TWIG 2.x docs:
Unlike in PHP, it's not possible to break or continue in a loop.
But still:
You can however filter the sequence during iteration which allows you to skip items.
Example 1 (for huge lists you can filter posts using slice, slice(start, length)):
{% for post in posts|slice(0,10) %}
<h2>{{ post.heading }}</h2>
{% endfor %}
Example 2 works TWIG 3.0 as well:
{% for post in posts if post.id < 10 %}
<h2>{{ post.heading }}</h2>
{% endfor %}
You can even use own TWIG filters for more complexed conditions, like:
{% for post in posts|onlySuperPosts %}
<h2>{{ post.heading }}</h2>
{% endfor %}
A way to be able to use {% break %} or {% continue %} is to write TokenParsers for them.
I did it for the {% break %} token in the code below. You can, without much modifications, do the same thing for the {% continue %}.
AppBundle\Twig\AppExtension.php:
namespace AppBundle\Twig;
class AppExtension extends \Twig_Extension
{
function getTokenParsers() {
return array(
new BreakToken(),
);
}
public function getName()
{
return 'app_extension';
}
}
AppBundle\Twig\BreakToken.php:
namespace AppBundle\Twig;
class BreakToken extends \Twig_TokenParser
{
public function parse(\Twig_Token $token)
{
$stream = $this->parser->getStream();
$stream->expect(\Twig_Token::BLOCK_END_TYPE);
// Trick to check if we are currently in a loop.
$currentForLoop = 0;
for ($i = 1; true; $i++) {
try {
// if we look before the beginning of the stream
// the stream will throw a \Twig_Error_Syntax
$token = $stream->look(-$i);
} catch (\Twig_Error_Syntax $e) {
break;
}
if ($token->test(\Twig_Token::NAME_TYPE, 'for')) {
$currentForLoop++;
} else if ($token->test(\Twig_Token::NAME_TYPE, 'endfor')) {
$currentForLoop--;
}
}
if ($currentForLoop < 1) {
throw new \Twig_Error_Syntax(
'Break tag is only allowed in \'for\' loops.',
$stream->getCurrent()->getLine(),
$stream->getSourceContext()->getName()
);
}
return new BreakNode();
}
public function getTag()
{
return 'break';
}
}
AppBundle\Twig\BreakNode.php:
namespace AppBundle\Twig;
class BreakNode extends \Twig_Node
{
public function compile(\Twig_Compiler $compiler)
{
$compiler
->write("break;\n")
;
}
}
Then you can simply use {% break %} to get out of loops like this:
{% for post in posts %}
{% if post.id == 10 %}
{% break %}
{% endif %}
<h2>{{ post.heading }}</h2>
{% endfor %}
To go even further, you may write token parsers for {% continue X %} and {% break X %} (where X is an integer >= 1) to get out/continue multiple loops like in PHP.
From #NHG comment — works perfectly
{% for post in posts|slice(0,10) %}
I have found a good work-around for continue (love the break sample above).
Here I do not want to list "agency". In PHP I'd "continue" but in twig, I came up with alternative:
{% for basename, perms in permsByBasenames %}
{% if basename == 'agency' %}
{# do nothing #}
{% else %}
<a class="scrollLink" onclick='scrollToSpot("#{{ basename }}")'>{{ basename }}</a>
{% endif %}
{% endfor %}
OR I simply skip it if it doesn't meet my criteria:
{% for tr in time_reports %}
{% if not tr.isApproved %}
.....
{% endif %}
{% endfor %}

Categories