Login page theming (theme class override)

Login page theming (theme class override)

by Didier Raboud -
Number of replies: 2

While implementing a lightweight theme inheriting from Boost, I stumbled upon a change I didn't manage to do cleanly without a core patch.

The idea is to prominently propose Shibboleth login without using $CFG->alternateloginurl, producing something along these lines →

As I didn't want to put that code in the mustache template (because that's WAYF code handled by a block, here's what I did:

  • Added theme/xxx/templates/core/loginform.mustache with a variable addition:
(…)
{{#mycontent}}
<div>{{{ mycontent }}}</div>
{{/mycontent}}
(…)
  • Created theme/xxx/classes/core_auth/output/login.php with this:
    <?php
    namespace theme_xxx\core_auth\output;
    require_once($CFG->libdir . '/externallib.php');
    use renderer_base;
    class login extends \core_auth\output\login {
        public function export_for_template(renderer_base $output) {
            global $CFG, $PAGE;
            $data = parent::export_for_template($output);
            // Add my content here; assume it's not possible in a mustache template
            $data->mycontent = rand();
            return $data;
        }
    }
  • Then I expected that \theme_xxx\core_auth\output\login class to be used from /login/index.php automagically
  • … it doesn't work, so I had to patch /login/index.php with this:
         } else {
    -    $loginform = new \core_auth\output\login($authsequence, $frm->username);
    +    if ($PAGE->theme->name == 'xxx') {
    +        $loginform = new \theme_xxx\core_auth\output\login($authsequence, $frm->username);
    +    } else {
    +        $loginform = new \core_auth\output\login($authsequence, $frm->username);
    +    }
         $loginform->set_error($errormsg);
    
Is this a bug, or me not understanding how classes and theme classes override work?

Should the \core_auth\output\login renderer not be more easily overrideable?
If not, what am I missing, and how more easily could such a thing be done?
Average of ratings: -
In reply to Didier Raboud

Re: Login page theming (theme class override)

by Gareth J Barnard -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Plugin developers

How do you know your 'export_for_template' is not actually being called but not using your template?....

But then in 'outputrenderers.php' there is:

    /**
     * Renders the login form.
     *
     * @param \core_auth\output\login $form The renderable.
     * @return string
     */
    public function render_login(\core_auth\output\login $form) {
        $context = $form->export_for_template($this);
        // Override because rendering is not supported in template yet.
        $context->cookieshelpiconformatted = $this->help_icon('cookiesenabled');
        $context->errorformatted = $this->error_text($context->error);
        return $this->render_from_template('core/loginform', $context);
    }

so no autoloading but fixed class names and specifically located template.  Which if I'm wrong and the class you have is autoloaded, will still mean that the template is not yours so the additional context data will be unused.

In reply to Gareth J Barnard

Re: Login page theming (theme class override)

by Didier Raboud -
How do you know your 'export_for_template' is not actually being called but not using your template?....

I tested smile

The template is not fixed (it's not a fullpath, but a template name); and render_from_template will use the correct template, I tested that as well.

My understanding is that themes are allowed to override renderers only, through theme_overridden_renderer_factory, but not arbitrary functions.

But you put me on the right tracks: by overriding render_login in the theme_xxx/classes/core_renderer.php's theme_fhsg_core_renderer class, one can achieve what they want without a core hack. Thanks!