Bladeren bron

[Templating] changed the load() signature for loaders to allow for more flexibility

Fabien Potencier 15 jaren geleden
bovenliggende
commit
5c20bfec92

+ 27 - 18
src/Symfony/Components/Templating/Engine.php

@@ -67,7 +67,13 @@ class Engine
   /**
    * Renders a template.
    *
-   * @param string $name       A template logical name
+   * The template name is composed of segments separated by a colon (:).
+   * By default, this engine knows how to parse templates with one or two segments:
+   *
+   *  * index:      The template logical name is index and the renderer is php
+   *  * index:twig: The template logical name is index and the renderer is twig
+   *
+   * @param string $name       A template name
    * @param array  $parameters An array of parameters to pass to the template
    *
    * @return string The evaluated template as a string
@@ -77,35 +83,23 @@ class Engine
    */
   public function render($name, array $parameters = array())
   {
-    // split renderer & template
-    if (false !== $pos = strpos($name, ':'))
-    {
-      $renderer = substr($name, 0, $pos);
-      $name = substr($name, $pos + 1);
-    }
-    else
-    {
-      $renderer = 'php';
-    }
+    list($name, $options) = $this->splitTemplateName($name);
 
     // load
-    $template = $this->loader->load($name, $renderer);
+    $template = $this->loader->load($name, $options);
 
     if (false === $template)
     {
-      throw new \InvalidArgumentException(sprintf('The template "%s" does not exist (renderer: %s).', $name, $renderer));
+      throw new \InvalidArgumentException(sprintf('The template "%s" does not exist (renderer: %s).', $name, $options['renderer']));
     }
 
     $this->current = $name;
     $this->parents[$name] = null;
 
     // renderer
-    if ($template->getRenderer())
-    {
-      $renderer = $template->getRenderer();
-    }
+    $renderer = $template->getRenderer() ? $template->getRenderer() : $options['renderer'];
 
-    if (!isset($this->renderers[$renderer]))
+    if (!isset($this->renderers[$options['renderer']]))
     {
       throw new \InvalidArgumentException(sprintf('The renderer "%s" is not registered.', $renderer));
     }
@@ -312,4 +306,19 @@ class Engine
   {
     return $this->charset;
   }
+
+  protected function splitTemplateName($name)
+  {
+    if (false !== $pos = strpos($name, ':'))
+    {
+      $renderer = substr($name, $pos + 1);
+      $name = substr($name, 0, $pos);
+    }
+    else
+    {
+      $renderer = 'php';
+    }
+
+    return array($name, array('renderer' => $renderer));
+  }
 }

+ 11 - 7
src/Symfony/Components/Templating/Loader/CacheLoader.php

@@ -40,23 +40,27 @@ class CacheLoader extends Loader
   {
     $this->loader = $loader;
     $this->dir = $dir;
+
+    parent::__construct();
   }
 
   /**
    * Loads a template.
    *
    * @param string $template The logical template name
-   * @param string $renderer The renderer to use
+   * @param array  $options  An array of options
    *
    * @return Storage|Boolean false if the template cannot be loaded, a Storage instance otherwise
    */
-  public function load($template, $renderer = 'php')
+  public function load($template, array $options = array())
   {
-    $path = $this->dir.DIRECTORY_SEPARATOR.md5($template.$renderer).'.tpl';
+    $options = $this->mergeDefaultOptions($options);
+
+    $path = $this->dir.DIRECTORY_SEPARATOR.md5($template.$options['renderer']).'.tpl';
 
     if ($this->loader instanceof CompilableLoaderInterface)
     {
-      $renderer = 'php';
+      $options['renderer'] = 'php';
     }
 
     if (file_exists($path))
@@ -66,10 +70,10 @@ class CacheLoader extends Loader
         $this->debugger->log(sprintf('Fetching template "%s" from cache', $template));
       }
 
-      return new FileStorage($path, $renderer);
+      return new FileStorage($path, $options['renderer']);
     }
 
-    if (false === $content = $this->loader->load($template, $renderer))
+    if (false === $content = $this->loader->load($template, $options))
     {
       return false;
     }
@@ -86,6 +90,6 @@ class CacheLoader extends Loader
       $this->debugger->log(sprintf('Storing template "%s" in cache', $template));
     }
 
-    return new FileStorage($path, $renderer);
+    return new FileStorage($path, $options['renderer']);
   }
 }

+ 5 - 3
src/Symfony/Components/Templating/Loader/ChainLoader.php

@@ -36,6 +36,8 @@ class ChainLoader extends Loader
     {
       $this->addLoader($loader);
     }
+
+    parent::__construct();
   }
 
   /**
@@ -52,15 +54,15 @@ class ChainLoader extends Loader
    * Loads a template.
    *
    * @param string $template The logical template name
-   * @param string $renderer The renderer to use
+   * @param array  $options  An array of options
    *
    * @return Storage|Boolean false if the template cannot be loaded, a Storage instance otherwise
    */
-  public function load($template, $renderer = 'php')
+  public function load($template, array $options = array())
   {
     foreach ($this->loaders as $loader)
     {
-      if (false !== $ret = $loader->load($template, $renderer))
+      if (false !== $ret = $loader->load($template, $options))
       {
         return $ret;
       }

+ 16 - 5
src/Symfony/Components/Templating/Loader/FilesystemLoader.php

@@ -38,30 +38,41 @@ class FilesystemLoader extends Loader
     }
 
     $this->templatePathPatterns = $templatePathPatterns;
+
+    parent::__construct();
   }
 
   /**
    * Loads a template.
    *
    * @param string $template The logical template name
-   * @param string $renderer The renderer to use
+   * @param array  $options  An array of options
    *
    * @return Storage|Boolean false if the template cannot be loaded, a Storage instance otherwise
    */
-  public function load($template, $renderer = 'php')
+  public function load($template, array $options = array())
   {
     if (self::isAbsolutePath($template) && file_exists($template))
     {
       return new FileStorage($template);
     }
 
+    $options = $this->mergeDefaultOptions($options);
+    $options['name'] = $template;
+
+    $replacements = array();
+    foreach ($options as $key => $value)
+    {
+      $replacements['%'.$key.'%'] = $value;
+    }
+
     foreach ($this->templatePathPatterns as $templatePathPattern)
     {
-      if (is_file($file = strtr($templatePathPattern, array('%name%' => $template, '%renderer%' => $renderer))))
+      if (is_file($file = strtr($templatePathPattern, $replacements)))
       {
         if ($this->debugger)
         {
-          $this->debugger->log(sprintf('Loaded template file "%s" (renderer: %s)', $file, $renderer));
+          $this->debugger->log(sprintf('Loaded template file "%s" (renderer: %s)', $file, $options['renderer']));
         }
 
         return new FileStorage($file);
@@ -69,7 +80,7 @@ class FilesystemLoader extends Loader
 
       if ($this->debugger)
       {
-        $this->debugger->log(sprintf('Failed loading template file "%s" (renderer: %s)', $file, $renderer));
+        $this->debugger->log(sprintf('Failed loading template file "%s" (renderer: %s)', $file, $options['renderer']));
       }
     }
 

+ 29 - 0
src/Symfony/Components/Templating/Loader/Loader.php

@@ -23,6 +23,12 @@ use Symfony\Components\Templating\DebuggerInterface;
 abstract class Loader implements LoaderInterface
 {
   protected $debugger;
+  protected $defaultOptions;
+
+  public function __construct()
+  {
+    $this->defaultOptions = array('renderer' => 'php');
+  }
 
   /**
    * Sets the debugger to use for this loader.
@@ -33,4 +39,27 @@ abstract class Loader implements LoaderInterface
   {
     $this->debugger = $debugger;
   }
+
+  /**
+   * Sets a default option.
+   *
+   * @param string $name  The option name
+   * @param mixed  $value The option value
+   */
+  public function setDefaultOption($name, $value)
+  {
+    $this->defaultOptions[$name] = $value;
+  }
+
+  /**
+   * Merges the default options with the given set of options.
+   *
+   * @param array $options An array of options
+   *
+   * @return array The merged set of options
+   */
+  protected function mergeDefaultOptions(array $options)
+  {
+    return array_merge($this->defaultOptions, $options);
+  }
 }

+ 2 - 2
src/Symfony/Components/Templating/Loader/LoaderInterface.php

@@ -24,9 +24,9 @@ interface LoaderInterface
    * Loads a template.
    *
    * @param string $template The logical template name
-   * @param string $renderer The renderer to use
+   * @param array  $options  An array of options
    *
    * @return Storage|Boolean false if the template cannot be loaded, a Storage instance otherwise
    */
-  function load($template, $renderer = 'php');
+  function load($template, array $options = array());
 }

+ 4 - 4
tests/unit/Symfony/Components/Templating/EngineTest.php

@@ -54,11 +54,11 @@ class ProjectTemplateLoader extends Loader
     $this->templates[$name] = $template;
   }
 
-  public function load($template, $renderer = 'php')
+  public function load($template, array $options = array())
   {
-    if (isset($this->templates[$template.'.'.$renderer]))
+    if (isset($this->templates[$template.'.'.$options['renderer']]))
     {
-      return new StringStorage($this->templates[$template.'.'.$renderer]);
+      return new StringStorage($this->templates[$template.'.'.$options['renderer']]);
     }
 
     return false;
@@ -202,7 +202,7 @@ $t->is($engine->render('foo', array('foo' => 'foo', 'bar' => 'bar')), 'bar-foo-'
 
 class CompilableTemplateLoader extends Loader implements CompilableLoaderInterface
 {
-  public function load($template, $renderer = 'php')
+  public function load($template, array $options = array())
   {
     return new StringStorage($template, 'foo');
   }

+ 3 - 3
tests/unit/Symfony/Components/Templating/Loader/CacheLoaderTest.php

@@ -44,7 +44,7 @@ class ProjectTemplateLoaderVar extends Loader
     return 'Hello {{ name }}';
   }
 
-  public function load($template, $renderer = 'php')
+  public function load($template, array $options = array())
   {
     if (method_exists($this, $method = 'get'.ucfirst($template).'Template'))
     {
@@ -89,10 +89,10 @@ mkdir($dir, 0777, true);
 
 $loader = new ProjectTemplateLoader(new CompilableTemplateLoader(), $dir);
 $loader->setDebugger($debugger = new ProjectTemplateDebugger());
-$template = $loader->load('special', 'comp');
+$template = $loader->load('special', array('renderer' => 'comp'));
 $t->ok($debugger->hasMessage('Storing template'), '->load() logs a "Storing template" message if the template is found');
 $t->is($template->getRenderer(), 'php', '->load() changes the renderer to php if the template is compilable');
 
-$template = $loader->load('special', 'comp');
+$template = $loader->load('special', array('renderer' => 'comp'));
 $t->ok($debugger->hasMessage('Fetching template'), '->load() logs a "Storing template" message if the template is fetched from cache');
 $t->is($template->getRenderer(), 'php', '->load() changes the renderer to php if the template is compilable');

+ 1 - 1
tests/unit/Symfony/Components/Templating/Loader/ChainLoaderTest.php

@@ -47,5 +47,5 @@ $t->is($loader->getLoaders(), array($loader1, $loader2), '->addLoader() adds a t
 $t->diag('->load()');
 $loader = new ProjectTemplateLoader(array($loader1, $loader2));
 $t->ok($loader->load('bar') === false, '->load() returns false if the template is not found');
-$t->ok($loader->load('foo', 'xml') === false, '->load() returns false if the template does not exists for the given renderer');
+$t->ok($loader->load('foo', array('renderer' => 'xml')) === false, '->load() returns false if the template does not exists for the given renderer');
 $t->ok($loader->load('foo') instanceof FileStorage, '->load() returns a FileStorage if the template exists');

+ 1 - 1
tests/unit/Symfony/Components/Templating/Loader/FilesystemLoaderTest.php

@@ -64,7 +64,7 @@ $t->is((string) $storage, $path.'/foo.php', '->load() returns a FileStorage poin
 
 $loader = new ProjectTemplateLoader($pathPattern);
 $loader->setDebugger($debugger = new ProjectTemplateDebugger());
-$t->ok($loader->load('foo', 'xml') === false, '->load() returns false if the template does not exists for the given renderer');
+$t->ok($loader->load('foo', array('renderer' => 'xml')) === false, '->load() returns false if the template does not exists for the given renderer');
 $t->ok($debugger->hasMessage('Failed loading template'), '->load() logs a "Failed loading template" message if the template is not found');
 
 $loader = new ProjectTemplateLoader(array($fixturesPath.'/null/%name%', $pathPattern));

+ 1 - 1
tests/unit/Symfony/Components/Templating/Loader/LoaderTest.php

@@ -19,7 +19,7 @@ $t = new LimeTest(1);
 
 class ProjectTemplateLoader extends Loader
 {
-  public function load($template, $renderer = 'php')
+  public function load($template, array $options = array())
   {
   }