Skip to main content
Post Undeleted by Mats Mikkel Rummelhoff
added 3125 characters in body
Source Link

You're correctdealing with scope issues – both related to for loops and in regards to extending templates (blocks).

First, any variable set insideinside a for loop will not be available outside that loop.

{% set homeFeature = null %}
{% for entry in entries %}
    {% set homeFeature = entry.id %}
{% endfor %}

<p>The home feature's ID is {{ homeFeature }}</p>

For {% block %} tags, the same applies – any variable set inside a block is not available outside that block. Much like with for loops, you can declare a variable outside a block, and it will be available inside the block. However, unlike with for loops if you change the value of that variable inside a block, the updated variable will not be available to other blocks in the same template. In other words, this doesn't work:

{% extends '_layout' %}

{% set homeFeature = null %}

{% block headerContent %}
    {% set homeFeature = 'foo' %}
{% endblock %}

{% block content %}
    {{ homeFeature }} {# Still a `null` value! #}
{% endblock %}

There are a lot of potential workarounds to your specific issue, though.

First, since you can set a variable outside the blocks, something like this would work – simply execute the craft.entries query for the featured entry outside the blocks, and store the result in a variable that can be accessed inside the blocks:

{% extends '_layout' %}

{% set homeFeature = craft.entries({
    section: 'articles',
    limit: 1,
    featuredOnHomepage: '1'
}).first() %}

{% block headercontent %}
    <div id="home-featured">
        {% if homeFeature %}<h1>The feature id is: {{ homeFeature.id }}</h1>{% endif %}
    </div>
{% endblock %}

{% block content %}
    {% set entries = craft.entries({
        section:        'articles',
        order:          'postDate',
        limit:          4,
        id: homeFeature ? 'not '~homeFeature.id : null
    }) %}
    ...
{% endblock %}

The drawback with the above, is that it's going to be difficult to {% cache %} the craft.entries query outside the blocks. For a single, basic query this probably doesn't matter much in the scheme of things, though.

Another approach is to simply query for the homeFeature entry inside each {% block %}. You can even make things a bit more DRY by storing the actual query parameters in a variable outside the blocks:

{% extends '_layout' %}

{% set homeFeatureQuery = {
    section: 'articles',
    limit: 1,
    featuredOnHomepage: '1'
} %}

{% block headercontent %}
    <div id="home-featured">
        {% set homeFeature = craft.entries(homeFeatureQuery).first() %}
        {% if homeFeature %}<h1>The feature id is: {{ homeFeature.id }}</h1>{% endif %}
    </div>
{% endblock %}

{% block content %}
    {% set homeFeature = craft.entries(homeFeatureQuery).first() %}
    {% set entries = craft.entries({
        section:        'articles',
        order:          'postDate',
        limit:          4,
        id: homeFeature ? 'not '~homeFeature.id : null
    }) %}
    ...
{% endblock %}
    

Of course, the drawback with this approach is that you need to do two separate queries – but at least everything can be cached.

You're correct, any variable set inside a for loop will not be available outside that loop.

{% set homeFeature = null %}
{% for entry in entries %}
    {% set homeFeature = entry.id %}
{% endfor %}

<p>The home feature's ID is {{ homeFeature }}</p>

You're dealing with scope issues – both related to for loops and in regards to extending templates (blocks).

First, any variable set inside a for loop will not be available outside that loop.

{% set homeFeature = null %}
{% for entry in entries %}
    {% set homeFeature = entry.id %}
{% endfor %}

<p>The home feature's ID is {{ homeFeature }}</p>

For {% block %} tags, the same applies – any variable set inside a block is not available outside that block. Much like with for loops, you can declare a variable outside a block, and it will be available inside the block. However, unlike with for loops if you change the value of that variable inside a block, the updated variable will not be available to other blocks in the same template. In other words, this doesn't work:

{% extends '_layout' %}

{% set homeFeature = null %}

{% block headerContent %}
    {% set homeFeature = 'foo' %}
{% endblock %}

{% block content %}
    {{ homeFeature }} {# Still a `null` value! #}
{% endblock %}

There are a lot of potential workarounds to your specific issue, though.

First, since you can set a variable outside the blocks, something like this would work – simply execute the craft.entries query for the featured entry outside the blocks, and store the result in a variable that can be accessed inside the blocks:

{% extends '_layout' %}

{% set homeFeature = craft.entries({
    section: 'articles',
    limit: 1,
    featuredOnHomepage: '1'
}).first() %}

{% block headercontent %}
    <div id="home-featured">
        {% if homeFeature %}<h1>The feature id is: {{ homeFeature.id }}</h1>{% endif %}
    </div>
{% endblock %}

{% block content %}
    {% set entries = craft.entries({
        section:        'articles',
        order:          'postDate',
        limit:          4,
        id: homeFeature ? 'not '~homeFeature.id : null
    }) %}
    ...
{% endblock %}

The drawback with the above, is that it's going to be difficult to {% cache %} the craft.entries query outside the blocks. For a single, basic query this probably doesn't matter much in the scheme of things, though.

Another approach is to simply query for the homeFeature entry inside each {% block %}. You can even make things a bit more DRY by storing the actual query parameters in a variable outside the blocks:

{% extends '_layout' %}

{% set homeFeatureQuery = {
    section: 'articles',
    limit: 1,
    featuredOnHomepage: '1'
} %}

{% block headercontent %}
    <div id="home-featured">
        {% set homeFeature = craft.entries(homeFeatureQuery).first() %}
        {% if homeFeature %}<h1>The feature id is: {{ homeFeature.id }}</h1>{% endif %}
    </div>
{% endblock %}

{% block content %}
    {% set homeFeature = craft.entries(homeFeatureQuery).first() %}
    {% set entries = craft.entries({
        section:        'articles',
        order:          'postDate',
        limit:          4,
        id: homeFeature ? 'not '~homeFeature.id : null
    }) %}
    ...
{% endblock %}
    

Of course, the drawback with this approach is that you need to do two separate queries – but at least everything can be cached.

Post Deleted by Mats Mikkel Rummelhoff
Source Link

You're correct, any variable set inside a for loop will not be available outside that loop.

The solution is to declare the variable outside the loop:

{% set homeFeature = null %}
{% for entry in entries %}
    {% set homeFeature = entry.id %}
{% endfor %}

<p>The home feature's ID is {{ homeFeature }}</p>