added namespaced templates support in Twig_Loader_Filesystem
authorFabien Potencier <fabien.potencier@gmail.com>
Sat, 14 Jul 2012 13:26:10 +0000 (15:26 +0200)
committerFabien Potencier <fabien.potencier@gmail.com>
Sun, 22 Jul 2012 11:52:31 +0000 (13:52 +0200)
14 files changed:
CHANGELOG
composer.json
doc/api.rst
ext/twig/php_twig.h
lib/Twig/Loader/Filesystem.php
test/Twig/Tests/Loader/FilesystemTest.php
test/Twig/Tests/Loader/Fixtures/named/index.html [new file with mode: 0644]
test/Twig/Tests/Loader/Fixtures/named_bis/index.html [new file with mode: 0644]
test/Twig/Tests/Loader/Fixtures/named_final/index.html [new file with mode: 0644]
test/Twig/Tests/Loader/Fixtures/named_ter/index.html [new file with mode: 0644]
test/Twig/Tests/Loader/Fixtures/normal/index.html [new file with mode: 0644]
test/Twig/Tests/Loader/Fixtures/normal_bis/index.html [new file with mode: 0644]
test/Twig/Tests/Loader/Fixtures/normal_final/index.html [new file with mode: 0644]
test/Twig/Tests/Loader/Fixtures/normal_ter/index.html [new file with mode: 0644]

index f47168a..781d592 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,6 @@
-* 1.9.2 (2012-XX-XX)
+* 1.10.0 (2012-XX-XX)
 
+ * added namespaced templates support in Twig_Loader_Filesystem
  * added Twig_Loader_Filesystem::prependPath()
 
 * 1.9.1 (2012-07-22)
index d3d435b..463d1f2 100644 (file)
@@ -25,7 +25,7 @@
     },
     "extra": {
         "branch-alias": {
-            "dev-master": "1.9-dev"
+            "dev-master": "1.10-dev"
         }
     }
 }
index 30107d0..3a49129 100644 (file)
@@ -148,6 +148,19 @@ methods::
     $loader->addPath($templateDir3);
     $loader->prependPath($templateDir4);
 
+The filesystem loader also supports namespaced templates. This allows to
+divide your templates in different namespaces; each namespace having its own
+template paths. Namespaced templates can be accessed via the special
+``namespace_name#template_path`` notation::
+
+    $loader->addPath($templateDir, 'admin');
+
+    $twig->render('admin#index.html', array());
+
+The ``setPaths()``, ``addPath()``, and ``prependPath()`` methods all takes a
+namespace as an optional second argument; when not specified, these methods
+work on the "main" namespace.
+
 ``Twig_Loader_String``
 ......................
 
index 1973a8c..4e781c3 100644 (file)
@@ -15,7 +15,7 @@
 #ifndef PHP_TWIG_H
 #define PHP_TWIG_H
 
-#define PHP_TWIG_VERSION "1.9.2-DEV"
+#define PHP_TWIG_VERSION "1.10.0-DEV"
 
 #include "php.h"
 
index 62043bd..7def513 100644 (file)
@@ -33,36 +33,40 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface
     /**
      * Returns the paths to the templates.
      *
+     * @param string $namespace A path namespace
+     *
      * @return array The array of paths where to look for templates
      */
-    public function getPaths()
+    public function getPaths($namespace = '')
     {
-        return $this->paths;
+        return isset($this->paths[$namespace]) ? $this->paths[$namespace] : array();
     }
 
     /**
      * Sets the paths where templates are stored.
      *
-     * @param string|array $paths A path or an array of paths where to look for templates
+     * @param string|array $paths     A path or an array of paths where to look for templates
+     * @param string       $namespace A path namespace
      */
-    public function setPaths($paths)
+    public function setPaths($paths, $namespace = '')
     {
         if (!is_array($paths)) {
             $paths = array($paths);
         }
 
-        $this->paths = array();
+        $this->paths[$namespace] = array();
         foreach ($paths as $path) {
-            $this->addPath($path);
+            $this->addPath($path, $namespace);
         }
     }
 
     /**
      * Adds a path where templates are stored.
      *
-     * @param string $path A path where to look for templates
+     * @param string $path      A path where to look for templates
+     * @param string $namespace A path name
      */
-    public function addPath($path)
+    public function addPath($path, $namespace = '')
     {
         // invalidate the cache
         $this->cache = array();
@@ -71,15 +75,16 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface
             throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path));
         }
 
-        $this->paths[] = rtrim($path, '/\\');
+        $this->paths[$namespace][] = rtrim($path, '/\\');
     }
 
     /**
      * Prepends a path where templates are stored.
      *
-     * @param string $path A path where to look for templates
+     * @param string $path      A path where to look for templates
+     * @param string $namespace A path name
      */
-    public function prependPath($path)
+    public function prependPath($path, $namespace = '')
     {
         // invalidate the cache
         $this->cache = array();
@@ -88,7 +93,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface
             throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path));
         }
 
-        array_unshift($this->paths, rtrim($path, '/\\'));
+        array_unshift($this->paths[$namespace], rtrim($path, '/\\'));
     }
 
     /**
@@ -137,13 +142,23 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface
 
         $this->validateName($name);
 
-        foreach ($this->paths as $path) {
+        $namespace = '';
+        if (false !== $pos = strpos($name, '#')) {
+            $namespace = substr($name, 0, $pos);
+            $name = substr($name, $pos + 1);
+        }
+
+        if (!isset($this->paths[$namespace])) {
+            throw new \Twig_Error_Loader(sprintf('There is not registered paths for path name "%s".', $namespace));
+        }
+
+        foreach ($this->paths[$namespace] as $path) {
             if (is_file($path.'/'.$name)) {
                 return $this->cache[$name] = $path.'/'.$name;
             }
         }
 
-        throw new Twig_Error_Loader(sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths)));
+        throw new Twig_Error_Loader(sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths[$namespace])));
     }
 
     protected function validateName($name)
index 22ae5aa..28b5d18 100644 (file)
@@ -49,4 +49,32 @@ class Twig_Tests_Loader_FilesystemTest extends PHPUnit_Framework_TestCase
             array('filters\\//../\\/\\..\\AutoloaderTest.php'),
         );
     }
+
+    public function testPaths()
+    {
+        $basePath = dirname(__FILE__).'/Fixtures';
+
+        $loader = new Twig_Loader_Filesystem(array($basePath.'/normal', $basePath.'/normal_bis'));
+        $loader->setPaths(array($basePath.'/named', $basePath.'/named_bis'), 'named');
+        $loader->addPath($basePath.'/named_ter', 'named');
+        $loader->addPath($basePath.'/normal_ter');
+        $loader->prependPath($basePath.'/normal_final');
+        $loader->prependPath($basePath.'/named_final', 'named');
+
+        $this->assertEquals(array(
+            $basePath.'/normal_final',
+            $basePath.'/normal',
+            $basePath.'/normal_bis',
+            $basePath.'/normal_ter',
+        ), $loader->getPaths());
+        $this->assertEquals(array(
+            $basePath.'/named_final',
+            $basePath.'/named',
+            $basePath.'/named_bis',
+            $basePath.'/named_ter',
+        ), $loader->getPaths('named'));
+
+        $this->assertEquals("path (final)\n", $loader->getSource('index.html'));
+        $this->assertEquals("named path (final)\n", $loader->getSource('named#index.html'));
+    }
 }
diff --git a/test/Twig/Tests/Loader/Fixtures/named/index.html b/test/Twig/Tests/Loader/Fixtures/named/index.html
new file mode 100644 (file)
index 0000000..9e5449c
--- /dev/null
@@ -0,0 +1 @@
+named path
diff --git a/test/Twig/Tests/Loader/Fixtures/named_bis/index.html b/test/Twig/Tests/Loader/Fixtures/named_bis/index.html
new file mode 100644 (file)
index 0000000..d3a272b
--- /dev/null
@@ -0,0 +1 @@
+named path (bis)
diff --git a/test/Twig/Tests/Loader/Fixtures/named_final/index.html b/test/Twig/Tests/Loader/Fixtures/named_final/index.html
new file mode 100644 (file)
index 0000000..9f05d15
--- /dev/null
@@ -0,0 +1 @@
+named path (final)
diff --git a/test/Twig/Tests/Loader/Fixtures/named_ter/index.html b/test/Twig/Tests/Loader/Fixtures/named_ter/index.html
new file mode 100644 (file)
index 0000000..24fb68a
--- /dev/null
@@ -0,0 +1 @@
+named path (ter)
diff --git a/test/Twig/Tests/Loader/Fixtures/normal/index.html b/test/Twig/Tests/Loader/Fixtures/normal/index.html
new file mode 100644 (file)
index 0000000..e7a8fd4
--- /dev/null
@@ -0,0 +1 @@
+path
diff --git a/test/Twig/Tests/Loader/Fixtures/normal_bis/index.html b/test/Twig/Tests/Loader/Fixtures/normal_bis/index.html
new file mode 100644 (file)
index 0000000..bfa9160
--- /dev/null
@@ -0,0 +1 @@
+path (bis)
diff --git a/test/Twig/Tests/Loader/Fixtures/normal_final/index.html b/test/Twig/Tests/Loader/Fixtures/normal_final/index.html
new file mode 100644 (file)
index 0000000..73a089b
--- /dev/null
@@ -0,0 +1 @@
+path (final)
diff --git a/test/Twig/Tests/Loader/Fixtures/normal_ter/index.html b/test/Twig/Tests/Loader/Fixtures/normal_ter/index.html
new file mode 100644 (file)
index 0000000..b7ad97d
--- /dev/null
@@ -0,0 +1 @@
+path (ter)