Override few mform templates

Override few mform templates

by Daniele Cordella -
Number of replies: 15
Picture of Core developers Picture of Plugin developers

Following the good article "Adding renderers and templates to your Moodle plugin" by Mike Churchward it is simple to understand how to add new renderers and templates to display a page. What I still can not figure out is how can I override few templates used by mform to display mform elements in the frame of a new plugin.

Moodle uses .mustache element templates from lib/form/templates. Following https://docs.moodle.org/dev/Templates I tried to override few of them by duplicating them to to my myplugin/templates but they are not loaded (of course). I am not sure about how to use render_from_template only for some mform element. For instance: I want to accept all the templates used by moodle for each mform element but not the one used to display, let's say, the "select" element (element-select.mustache). How can I override it only?

Average of ratings: -
In reply to Daniele Cordella

Re: Override few mform templates

by Mark Johnson -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

Only themes can override templates and renderers. You can't do it in other plugin types.

To override a specific template, you put your copy of just that template in your theme's templates folder (under the appropriate subdirectory as described in the documentation).

In reply to Mark Johnson

Re: Re: Override few mform templates

by Daniele Cordella -
Picture of Core developers Picture of Plugin developers
Thanks Johnson but I tried to do 100% what you suggest and it doesn't work.
My local template file is not loaded at mform display time.
I copied into my myplugin/templates/element-select.mustache taken from lib/form/templates/ and it is ignored. I slightly changed it adding a silly text and I am 100% sure it is ignored.
In reply to Daniele Cordella

Re: Re: Re: Override few mform templates

by Mark Johnson -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

For form elements, I think they need to go in /theme/mytheme/templates/core_form/

In reply to Mark Johnson

Re: Re: Re: Re: Override few mform templates

by Daniele Cordella -
Picture of Core developers Picture of Plugin developers
I am not writing a theme. I am developing an activity module. I am not supposed to interact with any theme.
In reply to Daniele Cordella

Re: Re: Re: Re: Re: Override few mform templates

by Mark Johnson -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

As I said above, if you want to override a template or renderer, this is only possible in a theme. Other types of plugin cannot do this.

In reply to Daniele Cordella

Re: Aw: Override few mform templates

by Andreas Grabs -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers Picture of Translators
Hi Daniele,

what exactly do you mean by "display mform elements in the frame of a new plugin"?

If you don't want to change the whole element but some styles you can use the "styles.css" in your plugin folder.
If you want to display the elements in a different way as it is by default, for example you want to show your elements in separate div containers of your page, you could use the html-elements in your mform.
That means you could start a div container, add an input and close the div container.

Example:

$mform->addElement('html', '<div class="xyz">');
$mform->addElement('text', .....);
$mform->addElement('html', '</div>');

Maybe that helps a bit.

Best regards
Andreas

In reply to Andreas Grabs

Re: Re: Aw: Override few mform templates

by Daniele Cordella -
Picture of Core developers Picture of Plugin developers
Ciao Andreas and thanks for your answer.
I am developing this: https://github.com/kordan/moodle-mod_surveypro.
In the frame of this plugin I use mform to provide forms to users.
I 100% use mform library.
An example of code from my activity module could be:
<?php

require_once('config.php');
require_once($CFG->dirroot.'/lib/formslib.php');
class test_form extends moodleform { function definition() { $mform = $this->_form; $mform->addElement('text', 'text_element', 'Enter a text'); $mform->setType('text_element', PARAM_TEXT); $mform->addElement('select', 'select_element', 'Choose an item', ['north', 'west', 'south', 'east']); $this->add_action_buttons(); } } // =================== $PAGE->set_context(context_system::instance()); $PAGE->set_url('/mformtest.php'); $PAGE->set_title('mformtest'); $mform = new test_form(new moodle_url('/mformtest.php')); if ($mform->is_cancelled()) {} if ($data = $mform->get_data()) {} echo $OUTPUT->header(); $mform->display(); echo $OUTPUT->footer();
To display the form, Moodle uses templates from lib/form/templates. Each mform element has a specific template.
For instance:
  • $mform->addElement('text', 'text_element', 'Enter a text'); uses lib/form/templates/element-text.mustache
  • $mform->addElement('select', 'select_element', 'Choose an item', ['north', 'west', 'south', 'east']);uses lib/form/templates/element-select.mustache
I would only replace few of them with a custom copy from my activity module.
Following https://docs.moodle.org/dev/Templates and what Mark Johnson writes, I should only add a custom copy of the templates to my plugin/templates/ folder.
The problem is that... it doesn't work.
In reply to Daniele Cordella

Re: Re: Re: Aw: Override few mform templates

by Davo Smith -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
As already mentioned in this discussion, it is only themes that can override templates.

The reason for this is that there is no way to override a template on only specific pages - when a template is overridden, it is overridden across the entire site. Themes are allowed to do this as a powerful mechanism for making consistent changes to the look of page elements across the site.

The important question in this case is what do you actually want to change in the template?

Normally, you would want Moodle form elements to be displayed consistently on every page (that is one of the advantages of using a forms library, instead of hand-coding each form).
In reply to Davo Smith

Re: Re: Re: Re: Aw: Override few mform templates

by Daniele Cordella -
Picture of Core developers Picture of Plugin developers
Thanks Davo.
I found details that I feel are bugs.
Instead of asking in the tracker to change templates I thought it was simpler to override them locally.
I go to rise up issues in the tracker explaining why I feel there are details to fix.
Thanks again.
In reply to Daniele Cordella

Re: Re: Re: Aw: Override few mform templates

by Mark Sharp -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Plugin developers
Is your custom template for the element so radical you can't achieve the same outcome by passing in some classes or other attributes and manage how they look or behave via css or javascript?
In reply to Daniele Cordella

Re: Override few mform templates

by Darko Miletić -

You have several options here:

  • Modify templates in the theme you are currently using.
  • Create a custom theme and place your templates there. You would ship the plugin and custom theme.
  • Rewrite generated HTML of form before displaying it.

In the the classic Moodle page you usually have something like this:

$form = new tform($PAGE->url);

echo $OUTPUT->header();

$form->display();

echo $OUTPUT->footer();

In your case you could do something like this:

$form = new tform($PAGE->url);

// HTML of the form.
$rendered = $form->render();
// Do something with the string.
$rewrite = str_replace('foo', 'faa', $rendered);

echo $OUTPUT->header();

echo $rewrite;

echo $OUTPUT->footer();


In reply to Darko Miletić

Re: Re: Override few mform templates

by Daniele Cordella -
Picture of Core developers Picture of Plugin developers
Ciao Darko and thanks for your answer.
I wrote an answer to Andreas in this thread that could be correct for you too.
In reply to Daniele Cordella

Re: Re: Re: Override few mform templates

by Darko Miletić -
You do not understand what all of us are trying to tell you here. If you develop a plugin that depends on the modification inside Moodle core in order to get that functionality somewhere else you have to give to the user your complete version of Moodle. You are essentially creating a fork. Who will ensure later to update that moodle and not break your changes etc.