<p>I'm working on solving a similar problem and I've come up with a solution that stores a string of comma-delimited IDs in the session like this:</p>
<pre><code>{% set displayedContentIds = craft.app.session.get('displayedContentIds')|split(',') %}
</code></pre>
<p>This code is added to all components on the page that are required to exclude content that's already been shown further up the page. I pass the array of IDs to the entry query for that block, if there are IDs to exclude:</p>
<pre><code>{% set criteria = {
    section: 'mySection',
    limit: 5
} %}

{% if displayedContentIds|length &gt; 0 %}
    {% set criteria = criteria|merge({ id: 'and, ' ~ displayedContentIds|join(', not') }) %}
{% endif %}

{% set entries = craft.entries(criteria) %}
</code></pre>
<p>I output my entries as normal with <code>entries.all()</code>, then I update <code>displayedContentIds</code> with the just-displayed entry IDs:</p>
<pre><code>{% set displayedContentIds = &quot;#{displayedContentIds},#{entries.ids()|join(',')}&quot; %}
{% do craft.app.session.set('displayedContentIds', displayedContentIds) %}
</code></pre>
<p>This is a bit crude if I'm honest, but it's the only way I can think of to update a variable inside a block and have the updated value available to blocks further down the page.</p>

CC BY-SA 4.0
2020-10-20T14:57:36.863Z
One man's crude is another man's elegant! With small modifications this worked perfectly for me, thanks!
Rune Sandnes
CC BY-SA 4.0
2020-10-19T18:13:20.720Z
2020-10-20T11:41:13.367Z
2020-10-20T11:41:13.367Z
Martin Spain
<p>I have made a frontpage editing system where the user can desk a frontpage, adding news items and other blocks manually. One of the blocks is &quot;Last n news items&quot;. I would like this to include the last added news posts, <em>except</em> the ones that are already added manually.</p>
<p>I create an array called <code>shownNews</code> and add items to it each time the &quot;show news item&quot; block is called. My problem is probably related to variable scoping, the array is updated locally, but not in the global page scope.</p>
<pre><code>{% set shownNews = [] %}

    {% for block in entry.layout.all() %}
        {% include '_blocks/' ~  block.type %}
    {% endfor %}
</code></pre>
<p>And then inside the included block I call</p>
<pre><code>{% set entry = block.article.one() %}
{% set shownNews = shownNews|merge([entry.id]) %}
</code></pre>
<p>If I output the <code>shownNews</code> variable at this point inside the block it has correcly added the id to the array, but it is not available to the next block that is called.</p>
<p>I believed that if I declared the array on the top level it would be available for the included blocks both for reading (which works) and writing (which doesn't). What am I doing wrong here?</p>

<templating><scope>
Adding entries to the top level scope of a variable in Twig
# Adding entries to the top level scope of a variable in Twig

(Asked by: username_0 on 2020-10-19)

I have made a frontpage editing system where the user can desk a frontpage, adding news items and other blocks manually. One of the blocks is "Last n news items". I would like this to include the last added news posts, except the ones that are already added manually.
I create an array called shownNews and add items to it each time the "show news item" block is called. My problem is probably related to variable scoping, the array is updated locally, but not in the global page scope.
{% set shownNews = [] %}

    {% for block in entry.layout.all() %}
        {% include '_blocks/' ~  block.type %}
    {% endfor %}

And then inside the included block I call
{% set entry = block.article.one() %}
{% set shownNews = shownNews|merge([entry.id]) %}

If I output the shownNews variable at this point inside the block it has correcly added the id to the array, but it is not available to the next block that is called.
I believed that if I declared the array on the top level it would be available for the included blocks both for reading (which works) and writing (which doesn't). What am I doing wrong here?

**Tags:** templating, scope

---

## 1 answers

### Answer by username_1 on 2020-10-19. Score: 1 | Accepted answer

I'm working on solving a similar problem and I've come up with a solution that stores a string of comma-delimited IDs in the session like this:
{% set displayedContentIds = craft.app.session.get('displayedContentIds')|split(',') %}

This code is added to all components on the page that are required to exclude content that's already been shown further up the page. I pass the array of IDs to the entry query for that block, if there are IDs to exclude:
{% set criteria = {
    section: 'mySection',
    limit: 5
} %}

{% if displayedContentIds|length > 0 %}
    {% set criteria = criteria|merge({ id: 'and, ' ~ displayedContentIds|join(', not') }) %}
{% endif %}

{% set entries = craft.entries(criteria) %}

I output my entries as normal with entries.all(), then I update displayedContentIds with the just-displayed entry IDs:
{% set displayedContentIds = "#{displayedContentIds},#{entries.ids()|join(',')}" %}
{% do craft.app.session.set('displayedContentIds', displayedContentIds) %}

This is a bit crude if I'm honest, but it's the only way I can think of to update a variable inside a block and have the updated value available to blocks further down the page.

> **Comments:**
> **username_0**: One man's crude is another man's elegant! With small modifications this worked perfectly for me, thanks!  

---

