[docs] Update output documentation for react - #1685
Conversation
✅ Deploy Preview for moodledevdocs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Pull request overview
Updates Moodle DevDocs output documentation to better cover React-based rendering and clarify how renderables, templates, and renderers fit together, including documenting html_writer::react_component().
Changes:
- Expanded and reorganised output subsystem docs to describe React component renderables, templatable/named_templatable flows, and rendering priority.
- Added API documentation for
html_writer::react_component()with an example and guidance on when it’s called automatically. - Updated the project word list to include “templatables”.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| project-words.txt | Adds “templatables” to the project dictionary. |
| docs/apis/subsystems/output/index.md | Reworks output docs with new React renderable guidance and updated rendering explanations. |
| docs/apis/core/htmlwriter/index.md | Documents html_writer::react_component() and its output attributes. |
Suppressed comments (7)
docs/apis/subsystems/output/index.md:82
- The paragraph starts using “Theme designers” but the final clause still says “themers”. Consider using the same term consistently.
This gets an instance of the `plugin_renderer_base` class that we use to create all output for our page. Theme designers can subclass this renderer to override specific render methods in order to customise Moodle's output. See [Output renderers](https://docs.moodle.org/dev/Output_renderers) for more information, and [Overriding a renderer](https://docs.moodle.org/dev/Overriding_a_renderer) for information about how themers can customise a renderer.
docs/apis/subsystems/output/index.md:212
- In the named_templatable example, the class is declared as
my_react_widgetbut the instantiation later usesmy_named_templatable_widget. Renaming the class here keeps the example consistent.
class my_react_widget implements
docs/apis/subsystems/output/index.md:243
- The explicit section id uses “templatables” but the interface name is
templatable. Using...-templatable-interfacekeeps the anchor consistent and avoids introducing a new plural form.
#### Renderables implementing the `templatable` interface {/* #renderables-implementing-the-templatables-interface */}
docs/apis/subsystems/output/index.md:255
- This code block is for a
templatableexample but the title says “named_templatable” and the class name doesn’t match themy_templatable_widgetused in the examples below.
```php title="Example named_templatable implementation"
namespace tool_demo\output;
class my_react_widget implements
\core\output\templatable,
docs/apis/subsystems/output/index.md:326
- Typo: “thd” should be “the”.
Most implementations should use either the `react_component_renderable` implementation for newer React code, or thd `named_templatable` implementation for Mustache.
docs/apis/subsystems/output/index.md:346
- Grammar: “provide a ... methods” should either be singular or remove the article; also consider showing the method form as
render_<renderable>().
Renderers _may_ provide a `render_<renderable>` methods for all renderables used in the plugin.
docs/apis/subsystems/output/index.md:350
- Spelling/grammar: “does 2 things” and “export it's data” read as informal/incorrect in docs; also “customize” is inconsistent with other uses of “customise” on this page.
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.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
9bde953 to
bfa15f1
Compare
bfa15f1 to
55d5042
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved documentation parsing, link, and example correctness issues remain.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (13)
docs/apis/core/htmlwriter/index.md:74
- This repeats the same contradiction: the example passes preference values as props, while this sentence says props must contain no data. Please narrow the warning to additional application data so the documented use of configuration and preferences remains valid.
React properties **should not** contain any data.
docs/apis/core/htmlwriter/index.md:83
html_writer::react_component()returns the placeholder HTML; withoutecho, this example emits nothing even though the following comment shows output.
html_writer::react_component(
docs/apis/subsystems/output/index.md:259
renderer_base::render()returns a string rather than printing it, so this named-templatable example renders nothing as written. Echo the call's return value.
$renderer->render($widget);
docs/apis/subsystems/output/index.md:294
- This
render()call also only returns the HTML, so the example produces no output unless the return value is echoed.
$renderer->render($widget);
docs/apis/subsystems/output/index.md:303
- The direct
render_from_template()call returns the rendered string and does not print it. Prefix the call withechoin this standalone usage example.
$renderer->render_from_template(
docs/apis/subsystems/output/index.md:273
- The rendering snippet below instantiates
my_templatable_widget, but this block declaresmy_react_widget. As written, the example cannot run because that class is not defined; make the declaration and usage use the same class name.
class my_react_widget implements
docs/apis/subsystems/output/index.md:148
- The new renderable overview removed the
index_pageimplementation, but the page-start examples still instantiate\tool_demo\output\index_page(at lines 37 and 98). Update those examples to use one of the documented renderables or retain a completeindex_pageexample.
In the code above we rendered a `renderable`. This class holds all the data required to display that item on the page.
docs/apis/subsystems/output/index.md:339
renderer_base::render()accepts arenderable, while these three interfaces do not themselves extendrenderable. The priority list should say that each option is a renderable implementing the relevant interface; otherwise a reader may implement only the interface and get a type error when callingrender().
2. A class which implements the `react_component_renderable` interface.
3. A class which implements the `named_templatable` interface.
4. A class which implements the `templatable` interface.
docs/apis/subsystems/output/index.md:219
- This PR rewrites the existing Mustache/templatable guidance as well as adding the 5.3 React section, but only the unversioned page was updated. The same output page exists in
versioned_docs/version-4.5throughversioned_docs/version-5.2; please backport the non-React documentation corrections to those copies while leaving the 5.3-only React additions version-gated.
### Using templates with renderables {/* #using-templates-with-renderables */}
Moodle makes use of the Mustache templating system and provides the following interfaces to simplify rendering a Mustache template:
- `\core\output\named_templatable` - an implementation which automatically renders a specific template;
- `\core\output\templatable` - a basic implementation which attempts to render based on a guessed template name.
docs/apis/subsystems/output/index.md:256
- The renderable is declared in the
tool_demo\outputnamespace above, but this page-level example instantiates it unqualified, so PHP looks for a global class and fails. Use the fully qualified class name or import it.
$widget = new my_named_templatable_widget();
docs/apis/subsystems/output/index.md:291
- The renderable is declared in the
tool_demo\outputnamespace above, but this page-level example instantiates it unqualified, so PHP looks for a global class and fails. Use the fully qualified class name or import it.
$widget = new my_templatable_widget();
docs/apis/subsystems/output/index.md:318
- The renderer file is shown without its
tool_demo\outputnamespace. Without that namespace Moodle will not discover it as the plugin renderer, and the unqualifiedmy_templatable_widgettype will resolve incorrectly.
use core\output\plugin_renderer_base;
docs/apis/subsystems/output/index.md:369
it'sis the possessive error here; the sentence needsitsfor the renderable's data.
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.
- Files reviewed: 3/3 changed files
- Comments generated: 10
- Review effort level: Lite
55d5042 to
1611a45
Compare
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Several documentation correctness, example, and compatibility issues remain unresolved.
Review effort: Lite
Findings: 2
Open (2)
Resolved since last review (10)
The:::importantblock opened here is never closed before## Output Functions. Add the closing… The following rendering snippet instantiatesmy_named_templatable_widget, but this block declares…renderer_base::render()returns the generated HTML; it does not print it. As written, this… This output cannot be produced by the shown call: the values depend on the current user's… This paragraph still refers to the removedrender_index_pageexample and containsit'swhere… The articleadoes not agree with the pluralmethods, making this newly added sentence…thdis a typo in this newly added recommendation. This code-block title saysnamed_templatable, but the example implements the plaintemplatable… This relative link resolves underapis/subsystems/core, notapis/core, so the new alternative… These two sentences contradict each other: the preceding guidance permits initial configuration and…
1611a45 to
19eba90
Compare
19eba90 to
3b143d5
Compare
This commit also updates the output documentation to provide better examples, and provide more context.
3b143d5 to
9210417
Compare
|
I think I got it all @meirzamoodle |
|
Sweet. Thanks @andrewnicols |



This commit also updates the output documentation to provide better examples, and provide more context.
See MDL-89296 for information.