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.
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 $PAGE->set_pagelayout('incourse');
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:
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.
Example:
#settings.php 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; $PAGE->set_url('/local/face2face/index.php?id=1&controller=face2face_session&action=index'); $this->get_view(); }
To show the Navigation ($PAGE→navigation) and Settings ($PAGE→settingsnav) blocks in your local plugin, use this code:
$PAGE->set_pagelayout('standard');
Where appropriate, you may also want to use 'admin' or 'incourse'.
Include a hook in your plugin's lib.php file to add a menu item to the navigation block.
#/local/face2face/lib.php 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.
From docs.moodle.org:
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) { return; } // Only let users with the appropriate capability see this settings item. if (!has_capability('local/expirydate:administration', context_course::instance($PAGE->course->id))) { return; } 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( $menu_label, $url, navigation_node::NODETYPE_LEAF, 'expirydate', 'expirydate', new pix_icon('t/addcontact', $menu_label) ); if ($PAGE->url->compare($url, URL_MATCH_BASE)) { $navigation_node->make_active(); } $settingnode->add_node($navigation_node); } } // function local_expirydate_extends_settings_navigation
You'll find the icons in various subdirectories under /pix
.
Create a settings.php
file for your plugin, and add this code to create a link under “Site administration > Users”:
# settings.php $ADMIN->add('users', new admin_externalpage( 'crm_mailer', get_string('pluginname', 'local_crm_mailer'), "$CFG->wwwroot/local/crm_mailer/index.php?id=1", 'local/crm_mailer:edit' ) );
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: