Note:

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

Navigation 2.0 navbar proposal: Difference between revisions

From MoodleDocs
No edit summary
Line 1: Line 1:
==Navigation Bar in Moodle 2.0==
==Implementation of global navigation, settings navigation, and the navbar in Moodle 2.0==
To help Tim in his mammoth task of navigation implementation I have undertaken to complete the implementation of the global navigation, settings navigation, and the navbar for him.


Currently I am aiding Tim and his mega-development effort by looking into what can be done with the navigation bar in Moodle 2.0.
The following is the specification for the three, as they are very closely tied in to each other.
The end desire is that ''build_navigation()'' is deprecated and replaced by a new OO navbar.


We would obviously like this new navbar to be self responsible whilst still being flexible enough that you can add to it as you need to.
===Implementation Overview===
The purpose of the new navigation is to capture the structure of a Moodle site and present a series of navigation objects that allow the user to easily navigate Moodle 2.0.


The following is my current thinking on this topic and I would love to know your thoughts on the matter, as well as any changes or work-overs you can spot.
The focus is to create a usable navigation structure for Moodle, that is constant in its appearance and usage.


===The Plan===
In order to achieve this it was decided that three navigation structures were needed.
As suggested in [[Navigation 2.0]] the navbar object will be made available through $OUTPUT->navbar, both for output and interaction.
It will be set up to generate as much of the navbar as it possibly can without any input, and allow the developer to add items to the navbar as they wish.


By default the navigation bar will generate the following items (depending on what is available):
* Global navigation: This is the course structure for the site, starting at the site level, through categories, courses, course sections, and activities. With the ability for an activity to further expand the navigation.
* Site's short name
* Settings navigation: The settings available to the user for their current context. This will contain things such as site administration, course settings, activity settings, and profile settings.
* Course categories (1..n)
* Navigation bar: As seen in Moodle, at the same time as implementing the above two navigation structures we will also re-implement the navigation bar in a object oriented method and make it more intuitive by getting it to auto-generate as deep as possible based on the information available through the PAGE object that is now available.
* Course short name
* Module plural (e.g. forums, SCORMs/AICCs)
* Module's name


Also worth noting is that when looking at the structure of a Moodle course it made more sense to me that rather than adding an item for the modules plural name, an item should be added for the course section (e.g. week 1, week 2, week 3) however as there is no page specifically for the course section this is not possible. I will however comment an appropriate point for which this could be modified should this ever be an option.
How these tie in: During the creation of mock up's it became apparent that there was a great deal of repetition in code if all three navigation structures we generated individually. In working through the possibilities we decided on the following approach of implementation:
 
# Start with the global navigation object nesting it as a property of the moodle_page ($PAGE) object.
# Initialise the global navigation object the first time it is requested, initially we thought that we would do this at the same time as we initialise theme and output, however this proved to be problematic.
# When global navigation initialises it will look at the context held by $PAGE and generate its own structure based on that context, ensuring that it adheres to the capabilities of the current user.
# Every node that gets added to the global navigation tree is analysed to find out if it is the active node (the node the user is currently viewing)
# Next the navigation bar, like global navigation it is initialised when it is first used
# When the navigation bar is first called it also calls global navigation to initialise to ensure that the general navigation structure has been generated.
# Unlike the global navigation nothing is generated during initialisation, the object is set-up to be used and nothing else.
# When called to display the navigation bar will analyse the global navigation object ($PAGE->navigation) and retrieve all nodes that form the path to the active node, these nodes will form the breadcrumb.
# After generating the path as above, the navigation bar then looks at itself to check for any children that have been added specifically to the navigation bar.
# Finally the settings navigation.
# Settings navigation is again only initialised when it is first used. However it is [currently] only used by the settings block which will be implemented at the same time.
# When being initialised settings navigation will call global navigation to initialise if it has not already to ensure that it loaded and ready for inspection.
# During initialisation the settings navigation inspects the global navigation to find the currently active node, and $PAGE and its properties to find the different elements that can contribute to the settings available for the user.
# Settings navigation then proceeds to generate the permitted settings for the current user for each of the elements found above.
 
As you can see above all three objects are initialised when they are first used, and global navigation is the main structure that the other two objects (settings and navbar) both inspect in order to lessen the amount of information that they must generate.
 
The following are the points during processing that the tree will likely be initialised:
 
* When interacted with directly; All three blocks can be interacted with directly, and independently, when such an interaction occurs the blocks will be initialised as described above.
* During block processing; If either a global navigation or settings navigation block have been added to the page the relevant objects will be initialised when we start block processing.
* Within the template call to display the navigation bar; simple as that when the template wants to use the navigation bar we need to initialise the global navigation and then the navbar.
 
===General Interaction===
Whilst the three objects will automatically generate as much of the navigation structure as possible there is case for further extending the navigation beyond the what it is able to generate.
 
The objects themselves are all made available through the $PAGE object in the following manor:


===Internal Operation===
The navbar object will be initialised by $PAGE at the same time that theme and output are initialised (PAGE::initialise_theme_and_output) by calling an internal method of navbar
<code php>
<code php>
$this->_navbar = navbar::load();
// Don't forget if you are in a function you will need global $PAGE
$PAGE->navigation;  // This will return the navigation object
$PAGE->settingsnav; // This will return the settings navigation object
$PAGE->navbar;     // This will return the navigation bar object
</code>
</code>
The load function for navbar will then proceed to investigate the PAGE object in order to work out what it can automatically build.
 
In order to aid the navbar in its auto-generation the following functions should be called if appropriate.
The following method has also been made available through the $OUTPUT object
 
<code php>
<code php>
$PAGE->set_cm($cm);
// This method will return true if the navigation bar object has anything to display
$PAGE->set_course($course);
// and has been added to allow template designers to include a navbar only if there is one
$PAGE->set_category_by_id($id);
$OUTPUT->has_navbar();
</code>
</code>
In actuality only $PAGE->set_category_by_id() is needed to be called if appropriate as both $PAGE->set_course() and $PAGE->set_cm() are called for you by require_login()


Generation of navbar items will be undertaken by one or more of the following three internal functions depending on what level of information is available.
===Global navigation interaction===
<code php>
The following examples show the common task of adding an item to each node. Within each example you will see several of the methods available to developers for interacting with the navigation objects.
navbar::generate_for_category(); // Called if cm, course, and/or category have been set
navbar::generate_for_course(); // Called if cm or course have been set
navbar::generate_for_cm(); // Called only if cm has been set
</code>
Each of the functions will add items for its appropriate object (cm, course, category) to the item stack.
When the navbar output function is called any items that the user has added will be added to the end of the item stack, and then the navbar HTML will be generated.


===Interaction===
For more information on other methods please refer to the documentation for the objects available in the phpdocs section of moodle.org
When developing code for Moodle the following methods can be used to interact with the navbar.
<code php>
$OUTPUT->navbar->add(title, url, type[optional]); // Add a new navbar item
</code>


===Implementation===
====Adding items to the navigation structure====
The plan is to deprecate build_navigation and would be done using the above planned code in the following manner.
The following example illustrates how one would go about adding custom nodes into the main navigation structure along with the additional actions that can be used to further manipulate that newly added nodes.


Replace:
<code php>
<code php>
$navlinks = array();
/**
if (has_capability('moodle/course:viewparticipants', get_context_instance(CONTEXT_COURSE, $course->id)) || has_capability('moodle/site:viewparticipants', $syscontext)) {
* First we must locate the node that we wish to add content for.
     $navlinks[] = array('name' => $strparticipants, 'link' => "$CFG->wwwroot/user/index.php?id=$course->id", 'type' => 'core');
* In this case we will use the current course.
* The following line asks the global navigation object to return the
* active course node.
*/
$coursenode = $PAGE->navigation->find_active_node(navigation_node::TYPE_COURSE);
 
/**
* $coursenode will be false if there was no currently active course node
*/
if ($coursenode === false) {
    /**
    * Seeing as the above didn't work lets get the course object for the course
    * set against $PAGE
    */
     $coursenode = $PAGE->navigation->find_child($PAGE->course->id, navigation_node::TYPE_COURSE);
}
}
$navlinks[] = array('name' => $fullname, 'link' => "$CFG->wwwroot/user/view.php?id=$user->id&amp;course=$course->id", 'type' => 'title');
 
$navlinks[] = array('name' => $strforumposts, 'link' => '', 'type' => 'title');
/**
$navlinks[] = array('name' => $strmode, 'link' => '', 'type' => 'title');
* If $coursenode is still false we can't proceed as we don't have a point to add
$navigation = build_navigation($navlinks);
* our new node to
print_header("$course->shortname: $fullname: $strmode", $course->fullname,$navigation);
*/
if ($coursenode === false) return;
 
/**
* Now we can add a branch to put our custom nodes into, remember add returns the
* key that can be used to retrieve the newly added branch for later use
*/
$branchkey = $coursenode->add('My custom branch');
 
/**
* Get the newly added branch using the returned key
*/
$branch = $coursenode->get($branchkey);
 
/**
* Now lets add a node into the branch with my name, and my profile
* first we need to create moodle_url object to use as the action (or link)
* for this node, and then we can create the node
*/
$url = new moodle_url($CFG->wwwroot.'/course/view.php', Array('id'=>$coursenode->key);
$mykey = $branch->add('Sam Hemelryk', 'Sam', null, navigation_node::TYPE_CUSTOM, $url);
 
/**
* With my node created I could then proceed to call/set the following to
* achieve difference effects
*/
 
// This will force the branch I added to be expanded (open) when displayed
$branch->forceopen = true;
 
// This will add the CSS class mycustomclass to the node when it is displayed
$branch->get($mykey)->add_class('mycustomclass');
 
// This will make my node active (giving it the active class and forcing it open
// if it becomes a branch
// Remember: If a node is made active and is within the active branch then it is displayed
// as part of the navigation bar as well as the global navigation
$branch->get($mykey)->make_active();
</code>
</code>


With:
====Adding items to the navigation bar but not the main navigation structure====
Adding items to just the navigation structure is much easier than adding items to the global navigation. This is because you are not required to find the node you wish to add to, and you don't need to track the keys you add.
 
When you add to the navigation bar the new node is simply added to the end of the navigation bar.
 
<code php>
<code php>
if (has_capability('moodle/course:viewparticipants', get_context_instance(CONTEXT_COURSE, $course->id)) || has_capability('moodle/site:viewparticipants', $syscontext)) {
/**
    $OUTPUT->navbar->add($strparticipants, $CFG->wwwroot.'/user/index.php?id='.$course->id);
* In this example we will add two node to the navigation bar, the first with a link, the second without
}
*
$OUTPUT->navbar->add($strforumposts);
* To start lets create a moodle_url for the action of the first item
$OUTPUT->navbar->add($strmode);
*/
$PAGE->set_heading($course->fullname);
$url = new moodle_url($CFG->wwwroot.'/path/to/stuff.php');
echo $OUTPUT->header();
 
/**
* Now lets add the first item with its action
*/
$PAGE->navbar->add('first node', null, null, null, $url);
 
/**
* And with the first node added we can add the second
*/
$PAGE->navbar->add('second node');
 
/**
* And with that we are done.
* Remember though add returns the key so if you want to manipulate
* the new nodes you can do by capturing the key and using it to retrieve
* the node you want.
*/
</code>
</code>


In the template:
 
<code php>
 
if ($navigation) { // This is the navigation bar with breadcrumbs  ?>
====Adding module settings to the settings navigation====
    <div class="navbar clearfix">
Adding nodes to the settings navigation is identical to the global navigation however rather than using $PAGE->navigation you use $PAGE->settingsnavigation. The only thing to note is that the settings navigation nodes that are made active will only be shown in the navigation bar is there is no active branch within the global navigation.
        <div class="breadcrumb"><?php print_navigation($navigation); ?></div>
 
</code>
===Usability===
Will be replaced by
Usability of the navigation blocks was a big consideration when planning these changes as such several things have been done to aid the performance, design, and functionality of the navigation blocks.
<code php>
 
<?php if ($OUTPUT->navbar()) { // This is the navigation bar with breadcrumbs  ?>
Some of the notable features that have come from this include:
    <div class="navbar clearfix">
 
        <div class="breadcrumb"><?php echo $OUTPUT->navbar(); ?></div>
====Loading branches through AJAX when the user digs down the tree====
</code>
There is potentially a phenomenal amount of information that could be generated by the navigation structure when it initialises. Because of this the amount of information that the tree structure shows is limited to information that is pertinent to the current user, and is within a given depth. Anything that is further-a-field can only be viewed by progressing towards that information within Moodle.
 
To aid the usability of the navigation tree AJAX loading of branches into the tree has been added as a feature. This enables a user with Javascript enabled to dig down into the tree expanding branches that we not generated initially for the tree by means of requesting those branches with AJAX.
 
====Caching of retrieved information to add generation time====
Again to aid in the generation time of the tree particularly in large installations caching has been implemented within the navigation structure using a class that allows easy caching within the user's session. The cache is lasts only for a short period (60 seconds by default). Into it we include things that are used repetitively, or objects that are used in every page load. This greatly speeds up the delivery of the page when the user is navigating to their desired location, whilst ensuring that when changes that would effect the navigation structure occur they are seen in a timely fashion.
 
====Javascript transformation of blocks====
Again the information that is potentially displayed in the navigation could lead to some very negative effects on usability, the biggest of these being horizontal scrolling of the navigation blocks.
 
Because of this two Javascript transformation methods for the block have been defined and can be configured by the user adding the blocks.
 
# The first method is Javascript block expansion that can be turned on through the block configuration panel. When enabled if the user also has Javascript enabled then when they move the mouse over the navigation block it will grow in width (currently to 200%) allowing much more of the tree to be viewed before having to horizontally scrolled.
# The second method involves removing the block from the page and then adding a side-panel for the page, and re-adding the block back into the page as a tab on the side panel. When you mouse over the navigation tab you the navigation block expands out and can take up as much room as required.
 
Currently both of these options can be enabled within the settings for the block.
 
===API===
====navigation_node====
<b>Methods</b>
* navigation_node::__construct(Array $properties)
* navigation_node::__construct(String $text)
* navigation_node::add($text, $shorttext, $key, $type, $action, $icon)
* navigation_node::add_class($class)
* navigation_node::add_to_path($patharray, $key=null, $text=null, $shorttext=null, $type=null, $action=null, $icon=null)
* navigation_node::check_if_active()
* navigation_node::contains_active_node()
* navigation_node::content()
* navigation_node::find_active_node()
* navigation_node::find_child()
* navigation_node::find_child_depth()
* navigation_node::find_expandable()
* navigation_node::get()
* navigation_node::get_by_path()
* navigation_node::get_css_type()
* navigation_node::make_active()
* navigation_node::reiterate_active_nodes()
* navigation_node::remove_child()
* navigation_node::remove_class()
* navigation_node::respect_forced_open()
* navigation_node::toggle_type_display()
 
<b>Properties</b>
* navigation_node::action
* navigation_node::children
* navigation_node::classes
* navigation_node::collapse
* navigation_node::display
* navigation_node::forceopen
* navigation_node::helpbutton
* navigation_node::hidden
* navigation_node::icon
* navigation_node::id
* navigation_node::isactive
* navigation_node::key
* navigation_node::nodetype
* navigation_node::preceedwithhr
* navigation_node::shorttext
* navigation_node::text
* navigation_node::type
 
<b>Constants</b>
Node type contants set whether the node is a leaf (no children) or a branch (has children) and is stored in navigation_node::nodetype
* navigation_node::NODETYPE_LEAF
* navigation_node::NODETYPE_BRANCH
 
Type constants are used to identify the moodle structure point that this node represents
* navigation_node::TYPE_SYSTEM
* navigation_node::TYPE_CATEGORY
* navigation_node::TYPE_COURSE
* navigation_node::TYPE_SECTION
* navigation_node::TYPE_ACTIVITY
* navigation_node::TYPE_RESOURCE
* navigation_node::TYPE_CUSTOM
* navigation_node::TYPE_SETTING
 
====global_navigation ''extends navigation_node''====
<b>Note:</b> global_navigation extends navigation_node thus all navigation node methods and properties not override below will be available.
 
<b>Methods</b>
* global_navigation::add_course_section_generic(&$keys, $course, $name, $activeparam)
* global_navigation::add_courses($courses, $categoryid=null)
* global_navigation::content()
 
<b>Properties</b>
* global_navigation::expandable [property: an array of nodes that could be expanded]
* global_navigation::expansionlimit [property: used to limit the items displayed]
 
====settings_navigation ''extends navigation_node''====
<b>Note:</b> settings_navigation extends navigation_node thus all navigation node methods and properties not override below will be available.
 
<b>Methods</b>
* settings_navigation::add($text, $shorttext, $key, $type, $action, $icon)
* settings_navigation::remove_empty_root_branches()
* settings_navigation::content()
 
====navbar ''extends navigation_node''====
<b>Note:</b> navbar extends navigation_node thus all navigation node methods and properties not override below will be available.
 
<b>Methods</b>
* navbar::add($text, $shorttext, $key, $type, $action, $icon)
* navbar::has_items()
* settings_navigation::content()


==Further Information==
==Further Information==

Revision as of 05:17, 11 August 2009

Implementation of global navigation, settings navigation, and the navbar in Moodle 2.0

To help Tim in his mammoth task of navigation implementation I have undertaken to complete the implementation of the global navigation, settings navigation, and the navbar for him.

The following is the specification for the three, as they are very closely tied in to each other.

Implementation Overview

The purpose of the new navigation is to capture the structure of a Moodle site and present a series of navigation objects that allow the user to easily navigate Moodle 2.0.

The focus is to create a usable navigation structure for Moodle, that is constant in its appearance and usage.

In order to achieve this it was decided that three navigation structures were needed.

  • Global navigation: This is the course structure for the site, starting at the site level, through categories, courses, course sections, and activities. With the ability for an activity to further expand the navigation.
  • Settings navigation: The settings available to the user for their current context. This will contain things such as site administration, course settings, activity settings, and profile settings.
  • Navigation bar: As seen in Moodle, at the same time as implementing the above two navigation structures we will also re-implement the navigation bar in a object oriented method and make it more intuitive by getting it to auto-generate as deep as possible based on the information available through the PAGE object that is now available.

How these tie in: During the creation of mock up's it became apparent that there was a great deal of repetition in code if all three navigation structures we generated individually. In working through the possibilities we decided on the following approach of implementation:

  1. Start with the global navigation object nesting it as a property of the moodle_page ($PAGE) object.
  2. Initialise the global navigation object the first time it is requested, initially we thought that we would do this at the same time as we initialise theme and output, however this proved to be problematic.
  3. When global navigation initialises it will look at the context held by $PAGE and generate its own structure based on that context, ensuring that it adheres to the capabilities of the current user.
  4. Every node that gets added to the global navigation tree is analysed to find out if it is the active node (the node the user is currently viewing)
  5. Next the navigation bar, like global navigation it is initialised when it is first used
  6. When the navigation bar is first called it also calls global navigation to initialise to ensure that the general navigation structure has been generated.
  7. Unlike the global navigation nothing is generated during initialisation, the object is set-up to be used and nothing else.
  8. When called to display the navigation bar will analyse the global navigation object ($PAGE->navigation) and retrieve all nodes that form the path to the active node, these nodes will form the breadcrumb.
  9. After generating the path as above, the navigation bar then looks at itself to check for any children that have been added specifically to the navigation bar.
  10. Finally the settings navigation.
  11. Settings navigation is again only initialised when it is first used. However it is [currently] only used by the settings block which will be implemented at the same time.
  12. When being initialised settings navigation will call global navigation to initialise if it has not already to ensure that it loaded and ready for inspection.
  13. During initialisation the settings navigation inspects the global navigation to find the currently active node, and $PAGE and its properties to find the different elements that can contribute to the settings available for the user.
  14. Settings navigation then proceeds to generate the permitted settings for the current user for each of the elements found above.

As you can see above all three objects are initialised when they are first used, and global navigation is the main structure that the other two objects (settings and navbar) both inspect in order to lessen the amount of information that they must generate.

The following are the points during processing that the tree will likely be initialised:

  • When interacted with directly; All three blocks can be interacted with directly, and independently, when such an interaction occurs the blocks will be initialised as described above.
  • During block processing; If either a global navigation or settings navigation block have been added to the page the relevant objects will be initialised when we start block processing.
  • Within the template call to display the navigation bar; simple as that when the template wants to use the navigation bar we need to initialise the global navigation and then the navbar.

General Interaction

Whilst the three objects will automatically generate as much of the navigation structure as possible there is case for further extending the navigation beyond the what it is able to generate.

The objects themselves are all made available through the $PAGE object in the following manor:

// Don't forget if you are in a function you will need global $PAGE $PAGE->navigation; // This will return the navigation object $PAGE->settingsnav; // This will return the settings navigation object $PAGE->navbar; // This will return the navigation bar object

The following method has also been made available through the $OUTPUT object

// This method will return true if the navigation bar object has anything to display // and has been added to allow template designers to include a navbar only if there is one $OUTPUT->has_navbar();

Global navigation interaction

The following examples show the common task of adding an item to each node. Within each example you will see several of the methods available to developers for interacting with the navigation objects.

For more information on other methods please refer to the documentation for the objects available in the phpdocs section of moodle.org

Adding items to the navigation structure

The following example illustrates how one would go about adding custom nodes into the main navigation structure along with the additional actions that can be used to further manipulate that newly added nodes.

/**

* First we must locate the node that we wish to add content for.
* In this case we will use the current course.
* The following line asks the global navigation object to return the
* active course node.
*/

$coursenode = $PAGE->navigation->find_active_node(navigation_node::TYPE_COURSE);

/**

* $coursenode will be false if there was no currently active course node
*/

if ($coursenode === false) {

   /**
    * Seeing as the above didn't work lets get the course object for the course
    * set against $PAGE
    */
   $coursenode = $PAGE->navigation->find_child($PAGE->course->id, navigation_node::TYPE_COURSE);

}

/**

* If $coursenode is still false we can't proceed as we don't have a point to add
* our new node to
*/

if ($coursenode === false) return;

/**

* Now we can add a branch to put our custom nodes into, remember add returns the
* key that can be used to retrieve the newly added branch for later use
*/

$branchkey = $coursenode->add('My custom branch');

/**

* Get the newly added branch using the returned key
*/

$branch = $coursenode->get($branchkey);

/**

* Now lets add a node into the branch with my name, and my profile
* first we need to create moodle_url object to use as the action (or link)
* for this node, and then we can create the node
*/

$url = new moodle_url($CFG->wwwroot.'/course/view.php', Array('id'=>$coursenode->key); $mykey = $branch->add('Sam Hemelryk', 'Sam', null, navigation_node::TYPE_CUSTOM, $url);

/**

* With my node created I could then proceed to call/set the following to
* achieve difference effects
*/

// This will force the branch I added to be expanded (open) when displayed $branch->forceopen = true;

// This will add the CSS class mycustomclass to the node when it is displayed $branch->get($mykey)->add_class('mycustomclass');

// This will make my node active (giving it the active class and forcing it open // if it becomes a branch // Remember: If a node is made active and is within the active branch then it is displayed // as part of the navigation bar as well as the global navigation $branch->get($mykey)->make_active();

Adding items to the navigation bar but not the main navigation structure

Adding items to just the navigation structure is much easier than adding items to the global navigation. This is because you are not required to find the node you wish to add to, and you don't need to track the keys you add.

When you add to the navigation bar the new node is simply added to the end of the navigation bar.

/**

* In this example we will add two node to the navigation bar, the first with a link, the second without
*
* To start lets create a moodle_url for the action of the first item
*/

$url = new moodle_url($CFG->wwwroot.'/path/to/stuff.php');

/**

* Now lets add the first item with its action
*/

$PAGE->navbar->add('first node', null, null, null, $url);

/**

* And with the first node added we can add the second
*/

$PAGE->navbar->add('second node');

/**

* And with that we are done.
* Remember though add returns the key so if you want to manipulate
* the new nodes you can do by capturing the key and using it to retrieve
* the node you want.
*/


Adding module settings to the settings navigation

Adding nodes to the settings navigation is identical to the global navigation however rather than using $PAGE->navigation you use $PAGE->settingsnavigation. The only thing to note is that the settings navigation nodes that are made active will only be shown in the navigation bar is there is no active branch within the global navigation.

Usability

Usability of the navigation blocks was a big consideration when planning these changes as such several things have been done to aid the performance, design, and functionality of the navigation blocks.

Some of the notable features that have come from this include:

Loading branches through AJAX when the user digs down the tree

There is potentially a phenomenal amount of information that could be generated by the navigation structure when it initialises. Because of this the amount of information that the tree structure shows is limited to information that is pertinent to the current user, and is within a given depth. Anything that is further-a-field can only be viewed by progressing towards that information within Moodle.

To aid the usability of the navigation tree AJAX loading of branches into the tree has been added as a feature. This enables a user with Javascript enabled to dig down into the tree expanding branches that we not generated initially for the tree by means of requesting those branches with AJAX.

Caching of retrieved information to add generation time

Again to aid in the generation time of the tree particularly in large installations caching has been implemented within the navigation structure using a class that allows easy caching within the user's session. The cache is lasts only for a short period (60 seconds by default). Into it we include things that are used repetitively, or objects that are used in every page load. This greatly speeds up the delivery of the page when the user is navigating to their desired location, whilst ensuring that when changes that would effect the navigation structure occur they are seen in a timely fashion.

Javascript transformation of blocks

Again the information that is potentially displayed in the navigation could lead to some very negative effects on usability, the biggest of these being horizontal scrolling of the navigation blocks.

Because of this two Javascript transformation methods for the block have been defined and can be configured by the user adding the blocks.

  1. The first method is Javascript block expansion that can be turned on through the block configuration panel. When enabled if the user also has Javascript enabled then when they move the mouse over the navigation block it will grow in width (currently to 200%) allowing much more of the tree to be viewed before having to horizontally scrolled.
  2. The second method involves removing the block from the page and then adding a side-panel for the page, and re-adding the block back into the page as a tab on the side panel. When you mouse over the navigation tab you the navigation block expands out and can take up as much room as required.

Currently both of these options can be enabled within the settings for the block.

API

navigation_node

Methods

  • navigation_node::__construct(Array $properties)
  • navigation_node::__construct(String $text)
  • navigation_node::add($text, $shorttext, $key, $type, $action, $icon)
  • navigation_node::add_class($class)
  • navigation_node::add_to_path($patharray, $key=null, $text=null, $shorttext=null, $type=null, $action=null, $icon=null)
  • navigation_node::check_if_active()
  • navigation_node::contains_active_node()
  • navigation_node::content()
  • navigation_node::find_active_node()
  • navigation_node::find_child()
  • navigation_node::find_child_depth()
  • navigation_node::find_expandable()
  • navigation_node::get()
  • navigation_node::get_by_path()
  • navigation_node::get_css_type()
  • navigation_node::make_active()
  • navigation_node::reiterate_active_nodes()
  • navigation_node::remove_child()
  • navigation_node::remove_class()
  • navigation_node::respect_forced_open()
  • navigation_node::toggle_type_display()

Properties

  • navigation_node::action
  • navigation_node::children
  • navigation_node::classes
  • navigation_node::collapse
  • navigation_node::display
  • navigation_node::forceopen
  • navigation_node::helpbutton
  • navigation_node::hidden
  • navigation_node::icon
  • navigation_node::id
  • navigation_node::isactive
  • navigation_node::key
  • navigation_node::nodetype
  • navigation_node::preceedwithhr
  • navigation_node::shorttext
  • navigation_node::text
  • navigation_node::type

Constants Node type contants set whether the node is a leaf (no children) or a branch (has children) and is stored in navigation_node::nodetype

  • navigation_node::NODETYPE_LEAF
  • navigation_node::NODETYPE_BRANCH

Type constants are used to identify the moodle structure point that this node represents

  • navigation_node::TYPE_SYSTEM
  • navigation_node::TYPE_CATEGORY
  • navigation_node::TYPE_COURSE
  • navigation_node::TYPE_SECTION
  • navigation_node::TYPE_ACTIVITY
  • navigation_node::TYPE_RESOURCE
  • navigation_node::TYPE_CUSTOM
  • navigation_node::TYPE_SETTING

global_navigation extends navigation_node

Note: global_navigation extends navigation_node thus all navigation node methods and properties not override below will be available.

Methods

  • global_navigation::add_course_section_generic(&$keys, $course, $name, $activeparam)
  • global_navigation::add_courses($courses, $categoryid=null)
  • global_navigation::content()

Properties

  • global_navigation::expandable [property: an array of nodes that could be expanded]
  • global_navigation::expansionlimit [property: used to limit the items displayed]

settings_navigation extends navigation_node

Note: settings_navigation extends navigation_node thus all navigation node methods and properties not override below will be available.

Methods

  • settings_navigation::add($text, $shorttext, $key, $type, $action, $icon)
  • settings_navigation::remove_empty_root_branches()
  • settings_navigation::content()

navbar extends navigation_node

Note: navbar extends navigation_node thus all navigation node methods and properties not override below will be available.

Methods

  • navbar::add($text, $shorttext, $key, $type, $action, $icon)
  • navbar::has_items()
  • settings_navigation::content()

Further Information

Navigation 2.0

Navigation 2.0 implementation plan

Forum Discussion