<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Stephenla</id>
	<title>MoodleDocs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Stephenla"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/Special:Contributions/Stephenla"/>
	<updated>2026-06-07T12:05:11Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Upgrade_API&amp;diff=34389</id>
		<title>Upgrade API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Upgrade_API&amp;diff=34389"/>
		<updated>2012-07-07T17:04:33Z</updated>

		<summary type="html">&lt;p&gt;Stephenla: Corrected typo &amp;quot;does&amp;quot; to &amp;quot;goes&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Upgrade API is how your module installs and upgrades itself, by keeping track of its own version.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
By implementing this API in your plugin, Moodle will automatically create your database tables for you when you visit the Admin notifications page (.../admin/index.php). &lt;br /&gt;
&lt;br /&gt;
This process is controlled by three files within your plugin (there are other optional files you can use for various things. These are covered at the end of this document):&lt;br /&gt;
;[[version.php]] : This records the version of the plugin code (&#039;&#039;&#039;Please note:&#039;&#039;&#039; In Moodle installations below v2.0, this is not required for blocks, which use the version number returned by the block&#039;s init() method - see [[Blocks#Ready.2C_Set.2C_Go.21|the blocks development page]]). You must increase version in version.php after any change in /db/ folder, any change in javascript code and also after any change in language pack because new version triggers upgrade upgrade procedure and resets all caches.&lt;br /&gt;
;db/install.xml : This is used when someone installs your plugin for the first time.&lt;br /&gt;
;db/upgrade.php : This is used when someone who had an older version of your plugin installed upgrades to the latest version.&lt;br /&gt;
&lt;br /&gt;
In addition, Moodle also stores in the database the currently installed version of each plugin.&lt;br /&gt;
&lt;br /&gt;
In Moodle 1.x, this is stored in the mdl_config table, in a row with the name &#039;&#039;plugintype&#039;&#039;_&#039;&#039;pluginname&#039;&#039;_version. For example qtype_myqtype_version. The exception to this rule are modules and blocks. Installed module version numbers are stored in the mdl_modules table. Block version numbers are in mdl_block.&lt;br /&gt;
&lt;br /&gt;
In Moodle 2.x, plugin version numbers are stored in the mdl_config_plugins table, with &#039;&#039;plugintype&#039;&#039;_&#039;&#039;pluginname&#039;&#039; in the plugin column, and &#039;version&#039; in the name column - with the same exception for modules and blocks.&lt;br /&gt;
&lt;br /&gt;
==A specific example==&lt;br /&gt;
&lt;br /&gt;
For the rest of this document, I will use a particular example, because it should make the explanation easier. You should be able to see how to generalise it.&lt;br /&gt;
&lt;br /&gt;
We will suppose you that you are making a new question type myqtype. This is plugin type qtype, and the code will be in the question/type/myqtype folder. The currently installed version number will be stored in the (&#039;qtype_myqtype&#039;, &#039;version&#039;) row of the mdl_config_plugins table.&lt;br /&gt;
&lt;br /&gt;
In addition, we will just consider the first two releases of the plugin. The first release will have version number 2008080100, and will just use one database table mdl_myqtype_options, with two columns col1 and col2. Then we will suppose that the second release is 2008080200, and that requires an extra column, newcol, to be added to the mdl_myqtype_options table.&lt;br /&gt;
&lt;br /&gt;
==The files you need for the first release==&lt;br /&gt;
&lt;br /&gt;
In what follows, the bits of code you need to replace are &#039;&#039;&#039;in bold&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
;version.php&lt;br /&gt;
 $plugin-&amp;gt;version  = 2008080100; // Today&#039;s date in YYYYMMDD format, plus two additional digits&lt;br /&gt;
 $plugin-&amp;gt;requires = &#039;&#039;&#039;XXXXXXXXXX; // Moodle version - copy from $version in the top-level version.php file.&#039;&#039;&#039;&lt;br /&gt;
:Version numbers normally consist of the day&#039;s date in YYYYMMDD format, followed by two additional digits to allow for multiple versions in the same day, e.g. Sept 15, 2010 could have versions 2010091500, 2010091501, 2010091502, etc.&lt;br /&gt;
&lt;br /&gt;
;db/install.xml&lt;br /&gt;
:This file, which you should [[XMLDB editor|create with the XMLDB editor]], should contain the definition for your mdl_myqtype_options table, with the two columns col1 and col2.&lt;br /&gt;
&lt;br /&gt;
At this stage, you do not need a db/upgrade.php file.&lt;br /&gt;
&lt;br /&gt;
==The files you need for the second release==&lt;br /&gt;
&lt;br /&gt;
;version.php&lt;br /&gt;
 $plugin-&amp;gt;version  = 2008080200;&lt;br /&gt;
 $plugin-&amp;gt;requires = &#039;&#039;&#039;XXXXXXXXXX; // Copy the current value from the top-level version.php file.&#039;&#039;&#039;&lt;br /&gt;
;db/install.xml : This file should now contain the updated definition for your mdl_myqtype_options table, with three columns col1, col2 and newcol. You modify this file using the XMLDB editor.&lt;br /&gt;
;db/upgrade.php&lt;br /&gt;
:This file should contain the code that people need to run to upgrade from version 2008080100 of your plugin. That is, the code to add a column newcol to the mdl_myqtype_options table. You don&#039;t have to write this code yourself as the XMLDB editor will generate it for you. The upgrade.php file should contain a single function xmldb_qtype_myqtype_upgrade that looks a bit like:&lt;br /&gt;
 function xmldb_qtype_myqtype_upgrade($oldversion = 0) {&lt;br /&gt;
     global $DB;&lt;br /&gt;
     $dbman = $DB-&amp;gt;get_manager();&lt;br /&gt;
 &lt;br /&gt;
     $result = true;&lt;br /&gt;
 &lt;br /&gt;
     /// Add a new column newcol to the mdl_myqtype_options&lt;br /&gt;
     if ($result &amp;amp;&amp;amp; $oldversion &amp;lt; 2008080200) {&lt;br /&gt;
         &#039;&#039;&#039;// Code to add the column, generated by the &#039;View PHP Code&#039; option of the XMLDB editor.&#039;&#039;&#039;&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     return $result;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Hint: If you are modifying or adding a field/table, get the XMLDB editor to generate the PHP update code for you &#039;&#039;&#039;after&#039;&#039;&#039; making the changes in the editor. If you are deleting one, you need to generate the PHP code &#039;&#039;&#039;before&#039;&#039;&#039; making the change - or you won&#039;t be able to select the field/table to write the code for, because it no longer exists.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==What happens when a user installs or upgrades your plugin==&lt;br /&gt;
&lt;br /&gt;
The process is triggered when an administrator goes to the Admin notifications page (.../admin/index.php). The code that does the work is the upgrade_plugins function in lib/adminlib.php and reading this code is the best way to find out exactly what happens. In pseudo-code, what it does is:&lt;br /&gt;
&lt;br /&gt;
 For each plugin of this type (e.g. all qtype plugins) {&lt;br /&gt;
     // For the body of this loop, suppose the current plugin being processed is myqtype.&lt;br /&gt;
 &lt;br /&gt;
     Check that question/type/myqtype/version.php, .../db/upgrade.php and .../db/install.xml exist.&lt;br /&gt;
 &lt;br /&gt;
     if (get_config(&#039;qtype_myqtype&#039;, &#039;version&#039;) exists, and is less than the number in version.php) {&lt;br /&gt;
         Call the upgrade function xmldb_qtype_myqtype_upgrade from upgrade.php,&lt;br /&gt;
                 passing the old version number that says what is currently installed&lt;br /&gt;
         set_config(&#039;version&#039;, &#039;&#039;latest number from version.php&#039;&#039;, &#039;qtype_myqtype&#039;)&lt;br /&gt;
                 to record what is currently installed&lt;br /&gt;
 &lt;br /&gt;
     } else if (get_config(&#039;qtype_myqtype&#039;, &#039;version&#039;) does not exist) {&lt;br /&gt;
         Create the tables from the definitions in install.xml&lt;br /&gt;
         set_config(&#039;version&#039;, &#039;&#039;latest number from version.php&#039;&#039;, &#039;qtype_myqtype&#039;)&lt;br /&gt;
                 to record what is currently installed&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Of course, it is a bit more complex that than. However, the code in the upgrade_plugins is quite clear, and I encourage you to go and have a look at it so you can see all the details of how it works.&lt;br /&gt;
&lt;br /&gt;
Let us now look at some worked examples:&lt;br /&gt;
&lt;br /&gt;
===User installs version 2008080100 of myqtype===&lt;br /&gt;
&lt;br /&gt;
To start with, the mdl_myqtype_options does not exist, and there will not be a (&#039;qtype_myqtype&#039;, &#039;version&#039;) row in the mdl_config_plugins table.&lt;br /&gt;
&lt;br /&gt;
# The user will unzip myqtype.zip into the question/type folder.&lt;br /&gt;
# The user will visit the Admin notifications page.&lt;br /&gt;
# This will trigger Moodle to search for plugings to upgrade. It will find that the code for the qtype_myqtype plugin is now present, but there is no trace of it in the database, so it will install the plugin from the install.xml file.&lt;br /&gt;
&lt;br /&gt;
At the end of this process, the mdl_myqtype_options table will exist with the two columns col1 and col2; and the (&#039;qtype_myqtype&#039;, &#039;version&#039;) row in the mdl_config_plugins table will contain 2008080100.&lt;br /&gt;
&lt;br /&gt;
===User upgrades from version 2008080100 to version 2008080200 of myqtype===&lt;br /&gt;
&lt;br /&gt;
To start with, the mdl_myqtype_options table will exist with the two columns col1 and col2; and the (&#039;qtype_myqtype&#039;, &#039;version&#039;) row in the mdl_config_plugins table will contain 2008080100.&lt;br /&gt;
&lt;br /&gt;
# The user will delete the old question/type/myqtype folder.&lt;br /&gt;
# The user will unzip the new myqtype.zip into the question/type folder.&lt;br /&gt;
# The user will visit the Admin notifications page.&lt;br /&gt;
# This will trigger Moodle to search for plugings to upgrade. It will find that the code for version 2008080200 the qtype_myqtype plugin is now present, but the installed version of the the database tables (&#039;qtype_myqtype&#039;, &#039;version&#039;) is 2008080100. Therefore, it will call xmldb_qtype_myqtype_upgrade from upgrade.php, passing 2008080100 as the $oldversion argument.&lt;br /&gt;
&lt;br /&gt;
At the end of this process, the mdl_myqtype_options table will now have three columns col1, col2 and newcol; and the (&#039;qtype_myqtype&#039;, &#039;version&#039;) row in the mdl_config_plugins table will contain 2008080200.&lt;br /&gt;
&lt;br /&gt;
===User installs version 2008080200 of myqtype into a clean Moodle install===&lt;br /&gt;
&lt;br /&gt;
To start with, the mdl_myqtype_options does not exist, and there will not be a (&#039;qtype_myqtype&#039;, &#039;version&#039;) row in the mdl_config_plugins table.&lt;br /&gt;
&lt;br /&gt;
# The user will unzip the 2008080200 version of myqtype.zip into the question/type folder.&lt;br /&gt;
# The user will visit the Admin notifications page.&lt;br /&gt;
# This will trigger Moodle to search for plugings to upgrade. It will find that the code for the qtype_myqtype plugin is now present, but there is no trace of it in the database, so it will install the plugin from the install.xml file.&lt;br /&gt;
&lt;br /&gt;
At the end of this process, the mdl_myqtype_options table will exist with three columns col1, col2 and newcol; and the (&#039;qtype_myqtype&#039;, &#039;version&#039;) row in the mdl_config_plugins table will contain 2008080200.&lt;br /&gt;
&lt;br /&gt;
== Upgrade code restrictions ==&lt;br /&gt;
&lt;br /&gt;
Within an upgrade, there are restrictions on the functions your code should call, because the system has not been fully updated.&lt;br /&gt;
&lt;br /&gt;
* All upgrade code can use the basic database API ($DB-&amp;gt;... functions).&lt;br /&gt;
* In a &#039;&#039;&#039;plugin&#039;&#039;&#039;, upgrade code should not call &#039;&#039;&#039;any plugin functions&#039;&#039;&#039;. (For example, if your plugin has a function that changes frog settings to &#039;green&#039;, and you need to do this during upgrade, then you should not call this function; instead, manually update the database rows so that the frog settings become green.) However, you should call core functions rather than making core changes in database.&lt;br /&gt;
* In &#039;&#039;&#039;core&#039;&#039;&#039;, upgrade code should not even call &#039;&#039;&#039;any core functions&#039;&#039;&#039;. (For example, if you need to add a calendar event, this should be done by inserting into a database table rather than calling a function to add the event.)&lt;br /&gt;
&lt;br /&gt;
The reason for this is the state of the system during upgrade.&lt;br /&gt;
&lt;br /&gt;
During core upgrade the state is as follows:&lt;br /&gt;
&lt;br /&gt;
* Core data: &#039;&#039;&#039;Old&#039;&#039;&#039;. &lt;br /&gt;
* Plugin data: &#039;&#039;&#039;Old&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Core functions expect core data to be in the Current state, so it is not safe to call them.&lt;br /&gt;
&lt;br /&gt;
During plugin upgrade the state is as follows:&lt;br /&gt;
&lt;br /&gt;
* Core data: &#039;&#039;&#039;Current&#039;&#039;&#039;. (Because core upgrade runs before plugin upgrade.)&lt;br /&gt;
* Plugin data: &#039;&#039;&#039;Old&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Core functions are now safe to call because the core data is in Current state. But plugin functions, which expect data to be in the Current state, are not safe.&lt;br /&gt;
&lt;br /&gt;
==Summary==&lt;br /&gt;
&lt;br /&gt;
The first time a user installs any version of your plugin, the install.xml file will be used to create all the required database tables. Therefore install.xml should always contain the definition of the up-to-date database structure. Moodle recognises this situation because there is a version.php file on disc, but there is no (&#039;&#039;plugintype&#039;&#039;_&#039;&#039;pluginname&#039;&#039;, version) value in the mdl_config_plugins table.&lt;br /&gt;
&lt;br /&gt;
If the user already had a version of your plugin installed, and then upgrades to a newer version, Moodle will detect this because the version.php file will contain a newer version number than the (&#039;&#039;plugintype&#039;&#039;_&#039;&#039;pluginname&#039;&#039;, version) value in the mdl_config_plugins table. In this case, Moodle will run the code in the upgrade.php file, passing in the old version number, so that the correct bits of upgrade can be run, as controlled by the if ($oldversion &amp;lt; XXXXXXXXXX) blocks of code.&lt;br /&gt;
&lt;br /&gt;
The contents of the install.xml and upgrade.php files should be generated using the XMLDB editor.&lt;br /&gt;
&lt;br /&gt;
==Other things that can be in the db folder==&lt;br /&gt;
&lt;br /&gt;
Of these, only install.php relates to creating the necessary database structure. The other files are mainly about providing the other meta-data that is required when the plugin is installed. I have tried to link to other documentation that goes into detail where possible.&lt;br /&gt;
&lt;br /&gt;
===install.php===&lt;br /&gt;
&lt;br /&gt;
(Moodle 2.0 and later)&lt;br /&gt;
&lt;br /&gt;
If you define a function like xmldb_qtype_myqtype_install(), this PHP code will be executed when your plugin is installed. This is an opportunity to do things that you cannot do with install.xml. It&#039;s executed immediately after the DB schema associated with the component (install.xml) is created.&lt;br /&gt;
&lt;br /&gt;
(Moodle 1.9)&lt;br /&gt;
&lt;br /&gt;
An install function can be defined in lib.php in the root directory of your module. The install function must have the name qtype_install() and takes no arguments (n.b. this is called from lib/adminlib.php after install.xml is parsed)&lt;br /&gt;
&lt;br /&gt;
===uninstall.php===&lt;br /&gt;
&lt;br /&gt;
(Moodle 2.0 and later)&lt;br /&gt;
&lt;br /&gt;
Balancing the previous feature, it&#039;s also possible to define one function like xmldb_qtype_myqtype_uninstall(), that will be executed when your plugin is uninstalled, before dropping its DB schema.&lt;br /&gt;
&lt;br /&gt;
===access.php===&lt;br /&gt;
&lt;br /&gt;
(Moodle 1.7 and later)&lt;br /&gt;
&lt;br /&gt;
Use to define the [[Roles#Capabilities|capabilities]] that this plugin handles with the [[Access API]]. You must increase version in version.php after adding new capabilities.&lt;br /&gt;
&lt;br /&gt;
===events.php===&lt;br /&gt;
&lt;br /&gt;
(Moodle 1.9(?) and later)&lt;br /&gt;
&lt;br /&gt;
Used to define the events this plugin sends to the [[Events_API|Events API]]. You must increase version in version.php after modifying or adding new events.&lt;br /&gt;
&lt;br /&gt;
===log.php===&lt;br /&gt;
&lt;br /&gt;
(Moodle 2.0 and later)&lt;br /&gt;
&lt;br /&gt;
Used to describe the type of log entries that this plugin creates. See the [[Logging API#Mod/*/db/log.php Files| log.php section]] of the [[Logging API]] for more information. You must increase version in version.php after any change.&lt;br /&gt;
&lt;br /&gt;
===messages.php===&lt;br /&gt;
&lt;br /&gt;
(Moodle 2.0 and later)&lt;br /&gt;
&lt;br /&gt;
Used to define the messages this plugin sends through the [[Message API|Messaging API]]. You must increase version in version.php after any change.&lt;br /&gt;
&lt;br /&gt;
===services.php===&lt;br /&gt;
&lt;br /&gt;
(Moodle 2.0 and later)&lt;br /&gt;
&lt;br /&gt;
Used to define the functions and services this plugin publishes through the [[Web services API]]. Usually all those functions are part of the [[External functions API]]. You must increase version in version.php after any change.&lt;br /&gt;
&lt;br /&gt;
===upgradelib.php===&lt;br /&gt;
&lt;br /&gt;
Optional file where upgrade code can be grouped under some &#039;&#039;&#039;helper functions&#039;&#039;&#039; to be used in the upgrade.php file. If needed, this file must be &#039;&#039;&#039;manually required&#039;&#039;&#039; once from upgrade.php. Its main goal is to keep the upgrade.php scripts reduced and clear (this cannot contain any function themselves apart from the xmldb_xxx_upgrade() one).&lt;br /&gt;
&lt;br /&gt;
It&#039;s &#039;&#039;&#039;important&#039;&#039;&#039; to note that the upgradelib.php files should always be performing any task using raw - low level - database access exclusively, &#039;&#039;&#039;avoiding any use of the Moodle APIs&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===mod/.../db/subplugins.php===&lt;br /&gt;
&lt;br /&gt;
(Moodle 2.0 and later)&lt;br /&gt;
&lt;br /&gt;
This only applies to activity modules, not other types of plugin. It is a way to allow an activity module to have its own sorts of plugins. For example workshop allocation schemes, or quiz reports.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Language packs==&lt;br /&gt;
&lt;br /&gt;
Do not forget to increase version number after modifying lang/en/type_yourplugin.php language file. See [[Languages/AMOS]] section AMOS script for more information.&lt;br /&gt;
&lt;br /&gt;
==Upgrade API Cheatsheet==&lt;br /&gt;
&lt;br /&gt;
The Upgrade API is &#039;&#039;&#039;related with a lot&#039;&#039;&#039; of different files and APIs (access, event, log, webservice...) as far as it&#039;s the API used to install/upgrade all those artifacts. The previous sections have tried to list all those dependencies when possible. &lt;br /&gt;
&lt;br /&gt;
Also, the Upgrade API &#039;&#039;&#039;does a very intensive use&#039;&#039;&#039; of other APIs ([[Data definition API|ddl]], [[Data manipulation API|dml]]) and tools (the XMLDB editor...) in order to proceed with the modifications of the Moodle system.&lt;br /&gt;
&lt;br /&gt;
Once stated the above, we could summarise the API as the &#039;&#039;&#039;collection of a few files and functions&#039;&#039;&#039;, here they are:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The files&#039;&#039;&#039;: For each component we can have, under its &amp;quot;db&amp;quot; directory.&lt;br /&gt;
* &#039;&#039;&#039;version.php&#039;&#039;&#039;: Where the $version is specified and, if bumped, the upgrade machinery will be launched and all caches reset. Bump up version after changing /db/, /lang/, theme or JavaScript.&lt;br /&gt;
* &#039;&#039;&#039;install.xml&#039;&#039;&#039;: XMLDB definition of the DB schema. generated with the XMLDB Editor.&lt;br /&gt;
* &#039;&#039;&#039;install.php&#039;&#039;&#039;: Post-install file executed once the schema has been created.&lt;br /&gt;
* &#039;&#039;&#039;uninstall.php&#039;&#039;&#039;: Pre-uninstall file executed before the schema is dropped.&lt;br /&gt;
* &#039;&#039;&#039;upgrade.php&#039;&#039;&#039;: Ordered list of upgrade steps, each one performing a well-defined task. &lt;br /&gt;
* &#039;&#039;&#039;upgradelib.php&#039;&#039;&#039;: Library files composed of helper functions to be used by upgrade.php.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The functions&#039;&#039;&#039;: With different names for different components, but available to all them:&lt;br /&gt;
* &#039;&#039;&#039;xmldb_[main|[[Frankenstyle|frankenstyle]]]_install()&#039;&#039;&#039;: to be used in install.php files.&lt;br /&gt;
* &#039;&#039;&#039;xmldb_[main|frankenstyle]_uninstall()&#039;&#039;&#039;: to be used in uninstall.php files.&lt;br /&gt;
* &#039;&#039;&#039;xmldb_[main|frankenstyle]_upgrade()&#039;&#039;&#039;: to be used in upgrade.php files.&lt;br /&gt;
* &#039;&#039;&#039;upgrade_set_timeout()&#039;&#039;&#039;: to be used within the upgrade steps in upgrade.php files, in order to grant more time to the step.&lt;br /&gt;
* &#039;&#039;&#039;upgrade_[main|mod|block|plugin]_savepoint()&#039;&#039;&#039;: to consider one upgrade step completed and reset timeouts. Avoids double executions.&lt;br /&gt;
&lt;br /&gt;
Of course, for practical examples of the use of this API it&#039;s &#039;&#039;&#039;highly recommended to examine and understand current code&#039;&#039;&#039;. Everything is out there.&lt;br /&gt;
&lt;br /&gt;
==Database upgrades and stable branches==&lt;br /&gt;
&lt;br /&gt;
The simple rule is, never make any database changes on a stable branch. You only need to read this section in the rare situations where a database change on the stable branch is unavoidable.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warning!!! advanced material follows.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Suppose, in order to fix a bug, you need to make a database change in Moodle 1.9.3+ (which must also be merged into HEAD). The root of the problem is that people may upgrade their Moodle in three different ways, which &lt;br /&gt;
&lt;br /&gt;
* Upgrade from &amp;lt;=1.9.3 to 1.9.4 - this executes the ugprade script on the 1.9 branch.&lt;br /&gt;
* Upgrade from &amp;lt;=1.9.3 directly to &amp;gt;=2.0 - this executes the upgrade script on the HEAD branch.&lt;br /&gt;
* Upgrade from 1.9.4 to &amp;gt;=2.0 - in this case, you must ensure that the upgrade on HEAD is not executed.&lt;br /&gt;
&lt;br /&gt;
The normal way to do this is ensure that your database upgrade is idempotent. That is, it does not matter if you do it twice. So for example, instead of doing&lt;br /&gt;
&lt;br /&gt;
        $dbman-&amp;gt;create_table($table);&lt;br /&gt;
&lt;br /&gt;
you should do&lt;br /&gt;
&lt;br /&gt;
        if (!$dbman-&amp;gt;table_exists($table)) {&lt;br /&gt;
            $dbman-&amp;gt;create_table($table);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
You should also think about what version numbers to put in your version.php file on each branch. Above all, test carefully.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Core APIs]]&lt;br /&gt;
* [[XMLDB_Documentation|XMLDB_Documentation]]&lt;br /&gt;
* [[Coding|Coding guidelines]]&lt;br /&gt;
* [[DDL functions|DDL functions]]&lt;br /&gt;
* [[XMLDB defining an XML structure|install.xml file documentation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:XMLDB]]&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
[[Category:Plugins]]&lt;br /&gt;
[[Category:API]]&lt;/div&gt;</summary>
		<author><name>Stephenla</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Themes_overview&amp;diff=17301</id>
		<title>Themes overview</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Themes_overview&amp;diff=17301"/>
		<updated>2010-06-15T01:38:35Z</updated>

		<summary type="html">&lt;p&gt;Stephenla: /* Layouts */  just fixed minor punctuation in text&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}{{Moodle 2.0}}Welcome to the new world of themes within Moodle 2.0!&lt;br /&gt;
&lt;br /&gt;
This document explains how themes work in Moodle and is intended to help you create or modify most themes for Moodle 2.0.&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Moodle themes are responsible for much of the &amp;quot;look&amp;quot; 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.  &lt;br /&gt;
&lt;br /&gt;
A theme can either contain all the definitions (completely stand alone) or it can extend an existing theme with one or more customizations. &lt;br /&gt;
&lt;br /&gt;
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 &amp;quot;parent&amp;quot; (or up the hierarchy of themes) to find one.  It an easy way to achieve just about any look you want for a theme.&lt;br /&gt;
&lt;br /&gt;
==What&#039;s new in 2.0==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Unfortunately it was not possible to maintain backward compatibility, so all Moodle 1.x themes need to be recreated for Moodle 2.0.&lt;br /&gt;
&lt;br /&gt;
Major changes include:&lt;br /&gt;
* Clearer and more consistent CSS classes and IDs throughout all pages in Moodle&lt;br /&gt;
* Introduction of layout files (templates) describing overall layout HTML for many different types of pages in Moodle.&lt;br /&gt;
* Introduction of renderers, which produce the smaller &amp;quot;parts&amp;quot; of a HTML page.  Advanced themes can choose to override these too if they choose.&lt;br /&gt;
* Introduction of standard methods for adding Javascript to themes.&lt;br /&gt;
* Easier control over icons and images in Moodle.&lt;br /&gt;
* The old &amp;quot;standard&amp;quot; theme has been split into two themes:&lt;br /&gt;
**&#039;&#039;&#039;base&#039;&#039;&#039; - contains absolutely basic layout, and&lt;br /&gt;
**&#039;&#039;&#039;standard&#039;&#039;&#039; - which adds CSS to the base theme to make it look like the old standard theme.&lt;br /&gt;
* 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.&lt;br /&gt;
&lt;br /&gt;
==The structure of a theme==&lt;br /&gt;
&lt;br /&gt;
Some important things to know when building good themes:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;config.php&#039;&#039;&#039; - 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. &lt;br /&gt;
# &#039;&#039;&#039;Layouts and layout files&#039;&#039;&#039; -  in config.php there is one definition for each page type (see [[#theme_layouts_table|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&#039;s like a combination of header.html and footer.html).&lt;br /&gt;
# &#039;&#039;&#039;The base theme&#039;&#039;&#039; - 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 &#039;&#039;or&#039;&#039; to Moodle as a whole.  It tries not to make any unnecessary rules and makes as few assumptions as possible.  It&#039;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.&lt;br /&gt;
&lt;br /&gt;
===Files and folders===&lt;br /&gt;
A theme&#039;s files are placed in a folder with under moodle/theme folder and have subfolders. They are laid out like this:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Directory&lt;br /&gt;
! File&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| /config.php&lt;br /&gt;
| Contains all of the configuration and definitions for each theme&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| /lib.php &lt;br /&gt;
| Contains speciality classes and functions that are used by theme&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| /renderers.php &lt;br /&gt;
| Contains any custom renderers for the theme.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| /settings.php &lt;br /&gt;
| 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)&lt;br /&gt;
|-&lt;br /&gt;
| /javascript/ &lt;br /&gt;
| &lt;br /&gt;
| All speciality JavaScript files the theme requires should be located in here.&lt;br /&gt;
|-&lt;br /&gt;
| /lang/ &lt;br /&gt;
| &lt;br /&gt;
| Any special language files the theme requires should be located in here.&lt;br /&gt;
|-&lt;br /&gt;
| /layout/ &lt;br /&gt;
| &lt;br /&gt;
| Contains the layout files for the theme.&lt;br /&gt;
|-&lt;br /&gt;
| /pix/ &lt;br /&gt;
| &lt;br /&gt;
| Contains any images the theme makes use of either in CSS or in the layout files.&lt;br /&gt;
|-&lt;br /&gt;
|  /pix&lt;br /&gt;
| /favicon.ico &lt;br /&gt;
| The favicon to display for this theme.&lt;br /&gt;
|-&lt;br /&gt;
| /pix&lt;br /&gt;
| /screenshot.jpg &lt;br /&gt;
| A screenshot of the theme to be displayed in on the theme selection screen.&lt;br /&gt;
|-&lt;br /&gt;
| /style &lt;br /&gt;
| &lt;br /&gt;
| Default location for CSS files.&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|/*.css&lt;br /&gt;
|CSS files the theme requires&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
There are also several other places that stylesheets can be included from (see the CSS how and why section below).&lt;br /&gt;
&lt;br /&gt;
==Theme options==&lt;br /&gt;
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 &#039;&#039;&#039;[[#theme_options_table|theme options table]]&#039;&#039;&#039; for a complete list of theme options which include lesser used specialised or advanced settings.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Basic theme config example===&lt;br /&gt;
Lets have a look at a basic theme configuration file and the different bits that make it up:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;name = &#039;newtheme&#039;;&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;parents = array(&lt;br /&gt;
    &#039;base&#039;&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&lt;br /&gt;
    &#039;admin&#039;,&lt;br /&gt;
    &#039;blocks&#039;,&lt;br /&gt;
    &#039;calendar&#039;,&lt;br /&gt;
    &#039;course&#039;,&lt;br /&gt;
    &#039;grade&#039;,&lt;br /&gt;
    &#039;message&#039;,&lt;br /&gt;
    &#039;question&#039;,&lt;br /&gt;
    &#039;user&#039;&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;theme&#039; =&amp;gt; &#039;newtheme&#039;,&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;standard&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;theme&#039; =&amp;gt; &#039;newtheme&#039;,&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    )&lt;br /&gt;
    //.......&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;javascripts_footer = array(&lt;br /&gt;
    &#039;navigation&#039;&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Basic theme example settings explained===&lt;br /&gt;
First up you will notice everything is added to $THEME. This is the theme&#039;s configuration object, it is created by Moodle using default settings and is then updated by whatever settings you add to it.&lt;br /&gt;
&lt;br /&gt;
The first setting, $THEME-&amp;gt;name is the theme&#039;s name. This should simply be whatever your theme&#039;s name is, most likely whatever you named your theme directory.&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;parents defines the themes that the theme will extend. In this case it is extending only the base theme.&lt;br /&gt;
&lt;br /&gt;
After this is the $THEME-&amp;gt;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&#039;s stylesheets will be located in the styles directory of the theme and have .css as an extension.&lt;br /&gt;
&lt;br /&gt;
Next we see the $THEME-&amp;gt;layouts definition. In this example, two layouts have been defined to override the layouts from the base theme. For more information see the [[#Layouts|layouts]] section below.&lt;br /&gt;
&lt;br /&gt;
The final setting is to include a JavaScript file, as $THEME-&amp;gt;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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note&#039;&#039;&#039;&#039;&#039;: 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.&lt;br /&gt;
&lt;br /&gt;
==CSS==&lt;br /&gt;
===Locations of CSS files===&lt;br /&gt;
First lets look at where CSS can be included from within Moodle:&lt;br /&gt;
; \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.&lt;br /&gt;
&lt;br /&gt;
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&#039;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&#039;s CSS rules/definitions have the last say.&lt;br /&gt;
&lt;br /&gt;
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 aware of but not have to worry about these locations of CSS files.  Here are some examples:&lt;br /&gt;
&lt;br /&gt;
; {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.&amp;lt;br /&amp;gt;Theme specific styles for a plugin should be located within the themes styles directory.&lt;br /&gt;
; {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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Moodle&#039;s core CSS organisation===&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
First is the  pagelayout.css file. This contains the CSS required to give the layouts their look and feel.  It doesn&#039;t contain any rules that affect the content generated by Moodle.&lt;br /&gt;
&lt;br /&gt;
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&#039;t relate to a specific section of Moodle but to Moodle as a whole.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
:For those who are familiar with Moodle 1.9 theme&#039;s, this organisation will be a big change. In 1.9, CSS was organised by its nature (for example: colours, layout, other).&lt;br /&gt;
&lt;br /&gt;
===How to write effective CSS rules within Moodle===&lt;br /&gt;
In Moodle 2.0, writing good CSS rules is an incredibly important.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
====The body tag====&lt;br /&gt;
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 &#039;/mod/forum/view.php&#039; then the body tags ID will be &#039;#page-mod-forum-view&#039;.&lt;br /&gt;
&lt;br /&gt;
As well as the body&#039;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 &#039;/mod/forum/view&#039; you would end up with the following classes being added to the body tag &#039;.path-mod&#039;, &#039;.path-mod-forum&#039;. Note that &#039;.path-mod-forum-view&#039; 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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
* If JavaScript is enabled then &#039;jsenabled&#039; will be added as a class to the body tag allowing you to style based on JavaScript being enabled or not.&lt;br /&gt;
* Either &#039;dir-rtl&#039; or &#039;dir-ltr&#039; 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.&lt;br /&gt;
* 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 &#039;lang-en_utf8&#039; being added to the body tag.&lt;br /&gt;
* 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 &#039;.sam-moodle-local—moodle&#039;&lt;br /&gt;
* If the current user is not logged then &#039;.notloggedin&#039; will be added to the body tag.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;code html4strict&amp;gt;&amp;lt;body id=”page-mod-forum-view” class=”path-mod path-mod-forum” /&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Writing your rules====&lt;br /&gt;
The best use of body ids and classes and writing selectors will reduce problems.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
If you want to write a rule for a specific page make use of the body tag&#039;s ID, e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;#page-mod-forum-view .forumpost {border:1px solid orange;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to write a rule that will be applied all throughout the forum.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.path-mod-forum .forumpost {border:1px solid orange;}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
By making use of body id&#039;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.&lt;br /&gt;
&lt;br /&gt;
==Layouts==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
So layouts... as mentioned earlier layouts are defined in config.php within $THEME-&amp;gt;layouts. The following is an example of one such layout definition:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Standard layout with blocks, this is recommended for most pages with general information&lt;br /&gt;
    &#039;standard&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;theme&#039; =&amp;gt; &#039;base&#039;,&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
; theme : is the theme the layout file exists in. That&#039;s right you can make use of layouts from other installed themes.&lt;br /&gt;
; file : is the name of the layout file this layout wants to use.&lt;br /&gt;
; regions : is the different block regions (places you can put blocks) within the theme.&lt;br /&gt;
; defaultregion : is the default location when adding new blocks.&lt;br /&gt;
; options : an array of layout specific options described in detail below.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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 &#039;&#039;&#039;nonavbar&#039;&#039;&#039; and &#039;&#039;&#039;nofooter&#039;&#039;&#039; 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:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$hasnavbar = (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar());&lt;br /&gt;
$hasfooter = (empty($PAGE-&amp;gt;layout_options[&#039;nofooter&#039;]));&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
............&lt;br /&gt;
&amp;lt;?php if ($hasnavbar) { ?&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;navbar clearfix&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;breadcrumb&amp;quot;&amp;gt;&amp;lt;?php echo $OUTPUT-&amp;gt;navbar(); ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;navbutton&amp;quot;&amp;gt; &amp;lt;?php echo $PAGE-&amp;gt;button; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Layout files==&lt;br /&gt;
A layout file is a file that contains the core HTML structure for a layout including the header, footer, content and block regions.&lt;br /&gt;
For those of you who are familiar with themes in Moodle 1.9 this is simply header.html and footer.html combined.&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
The following is a very simple layout file to illustrate the different bits that make it up:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;doctype() ?&amp;gt;&lt;br /&gt;
&amp;lt;html &amp;lt;?php echo $OUTPUT-&amp;gt;htmlattributes() ?&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;title ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;?php echo $OUTPUT-&amp;gt;standard_head_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyid ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyclasses; ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_top_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;table id=&amp;quot;page&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
        &amp;lt;td colspan=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;h1 class=&amp;quot;headermain&amp;quot;&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;heading ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;headermenu&amp;quot;&amp;gt;&amp;lt;?php echo $OUTPUT-&amp;gt;login_info(); echo $PAGE-&amp;gt;headingmenu; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-pre&#039;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-post&#039;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
        &amp;lt;td colspan=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;p class=&amp;quot;helplink&amp;quot;&amp;gt;&amp;lt;?php echo page_doc_link(get_string(&#039;moodledocslink&#039;)) ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
            &amp;lt;?php&lt;br /&gt;
            echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
            echo $OUTPUT-&amp;gt;home_link();&lt;br /&gt;
            echo $OUTPUT-&amp;gt;standard_footer_html();&lt;br /&gt;
            ?&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_end_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lets assume you know a enough HTML to understand the basic structure above, what you probably don&#039;t understand are the PHP calls so lets look at them.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;doctype() ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;html &amp;lt;?php echo $OUTPUT-&amp;gt;htmlattributes() ?&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $PAGE-&amp;gt;title ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This gets us the title for the page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_head_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyid; ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyclasses; ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;h1 class=&amp;quot;headermain&amp;quot;&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;heading; ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;headermenu&amp;quot;&amp;gt;&amp;lt;?php echo $OUTPUT-&amp;gt;login_info(); echo $PAGE-&amp;gt;headingmenu; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-pre&#039;) ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
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 &#039;&#039;side-pre&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is one of the most important calls within the file, it determines where the actual content for the page gets inserted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-post&#039;) ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
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 &#039;&#039;side-post&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
echo $OUTPUT-&amp;gt;home_link();&lt;br /&gt;
echo $OUTPUT-&amp;gt;standard_footer_html();&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note&#039;&#039;&#039;&#039;&#039;: 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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==Making use of images==&lt;br /&gt;
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.&lt;br /&gt;
So first up a bit about images within Moodle,&lt;br /&gt;
&lt;br /&gt;
# Images you want to use within your theme &#039;&#039;&#039;need&#039;&#039;&#039; to be located within your theme&#039;s pix directory.&lt;br /&gt;
# You can use sub directories within the pix directory of your theme.&lt;br /&gt;
# Images used by Moodle&#039;s core are located within the pix directory of Moodle.&lt;br /&gt;
# Modules, blocks and other plugins should also store there images within a pix directory.&lt;br /&gt;
&lt;br /&gt;
So making use of your own images first up. Lets assume you have added two image files to the pix directory of your theme.&lt;br /&gt;
&lt;br /&gt;
* /theme/yourthemename/pix/imageone.jpg&lt;br /&gt;
* /theme/yourthemename/pix/subdir/imagetwo.png&lt;br /&gt;
&lt;br /&gt;
Notice that one image is a JPEG image, and the second is a PNG. Also the second image is in a subdirectory.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;&amp;lt;?php echo $OUTPUT-&amp;gt;pix_url(&#039;imageone&#039;, &#039;theme&#039;);?&amp;gt;&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt; &lt;br /&gt;
&amp;lt;img src=&amp;quot;&amp;lt;?php echo $OUTPUT-&amp;gt;pix_url(&#039;subdir/imagetwo&#039;, &#039;theme&#039;);?&amp;gt;&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt; &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
In this case rather than writing out the URL to the image we use a method of Moodle&#039;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.&lt;br /&gt;
&lt;br /&gt;
The following is how you would use the images from within CSS as background images.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
.divone {background-image:url([[pix:theme|imageone]]);}&lt;br /&gt;
.divtwo {background-image:url([[pix:theme|subdir/imagetwo]]);}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
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 &#039;&#039;[[something]]&#039;&#039; tags and replaces them with what is required.&lt;br /&gt;
&lt;br /&gt;
The final thing to notice with both of the cases above is that at no point do we include the images file extension. &lt;br /&gt;
The reason for this leads us into the next topic, how to override images.&lt;br /&gt;
&lt;br /&gt;
From within a theme you can VERY easily override any standard image within Moodle by simply adding the replacement image to the theme&#039;s pix directory in the same sub directory structure as it is in Moodle.&lt;br /&gt;
So for instance we wanted to override the following two images:&lt;br /&gt;
# /pix/moodlelogo.gif&lt;br /&gt;
# /pix/i/user.gif&lt;br /&gt;
We would simply need to add our replacement images to the theme in the following locations&lt;br /&gt;
# /theme/themename/pix/moodlelogo.gif&lt;br /&gt;
# /theme/themename/pix/i/user.gif&lt;br /&gt;
How easy is that!&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
This means that the following would also work:&lt;br /&gt;
# /theme/themename/pix/moodlelogo.png&lt;br /&gt;
# /theme/themename/pix/i/user.bmp&lt;br /&gt;
&lt;br /&gt;
For a more detailed description of how this all works see the page on [[Themes_2.0_How_to_use_images_within_your_theme|using images within your theme]]&lt;br /&gt;
&lt;br /&gt;
==Appendix A==&lt;br /&gt;
===Theme options as of April 28th, 2010===&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot; id=&amp;quot;theme_options_table&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting&lt;br /&gt;
! Effect&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;csspostprocess&#039;&#039;&#039;&lt;br /&gt;
|  Allows the user to provide the name of a function that all CSS should be passed to before being delivered.&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;editor_sheets&#039;&#039;&#039;&lt;br /&gt;
|  An array of stylesheets to include within the body of the editor.&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;enable_dock&#039;&#039;&#039;&lt;br /&gt;
|  If set to true the side dock is enabled for blocks&lt;br /&gt;
|-&lt;br /&gt;
| $THEME-&amp;gt;&#039;&#039;&#039;hidefromselector&#039;&#039;&#039;&lt;br /&gt;
| Used to hide a theme from the theme selector (unless theme designer mode is on). Accepts true or false.&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;filter_mediaplugin_colors&#039;&#039;&#039;&lt;br /&gt;
|  Used to control the colours used in the small media player for the filters&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;javascripts&#039;&#039;&#039;&lt;br /&gt;
|  An array containing the names of JavaScript files located in /javascript/ to include in the theme. (gets included in the head)&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;javascripts_footer&#039;&#039;&#039;&lt;br /&gt;
|  As above but will be included in the page footer.&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;larrow&#039;&#039;&#039;&lt;br /&gt;
|  Overrides the left arrow image used throughout Moodle&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;layouts&#039;&#039;&#039;&lt;br /&gt;
|  An array setting the layouts for the theme&lt;br /&gt;
|-&lt;br /&gt;
| $THEME-&amp;gt;&#039;&#039;&#039;name&#039;&#039;&#039;&lt;br /&gt;
| Name of the theme. Most likely the name of the directory in which this file resides.&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;parents&#039;&#039;&#039;&lt;br /&gt;
|  An array of themes to inherit from&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;parents_exclude_javascripts&#039;&#039;&#039;&lt;br /&gt;
|  An array of JavaScript files NOT to inherit from the themes parents&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;parents_exclude_sheets&#039;&#039;&#039;&lt;br /&gt;
|  An array of stylesheets not to inherit from the themes parents&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;plugins_exclude_sheets&#039;&#039;&#039;&lt;br /&gt;
|  An array of plugin sheets to ignore and not include.&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;rarrow&#039;&#039;&#039;&lt;br /&gt;
|  Overrides the right arrow image used throughout Moodle&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;renderfactory&#039;&#039;&#039;&lt;br /&gt;
|  Sets a custom render factory to use with the theme, used when working with custom renderers.&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;resource_mp3player_colors&#039;&#039;&#039;&lt;br /&gt;
|  Controls the colours for the MP3 player&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;sheets&#039;&#039;&#039;&lt;br /&gt;
|  An array of stylesheets to include for this theme. Should be located in the theme&#039;s style directory.&lt;br /&gt;
|}&lt;br /&gt;
===The different layouts as of March 29th, 2010===&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot; id=&amp;quot;theme_layouts_table&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Layout&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| base&lt;br /&gt;
| Most backwards compatible layout without the blocks - this is the layout used by default.&lt;br /&gt;
|- &lt;br /&gt;
| standard&lt;br /&gt;
| Standard layout with blocks, this is recommended for most pages with general information.&lt;br /&gt;
|- &lt;br /&gt;
| course&lt;br /&gt;
| Main course page.&lt;br /&gt;
|- &lt;br /&gt;
| coursecategory&lt;br /&gt;
| Use for browsing through course categories.&lt;br /&gt;
|- &lt;br /&gt;
| incourse&lt;br /&gt;
| Default layout while browsing a course, typical for modules.&lt;br /&gt;
|- &lt;br /&gt;
| frontpage&lt;br /&gt;
| The site home page.&lt;br /&gt;
|- &lt;br /&gt;
| admin&lt;br /&gt;
| Administration pages and scripts.&lt;br /&gt;
|- &lt;br /&gt;
| mydashboard&lt;br /&gt;
| My dashboard page.&lt;br /&gt;
|- &lt;br /&gt;
| mypublic&lt;br /&gt;
| My public page.&lt;br /&gt;
|- &lt;br /&gt;
| login&lt;br /&gt;
| The login page.&lt;br /&gt;
|-&lt;br /&gt;
| popup&lt;br /&gt;
| Pages that appear in pop-up windows - no navigation, no blocks, no header.&lt;br /&gt;
|-&lt;br /&gt;
| frametop&lt;br /&gt;
| Used for legacy frame layouts only. No blocks and minimal footer.&lt;br /&gt;
|-&lt;br /&gt;
| embedded&lt;br /&gt;
| Embeded pages, like iframe/object embedded in moodleform - it needs as much space as possible&lt;br /&gt;
|-&lt;br /&gt;
| maintenance&lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Themes 2.0 creating your first theme]] - A quick step by step guide to creating your first theme.&lt;br /&gt;
* [[Themes 2.0 overriding a renderer]] - A tutorial on creating a custom renderer and changing the HTML Moodle produces.&lt;br /&gt;
* [[Themes 2.0 How to use images within your theme]] - Explains how to use and override images within your theme.&lt;br /&gt;
* [[Themes 2.0 adding a settings page]] - Looks at how to add a setting page making your theme easily customisable.&lt;br /&gt;
* [[Styling_and_customising_the_dock]] - How to style and customise the dock.&lt;br /&gt;
* [[Theme changes in 2.0]]&lt;br /&gt;
* [[Using jQuery with Moodle 2.0]]&lt;/div&gt;</summary>
		<author><name>Stephenla</name></author>
	</entry>
</feed>