Skip to content

Commit 65c719f

Browse files
authored
Merge pull request #1104 from NeillM/named_templates
Document named_templates
2 parents 96ad1c6 + b763e8a commit 65c719f

File tree

9 files changed

+253
-59
lines changed

9 files changed

+253
-59
lines changed

docs/apis/subsystems/output/index.md

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,9 @@ In the code above, we created a renderable. This is a class that you have to add
116116

117117
namespace tool_demo\output;
118118

119-
use renderable
120-
use renderer_base
121-
use templatable
119+
use renderable;
120+
use renderer_base;
121+
use templatable;
122122
use stdClass;
123123

124124
class index_page implements renderable, templatable {
@@ -142,7 +142,25 @@ class index_page implements renderable, templatable {
142142
}
143143
```
144144

145-
This class implements the renderable interface, which has no methods, and the templatable interface, which means that this class could be rendered with a template, so it must implement the `export_for_template` method. So in this example, the class accepts data via it's constructor, and stores that data in class variables. It does nothing else fancy with the data in this example (but it could). Note that the `export_for_template` function should only return simple types (arrays, stdClass, bool, int, float, string).
145+
This class implements the:
146+
147+
- `renderable` interface, which has no methods
148+
- `templatable` interface, which means that this class could be rendered with a template, so it must implement the `export_for_template` method
149+
150+
In this example, the class accepts data via it's constructor, and stores that data in class variables. It does nothing else with the data in this example (but it could). Note that the `export_for_template` function should only return simple types (`arrays`, `stdClass`, `bool`, `int`, `float`, `string`), or those that implement the [`Stringable`](https://www.php.net/manual/en/class.stringable.php) interface.
151+
152+
If you wish to use a specific template to render the content you may specify anyone by replacing `templatable` with `named_templatable`, which extends templatable and requires that you implement a `get_template_name()` method that returns the name of the template you wish to use.
153+
154+
```php title="Example implementation of get_template_name()"
155+
/**
156+
* Gets the name of the mustache template used to render the data.
157+
*
158+
* @return string
159+
*/
160+
public function get_template_name(\renderer_base $renderer): string {
161+
return 'tool_demo/index_page';
162+
}
163+
```
146164

147165
Now let's look at the renderer for this plugin.
148166

@@ -171,6 +189,13 @@ class renderer extends plugin_renderer_base {
171189

172190
The renderer exists to provide `render_<page>` methods for all renderables used in the plugin. A theme designer can provide a custom version of this renderer that changes the behaviour of any of the render methods and so to customize their theme. In this example, the render method for the index page (`render_index_page`) does 2 things. It asks the renderable to export it's data so that it is suitable for passing as the context to a template, and then renders a specific template with this context. A theme designer could either manipulate the data in the render method (e.g. removing menu entries), or change the template (change the generated HTML) to customize the output.
173191

192+
You do not need to implement a renderer for a plugin if you are using templates and you either:
193+
194+
1. Use the `templatable` interface and have a template with the same name in the same namespace
195+
2. Use the `named_templatable` interface
196+
197+
In these cases the data from the renderable will be automatically routed to the correct template, however if you do implement a render method that will be used in preference to the default routing.
198+
174199
The template used in this plugin is located in the plugin's templates folder. The template can also be overridden by a theme designer.
175200

176201
```xml title="admin/tool/demo/templates/index_page.mustache"

docs/guides/templates/index.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ description: A guide to the features and use of Mustache templating in Moodle.
1010

1111
Moodle makes use of the [Mustache](https://mustache.github.io) template system to render most of its HTML output, and in some other cases too.
1212

13-
Templates are defined as plain text, which typically includes HTML, and a range of Mustache tags and placeholders. The Mustache placeholders are replaced with actual values during the render of the page. Mustache templates can be rendered both server-side in PHP, and client-side using JavaScript. Themes can overrides the templates defined in other components if required.
13+
Templates are defined as plain text, which typically includes HTML, and a range of Mustache tags and placeholders. The Mustache placeholders are replaced with actual values during the render of the page. Mustache templates can be rendered both server-side in PHP, and client-side using JavaScript. Themes can override the templates defined in other components if required.
1414

1515
<details>
1616
<summary>A simple example</summary>
@@ -388,7 +388,7 @@ Templates can be effectively used in [renderers](https://docs.moodle.org/dev/Ren
388388

389389
In the simplest case where you have a renderable, templatable object with a class name matching the name of the template that will render it, you do not need to add any renderer code explicity. Passing your widget directly to `$OUTPUT->render()` will infer the name of your template, call `export_for_template()` and `render_from_template()`, then return the result.
390390

391-
Example of the method added to the renderable `mywidget`:
391+
The following example shows a renderable using the `mywidget.mustache` template in the `tool_myplugin` plugin templates directory:
392392

393393
```php
394394
/**
@@ -413,6 +413,22 @@ public function export_for_template(renderer_base $output) {
413413
}
414414
```
415415

416+
If you wish to render using any template your renderable can implement `named_templatable` interface instead of `templatable`. It will have to implement an additional new method `public function get_template_name(\renderer_base $renderer): string` that returns the name of the template to be used.
417+
418+
Example of the method added to tell a renderable to use the `mywidget.mustache` template in the `tool_myplugin` plugin templates directory:
419+
420+
```php
421+
/**
422+
* Get the name of the template to use for this templatable.
423+
*
424+
* @param renderer_base $output
425+
* @return string
426+
*/
427+
public function get_template_name(\renderer_base $renderer): string {
428+
return 'tool_myplugin/mywidget';
429+
}
430+
```
431+
416432
:::tip
417433

418434
When naming variables in your export data, be careful not to reuse names of helpers such as `str` or `js` - these will silently fail. Try to keep your variable names short but descriptive.

versioned_docs/version-4.1/guides/templates/index.md

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ description: A guide to the features and use of Mustache templating in Moodle.
1010

1111
Moodle makes use of the [Mustache](https://mustache.github.io) template system to render most of its HTML output, and in some other cases too.
1212

13-
Templates are defined as plain text, which typically includes HTML, and a range of Mustache tags and placeholders. THe Mustache placeholders are replaced with actual values during the render of the page. Mustache templates can be rendered both server-side in PHP, and client-side using JavaScript. Themes can overrides the templates defined in other components if required.
13+
Templates are defined as plain text, which typically includes HTML, and a range of Mustache tags and placeholders. The Mustache placeholders are replaced with actual values during the render of the page. Mustache templates can be rendered both server-side in PHP, and client-side using JavaScript. Themes can override the templates defined in other components if required.
1414

1515
<details>
1616
<summary>A simple example</summary>
@@ -388,7 +388,7 @@ Templates can be effectively used in [renderers](https://docs.moodle.org/dev/Ren
388388

389389
In the simplest case where you have a renderable, templatable object with a class name matching the name of the template that will render it, you do not need to add any renderer code explicity. Passing your widget directly to `$OUTPUT->render()` will infer the name of your template, call `export_for_template()` and `render_from_template()`, then return the result.
390390

391-
Example of the method added to the renderable `mywidget`:
391+
The following example shows a renderable using the `mywidget.mustache` template in the `tool_myplugin` plugin templates directory:
392392

393393
```php
394394
/**
@@ -413,6 +413,22 @@ public function export_for_template(renderer_base $output) {
413413
}
414414
```
415415

416+
If you wish to render using any template your renderable can implement `named_templatable` interface instead of `templatable`. It will have to implement an additional new method `public function get_template_name(\renderer_base $renderer): string` that returns the name of the template to be used.
417+
418+
Example of the method added to tell a renderable to use the `mywidget.mustache` template in the `tool_myplugin` plugin templates directory:
419+
420+
```php
421+
/**
422+
* Get the name of the template to use for this templatable.
423+
*
424+
* @param renderer_base $output
425+
* @return string
426+
*/
427+
public function get_template_name(\renderer_base $renderer): string {
428+
return 'tool_myplugin/mywidget';
429+
}
430+
```
431+
416432
:::tip
417433

418434
When naming variables in your export data, be careful not to reuse names of helpers such as `str` or `js` - these will silently fail. Try to keep your variable names short but descriptive.
@@ -470,7 +486,7 @@ Templates.renderForPromise('block_looneytunes/profile', context)
470486
.catch((error) => displayException(error));
471487
```
472488

473-
Under the hood, this does a few clever things for us. It loads the template via an AJAX call if it was not cached. It finds any missing lang strings in the template and loads them in a single AJAX request. It split the JS from the HTML and returns us both in easy to use way. Read on for how to nicely deal with that `js` parameter.
489+
Under the hood, this does a few clever things for us. It loads the template via an AJAX call if it was not cached. It finds any missing lang strings in the template and loads them in a single AJAX request. It splits the JS from the HTML and returns both in an easy to use way. Read on for how to nicely deal with that `js` parameter.
474490

475491
## Templates requiring JavaScript
476492

@@ -645,6 +661,7 @@ In PHP you have access to the `$CFG` object to allow access to properties. Musta
645661
```
646662

647663
The properties available on the `globals.config` object are the same as normally exposed for JavaScript; these are gathered from `get_config_for_javascript()` function in `lib/outputrequirementslib.php`.
664+
This object is only available when using client-side Mustache rendering in JavaScript; it is not added to templates rendered with the PHP Mustache engine.
648665

649666
## Core templates
650667

0 commit comments

Comments
 (0)