diff --git a/modules/admin/lib/ConfigController.php b/modules/admin/lib/ConfigController.php
index 0a06413b2c0282a135c2420e8b468bdafdce6986..d3851559b20e18beda0f5cef38058f3cb9d9f71b 100644
--- a/modules/admin/lib/ConfigController.php
+++ b/modules/admin/lib/ConfigController.php
@@ -24,6 +24,9 @@ class ConfigController
     /** @var \SimpleSAML\Configuration */
     protected $config;
 
+    /** @var Menu */
+    protected $menu;
+
     /** @var \SimpleSAML\Session */
     protected $session;
 
@@ -38,6 +41,7 @@ class ConfigController
     {
         $this->config = $config;
         $this->session = $session;
+        $this->menu = new Menu();
     }
 
 
@@ -70,7 +74,9 @@ class ConfigController
                 'getSelfURL()' => [HTTP::getSelfURL()],
             ],
         ];
-        return $t;
+
+        $this->menu->addOption('logout', \SimpleSAML\Utils\Auth::getAdminLogoutURL(), Translate::noop('Log out'));
+        return $this->menu->insert($t);
     }
 
 
@@ -107,8 +113,8 @@ class ConfigController
         ];
 
         \SimpleSAML\Module::callHooks('configpage', $t);
-
-        return $t;
+        $this->menu->addOption('logout', \SimpleSAML\Utils\Auth::getAdminLogoutURL(), Translate::noop('Log out'));
+        return $this->menu->insert($t);
     }
 
 
@@ -124,6 +130,16 @@ class ConfigController
 
 
     /**
+     * Perform a list of checks on the current installation, and return the results as an array.
+     *
+     * The elements in the array returned are also arrays with the following keys:
+     *
+     *   - required: Whether this prerequisite is mandatory or not. One of "required" or "optional".
+     *   - descr: A translatable text that describes the prerequisite. If the text uses parameters, the value must be an
+     *     array where the first value is the text to translate, and the second is a hashed array containing the
+     *     parameters needed to properly translate the text.
+     *   - enabled: True if the prerequisite is met, false otherwise.
+     *
      * @return array
      */
     protected function getPrerequisiteChecks()
@@ -131,7 +147,13 @@ class ConfigController
         $matrix = [
             [
                 'required' => 'required',
-                'descr' => 'PHP version >= 5.5. You run: '.phpversion(),
+                'descr' => [
+                    Translate::noop('PHP %minimum% or newer is needed. You are running: %current%'),
+                    [
+                        '%minimum%' => '5.5',
+                        '%current%' => explode('-', phpversion())[0]
+                    ]
+                ],
                 'enabled' => version_compare(phpversion(), '5.5', '>=')
             ]
         ];
diff --git a/modules/admin/lib/Menu.php b/modules/admin/lib/Menu.php
new file mode 100644
index 0000000000000000000000000000000000000000..e4e55250cfda2b9e43a1e5bb8ab58b87298b52a1
--- /dev/null
+++ b/modules/admin/lib/Menu.php
@@ -0,0 +1,90 @@
+<?php
+
+namespace SimpleSAML\Module\admin;
+
+use SimpleSAML\Locale\Translate;
+use SimpleSAML\Module;
+use SimpleSAML\XHTML\Template;
+
+/**
+ * A class to handle the menu in admin pages.
+ *
+ * @package SimpleSAML\Module\admin
+ */
+final class Menu
+{
+    /** @var array */
+    private $options;
+
+
+    /**
+     * Menu constructor.
+     *
+     * Initialize the menu with some default admin options, and call a hook for anyone willing to extend it.
+     */
+    public function __construct()
+    {
+        $this->options = [
+            'main' => [
+                'url' => Module::getModuleURL('admin/'),
+                'name' => Translate::noop('Configuration'),
+            ],
+            'test' => [
+                'url' => Module::getModuleURL('admin/test'),
+                'name' => Translate::noop('Test'),
+            ],
+            'federation' => [
+                'url' => Module::getModuleURL('admin/federation'),
+                'name' => Translate::noop('Federation')
+            ]
+        ];
+    }
+
+
+    /**
+     * Add a new option to this menu.
+     *
+     * If an option with the same $id already exists, it will be overwritten. Otherwise, the option is appended. Note
+     * that if the name of the option needs translation, you need to prepare for translation on your own (e.g. by
+     * registering your module as a translation domain in the template).
+     *
+     * @param string $id The identifier of this option.
+     * @param string $url The URL this option points to.
+     * @param string $name The name of the option for display purposes.
+     */
+    public function addOption($id, $url, $name)
+    {
+        $this->options[$id] = [
+            'url' => $url,
+            'name' => $name,
+        ];
+    }
+
+
+    /**
+     * Inserts this menu into a template.
+     *
+     * The menu will be inserted into the "data" of the template, in the form of an array, where the key for each
+     * element is the identifier of the option (the default theme will compare this ID when determining if a menu
+     * option is currently selected), and the value itself is also an array with two keys:
+     *
+     *   - url: The URL this option points to.
+     *   - name: The name of the option for display purposes.
+     *
+     * This method will call the "adminmenu" hook, allowing modules to extend the menu by adding new options. If you
+     * are adding an option and need to translate its name, you need to add the translations to your own module, and
+     * add your module as a translation domain to the template object:
+     *
+     *   $template->getLocalization()->addModuleDomain('mymodule');
+     *
+     * @param \SimpleSAML\XHTML\Template $template The template we should insert this menu into.
+     *
+     * @return \SimpleSAML\XHTML\Template The template with the added menu.
+     */
+    public function insert(Template $template)
+    {
+        $template->data['menu'] = $this->options;
+        Module::callHooks('adminmenu', $template);
+        return $template;
+    }
+}
diff --git a/modules/admin/templates/config.twig b/modules/admin/templates/config.twig
index 58bbbbbbef5eba4df1f137c19e9536b4fddf4b27..300ae6994744cdce1a6721c8c728b04d40182d27 100644
--- a/modules/admin/templates/config.twig
+++ b/modules/admin/templates/config.twig
@@ -51,7 +51,13 @@
               {%- trans %}optional{% endtrans %}
             {%- endif -%}
             </td>
-            <td>{{ func.descr|trans|raw }}</td>
+            <td>
+              {%- if func.descr is iterable -%}
+                {{ func.descr[0]|trans(func.descr[1]|raw) }}
+              {%- else -%}
+                {{ func.descr|trans|raw }}
+              {%- endif -%}
+            </td>
           </tr>
         {%- endfor %}
 
diff --git a/modules/admin/templates/includes/menu.twig b/modules/admin/templates/includes/menu.twig
index 7400477dffae0928fc2cc3f65d90634d541d5d74..fda00d6e6abe538740546593eeb2c59cf61b7438 100644
--- a/modules/admin/templates/includes/menu.twig
+++ b/modules/admin/templates/includes/menu.twig
@@ -1,20 +1,15 @@
 <div class="pure-g frontpage-menu">
-    <div class="pure-u-2-3">
-        <div class="pure-menu pure-menu-horizontal">
-            <ul class="pure-menu-list">
-                <li class="pure-menu-item{% if frontpage_section == "main" %} pure-menu-selected{% endif %}">
-                    <a href="/{{ baseurlpath }}module.php/admin/" class="pure-menu-link">Admin</a>
-                </li>
-                <li class="pure-menu-item{% if frontpage_section == "test" %} pure-menu-selected{% endif %}">
-                    <a href="/{{ baseurlpath }}module.php/admin/test" class="pure-menu-link">Test</a>
-                </li>
-                <li class="pure-menu-item{% if frontpage_section == "federation" %} pure-menu-selected{% endif %}">
-                    <a href="/{{ baseurlpath }}module.php/admin/federation" class="pure-menu-link">Federation</a>
-                </li>
-                <li class="pure-menu-item">
-                    <a href="{{ logouturl }}" class="pure-menu-link">Logout</a>
-                </li>
-            </ul>
-        </div>
+  <div class="pure-u-2-3">
+    <div class="pure-menu pure-menu-horizontal">
+      <ul class="pure-menu-list">
+        {%- for id,option in menu %}
+
+        <li class="pure-menu-item{% if frontpage_section == id %} pure-menu-selected{% endif %}">
+          <a href="{{ option.url }}" class="pure-menu-link">{{ option.name|trans }}</a>
+        </li>
+        {%- endfor %}
+
+      </ul>
     </div>
+  </div>
 </div>