diff --git a/src/Mustache/Loader/FilesystemLoader.php b/src/Mustache/Loader/FilesystemLoader.php index a3137513..bd5101ee 100644 --- a/src/Mustache/Loader/FilesystemLoader.php +++ b/src/Mustache/Loader/FilesystemLoader.php @@ -42,19 +42,23 @@ class Mustache_Loader_FilesystemLoader implements Mustache_Loader * * @throws Mustache_Exception_RuntimeException if $baseDir does not exist * - * @param string $baseDir Base directory containing Mustache template files - * @param array $options Array of Loader options (default: array()) + * @param string|array $baseDir Base directory containing Mustache template files + * @param array $options Array of Loader options (default: array()) */ public function __construct($baseDir, array $options = array()) { - $this->baseDir = $baseDir; - - if (strpos($this->baseDir, '://') === false) { - $this->baseDir = realpath($this->baseDir); + if (is_array($baseDir)) { + $this->baseDir = array(); + foreach ($baseDir as $dir) { + $this->baseDir[] = $this->sanitizeDir($dir); + } + } else { + $this->baseDir = array($this->sanitizeDir($baseDir)); } - if ($this->shouldCheckPath() && !is_dir($this->baseDir)) { - throw new Mustache_Exception_RuntimeException(sprintf('FilesystemLoader baseDir must be a directory: %s', $baseDir)); + + if (empty($this->baseDir)) { + throw new Mustache_Exception_RuntimeException('FilesystemLoader baseDir must have at least one directory.'); } if (array_key_exists('extension', $options)) { @@ -96,25 +100,29 @@ public function load($name) */ protected function loadFile($name) { - $fileName = $this->getFileName($name); + foreach ($this->baseDir as $dir) { + $fileName = $this->getFileName($name, $dir); - if ($this->shouldCheckPath() && !file_exists($fileName)) { - throw new Mustache_Exception_UnknownTemplateException($name); + if (!$this->shouldCheckPath($dir) || file_exists($fileName)) { + return file_get_contents($fileName); + } } - return file_get_contents($fileName); + // No template found + throw new Mustache_Exception_UnknownTemplateException($name); } /** * Helper function for getting a Mustache template file name. * * @param string $name + * @param string $dir * * @return string Template file name */ - protected function getFileName($name) + protected function getFileName($name, $dir) { - $fileName = $this->baseDir . '/' . $name; + $fileName = $dir . '/' . $name; if (substr($fileName, 0 - strlen($this->extension)) !== $this->extension) { $fileName .= $this->extension; } @@ -122,14 +130,39 @@ protected function getFileName($name) return $fileName; } + /** + * Sanitize a directory name. + * + * @throws Mustache_Exception_RuntimeException If a directory is not valid + * + * @param string $dir + * + * @return string The sanitized / real path of the directory + */ + protected function sanitizeDir($dir) + { + + if (strpos($dir, '://') === false) { + $dir = realpath($dir); + } + + if ($this->shouldCheckPath($dir) && !is_dir($dir)) { + throw new Mustache_Exception_RuntimeException(sprintf('FilesystemLoader directory must be a directory: %s', $dir)); + } + + return $dir; + } + /** * Only check if baseDir is a directory and requested templates are files if * baseDir is using the filesystem stream wrapper. * + * @param string $dir + * * @return bool Whether to check `is_dir` and `file_exists` */ - protected function shouldCheckPath() + protected function shouldCheckPath($dir) { - return strpos($this->baseDir, '://') === false || strpos($this->baseDir, 'file://') === 0; + return strpos($dir, '://') === false || strpos($dir, 'file://') === 0; } } diff --git a/test/Mustache/Test/Loader/FilesystemLoaderTest.php b/test/Mustache/Test/Loader/FilesystemLoaderTest.php index 75880d40..6e39cc51 100644 --- a/test/Mustache/Test/Loader/FilesystemLoaderTest.php +++ b/test/Mustache/Test/Loader/FilesystemLoaderTest.php @@ -29,6 +29,18 @@ public function testTrailingSlashes() $this->assertEquals('one contents', $loader->load('one')); } + public function testConstructorWithMultipleDirs() + { + $baseDir = array( + realpath(dirname(__FILE__) . '/../../../fixtures/templates'), + realpath(dirname(__FILE__) . '/../../../fixtures/more_templates'), + ); + $loader = new Mustache_Loader_FilesystemLoader($baseDir, array('extension' => '.ms')); + $this->assertEquals('alpha contents', $loader->load('alpha')); + $this->assertEquals('beta contents', $loader->load('beta.ms')); + $this->assertEquals('gamma contents', $loader->load('gamma.ms')); + } + public function testConstructorWithProtocol() { $baseDir = realpath(dirname(__FILE__) . '/../../../fixtures/templates'); diff --git a/test/fixtures/more_templates/gamma.ms b/test/fixtures/more_templates/gamma.ms new file mode 100644 index 00000000..0416a599 --- /dev/null +++ b/test/fixtures/more_templates/gamma.ms @@ -0,0 +1 @@ +gamma contents \ No newline at end of file diff --git a/test/fixtures/more_templates/three.ms b/test/fixtures/more_templates/three.ms new file mode 100644 index 00000000..76abb9df --- /dev/null +++ b/test/fixtures/more_templates/three.ms @@ -0,0 +1 @@ +three contents \ No newline at end of file