¿Cómo puedo usar la plantilla break o continue dentro de for loop in Twig?
Trato de usar un bucle simple, en mi código real este bucle es más complejo, y necesito break
esta iteración como:
{% for post in posts %}
{% if post.id == 10 %}
{# break #}
{% endif %}
<h2>{{ post.heading }}</h2>
{% endfor %}
¿Cómo puedo usar el comportamiento de break
o continue
de las estructuras de control PHP en Twig?
5 answers
De docs TWIG docs :
A diferencia de PHP, no es posible romper o continuar en un bucle.
Pero aún así:
Sin embargo, puede filtrar la secuencia durante la iteración, lo que le permite omitir elementos.
Ejemplo:
{% for post in posts if post.id < 10 %}
<h2>{{ post.heading }}</h2>
{% endfor %}
Incluso puede usar sus propios filtros TWIG para condiciones más complejas, como:
{% for post in posts|onlySuperPosts %}
<h2>{{ post.heading }}</h2>
{% endfor %}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-24 21:49:47
Esto puede ser casi hecho estableciendo una nueva variable como una bandera a break
iterando:
{% set break = false %}
{% for post in posts if not break %}
<h2>{{ post.heading }}</h2>
{% if post.id == 10 %}
{% set break = true %}
{% endif %}
{% endfor %}
Más feo, pero trabajo ejemplo para 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 %}
Pero no hay beneficio de rendimiento, solo un comportamiento similar a las instrucciones integradas
break
ycontinue
como en PHP plano.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-13 08:06:13
De @NHG comentario-funciona perfectamente
{% for post in posts|slice(0,10) %}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-10 14:27:21
Una forma de poder usar {% break %}
o {% continue %}
es escribir TokenParser
s para ellos.
Lo hice para el token {% break %}
en el código de abajo. Usted puede, sin muchas modificaciones, hacer lo mismo para el {% 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") ; } }
Entonces simplemente puede usar {% break %}
para sal de bucles como este:
{% for post in posts %}
{% if post.id == 10 %}
{% break %}
{% endif %}
<h2>{{ post.heading }}</h2>
{% endfor %}
Para ir aún más lejos, puede escribir analizadores de tokens para {% continue X %}
y {% break X %}
(donde X es un entero >= 1) para salir/continuar múltiples bucles como en PHP.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-03 15:25:01
He encontrado una buena solución para continuar (me encanta la muestra de descanso anterior). Aquí no quiero enumerar "agencia". En PHP "continuaría" pero en twig, se me ocurrió una alternativa:
{% for basename, perms in permsByBasenames %}
{% if basename == 'agency' %}
{# do nothing #}
{% else %}
<a class="scrollLink" onclick='scrollToSpot("#{{ basename }}")'>{{ basename }}</a>
{% endif %}
{% endfor %}
O simplemente lo omito si no cumple con mis criterios:
{% for tr in time_reports %}
{% if not tr.isApproved %}
.....
{% endif %}
{% endfor %}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-06 20:48:27