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.