How Moodle outputs HTML
|Warning: This page is no longer in use. The information contained on the page should NOT be seen as relevant or reliable.|
(What should you use instead?)
If you think about the HTML that is output by Moodle, then you can split it into two parts:
- the parts like the header and the user-interface, that are generated automatically by the Moodle code and the themes; and
- the bits like the contents of forum posts and labels that are input by the users.
This page is about the bits of output that are generated automatically. It explains how that happens.
Most of what is described here is new in Moodle 2.0. The work that lead to this new system is described in Theme engines for Moodle? and Navigation 2.0 implementation plan. Those documents were both written before the new system was developed and shows how the thinking evolved and the rationale behind it.
If you are familiar with Moodle 1.9 or before, and just wish to update your existing code, you may wish to read Migrating your code to the 2.0 rendering API.
I said above that this page is about the parts of the output that are automatically generated by Moodle code. We can break those bits of output down further:
- The overall layout of the page including the header and the footer. This is generated from the layout template provided by the theme (for example theme/standard/layout.php).
- The blocks that can appear in various places on the page. Where the blocks can appear on the page is determined by the theme layout. Which blocks appear where on which pages is configured by the user. The code that manages this is in blocklib.php. Finally, the contents of the blocks is a mixture of user-entered content (for example, the HTML block) and automatically generated content (for example, the Administration block).
- The main content in the middle of the page. This is generated by the particular script, for example mod/forum/view.php using the output libraries. (Moodle mostly uses a transaction script architecture.) This area frequently contains user-entered content too.
Basic HTML output and $OUTPUT
Themes (along with some of the other the configuration choices made by the administrator) control the overall look of a Moodle site.
A Moodle theme is a folder of code like theme/mytheme. It contains a number of files:
- tells Moodle the settings that this theme wants.
- layout.php, layout-head.php, ...
- defines the overall layout of the page. Different types of page can have different templates. This is controlled by config.php.
- styles.css, styles_colours.css, ...
- the stylesheets that determine the layout. It is up to the theme whether to have one or many.
- A special stylesheet that is only included if the current language is right-to-left.
- readme.html, screenshot.jpg
- Information about the theme. Used in the theme chooser user interface.
- favicon.ico, pix/*
- Images that the theme wants to use. These can replace the default Moodle icons.
- A way to add information to the page header. Somewhat an implementation detail.
- Implementation detail. Responsible for serving the CSS.
Ways themes can change other parts of the HTML
Minor changes to the HTML
$THEME gets initialised the frist time you use $OUTPUT, or the first time you refer to $PAGE->theme
$OUTPUT lets themes customise the HTML used for standard things like boxes, but what about places where code echoes HTML directly? Well, in addition to moodle_core_renderer, every plugin should also define its own renderer, like moodle_mod_workshop_renderer, and all module-specific HTML output should done in methods of that class. That class should be defined in a files called renderers.php inside your plugin.
When you actually want to do some output, you need to get an instance of your class (or whatever subclass the theme wants to substitute). You do that like this:
global $PAGE; // If necessary. $wsoutput = $PAGE->theme->get_renderer('mod_workshop', $PAGE); echo $wsoutput->manual_allocation_interface($workshop, $allocationdata);
The moodle_mod_workshop_renderer object will have access to a moodle_core_renderer available as $this->output. You should use this instead of global $OUTPUT, and you should use it. That is, boxes in the workshop should look like boxes elsewhere, so boxes in the workshop should be output with $this->output->box().
How to learn more
Software normally needs documentation on three levels:
- An general overview of how all the parts fit together. You've just read that!
- Detailed documentation of the API and how to use it. What functions exist. What arguments they take and what they mean. What is returned. You can find that at http://phpdocs.moodle.org/. All the output code is in the moodlecore package.
- All the details of how the code actually works. In the open source world, the best way to learn that (after you have read the overview) is to read the code itself. It is the only sort of documentation that never goes out of date!
You should also remember Moodle's social constructionist pedagogy. We learn best by doing, and then showing what we have done to others; we learn by looking at what other people have done; and we learn by asking each other questions. Don't be afraid to use the forums to share what you have done, and to ask for further explanation. This document has already benefited greatly from the questions that Sam Hemelryk and David Mudrak asked when they started working with this code.