[FrameworkBundle] added a cache warmer to pre-compute template paths
To enable this cache warmer, you must add a "cache-warner" option to app:templating: <app:templating cache-warmer="true">
This commit is contained in:
parent
d0b4bfc8f6
commit
206b49a22f
@ -263,6 +263,15 @@ class FrameworkExtension extends Extension
|
||||
$container->setParameter('templating.loader.cache.path', $config['cache']);
|
||||
}
|
||||
|
||||
if (isset($config['cache-warmer'])) {
|
||||
$config['cache_warmer'] = $config['cache-warmer'];
|
||||
}
|
||||
|
||||
if (isset($config['cache_warmer']) && $config['cache_warmer']) {
|
||||
$container->getDefinition('templating.cache_warmer.template_paths')->addTag('kernel.cache_warmer');
|
||||
$container->setAlias('templating.locator', 'templating.locator.cached');
|
||||
}
|
||||
|
||||
// engines
|
||||
if (!$engines = $this->normalizeConfig($config, 'engine')) {
|
||||
throw new \LogicException('You must register at least one templating engine.');
|
||||
@ -281,10 +290,11 @@ class FrameworkExtension extends Extension
|
||||
$container->setAlias('templating', 'templating.engine.delegating');
|
||||
}
|
||||
|
||||
// compilation
|
||||
$this->addClassesToCompile(array(
|
||||
'Symfony\\Bundle\\FrameworkBundle\\Templating\\EngineInterface',
|
||||
'Symfony\\Component\\Templating\\EngineInterface',
|
||||
'Symfony\\Bundle\\FrameworkBundle\\Templating\\Loader\\TemplateLocatorInterface',
|
||||
$container->findDefinition('templating.locator')->getClass(),
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -80,6 +80,7 @@
|
||||
<xsd:attribute name="assets-version" type="xsd:string" />
|
||||
<xsd:attribute name="assets-base-urls" type="xsd:string" />
|
||||
<xsd:attribute name="cache" type="xsd:string" />
|
||||
<xsd:attribute name="cache-warmer" type="cache_warmer" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="translator">
|
||||
|
@ -7,7 +7,9 @@
|
||||
<parameters>
|
||||
<parameter key="templating.engine.delegating.class">Symfony\Bundle\FrameworkBundle\Templating\DelegatingEngine</parameter>
|
||||
<parameter key="templating.name_parser.class">Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateNameParser</parameter>
|
||||
<parameter key="templating.cache_warmer.template_paths.class">Symfony\Bundle\FrameworkBundle\Templating\CacheWarmer\TemplatePathsCacheWarmer</parameter>
|
||||
<parameter key="templating.locator.class">Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateLocator</parameter>
|
||||
<parameter key="templating.locator.cached.class">Symfony\Bundle\FrameworkBundle\Templating\Loader\CachedTemplateLocator</parameter>
|
||||
<parameter key="templating.loader.filesystem.class">Symfony\Bundle\FrameworkBundle\Templating\Loader\FilesystemLoader</parameter>
|
||||
<parameter key="templating.loader.cache.class">Symfony\Component\Templating\Loader\CacheLoader</parameter>
|
||||
<parameter key="templating.loader.chain.class">Symfony\Component\Templating\Loader\ChainLoader</parameter>
|
||||
@ -32,6 +34,15 @@
|
||||
<argument>%kernel.root_dir%</argument>
|
||||
</service>
|
||||
|
||||
<service id="templating.locator.cached" class="%templating.locator.cached.class%" public="false">
|
||||
<argument>%kernel.cache_dir%</argument>
|
||||
</service>
|
||||
|
||||
<service id="templating.cache_warmer.template_paths" class="%templating.cache_warmer.template_paths.class%" public="false">
|
||||
<argument type="service" id="kernel" />
|
||||
<argument>%kernel.root_dir%/views</argument>
|
||||
</service>
|
||||
|
||||
<service id="templating.loader.filesystem" class="%templating.loader.filesystem.class%" public="false">
|
||||
<argument type="service" id="templating.locator" />
|
||||
</service>
|
||||
|
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\Templating\CacheWarmer;
|
||||
|
||||
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmer;
|
||||
use Symfony\Component\HttpKernel\Kernel;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
|
||||
/**
|
||||
* Computes the association between template names and their paths on the disk.
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class TemplatePathsCacheWarmer extends CacheWarmer
|
||||
{
|
||||
protected $kernel;
|
||||
protected $rootDir;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Kernel $kernel A Kernel instance
|
||||
* @param string $rootDir The directory where global templates can be stored
|
||||
*/
|
||||
public function __construct(Kernel $kernel, $rootDir)
|
||||
{
|
||||
$this->kernel = $kernel;
|
||||
$this->rootDir = $rootDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Warms up the cache.
|
||||
*
|
||||
* @param string $cacheDir The cache directory
|
||||
*/
|
||||
public function warmUp($cacheDir)
|
||||
{
|
||||
$templates = $this->computeTemplatePaths();
|
||||
|
||||
$this->writeCacheFile($cacheDir.'/templates.php', sprintf('<?php return %s;', var_export($templates, true)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this warmer is optional or not.
|
||||
*
|
||||
* @return Boolean always false
|
||||
*/
|
||||
public function isOptional()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function computeTemplatePaths()
|
||||
{
|
||||
$prefix = '/Resources/views';
|
||||
$templates = array();
|
||||
foreach ($this->kernel->getBundles() as $name => $bundle) {
|
||||
if (!is_dir($dir = $bundle->getPath().$prefix)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$finder = new Finder();
|
||||
foreach ($finder->files()->followLinks()->name('*.twig')->in($dir) as $file) {
|
||||
list($category, $template) = $this->parseTemplateName($file, $prefix.'/');
|
||||
$name = sprintf('%s:%s:%s', $bundle->getName(), $category, $template);
|
||||
$resource = '@'.$bundle->getName().$prefix.'/'.$category.'/'.$template;
|
||||
|
||||
$templates[$name] = $this->kernel->locateResource($resource, $this->rootDir);
|
||||
}
|
||||
}
|
||||
|
||||
return $templates;
|
||||
}
|
||||
|
||||
protected function parseTemplateName($file, $prefix)
|
||||
{
|
||||
$path = $file->getPathname();
|
||||
|
||||
list(, $tmp) = explode($prefix, $path, 2);
|
||||
$parts = explode('/', strtr($tmp, '\\', '/'));
|
||||
$template = array_pop($parts);
|
||||
|
||||
return array(implode('/', $parts), $template);
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\Templating\Loader;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class CachedTemplateLocator implements TemplateLocatorInterface
|
||||
{
|
||||
protected $templates;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct($cacheDir)
|
||||
{
|
||||
if (!file_exists($cache = $cacheDir.'/templates.php')) {
|
||||
throw new \RuntimeException(sprintf('The template locator cache is not warmed up (%s).', $cache));
|
||||
}
|
||||
|
||||
$this->templates = require $cache;
|
||||
}
|
||||
|
||||
public function locate($name)
|
||||
{
|
||||
if (!isset($this->templates[$name])) {
|
||||
throw new \InvalidArgumentException(sprintf('Unable to find template "%s".', $name));
|
||||
}
|
||||
|
||||
return $this->templates[$name];
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user