TransWikia.com

Adding entries to the top level scope of a variable in Twig

Craft CMS Asked by Rune Sandnes on February 17, 2021

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?

One 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.

Correct answer by Martin Spain on February 17, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP