I'm using the twig cache in a Symfony 5.4 project. If I cache something like:
{% cache "customer_1" ttl(3600) tags('customer') %}
Some HTML here
{% endcache %}
I need to be able to invalidate the twig cache with tag customer
from within a Symfony controller or service.
I've tried autoloading Symfony\Contracts\Cache\TagAwareCacheInterface $twigCache
(found from bin/console debug:autowiring
) but this doesn't seem to work.
With this I called $twigCache->invalidateTags(['customer'])
, but does not appear to do nothing.
Is it possible to access and clear the twig cache from the Symfony side?
Apparently, you are doing it correctly.
I have just set up a Symfony 5.4 project from scratch and tried it, and it works as expected.
E.g.:
composer create-project symfony/skeleton:"5.4.*" twig-cache-5.4
cd twig-cache-5.4
composer req twig
composer req twig/cache-extra
<?php declare(strict_types=1);
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Attribute\AsController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\Cache\TagAwareCacheInterface;
use Twig\Environment;
#[AsController]
#[Route('/super-cache/{tag}', 'super')]
readonly class SuperController
{
public function __construct(
private Environment $twig,
private TagAwareCacheInterface $twigCache,
)
{ }
public function __invoke(?string $tag = null): Response
{
if ($tag !== null) {
$this->twigCache->invalidateTags([$tag]);
}
return new Response($this->twig->render('super.html.twig'));
}
}
And the template:
{% extends 'base.html.twig' %}
{% block body %}
<H1>Hello, content</H1>
{% cache "first-key" tags('foo') %}
<p>Key "main-key", tag "foo" (cached at: {{ "now"|date("F jS \\a\\t g:ia") }})</p>
{% endcache %}
{% cache "second-key" tags('foo') %}
<p>Key "second-key", tag "foo" (cached at: {{ "now"|date("F jS \\a\\t g:ia") }})</p>
{% endcache %}
{% cache "third-key" tags('bar') %}
<p>Key "third-key", tag "bar" (cached at: {{ "now"|date("F jS \\a\\t g:ia") }})</p>
{% endcache %}
<p>This is some uncached content.</p>
{% endblock %}
I have verified with bin/console cache:pool:list
that the pool twig.cache
has been created, so I can autowire that pool directly with $twigCache
.
If I access /super-cache
, the first time the template will be cached completely, and the "cached at" string won't change in following calls:
Now accessing /super-cache/foo
, the controller will invalidate the tag foo
for the pool, and the template content will be refreshed accordingly (check the "created at" string on the first two blocks):
Knowing that this should work as intended, you'll need to find if there is something else amiss in your setup.