diff --git a/lib/SimpleSAML/XHTML/Template.php b/lib/SimpleSAML/XHTML/Template.php index 06a9a163d67247e79b9c3c75077c9e4535444ab5..74f85e63115163d4d7f9678a8740e16533af0f5c 100644 --- a/lib/SimpleSAML/XHTML/Template.php +++ b/lib/SimpleSAML/XHTML/Template.php @@ -165,14 +165,16 @@ class Template // get namespace if any list($namespace, $filename) = $this->findModuleAndTemplateName($filename); $this->twig_template = ($namespace !== null) ? '@'.$namespace.'/'.$filename : $filename; - $loader = new \Twig_Loader_Filesystem(); + $loader = new TemplateLoader(); $templateDirs = $this->findThemeTemplateDirs(); if ($this->module) { - $templateDirs[] = array($this->module => $this->getModuleTemplateDir($this->module)); + $templateDirs[] = array($this->module => TemplateLoader::getModuleTemplateDir($this->module)); } if ($this->theme['module']) { try { - $templateDirs[] = array($this->theme['module'] => $this->getModuleTemplateDir($this->theme['module'])); + $templateDirs[] = array( + $this->theme['module'] => TemplateLoader::getModuleTemplateDir($this->theme['module']) + ); } catch (\InvalidArgumentException $e) { // either the module is not enabled or it has no "templates" directory, ignore } @@ -297,10 +299,11 @@ class Template return $themeTemplateDirs; } + /** * Get the template directory of a module, if it exists. * - * @return string The templates directory of a module. + * @return string The templates directory of a module * * @throws \InvalidArgumentException If the module is not enabled or it has no templates directory. */ @@ -330,7 +333,7 @@ class Template */ public function addTemplatesFromModule($module) { - $dir = $this->getModuleTemplateDir($module); + $dir = TemplateLoader::getModuleTemplateDir($module); /** @var \Twig_Loader_Filesystem $loader */ $loader = $this->twig->getLoader(); $loader->addPath($dir, $module); diff --git a/lib/SimpleSAML/XHTML/TemplateLoader.php b/lib/SimpleSAML/XHTML/TemplateLoader.php new file mode 100644 index 0000000000000000000000000000000000000000..d3a9f853c691beff206109a192ae4059faff58e0 --- /dev/null +++ b/lib/SimpleSAML/XHTML/TemplateLoader.php @@ -0,0 +1,65 @@ +<?php + + +namespace SimpleSAML\XHTML; + +/** + * This class extends the Twig\Loader\FilesystemLoader so that we can load templates from modules in twig, even + * when the main template is not part of a module (or the same one). + * + * @package simplesamlphp/simplesamlphp + */ +class TemplateLoader extends \Twig\Loader\FilesystemLoader +{ + /** + * This method adds a namespace dynamically so that we can load templates from modules whenever we want. + * + * @inheritdoc + */ + protected function findTemplate($name) + { + list($namespace, $shortname) = $this->parseName($name); + if (!in_array($namespace, $this->paths, true) && $namespace !== self::MAIN_NAMESPACE) { + $this->addPath(self::getModuleTemplateDir($namespace), $namespace); + } + return parent::findTemplate($name); + } + + + protected function parseName($name, $default = self::MAIN_NAMESPACE) + { + if (strpos($name, ':')) { + // we have our old SSP format + list($namespace, $shortname) = explode(':', $name, 2); + $shortname = strtr($shortname, array( + '.tpl.php' => '.twig', + '.php' => '.twig', + )); + return array($namespace, $shortname); + } + return parent::parseName($name, $default); + } + + + /** + * Get the template directory of a module, if it exists. + * + * @return string The templates directory of a module. + * + * @throws \InvalidArgumentException If the module is not enabled or it has no templates directory. + */ + public static function getModuleTemplateDir($module) + { + if (!\SimpleSAML\Module::isModuleEnabled($module)) { + throw new \InvalidArgumentException('The module \''.$module.'\' is not enabled.'); + } + $moduledir = \SimpleSAML\Module::getModuleDir($module); + // check if module has a /templates dir, if so, append + $templatedir = $moduledir.'/templates'; + if (!is_dir($templatedir)) { + throw new \InvalidArgumentException('The module \''.$module.'\' has no templates directory.'); + + } + return $templatedir; + } +} \ No newline at end of file