mirror of
https://github.com/twigphp/Twig.git
synced 2026-08-30 20:16:45 +00:00
Add a cache tag
This commit is contained in:
@@ -80,6 +80,7 @@ jobs:
|
||||
- '7.4'
|
||||
- '8.0'
|
||||
extension:
|
||||
- 'extra/cache-extra'
|
||||
- 'extra/cssinliner-extra'
|
||||
- 'extra/html-extra'
|
||||
- 'extra/inky-extra'
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# 3.2.0 (2021-XX-XX)
|
||||
|
||||
* Add the Cache extension in the "extra" repositories: "cache" tag
|
||||
* Add "registerUndefinedTokenParserCallback"
|
||||
|
||||
# 3.1.1 (2020-10-27)
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
``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" tag('blog') %}
|
||||
Some code
|
||||
{% endcache %}
|
||||
|
||||
{% cache "cache key" tag(['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" tag('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 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 FilesystemAdapter());
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -7,6 +7,7 @@ Tags
|
||||
apply
|
||||
autoescape
|
||||
block
|
||||
cache
|
||||
deprecated
|
||||
do
|
||||
embed
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
/Tests export-ignore
|
||||
/phpunit.xml.dist export-ignore
|
||||
@@ -0,0 +1,4 @@
|
||||
vendor/
|
||||
composer.lock
|
||||
phpunit.xml
|
||||
.phpunit.result.cache
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Twig\Extra\Cache;
|
||||
|
||||
use Twig\Extension\AbstractExtension;
|
||||
use Twig\Extra\Cache\TokenParser\CacheTokenParser;
|
||||
|
||||
final class CacheExtension extends AbstractExtension
|
||||
{
|
||||
public function getTokenParsers()
|
||||
{
|
||||
return [
|
||||
new CacheTokenParser(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Twig\Extra\Cache;
|
||||
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
|
||||
class CacheRuntime
|
||||
{
|
||||
private $cache;
|
||||
|
||||
public function __construct(CacheInterface $cache)
|
||||
{
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
public function getCache(): CacheInterface
|
||||
{
|
||||
return $this->cache;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2021 Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Twig\Extra\Cache\Node;
|
||||
|
||||
use Twig\Compiler;
|
||||
use Twig\Node\Expression\AbstractExpression;
|
||||
use Twig\Node\Node;
|
||||
|
||||
class CacheNode extends Node
|
||||
{
|
||||
public function __construct(AbstractExpression $key, ?AbstractExpression $ttl, ?AbstractExpression $tags, Node $body, int $lineno, string $tag)
|
||||
{
|
||||
$nodes = ['key' => $key, 'body' => $body];
|
||||
if (null !== $ttl) {
|
||||
$nodes['ttl'] = $ttl;
|
||||
}
|
||||
if (null !== $tags) {
|
||||
$nodes['tags'] = $tags;
|
||||
}
|
||||
|
||||
parent::__construct($nodes, [], $lineno, $tag);
|
||||
}
|
||||
|
||||
public function compile(Compiler $compiler): void
|
||||
{
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write('$cached = $this->env->getRuntime(\'Twig\Extra\Cache\CacheRuntime\')->getCache()->get(')
|
||||
->subcompile($this->getNode('key'))
|
||||
->raw(", function (\Symfony\Contracts\Cache\ItemInterface \$item) use (\$context) {\n")
|
||||
->indent()
|
||||
->write("try {\n")
|
||||
->indent()
|
||||
->write("\$item->tag('twig');\n")
|
||||
;
|
||||
|
||||
if ($this->hasNode('tags')) {
|
||||
$compiler
|
||||
->write("\$item->tag(")
|
||||
->subcompile($this->getNode('tags'))
|
||||
->raw(");\n")
|
||||
;
|
||||
}
|
||||
|
||||
$compiler
|
||||
->outdent()
|
||||
->write("} catch (\Psr\Cache\CacheException \$e) {\n")
|
||||
->indent()
|
||||
->write("// cache doesn't support tags\n")
|
||||
->outdent()
|
||||
->write("}\n")
|
||||
;
|
||||
|
||||
if ($this->hasNode('ttl')) {
|
||||
$compiler
|
||||
->write('$item->expiresAfter(')
|
||||
->subcompile($this->getNode('ttl'))
|
||||
->raw(");\n")
|
||||
;
|
||||
}
|
||||
|
||||
$compiler
|
||||
->write("ob_start(function () { return ''; });\n")
|
||||
->subcompile($this->getNode('body'))
|
||||
->write("\n")
|
||||
->write("return ob_get_clean();\n")
|
||||
->outdent()
|
||||
->write("});\n")
|
||||
->write("echo '' === \$cached ? '' : new Markup(\$cached, \$this->env->getCharset());\n")
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
Cache Extension
|
||||
===============
|
||||
|
||||
This package is a Twig extension that provides integration with the Symfony
|
||||
Cache component.
|
||||
|
||||
It provides a single `cache` tag that allows to cache template fragments.
|
||||
@@ -0,0 +1,22 @@
|
||||
--TEST--
|
||||
"cache" tag
|
||||
--TEMPLATE--
|
||||
{% set foo = "bar" %}
|
||||
{% set value1 %}
|
||||
{% cache "test;v1" ttl(3) %}
|
||||
{% set foo = "bar1" %}
|
||||
{{ random(1, 1000000) }}
|
||||
{% endcache %}
|
||||
{% endset %}
|
||||
{% set value2 %}
|
||||
{% cache "test;v1" ttl(3) %}
|
||||
{{ random(1, 1000000) }}
|
||||
{% endcache %}
|
||||
{% endset %}
|
||||
{{ value1 == value2 ? 'OK' : 'KO' }}
|
||||
{{ foo == "bar" ? 'OK' : 'KO' }}
|
||||
--DATA--
|
||||
return []
|
||||
--EXPECT--
|
||||
OK
|
||||
OK
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Twig\Extra\Cache\Tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
use Twig\Environment;
|
||||
use Twig\Error\SyntaxError;
|
||||
use Twig\Extra\Cache\CacheExtension;
|
||||
use Twig\Extra\Cache\CacheRuntime;
|
||||
use Twig\Loader\ArrayLoader;
|
||||
use Twig\RuntimeLoader\RuntimeLoaderInterface;
|
||||
|
||||
class FunctionalTest extends TestCase
|
||||
{
|
||||
public function testIsCached()
|
||||
{
|
||||
$cache = new ArrayAdapter();
|
||||
$twig = $this->createEnvironment(['index' => '{% cache "city;v1" %}{{- city -}}{% endcache %}'], $cache);
|
||||
|
||||
$this->assertSame('Paris', $twig->render('index', ['city' => 'Paris']));
|
||||
$value = $cache->get('city;v1', function () { throw new \RuntimeException('Key should be in the cache'); });
|
||||
$this->assertSame('Paris', $value);
|
||||
}
|
||||
|
||||
public function testTtlNoArgs()
|
||||
{
|
||||
$twig = $this->createEnvironment(['index' => '{% cache "ttl_no_args" ttl() %}{% endcache %}']);
|
||||
$this->expectException(SyntaxError::class);
|
||||
$this->expectExceptionMessage('The "ttl" modifier takes exactly one argument (0 given) in "index" at line 1.');
|
||||
$twig->render('index');
|
||||
}
|
||||
|
||||
public function testTtlTooManyArgs()
|
||||
{
|
||||
$twig = $this->createEnvironment(['index' => '{% cache "ttl_too_many_args" ttl(0, 1) %}{% endcache %}']);
|
||||
$this->expectException(SyntaxError::class);
|
||||
$this->expectExceptionMessage('The "ttl" modifier takes exactly one argument (2 given) in "index" at line 1.');
|
||||
$twig->render('index');
|
||||
}
|
||||
|
||||
public function testTagsNoArgs()
|
||||
{
|
||||
$twig = $this->createEnvironment(['index' => '{% cache "tags_no_args" tags() %}{% endcache %}']);
|
||||
$this->expectException(SyntaxError::class);
|
||||
$this->expectExceptionMessage('The "ttl" modifier takes exactly one argument (0 given) in "index" at line 1.');
|
||||
$twig->render('index');
|
||||
}
|
||||
|
||||
public function testTagsTooManyArgs()
|
||||
{
|
||||
$twig = $this->createEnvironment(['index' => '{% cache "tags_too_many_args" tags(["foo"], 1) %}{% endcache %}']);
|
||||
$this->expectException(SyntaxError::class);
|
||||
$this->expectExceptionMessage('The "ttl" modifier takes exactly one argument (2 given) in "index" at line 1.');
|
||||
$twig->render('index');
|
||||
}
|
||||
|
||||
private function createEnvironment(array $templates, ArrayAdapter $cache = null): Environment
|
||||
{
|
||||
$twig = new Environment(new ArrayLoader($templates));
|
||||
$cache = $cache ?? new ArrayAdapter();
|
||||
$twig->addExtension(new CacheExtension());
|
||||
$twig->addRuntimeLoader(new class($cache) implements RuntimeLoaderInterface {
|
||||
private $cache;
|
||||
|
||||
public function __construct(CacheInterface $cache)
|
||||
{
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
public function load($class) {
|
||||
if (CacheRuntime::class === $class) {
|
||||
return new CacheRuntime($this->cache);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return $twig;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Twig\Extra\Cache\Tests;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
use Twig\Extra\Cache\CacheExtension;
|
||||
use Twig\Extra\Cache\CacheRuntime;
|
||||
use Twig\RuntimeLoader\RuntimeLoaderInterface;
|
||||
use Twig\Test\IntegrationTestCase;
|
||||
|
||||
class IntegrationTest extends IntegrationTestCase
|
||||
{
|
||||
public function getExtensions()
|
||||
{
|
||||
return [
|
||||
new CacheExtension(),
|
||||
];
|
||||
}
|
||||
|
||||
protected function getRuntimeLoaders()
|
||||
{
|
||||
return [
|
||||
new class implements RuntimeLoaderInterface {
|
||||
public function load($class) {
|
||||
if (CacheRuntime::class === $class) {
|
||||
return new CacheRuntime(new ArrayAdapter());
|
||||
}
|
||||
}
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
public function getFixturesDir()
|
||||
{
|
||||
return __DIR__.'/Fixtures/';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Twig\Extra\Cache\TokenParser;
|
||||
|
||||
use Twig\Error\SyntaxError;
|
||||
use Twig\Extra\Cache\Node\CacheNode;
|
||||
use Twig\Node\Node;
|
||||
use Twig\Token;
|
||||
use Twig\TokenParser\AbstractTokenParser;
|
||||
|
||||
class CacheTokenParser extends AbstractTokenParser
|
||||
{
|
||||
public function parse(Token $token): Node
|
||||
{
|
||||
$stream = $this->parser->getStream();
|
||||
$expressionParser = $this->parser->getExpressionParser();
|
||||
$key = $expressionParser->parseExpression();
|
||||
|
||||
$ttl = null;
|
||||
$tags = null;
|
||||
while ($stream->test(Token::NAME_TYPE)) {
|
||||
$k = $stream->getCurrent()->getValue();
|
||||
$stream->next();
|
||||
$args = $expressionParser->parseArguments();
|
||||
|
||||
switch ($k) {
|
||||
case 'ttl':
|
||||
if (1 !== count($args)) {
|
||||
throw new SyntaxError(sprintf('The "ttl" modifier takes exactly one argument (%d given).', count($args)), $stream->getCurrent()->getLine(), $stream->getSourceContext());
|
||||
}
|
||||
$ttl = $args->getNode(0);
|
||||
break;
|
||||
case 'tags':
|
||||
if (1 !== count($args)) {
|
||||
throw new SyntaxError(sprintf('The "ttl" modifier takes exactly one argument (%d given).', count($args)), $stream->getCurrent()->getLine(), $stream->getSourceContext());
|
||||
}
|
||||
$tags = $args->getNode(0);
|
||||
break;
|
||||
default:
|
||||
throw new SyntaxError(sprintf('Unknown "%s" configuration.', $k), $stream->getCurrent()->getLine(), $stream->getSourceContext());
|
||||
}
|
||||
}
|
||||
|
||||
$stream->expect(Token::BLOCK_END_TYPE);
|
||||
$body = $this->parser->subparse([$this, 'decideCacheEnd'], true);
|
||||
$stream->expect(Token::BLOCK_END_TYPE);
|
||||
|
||||
return new CacheNode($key, $ttl, $tags, $body, $token->getLine(), $this->getTag());
|
||||
}
|
||||
|
||||
public function decideCacheEnd(Token $token): bool
|
||||
{
|
||||
return $token->test('endcache');
|
||||
}
|
||||
|
||||
public function getTag(): string
|
||||
{
|
||||
return 'cache';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "twig/cache-extra",
|
||||
"type": "library",
|
||||
"description": "A Twig extension for Symfony Cache",
|
||||
"keywords": ["twig", "html", "cache"],
|
||||
"homepage": "https://twig.symfony.com",
|
||||
"license": "MIT",
|
||||
"minimum-stability": "dev",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com",
|
||||
"homepage": "http://fabien.potencier.org",
|
||||
"role": "Lead Developer"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"symfony/cache": "^5.0",
|
||||
"twig/twig": "^2.4|^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "^4.4.9|^5.0.9"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4" : { "Twig\\Extra\\Cache\\" : "" },
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.2-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/5.2/phpunit.xsd"
|
||||
backupGlobals="false"
|
||||
colors="true"
|
||||
bootstrap="vendor/autoload.php"
|
||||
failOnRisky="true"
|
||||
failOnWarning="true"
|
||||
>
|
||||
<php>
|
||||
<ini name="error_reporting" value="-1" />
|
||||
</php>
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="Twig Cache Extension Test Suite">
|
||||
<directory>./Tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>./</directory>
|
||||
<exclude>
|
||||
<directory>./Tests</directory>
|
||||
<directory>./vendor</directory>
|
||||
</exclude>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace Twig\Extra\TwigExtraBundle;
|
||||
|
||||
use Twig\Extra\Cache\CacheExtension;
|
||||
use Twig\Extra\CssInliner\CssInlinerExtension;
|
||||
use Twig\Extra\Html\HtmlExtension;
|
||||
use Twig\Extra\Inky\InkyExtension;
|
||||
@@ -21,6 +22,15 @@ use Twig\Extra\String\StringExtension;
|
||||
final class Extensions
|
||||
{
|
||||
private const EXTENSIONS = [
|
||||
'cache' => [
|
||||
'name' => 'cache',
|
||||
'class' => CacheExtension::class,
|
||||
'class_name' => 'CacheExtension',
|
||||
'package' => 'twig/cache-extra',
|
||||
'filters' => [],
|
||||
'functions' => [],
|
||||
'tags' => ['cache'],
|
||||
],
|
||||
'html' => [
|
||||
'name' => 'html',
|
||||
'class' => HtmlExtension::class,
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "^4.4.9|^5.0.9",
|
||||
"twig/cache-extra": "^3.0",
|
||||
"twig/cssinliner-extra": "^2.12|^3.0",
|
||||
"twig/html-extra": "^2.12|^3.0",
|
||||
"twig/inky-extra": "^2.12|^3.0",
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
|
||||
use Symfony\Contracts\Cache\TagAwareCacheInterface;
|
||||
use Twig\Extra\Cache\CacheExtension;
|
||||
use Twig\Extra\Cache\CacheRuntime;
|
||||
|
||||
return static function (ContainerConfigurator $container) {
|
||||
$container->services()
|
||||
->set('twig.extension.cache', CacheExtension::class)
|
||||
->tag('twig.extension')
|
||||
|
||||
->set('twig.runtime.cache', CacheRuntime::class)
|
||||
->args([
|
||||
service('twig.cache.default'),
|
||||
])
|
||||
->tag('twig.runtime')
|
||||
|
||||
->alias('twig.cache.default', TagAwareCacheInterface::class)
|
||||
;
|
||||
};
|
||||
Reference in New Issue
Block a user