General developer forum

Can the class qbehaviour_renderer be overriden in theme?

Picture of Lea Cohen
Can the class qbehaviour_renderer be overriden in theme?

I want to add a  CSS class to the submit button of a question. I thought the best way to do that is by overriding the submit_button function of the qbehaviour_renderer class in my theme.

I tried doing that, and although my IDE shows that my function IS overriding what I want, Moodle actually doesn't go into my class and function.

I don't know what I'm doing wrong:

  1. Does the class name matter? Does it have to start with theme_mytheme
  2. Does the name of the file in which I place the class matter?
  3. Do I place the file under classes/output or under classes/output/core?

Or maybe it's not at all possible to override that class from a theme? I couldn't find any documentation on this subject.

Average of ratings: -
Picture of Michael Aherne
Re: Can the class qbehaviour_renderer be overriden in theme?
Core developersPlugin developers

The documentation you're looking for is You should find answers to all your questions in there.

Average of ratings: Useful (1)
Picture of Lea Cohen
Re: Can the class qbehaviour_renderer be overriden in theme?

Thank you very much. I actually did follow that document, but things didn't work.

I created a class and named it according to the rules, and included the file in which the original class was.

I put all of that in my classes/output/core_renderer.php file (which already has a core_renderer class in it, that works).

include_once ($CFG->dirroot."/question/behaviour/rendererbase.php");
class theme_aviv2018_qbehaviour_renderer extends qbehaviour_renderer {

However that rendered an error:

( ! ) Fatal error: Class 'theme_aviv2018\output\qbehaviour_renderer' not found in /theme/aviv2018/classes/output/core_renderer.php on line 665

So I added a slash before the classname I extended and that got rid of the error.

class theme_aviv2018_qbehaviour_renderer extends \qbehaviour_renderer
Now the error went away, but the function which I overrode isn't called.

I tried moving the class to different files, tried creating a folder called question (the same as there is a folder named core) but I haven't found anything that works.

This is where I'm stuck now smile

Average of ratings: -
Tim at Lone Pine Koala Sanctuary
Re: Can the class qbehaviour_renderer be overriden in theme?
Core developersDocumentation writersParticularly helpful MoodlersPlugin developers

Unfortunately, this is a mistake (that was my fault).

Overriding a renderer does not work for a base class. So, the fact we have qbehaviour_deferredfeedback_renderer extends qbehaviour_renderer means that you can override qbehaviour_deferredfeedback_renderer, because then you end up with

theme_mytheme_qbehaviour_deferredfeedback_renderer extends qbehaviour_deferredfeedback_renderer extends qbehaviour_renderer, and your methods will be used in preference to the core ones.

However, making as subclass that extends qbehaviour_renderer does not have any effect, becuase  qbehaviour_deferredfeedback_renderer does not extend theme_mytheme_qbehaviour_renderer.

What should have been done is that shared methods that output stuff that themes want to override should have been methods of something like core_question_renderer, that could be overridden.

At some point, we will have to change things to make this work, but no-one has needed it badly enough to implement it yet. Patches welcome.

Average of ratings: Useful (1)
Picture of Lea Cohen
Re: Can the class qbehaviour_renderer be overriden in theme?
Thank you very much for your detailed reply, I really appreciate it. I actually did see that the base calls was ovrriden by the various behaviours but it didn't occur to me that that means I should be extending them. Wasn't thinking things through, unfortunately.

I tried now, however, to override one of the subclassses used in our instance - adaptivenopenalty:
require_once($CFG->dirroot . '/question/behaviour/adaptivenopenalty/renderer.php'); 
class theme_mytheme_qbehaviour_adaptivenopenalty_renderer extends \qbehaviour_adaptivenopenalty_renderer {
But that still doesn't work (the function isn't called), and on some pages it even gives me an error about its parent class (qbehaviour_adaptivenopenalty_renderer extentds qbehaviour_adaptive_renderer) and that's weird since I didn't touch any other file other that my core_renderer:

( ! ) Fatal error: Class 'qbehaviour_renderer' not found in /html/aviv2017/question/behaviour/adaptive/renderer.php on line

But I don't want to burden you with these problem since I think this isn't the path to go in since, even if it worked, I'd have to extend all subclasses and that's too tedious and error prone, and also doesn't scale if more subclasses are added.

Since the change I want is to add a class to the submit button,  I see my options as follows:
  1. Make my change in core (in the original qbehaviour_renderer class) and take care of upgrade clashes, if occur, using git.
  2. Make my change using JavaScript.
  3. Adapt the CSS to conform to the current classes.
Non of them is ideal, but they'll work.

Regarding patch:  I'd love to write a patch but unfortunately I'm not familiar enough with the Moodle code to do so.
Average of ratings: -