Skip to content

Commit 532e408

Browse files
committed
feature #54384 [TwigBundle] Use kernel.build_dir to store the templates known at build time (Okhoshi)
This PR was merged into the 7.3 branch. Discussion ---------- [TwigBundle] Use `kernel.build_dir` to store the templates known at build time | Q | A | ------------- | --- | Branch? | 7.3 | Bug fix? | no | New feature? | yes | Deprecations? | no | Issues | none | License | MIT Follow up to #50391, set up the Twig `TemplateCacheWarmer` to use the `kernel.build_dir` instead of `kernel.cache_dir`. A new argument is added to its constructor to specify the directory to use for the cache. Commits ------- 0f841d2 [TwigBundle] Use `kernel.build_dir` to store the templates known at build time
2 parents e532750 + 0f841d2 commit 532e408

File tree

19 files changed

+210
-28
lines changed

19 files changed

+210
-28
lines changed

src/Symfony/Bundle/TwigBundle/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ CHANGELOG
77
* Enable `#[AsTwigFilter]`, `#[AsTwigFunction]` and `#[AsTwigTest]` attributes
88
to configure extensions on runtime classes
99
* Add support for a `twig` validator
10+
* Use `ChainCache` to store warmed-up cache in `kernel.build_dir` and runtime cache in `kernel.cache_dir`
11+
* Make `TemplateCacheWarmer` use `kernel.build_dir` instead of `kernel.cache_dir`
1012

1113
7.1
1214
---

src/Symfony/Bundle/TwigBundle/CacheWarmer/TemplateCacheWarmer.php

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
use Psr\Container\ContainerInterface;
1515
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
1616
use Symfony\Contracts\Service\ServiceSubscriberInterface;
17+
use Twig\Cache\CacheInterface;
18+
use Twig\Cache\NullCache;
1719
use Twig\Environment;
1820
use Twig\Error\Error;
1921

@@ -34,26 +36,48 @@ class TemplateCacheWarmer implements CacheWarmerInterface, ServiceSubscriberInte
3436
public function __construct(
3537
private ContainerInterface $container,
3638
private iterable $iterator,
39+
private ?CacheInterface $cache = null,
3740
) {
3841
}
3942

4043
public function warmUp(string $cacheDir, ?string $buildDir = null): array
4144
{
4245
$this->twig ??= $this->container->get('twig');
4346

44-
foreach ($this->iterator as $template) {
45-
try {
46-
$this->twig->load($template);
47-
} catch (Error) {
47+
$originalCache = $this->twig->getCache();
48+
if ($originalCache instanceof NullCache) {
49+
// There's no point to warm up a cache that won't be used afterward
50+
return [];
51+
}
52+
53+
if (null !== $this->cache) {
54+
if (!$buildDir) {
4855
/*
49-
* Problem during compilation, give up for this template (e.g. syntax errors).
50-
* Failing silently here allows to ignore templates that rely on functions that aren't available in
51-
* the current environment. For example, the WebProfilerBundle shouldn't be available in the prod
52-
* environment, but some templates that are never used in prod might rely on functions the bundle provides.
53-
* As we can't detect which templates are "really" important, we try to load all of them and ignore
54-
* errors. Error checks may be performed by calling the lint:twig command.
56+
* The cache has already been warmup during the build of the container, when $buildDir was set.
5557
*/
58+
return [];
59+
}
60+
// Swap the cache for the warmup as the Twig Environment has the ChainCache injected
61+
$this->twig->setCache($this->cache);
62+
}
63+
64+
try {
65+
foreach ($this->iterator as $template) {
66+
try {
67+
$this->twig->load($template);
68+
} catch (Error) {
69+
/*
70+
* Problem during compilation, give up for this template (e.g. syntax errors).
71+
* Failing silently here allows to ignore templates that rely on functions that aren't available in
72+
* the current environment. For example, the WebProfilerBundle shouldn't be available in the prod
73+
* environment, but some templates that are never used in prod might rely on functions the bundle provides.
74+
* As we can't detect which templates are "really" important, we try to load all of them and ignore
75+
* errors. Error checks may be performed by calling the lint:twig command.
76+
*/
77+
}
5678
}
79+
} finally {
80+
$this->twig->setCache($originalCache);
5781
}
5882

5983
return [];

src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ private function addTwigOptions(ArrayNodeDefinition $rootNode): void
136136
->example('Twig\Template')
137137
->cannotBeEmpty()
138138
->end()
139-
->scalarNode('cache')->defaultValue('%kernel.cache_dir%/twig')->end()
139+
->scalarNode('cache')->defaultTrue()->end()
140140
->scalarNode('charset')->defaultValue('%kernel.charset%')->end()
141141
->booleanNode('debug')->defaultValue('%kernel.debug%')->end()
142142
->booleanNode('strict_variables')->defaultValue('%kernel.debug%')->end()

src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
use Twig\Attribute\AsTwigFilter;
3131
use Twig\Attribute\AsTwigFunction;
3232
use Twig\Attribute\AsTwigTest;
33+
use Twig\Cache\FilesystemCache;
3334
use Twig\Environment;
3435
use Twig\Extension\ExtensionInterface;
3536
use Twig\Extension\RuntimeExtensionInterface;
@@ -167,6 +168,31 @@ public function load(array $configs, ContainerBuilder $container): void
167168
}
168169
}
169170

171+
if (true === $config['cache']) {
172+
$autoReloadOrDefault = $container->getParameterBag()->resolveValue($config['auto_reload'] ?? $config['debug']);
173+
$buildDir = $container->getParameter('kernel.build_dir');
174+
$cacheDir = $container->getParameter('kernel.cache_dir');
175+
176+
if ($autoReloadOrDefault || $cacheDir === $buildDir) {
177+
$config['cache'] = '%kernel.cache_dir%/twig';
178+
}
179+
}
180+
181+
if (true === $config['cache']) {
182+
$config['cache'] = new Reference('twig.template_cache.chain');
183+
} else {
184+
$container->removeDefinition('twig.template_cache.chain');
185+
$container->removeDefinition('twig.template_cache.runtime_cache');
186+
$container->removeDefinition('twig.template_cache.readonly_cache');
187+
$container->removeDefinition('twig.template_cache.warmup_cache');
188+
189+
if (false === $config['cache']) {
190+
$container->removeDefinition('twig.template_cache_warmer');
191+
} else {
192+
$container->getDefinition('twig.template_cache_warmer')->replaceArgument(2, null);
193+
}
194+
}
195+
170196
if (isset($config['autoescape_service'])) {
171197
$config['autoescape'] = [new Reference($config['autoescape_service']), $config['autoescape_service_method'] ?? '__invoke'];
172198
} else {
@@ -191,10 +217,6 @@ public function load(array $configs, ContainerBuilder $container): void
191217
$container->registerAttributeForAutoconfiguration(AsTwigFilter::class, AttributeExtensionPass::autoconfigureFromAttribute(...));
192218
$container->registerAttributeForAutoconfiguration(AsTwigFunction::class, AttributeExtensionPass::autoconfigureFromAttribute(...));
193219
$container->registerAttributeForAutoconfiguration(AsTwigTest::class, AttributeExtensionPass::autoconfigureFromAttribute(...));
194-
195-
if (false === $config['cache']) {
196-
$container->removeDefinition('twig.template_cache_warmer');
197-
}
198220
}
199221

200222
private function getBundleTemplatePaths(ContainerBuilder $container, array $config): array

src/Symfony/Bundle/TwigBundle/Resources/config/twig.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@
3636
use Symfony\Bundle\TwigBundle\CacheWarmer\TemplateCacheWarmer;
3737
use Symfony\Bundle\TwigBundle\DependencyInjection\Configurator\EnvironmentConfigurator;
3838
use Symfony\Bundle\TwigBundle\TemplateIterator;
39+
use Twig\Cache\ChainCache;
3940
use Twig\Cache\FilesystemCache;
41+
use Twig\Cache\ReadOnlyFilesystemCache;
4042
use Twig\Environment;
4143
use Twig\Extension\CoreExtension;
4244
use Twig\Extension\DebugExtension;
@@ -79,8 +81,24 @@
7981
->set('twig.template_iterator', TemplateIterator::class)
8082
->args([service('kernel'), abstract_arg('Twig paths'), param('twig.default_path'), abstract_arg('File name pattern')])
8183

84+
->set('twig.template_cache.runtime_cache', FilesystemCache::class)
85+
->args([param('kernel.cache_dir').'/twig'])
86+
87+
->set('twig.template_cache.readonly_cache', ReadOnlyFilesystemCache::class)
88+
->args([param('kernel.build_dir').'/twig'])
89+
90+
->set('twig.template_cache.warmup_cache', FilesystemCache::class)
91+
->args([param('kernel.build_dir').'/twig'])
92+
93+
->set('twig.template_cache.chain', ChainCache::class)
94+
->args([[service('twig.template_cache.readonly_cache'), service('twig.template_cache.runtime_cache')]])
95+
8296
->set('twig.template_cache_warmer', TemplateCacheWarmer::class)
83-
->args([service(ContainerInterface::class), service('twig.template_iterator')])
97+
->args([
98+
service(ContainerInterface::class),
99+
service('twig.template_iterator'),
100+
service('twig.template_cache.warmup_cache'),
101+
])
84102
->tag('kernel.cache_warmer')
85103
->tag('container.service_subscriber', ['id' => 'twig'])
86104

src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/php/full.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
'pi' => 3.14,
1111
'bad' => ['key' => 'foo'],
1212
],
13-
'auto_reload' => true,
14-
'cache' => '/tmp',
13+
'auto_reload' => false,
1514
'charset' => 'ISO-8859-1',
1615
'debug' => true,
1716
'strict_variables' => true,
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?php
2+
3+
$container->loadFromExtension('twig', [
4+
'cache' => false,
5+
]);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?php
2+
3+
$container->loadFromExtension('twig', [
4+
'cache' => 'random-path',
5+
]);
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
3+
$container->loadFromExtension('twig', [
4+
'cache' => true,
5+
'auto_reload' => false,
6+
]);

src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Fixtures/xml/extra.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
77
http://symfony.com/schema/dic/twig https://symfony.com/schema/dic/twig/twig-1.0.xsd">
88

9-
<twig:config auto-reload="true" cache="/tmp" charset="ISO-8859-1" debug="true" strict-variables="true">
9+
<twig:config auto-reload="true" charset="ISO-8859-1" debug="true" strict-variables="true">
1010
<twig:path namespace="namespace3">namespaced_path3</twig:path>
1111
</twig:config>
1212
</container>

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy