Actions

Difference between revisions of "Customising/Themes/1.10"

From Mahara Wiki

< Customising‎ | Themes
Line 73: Line 73:
 
===== Should you put plugin assets under the plugin, or the theme? =====
 
===== Should you put plugin assets under the plugin, or the theme? =====
  
As you have no doubt noted in the above discussion, with plugin assets you have a choice. You can place them under the plugin (<code>htdocs/{plugintype}/{pluginname}/theme/{themename}/</code>) or under the theme (<code>htdocs/theme/{themename}/{plugintype}/{pluginname}/</code>). So which should you use? It depends on what you're doing.
+
As you have no doubt noted in the above discussion, with plugin assets you have a choice. You can place them under the plugin (<code>htdocs/{plugintype}/{pluginname}/theme/{themename}/</code>) or under the theme (<code>htdocs/theme/{themename}/{plugintype}/{pluginname}/</code>). So which should you use? It's pretty straightforward:
  
If you are writing a '''custom theme''', then you should put the code under the '''theme''' directory. Then if you distribute your theme to others, they'll already have all the files for it, all in one place. It is okay if your theme includes files for 3rd-party plugins that they don't have installed; these will be safely ignored. Upgrading your Mahara site will also be easier if you keep your assets under the theme directory, because it means there is less chance of accidentally overwriting them since they are all in one place.
+
1. If you're writing a '''custom theme''', then you should put the assets under the '''theme''' directory. Then if you distribute your theme to others, they'll already have all the files for it, all in one place. It is okay if your theme includes files for 3rd-party plugins that they don't have installed; these will be safely ignored.
 +
 
 +
2. If you are writing a 3rd-party '''plugin''', then you should put the assets under the '''plugin''' directory. Then if you distribute your plugin to others, they'll already have all the files for it. Your plugin should support the "raw" theme at least, and it may include support for other themes you think your users are likely to have. If it includes support for themes they haven't installed, these will be safely ignored.
 +
 
 +
3. If you're writing a theme ''or'' plugin to '''upstream''' into Mahara's standard distribution, then you should put the assets under the '''theme''' directory. This helps keep all the theme information centralized in one place where it's easier for theme designers to locate and work with.
  
 
===== Blocks that live inside artefacts =====
 
===== Blocks that live inside artefacts =====

Revision as of 18:52, 17 June 2014

This page is about Themes in Mahara version '1.10' and later.

For information about Themes in earlier Mahara versions see Customising/Themes

Overview

Mahara reads theme configuration files from htdocs/theme/{$themename}/themeconfig.php. The standard Mahara distribution comes with several themes pre-installed. If new theme directories are placed under htdocs/theme, with a themeconfig.php, they will appear for selection on the Site Options page in the Admin section.

Assets: Templates & Static

The main thing that a theme provides, is a set of Dwoo templates, and a set of static, which are mostly images and stylesheets. The Dwoo templates are used by Mahara's Dwoo templating system to display each page. So in theory, a theme author, by rewriting the templates, can rewrite nearly the entirety of Mahara's behavior. Although in practice, most themes do no more than rearranging the order of items in the templates.

Core assets

Templates for Mahara core are stored in htdocs/theme/{$themename}/templates, stylesheets are stored in htdocs/theme/{$themename}/static/style, and images in htdocs/theme/{$themename}/static/images.

The directory structure under htdocs/theme/{$themename}/templates mostly mirrors the structure of the php pages on the site, so for example, the page template used on the page htdocs/admin/site/options.php is found in htdocs/theme/default/templates/admin/site/options.tpl. However this is not a strict rule; some pages in different folders may share a template, and some templates don't belong to a particular page, but are included by other templates.

If you're a theme designer you don't really need to know how to use these, but just in case, here's how:

Templates are referred to by their relative path within the theme's "templates" directory. For instance, the template located at htdocs/theme/raw/templates/artefact/artefact.tpl would be to referred to as 'artefact/artefact.tpl'. Mahara then uses theme inheritance to decide which copy of the template it should use (see the section on inheritance below).

In PHP, this is usually as part of a call to $smarty->fetch:

$smarty->fetch('artefact/artefact.tpl');

In Dwoo, templates can be embedded into the current template using the {include} tag.

{include file="artefact/artefact.tpl"}

Static assets are located by a call to the $THEME->get_url() method of the global $THEME object. As with templates, they're referred to by their relative path within the theme's "static" directory. For instance the image file htdocs/mahara/theme/raw/static/images/site-logo.png would be referred to as "images/site-logo.png". There is no method to directly access these in Dwoo, so you'll need to get the URL in PHP and assign it to a Dwoo variable to be used in the template.

global $THEME;
$url = $THEME->get_url('images/site-logo.png');

$smarty->fetch('test.tpl');
$smarty->assign('url', $url);

Plugin assets

Plugins can also have their own templates, stylesheets, and images, which are only used by that plugin. For instance, the "My Files" page, htdocs/artefact/file/index.php, has its own template, "index.tpl". They can also contain their own static assets, for instance the Creative Commons block contains an image of the Creative Commons logo.

The location of plugin assets is a little bit more complex. They can actually live under the htdocs/theme directory or under the plugin's own directory (e.g. artefact/file). Mahara will look for the file first under the theme directory, and if it doesn't find it there it will look for it under the plugin's directory.

As of Mahara 1.10 the preferred place to put plugin assets, is in a subdirectory under the theme itself. This should have the form htdocs/theme/{themename}/{plugintype}/{pluginname}. So for instance the file artefact's "index.tpl" file should go under htdocs/theme/{themename}/artefact/file/templates/index.tpl. And the Creative Commons block's "seal.png" image should go under htdocs/theme/{themename}/blocktype/creativecommons/static/images/seal.png

Plugins assets can also live under the plugin's own directory. This is useful if you're distributing a plugin that is not part of the standard Mahara distribution, and you want it to include its own assets. In this case, the file artefact's "index.tpl" would go at htdocs/file/artefact/theme/{themename}/templates/index.tpl, and the Creative Commons block's "seal.png" image would go at htdocs/blocktype/creativecommons/theme/{themename}/static/images/seal.png. Note that the theme name is still part of the path! This is to allow a plugin to support a different appearance in different themes right out of the box. If you don't care about that, just use "raw" as the themename (see the inheritance section below)

Plugin template files are referenced as "{plugintype}:{pluginname}:path/to/template.tpl". For instance the file artefact's index.tpl file is "artefact:file:index.tpl". With this prefix in place, they're referred to exactly the same as normal templates.

$smarty->fetch('artefact:file:index.tpl');
{include file='artefact:file:index.tpl');

Plugin static assets are located using the $THEME->get_url() method's optional third parameter, which takes a plugin's relative path, in the form "{plugintype}/{pluginname}". (The 2nd parameter, which defaults to false, indicates whether to return the 1st match or all matches. In most cases it makes sense to leave it false.)

$THEME->get_url('seal.png', false, 'blocktype/creativecommons');

Note: In Mahara 1.9 and earlier, plugin assets were required to be located under the plugin's own directory, and were not looked for under the htdocs/theme directory. Also, there was no "templates" subdirectory in the path to the plugin's templates. Instead, the templates sat directly under the "{themename}" directory. For example: htdocs/artefact/file/theme/{themename}/index.tpl instead of htdocs/artefact/file/theme/templates/index.tpl. For backwards-compatibily reasons, Mahara 1.10 will still check for templates in this location as well, but it is further down the search path than the "templates" directory.

Should you put plugin assets under the plugin, or the theme?

As you have no doubt noted in the above discussion, with plugin assets you have a choice. You can place them under the plugin (htdocs/{plugintype}/{pluginname}/theme/{themename}/) or under the theme (htdocs/theme/{themename}/{plugintype}/{pluginname}/). So which should you use? It's pretty straightforward:

1. If you're writing a custom theme, then you should put the assets under the theme directory. Then if you distribute your theme to others, they'll already have all the files for it, all in one place. It is okay if your theme includes files for 3rd-party plugins that they don't have installed; these will be safely ignored.

2. If you are writing a 3rd-party plugin, then you should put the assets under the plugin directory. Then if you distribute your plugin to others, they'll already have all the files for it. Your plugin should support the "raw" theme at least, and it may include support for other themes you think your users are likely to have. If it includes support for themes they haven't installed, these will be safely ignored.

3. If you're writing a theme or plugin to upstream into Mahara's standard distribution, then you should put the assets under the theme directory. This helps keep all the theme information centralized in one place where it's easier for theme designers to locate and work with.

Blocks that live inside artefacts

One thing to note in all this is that blocktypes can live under artefact types. For instance, the "Tagged Journal Entries" block lives inside the "Journal" artefact, at htdocs/artefact/blog/blocktype/taggedposts.

When you store such a block's assets under the htdocs/theme directory, you should include the parent artefact in the path, like so: htdocs/theme/{themename}/artefact/blog/blocktype/taggedposts/static/images/thumb.png

Templates for these blocktypes just need to mention the blocktype name, like $smarty->fetch('blocktype:comment:comment.tpl');

Static assets for these blocktypes use a pluginpath that has the artefact name in it, like $THEME->get_url('thumb.png', false, 'artefact/blog/blocktype/taggedposts');

Export code that lives under artefacts

Artefact plugins can include an "export" subdirectory, in which they have subplugins that provides compatibility with specific export plugins. For instance htdocs/artefact/file/export/html/ contains code that supports the "html" export plugin, for the "file" artefact.

These export compatibility subplugins can have their own theme assets. If they live under the htdocs/theme directory they should go in htdocs/theme/{themename}/artefact/{artefacttype}/export/{exporttype}. If they live under the artefact's own directory they should go in htdocs/artefact/{artefacttype}/export/{exporttype}/theme/{themename}.

Artefact export subplugins are referred to in dwoo as "export:{exporttype}/{artefacttype}:path/to/template.tpl". For instance "export:html/file:summary.tpl".

Artefact export subplugins don't have any static assets, except for optional stylesheets called "style.css" and "print.css" used by the html export plugin which should be located at htdocs/artefact/{artefacttype}/export/html/theme/{themename}/static/style/. These are looked for directly by the "html" export plugin, and cannot be accessed by $THEME->get_url() or $THEME->get_path(). Unlike all other plugin assets, these stylesheets must be located under the plugin's own directory.

Inheritance

A theme may specify a parent theme in its themeconfig.php file. If it leaves this out, the special "Raw" theme will be its parent. Both the parent and child stylesheets will be served up (in that order, so the child will override the parent). Also, specific pages can require their own additional stylesheets, and in these cases the additional stylesheets from both the parent and child are served.

For example, the artefact/file plugin has its own extra stylesheets. If a user's theme is "Default", which has a parent theme of "Raw", then the user will retrieve the following stylesheets on the My Files page:

theme/raw/static/style/style.css
theme/default/static/style/style.css
artefact/file/theme/raw/static/style/style.css
artefact/file/theme/default/static/style/style.css

This gives us lots of flexibility but unfortunately browsers can end up doing a lot of stylesheet requests this way.

Of the six pre-installed themes, the "Raw" theme is special and is used as the parent theme by all the others. Because of this, we have been able to keep the majority of the layout in the Raw theme css, and the other themes' stylesheets are much smaller because they mostly just override colours.

The child themes specify their own images, but we have been able to implement them without overriding any of the templates. They are a good place to look when getting started with a new theme.

We recommend using "Raw" as a parent for all new themes.

Creating a new theme for Mahara 1.10

  1. Create a new directory in the theme/ subdirectory (e.g. theme/ponies or similar)
  2. Copy the themeconfig.php from the default theme directory to your new directory
  3. Edit your themeconfig.php, and add a name for your theme in the $theme->displayname line.

From then on, you will have created a new theme that inherits from the raw theme. What this means is, when Mahara needs a theme file (image, CSS file or template), it will look for it in your theme's directory, and if it can't find it there it will use the one in raw/.

To override images, create a static/images directory under your theme directory. For example, to change the site logo, put a site-logo.png in theme/ponies/static/images, and this will change the site logo for the ponies theme.

You can do the same with static/style/*.css - those stylesheets will be included on the page after the parent theme's ones, so you just need to override rules you want to change.

You will probably also want to override some of the standard plugin stylesheets too. For example, if you want to change the look of the forums, the stylesheet used by the raw theme is in interaction/forum/theme/raw/static/style/style.css. To override these rules, you need to create new directories under interaction/forum/theme for your theme. So if the directory you created in step 1 was theme/ponies/, you would create the set of directories interaction/forum/theme/ponies/static/style/ and add a style.css in there, with the styles needed to override those contained in interaction/forum/theme/raw/static/style/style.css.

We hope that in most cases, theme authors won't need to create new templates, or make copies of templates from the raw theme into their new themes; a lot of the work can be done just by overriding default styles in the new theme's stylesheets.

Dwoo

Mahara moved to uses Dwoo, a fork of Smarty, as its backend templating engine. Developers familiar with Smarty should also read Differences between Smarty and Dwoo

Local theme overrides

You can also place template files in your /local directory, and they will be placed in the template search path, and used if the current theme does not have a matching template. They should go under local/theme/templates/.