You are here

Navigation 2.0 implementation plan

This page lists the various strands of work that will be needed to implement Navigation 2.0 and tried to break them down into manageable chunks.

I think the aim is for me to do as much as this as possible during the 13 weeks I am still working for moodle.com. Therefore, I have focussed on the core work it is necessary to do to achieve the core goals, and then noted ways we could do more later as 'Future ideas'.

Note, all the estimates below should include writing unit tests for the new code, and updateing the corresponding developer documentation on this wiki.

As you can see, quite a lot of magic goes on by default, for example, automatically creating $OUTPUT once we have enough information to to work out the current theme, and automatically setting up the navigation bar once we know that this page belongs to a course_module, and what the page title is. Naturally, any of this magic can be explicitly overridden by making extra method calls if the default behaviour is not what you want.

Also, these objects will track their own state, so, for example, if you try to do $PAGE->set_theme() after you have used $OUTPUT to output anything, you will get an exception explaining to you what you have done wrong, rather than mysterious weird behaviour.

✔ Page object

$PAGE is a central store of information about the current page we are generating in response to the user's request. It does not do very much itself except keep track of information, however, it serves as the access point to some more significant components like $PAGE->theme, $PAGE->requires, $PAGE->blocks, etc.

There was a $PAGE global in 1.9 that scripts had to create themselves, and which was not used consistently everywhere. In Moodle 2.0, there will always be a $PAGE, and it will be created automatically during require_once('config.php'); However, as far as possible, we will try to implement deprecated functions and methods so that old code using $PAGE does not break, but that will probably require some trickiness.

General information - there will be fields

✔ $PAGE->status - tracks whether we have printed the header yet.

✔ $PAGE->course - alias for $COURSE.

✔ $PAGE->category - the object corresponding to $PAGE->course->category (lazy-loaded only if needed)

✔ $PAGE->categories - all the nested categories from $PAGE->category->path (lazy-loaded only if needed) - MDL-14306

✔ $PAGE->cm - it we are in an activity, otherwise null.

✔ $PAGE->activityrecord - it we are in an activity, otherwise null.

✔ $PAGE->activityname - (e.g. 'forum') it we are in an activity, otherwise null.

✔ $PAGE->context

✔ $PAGE->title - goes into <title> in the HTML

✔ $PAGE->heading - goes into the page header

✔ $PAGE->url - a moodle_url object for this page.

✔ $PAGE->add_alternate_version($title, $url, $type) - use to list alternate versions of the page like RSS. (See mod/data/edit.php for an example.)

✔ $PAGE->cachable - true by default, can be set to other things by pages that need to restrict HTTP caching.

✔ $PAGE->focuscontrol the HTML element to focus by default.

✔ $PAGE->button like the old $button parameter to print_header.

Other stuff, covered in the more specific sections below.

Most of this is set up automatically as a result of require_once('config.php'); but could later be overridden by a particular script in special circumstances. Other parts, (e.g. ->course and ->cm) are set up when we have the relevant information, normally as a side-effect of require_login().

Although it looks like we are using an object with public fields, I am actually, proposing we use private fields, with __get magic to allow read-only access with $PAGE->url. However, write access to these fields will be via $PAGE->set_url(...) which does appropriate sanity checking.

Estimates

✔ MDL-12213 Document the sequence in which things get set up during the start of any Moodle page (from require_once('config.php'); to require_login(), or so, showing where all the globals get set up. Both the current flow, and the propsed new order: 2 daysWhat_happens_when_you_require_config.php

✔ MDL-12212, MDL-15817 Based on that implement the basic information storage role of $PAGE, and kill the existing $PAGE subclasses, moving any important code elsewhere: 1 week, but depends on the previous task.

✔ Blocks infrastructure

The concept is that themes are responsible for printing the blocks, and can also determine where blocks may appear on the page. To manage all this there is a block_manager class, accessible as $PAGE->blocks. When this is created, it does

Future ideas

Navigation

There are two main concepts here:

1. We classify every page in Moodle as either a 'normal' page or a 'settings' page. 'normal' pages are the ones you see when browsing around the site, or learning or teaching. 'settings' pages are the ones that control that 'normal' experience. That is, all the things that you can access only as an Editing Teacher, Course Creator or Administrator. There are also a few settings links that are used by Students, and other lowly people. I would classify 'Change my password' and 'Unenrol me from this course' as settings pages.

Future ideas

Extend requirements_manager so it could automatically concatenate CSS and JS into fewer larger files. (This could be done on upgrade and install.) Then serve the appropriate concatenation instead of many separate files, which is better for performance.

Investigate open source CSS and JS minifiers, that could be used in in combination with the above.

Themability

The main change is that there will be a new $OUTPUT global for generating HTML. So, for example, instead of calling the function print_heading(...) from weblib.php, you will instead call $OUTPUT->heading(...). The point is that since $OUTPUT is an object, the theme can choose exactly which object it is, and so the theme can change how standard elements are rendered.

We will also change header.html and footer.html in themes. In the past they could only use the variable that the print_header function had prepared for them - there was code like

That is, the theme files will use $OUTPUT to generate just the standard bits of output they want. The header can also take some low-level information like $PAGE->pagetype directly from $PAGE.

In fact, $OUTPUT->header will not be that simple because, to ensure backwards-compatibility, we will have to build all of the standard variables as we currently do before including header.html, unless the theme config.php defines a variable like $doesnotneedlegacyvariables = true;

New moodle_core_renderer class and a global instance $OUTPUT, and make deprecated versions of all the old weblib.php functions that delegate to it. 1+ week

✔ Implement default_renderer_factory, with the option for themes to specify a different renderer factory in their config.php. The current renderer factory will be accessible as $PAGE->theme, as in $PAGE->theme->get_renderer('forum'); 1- week

✔ Create moodle_custom_corners_renderer to get the custom corners mess out of moodle_core_renderer, and to prove that bit of the concept. 1 day

Future ideas

Convert a couple of other parts of moodle to start using a renderer class, to prove the concept. Perhaps just forum post, and a block. We should pick things that are not too difficult, and things that themers are likely to want to customise.

Refactor other core plugins to use a renderer class (a bit at a time).

Create a theme/standardtemplate.

Develop a highly optimised themeengine/phptemplates.

Misc themeability issues:

MDL-9306 Main course formats need to have tables removed but keep AJAX working - there seem to be some regressions from this work ;-)