1

-- UPDATED --

My understanding of how the cache busting works is to make sure the query is within the {% cache %} tag. When looking into how it works I may not really be understanding the ins and outs of using the cache tag properly. Correct me if I'm wrong.

The goal with this example is to show posts on the index and any category page that excludes cateogry-one unless a user is viewing the category one page.

If I have an entry that is initially not tagged with category-one and it will output as expected as well as when I tag that entry with that category. However if I were to again edit that entry and remove category one the cache doesn't bust and won't output the entry.

Blog Index Code:

{# Get all the categories you want to INCLUDE #}
{% set categoryIds = craft.categories()
    .group('categories')
    .slug('category-one')
    .ids() %}

{% set excludeIds = craft.entries()
    .relatedTo({
        targetElement: categoryIds
    })
    .ids() %}

{% cache globally using key craft.app.request.pathInfo ~ '/p' ~ craft.app.request.pageNum %}

    {% set blogEntriesCriteria = craft.entries({
        section: 'blog',
        id: ['not']|merge(excludeIds),
        with: ([
            ['image', {
               withTransforms: ['medium']
            }]
        ])
    }) %}
    {% set isFirstPage = craft.app.request.pageNum() == 1 %}
    {% set limit = 10 %}
    {% paginate blogEntriesCriteria.limit(limit) as pageInfo, blogEntries %}

    {% if blogEntries %}

        {# Loop through this page's News entries #}
        {% for entry in blogEntries %}

            {% include 'includes/components/_news-card' %}

        {% endfor %}

    {% else %}

        <p>Sorry, no posts found.</p>

    {% endif %}

{% endcache %}

Blog Category Code:

{% set catIdCheck = false %}

{# Get all the categories you want to INCLUDE #}
{% set categoryIds = craft.categories()
    .group('categories')
    .slug('category-one')
    .ids() %}

{% set excludeIds = craft.entries()
    .relatedTo({
        targetElement: categoryIds
    })
    .ids() %}

{% if category.id == categoryIds[0] %}
    {% set catIdCheck = true %}
{% endif %}

{% cache globally using key craft.app.request.pathInfo ~ '/p' ~ craft.app.request.pageNum %}

    {% if catIdCheck == true %}  
        {# If true show category-one entries 
        on Category One Page #}
        {% set blogEntriesCriteria = craft.entries({
            section: 'blog',
            relatedTo: category,
            with: ([
               ['image', {
                   withTransforms: ['medium']
               }]
            ])
        }) %}
    {% endif %}

    {% if catIdCheck == false %}
        {# If false show all posts that 
        do not include category-one on all other
        category pages #}             
        {% set blogEntriesCriteria = craft.entries({
            section: 'news',
            relatedTo: category,
            id: ['not']|merge(excludeIds),
                with: ([
                    ['image', {
                        withTransforms: ['medium']
                    }]
                 ])
          }) %}
    {% endif %}

    {% set isFirstPage = craft.app.request.pageNum() == 1 %}
    {% set limit = 10 %}
    {% paginate blogEntriesCriteria.limit(limit) as pageInfo, blogEntries %}

    {% if blogEntries %}

        {# Loop through this page's News entries #}
        {% for entry in blogEntries %}

            {% include 'includes/components/_news-card' %}

        {% endfor %}

    {% else %}

        <p>Sorry, no posts found.</p>

    {% endif %}

{% endcache %}

I have had success with the busting the cache for the category page when I use the following code, which does not include id: ['not']|merge(excludeIds)

Any insight about the cache tag and if the id not array would be really helpful.

NOTE: I have updated my Blog Category file to have the if statements outside of the cache tag recommended by @RitterKnight but this did not fix the cache issue related to excluding entry ids.

  • I should note that for the Blog Category Code that doesn't bust the cache, it does bust the cache for Category One, but not any other category pages. – Michael Jan 11 at 19:50
1

The cache tag is somewhat misunderstood and it tends to trip up even the most seasoned Crafters.

The best way to explain about the {% cache %} tag is to think of it as a snapshot in time.

The first time the template runs, Craft saves the output to the database. It does not actually save queries. On subsequent runs, Craft simply grabs the output from the cache. Again, it doesn't save state or variables, it simply saves the output.

Specifically, I see you have {% if %} tags inside {% cache %}. Those conditionals will only run once. The {% if %} tags won't re-execute and the output is going to be the same.

What you can do is something like:

{% if whatever %} {% cache %} {{ do some output stuff }} {%endcache%} {% endif %}

For more info, check out Straight UP Craft as well as Andrew Welch's great piece on the subject.

  • I've done some further testing and I think I'm finding that the id param array might be part of my issue. If I remove .id(['not']|merge(excludeIds)) it seems to be working as expected. Any thoughts? – Michael Jan 11 at 22:42

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.