0

I am struggling to get this working correctly. If I keep the element queries outside the cache tag then this naturally stops the cache being broken and so is not a viable option. However, when I put the element queries inside the cache tag, I hit issues with not being able to get the pageInfo variable to pass to the pagination links but also to SEOmatic.

So how can I combine the ability to paginate the content, cache it but then also place it in the correct place so future or new posts automatically break the cache.

Here is the full code outside the cache tag: Caching works, SEOmatic and Pagination URLS work - but the page cache is never broken.

{% set firstPending = craft.entries({
  section: 'news',
  status: 'pending',
  orderBy: 'postDate asc'
}).one %}
{% set cacheUntil = firstPending ? firstPending.postDate : now|date_modify('+1 year') %}


{% set news = craft.entries
  .section('news')
  .with('articleImages')
  .limit(4) %}

{# Get the articles and paginate them #}
{% paginate news as pageInfo, pageEntries %}

{# SEOmatic pagniate codfe into head #}
{% do seomatic.helper.paginate(pageInfo) %}

{% cache globally using key 'url: ' ~ craft.app.request.getFullPath() until cacheUntil %}
  {% for entry in pageEntries %}
    <div class="max-w-4xl">
      {% include 'pages/news/_partials/_news-teaser.twig' %}
    </div>
  {% endfor %}
{% endcache %}

Here is the code inside the cache tag: Caching Works, Cache is broken, but then the SEOMatic and Pagination URLS break as they cannot access pageInfo as it is not set.

{% cache globally using key 'url: ' ~ craft.app.request.getFullPath() until cacheUntil %}
  
  {% set firstPending = craft.entries({
    section: 'news',
    status: 'pending',
    orderBy: 'postDate asc'
  }).one %}
  {% set cacheUntil = firstPending ? firstPending.postDate : now|date_modify('+1 year') %}
  
  {% set news = craft.entries
    .section('news')
    .with('articleImages')
    .limit(4) %}
  
  {# Get the articles and paginate them #}
{% paginate news as pageInfo, pageEntries %}
  {% do pageInfo.setBasePath('news') %}
  
  {% for entry in pageEntries %}
    <div class="max-w-4xl">
      {% include 'pages/news/_partials/_news-teaser.twig' %}
    </div>
  {% endfor %}
{% endcache %}

I am sure I could hack a way around this but duplicating element queries etc. But it doesn't feel right. I would like to know the ideal way to code this.

Thanks.

  • 1
    As you alude to at the end, a simple query for the element in question inside of the cache tag would do it -- and if you used the same exact query, it'd be in the query cache so the impact would be minimal. – andrew.welch Jul 6 at 13:16
  • 1
    There is also an TemplateCaches::includeElementInTemplateCaches() method you could use to do it, but you'd need to write a small module/plugin to do it, as its not exposed in Twig. – andrew.welch Jul 6 at 13:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.