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