मैं टहनी टेम्पलेट में लूप के लिए ब्रेक का उपयोग कैसे कर सकता हूं या जारी रख सकता हूं?


97

मैं एक साधारण लूप का उपयोग करने की कोशिश करता हूं, मेरे वास्तविक कोड में यह लूप अधिक जटिल है, और मुझे breakइस पुनरावृत्ति की आवश्यकता है :

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

मैं के व्यवहार कैसे उपयोग कर सकते हैं breakया continueटहनी में पीएचपी नियंत्रण संरचनाओं की?

जवाबों:


125

यह किया जा सकता है लगभग करने के लिए एक ध्वज के रूप में एक नया वेरिएबल सेट करके किया breakबार-बार दोहराना:

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

लेकिन कोई प्रदर्शन लाभ नहीं है, बिल्ट-इन breakऔर continueफ्लैट PHP जैसे बयानों के लिए केवल समान व्यवहार है ।


1
यह उपयोगी है। मेरे मामले में मुझे केवल पहला परिणाम दिखाने / प्राप्त करने की आवश्यकता है। क्या सिर्फ पहला मूल्य प्राप्त करने के लिए ट्विग में एक तरीका है? यह केवल बेहतर प्रदर्शन उद्देश्यों के लिए है।
पाथ्रो

1
@pathros पहला मान प्राप्त करने के लिए, ट्विगfirst फिल्टर का उपयोग करें : twig.sensiolabs.org/doc/filters/first.html
विक्टर बोकार्स्की

1
नोट से प्यार करो। मेरे पिछले 10mins की कोशिश कर रहा है कुछ ऐसा है जो वास्तव में मददगार नहीं है: D
ट्री गुयेन

2
यह ध्यान देने योग्य है कि इससे कोड निष्पादन नहीं टूटेगा, नीचे कुछ भी set break = trueनिष्पादित किया जाएगा जब तक कि आप इसे एक elseबयान में नहीं डालते । Twigfiddle.com/euio5w
गस

2
@Gus हाँ, यही कारण है कि अगर मैं बयान के साथ set break = trueबहुत अंत में था । लेकिन हाँ, यह आपके कोड पर निर्भर करता है, इसलिए इसे स्पष्ट करने के लिए धन्यवाद देने के लिए धन्यवाद
विक्टर बोचरस्की

120

डॉक्स TWIG डॉक्स से :

PHP के विपरीत, लूप को तोड़ना या जारी रखना संभव नहीं है।

फिर भी:

हालांकि आप पुनरावृत्ति के दौरान अनुक्रम को फ़िल्टर कर सकते हैं जो आपको आइटम को छोड़ने की अनुमति देता है।

उदाहरण 1 (विशाल सूची के लिए आपके द्वारा उपयोग किए पदों फ़िल्टर कर सकते हैं टुकड़ा , 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 %}

28
इसके अलावा अगर आप 10 बार चलना चाहते हैं तो आप इस तरह से sth का उपयोग कर सकते हैं:{% for post in posts|slice(0,10) %}
NHG

5
ठीक है, धन्यवाद, Unlike in PHP, it's not possible to break or continue in a loop.डॉक्स पढ़ने पर मैं शायद चूक गया। लेकिन मुझे लगता है breakऔर continueएक अच्छा सुविधाओं, जो जोड़ने की जरूरत होती है
विक्टर Bocharsky

आप लूप स्टेटमेंट में लूप वेरिएबल तक नहीं पहुंच सकते हैं!
मैक्सिमस

काम नहीं करता है। लंबी सूची, forपहली हिट के बाद ब्रेक करने योग्य होनी चाहिए।
@VictorBocharsky का

@VasiliiSuricov आप {% for post in posts|slice(0,10) %}बड़ी सूची के लिए उपयोग कर सकते हैं । मेरी पहली टिप्पणी देखें। मैंने अपना उत्तर भी अपडेट कर दिया है।
एनएचजी

12

उनके लिए s लिखने {% break %}या उपयोग करने में सक्षम होने का एक तरीका ।{% continue %}TokenParser

मैंने इसे {% 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 %}

इससे भी आगे जाने के लिए, आप PHP की तरह कई छोरों को बाहर निकालने / जारी रखने के लिए {% continue X %}और {% break X %}(जहां X एक पूर्णांक> = 1 है) के लिए टोकन पार्सर लिख सकते हैं ।


10
वह सिर्फ ओवरकिल है। टहनी छोरों को विराम का समर्थन करना चाहिए और मूल रूप से जारी रखना चाहिए।
crafter

यदि आप फ़िल्टर का उपयोग नहीं करना चाहते हैं तो यह अच्छा है।
डैनियल डेहर्स्ट

squirrelphp/twig-php-syntaxपुस्तकालय प्रदान करता है {% break %}, {% break n %}और {% continue %}टोकन।
एमटी

@mtsknn और लेखकों ने उस कोड का उपयोग और सुधार किया जो मैंने इस उत्तर के लिए लिखा था!
जूल्स लामुर

@JulesLamur, आपने कहा "@mtsknn और लेखक," लेकिन मैं उस लाइब्रेरी से शामिल नहीं हूं।
mts kn

9

@ एनएचजी टिप्पणी से - पूरी तरह से काम करता है

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

@ यदि पोस्ट के अनुसार आदेश दिए गए हैं, तो बताएं?
वासिलि सुरिकोव

6

मैंने जारी रखने के लिए एक अच्छा काम किया है। यहां मैं "एजेंसी" को सूचीबद्ध नहीं करना चाहता। 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 %}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.