Skip to content

Commit a3363dc

Browse files
committed
[TwigBundle] added a Twig templates warmer when templating is disabled
1 parent 6f48ec5 commit a3363dc

File tree

10 files changed

+208
-3
lines changed

10 files changed

+208
-3
lines changed

src/Symfony/Bundle/FrameworkBundle/CacheWarmer/TemplateFinder.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public function __construct(KernelInterface $kernel, TemplateNameParserInterface
4545
/**
4646
* Find all the templates in the bundle and in the kernel Resources folder.
4747
*
48-
* @return array An array of templates of type TemplateReferenceInterface
48+
* @return TemplateReferenceInterface[]
4949
*/
5050
public function findAllTemplates()
5151
{
@@ -69,7 +69,7 @@ public function findAllTemplates()
6969
*
7070
* @param string $dir The folder where to look for templates
7171
*
72-
* @return array An array of templates of type TemplateReferenceInterface
72+
* @return TemplateReferenceInterface[]
7373
*/
7474
private function findTemplatesInFolder($dir)
7575
{
@@ -93,7 +93,7 @@ private function findTemplatesInFolder($dir)
9393
*
9494
* @param BundleInterface $bundle The bundle where to look for templates
9595
*
96-
* @return array An array of templates of type TemplateReferenceInterface
96+
* @return TemplateReferenceInterface[]
9797
*/
9898
private function findTemplatesInBundle(BundleInterface $bundle)
9999
{
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\TwigBundle\CacheWarmer;
13+
14+
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
15+
16+
/**
17+
* Generates the Twig cache for all templates.
18+
*
19+
* @author Fabien Potencier <fabien@symfony.com>
20+
*/
21+
class TemplateCacheWarmer implements CacheWarmerInterface
22+
{
23+
private $twig;
24+
private $iterator;
25+
26+
public function __construct(\Twig_Environment $twig, \Iterator $iterator)
27+
{
28+
$this->twig = $twig;
29+
$this->iterator = $iterator;
30+
}
31+
32+
/**
33+
* {@inheritdoc}
34+
*/
35+
public function warmUp($cacheDir)
36+
{
37+
foreach ($this->iterator as $template) {
38+
try {
39+
$this->twig->loadTemplate($template);
40+
} catch (\Twig_Error $e) {
41+
// problem during compilation, give up
42+
// might be a syntax error or a non-Twig template
43+
}
44+
}
45+
}
46+
47+
/**
48+
* {@inheritdoc}
49+
*/
50+
public function isOptional()
51+
{
52+
return true;
53+
}
54+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ public function load(array $configs, ContainerBuilder $container)
7878
}
7979

8080
$container->getDefinition('twig.cache_warmer')->replaceArgument(2, $config['paths']);
81+
$container->getDefinition('twig.template_iterator')->replaceArgument(2, $config['paths']);
8182

8283
// register bundles as Twig namespaces
8384
foreach ($container->getParameter('kernel.bundles') as $bundle => $class) {

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,18 @@
5252
<argument type="collection" /> <!-- Twig paths -->
5353
</service>
5454

55+
<service id="twig.template_iterator" class="Symfony\Bundle\TwigBundle\TemplateIterator" public="false">
56+
<argument type="service" id="kernel" />
57+
<argument>%kernel.root_dir%</argument>
58+
<argument type="collection" /> <!-- Twig paths -->
59+
</service>
60+
61+
<service id="twig.template_cache_warmer" class="Symfony\Bundle\TwigBundle\CacheWarmer\TemplateCacheWarmer" public="false">
62+
<tag name="kernel.cache_warmer" />
63+
<argument type="service" id="twig" />
64+
<argument type="service" id="twig.template_iterator" />
65+
</service>
66+
5567
<service id="twig.loader.native_filesystem" class="Twig_Loader_Filesystem" public="false">
5668
<argument type="collection" />
5769
</service>
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\TwigBundle;
13+
14+
use Symfony\Component\HttpKernel\KernelInterface;
15+
use Symfony\Component\Finder\Finder;
16+
17+
/**
18+
* Iterator for all templates in bundles and in the application Resources directory.
19+
*
20+
* @author Fabien Potencier <fabien@symfony.com>
21+
*/
22+
class TemplateIterator implements \IteratorAggregate
23+
{
24+
private $kernel;
25+
private $rootDir;
26+
private $templates;
27+
private $paths;
28+
29+
/**
30+
* @param KernelInterface $kernel A KernelInterface instance
31+
* @param string $rootDir The directory where global templates can be stored
32+
* @param array $paths Additional Twig paths to warm
33+
*/
34+
public function __construct(KernelInterface $kernel, $rootDir, array $paths = array())
35+
{
36+
$this->kernel = $kernel;
37+
$this->rootDir = $rootDir;
38+
$this->paths = $paths;
39+
}
40+
41+
/**
42+
* {@inheritdoc}
43+
*/
44+
public function getIterator()
45+
{
46+
if (null !== $this->templates) {
47+
return $this->templates;
48+
}
49+
50+
$this->templates = $this->findTemplatesInDirectory($this->rootDir.'/views');
51+
foreach ($this->kernel->getBundles() as $bundle) {
52+
$name = $bundle->getName();
53+
if ('Bundle' === substr($name, -6)) {
54+
$name = substr($name, 0, -6);
55+
}
56+
57+
$this->templates = array_merge(
58+
$this->templates,
59+
$this->findTemplatesInDirectory($bundle->getPath().'/Resources/views', $name),
60+
$this->findTemplatesInDirectory($this->rootDir.'/'.$bundle->getName().'/views', $name)
61+
);
62+
}
63+
64+
foreach ($this->paths as $dir => $namespace) {
65+
$this->templates = array_merge($this->templates, $this->findTemplatesInDirectory($dir, $namespace));
66+
}
67+
68+
return $this->templates = new \ArrayIterator(array_unique($this->templates));
69+
}
70+
71+
/**
72+
* Find templates in the given directory.
73+
*
74+
* @param string $dir The directory where to look for templates
75+
* @param string $namespace The template namespace
76+
*
77+
* @return \Traversable
78+
*/
79+
private function findTemplatesInDirectory($dir, $namespace = null)
80+
{
81+
if (!is_dir($dir)) {
82+
return array();
83+
}
84+
85+
$templates = array();
86+
foreach (Finder::create()->files()->followLinks()->in($dir) as $file) {
87+
$templates[] = (null !== $namespace ? '@'.$namespace.'/' : '').$file->getRelativePathname();
88+
}
89+
90+
return $templates;
91+
}
92+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{# Twig template #}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{# Twig template #}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{# Twig template #}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{# Twig template #}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\TwigBundle\Tests;
13+
14+
use Symfony\Bundle\TwigBundle\TemplateIterator;
15+
16+
class TemplateIteratorTest extends TestCase
17+
{
18+
public function testGetIterator()
19+
{
20+
$bundle = $this->getMock('Symfony\Component\HttpKernel\Bundle\BundleInterface');
21+
$bundle->expects($this->any())->method('getName')->will($this->returnValue('BarBundle'));
22+
$bundle->expects($this->any())->method('getPath')->will($this->returnValue(__DIR__.'/Fixtures/templates/BarBundle'));
23+
24+
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\Kernel')->disableOriginalConstructor()->getMock();
25+
$kernel->expects($this->any())->method('getBundles')->will($this->returnValue(array(
26+
$bundle,
27+
)));
28+
$iterator = new TemplateIterator($kernel, __DIR__.'/Fixtures/templates', array(__DIR__.'/Fixtures/templates/Foo' => 'Foo'));
29+
30+
$sorted = iterator_to_array($iterator);
31+
sort($sorted);
32+
$this->assertEquals(
33+
array(
34+
'@Bar/index.html.twig',
35+
'@Foo/index.html.twig',
36+
'layout.html.twig',
37+
'sub/sub.html.twig',
38+
),
39+
$sorted
40+
);
41+
}
42+
}

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