Note: You are currently viewing documentation for Moodle 3.9. Up-to-date documentation for the latest stable version of Moodle may be available here: Themes 2.0.

Development:Themes 2.0: Difference between revisions

From MoodleDocs
 
(18 intermediate revisions by 9 users not shown)
Line 63: Line 63:
| /javascript/  
| /javascript/  
|  
|  
| All speciality JavaScript files the theme requires should be located in here.
| All specialty JavaScript files the theme requires should be located in here.
|-
|-
| /lang/  
| /lang/  
Line 153: Line 153:
The final setting is to include a JavaScript file, as $THEME->javascripts_footer. Much like stylesheets, you only need to provide the files name. Moodle will assume it is in your themes JavaScript directory and be a .js file.
The final setting is to include a JavaScript file, as $THEME->javascripts_footer. Much like stylesheets, you only need to provide the files name. Moodle will assume it is in your themes JavaScript directory and be a .js file.


'''''Note''''': When you start out theming, make sure you take a look at the configuration files of the other themes that get shipped with Moodle. You will get a good picture of how everything works, and what is going on in a theme, simply by reading it and taking notice of what it is including or excluding.
'''''Note''''': When you first begin writing themes, make sure you take a look at the configuration files of the other themes that get shipped with Moodle. You will get a good picture of how everything works, and what is going on in a theme, simply by reading it and taking notice of what it is including or excluding.


==CSS==
==CSS==
Line 240: Line 240:
The first thing Moodle looks at is the name of the layout, in this case it is `standard` (the array key in PHP), it then looks at the settings for the layout, this is the theme, file, regions, and default region. There are also a couple of other options that can be set by a layout.
The first thing Moodle looks at is the name of the layout, in this case it is `standard` (the array key in PHP), it then looks at the settings for the layout, this is the theme, file, regions, and default region. There are also a couple of other options that can be set by a layout.


; theme : is the theme the layout file exists in. That's right you can make use of layouts from other installed themes.
; theme : is the theme the layout file exists in. That's right you can make use of layouts from other installed themes. ''Optional''
; file : is the name of the layout file this layout wants to use.
; file : is the name of the layout file this layout wants to use. ''Required''
; regions : is the different block regions (places you can put blocks) within the theme.
; regions : is the different block regions (places you can put blocks) within the theme. ''Required''
; defaultregion : is the default location when adding new blocks.
; defaultregion : is the default location when adding new blocks. '''Required if regions is non-empty, otherwise optional'''
; options : an array of layout specific options described in detail below.
; options : an array of layout specific options described in detail below. '''Optional'''


The first four settings are required by each layout definition however the final setting `options` is a special case that only needs to be set if you want to make use of it. This setting allows the theme designer to specify special options that they would like to create that can be later accessed within the layout file. This allows the theme to make design decisions during the definition and react upon those decisions in what ever layout file is being used.
The '''theme''' is optional. Normally the the layout file is looked for in the current theme, or, if it is not there, in the parent theme. However, you can use a layout file from any other theme by giving the theme name here.


"Regions" is an array with defines which block 'columns' will be displayed by the layout. The possible values are '''side_pre''' and '''side_post'''. In most cases this will be synonymous with 'left side' and 'right side' but when the selected language is orientated right to left then the block columns will be reversed (hence pre and post).  
You can define whatever regions you like. You just need to pick an name for each one. Most themes just use one or both of '''side_pre''' and '''side_post''', which is like 'left side' and 'right side', except in right to left languages, when they are reversed. If you say in config.php that your the layout provides regions called 'fred' and 'barney', then you must call $OUTPUT->blocks_for_region('fred') and $OUTPUT->blocks_for_region('barney') somewhere in the layout file.
 
The final setting '''options''' is a special case that only needs to be set if you want to make use of it. This setting allows the theme designer to specify special options that they would like to create that can be later accessed within the layout file. This allows the theme to make design decisions during the definition and react upon those decisions in what ever layout file is being used.


One such place this has been used is infact within the base theme. If you take a look first at theme/base/config.php you will notice that several layouts specify options '''nonavbar''' and '''nofooter''' which can both be set to either true or false. Then if we take a look at theme/base/layout/general.php you will spot lines like the following:
One such place this has been used is infact within the base theme. If you take a look first at theme/base/config.php you will notice that several layouts specify options '''nonavbar''' and '''nofooter''' which can both be set to either true or false. Then if we take a look at theme/base/layout/general.php you will spot lines like the following:
Line 269: Line 271:
A layout file is a file that contains the core HTML structure for a layout including the header, footer, content and block regions.
A layout file is a file that contains the core HTML structure for a layout including the header, footer, content and block regions.
For those of you who are familiar with themes in Moodle 1.9 this is simply header.html and footer.html combined.
For those of you who are familiar with themes in Moodle 1.9 this is simply header.html and footer.html combined.
Of course it is not all HTML, there is bits of HTML and content that Moodle needs to put into the page, within each layout file this will be done by a couple of VERY simple PHP calls to get bits and pieces including content.
Of course it is not all HTML, there are bits of HTML and content that Moodle needs to put into the page, within each layout file this will be done by a couple of VERY simple PHP calls to get bits and pieces including content.


The following is a very simple layout file to illustrate the different bits that make it up:
The following is a very simple layout file to illustrate the different bits that make it up:
Line 279: Line 281:
     <?php echo $OUTPUT->standard_head_html() ?>
     <?php echo $OUTPUT->standard_head_html() ?>
</head>
</head>
<body id="<?php echo $PAGE->bodyid ?>" class="<?php echo $PAGE->bodyclasses; ?>">
<body id="<?php p($PAGE->bodyid) ?>" class="<?php p($PAGE->bodyclasses) ?>">
<?php echo $OUTPUT->standard_top_of_body_html() ?>
<?php echo $OUTPUT->standard_top_of_body_html() ?>
<table id="page">
<table id="page">
Line 319: Line 321:
<?php echo $OUTPUT->doctype() ?>
<?php echo $OUTPUT->doctype() ?>
</code>
</code>
This occurs at the VERY top of the page, it must be the first bit of output and is responsible for adding the (X)HTML document type definition to the page. This of course is determined by the settings of the site and is one of the things that the themer has no control over.
This occurs at the VERY top of the page, it must be the first bit of output and is responsible for adding the (X)HTML document type definition to the page. This of course is determined by the settings of the site and is one of the things that the theme designer has no control over.


<code php>
<code php>
Line 337: Line 339:


<code php>
<code php>
<body id="<?php echo $PAGE->bodyid; ?>" class="<?php echo $PAGE->bodyclasses; ?>">
<body id="<?php p($PAGE->bodyid); ?>" class="<?php p($PAGE->bodyclasses); ?>">
</code>
</code>
Much like the html tag above we have started writing the body tag and have asked for Moodle to get us the desired ID and classes that should be applied to it.
Much like the html tag above we have started writing the body tag and have asked for Moodle to get us the desired ID and classes that should be applied to it.
Line 377: Line 379:
Of course as mentioned above if you are customising an existing theme then you may not need to create any layouts or layout files at all.
Of course as mentioned above if you are customising an existing theme then you may not need to create any layouts or layout files at all.


Look at the '''core_renderer''' class in the file lib/outputrenderers.php to see all the functions that are available through $OUTPUT. Each function is clearly documented along with which is appropriate for use within the layout files.
'''$OUTPUT''' is an instance of the '''core_renderer''' class which is defined in lib/outputrenderers.php. Each method is clearly documented there, along with which is appropriate for use within the layout files.


The properties available within the $PAGE class can be discovered from the lib/pagelib.php file. Do note that accessing properties is achieved using the 'magic' __get() method which you might not be familiar with.
'''$PAGE''' is an instance of the '''moodle_page''' class defined in lib/pagelib.php. Most of the things you will want to use are the properties that are all documented at the top of the file. If you are not familiar with PHP properties, you access them like $PAGE->activityname, just like fields of an ordinary PHP object. (However, behind the scenes, some magic is going on, and the value you get is produced by calling a function. Also, you cannot change these values, they are read-only. However, you don't need to understand all that if you are just using these properties in your theme.)


==Making use of images==
==Making use of images==
Line 402: Line 404:
<img src="<?php echo $OUTPUT->pix_url('subdir/imagetwo', 'theme');?>" alt="" />  
<img src="<?php echo $OUTPUT->pix_url('subdir/imagetwo', 'theme');?>" alt="" />  
</code>
</code>
'''DO NOT''' include the image file extension. Moodle will work it out automatically and it will not work if you do include it.
In this case rather than writing out the URL to the image we use a method of Moodle's output library. Its not too important how that functions works but it is important that we use it as it is what allows images within Moodle to be over-rideable.
In this case rather than writing out the URL to the image we use a method of Moodle's output library. Its not too important how that functions works but it is important that we use it as it is what allows images within Moodle to be over-rideable.


Line 429: Line 434:


For a more detailed description of how this all works see the page on [[Development:Themes_2.0_How_to_use_images_within_your_theme|using images within your theme]]
For a more detailed description of how this all works see the page on [[Development:Themes_2.0_How_to_use_images_within_your_theme|using images within your theme]]
==Unobvious Things==
===Getting Your Theme to Appear Correctly in Theme Selector===
If you follow the examples on this page to the letter, when you go to the Theme Selector page you may be discouraged to find that your theme does not appear like the other themes do. In fact, instead of your theme's name, you will see something along the lines of <nowiki>[[pluginname]]</nowiki>.
To correct this, you must add the /lang/en/theme_THEMENAME.php file, where THEMENAME is the name of the theme folder. Inside that file, add the string "$string['pluginname'] = 'THEMENAME'; ". Make THEMENAME the name of your theme, however you want it displayed in the Theme selector.
The screenshot for the theme should be about 500x400 px.
===Required theme divs===
Some parts of Moodle may rely on particular divs, for example the div with id 'page-header'.
Consequently all themes must include at least the divs (with the same ids) that are present in the 'base' theme.
Missing out these elements may result in unexpected behaviour within specific modules or other plugins.


==Appendix A==
==Appendix A==
Line 545: Line 566:
==See also==
==See also==


* [http://www.youtube.com/watch?v=OvaU54uh-qA New themes in Moodle 2.0 video]
* [[Development:Themes 2.0 creating your first theme]] - A quick step by step guide to creating your first theme.
* [[Development:Themes 2.0 creating your first theme]] - A quick step by step guide to creating your first theme.
* [[Development:Themes 2.0 overriding a renderer]] - A tutorial on creating a custom renderer and changing the HTML Moodle produces.
* [[Development:Themes 2.0 overriding a renderer]] - A tutorial on creating a custom renderer and changing the HTML Moodle produces.
Line 551: Line 571:
* [[Development:Themes 2.0 adding a settings page]] - Looks at how to add a setting page making your theme easily customisable.
* [[Development:Themes 2.0 adding a settings page]] - Looks at how to add a setting page making your theme easily customisable.
* [[Development:Themes 2.0 extending the custom menu]] - Customising the custom menu.
* [[Development:Themes 2.0 extending the custom menu]] - Customising the custom menu.
* [[Development:Themes 2.0 adding courses and categories to the custom menu]] - Extending the custom menu further adding all categories + courses
* [[Development:Themes 2.0 how to make the dock horizontal]] - Modifying the dock to make it horizontal.
* [[Development:Themes 2.0 adding upgrade code]]
* [[Development:Styling and customising the dock]] - How to style and customise the dock.
* [[Development:Styling and customising the dock]] - How to style and customise the dock.
* [[Development:Theme changes in 2.0]]
* [[Development:Theme changes in 2.0]]
* [[Development:Using jQuery with Moodle 2.0]]
* [[Development:Using jQuery with Moodle 2.0]]
* [[Development:Themes 2.0 how to clone a Moodle 2.0 theme]]
* [http://www.youtube.com/watch?v=OvaU54uh-qA New themes in Moodle 2.0 video]


[[de:Designs 2.0]]
[[de:Designs 2.0]]
[[es:Temas 2.0]]

Latest revision as of 03:01, 6 May 2011

Template:Moodle 2.0Welcome to the new world of themes within Moodle 2.0!

This document explains how themes work in Moodle and is intended to help you create or modify most themes for Moodle 2.0.

Introduction

Moodle themes are responsible for much of the "look" of a Moodle site. They provide the CSS for colours, layouts, fonts and so on, and can also change the structural XHTML code below that.

A theme can either contain all the definitions (completely stand alone) or it can extend an existing theme with one or more customizations.

Most theme developers use the second method and simply add a few new CSS or layout definitions to their new theme. If a definition or element is not found in the new theme, it looks to the "parent" (or up the hierarchy of themes) to find one. It an easy way to achieve just about any look you want for a theme.

What's new in 2.0

The theme system was completely redesigned in Moodle 2.0. Known issues have been addressed and new features have been added to meet community requests.

Unfortunately it was not possible to maintain backward compatibility, so all Moodle 1.x themes need to be recreated for Moodle 2.0.

Major changes include:

  • Clearer and more consistent CSS classes and IDs throughout all pages in Moodle
  • Introduction of layout files (templates) describing overall layout HTML for many different types of pages in Moodle.
  • Introduction of renderers, which produce the smaller "parts" of a HTML page. Advanced themes can choose to override these too if they choose.
  • Introduction of standard methods for adding Javascript to themes.
  • Easier control over icons and images in Moodle.
  • The old "standard" theme has been split into two themes:
    • base - contains absolutely basic layout, and
    • standard - which adds CSS to the base theme to make it look like the old standard theme.
  • Performance tuning: In normal production mode CSS files are combined into a single optimised file, and both CSS and JavaScript files are minimised to ensure there are no wasted connections or traffic. Files are heavily cached, but also versioned, so that users never need to clear their caches.

The structure of a theme

Some important things to know when building good themes:

  1. config.php - this file is required in every theme. It defines configuration settings and definitions required to make the theme work in Moodle. These include theme, file, region, default region and options.
  2. Layouts and layout files - in config.php there is one definition for each page type (see Appendix A: Theme layouts for a list of over 12 types). Each page type definition tells Moodle which layout file will be used, what block regions this page type should display and so on. The layout file contains the HTML and the minimum PHP required to display basic structure of pages. (If you know Moodle 1.9, it's like a combination of header.html and footer.html).
  3. The base theme - is not intended to be used for production sites. It sets up the simplest possible generic layout and includes only CSS essential to that layout or to Moodle as a whole. It tries not to make any unnecessary rules and makes as few assumptions as possible. It's the perfect base on which to start designing a theme, as there are very few colours, borders, margins, and alignments to override. You can just start adding what you need.

Files and folders

A theme's files are placed in a folder with under moodle/theme folder and have subfolders. They are laid out like this:

Directory File Description
/config.php Contains all of the configuration and definitions for each theme
/lib.php Contains speciality classes and functions that are used by theme
/renderers.php Contains any custom renderers for the theme.
/settings.php Contains custom theme settings. These local settings are defined by the theme allowing the theme user to easily alter something about the way it looks or operates. (eg a background colour, or a header image)
/javascript/ All specialty JavaScript files the theme requires should be located in here.
/lang/ Any special language files the theme requires should be located in here.
/layout/ Contains the layout files for the theme.
/pix/ Contains any images the theme makes use of either in CSS or in the layout files.
/pix /favicon.ico The favicon to display for this theme.
/pix /screenshot.jpg A screenshot of the theme to be displayed in on the theme selection screen.
/style Default location for CSS files.
/*.css CSS files the theme requires

There are also several other places that stylesheets can be included from (see the CSS how and why section below).

Theme options

All theme options are set within the config.php file for the theme. The settings that are most used are: parents, sheets, layouts, and javascripts. Have a look at the theme options table for a complete list of theme options which include lesser used specialised or advanced settings.


Basic theme config example

Lets have a look at a basic theme configuration file and the different bits that make it up: $THEME->name = 'newtheme';

$THEME->parents = array(

   'base'

);

$THEME->sheets = array(

   'admin',
   'blocks',
   'calendar',
   'course',
   'grade',
   'message',
   'question',
   'user'

);

$THEME->layouts = array(

   'base' => array(
       'theme' => 'newtheme',
       'file' => 'general.php',
       'regions' => array(),
   ),
   'standard' => array(
       'theme' => 'newtheme',
       'file' => 'general.php',
       'regions' => array('side-pre', 'side-post'),
       'defaultregion' => 'side-post',
   )
   //.......

);

$THEME->javascripts_footer = array(

   'navigation'

);

Basic theme example settings explained

First up you will notice everything is added to $THEME. This is the theme's configuration object, it is created by Moodle using default settings and is then updated by whatever settings you add to it.

The first setting, $THEME->name is the theme's name. This should simply be whatever your theme's name is, most likely whatever you named your theme directory.

$THEME->parents defines the themes that the theme will extend. In this case it is extending only the base theme.

After this is the $THEME->sheets array containing the names of the CSS stylesheets to include for this theme. Note that it is just the name of the stylesheet and does not contain the directory or the file extension. Moodle assumes that the theme's stylesheets will be located in the styles directory of the theme and have .css as an extension.

Next we see the $THEME->layouts definition. In this example, two layouts have been defined to override the layouts from the base theme. For more information see the layouts section below.

The final setting is to include a JavaScript file, as $THEME->javascripts_footer. Much like stylesheets, you only need to provide the files name. Moodle will assume it is in your themes JavaScript directory and be a .js file.

Note: When you first begin writing themes, make sure you take a look at the configuration files of the other themes that get shipped with Moodle. You will get a good picture of how everything works, and what is going on in a theme, simply by reading it and taking notice of what it is including or excluding.

CSS

Locations of CSS files

First lets look at where CSS can be included from within Moodle:

\theme\themename\styles\*.css
This is the default location for all of the stylesheets that are used by a theme and the place which should be used by a theme designer.

New theme developers should note that the order in which CSS files are found and included creates a hierarchy. This order ensures that the rules, within a theme's style sheets, take precedence over identical rules in other files that may have been introduced before. This can both extend another files definitions (see parent array in the config file) and also ensures that the current theme's CSS rules/definitions have the last say.

There are other locations that can be used (although very rarely) to include CSS in a page. A developer of a php file can manually specify a stylesheet from anywhere within Moodle, like the database. Usually, if code is doing this, it is because there is a non-theme config or plugin setting that contains information requires special CSS information. As a theme designer you should be aware of, but not have to worry about, these locations of CSS files. Here are some examples:

{pluginpath}\styles.css e.g. \block\blockname\styles.css or \mod\modname\styles.css
Every plugin can have its own styles.css file. This file should only contain the required CSS rules for the module and should not add anything to the look of the plugin such as colours, font sizes, or margins other than those that are truly required.
Theme specific styles for a plugin should be located within the themes styles directory.
{pluginpath}\styles_themename.css
This should only ever be used by plugin developers. It allows them to write CSS that is designed for a specific theme without having to make changes to that theme. You will notice that this is never used within Moodle and is designed to be used only by contributed code.

As theme designers, we will only use the first method of introducing CSS: adding rules to a stylesheet file located in the themes styles directory.

Moodle's core CSS organisation

The next thing to look at is the organisation of CSS and rules within a theme. Although as a theme designer it is entirely up to you as to how you create and organise your CSS. Please note that within the themes provided in the standard install by Moodle there is a very clear organisation of CSS.

First is the pagelayout.css file. This contains the CSS required to give the layouts their look and feel. It doesn't contain any rules that affect the content generated by Moodle.

Next is the core.css file. If you open up core you will notice that it contains all manner of general (usually simple) rules that don't relate to a specific section of Moodle but to Moodle as a whole.

There can also be rules that relate to specific sections. However, this is done only when there are only a handful of rules for that section. These small clusters of rules are grouped together and separated by comments identifying for which section each relates.

Finally there are all the other CSS files, you will notice that there is a file for each section of Moodle that has a significant collection of rules.

For those who are familiar with Moodle 1.9 theme's, this organisation will be a big change. In 1.9, CSS was organised by its nature (for example: colours, layout, other).

How to write effective CSS rules within Moodle

In Moodle 2.0, writing good CSS rules is an incredibly important.

Due to performance requirements and browser limitations, all of the CSS files are combined into a single CSS file that gets included every time. This means that rules need to be written in such a way as to minimise the chances of a collision leading to unwanted styles being applied. Whilst writing good CSS is something most designers strive for we have implemented several new body classes and put more emphasis on developers for using classes more appropriately.

The body tag

As of Moodle 2.0 the ID tag that gets applied to the body will always be a representation of the URI. For example if you are looking at a forum posting and the URI is '/mod/forum/view.php' then the body tags ID will be '#page-mod-forum-view'.

As well as the body's ID attribute the URI is also exploded to form several CSS classes that get added to the body tag, so in the above example '/mod/forum/view' you would end up with the following classes being added to the body tag '.path-mod', '.path-mod-forum'. Note that '.path-mod-forum-view' is not added as a class, this is intentionally left out to lessen confusion and duplication as rules can relate directly to the page by using the ID and do not require the final class.

The body ID and body classes described above will form the bread and butter for many of the CSS rules you will need to write for your theme, however there are also several other very handy classes that get added to the body tag that will be beneficial to you once you start your journey down the rabbit hole that is themeing. Some of the more interesting classes are listed below.

  • If JavaScript is enabled then 'jsenabled' will be added as a class to the body tag allowing you to style based on JavaScript being enabled or not.
  • Either 'dir-rtl' or 'dir-ltr' will be added to the body as a class depending on the direction of the language pack: rtl = right to left, ltr = left to right. This allows you to determine your text-alignment based on language if required.
  • A class will be added to represent the language pack currently in use, by default en_utf8 is used by Moodle and will result in the class 'lang-en_utf8' being added to the body tag.
  • The wwwroot for Moodle will also be converted to a class and added to the body tag allowing you to stylise your theme based on the URL through which it was reached. e.g. http://sam.moodle.local/moodle/ will become '.sam-moodle-local—moodle'
  • If the current user is not logged then '.notloggedin' will be added to the body tag.

What does all of this look like in practise? Well using the above example /mod/forum/view.php you would get at least the following body tag: <body id=”page-mod-forum-view” class=”path-mod path-mod-forum” />

Writing your rules

The best use of body ids and classes and writing selectors will reduce problems.

There are many specific classes used within Moodle. We try to put them everywhere where anyone may want to apply their own styles. It is important to recognise that no one developer can be aware of the all of the class names that have been used all throughout Moodle, let alone within all of the different contributed bits and pieces available for Moodle. It is up to the theme developer to write good rules and minimise the chances of a collision between rules because in this case good CSS is FAR more effective.

When starting to write rules make sure that you have a good understanding of where you want those rules to be applied, it is a good idea to make the most of the body classes mentioned above. If you want to write a rule for a specific page make use of the body tag's ID, e.g.:

#page-mod-forum-view .forumpost {border:1px solid orange;)

If you want to write a rule that will be applied all throughout the forum.:

.path-mod-forum .forumpost {border:1px solid orange;}

The other very important thing to take into consideration is the structure leading up to the tag you want to style. Browsers apply conflicting styles with priority on the more specific selectors. It can be very beneficial to keep this in mind and write full selectors that rely on the structure of the tags leading to the tag you wish to style.

By making use of body id's and classes and writing selectors to take into account the leading structure you can greatly minimise the chance of a collision both with Moodle now and in the future.

Layouts

All themes are required to define the layouts they wish to be responsible for as well as create; however, many layout files are required by those layouts. If the theme is overriding another theme then it is a case of deciding which layouts this new theme should override. If the theme is a completely fresh start then you will need to define a layout for each of the different possibilities. For both situations these layouts should be defined within config.php.

It is also important to note that a new theme that will base itself on another theme (overriding it) does not need to define any layouts or use any layout files if there are no changes that it wishes to make to the layouts of the existing theme. The standard theme in Moodle is a good example of this as it extends the base theme simply adding CSS to achieve its look and feel.

So layouts... as mentioned earlier layouts are defined in config.php within $THEME->layouts. The following is an example of one such layout definition: $THEME->layouts = array(

   // Standard layout with blocks, this is recommended for most pages with general information
   'standard' => array(
       'theme' => 'base',
       'file' => 'general.php',
       'regions' => array('side-pre', 'side-post'),
       'defaultregion' => 'side-post'
   )

) The first thing Moodle looks at is the name of the layout, in this case it is `standard` (the array key in PHP), it then looks at the settings for the layout, this is the theme, file, regions, and default region. There are also a couple of other options that can be set by a layout.

theme
is the theme the layout file exists in. That's right you can make use of layouts from other installed themes. Optional
file
is the name of the layout file this layout wants to use. Required
regions
is the different block regions (places you can put blocks) within the theme. Required
defaultregion
is the default location when adding new blocks. Required if regions is non-empty, otherwise optional
options
an array of layout specific options described in detail below. Optional

The theme is optional. Normally the the layout file is looked for in the current theme, or, if it is not there, in the parent theme. However, you can use a layout file from any other theme by giving the theme name here.

You can define whatever regions you like. You just need to pick an name for each one. Most themes just use one or both of side_pre and side_post, which is like 'left side' and 'right side', except in right to left languages, when they are reversed. If you say in config.php that your the layout provides regions called 'fred' and 'barney', then you must call $OUTPUT->blocks_for_region('fred') and $OUTPUT->blocks_for_region('barney') somewhere in the layout file.

The final setting options is a special case that only needs to be set if you want to make use of it. This setting allows the theme designer to specify special options that they would like to create that can be later accessed within the layout file. This allows the theme to make design decisions during the definition and react upon those decisions in what ever layout file is being used.

One such place this has been used is infact within the base theme. If you take a look first at theme/base/config.php you will notice that several layouts specify options nonavbar and nofooter which can both be set to either true or false. Then if we take a look at theme/base/layout/general.php you will spot lines like the following: <?php $hasnavbar = (empty($PAGE->layout_options['nonavbar']) && $PAGE->has_navbar()); $hasfooter = (empty($PAGE->layout_options['nofooter'])); ?> ............ <?php if ($hasnavbar) { ?>

<?php } ?> What you are seeing here is the use of those settings from the layout within the layout file. In this case it is being used to toggle the display of the navigation bar and page footer.

Layout files

A layout file is a file that contains the core HTML structure for a layout including the header, footer, content and block regions. For those of you who are familiar with themes in Moodle 1.9 this is simply header.html and footer.html combined. Of course it is not all HTML, there are bits of HTML and content that Moodle needs to put into the page, within each layout file this will be done by a couple of VERY simple PHP calls to get bits and pieces including content.

The following is a very simple layout file to illustrate the different bits that make it up: <?php echo $OUTPUT->doctype() ?> <html <?php echo $OUTPUT->htmlattributes() ?>> <head>

   <title><?php echo $PAGE->title ?></title>
   <?php echo $OUTPUT->standard_head_html() ?>

</head> <body id="<?php p($PAGE->bodyid) ?>" class="<?php p($PAGE->bodyclasses) ?>"> <?php echo $OUTPUT->standard_top_of_body_html() ?>

<?php echo $PAGE->heading ?>

<?php echo $OUTPUT->login_info(); echo $PAGE->headingmenu; ?>
           <?php echo $OUTPUT->blocks_for_region('side-pre') ?>
           <?php echo core_renderer::MAIN_CONTENT_TOKEN ?>
           <?php echo $OUTPUT->blocks_for_region('side-post') ?>
           <?php
           echo $OUTPUT->login_info();
           echo $OUTPUT->home_link();
           echo $OUTPUT->standard_footer_html();
           ?>

<?php echo $OUTPUT->standard_end_of_body_html() ?> </body> </html>

Lets assume you know a enough HTML to understand the basic structure above, what you probably don't understand are the PHP calls so lets look at them. <?php echo $OUTPUT->doctype() ?> This occurs at the VERY top of the page, it must be the first bit of output and is responsible for adding the (X)HTML document type definition to the page. This of course is determined by the settings of the site and is one of the things that the theme designer has no control over.

<html <?php echo $OUTPUT->htmlattributes() ?>> Here we have started writing the opening html tag and have asked Moodle to give us the HTML attributes that should be applied to it. This again is determined by several settings within the actual HTML install.

<?php echo $PAGE->title ?> This gets us the title for the page.

<?php echo $OUTPUT->standard_head_html() ?> This very important call gets us the standard head HTML that needs to be within the HEAD tag of the page. This is where CSS and JavaScript requirements for the top of the page will be output as well as any special script or style tags.

<body id="<?php p($PAGE->bodyid); ?>" class="<?php p($PAGE->bodyclasses); ?>"> Much like the html tag above we have started writing the body tag and have asked for Moodle to get us the desired ID and classes that should be applied to it.

<?php echo $PAGE->heading; ?>

<?php echo $OUTPUT->login_info(); echo $PAGE->headingmenu; ?>

Here we are creating the header for the page. In this case we want the heading for the page, we want to display the login information which will be the current users username or a link to log in if they are not logged in, and we want the heading menu if there is one.

<?php echo $OUTPUT->blocks_for_region('side-pre') ?> Here we get the HTML to display the blocks that have been added to the page. In this case we have asked for all blocks that have been added to the area labelled side-pre.

<?php echo core_renderer::MAIN_CONTENT_TOKEN ?> This is one of the most important calls within the file, it determines where the actual content for the page gets inserted.

<?php echo $OUTPUT->blocks_for_region('side-post') ?> Here we get the HTML to display the blocks that have been added to the page. In this case we have asked for all blocks that have been added to the area labelled side-post.

<?php echo $OUTPUT->login_info(); echo $OUTPUT->home_link(); echo $OUTPUT->standard_footer_html(); ?> This final bit of code gets the content for the footer of the page. It gets the login information which is the same as in the header, a home link, and the standard footer HTML which like the standard head HTML contains all of the script and style tags required by the page and requested to go in the footer.

Note: Within Moodle 2.0 most of the JavaScript for the page will be included in the footer. This greatly helps reduce the loading time of the page.

When writing layout files think about the different layouts and how the HTML that each makes use of will differ. You will most likely find you do not need a different layout file for each layout, most likely you will be able to reuse the layout files you create across several layouts. You can of course make use of layout options as well to further reduce the number of layout files you need to produce.

Of course as mentioned above if you are customising an existing theme then you may not need to create any layouts or layout files at all.

$OUTPUT is an instance of the core_renderer class which is defined in lib/outputrenderers.php. Each method is clearly documented there, along with which is appropriate for use within the layout files.

$PAGE is an instance of the moodle_page class defined in lib/pagelib.php. Most of the things you will want to use are the properties that are all documented at the top of the file. If you are not familiar with PHP properties, you access them like $PAGE->activityname, just like fields of an ordinary PHP object. (However, behind the scenes, some magic is going on, and the value you get is produced by calling a function. Also, you cannot change these values, they are read-only. However, you don't need to understand all that if you are just using these properties in your theme.)

Making use of images

Right at the start when listing the features of the new themes system one of the features mentioned was the ability to override any of the standard images within Moodle from within your theme. At this point we will look at both how to make use of your own images within your theme, and secondly how to override the images being used by Moodle. So first up a bit about images within Moodle,

  1. Images you want to use within your theme need to be located within your theme's pix directory.
  2. You can use sub directories within the pix directory of your theme.
  3. Images used by Moodle's core are located within the pix directory of Moodle.
  4. Modules, blocks and other plugins should also store there images within a pix directory.

So making use of your own images first up. Lets assume you have added two image files to the pix directory of your theme.

  • /theme/yourthemename/pix/imageone.jpg
  • /theme/yourthemename/pix/subdir/imagetwo.png

Notice that one image is a JPEG image, and the second is a PNG. Also the second image is in a subdirectory.

The following code snippet illustrates how to make use of your images within HTML, such as if you wanted to use them within a layout file. <img src="<?php echo $OUTPUT->pix_url('imageone', 'theme');?>" alt="" /> <img src="<?php echo $OUTPUT->pix_url('subdir/imagetwo', 'theme');?>" alt="" />

DO NOT include the image file extension. Moodle will work it out automatically and it will not work if you do include it.

In this case rather than writing out the URL to the image we use a method of Moodle's output library. Its not too important how that functions works but it is important that we use it as it is what allows images within Moodle to be over-rideable.

The following is how you would use the images from within CSS as background images. .divone {background-image:url(imageone);} .divtwo {background-image:url(subdir/imagetwo);} If this case we have to use some special notations that Moodle looks for. Whenever Moodle hands out a CSS file it first searches for all something tags and replaces them with what is required.

The final thing to notice with both of the cases above is that at no point do we include the images file extension. The reason for this leads us into the next topic, how to override images.

From within a theme you can VERY easily override any standard image within Moodle by simply adding the replacement image to the theme's pix directory in the same sub directory structure as it is in Moodle. So for instance we wanted to override the following two images:

  1. /pix/moodlelogo.gif
  2. /pix/i/user.gif

We would simply need to add our replacement images to the theme in the following locations

  1. /theme/themename/pix/moodlelogo.gif
  2. /theme/themename/pix/i/user.gif

How easy is that!

Now the other very cool thing to mention is that Moodle looks for not just replacements of the same image type (jpg, gif, etc...) but also replacements in any image format. This is why above when working with our images we never specified the images file extension. This means that the following would also work:

  1. /theme/themename/pix/moodlelogo.png
  2. /theme/themename/pix/i/user.bmp

For a more detailed description of how this all works see the page on using images within your theme

Unobvious Things

Getting Your Theme to Appear Correctly in Theme Selector

If you follow the examples on this page to the letter, when you go to the Theme Selector page you may be discouraged to find that your theme does not appear like the other themes do. In fact, instead of your theme's name, you will see something along the lines of [[pluginname]].

To correct this, you must add the /lang/en/theme_THEMENAME.php file, where THEMENAME is the name of the theme folder. Inside that file, add the string "$string['pluginname'] = 'THEMENAME'; ". Make THEMENAME the name of your theme, however you want it displayed in the Theme selector.

The screenshot for the theme should be about 500x400 px.

Required theme divs

Some parts of Moodle may rely on particular divs, for example the div with id 'page-header'.

Consequently all themes must include at least the divs (with the same ids) that are present in the 'base' theme.

Missing out these elements may result in unexpected behaviour within specific modules or other plugins.

Appendix A

Theme options as of April 28th, 2010

Setting Effect
$THEME->csspostprocess Allows the user to provide the name of a function that all CSS should be passed to before being delivered.
$THEME->editor_sheets An array of stylesheets to include within the body of the editor.
$THEME->enable_dock If set to true the side dock is enabled for blocks
$THEME->hidefromselector Used to hide a theme from the theme selector (unless theme designer mode is on). Accepts true or false.
$THEME->filter_mediaplugin_colors Used to control the colours used in the small media player for the filters
$THEME->javascripts An array containing the names of JavaScript files located in /javascript/ to include in the theme. (gets included in the head)
$THEME->javascripts_footer As above but will be included in the page footer.
$THEME->larrow Overrides the left arrow image used throughout Moodle
$THEME->layouts An array setting the layouts for the theme
$THEME->name Name of the theme. Most likely the name of the directory in which this file resides.
$THEME->parents An array of themes to inherit from
$THEME->parents_exclude_javascripts An array of JavaScript files NOT to inherit from the themes parents
$THEME->parents_exclude_sheets An array of stylesheets not to inherit from the themes parents
$THEME->plugins_exclude_sheets An array of plugin sheets to ignore and not include.
$THEME->rarrow Overrides the right arrow image used throughout Moodle
$THEME->renderfactory Sets a custom render factory to use with the theme, used when working with custom renderers.
$THEME->resource_mp3player_colors Controls the colours for the MP3 player
$THEME->sheets An array of stylesheets to include for this theme. Should be located in the theme's style directory.

The different layouts as of August 17th, 2010

Layout Purpose
base Most backwards compatible layout without the blocks - this is the layout used by default.
standard Standard layout with blocks, this is recommended for most pages with general information.
course Main course page.
coursecategory Use for browsing through course categories.
incourse Default layout while browsing a course, typical for modules.
frontpage The site home page.
admin Administration pages and scripts.
mydashboard My dashboard page.
mypublic My public page.
login The login page.
popup Pages that appear in pop-up windows - no navigation, no blocks, no header.
frametop Used for legacy frame layouts only. No blocks and minimal footer.
embedded Embeded pages, like iframe/object embedded in moodleform - it needs as much space as possible
maintenance Used during upgrade and install. This must not have any blocks, and it is good idea if it does not have links to other places - for example there should not be a home link in the footer.
print Used when the page is being displayed specifically for printing.

See also