Jak mogę użyć break lub continue wewnątrz pętli for w szablonie gałązki?
Staram się używać prostej pętli, w moim prawdziwym kodzie pętla ta jest bardziej złożona i potrzebuję break
takiej iteracji jak:
{% for post in posts %}
{% if post.id == 10 %}
{# break #}
{% endif %}
<h2>{{ post.heading }}</h2>
{% endfor %}
Jak mogę wykorzystać zachowanie break
lub continue
struktur sterujących PHP w gałązce?
5 answers
From Docs TWIG docs :
W przeciwieństwie do PHP, nie jest możliwe przerwanie lub kontynuowanie w pętli.
Ale nadal:
Możesz jednak filtrować sekwencję podczas iteracji, co pozwala na pomijanie elementów.
Przykład:
{% for post in posts if post.id < 10 %}
<h2>{{ post.heading }}</h2>
{% endfor %}
Możesz nawet użyć własnych filtrów gałązek dla bardziej złożonych warunków, takich jak:
{% 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/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-24 21:49:47
Można to zrobić prawie ustawiając nową zmienną jako flagę nabreak
iterację:
{% set break = false %}
{% for post in posts if not break %}
<h2>{{ post.heading }}</h2>
{% if post.id == 10 %}
{% set break = true %}
{% endif %}
{% endfor %}
Bardziej brzydki, ale przykład pracy dla 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 %}
Ale nie ma zysku wydajności, tylko podobne zachowanie do wbudowanych
break
icontinue
Instrukcji, jak w flat PHP.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-13 08:06:13
From @ NHG comment-działa idealnie
{% 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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-10 14:27:21
Sposobem na użycie {% break %}
lub {% continue %}
jest napisanie TokenParser
s dla nich.
Zrobiłem to dla {% break %}
tokena w kodzie poniżej. Możesz, bez większych modyfikacji, zrobić to samo dla {% 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") ; } }
Wtedy możesz po prostu użyć {% break %}
, Aby get out of loops like this:
{% for post in posts %}
{% if post.id == 10 %}
{% break %}
{% endif %}
<h2>{{ post.heading }}</h2>
{% endfor %}
Aby przejść jeszcze dalej, możesz napisać parsery tokenów dla {% continue X %}
i {% break X %}
(gdzie X jest liczbą całkowitą >= 1), Aby wyjść/kontynuować wiele pętli, jak w PHP.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-03 15:25:01
Znalazłem dobre obejście do kontynuowania (uwielbiam próbkę przerwy powyżej). Tutaj nie chcę wymieniać "agencji". W PHP "kontynuowałbym", ale w gałązce wymyśliłem alternatywę:
{% for basename, perms in permsByBasenames %}
{% if basename == 'agency' %}
{# do nothing #}
{% else %}
<a class="scrollLink" onclick='scrollToSpot("#{{ basename }}")'>{{ basename }}</a>
{% endif %}
{% endfor %}
Lub po prostu go pomijam, jeśli nie spełnia moich kryteriów:
{% 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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-06 20:48:27