2

I have a complex template which uses various modules and sub-components for which I opted for handling all the logic and rendering directly in PHP, as it felt like it was too complex a job for twig.

Currently, when I change a field (e.g. swap out an image) inside one of the modules, the surrounding cache isn't busted, so the site doesn't update.

My question is: How can I make Craft aware of fields used inside a plugin within a {% cache %} tag, so that when a field is changed, the surrounding cache is busted?

I am aware of the TemplateCacheService, but unsure if / how I can use that in this case (I had a bit of an experiment with no success).

The modules represent a Neo field, but my assumption is that this would work very similarly if not identically to if this was a matrix field.

 

A super-reduced test case looks something like the following:

{% for module in modules %}
    {% cache using key module.id %}
        {{ craft.control.renderModule(module) }}
    {% endcache %}
{% endfor %}

_modules.twig

 

<?php

namespace Craft;

class ControlVariable
{

    public function renderModule($module)
    {
        return craft()->control_modules->renderModule($module);
    }
}

ControlVariable.php

 

<?php

namespace Craft;

class Control_ModulesService extends BaseApplicationComponent
{

public function __construct()
{}

public function renderModule($module)
{
    ?>

    <!-- How can Craft know when this image changes? -->
    <img src="<?= $module->myImageField->first()->getUrl(); ?>">

    <?php
}

Control_ModulesService.php

 

FWIW, in the following setup, the cache is successfully busted when changing the image field in the CMS:

{% for module in modules %}
    {% cache using key module.id %}
        <img src="{{ module.myImageField.first().getUrl() }}">      
    {% endcache %}
{% endfor %}

_modules.twig

1

The {% cache %} tag tracks Elements (Users, Entries, Categories, Tags, etc.), so if you're want to do this using a plugin, then the plugin's field type needs to inherit from BaseElementFieldType and needs to implement its own element type.

From there, it's just a matter of calling craft()->templateCache->includeElementInTemplateCaches().

| improve this answer | |
  • Thanks so much for getting back to me Brad! If I could just clarify / confirm something: the field types I am outputting the values of in the plugin are actually native Craft fields (e.g. myImageField above is just a regular assets field). Would that change anything? – Mike Vaux Apr 4 '17 at 8:15

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.