File: cache.rst

package info (click to toggle)
php-twig 3.20.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,940 kB
  • sloc: php: 23,320; makefile: 110; sh: 43
file content (113 lines) | stat: -rw-r--r-- 3,470 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
``cache``
=========

.. versionadded:: 3.2

    The ``cache`` tag was added in Twig 3.2.

The ``cache`` tag tells Twig to cache a template fragment:

.. code-block:: twig

    {% cache "cache key" %}
        Cached forever (depending on the cache implementation)
    {% endcache %}

If you want to expire the cache after a certain amount of time, specify an
expiration in seconds via the ``ttl()`` modifier:

.. code-block:: twig

    {% cache "cache key" ttl(300) %}
        Cached for 300 seconds
    {% endcache %}

The cache key can be any string that does not use the following reserved
characters ``{}()/\@:``; a good practice is to embed some useful information in
the key that allows the cache to automatically expire when it must be
refreshed:

* Give each cache a unique name and namespace it like your templates;

* Embed an integer that you increment whenever the template code changes (to
  automatically invalidate all current caches);

* Embed a unique key that is updated whenever the variables used in the
  template code changes.

For instance, I would use ``{% cache "blog_post;v1;" ~ post.id ~ ";" ~
post.updated_at %}`` to cache a blog content template fragment where
``blog_post`` describes the template fragment, ``v1`` represents the first
version of the template code, ``post.id`` represent the id of the blog post,
and ``post.updated_at`` returns a timestamp that represents the time where the
blog post was last modified.

Using such a strategy for naming cache keys allows to avoid using a ``ttl``.
It's like using a "validation" strategy instead of an "expiration" strategy as
we do for HTTP caches.

If your cache implementation supports tags, you can also tag your cache items:

.. code-block:: twig

    {% cache "cache key" tags('blog') %}
        Some code
    {% endcache %}

    {% cache "cache key" tags(['cms', 'blog']) %}
        Some code
    {% endcache %}

The ``cache`` tag creates a new "scope" for variables, meaning that the changes
are local to the template fragment:

.. code-block:: twig

    {% set count = 1 %}

    {% cache "cache key" tags('blog') %}
        {# Won't affect the value of count outside of the cache tag #}
        {% set count = 2 %}
        Some code
    {% endcache %}

    {# Displays 1 #}
    {{ count }}

.. note::

    The ``cache`` tag is part of the ``CacheExtension`` which is not installed
    by default. Install it first:

    .. code-block:: bash

        $ composer require twig/cache-extra

    On Symfony projects, you can automatically enable it by installing the
    ``twig/extra-bundle``:

    .. code-block:: bash

        $ composer require twig/extra-bundle

    Or add the extension explicitly on the Twig environment::

        use Twig\Extra\Cache\CacheExtension;

        $twig = new \Twig\Environment(...);
        $twig->addExtension(new CacheExtension());

    If you are not using Symfony, you must also register the extension runtime::

        use Symfony\Component\Cache\Adapter\FilesystemAdapter;
        use Symfony\Component\Cache\Adapter\TagAwareAdapter;
        use Twig\Extra\Cache\CacheRuntime;
        use Twig\RuntimeLoader\RuntimeLoaderInterface;

        $twig->addRuntimeLoader(new class implements RuntimeLoaderInterface {
            public function load($class) {
                if (CacheRuntime::class === $class) {
                    return new CacheRuntime(new TagAwareAdapter(new FilesystemAdapter()));
                }
            }
        });