Answers.Body: <p>Just to provide a slight improvement to @Matanya's solution: Instead of filtering the array of Neo blocks, you can limit your query to the blocks you actually want. This way, you're not loading blocks you don't actually need. For example, to only get level one blocks:</p>
  <pre class="lang-twig prettyprint-override"><code>{% for module in entry.pageBuilder.level(1).all() %}
  </code></pre>
  <p>See the <a href="https://github.com/spicywebau/craft-neo/blob/master/docs/templating.md" rel="nofollow noreferrer">Templating docs for Neo</a> for details.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-11-30T09:20:31.017Z
Answers.Text: Thanks @MoritzLost. This is definitely better
Answers.UserDisplayName: Matanya
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-12-01T01:10:21.733Z
Answers.Text: I was looking in completely the wrong spot for the conditional that was causing the problem. I was looking at the inner conditional and had code blindness for the one on the `for` loop itself. :/ Thanks both for pointing me in the right direction! 
Answers.UserDisplayName: Tyssen
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-11-30T09:19:09.387Z
Answers.LastActivityDate: 2021-11-30T09:19:09.387Z
Answers.UserDisplayName: MoritzLost
Answers.Body: <p>This is a Twig exception. When you are using an <code>if</code> condition on the <code>for</code> loop itself Twig has no way of knowing how many elements will be iterated over, or whether it is the first or last element.</p>
  <p>See: <a href="https://github.com/twigphp/Twig/issues/687" rel="nofollow noreferrer">https://github.com/twigphp/Twig/issues/687</a></p>
  <p>I see that support for using <code>if</code> on <code>for</code> loops was removed altogether on v3:
  <a href="https://github.com/twigphp/Twig/commit/dca3f74e49d8a2a3ffebeba826daeb8de014d286#diff-ecec88c33adb7591ee6aa88e29b62ad52ef443611cba5e0f0ecac9b5725afdbaR3" rel="nofollow noreferrer">https://github.com/twigphp/Twig/commit/dca3f74e49d8a2a3ffebeba826daeb8de014d286#diff-ecec88c33adb7591ee6aa88e29b62ad52ef443611cba5e0f0ecac9b5725afdbaR3</a></p>
  <p>Craft appears to be using v2, which is why this is still supported.
  <a href="https://github.com/craftcms/cms/blob/4330199e5b7001ca85b9d919d81e465dcc275742/composer.json#L52" rel="nofollow noreferrer">https://github.com/craftcms/cms/blob/4330199e5b7001ca85b9d919d81e465dcc275742/composer.json#L52</a></p>
  <p>A possible solution would be to use a filter instead, so rather than pruning irrelevant records during iteration, you serve twig the full pre-filtered array in advance.
  <a href="https://twig.symfony.com/doc/2.x/filters/filter.html" rel="nofollow noreferrer">https://twig.symfony.com/doc/2.x/filters/filter.html</a></p>
  <pre><code>{% for module in entry.pageBuilder.all() | filter(module=&gt;module.level == 1) %}
  </code></pre>
  <p>Not tested of course</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-11-30T08:55:24.407Z
Answers.LastActivityDate: 2021-11-30T09:01:37.927Z
Answers.LastEditDate: 2021-11-30T09:01:37.927Z
Answers.UserDisplayName: Matanya
Body: <p>I have a Neo field that contains blocks for hero, body, button etc. For every block except hero, I want them to be wrapped in a containing element. So I have this:</p>
  <pre><code>{% for module in entry.pageBuilder.all() if module.level == 1 %}
    {% if module.type == 'moduleHero' %}
      {% include '_partials/page-builder/_moduleHero' %}
    {% else %}
      {% if loop.index == 2 %}
        &lt;div class=&quot;container mx-auto&quot;&gt;
          &lt;div class=&quot;px-4 py-12&quot;&gt;
            &lt;div class=&quot;content clearfix&quot;&gt;
        {% endif %}
  
            {% include '_partials/page-builder/_' ~ module.type %}
  
        {% if loop.last %}
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      {% endif %}
    {% endif %}
  {% endfor %}
  </code></pre>
  <p>I only want the containing element at the beginning and end of the loop.</p>
  <p>But with this code I get:</p>
  <blockquote>
  <p>The &quot;loop.last&quot; variable is not defined when looping with a condition.</p>
  </blockquote>
  <p>Which I don't understand. Can someone explain why that is?</p>
  
Tags: <loop><plugin-neo>
Title: `loop.last` throws 'variable is not defined when looping with a condition' error
ThreadText: # `loop.last` throws 'variable is not defined when looping with a condition' error
  
  (Asked by: username_0 on 2021-11-30)
  
  I have a Neo field that contains blocks for hero, body, button etc. For every block except hero, I want them to be wrapped in a containing element. So I have this:
  
  ```
  {% for module in entry.pageBuilder.all() if module.level == 1 %}
    {% if module.type == 'moduleHero' %}
      {% include '_partials/page-builder/_moduleHero' %}
    {% else %}
      {% if loop.index == 2 %}
        <div class="container mx-auto">
          <div class="px-4 py-12">
            <div class="content clearfix">
        {% endif %}
  
            {% include '_partials/page-builder/_' ~ module.type %}
  
        {% if loop.last %}
          </div>
        </div>
      </div>
      {% endif %}
    {% endif %}
  {% endfor %}
  
  ```
  
  I only want the containing element at the beginning and end of the loop.
  
  But with this code I get:
  
  > The "loop.last" variable is not defined when looping with a condition.
  
  Which I don't understand. Can someone explain why that is?
  
  **Tags:** loop, plugin-neo
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_1 on 2021-11-30. Score: 3 | Accepted answer
  
  Just to provide a slight improvement to @username_2's solution: Instead of filtering the array of Neo blocks, you can limit your query to the blocks you actually want. This way, you're not loading blocks you don't actually need. For example, to only get level one blocks:
  
  ```twig
  {% for module in entry.pageBuilder.level(1).all() %}
  
  ```
  
  See the [Templating docs for Neo](https://github.com/spicywebau/craft-neo/blob/master/docs/templating.md) for details.
  
  > **Comments:**
  > **username_2**: Thanks @username_1. This is definitely better  
  > **username_0**: I was looking in completely the wrong spot for the conditional that was causing the problem. I was looking at the inner conditional and had code blindness for the one on the `for` loop itself. :/ Thanks both for pointing me in the right direction!   
  
  ---
  
  ### Answer by username_2 on 2021-11-30. Score: 2
  
  This is a Twig exception. When you are using an `if` condition on the `for` loop itself Twig has no way of knowing how many elements will be iterated over, or whether it is the first or last element.
  
  See: <https://github.com/twigphp/Twig/issues/687>
  
  I see that support for using `if` on `for` loops was removed altogether on v3:
  <https://github.com/twigphp/Twig/commit/dca3f74e49d8a2a3ffebeba826daeb8de014d286#diff-ecec88c33adb7591ee6aa88e29b62ad52ef443611cba5e0f0ecac9b5725afdbaR3>
  
  Craft appears to be using v2, which is why this is still supported.
  <https://github.com/craftcms/cms/blob/4330199e5b7001ca85b9d919d81e465dcc275742/composer.json#L52>
  
  A possible solution would be to use a filter instead, so rather than pruning irrelevant records during iteration, you serve twig the full pre-filtered array in advance.
  <https://twig.symfony.com/doc/2.x/filters/filter.html>
  
  ```
  {% for module in entry.pageBuilder.all() | filter(module=>module.level == 1) %}
  
  ```
  
  Not tested of course
  
  
  ---
  
  