1

Okay. I've figured it out but it left me with the question. After some page refreshes It's got stack back at empty output again.

Bad:

{% cache %}
  {% for item in orders %}
    {# Following variable was the problem #}
    {% set cart = item.cart %}
    {# Loop in cart's table fields: title and quantity #}
    {% for row in cart %}
      {% set data = data|merge([{ title: row.title, quantity: row.quantity }]) %}
    {% endfor %}
  {% endfor %}
{% endcache %}

On second page load it outputs nothing. So I simply call for a check like this.

{% for item in data %}
  {# for example #}{{ item.title }}
{% endfor %}

Good: This is my current state of the code design. It's a bit extended to the original post. But a problem may be in data merging into an array.

{# Prep array #}
{% set data = [] %}

{% cache %}
  {% for item in orders %}
    {# Loop in cart's table fields: title and quantity #}
    {% for row in item.cart %}
      {% set data = data|merge([{ title: row.title, quantity: row.quantity }]) %}
    {% endfor %}
  {% endfor %}
{% endcache %}

{% set someProduct = 'someProduct' %}
{% set someOrderQuantity = 0 %}
{# Count order's quantity #}
{% for item in data %}
  {% if someProduct = item.title %}
    {% set someOrderQuantity = someOrderQuantity + item.quantity %}
  {% endif %}
{% endfor %}

Setting variable cart to reuse in orders loop and wrap in cache tags wasn't good idea because it outputted nothing. So I had to take cart variable out. It worked out but I don't know why was setting variable in entries loop for another loop causing that empty output? I properly don't know how cache tags works?

  • 1
    Have you cleared the cache in the settings? Save's you alot of time. You could also change the Cache settings to only cache the page to non logged in users. craftcms.com/docs/templating/cache – Justin Dekkers May 1 '17 at 8:54
  • @JustinDekkers Yes I have and yes you're correct about saving time. The site runs solo. I haven't considered to do that but good to know! – Dom Krulak May 4 '17 at 13:44
4

The {% cache %} tag is only designed to do one thing – to capture output (e.g. HTML) and store that output to the database, so that the next time Craft encounters that particular cache tag, it can serve up the cached output from the database, instead of having to run whatever code is contained inside the {% cache %} tag pair, on every pageload.

In your code, you're attempting to cache a variable (data). That won't work. Essentially, you're just feeding the {% cache %} tag empty output, and the code that actually sets the data variable will only run on the first pageload (or whenever the cache has been cleared out). On subsequent pageloads, Craft won't bother to actually run the code inside the {% cache %} tag, it'll simply print whatever output was stored for that particular cache (which, in this case, is empty). Hence your code breaking.

What you need to do, is to revise your caching strategy so that your business logic (i.e. the part of your code that pulls and operates on data – which is usually the expensive part, resource-wise) and the part that actually prints your data is contained within the same {% cache %} tag pair.

Here's a small example to illustrate good vs. bad use of the {% cache %} tag:

Bad

{% cache %}
    {% set entries = craft.entries.section('news') %}
{% endcache %}

{% for entry in entries %}
    <a href="{{ entry.url }}">{{ entry.title }}</a><br />
{% endfor %}

^ Ouch. The variable entries will only be set whenever the cache is empty; on subsequent pageloads, Craft will serve up an empty, cached string instead of actually running the craft.entries query and the for loop will fail because it'll operate on a variable that isn't set.

Good

{% cache %}

    {% set entries = craft.entries.section('news') %}

    {% for entry in entries %}
        <a href="{{ entry.url }}">{{ entry.title }}</a><br />
    {% endfor %}

{% endcache %}

^ Awesome. The page will probably be served a bit faster because Craft doesn't have to pull the entries and compile the HTML for every pageload – it'll just spit out the output resulting from the code within the {% cache %} tag.

  • I intended to use cache tags on long list of entries. Those entries have a table field with some conditionals and math inside. No HTML compiling in loops just Twig alone. Just like from the question. So I've ended up with one loop stripped off and wrapping final output which includes HTML compiling. – Dom Krulak May 1 '17 at 13:21

Your Answer

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

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