Custom Horizontal Menu in Moodle Boost Theme

The menu structure in Moodle depends on the theme being used. The core Boost theme included with Moodle does not use a horizontal menu. Navigation is done using the menu in the left Administration panel and for this you need to toggle the hamburger menu. This left panel takes up quite a bit of screen space along with the right side panel for blocks leaving very little space. Further, the menu is not a drop down so for many items you have to scroll down to access menu items. Surely, there is a better way?

It is easy enough to implement a horizontal menu structure at the top of the screen which is normally unused in any case.  This will free us from having to access the inconvenient left pane.

For menu items which are not dependent on any conditions and for which the links are fixed, the most convenient way to add the menu is using the custom menu option in the Boost theme. So in our case we implement the following:

In the settings for Boost themes called custom menu items, the following is placed:

Student FAQ
-Assignment Submissions|https://yourmoodle.com/mod/book/view.php?id=1663
-Update profile|https://yourmoodle.com/mod/book/view.php?id=3159
-Communications|https://yourmoodle.com/mod/book/view.php?id=17665
-Video Tutorials|https://yourmoodle.com/mod/book/view.php?id=1663&chapterid=6562
-Portfolio|https://yourmoodle.com/mod/book/view.php?id=1663&chapterid=6571
Events
-Upcoming|https://yourmoodle.com/calendar/view.php?view=upcoming
-Calendar Day|yourmoodle.com/calendar/view.php?view=day
-Calendar Month|https://yourmoodle.com/calendar/view.php?view=month

This produces 2 menu’s called Student FAQ and Events with menu items: Assignment Submissions, Update profile, Communications, Video Tutorials, Portfolio, under the Student FAQ branch and menu items: Upcoming, Calendar Day, Calendar month, under the Events branch.

The above works, because in essence, this is a ‘static’ menu, with fixed URL’s and menu items that are universally accessible by all users.

What if the menu needs to be ‘dynamic’ with availability depending on context and user capability in the system? For this we need to do a little bit of PHP code.

We first create a child theme based on Boost. To do this we follow this tutorial.

We then edit the file: classes->output->core_renderer.php as follows:

These lines at the beginning of the file are references along with ensuring that outside access is prohibited.

namespace theme_slsboostchild\output;
use moodle_url;
defined('MOODLE_INTERNAL') || die;

The following lines are same as in Boost theme where the edit button is added back.

/**
 * Renderers to align Moodle's HTML with that expected by Bootstrap
 *
 * @package    theme_slsboostchild
 * @copyright  2012 Bas Brands, www.basbrands.nl, Madhu Avasarala
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
class core_renderer extends \core_renderer {
    public function edit_button(moodle_url $url) {
        $url->param('sesskey', sesskey());
        if ($this->page->user_is_editing()) {
            $url->param('edit', 'off');
            $editstring = get_string('turneditingoff');
        } else {
            $url->param('edit', 'on');
            $editstring = get_string('turneditingon');
        }
        $button = new \single_button($url, $editstring, 'post', ['class' => 'btn           btn-primary']);
        return $this->render_single_button($button);
    }

The rest of the code is sheer theme customization that we desire – we first override the render_custom_menu function. We define the needed globals and needed libraries.

/**
 * override function in parent to render custom menu
 *
 * @menu
 * @copyright  Madhu Avasarala
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
    protected function render_custom_menu(\custom_menu $menu)
    {
        global $CFG, $PAGE, $COURSE, $DB;
        require_once($CFG->dirroot.'/course/lib.php');

Next, the mycourses menu branch which is available for all logged users on any page, is added as follows:

// mycourses menu on all pages available to all
        if (isloggedin() && !isguestuser() && $mycourses = enrol_get_my_courses(NULL, 'visible DESC, fullname ASC'))
        {
            $branchlabel = get_string('mycourses') ;
            $branchurl   = new moodle_url('/course/index.php');
            $branchtitle = $branchlabel;
            $branchsort  = 12000 ; // lower numbers = higher priority e.g. move this item to the left on the Custom Menu
            $branch = $menu->add($branchlabel, $branchurl, $branchtitle, $branchsort);

            foreach ($mycourses as $mycourse)
            {
                $branch->add($mycourse->shortname, new moodle_url('/course/view.php', array('id' => $mycourse->id)), $mycourse->fullname);
            }
        }
Posted in customization, moodle.