私は単純なループを使用しようとしますが、実際のコードではこのループはより複雑であり、この反復をbreak
する必要があります。
{% for post in posts %}
{% if post.id == 10 %}
{# break #}
{% endif %}
<h2>{{ post.heading }}</h2>
{% endfor %}
TwigのPHP制御構造のbreak
またはcontinue
の動作を使用するにはどうすればよいですか?
これは、新しい変数をフラグとして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 %}
もっといですが、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 %}
しかし、noパフォーマンスの利益があり、フラットPHPのような組み込み
break
およびcontinue
ステートメントと同様の動作のみがあります。
ドキュメントからTWIG docs :
PHPとは異なり、ループ内で中断したり継続したりすることはできません。
それでも:
ただし、反復中にシーケンスをフィルタリングして、アイテムをスキップできます。
例1(巨大なリストの場合、 slice 、slice(start, length)
を使用して投稿をフィルタリングできます):
{% for post in posts|slice(0,10) %}
<h2>{{ post.heading }}</h2>
{% endfor %}
例2:
{% for post in posts if post.id < 10 %}
<h2>{{ post.heading }}</h2>
{% endfor %}
次のように、より複雑な条件に対して独自の TWIGフィルター を使用することもできます。
{% for post in posts|onlySuperPosts %}
<h2>{{ post.heading }}</h2>
{% endfor %}
@NHGコメントより—完璧に機能
{% for post in posts|slice(0,10) %}
{% break %}
または{% continue %}
を使用できるようにする方法は、それらにTokenParser
sを書き込むことです。
以下のコードの{% break %}
トークンに対してそれを行いました。多くの変更をせずに、{% 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")
;
}
}
次に、{% break %}
を使用して、次のようなループから抜け出します。
{% for post in posts %}
{% if post.id == 10 %}
{% break %}
{% endif %}
<h2>{{ post.heading }}</h2>
{% endfor %}
さらに進むには、{% continue X %}
および{% break X %}
(Xは整数> = 1)のトークンパーサーを PHPのような複数のループの取得/継続 に記述します。
続行するための適切な回避策を見つけました(上記のブレークサンプルが大好きです)。ここでは、「代理店」をリストしたくありません。 PHPで「続行」しますが、小枝では、代替案を思いつきました。
{% for basename, perms in permsByBasenames %}
{% if basename == 'agency' %}
{# do nothing #}
{% else %}
<a class="scrollLink" onclick='scrollToSpot("#{{ basename }}")'>{{ basename }}</a>
{% endif %}
{% endfor %}
または、基準に合わない場合は単にスキップします。
{% for tr in time_reports %}
{% if not tr.isApproved %}
.....
{% endif %}
{% endfor %}