In PHP you've got the possibility to break from a loop or continue to the next iteration. I was wondering if you've got the same functionality in Symfony's Twig.
For example, in PHP I am able to do:
foreach ($array as $key => $value) {
if ($value == 'something') {
continue;
} elseif ($value == 'somethingElse') {
break;
}
echo $value;
}
Is there something similiar in Twig? For example something like:
{% for value in array %}
{% if value == 'something' %}
{% continue %}
{% endif %}
{% if value == 'somethingElse' %}
{% break %}
{% endif %}
{{ value }}
{% endfor %}
You could do something like this, in order to simulate the pattern:
{% set breakLoop = false %}
{% for value in array if breakLoop == false %}
{% if value == 'somethingElse' %}
{% breakLoop = true %}
{% endif %}
{% if value != 'something' and breakLoop == false %}
{{ value }}
{% endif %}
{% endfor %}
Just wrap the code inside the condition to not continue.
For breaking use a variable visible from outside the for loop.
You could also write your own, custom for loop, I guess.
I've read all the answers and I agree with them but aren't totally right, so I decided to write mine too.
First of all, as @CristiC777 pointed in his message, if you reach the case where you need to break a for, you are doing something wrong before this point . You probably can fix this just putting a limit on your queries or unsetting data from your arrays. This is a better solution because you will improve the response time and save server memory.
Twig views need to be silly. If you put a bunch of conditions and variables into them, you will only make them unreadable and unmaintenable.
If, for some reason, you cannot change the previous code, as @Edgar Alloro pointed, Twig allows you to put conditions on a for (since 1.2). Your example will change to something like this:
{% set keepFor = true %}
{% for value in array if keepFor %}
{% if value != 'valueExpected' %}
{% keepFor = false %}
{% endif %}
{{ value }}
{% endfor %}
You can also do your own implementation, specially if you don't have Twig 1.2. If you have Twig 1.2 or above I do not recommend this because the for will iterate the entire array and you will spend more memory :
{% set keepFor = true %}
{% for value in array %}
{% if keepFor %}
{% if value != 'valueExpected' %}
{% keepFor = false %}
{% endif %}
{{ value }}
{% endif %}
{% endfor %}
First of all !
prepare your data in controller and send just what you need in twig !
because twig is view , and is not recommend to play with big lists. Think about you can find yourself in the situation when you load in view a lot of objects or entities that you don't use ..
so if you still want do have a hard life use Edgar Alloro solution with a variable declared before loop. Or I know this iteration has LastIndex try to set that when you want to brake the loop..
Have fun ! ;)
according to documentation, it's not possible to break or continue in a loop. You can however filter the sequence during iteration which allows you to skip items. The following example skips all the users which are not active:
<ul>
{% for user in users if user.active %}
<li>{{ user.username }}</li>
{% endfor %}
</ul>
Create a TwigExtension using these classes:
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; try { // This "try" is because look() will throws a PHP exception if $this->current - $i is negative (where $this is $stream). for ($i = 1; true; $i++) { $token = $stream->look(-$i); if ($token->test(\\Twig_Token::NAME_TYPE, 'for')) { $currentForLoop++; } else if ($token->test(\\Twig_Token::NAME_TYPE, 'endfor')) { $currentForLoop--; } } } catch (\\Exception $e) { } 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:
{% set var = ['foo', 'bar'] %}
{% for v in var %}
{{ v }}
{% break %}
{% endfor %}
I don't have enough time to code it, but you could write the continue
block the same way.
To go even further, you may handle {% continue X %}
and {% break X %}
to get out/continue multiple loops like in PHP.
If someone wants to do it and share it, feel free to edit my answer.
{% set break = false %}
{% for value in array if not break %}
{% if value == 'something' %}
{% continue %}
{% endif %}
{% if value == 'somethingElse' %}
{% set break = true %}
{% endif %}
{{ value }}
{% endfor %}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.