diff --git a/lib/SimpleSAML/XHTML/Template.php b/lib/SimpleSAML/XHTML/Template.php index 730fadff198956732552e30aa85b513896f4470b..14650fefb4d36127e806447ee89c3b335063b1c4 100644 --- a/lib/SimpleSAML/XHTML/Template.php +++ b/lib/SimpleSAML/XHTML/Template.php @@ -38,6 +38,11 @@ class SimpleSAML_XHTML_Template */ private $template = 'default.php'; + /* + * Main Twig namespace, to avoid misspelling it *again* + */ + private $twig_namespace = \Twig_Loader_Filesystem::MAIN_NAMESPACE; + /** * Constructor @@ -97,9 +102,17 @@ class SimpleSAML_XHTML_Template $filename = $split[1]; } $this->twig_template = $namespace ? '@'.$namespace.'/'.$filename : $filename; - $loader = new \Twig_Loader_Filesystem($this->configuration->resolvePath('templates')); - foreach ($this->findModuleTemplateDirs() as $module => $templateDir) { - $loader->prependPath($templateDir, $module); + $loader = new \Twig_Loader_Filesystem(); + $templateDirs = array_merge( + $this->findThemeTemplateDirs(), + $this->findModuleTemplateDirs() + ); + // default, themeless templates are checked last + $templateDirs[] = array( + $this->twig_namespace => $this->configuration->resolvePath('templates') + ); + foreach ($templateDirs as $entry) { + $loader->addPath($entry[key($entry)], key($entry)); } if (!$loader->exists($this->twig_template)) { return false; @@ -125,7 +138,47 @@ class SimpleSAML_XHTML_Template return true; } + private function findThemeTemplateDirs() + { + // parse config to find theme and module theme is in, if any + $tmp = explode(':', $this->configuration->getString('theme.use', 'default'), 2); + if (count($tmp) === 2) { + $themeModule = $tmp[0]; + $themeName = $tmp[1]; + } else { + $themeModule = null; + $themeName = $tmp[0]; + } + // default theme in use, abort + if ($themeName == 'default') { + return array(); + } + if ($themeModule !== null) { + $moduleDir = \SimpleSAML\Module::getModuleDir($themeModule); + $themeDir = $moduleDir.'/themes/'.$themeName; + $files = scandir($themeDir); + if ($files) { + $themeTemplateDirs = array(); + foreach ($files as $file) { + if ($file == '.' || $file == '..') { + continue; + } + // set correct name for default namespace + $ns = $file == 'default' ? $this->twig_namespace : $file; + $themeTemplateDirs[] = array($ns => $themeDir.'/'.$file); + } + return $themeTemplateDirs; + } + } + // theme not found + return array(); + } + /* + * Which enabled modules have templates? + * + * @return an array of module => templatedir lookups + */ private function findModuleTemplateDirs() { $all_modules = \SimpleSAML\Module::getModules(); @@ -138,7 +191,7 @@ class SimpleSAML_XHTML_Template // check if module has a /templates dir, if so, append $templatedir = $moduledir.'/templates'; if (is_dir($templatedir)) { - $modules[$module] = $templatedir; + $modules[] = array($module => $templatedir); } } return $modules;