2014-02-10 31 views
52

我嘗試用一​​個簡單的循環,在我真正的代碼,這個循環是比較複雜的,我需要break本次迭代,如:如何在Twig模板的循環中使用break或continue?

{% for post in posts %} 
    {% if post.id == 10 %} 
     {# break #} 
    {% endif %} 
    <h2>{{ post.heading }}</h2> 
{% endfor %} 

如何使用的break或PHP控制結構的continue行爲枝條?

+1

@Peter它可以」 t是你的問題的重複,因爲這個問題被問及你的前一年:) –

+0

Touché。我立場糾正。 – Peter

+0

@RupaliPemare看看日期,*你的*鏈接是這個問題的重複:) –

回答

63

這可能是通過設置新的變量作爲標誌位來完成到break迭代:

{% set break = false %} 
{% for post in posts if not break %} 
    <h2>{{ post.heading }}</h2> 
    {% if post.id == 10 %} 
     {% set break = true %} 
    {% endif %} 
{% endfor %} 
0123對於

更難看,但工作例如:

{% 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 %} 

但有沒有性能的利潤,只有類似的行爲內置breakcontinue之類的語句在平PHP。

+1

這很有用。在我的情況下,我只需要顯示/獲得第一個結果。 Twig有沒有辦法獲得第一個值?這只是爲了更好的性能目的。 – Pathros

+1

@pathros爲了獲得第一個值,請使用'第一個'樹枝過濾器:http://twig.sensiolabs.org/doc/filters/first.html –

+0

喜歡這個筆記。一直在嘗試我最後的10分鐘發現一些並不真正有用的東西:D –

79

從文檔嫩枝docs

不像在PHP中,這是不可能的中斷或繼續在循環中。

但還是:

但是,您可以篩選迭代過程的順序,它允許您跳過的項目。

例子:

{% for post in posts if post.id < 10 %} 
    <h2>{{ post.heading }}</h2> 
{% endfor %} 

你甚至可以使用自己的TWIG filters更多的複合條件,如:

{% for post in posts|onlySuperPosts %} 
    <h2>{{ post.heading }}</h2> 
{% endfor %} 
+20

此外,如果你想在10次迭代後達到一個循環,你可以這樣使用:'{%for post in posts | slice(0,10) %}' – NHG

+2

好的,謝謝,我可能錯過了'與PHP不同,在閱讀文檔時不可能在循環中斷開或繼續。但我認爲'break'和'continue'是一個很好的功能,需要添加 –

+0

您無法在循環語句中訪問循環變量! – Maximus

5

的一種方法,以便能夠使用{% break %}{% continue %}是寫TokenParser對於他們。

我在下面的代碼中使用了{% break %}令牌。您可以在不做太多修改的情況下爲{% continue %}做同樣的事情。

  • 的appbundle \嫩枝\ AppExtension.php

    namespace AppBundle\Twig; 
    
    class AppExtension extends \Twig_Extension 
    { 
        function getTokenParsers() { 
         return array(
          new BreakToken(), 
         ); 
        } 
    
        public function getName() 
        { 
         return 'app_extension'; 
        } 
    } 
    
  • 的appbundle \嫩枝\ 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 \枝杈\ 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的整數)至get out/continue multiple loops like in PHP

+0

它是有道理的,謝謝! –

+6

這只是矯枉過正。枝條環應該支持休息,並繼續本地。 – crafter

+0

如果你不想/不能使用過濾器,這很好。 –

4

從@NHG評論 - 完美的作品

{% for post in posts|slice(0,10) %} 
+0

很好,謝謝! –

3

我找到了一個好工作,周圍繼續(愛上方突破樣品)。 這裏我不想列出「代理」。在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 %} 
相關問題