Navigation Bar: Breadcrumbs Menu

The navbar is not really a breadcrumbs menu (doesn't keep track of where you have been, just shows you where you are now in relation to the course).

The navigation bar's composition is determined through the $PAGE object (stored in a global Moodle variable).

The 'Navigation API' sums up some methods (functions) of the $PAGE object. Unfortunately, it does not clarify what the effects of calling these methods are, exactly.

Side Effects of Calling require_login

What's require_login doing in a tutorial on navigation? Well, require_login, a function of ~300 lines of code, has quite a few side effects. Here are the ones which are relevant for navigation.

When called with a course_module object ($cm, 3rd parameter), require_login calls:

  • $PAGE->set_cm($cm, $course); // sets up global $COURSE

The set_pagelayout method adds the relevant blocks to the page (usually at least the 'Settings' block).

If $cm is NULL (default value of this parameter), require_login calls:

  • $PAGE->set_course($course); // sets up global $COURSE

set_cm Calls set_course, so the latter function is always executed through require_login.

As a matter of fact, if you do not use require_login, you should call $PAGE→set_course yourself. Either directly, or through $PAGE→set_cm.

Calling $PAGE→set_course has the effect of changing the navbar. Also, from the inline documentation:

  • “Set the current course. This sets both $PAGE→course and $COURSE. It also sets the right theme and locale. (..) Sets $PAGE→context to the course context, if it is not already set.”

Entry in navbar (Bread Crumbs Menu) through settings.php

The file local/yourplugin/settings.php can be used to create an entry in the Site Administration menu. This entry is also shown in the navbar (bread crumbs menu) if the current url matches the entry's url exactly.

For instance, this code:

if ($hassiteconfig) { // needs this condition or there is error on login page
    $ADMIN->add('root', new admin_externalpage('face2face',
            get_string('pluginname', 'local_face2face'),
            new moodle_url('/local/face2face/index.php?id=1&controller=face2face_session')));

- will only activate the breadcrumbs menu if you do not add an extra querystring parameter, such as &action=edit.

If you do add an additional querystring parameter, the function has_items in /lib/navigationlib.php will no longer recognize the url.

The solution for this problem is to use $PAGE→seturl in your plugin, to specify that the $PAGE→url is the 'canonical' url for you plugin (i.e. the one specified in settings.php). And in settings.php you'll have to use the canonical url too.


if ($hassiteconfig) { // needs this condition or there is error on login page
    $ADMIN->add('root', new admin_externalpage('face2face',
            get_string('pluginname', 'local_face2face'),
            new moodle_url('/local/face2face/index.php?id=1')));

And for the regular pages of your plugin:

$PAGE->set_url("/local/face2face/index.php", array('id' => $id));

Please note that Soda handles this for you automatically, from version 2014063000 onwards. The canonical url for a Soda based plugin is:

#/local/soda/class.controller.php, line 430:
$PAGE->set_url("/{$this->plugin_type}/$mod_name/index.php", array('id' => $query_array['id']));

You can overwrite this canonical url in one of your controllers' actions. Example:

function index() {
    global $PAGE;

Show Navigation And Settings in Your Local Plugin

To show the Navigation ($PAGE→navigation) and Settings ($PAGE→settingsnav) blocks in your local plugin, use this code:


Where appropriate, you may also want to use 'admin' or 'incourse'.

Add Menu Item in Navigation Block for Your Local Plugin

Include a hook in your plugin's lib.php file to add a menu item to the navigation block.

function local_face2face_extends_navigation(global_navigation $navigation) {
    $nodeFoo = $navigation->add(get_string('subscribe', 'local_face2face'), '/local/face2face/index.php?id=1&controller=participant');
    //$nodeBar = $nodeFoo->add('Bar');

See also this forum thread: How to build a main menu using the navigation block.

Add Item to Course Administration Menu


function local_expirydate_extends_settings_navigation($settingsnav, $context) {
    global $PAGE;
    // Only add this settings item on non-site course pages.
    if (!$PAGE->course or $PAGE->course->id == 1) {
    // Only let users with the appropriate capability see this settings item.
    if (!has_capability('local/expirydate:administration', context_course::instance($PAGE->course->id))) {
    if ($settingnode = $settingsnav->find('courseadmin', navigation_node::TYPE_COURSE)) {
        $menu_label = get_string('menu_label', 'local_expirydate');
        $url = new moodle_url('/local/expirydate/index.php', array('course_id' => $PAGE->course->id));
        $navigation_node = navigation_node::create(
            new pix_icon('t/addcontact', $menu_label)
        if ($PAGE->url->compare($url, URL_MATCH_BASE)) {
} // function local_expirydate_extends_settings_navigation

You'll find the icons in various subdirectories under /pix.

Add A Menu Item to The Administration Block

Create a settings.php file for your plugin, and add this code to create a link under “Site administration > Users”:

# settings.php
    new admin_externalpage(
        get_string('pluginname', 'local_crm_mailer'),

See also the documentation for the constructor (__construct) of the admin_externalpage class, in /lib/adminlib.php. As far as I can tell, the required capability (fourth argument of the constructor) is checked against the system context.

Add the admin node in a specific place in the administration menu:

The $ADMIN→add() function has 3 parameters:

  1. The first parameter gives the parent node of the site administration menu. (For example: 'root', 'users' or 'courses').
  2. The second parameter is the new admin page with the name of the link and the link to the page.
  3. The third parameter is the name of the node where the new node is placed in front of.

Personal Tools