How can I make Craft's caching aware of fields used inside a plugin? 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.

&nbsp;

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

&nbsp;

&lt;?php

namespace Craft;

class ControlVariable
{

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


ControlVariable.php

&nbsp;

&lt;?php

namespace Craft;

class Control_ModulesService extends BaseApplicationComponent
{

public function __construct()
{}

public function renderModule($module)
{
    ?&gt;

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

    &lt;?php
}


Control_ModulesService.php

&nbsp;

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 %}
        &lt;img src="{{ module.myImageField.first().getUrl() }}"&gt;      
    {% endcache %}
{% endfor %}


_modules.twig
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()-&gt;templateCache-&gt;includeElementInTemplateCaches().