如何停止或摆脱 Twig 循环?
Posted
技术标签:
【中文标题】如何停止或摆脱 Twig 循环?【英文标题】:How to stop or break free from a Twig loop? 【发布时间】:2015-04-26 04:08:06 【问题描述】:在 php 中,您可以从循环中中断或继续下一次迭代。我想知道您是否在 Symfony 的 Twig 中拥有相同的功能。
例如,在 PHP 中我可以做到:
foreach ($array as $key => $value)
if ($value == 'something')
continue;
elseif ($value == 'somethingElse')
break;
echo $value;
在 Twig 中有类似的东西吗?例如:
% for value in array %
% if value == 'something' %
% continue %
% endif %
% if value == 'somethingElse' %
% break %
% endif %
value
% endfor %
【问题讨论】:
来自docs - “与 PHP 不同,它不可能在循环中中断或继续。但是,您可以在迭代期间过滤序列,从而允许您跳过项目。以下示例跳过所有不活跃的用户:" 是的 - 但您可以通过过滤器发挥创意来模拟休息时间。 How can I use break or continue within for in twig template?的可能重复 我为此使用 Angular.JS!看这里如何:http://***.com/questions/33853419/search-filter-angular-js-inside-twig-loop 我想给 CristiC777 的回答更多点赞。 Twig 是一种简单的模板语言,它是关于演示的。如果你不能在 Twig 中做某事,你可能有一些需要重写的时髦逻辑。如果您绝对必须“处理”数据,使用嵌入式控制器 (symfony.com/doc/current/templating/embedding_controllers.html) 会解决您的问题吗? IE。您不必担心页面上的逻辑,而是在控制器环境中按预期获取/解析数据集? 【参考方案1】:你可以这样做,以模拟模式:
% 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 %
只需将代码包装在条件中即可不继续。
为了打破使用从 for 循环外部可见的变量。
我猜你也可以编写自己的自定义 for 循环。
【讨论】:
这是正确答案,无需添加新的语言结构。【参考方案2】:我已经阅读了所有的答案,我同意他们,但并不完全正确,所以我决定也写我的。
首先,正如@CristiC777 在他的消息中指出的那样,如果您遇到需要中断 for 的情况,在此之前您做错了什么。您可能可以解决此问题,只需限制您的查询或取消设置数组中的数据。这是一个更好的解决方案,因为您将缩短响应时间并节省服务器内存。
Twig 视图要傻。如果你把一堆条件和变量放进去,你只会让它们不可读和不可维护。
如果由于某种原因您无法更改之前的代码,正如@Edgar Alloro 指出的那样,Twig 允许您更改为put conditions on a for(从 1.2 开始)。你的例子会变成这样:
% set keepFor = true %
% for value in array if keepFor %
% if value != 'valueExpected' %
% keepFor = false %
% endif %
value
% endfor %
您也可以自己实现,特别是如果您没有 Twig 1.2。如果你有 Twig 1.2 或更高版本我不建议这样做,因为 for 会迭代整个数组,你会花费更多的内存:
% set keepFor = true %
% for value in array %
% if keepFor %
% if value != 'valueExpected' %
% keepFor = false %
% endif %
value
% endif %
% endfor %
【讨论】:
我希望没有人使用 Twig 1.2,1.20 中有重大的安全修复。 如果您知道 Symfony 2.0 甚至 Symfony 1 中还有多少项目,您会感到惊讶。*【参考方案3】:首先!在controller中准备好你的数据并发送just你在twig中需要的东西!因为twig是view strong>,不建议玩大列表。想想当你在视图中加载很多你不使用的对象或实体时,你会发现自己处于这种情况..
因此,如果您仍然想过上艰难的生活,请使用 Edgar Alloro 解决方案,并在循环之前声明一个变量。或者我知道这个迭代有 LastIndex 尝试在你想停止循环时设置它..
玩得开心! ;)
【讨论】:
【参考方案4】:根据文档,不可能在循环中中断或继续。但是,您可以在迭代期间过滤序列,从而允许您跳过项目。下面的例子会跳过所有不活跃的用户:
<ul>
% for user in users if user.active %
<li> user.username </li>
% endfor %
</ul>
【讨论】:
【参考方案5】:使用这些类创建TwigExtension:
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")
;
然后你可以简单地使用% break %
来摆脱这样的循环:
% set var = ['foo', 'bar'] %
% for v in var %
v
% break %
% endfor %
我没有足够的时间编写代码,但您可以用同样的方式编写 continue
块。
更进一步,您可以处理 % continue X %
和 % break X %
以退出/继续多个循环,就像在 PHP 中一样。
如果有人想这样做并分享它,请随时编辑我的答案。
【讨论】:
这太棒了!谢谢!【参考方案6】:% set break = false %
% for value in array if not break %
% if value == 'something' %
% continue %
% endif %
% if value == 'somethingElse' %
% set break = true %
% endif %
value
% endfor %
【讨论】:
以上是关于如何停止或摆脱 Twig 循环?的主要内容,如果未能解决你的问题,请参考以下文章