Note:

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

Creating different custom menu bars for different courses: Creating different menu bars: Difference between revisions

From MoodleDocs
Line 137: Line 137:
<code php>
<code php>
public function custom_menu
public function custom_menu
</php>
</code>


with the following code:
with the following code:
Line 153: Line 153:
     }
     }


</php>
</code>




We are just changing the code according to [https://tracker.moodle.org/browse/MDL-31043/MDL-31043:]
We are just changing the code according to [https://tracker.moodle.org/browse/MDL-31043/MDL-31043:]

Revision as of 11:28, 6 August 2013

This tutorials explains how to create different custom menu bars for different courses in a Moodle site

This level of technical knowledge is moderate to advanced, as the tutorial involves some previous knowledge of php and css.

Before starting this tutorial, you should be familiar with the following contents:


What is the 'custom menu' bar

The custom menu bar is the horizontal bar displayed on top of the screen, usually after the Moodle logo:

   menu bar

The name 'custom menu' bar comes from the fact that, in Moodle 2.0, the links displayed on that bar can be easily customised by the administrator of a Moodle site through the menu:

Appearance->Themes-> Theme settings and then, configuring the 'Custom menu items' box:

 custom menu items

The links added in that box are used to created a custom menu object, which is a structured collection of custom_menu_item nodes that can be rendered by the core renderer. If you want a more technical explanation, the custom menu object is built according to the configuration of $CFG->custommenuitems, and custommenuitems take all the links added to that box.


Most of the Moodle sites use the same custom menu bar throughout the whole site, which means that the links added to the 'Custom menu items' box are displayed in ALL the courses. This is probably fine in most of the cases, however:

Wouldn't it be great if, within the same Moodle site, we could display different custom menu bar for different courses ?

Why would you want to do that?... Imagine, for instance, that you want to display different links in the custom menu bar for a specific course (or for a specific category in Moodle)

Moodle 2.0 includes a core theme -Afterburner - that supports their own 'Custom menu items' box, in addition to the general box in the Theme settings menu. This is because the theme Afterburner renders its on custom menu object by overriding the function render_custom_menu in /moodle/lib/outputrenderers. php. In plan English: Afterburner overrides the part of the code that tells Moodle how to build the custom menu items.

We can therefore use the same renderer that Afterburner uses in order to create a different custom menu bar for specific courses while using our own Moodle theme.

This is, step by step, the process that we are going to follow:

  1. Creating a child theme that inherits the CSS styles and pagelayout from our Moodle theme.
  2. Enable a specific 'Custom menu box' for our child theme
  3. Overriding the renderer custom_menu of the core renderer and using the same custom_menu renderer of Afterburner's
  4. Creating a menu.css file to display the custom menu items in our child theme
  5. Enabling Course themes in our Moodle site
  6. Selecting the child theme as the theme of those courses that require a different custom menu bar.

This is not the only way of doing it: alternatively, you could override the renderer custom menu in your Moodle theme and the child theme will inherit the renderer. However, for Moodle users who do not have an in-depth knowledge of how themes and renderers work, it is probably wiser not to mess around with the main theme and try the code modifications with a child theme.

The following sections explain each of the six steps in detail.

Creating a child theme

In order to create a child theme, just follow the same instructions that for creating a new theme, but you will not have to worry about the css files in:

child_theme/styles.

Make sure that the config.php file of your child theme includes the following lines:

$THEME->parents = array(

   'parent theme', 'granparent theme','base');

The next step is to open the config.php file and add the following configuration option to it (at the bottom): $THEME->rendererfactory = 'theme_overridden_renderer_factory';


If you are already using a custom renderer, you will already have this line.

And that is! Now we move on to extending the custom menu.


Notice: In addition to settings.php, it is a good practice that you also create your own version.php file for your child theme as specified at * Themes 2.0 creating your first theme


Enabling a custom menu box for our child theme

You need to create a file called 'settings.php' in the root folder of your child theme (i.e. /theme/child_theme/). Add the following code to settings.php:

<?php

/**

* Settings for the child theme
*/

defined('MOODLE_INTERNAL') || die;

if ($ADMIN->fulltree) {


$name = 'theme_child_theme/customcss'; $title = get_string('customcss','theme_child_theme'); $description = get_string('customcssdesc', 'theme_child_theme'); $setting = new admin_setting_configtextarea($name, $title, $description, ); $settings->add($setting);

 // Theme overrides custom menu setting...
   $name = 'theme_child_theme/custommenuitems';
   $title = get_string('custommenuitems', 'admin');
   $description = get_string('configcustommenuitems', 'admin');
   $default = ;
   $setting = new admin_setting_configtextarea($name, $title, $description, $default);
   $settings->add($setting);


} ?>

Remember to replace the string '_child_theme' with the name of your own child theme.


Overriding the renderer custom_menu

Since we are going to use the same renderer that the theme Afterburner uses, you need to copy the file renderers.php into your child theme root folder. Open renderers.php and replace the text string _afterburner_ with the name of your own child theme.

As we are overriding the renderer custom_menu in the child theme, we need to tweak a bit the layout files that the child theme has inherited from its parent theme. Layout files are kept in the folder /layout of the parent theme. The number of layout files depends on the theme that you are using. Open each of the layout files and replace the line:

$custommenu = $OUTPUT->custom_menu();

with the following code: $custommenu = $OUTPUT->custom_menu($PAGE->theme->settings->custommenuitems); $hascustommenu = (empty($PAGE->layout_options['nocustommenu']) && !empty($custommenu));

In Moodle 2.2, there is an extra step required so that the renderer in the child theme can work. You need to modify function custom_menu located in the file /moodle/lib/outputrenderers.php. By default the function custom_menu returns the custom menu as a string including the links that were added to the Administration > Appearance > Themes > Theme settings 'Custom menu item' box. We need to modify that function to allow that different strings can be passed. By defaul, the function custom_menu only looks for links at the general Theme settings 'Custom menu box'. It is now time to tell the function that, if the child theme supports its own 'Custom menu item' box, then use the links defined in that specific box in order to generate the custom menu string.

Open the file outputrenderers.php and replace the function: public function custom_menu

with the following code:

public function custom_menu($custommenuitems = ) {
       global $CFG;
       if (empty($custommenuitems) && !empty($CFG->custommenuitems)) {
           $custommenuitems = $CFG->custommenuitems;
       }
       if (empty($custommenuitems)) {
           return ;
       }
       $custommenu = new custom_menu($custommenuitems, current_language());
       return $this->render_custom_menu($custommenu);
   }


We are just changing the code according to [1]