Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Navigation API: Difference between revisions

From MoodleDocs
Line 32: Line 32:
# The navigation and settings blocks display the back-end navigation structure but add nothing to it at all.
# The navigation and settings blocks display the back-end navigation structure but add nothing to it at all.


The navbar also needs to be looked at. The navbar as mentioned above is just the path to the active navigation or settings item. In the case of the navbar however it is not displayed by a block, instead it is displayed by the core renderer. This is of course because the navbar is not normally displayed as a block but added into the theme's layout files. Other than that different it is just like the rest of the navigation, a back-end structure that is displayed by a separate something.
The navbar also needs to be looked at. The navbar as mentioned above is just the path to the active navigation or settings item. In the case of the navbar however it is not displayed by a block, instead it is displayed by the core renderer. This is of course because the navbar is not normally displayed as a block but added into the theme's layout files. Other than that difference it is just like the rest of the navigation, a back-end structure that is displayed by a separate something.
 
::If you are familiar with model-view-controller pattern, then $PAGE->navigation, $PAGE->settingsnav and $PAGE->navbar are the model, and the navigation and settings blocks are views.


==How the navigation works==
==How the navigation works==

Revision as of 07:39, 28 June 2010

Moodle 2.0

This page is currently under construction. It should be complete within the next 48 hours.
Please do not edit it until this notice has been removed.

This document looks at the navigation within Moodle 2.0 from a development perspective. It aims to outline what the navigation is, how it works, how to add to it, how to hack it, and how to debug it. If you're writing a plugin, or some arbitrary code and want to make the navigation meet your needs to complete the look of what ever you are working on then this is the document for you. If you're not a PHP developer you're certainly in the wrong place.

What the navigation is

It's very important to understand what the navigation is exactly within Moodle 2.0. One of the numerous goals for Moodle 2.0 was to standardise navigation throughout Moodle and try to bring order to the structure of a Moodle site.

The solution to this was of course the navigation. Don't think about the navigation or settings blocks those are just interpretations of the navigation structure Moodle creates. The navigation structure is what you really need to understand.

For those of you who have already started looking into either writing code for Moodle 2.0 or converting some existing code you will have undoubtedly come across the page object $PAGE against which you set the heading for the page, the title, any JavaScript requirements, and a whole lot of other stuff that is used by the page.

The navigation structure within Moodle uses the information $PAGE contains to generate a navigation structure for the site that reflects the page that the user is viewing.

This navigation structure is the available through three variables the can be interacted with the alter the navigation, but more about that later. The three variables are:

$PAGE->navigation
This is the main navigation structure, it will contain items that will allow the user to browse to the other important pages that are available to them.
$PAGE->settingsnav
This is the settings navigation structure, it will contain items that will allow the user to edit different things for whatever they are viewing.
$PAGE->navbar
The navbar is a special structure, it is essentially the active item in the navigation preceded by all of its parents plus anything the page wants to add.

The above is a basic overview of the navigation structures which the following sections will attempt to explain in more detail. So onto what the navigation is not.

What the navigation isn't

Now it is equally important to look at what the navigation is not and why that is.

The navigation is NOT the navigation block or the settings block!

These two blocks were in fact created at the same time as the navigation in order to display it, and that is all they do. Each block looks at a part of the navigation structure, the navigation block looks at $PAGE->navigation, and the settings block looks at $PAGE->settingsnav and then both blocks interpret it into an HTML structure that allows you to see what is going on.

There are two things that this should lead you to understand:

  1. The navigation is a back-end structure that is built behind the scenes and has no immediate method of display.
  2. The navigation and settings blocks display the back-end navigation structure but add nothing to it at all.

The navbar also needs to be looked at. The navbar as mentioned above is just the path to the active navigation or settings item. In the case of the navbar however it is not displayed by a block, instead it is displayed by the core renderer. This is of course because the navbar is not normally displayed as a block but added into the theme's layout files. Other than that difference it is just like the rest of the navigation, a back-end structure that is displayed by a separate something.

If you are familiar with model-view-controller pattern, then $PAGE->navigation, $PAGE->settingsnav and $PAGE->navbar are the model, and the navigation and settings blocks are views.

How the navigation works

Alright so now that we know that the navigation is, and what it isn't lets look into it in greater detail starting with the main navigation structure.

First up the main navigation structure can be accessed through $PAGE->navigation, and worth mentioning is that $PAGE is essential to the navigation, without it the navigation wouldn't be able to generate a structure for the Moodle site or work out what the user is looking at and correlate that with the structure, which is what we shall look at now.

As mentioned the $PAGE object is referenced by the navigation when it is generating its structure, this is is because the navigation, and settings are contextual in that as well as being a general navigation structure they will relate to the page that the user is viewing. This is of course determined by the things that the $PAGE object has been made aware of. The most import parts are listed below.

  • $PAGE->context is the most essential, it is of course a Moodle context that immediately outlines the nature of the page the user is viewing.
  • $PAGE->course is used to get the course the user is viewing, this of course is essential if the context is CONTEXT_COURSE or greater, however may also be useful in other areas such as CONTEXT_USER.
  • $PAGE->cm if the user is within a page promoting CONTEXT_MODULE or greater this will be the course module instance the page is using.
  • $PAGE->url is critical to the navigation, it is used to match the active navigation item. If you have a page on the navigation but it is not being found to be the active page check here first.

So at this point we know how the navigation finds out about what the user is viewing, now we need quickly look at how navigation gets that information. As you've probably realised by looking at code nearly every page sets $PAGE->url through a call to $PAGE->set_url however not many explicitly set the context, course, of cm.

This is because require_login does it for you if it is called with a course, and or cm (other than the front-page course). When you call require_login with the a course and/or cm it automatically calls the following: if ($cm) {

   $PAGE->set_cm($cm, $course); // set's up global $COURSE

} else if ($cm) {

   $PAGE->set_course($course);

Then within each of those two functions it sets the context for the item it was just given. This is how $PAGE finds out about courses and course modules.

Providing require_login is being called correctly a page will only be required to explicitly set a context, course, or cm if one of the following conditions are met:

  1. $PAGE->set_context The page is using CONTEXT_SYSTEM, CONTEXT_COURSECAT, or CONTEXT_USER.
  2. $PAGE->set_course or $PAGE->set_cm The page is using a course or cm but it is also using one of the above contexts.

So by looking at the $PAGE object the navigation is able to generate a structure that reflects the Moodle site as well as the page the user is viewing.

Before we move on to look at how to interact with the navigation however there is one more thing that you need to know and that is when the navigation structure is generated.

Of course we can't generate the navigation structure immediately as we need to give the code a chance to set the $PAGE object correctly. Because of this the navigation structure is only generated when it is first used. This may be either when it something tries to access the structure or when code tries to add to it. Also the navigation is initialised in a specific order:

  1. Main navigation structure
  2. Settings navigation
  3. Navbar

The navbar however is a special case, as it is just the path up to and including the active item it doesn't need generation, it will of course be determined when interacted with by which time everything else will have been generated.

Extending the navigation

Before we tear into this we need to look at the different ways in which you can extend or manipulate the navigation.

  1. Code extension : This method of extending is when the code arbitrarily extends the navigation during its execution. Extending the navigation through this means allows you to extend the navigation anywhere easily, however it will only be show on pages where you extending code gets called (you should probably put it in a function within lib.php).
    1. Navigation : This is extending the main navigation structure.
    2. Settings navigation : This is extending the settings navigation.
    3. The navbar : This is adding to the navbar.
  2. Plugin call-backs : These are specific functions that the navigation looks for and calls if they exist for the plugin, presently only three plugin types can extend the navigation through these call-backs.
    1. Modules : Modules have two call-back methods, first to extend the navigation, and second to extend the settings. These call-backs get called when ever the user is viewing a page within the module and should only extend the navigation for the module.
    2. Course formats : Course formats are able to completely redefine the way in which navigation is generated for a course, as well as this they also have several methods to ensure the navigation is generated correctly.
    3. Course reports : By default reports don't add themselves or anything else to the navigation however there is a call-back that can be implemented to allow them to do so.

Code extension

Navigation

Settings navigation

Navbar

Plugin call-backs

Modules

Course formats

Course reports

Manipulating the navigation

Why would you want to, its perfect just as it is.

FAQ's and troubleshooting

Q. My page is on the navigation but it doesn't find it?

The first thing to do here is check the URL you are setting for the page. It should match the URL your page has within the navigation. If it doesn't you have two options, first change your $PAGE->set_url call, or second override the URL the navigation is using to find the active node as shown below: navigation_node::override_active_url(new moodle_url('/your/url/here.php', array('param'=>'value')));

More information