Grav: addInlineJs Cache not working

Created on 21 Mar 2018  路  12Comments  路  Source: getgrav/grav

In an Twig Tempalate I have this code:

{% set script %}
alert('Test');
{% endset %}
{% do assets.addInlineJs(script,{ 'group':'bottom','priority':100 }) %}

{{ assets.js('bottom') }}

This code is successfully displayed in the html code the first time it is called:

But after a reload, the code section is no longer available. It looks like the inline cache is not working well.

Cache: [true] Setting: [auto] Driver: [file]

1.7 feature

All 12 comments

What is the full Twig? It makes a difference.

modular.html.twig file:

{% extends 'partials/base.html.twig' %}
{% block body %}
{% for module in page.collection() %}
{{ module.content }}
{% endfor %}
{% endblock %}

modular template file:

{% set script %}
alert('Test');
{% endset %}
{% do assets.addInlineJs(script,{ 'group':'bottom','priority':100 }) %}

Javascript works within the modular.html.twig file, but not in the modular template file.

This is expected behavior. This is because modular subpages are processed along with their twig and then the resulting rendered html is stored as the content and cached. Once this the twig is not processed again so anything that is not output to html of that page is lost.

However the solution is quite simple. Simply set never_cache_twig: true in the modular subpages frontmatter.

This way the twig is run on this particular modular subpage every-time and yo won鈥檛 lose your JS.

Ok, thanks for your help. It works... Of course, it would be better to leave the cache switched on. :)

Don't cache does not feel right. This affects many use cases.
From form fields to modular templates making use of assets/inlinejs/... or even plugins listening to form events to add assets (because these are only fired once during initial processing and corresponding assets are lost in subsequent reloads).

Is there another issue where this is tracked?

ping / reopen-request

There is really no way caching parts of the page output right now.

My take on this is that I have plans to fix this issue, though it will require quite major architectural changes, so it will not be fixed until I have rewritten pages logic and made some additional fixes into elsewhere as well. I have some basis for this already implemented, though.

The more detailed response is that I need to rewrite pages to the new Flex objects as well as improve HtmlBlocks to allow dynamic content inside of cached content. Flex objects are much better defined than the current pages, meaning that they are self-contained (for example they know how to render themselves). They also allow us to differentiate different page types by allowing custom logic; for example, modular pages could have custom behaviour to regular pages. They also use HtmlBlocks which are basically advanced blocks which can contain not only HTML but also CSS/JS/images, custom metadata and other HtmlBlocks. It will automatically fix the missing CSS/JS issue, but later it could allow much more advanced caching as well.

I marked this for 1.7 even if it's likely that this will not be fully supported in that version. But the goal is to rewrite this part of the logic by 2.0.

The underlying issue is that doctrine cache is only enabled for individuals pages but is not for a (modular) page as a whole.
That means cached version of every individual components is restored but any modification affecting the page as a whole done during initial rendering (= any deferred operation, like enqueing assets, deferred blocks, ...) is not recorded.

A very quick fix would be to enable cache for whole modular pages too.

Enabling cache for whole modular pages would not resolve the issue.

The issue is that when you call page->content() on any page (be it modular or not) the first time, the content itself is cached. Modular pages have the extra 'feature' of rendering content with an associated Twig template, the HTML output, as a result, is then cached. However, if your modular Twig has some asset calls those will work the first time (while Twig is rendering), but then after the resultant content is cached, the Twig is no longer processed (as the HTML output is cached).

This is why we recommend never_cache_twig: true to be set when you need Twig to be rendered each time for modular pages.

It would be wonderful to add assets on a per modular basis. Hell you could even label that "component based" :P

As 1.7 is out can we remark this for 2.0, as it would be nice to see this in an upcoming release?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gizmecano picture gizmecano  路  17Comments

marktaylor46 picture marktaylor46  路  26Comments

Japhys picture Japhys  路  21Comments

lazzich picture lazzich  路  19Comments

joville picture joville  路  23Comments