<?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=Tqr</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=Tqr"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/Special:Contributions/Tqr"/>
	<updated>2026-04-12T13:19:37Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Templates&amp;diff=54276</id>
		<title>Templates</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Templates&amp;diff=54276"/>
		<updated>2018-05-23T21:01:08Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* An example: tabs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.9}}&lt;br /&gt;
&lt;br /&gt;
= Templates =&lt;br /&gt;
&lt;br /&gt;
== What is a template? ==&lt;br /&gt;
A template is an alternative to writing blocks of HTML directly in javascript / php by concatenating strings. The end result is the same, but templates have a number of advantages:&lt;br /&gt;
* It is easier to see the final result of the template because the code for a template is very close to what the final HTML will look like&lt;br /&gt;
* Because the templating language is intentionally limited, it is hard to introduce complex logic into a template. This makes it far easier for a theme designer to override a template, without breaking the logic&lt;br /&gt;
* Templates can be rendered from javascript. This allows ajax operations to re-render a portion of the page.&lt;br /&gt;
&lt;br /&gt;
== How do I write a template? ==&lt;br /&gt;
Templates are written in a language called &amp;quot;[http://mustache.github.io/mustache.5.html Mustache]&amp;quot;. Mustache is written as HTML with additional tags used to format the display of the data. Mustache tags are made of 2 opening and closing curly braces &amp;lt;code xml&amp;gt;{{tag}}&amp;lt;/code&amp;gt;. There are a few variations of these tags that behave differently.&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{raiden}}&amp;lt;/code&amp;gt; This is a simple variable substitution. The variable named &amp;quot;raiden&amp;quot; will be searched for in the current context (and any parent contexts) and when a value is found, the entire tag will be replaced by the variable (HTML escaped).&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{{galaga}}}&amp;lt;/code&amp;gt; This is an unescaped variable substitution. Instead of escaping the variable before replacing it in the template, the variable is included raw. This is useful when the variable contains a block of HTML (for example).&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{#lemmings}} jump off cliff {{/lemmings}}&amp;lt;/code&amp;gt; These are opening and closing section tags. If the lemmings variable exists and evaluates to &amp;quot;not false&amp;quot; value, the variable is pushed on the stack, the contents of the section are parsed and included in the result. If the variable does not exist, or evaluates to false - the section will be skipped. If the variable lemmings evaluates to an array, the section will be repeated for each item in the array with the items of the array on the context. This is how to output a list.&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{^lemmings}} enjoy view {{/lemmings}}&amp;lt;/code&amp;gt; Equivalent of &amp;quot;if-not&amp;quot; block, there is no &amp;quot;else&amp;quot; in mustache.&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{&amp;gt; franken_style/name_of_template }}&amp;lt;/code&amp;gt; This is a partial. Think of it like an include. Templates can include other templates using this tag. In the called template, the data it sees (for including values is the same as the data available where the partial is included.&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{$blockvar}} ... {{/blockvar}}&amp;lt;/code&amp;gt; This is a block variable. It defines a section of the template that can be overridden when it&#039;s included in another template.&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{&amp;lt; template_name}} ... {{/template_name}}&amp;lt;/code&amp;gt; This is similar to including a partial but specifically indicates that you&#039;d like to override one or more block variables defined within the template you&#039;re including. You can override the block variables by defining a block variable within these tags that matches the name of the block variable you&#039;d like to override in the included template.&lt;br /&gt;
&lt;br /&gt;
So - putting this all together:&lt;br /&gt;
&lt;br /&gt;
recipe.mustache&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;{{recipename}}&amp;lt;/h3&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;{{description}}&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;Ingredients&amp;lt;/h4&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
{{#ingredients}}&lt;br /&gt;
&amp;lt;li&amp;gt;{{.}}&amp;lt;/li&amp;gt;&lt;br /&gt;
{{/ingredients}}&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;Steps&amp;lt;/h4&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
{{#steps}}&lt;br /&gt;
&amp;lt;li&amp;gt;{{{.}}}&amp;lt;/li&amp;gt;&lt;br /&gt;
{{/steps}}&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
{{ &amp;gt; ratethisrecipe }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When given this data:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  recipename: &amp;quot;Cheese sandwich&amp;quot;,&lt;br /&gt;
  description: &amp;quot;Who doesn&#039;t like a good cheese sandwich?&amp;quot;,&lt;br /&gt;
  ingredients: [&amp;quot;bread&amp;quot;, &amp;quot;cheese&amp;quot;, &amp;quot;butter&amp;quot;],&lt;br /&gt;
  steps: [&amp;quot;&amp;lt;p&amp;gt;Step 1 is to spread the butter on the bread&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;&amp;lt;p&amp;gt;Step 2 is to put the cheese &amp;amp;quot;in&amp;amp;quot; the bread (not on top, or underneath)&amp;lt;/p&amp;gt;&amp;quot;]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Gives this: &amp;lt;span style=&amp;quot;font-size:4em&amp;quot;&amp;gt;😋&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info - there are much clearer explanations of templates on the [http://mustache.github.io/mustache.5.html Mustache] website. Try reading those pages &amp;quot;before&amp;quot; posting on stack overflow :) .&lt;br /&gt;
&lt;br /&gt;
=== Blocks (Moodle 3.0 onwards) ===&lt;br /&gt;
Blocks are a feature of Mustache that deserves a special mention. They are used as a form of inheritance - and are crucial to building a library of re-usable templates. To make use of &amp;quot;blocks&amp;quot; you define a parent template with replaceable sections. Each of those sections is marked with a &amp;quot;blocks&amp;quot; tag like this (A blocks tag looks like a regular tag, but the variable name is preceded with $):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;section&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;{{$sectionheading}}Default heading{{/sectionheading}}&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
{{$content}}Content for section{{/content}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now - wherever I need to re-use this template I can include it and replace the content of those sections at the same time. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{&amp;lt; section}}&lt;br /&gt;
{{$sectionheading}}Latest News{{/sectionheading}}&lt;br /&gt;
{{$content}}Nothing happened today - sorry!{{/content}}&lt;br /&gt;
{{/section}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that when I include a template and I want to make use of blocks - the include tag points the other way:&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{&amp;lt; section}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Not&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{&amp;gt; section}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Blocks support looping and many other cool things - for more info see https://github.com/bobthecow/mustache.php/wiki/BLOCKS-pragma&lt;br /&gt;
&lt;br /&gt;
== Where do I put my templates? ==&lt;br /&gt;
&lt;br /&gt;
Templates go in the &amp;lt;componentdir&amp;gt;/templates folder and must have a .mustache file extension. When loading templates the template name is &amp;lt;componentname&amp;gt;/&amp;lt;filename&amp;gt; (no file extension). &lt;br /&gt;
&lt;br /&gt;
So &amp;quot;mod_lesson/timer&amp;quot; would load the template at mod/lesson/templates/timer.mustache.&lt;br /&gt;
&lt;br /&gt;
Note: Do not try and put your templates in sub folders under the &amp;quot;/templates&amp;quot; directory. This is not supported and will not work.&lt;br /&gt;
&lt;br /&gt;
== How do I call a template from javascript? ==&lt;br /&gt;
&lt;br /&gt;
Rendering a template from javascript is fairly easy. There is a new AMD module that can load/cache and render a template for you. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
// This is AMD code for loading the &amp;quot;core/templates&amp;quot; module. see [Javascript Modules].&lt;br /&gt;
require([&#039;core/templates&#039;], function(templates) {&lt;br /&gt;
&lt;br /&gt;
    // This will be the context for our template. So {{name}} in the template will resolve to &amp;quot;Tweety bird&amp;quot;.&lt;br /&gt;
    var context = { name: &#039;Tweety bird&#039;, intelligence: 2 };&lt;br /&gt;
&lt;br /&gt;
    // This will call the function to load and render our template. &lt;br /&gt;
    templates.render(&#039;block_looneytunes/profile&#039;, context)&lt;br /&gt;
&lt;br /&gt;
    // It returns a promise that needs to be resoved.&lt;br /&gt;
            .then(function(html, js) {&lt;br /&gt;
                // Here eventually I have my compiled template, and any javascript that it generated.&lt;br /&gt;
                // The templates object has append, prepend and replace functions.&lt;br /&gt;
                templates.appendNodeContents(&#039;.block_looneytunes .content&#039;, source, javascript);&lt;br /&gt;
            }).fail(function(ex) {&lt;br /&gt;
                // Deal with this exception (I recommend core/notify exception function for this).&lt;br /&gt;
            });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under the hood, this did many clever things for us. It loaded the template via an ajax call if it was not cached. It found any missing lang strings in the template and loaded them in a single ajax request, it split the JS from the HTML and returned us both in easy to use way. Read on for how to nicely deal with the javascript parameter.&lt;br /&gt;
&lt;br /&gt;
Note: with some nice chaining and sugar, we can shorten the above example quite a bit:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
require([&#039;core/templates&#039;, &#039;core/notification&#039;], function(templates, notification) {&lt;br /&gt;
    var context = { name: &#039;Tweety bird&#039;, intelligence: 2 };&lt;br /&gt;
    templates.render(&#039;block_looneytunes/profile&#039;, context)&lt;br /&gt;
        .then(doneCallback)&lt;br /&gt;
        .fail(notification.exception);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== What if a template contains javascript? ==&lt;br /&gt;
&lt;br /&gt;
Sometimes a template requires that some JS be run when it is added to the page in order to give it more features. In the template we can include blocks of javascript, but we should use a special section tag that has a &amp;quot;helper&amp;quot; method registered to handle javascript carefully. &lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
profile.mustache&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;profile&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Name: {{name}}&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Intelligence: {{intelligence}}&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
{{#js}}&lt;br /&gt;
require([&#039;jquery&#039;], function($) {&lt;br /&gt;
    // Effects! Can we have &amp;quot;blink&amp;quot;?&lt;br /&gt;
    $(&#039;#profile&#039;).slideDown();&lt;br /&gt;
});&lt;br /&gt;
{{/js}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If this template is rendered by PHP, the javascript is separated from the HTML, and is appended to a special section in the footer of the page &amp;quot;after&amp;quot; requirejs has loaded. This provides the optimal page loading speed. If the template is rendered by javascript, the javascript source will be passed to the &amp;quot;done&amp;quot; handler from the promise. Then, when the &amp;quot;done&amp;quot; handler has added the template to the DOM, it can call &lt;br /&gt;
&amp;lt;code javascript&amp;gt;templates.runTemplateJS(javascript);&amp;lt;/code&amp;gt; &lt;br /&gt;
which will run the javascript (by creating a new script tag and appending it to the page head).&lt;br /&gt;
&lt;br /&gt;
== What other helpers can I use? ==&lt;br /&gt;
&lt;br /&gt;
The implementation of these helpers is in classes like [https://github.com/moodle/moodle/blob/master/lib/classes/output/mustache_string_helper.php#L31 \core\output\mustache_string_helper]. This is set up in the [https://github.com/moodle/moodle/blob/master/lib/outputrenderers.php#L100 get_mustache method in renderer_base] (There should be no need to look at the implementation, unless you are interested.) If you are considering adding a new helper, it should be limited to display logic - and you need to be able to create identical helpers for the javascript and php implementations (javascript ones go in lib/amd/src/templates.js). &lt;br /&gt;
&lt;br /&gt;
=== {{# str }} ===&lt;br /&gt;
&lt;br /&gt;
There is a string helper for loading language strings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{# str }} helloworld, mod_greeting {{/ str }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 2 parameters are the string id and the component name. So this is effectively Mustache variant of &amp;lt;code&amp;gt;get_string(&#039;helloworld&#039;, &#039;mod_greeting&#039;)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The optional third parameter defines the value for the string&#039;s &amp;lt;code&amp;gt;$a&amp;lt;/code&amp;gt; placeholder:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{# str }} iscool, mod_cool, David Beckham {{/ str }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example would effectively do what &amp;lt;code&amp;gt;get_string(&#039;iscool&#039;, &#039;mod_cool&#039;, &#039;David Beckham&#039;)&amp;lt;/code&amp;gt; does in Moodle PHP code.&lt;br /&gt;
&lt;br /&gt;
Variable tags are allowed to define the value of the &amp;lt;code&amp;gt;$a&amp;lt;/code&amp;gt; placeholder:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{# str }} iscool, mod_cool, {{ name }} {{/ str }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For strings that accept complex placeholder, see the following section.&lt;br /&gt;
&lt;br /&gt;
=== {{# quote }} ===&lt;br /&gt;
&lt;br /&gt;
As shown in the previous section, the &amp;lt;code&amp;gt;{{# str }}&amp;lt;/code&amp;gt; helper may need complex data structures passed as the value of the &amp;lt;code&amp;gt;$a&amp;lt;/code&amp;gt; placeholder. You can use a JSON object syntax in that case:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{# str }} iscool, mod_cool, { &amp;quot;firstname&amp;quot;: &amp;quot;David&amp;quot;, &amp;quot;lastname&amp;quot;: &amp;quot;Beckham&amp;quot; } {{/ str }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you wanted to use the context values instead of literal strings, you might intuitively use something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{! DO NOT DO THIS !}}&lt;br /&gt;
{{# str }} iscool, mod_cool, { &amp;quot;firstname&amp;quot;: &amp;quot;{{ firstname }}&amp;quot;, &amp;quot;lastname&amp;quot;: &amp;quot;{{ lastname }}&amp;quot; } {{/ str }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is a potential problem though. If the variable tag &amp;lt;code&amp;gt;{{ firstname }}&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;{{ lastname }}&amp;lt;/code&amp;gt; evaluates to a string containing the double quote character, that will break the JSON syntax. We need to escape the double quotes potentially appearing in the variable tags. For this, use the &amp;lt;code&amp;gt;{{# quote }}&amp;lt;/code&amp;gt; helper:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{! This is OK !}}&lt;br /&gt;
{{# str }} iscool, mod_cool, { &amp;quot;firstname&amp;quot;:  {{# quote }}{{ firstname }}{{/ quote }}, &amp;quot;lastname&amp;quot;: {{# quote }}{{ lastname }}{{/ quote }} } {{/ str }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See MDL-52136 for details.&lt;br /&gt;
=== {{# pix }} ===&lt;br /&gt;
&lt;br /&gt;
There is a pix icon helper for generating pix icon tags.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{# pix }} t/edit, core, Edit David Beckham {{/ pix }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 2 parameters are the string id and the component name, the rest is the alt text for the image.&lt;br /&gt;
&lt;br /&gt;
=== {{# userdate }} (Moodle 3.3 onwards) ===&lt;br /&gt;
{{Moodle 3.3}}&lt;br /&gt;
This mustache template helper will format unix timestamps into a given human readable date format while using the user&#039;s timezone settings configured (if any) in Moodle. The helper will accept hardcoded values, context variables, or other helpers. &lt;br /&gt;
&lt;br /&gt;
The recommended way to use this helper is to use the string helper to get one of the core Moodle formats because they have been translated into other languages so you&#039;ll get multi-lang support for free (that&#039;s a pretty good deal!).&lt;br /&gt;
&lt;br /&gt;
==== Using the string helper (recommended) ====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
// Assuming we had a context variable named &amp;quot;time&amp;quot; set to 1293876000.&lt;br /&gt;
{{#userdate}} {{time}}, {{#str}} strftimedate {{/str}} {{/userdate}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This will ask the Moodle server for the string &amp;quot;strftimedate&amp;quot; and will use the value (which in this case is &amp;quot;%d %B %Y&amp;quot;)  to format the user date. So the resulting formatted timestamp from the userdate helper will be &amp;quot;01 January 2011&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Using context variables ====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
// Assuming we had a context variable named &amp;quot;time&amp;quot; set to 1293876000.&lt;br /&gt;
{{#userdate}} {{time}}, %A, %d %B %Y, %I:%M %p {{/userdate}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Will produce &amp;quot;Saturday, 01 January 2011, 10:00 AM&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Using hardcoded values ====&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{#userdate}} 1293876000, %A, %d %B %Y, %I:%M %p {{/userdate}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Will produce &amp;quot;Saturday, 01 January 2011, 10:00 AM&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== {{# shortentext }} (Moodle 3.3 onwards) ===&lt;br /&gt;
{{Moodle 3.3}}&lt;br /&gt;
This helper can be used to shorten a large amount of text to a specified length and will append a trailing ellipsis to signify that the text has been shortened. &lt;br /&gt;
&lt;br /&gt;
The algorithm will attempt to preserve words while shortening to text. Words, for the purposes of the helper, are considered to be groups of consecutive characters broken by a space or, in the case of a multi-byte character, after the completion of the multi-byte character (rather than in the middle of the character).&lt;br /&gt;
&lt;br /&gt;
It will also attempt to preserve HTML in the text by keeping the opening and closing tags. Only text within the tags will be considered when calculating how much should be truncated to reach the desired length.&lt;br /&gt;
&lt;br /&gt;
The helper takes two comma separated arguments. The first is the desired length and the second is the text to be shortened. Both can be provided as context variables.&lt;br /&gt;
&lt;br /&gt;
==== Plain text ====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
{{#shortentext}} 30, long text without any tags blah de blah blah blah what {{/shortentext}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Will produce:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
long text without any tags ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== HTML text ====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
{{#shortentext}} 30, &amp;lt;div class=&#039;frog&#039;&amp;gt;&amp;lt;p&amp;gt;&amp;lt;blockquote&amp;gt;Long text with tags that will be chopped off but &amp;lt;b&amp;gt;should be added back again&amp;lt;/b&amp;gt;&amp;lt;/blockquote&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/p&amp;gt; {{/shortentext}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Will produce:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;div class=&#039;frog&#039;&amp;gt;&amp;lt;p&amp;gt;&amp;lt;blockquote&amp;gt;Long text with tags that ...&amp;lt;/blockquote&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multi-byte text ====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
{{#shortentext}} 6, 𠮟𠮟𠮟𠮟𠮟𠮟𠮟𠮟𠮟𠮟𠮟𠮟 {{/shortentext}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Will produce:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
𠮟𠮟𠮟...&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How do I call a template from php? ==&lt;br /&gt;
&lt;br /&gt;
The templates in php are attached to the renderers. There is a renderer method &amp;quot;render_from_template($templatename, $context)&amp;quot; that does the trick.&lt;br /&gt;
&lt;br /&gt;
Note $context is nothing to do with normal Moodle &#039;contexts&#039;. It is the data passed to the template (the &#039;context&#039; mentioned in mustache documentation).&lt;br /&gt;
&lt;br /&gt;
== How do templates work with renderers? ==&lt;br /&gt;
&lt;br /&gt;
Extra care must be taken to ensure that the data passed to the context parameter is useful to the templating language. The template language cannot:&lt;br /&gt;
* Call functions&lt;br /&gt;
* Perform any boolean logic&lt;br /&gt;
* Render renderables&lt;br /&gt;
* Do capability checks&lt;br /&gt;
* Make DB queries&lt;br /&gt;
&lt;br /&gt;
So - I have &amp;quot;some&amp;quot; data in my renderable and some logic and HTML generation in my render method for that renderable - how do I refactor this to use a template?&lt;br /&gt;
&lt;br /&gt;
The first thing to note, is that you don&#039;t have to use a template if you don&#039;t want to. It just means that themers will still have to override your render method, instead of just overriding the template. But if you DO want to use a template, you will earn &amp;quot;cred&amp;quot; with themers, and you will be able to re-render parts of your interface from javascript in response to ajax requests without reloading the whole page (that&#039;s cool).&lt;br /&gt;
&lt;br /&gt;
There is a simple pattern to use to hook a template into a render method. If you make your renderable implement templatable as well as renderable - it will have to implement a new method &amp;quot;export_for_template(renderer_base $output)&amp;quot;. This method takes the data stored in the renderable and &amp;quot;flattens it&amp;quot; so it can be used in a template. If there is some nested data in the renderable (like other renderables) and they do not support templates, they can be &amp;quot;rendered&amp;quot; into the flat data structure using the renderer parameter. It should return an stdClass with properties that are only made of simple types: int, string, bool, float, stdClass or arrays of these types. Then the render method can updated to export the data and render it with the template.&lt;br /&gt;
&lt;br /&gt;
In the renderable:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
     * Export this data so it can be used as the context for a mustache template.&lt;br /&gt;
     *&lt;br /&gt;
     * @return stdClass&lt;br /&gt;
     */&lt;br /&gt;
    public function export_for_template(renderer_base $output) {&lt;br /&gt;
        $data = new stdClass();&lt;br /&gt;
        $data-&amp;gt;canmanage = $this-&amp;gt;canmanage;&lt;br /&gt;
        $data-&amp;gt;things = array();&lt;br /&gt;
        foreach ($this-&amp;gt;things as $thing) {&lt;br /&gt;
            $data-&amp;gt;things[] = $thing-&amp;gt;to_record();&lt;br /&gt;
        }&lt;br /&gt;
        $data-&amp;gt;navigation = array();&lt;br /&gt;
        foreach ($this-&amp;gt;navigation as $button) {&lt;br /&gt;
            $data-&amp;gt;navigation[] = $output-&amp;gt;render($button);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return $data;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the renderer class:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    /**&lt;br /&gt;
     * Defer to template.&lt;br /&gt;
     *&lt;br /&gt;
     * @param mywidget $widget&lt;br /&gt;
     *&lt;br /&gt;
     * @return string HTML for the page&lt;br /&gt;
     */&lt;br /&gt;
    render(mywidget $widget) {&lt;br /&gt;
        $data = $widget-&amp;gt;export_for_template($this);&lt;br /&gt;
        return $this-&amp;gt;render_from_template(&#039;mywidget&#039;, $data);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How to I override a template in my theme? ==&lt;br /&gt;
&lt;br /&gt;
Templates can be overridden a bit easier than overriding a renderer. First - find the template that you want to change. E.g. &amp;quot;mod/wiki/templates/ratingui.mustache&amp;quot;. Now, create a sub-folder under your themes &amp;quot;templates&amp;quot; directory with the component name of the plugin you are overriding. E.g &amp;quot;theme/timtam/templates/mod_wiki&amp;quot;. Finally, copy the ratingui.mustache file into the newly created &amp;quot;theme/timtam/templates/mod_wiki&amp;quot; and edit it. You should see your changes immediately if theme designer mode is on. Note: templates are cached just like CSS, so if you are not using theme designer mode you will need to purge all caches to see the latest version of an edited template. If the template you are overriding contains a documentation comment (see next section) it is recommended to remove it, it will still show the documentation in the template library.&lt;br /&gt;
&lt;br /&gt;
== Should I document my templates? ==&lt;br /&gt;
&lt;br /&gt;
Yes!!!! Theme designers need to know the limits of what they can expect to change without breaking anything. As a further benefit - your beautiful new template can be displayed in the &amp;quot;Template Library&amp;quot; tool shipped with Moodle. In order to provide nice documentation and examples for the Template Library, you should follow these conventions when documenting your template.&lt;br /&gt;
&lt;br /&gt;
=== Add a documentation comment to your template ===&lt;br /&gt;
Mustache comments look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  {{! &lt;br /&gt;
   I am a comment.&lt;br /&gt;
   I can span multiple lines.&lt;br /&gt;
  }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The template library will look for a mustache comment that contains this special marker as the documentation to display, and the source of an example context.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
@template component/templatename&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Useful things to include in the documentation for a template ====&lt;br /&gt;
===== Classes required for JS =====&lt;br /&gt;
This is a list of classes that are used by the javascript for this template. If removing a class from an element in the template will break the javascript, list it here.&lt;br /&gt;
&lt;br /&gt;
===== Data attributes required for JS =====&lt;br /&gt;
This is a list of data attributes (e.g. data-enhance=&amp;quot;true&amp;quot;) that are used by the javascript for this template. If removing a data attribute from an element in the template will break the javascript, list it here.&lt;br /&gt;
&lt;br /&gt;
===== Context variables required for this template =====&lt;br /&gt;
This is a description of the data that may be contained in the context that is passed to the template. Be explicit and document every attribute.&lt;br /&gt;
&lt;br /&gt;
===== Example context (JSON) =====&lt;br /&gt;
The Template Library will look for this data in your documentation comment as it allows it to render a &amp;quot;preview&amp;quot; of the template right in the Template Library. This is useful for theme designers to test all the available templates in their new theme to make sure they look nice in a new theme. It is also useful to make sure the template responds to different screen sizes, languages and devices. The format is a JSON-encoded object that is passed directly into the render method for this template. &lt;br /&gt;
&lt;br /&gt;
==== A full example ====&lt;br /&gt;
lib/templates/pix_icon.mustache&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  {{!                                                                                                                                 &lt;br /&gt;
    This file is part of Moodle - http://moodle.org/                                                                                &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Moodle is free software: you can redistribute it and/or modify                                                                  &lt;br /&gt;
    it under the terms of the GNU General Public License as published by                                                            &lt;br /&gt;
    the Free Software Foundation, either version 3 of the License, or                                                               &lt;br /&gt;
    (at your option) any later version.                                                                                             &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Moodle is distributed in the hope that it will be useful,                                                                       &lt;br /&gt;
    but WITHOUT ANY WARRANTY; without even the implied warranty of                                                                  &lt;br /&gt;
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                                                   &lt;br /&gt;
    GNU General Public License for more details.                                                                                    &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    You should have received a copy of the GNU General Public License                                                               &lt;br /&gt;
    along with Moodle.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.                                                                 &lt;br /&gt;
  }}                                                                                                                                  &lt;br /&gt;
  {{!                                                                                                                                 &lt;br /&gt;
    @template core/pix_icon                                                                                                         &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Moodle pix_icon template.                                                                                                       &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    The purpose of this template is to render a pix_icon.                                                                           &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Classes required for JS:                                                                                                        &lt;br /&gt;
    * none                                                                                                                          &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Data attributes required for JS:                                                                                                &lt;br /&gt;
    * none                                                                                                                          &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Context variables required for this template:                                                                                   &lt;br /&gt;
    * attributes Array of name / value pairs.                                                                                       &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Example context (json):                                                                                                         &lt;br /&gt;
    {                                                                                                                               &lt;br /&gt;
        &amp;quot;attributes&amp;quot;: [                                                                                                             &lt;br /&gt;
            { &amp;quot;name&amp;quot;: &amp;quot;src&amp;quot;, &amp;quot;value&amp;quot;: &amp;quot;http://moodle.com/wp-content/themes/moodle/images/logo-hat2.png&amp;quot; },                          &lt;br /&gt;
            { &amp;quot;name&amp;quot;: &amp;quot;class&amp;quot;, &amp;quot;value&amp;quot;: &amp;quot;iconsmall&amp;quot; }                                                                               &lt;br /&gt;
        ]                                                                                                                           &lt;br /&gt;
    }                                                                                                                               &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
  }}                                                                                                                                  &lt;br /&gt;
  &amp;lt;img {{#attributes}}{{name}}=&amp;quot;{{value}}&amp;quot; {{/attributes}}/&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Coding style for templates ==&lt;br /&gt;
This section documents some coding style guidelines to follow when writing templates. The reason for these guidelines is to promote consistency, and interoperability of the templates.&lt;br /&gt;
&lt;br /&gt;
=== Include GPL at the top of each template ===&lt;br /&gt;
&lt;br /&gt;
Templates are a form of code and it is appropriate to license them like any other code.&lt;br /&gt;
&lt;br /&gt;
===Include a documentation comment for each template===&lt;br /&gt;
&lt;br /&gt;
The exception is when you are overriding a template, if the documentation from the parent still applies, you do not need to copy it to the overridden template.&lt;br /&gt;
&lt;br /&gt;
===Use data-attributes for JS hooks===&lt;br /&gt;
&lt;br /&gt;
Data attributes are ideal for adding javascript hooks to templates because:&lt;br /&gt;
* Classes are meant for styling - theme designers should be able to change the classes at will without breaking any functionality.&lt;br /&gt;
* IDs must be unique in the page, but it is not possible to control how many times the same template might be included in the page.&lt;br /&gt;
* Data attributes can have meaningful names and can be efficiently queried with a selector&lt;br /&gt;
&lt;br /&gt;
===Avoid custom CSS for templates===&lt;br /&gt;
&lt;br /&gt;
This is not a hard rule, but a preference. We already have too much CSS in Moodle - where ever possible we should try and re-use the existing CSS instead of adding new CSS to support every new template.&lt;br /&gt;
&lt;br /&gt;
===Re-use core templates as much as possible===&lt;br /&gt;
&lt;br /&gt;
First we need to build the core set of reusable templates - but once that is in place we should always try to re-use those core templates to build interfaces. This will make Moodle more consistent, attractive and customisable.&lt;br /&gt;
&lt;br /&gt;
===Do use the CSS framework classes directly in the templates===&lt;br /&gt;
&lt;br /&gt;
We have bootstrap in core - so lets make the most of it. There is no problem using bootstrap classes in core templates, as long as the &amp;quot;base&amp;quot; theme is also tested, and an overridden template is added there if required.&lt;br /&gt;
&lt;br /&gt;
===Avoid IDs for styling or javascript===&lt;br /&gt;
&lt;br /&gt;
IDs should never evet be used for styling as they have a high CSS specificity, and so are hard to override. In addition, IDs should be unique in the page, which implies that a template could only be used once in a page. IDs are also not ideal for javascript, for the same reason (must be unique in a page).&lt;br /&gt;
&lt;br /&gt;
The only acceptable case to use an ID is you need to create a one to one connection between the JS and template. In this case use the uniqid helper to generate an ID that will not conflict with any other template on the page, and use it as part of the ID.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;{{uniqid}}-somethingspecific&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
{{#js}}&lt;br /&gt;
    callFunction(&#039;{{uniqid}}-somethingspecific&#039;);&lt;br /&gt;
{{/js}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Follow CSS coding style===&lt;br /&gt;
&lt;br /&gt;
https://docs.moodle.org/dev/CSS_coding_style&lt;br /&gt;
&lt;br /&gt;
Use hyphens as word-separators for class names. &lt;br /&gt;
Use lower case class names.&lt;br /&gt;
&lt;br /&gt;
===Wrap each template in one node with a classname that matches the template name===&lt;br /&gt;
&lt;br /&gt;
Generate a class name by combining the component and template names and separating words with underscore.&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;core_user_header&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:AJAX]]&lt;br /&gt;
[[Category:Javascript]]&lt;br /&gt;
[[Category:Output]]&lt;br /&gt;
&lt;br /&gt;
===Iterating over php arrays in a mustache template===&lt;br /&gt;
&lt;br /&gt;
Mustache treats hashes and arrays differently because of cross language compatibility&lt;br /&gt;
In php arrays and hashes are the same, but mustache treats them differently&lt;br /&gt;
It decides a php array is a hash and will not iterate over it if it is non 0 indexed and/or has a gap in the key numbers&lt;br /&gt;
so in short&lt;br /&gt;
you need to&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$datafortemplate-&amp;gt;mylist =  array_values($myarraywithnonnumerickeys)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
you could also use &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$datafortemplate-&amp;gt;mylist = new ArrayIterator($myarraywithnonnumerickeys);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
BUT this fails when $myarraywithnonnumerickeys is empty and you try to use&lt;br /&gt;
&amp;lt;code html5&amp;gt;&lt;br /&gt;
{{#mylist}}&lt;br /&gt;
with an array iterator if mylist is empty this block will not run&lt;br /&gt;
{{/mylist}}&lt;br /&gt;
{{^mylist}}&lt;br /&gt;
with an array iterator mylist will not run this block either because it is not quite empty&lt;br /&gt;
{{/mylist}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Test for not empty array in a mustache template===&lt;br /&gt;
&lt;br /&gt;
Short answer you can&#039;t. Include a specific property in the context like &amp;quot;hasusers&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
In php &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{{#users.0}} blah {{/users.0}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will work but please don&#039;t use this syntax, it will break if the template is used in javascript AND it mucks up the context.&lt;br /&gt;
&lt;br /&gt;
In javascript&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{{#users.length}} blah {{/users.length}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will work but please don&#039;t use this syntax, it will break if the template is used in php.&lt;br /&gt;
&lt;br /&gt;
===Squash whitespace in a template===&lt;br /&gt;
Sometimes whitespace is significant, for example inside a link it will show with an underline. If you want 2 mustache tags from separate lines to be rendered with no whitespace between them you can use mustache comments to squash the whitespace.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;blah&amp;quot;&amp;gt;{{!&lt;br /&gt;
}}{{icon}}{{!&lt;br /&gt;
}}{{name}}&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How do I write core templates? ==&lt;br /&gt;
Core templates should ideally be simple generic components that can be used within other templates to create more complex page layouts. They should be flexible enough for developers and themers to easily use without having to replace the template. The templates should attempt to encapsulate some core structure for the element as well as key classes while allowing the content to be easily overridden. Ultimately we want to avoid having duplicate HTML copied from template to template where possible, particularly if the HTML element has some classes associated with it.&lt;br /&gt;
&lt;br /&gt;
Mustache relies on variables to substitute context data into the template but unfortunately it&#039;s very unlikely that the the names of the context data will match what the template is expecting for all the places that the template might be used. So in order to allow easy extensibility and avoid having to duplicate templates just to rename the variables we can wrap them in block variables which would allow the template that is including our template to replace that variable with one from it&#039;s own context inline.&lt;br /&gt;
&lt;br /&gt;
There are a few key points to keep in mind when writing a core template:&lt;br /&gt;
* Consider how your template will actually be used. Try writing a test page that uses your template to help discover some of the assumptions you might have in the template.&lt;br /&gt;
* The example context you provide in the template is mostly just for showing the template in the template library and is likely not how your template will actually be used. Most uses of the template will have a different context all together.&lt;br /&gt;
* Try to enforce a core structure but avoid enforcing a specific context. Content should be overridable.&lt;br /&gt;
* Use block variables to indicate sections of your template that people are likely to want to change. Typically where they will be wanting to substitute in their own content.&lt;br /&gt;
* Try to keep any javascript that accompanies the template as decoupled from the HTML / CSS structure of the template as possible. Instead of relying on the existence of certain HTML elements or CSS classes it is generally better to leverage data-attributes which can be added to any element.&lt;br /&gt;
&lt;br /&gt;
=== An example: tabs ===&lt;br /&gt;
Let&#039;s go through an example to illustrate how you might build a core template. For the example we&#039;ll be building a tabs template, since it&#039;s a fairly complex component that requires the use of block variables and javascript.&lt;br /&gt;
&lt;br /&gt;
First we can create a basic template to get the general structure down, let&#039;s call it tabs. Here&#039;s what it might look like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;{{ uniqid }}-tab-container&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;ul role=&amp;quot;tablist&amp;quot; class=&amp;quot;nav nav-tabs&amp;quot;&amp;gt;&lt;br /&gt;
		{{# tabs }}&lt;br /&gt;
			&amp;lt;li role=&amp;quot;tab&amp;quot;&lt;br /&gt;
					data-target=&amp;quot;{{ uniqid }}-{{ id }}&amp;quot;&lt;br /&gt;
					data-selected-class=&amp;quot;active&amp;quot;&lt;br /&gt;
					aria-controls=&amp;quot;{{ uniqid }}-{{ id }}&amp;quot;&lt;br /&gt;
					aria-selected=&amp;quot;false&amp;quot; tabindex=&amp;quot;-1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
				&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;{{{ name }}}&amp;lt;/a&amp;gt;&lt;br /&gt;
			&amp;lt;/li&amp;gt;&lt;br /&gt;
		{{/ tabs }}&lt;br /&gt;
	&amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;tab-content&amp;quot;&amp;gt;&lt;br /&gt;
		{{# tabs }}&lt;br /&gt;
			&amp;lt;div role=&amp;quot;tabpanel&amp;quot;&lt;br /&gt;
				class=&amp;quot;tab-pane&amp;quot;&lt;br /&gt;
				id=&amp;quot;{{ uniqid }}-{{ id }}&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
				{{{ content }}}&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		{{/ tabs }}&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
{{#js}}&lt;br /&gt;
    require([&#039;jquery&#039;,&#039;core/tabs&#039;], function($, tabs) {&lt;br /&gt;
&lt;br /&gt;
        var container = $(&amp;quot;#{{ uniqid }}-tab-container&amp;quot;);&lt;br /&gt;
        tabs.create(container);&lt;br /&gt;
    });&lt;br /&gt;
{{/js}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The template requires a context that looks something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;tabs&amp;quot;: [&lt;br /&gt;
		{&amp;quot;id&amp;quot;:&amp;quot;tab1&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Tab 1&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;This is tab 1 content &amp;lt;a href=\&amp;quot;#\&amp;quot;&amp;gt;test&amp;lt;/a&amp;gt;&amp;quot;},&lt;br /&gt;
		{&amp;quot;id&amp;quot;:&amp;quot;tab2&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Tab 2&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;This is tab 2 content &amp;lt;a href=\&amp;quot;#\&amp;quot;&amp;gt;test&amp;lt;/a&amp;gt;&amp;quot;},&lt;br /&gt;
		{&amp;quot;id&amp;quot;:&amp;quot;tab3&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Tab 3&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;This is tab 3 content &amp;lt;a href=\&amp;quot;#\&amp;quot;&amp;gt;test&amp;lt;/a&amp;gt;&amp;quot;}&lt;br /&gt;
	]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The javascript required to power the tabs element (keyboard navigation, show / hide panels etc) is written as an AMD module and is included by the template. The javascript is a little too large to go through here, but some key points to consider when writing it are:&lt;br /&gt;
It should ideally be independent of the HTML structure, so if someone wants to completely rewrite the tabs to be different elements (e.g. buttons or a set of divs) then the same javascript can be used without needing to change it. In order to achieve this it is important to identify the key components of the template.&lt;br /&gt;
&lt;br /&gt;
In this case it is a tab list, a tab and it&#039;s content. One way to identify these components would be to inspect the structure of the DOM, for example you might say &amp;quot;find me the ul element&amp;quot; when looking for the tab list and then &amp;quot;find my the child li elements&amp;quot; to find the tabs. While this would work, it couples your javascript to the HTML structure and makes it difficult to change later. A different approach would be to use the element attributes, for example you might say &amp;quot;find my the element with the role &#039;tablist&#039;&amp;quot; to get the tab list and then &amp;quot;find me the elements with the role &#039;tab&#039;&amp;quot; to get the tabs. This allows the HTML structure to change without breaking the javascript (as long as the correct attributes are set, of course).&lt;br /&gt;
&lt;br /&gt;
Another point of consideration for this example is what class to apply to a tab when it is selected. It makes sense to just apply something like &amp;quot;active&amp;quot; in the javascript, but that once again couples it to a particular CSS framework which makes it more difficult to change without modifying the javascript. In this case I chose to add a data attribute to the element to indicate which class will be set when the tab is selected. This means the javascript doesn&#039;t have to guess what the appropriate class is, it can just get it from the template.&lt;br /&gt;
&lt;br /&gt;
Ok, so we&#039;ve got our basic template. It&#039;s time to use it! Let&#039;s say we want to create a simple user profile page that might show 2 tabs, the first tab will be the user&#039;s name and the second tab will be the user&#039;s email address (please excuse the contrived example).&lt;br /&gt;
&lt;br /&gt;
Here&#039;s what the page might look like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&amp;lt;title&amp;gt;User Profile&amp;lt;/title&amp;gt;&amp;lt;/header&amp;gt;&lt;br /&gt;
    &amp;lt;body&amp;gt;&lt;br /&gt;
        {{&amp;lt; core/tabs }}&lt;br /&gt;
    &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That looks pretty simple! The only problem is, how do I get my content there? I would have to supply a context like this in order to display the tabs I want:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;tabs&amp;quot;: [&lt;br /&gt;
		{&amp;quot;id&amp;quot;:&amp;quot;tab1&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Name&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;Your name is Mr. Test User.&amp;quot;},&lt;br /&gt;
		{&amp;quot;id&amp;quot;:&amp;quot;tab2&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Email&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;Your email is testuser@example.com&amp;quot;},&lt;br /&gt;
	]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let&#039;s assume that the context for this page doesn&#039;t match what the tabs template is expecting though (as will be the case most of the time). Let&#039;s assume the tabs template is being rendered with this context:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;name&amp;quot;:&amp;quot;Mr. Test User&amp;quot;,&lt;br /&gt;
	&amp;quot;email&amp;quot;:&amp;quot;testuser@example.com&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unfortunately, we&#039;ll almost certainly never have complete control over all of the contexts that our template will be rendered in which means we&#039;ll be expecting people to write new webservices to supply the same data in different formats every time they want to use a template. It becomes an unmanageable problem.&lt;br /&gt;
&lt;br /&gt;
Enter blocks! We can make the template more flexible by defining sections of the template that can be overriden when they are included. Pretty neat! This will allow us to enforce a certain core structure but not enforce a context on the template that is including the tabs.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s have another go at that template, this time leveraging blocks:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;{{ uniqid }}-tab-container&amp;quot;&amp;gt;&lt;br /&gt;
	{{$ tabheader }}&lt;br /&gt;
		&amp;lt;ul role=&amp;quot;tablist&amp;quot; class=&amp;quot;nav nav-tabs&amp;quot;&amp;gt;&lt;br /&gt;
			{{$ tablist }}&lt;br /&gt;
				{{# tabs }}&lt;br /&gt;
					&amp;lt;li role=&amp;quot;tab&amp;quot;&lt;br /&gt;
							data-target=&amp;quot;{{ uniqid }}-{{ id }}&amp;quot;&lt;br /&gt;
							data-selected-class=&amp;quot;active&amp;quot;&lt;br /&gt;
							aria-controls=&amp;quot;{{ uniqid }}-{{ id }}&amp;quot;&lt;br /&gt;
							aria-selected=&amp;quot;false&amp;quot; tabindex=&amp;quot;-1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
						&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;{{{ name }}}&amp;lt;/a&amp;gt;&lt;br /&gt;
					&amp;lt;/li&amp;gt;&lt;br /&gt;
				{{/ tabs }}&lt;br /&gt;
			{{/ tablist }}&lt;br /&gt;
		&amp;lt;/ul&amp;gt;&lt;br /&gt;
	{{/ tabheader }}&lt;br /&gt;
	{{$ tabbody }}&lt;br /&gt;
		&amp;lt;div class=&amp;quot;tab-content&amp;quot;&amp;gt;&lt;br /&gt;
			{{$ tabcontent }}&lt;br /&gt;
				{{# tabs }}&lt;br /&gt;
					&amp;lt;div role=&amp;quot;tabpanel&amp;quot;&lt;br /&gt;
						class=&amp;quot;tab-pane&amp;quot;&lt;br /&gt;
						id=&amp;quot;{{ uniqid }}-{{ id }}&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
						{{{ content }}}&lt;br /&gt;
					&amp;lt;/div&amp;gt;&lt;br /&gt;
				{{/ tabs }}&lt;br /&gt;
			{{/ tabcontent }}&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
	{{/ tabbody }}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
{{#js}}&lt;br /&gt;
    require([&#039;jquery&#039;,&#039;core/tabs&#039;], function($, tabs) {&lt;br /&gt;
&lt;br /&gt;
        var container = $(&amp;quot;#{{ uniqid }}-tab-container&amp;quot;);&lt;br /&gt;
        tabs.create(container);&lt;br /&gt;
    });&lt;br /&gt;
{{/js}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A summary of what we&#039;ve changed:&lt;br /&gt;
* Added a $tabheader block around the tab list, in case someone wants to change the ul element to something else.&lt;br /&gt;
* Added a $tablist block around the group of tabs to allow them to be overriden on incldue.&lt;br /&gt;
* Added a $tabbody block around the content, in case someone wants to change the content elements from divs.&lt;br /&gt;
* Added a $tabcontent block around the tab variable for the content to allow the content to be overriden on inlcude.&lt;br /&gt;
&lt;br /&gt;
Now let&#039;s see what using this template looks like for your User Profile page:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&amp;lt;title&amp;gt;User Profile&amp;lt;/title&amp;gt;&amp;lt;/header&amp;gt;&lt;br /&gt;
    &amp;lt;body&amp;gt;&lt;br /&gt;
        {{&amp;gt; core/tabs }}&lt;br /&gt;
			{{$ tablist }}&lt;br /&gt;
				&amp;lt;li role=&amp;quot;tab&amp;quot;&lt;br /&gt;
						data-target=&amp;quot;{{ uniqid }}-tab1&amp;quot;&lt;br /&gt;
						data-selected-class=&amp;quot;active&amp;quot;&lt;br /&gt;
						aria-controls=&amp;quot;{{ uniqid }}-tab1&amp;quot;&lt;br /&gt;
						aria-selected=&amp;quot;false&amp;quot; tabindex=&amp;quot;-1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
					&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;Name&amp;lt;/a&amp;gt;&lt;br /&gt;
				&amp;lt;/li&amp;gt;&lt;br /&gt;
				&amp;lt;li role=&amp;quot;tab&amp;quot;&lt;br /&gt;
						data-target=&amp;quot;{{ uniqid }}-tab2&amp;quot;&lt;br /&gt;
						data-selected-class=&amp;quot;active&amp;quot;&lt;br /&gt;
						aria-controls=&amp;quot;{{ uniqid }}-tab2&amp;quot;&lt;br /&gt;
						aria-selected=&amp;quot;false&amp;quot; tabindex=&amp;quot;-1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
					&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;Email&amp;lt;/a&amp;gt;&lt;br /&gt;
				&amp;lt;/li&amp;gt;&lt;br /&gt;
			{{/ tablist }}&lt;br /&gt;
			{{$ tabcontent }}&lt;br /&gt;
				&amp;lt;div role=&amp;quot;tabpanel&amp;quot;&lt;br /&gt;
					class=&amp;quot;tab-pane&amp;quot;&lt;br /&gt;
					id=&amp;quot;{{ uniqid }}-tab1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
					Your name is {{ name }}.&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div role=&amp;quot;tabpanel&amp;quot;&lt;br /&gt;
					class=&amp;quot;tab-pane&amp;quot;&lt;br /&gt;
					id=&amp;quot;{{ uniqid }}-tab2&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
					Your email address is {{ email }}.&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
			{{/ tabcontent }}&lt;br /&gt;
		{{/ core/tabs }}&lt;br /&gt;
    &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That looks a bit better! Now we&#039;ve been able to use the blocks to successfully change the template to use the context available to this page, we no longer need a &amp;quot;tabs&amp;quot; array with &amp;quot;name&amp;quot; and &amp;quot;content&amp;quot;. Even the javascript will continue to work because we&#039;ve kept the correct element attributes. &lt;br /&gt;
&lt;br /&gt;
We&#039;ve still got a slight problem though... In order to change the data for the template we&#039;ve had to copy &amp;amp; paste the HTML from the original template into our blocks as we do the override. While this works fine in this example, it means we don&#039;t quite get the encapsulation we want within the templates since we&#039;re leaking internal implementation details. If we ever wanted to change the CSS framework we use for Moodle (say from bootstrap 2 to boostrap 3 or 4) we&#039;d have to find all the places in the code where this tabs template is used and make sure that the HTML is correct in their block overrides.&lt;br /&gt;
&lt;br /&gt;
With that in mind, let&#039;s take one more pass at this template and see if we can improve it slightly again. This time we&#039;re doing to split the template out into 3 templates.&lt;br /&gt;
&lt;br /&gt;
tabs.mustache:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;{{ uniqid }}-tab-container&amp;quot;&amp;gt;&lt;br /&gt;
	{{$ tabheader }}&lt;br /&gt;
		&amp;lt;ul role=&amp;quot;tablist&amp;quot; class=&amp;quot;nav nav-tabs&amp;quot;&amp;gt;&lt;br /&gt;
			{{$ tablist }}&lt;br /&gt;
				{{# tabs }}&lt;br /&gt;
					{{&amp;gt; core/tab_header_item }}		&lt;br /&gt;
				{{/ tabs }}&lt;br /&gt;
			{{/ tablist }}&lt;br /&gt;
		&amp;lt;/ul&amp;gt;&lt;br /&gt;
	{{/ tabheader }}&lt;br /&gt;
	{{$ tabbody }}&lt;br /&gt;
		&amp;lt;div class=&amp;quot;tab-content&amp;quot;&amp;gt;&lt;br /&gt;
			{{$ tabcontent }}&lt;br /&gt;
				{{# tabs }}&lt;br /&gt;
					{{&amp;gt; core/tab_content_item }}&lt;br /&gt;
				{{/ tabs }}&lt;br /&gt;
			{{/ tabcontent }}&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
	{{/ tabbody }}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
{{#js}}&lt;br /&gt;
    require([&#039;jquery&#039;,&#039;core/tabs&#039;], function($, tabs) {&lt;br /&gt;
&lt;br /&gt;
        var container = $(&amp;quot;#{{ uniqid }}-tab-container&amp;quot;);&lt;br /&gt;
        tabs.create(container);&lt;br /&gt;
    });&lt;br /&gt;
{{/js}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tab_header_item.mustache&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;li role=&amp;quot;tab&amp;quot;&lt;br /&gt;
		data-selected-class=&amp;quot;active&amp;quot;&lt;br /&gt;
		aria-selected=&amp;quot;false&amp;quot; tabindex=&amp;quot;-1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;{{$ tabname }}{{{ name }}}{{/ tabname }}&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tab_content_item.mustache&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div role=&amp;quot;tabpanel&amp;quot;&lt;br /&gt;
	class=&amp;quot;tab-pane&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	{{$ tabpanelcontent }}{{{ content }}}{{/ tabpanelcontent }}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A summary of the changes:&lt;br /&gt;
* Split the template into 3, moving the tab into it&#039;s own template and the content into it&#039;s own and then including them in the tabs template.&lt;br /&gt;
* Removed the ids from the tabs and content. The javascript would be updating to assign these ids at runtime so that they don&#039;t need to be provided as part of the template context.&lt;br /&gt;
* Added a $tabname block for in the tab_header_item template to make the name flexible on import.&lt;br /&gt;
* Added a $tabpanelcontant block in the tab_content_item template to make the content flexible on import.&lt;br /&gt;
&lt;br /&gt;
Cool, so let&#039;s see what that looks like in our example now:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&amp;lt;title&amp;gt;User Profile&amp;lt;/title&amp;gt;&amp;lt;/header&amp;gt;&lt;br /&gt;
    &amp;lt;body&amp;gt;&lt;br /&gt;
        {{&amp;gt; core/tabs }}&lt;br /&gt;
			{{$ tablist }}&lt;br /&gt;
				{{&amp;lt; core/tab_header_item }}&lt;br /&gt;
					{{$ tabname }}Name{{/ tabname }}&lt;br /&gt;
				{{/ core/tab_header_item }}&lt;br /&gt;
				{{&amp;lt; core/tab_header_item }}&lt;br /&gt;
					{{$ tabname }}Email{{/ tabname }}&lt;br /&gt;
				{{/ core/tab_header_item }}&lt;br /&gt;
			{{/ tablist }}&lt;br /&gt;
			{{$ tabcontent }}&lt;br /&gt;
				{{&amp;lt; core/tab_content_item }}&lt;br /&gt;
					{{$ tabpanelcontent }}Your name is {{ name }}.{{/ tabpanelcontent }}&lt;br /&gt;
				{{/ core/tab_content_item }}&lt;br /&gt;
				{{&amp;lt; core/tab_content_item }}&lt;br /&gt;
					{{$ tabpanelcontent }}Your email address is {{ email }}.{{/ tabpanelcontent }}&lt;br /&gt;
				{{/ core/tab_content_item }}&lt;br /&gt;
			{{/ tabcontent }}&lt;br /&gt;
		{{/ core/tabs }}&lt;br /&gt;
    &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And we&#039;re done! After making the changes above we&#039;ve been able to keep the benefits of the previous change to allow the context changes but we&#039;ve also removed the need to copy &amp;amp; paste the HTML everywhere. Instead we&#039;re able to use the child templates with a few additional blocks defined to get the content in there.&lt;br /&gt;
&lt;br /&gt;
Now if we want to change tabs HTML or CSS frameworks we can just change the core tabs templates and this page will receive the updates for free.&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Templates&amp;diff=53824</id>
		<title>Templates</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Templates&amp;diff=53824"/>
		<updated>2018-03-18T22:07:53Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Blocks (Moodle 3.0 onwards) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.9}}&lt;br /&gt;
&lt;br /&gt;
= Templates =&lt;br /&gt;
&lt;br /&gt;
== What is a template? ==&lt;br /&gt;
A template is an alternative to writing blocks of HTML directly in javascript / php by concatenating strings. The end result is the same, but templates have a number of advantages:&lt;br /&gt;
* It is easier to see the final result of the template because the code for a template is very close to what the final HTML will look like&lt;br /&gt;
* Because the templating language is intentionally limited, it is hard to introduce complex logic into a template. This makes it far easier for a theme designer to override a template, without breaking the logic&lt;br /&gt;
* Templates can be rendered from javascript. This allows ajax operations to re-render a portion of the page.&lt;br /&gt;
&lt;br /&gt;
== How do I write a template? ==&lt;br /&gt;
Templates are written in a language called &amp;quot;[http://mustache.github.io/mustache.5.html Mustache]&amp;quot;. Mustache is written as HTML with additional tags used to format the display of the data. Mustache tags are made of 2 opening and closing curly braces &amp;lt;code xml&amp;gt;{{tag}}&amp;lt;/code&amp;gt;. There are a few variations of these tags that behave differently.&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{raiden}}&amp;lt;/code&amp;gt; This is a simple variable substitution. The variable named &amp;quot;raiden&amp;quot; will be searched for in the current context (and any parent contexts) and when a value is found, the entire tag will be replaced by the variable (HTML escaped).&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{{galaga}}}&amp;lt;/code&amp;gt; This is an unescaped variable substitution. Instead of escaping the variable before replacing it in the template, the variable is included raw. This is useful when the variable contains a block of HTML (for example).&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{#lemmings}} jump off cliff {{/lemmings}}&amp;lt;/code&amp;gt; These are opening and closing section tags. If the lemmings variable exists and evaluates to &amp;quot;not false&amp;quot; value, the variable is pushed on the stack, the contents of the section are parsed and included in the result. If the variable does not exist, or evaluates to false - the section will be skipped. If the variable lemmings evaluates to an array, the section will be repeated for each item in the array with the items of the array on the context. This is how to output a list.&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{^lemmings}} enjoy view {{/lemmings}}&amp;lt;/code&amp;gt; Equivalent of &amp;quot;if-not&amp;quot; block, there is no &amp;quot;else&amp;quot; in mustache.&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{&amp;gt; franken_style/name_of_template }}&amp;lt;/code&amp;gt; This is a partial. Think of it like an include. Templates can include other templates using this tag. In the called template, the data it sees (for including values is the same as the data available where the partial is included.&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{$blockvar}} ... {{/blockvar}}&amp;lt;/code&amp;gt; This is a block variable. It defines a section of the template that can be overridden when it&#039;s included in another template.&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{&amp;lt; template_name}} ... {{/template_name}}&amp;lt;/code&amp;gt; This is similar to including a partial but specifically indicates that you&#039;d like to override one or more block variables defined within the template you&#039;re including. You can override the block variables by defining a block variable within these tags that matches the name of the block variable you&#039;d like to override in the included template.&lt;br /&gt;
&lt;br /&gt;
So - putting this all together:&lt;br /&gt;
&lt;br /&gt;
recipe.mustache&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;{{recipename}}&amp;lt;/h3&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;{{description}}&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;Ingredients&amp;lt;/h4&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
{{#ingredients}}&lt;br /&gt;
&amp;lt;li&amp;gt;{{.}}&amp;lt;/li&amp;gt;&lt;br /&gt;
{{/ingredients}}&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;Steps&amp;lt;/h4&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
{{#steps}}&lt;br /&gt;
&amp;lt;li&amp;gt;{{{.}}}&amp;lt;/li&amp;gt;&lt;br /&gt;
{{/steps}}&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
{{ &amp;gt; ratethisrecipe }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When given this data:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  recipename: &amp;quot;Cheese sandwich&amp;quot;,&lt;br /&gt;
  description: &amp;quot;Who doesn&#039;t like a good cheese sandwich?&amp;quot;,&lt;br /&gt;
  ingredients: [&amp;quot;bread&amp;quot;, &amp;quot;cheese&amp;quot;, &amp;quot;butter&amp;quot;],&lt;br /&gt;
  steps: [&amp;quot;&amp;lt;p&amp;gt;Step 1 is to spread the butter on the bread&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;&amp;lt;p&amp;gt;Step 2 is to put the cheese &amp;amp;quot;in&amp;amp;quot; the bread (not on top, or underneath)&amp;lt;/p&amp;gt;&amp;quot;]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Gives this: &amp;lt;span style=&amp;quot;font-size:4em&amp;quot;&amp;gt;😋&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info - there are much clearer explanations of templates on the [http://mustache.github.io/mustache.5.html Mustache] website. Try reading those pages &amp;quot;before&amp;quot; posting on stack overflow :) .&lt;br /&gt;
&lt;br /&gt;
=== Blocks (Moodle 3.0 onwards) ===&lt;br /&gt;
Blocks are a feature of Mustache that deserves a special mention. They are used as a form of inheritance - and are crucial to building a library of re-usable templates. To make use of &amp;quot;blocks&amp;quot; you define a parent template with replaceable sections. Each of those sections is marked with a &amp;quot;blocks&amp;quot; tag like this (A blocks tag looks like a regular tag, but the variable name is preceded with $):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;section&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;{{$sectionheading}}Default heading{{/sectionheading}}&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
{{$content}}Content for section{{/content}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now - wherever I need to re-use this template I can include it and replace the content of those sections at the same time. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{&amp;lt; section}}&lt;br /&gt;
{{$sectionheading}}Latest News{{/sectionheading}}&lt;br /&gt;
{{$content}}Nothing happened today - sorry!{{/content}}&lt;br /&gt;
{{/section}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that when I include a template and I want to make use of blocks - the include tag points the other way:&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{&amp;lt; section}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Not&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{&amp;gt; section}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Blocks support looping and many other cool things - for more info see https://github.com/bobthecow/mustache.php/wiki/BLOCKS-pragma&lt;br /&gt;
&lt;br /&gt;
== Where do I put my templates? ==&lt;br /&gt;
&lt;br /&gt;
Templates go in the &amp;lt;componentdir&amp;gt;/templates folder and must have a .mustache file extension. When loading templates the template name is &amp;lt;componentname&amp;gt;/&amp;lt;filename&amp;gt; (no file extension). &lt;br /&gt;
&lt;br /&gt;
So &amp;quot;mod_lesson/timer&amp;quot; would load the template at mod/lesson/templates/timer.mustache.&lt;br /&gt;
&lt;br /&gt;
Note: Do not try and put your templates in sub folders under the &amp;quot;/templates&amp;quot; directory. This is not supported and will not work.&lt;br /&gt;
&lt;br /&gt;
== How do I call a template from javascript? ==&lt;br /&gt;
&lt;br /&gt;
Rendering a template from javascript is fairly easy. There is a new AMD module that can load/cache and render a template for you. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
// This is AMD code for loading the &amp;quot;core/templates&amp;quot; module. see [Javascript Modules].&lt;br /&gt;
require([&#039;core/templates&#039;], function(templates) {&lt;br /&gt;
&lt;br /&gt;
    // This will be the context for our template. So {{name}} in the template will resolve to &amp;quot;Tweety bird&amp;quot;.&lt;br /&gt;
    var context = { name: &#039;Tweety bird&#039;, intelligence: 2 };&lt;br /&gt;
&lt;br /&gt;
    // This will call the function to load and render our template. &lt;br /&gt;
    templates.render(&#039;block_looneytunes/profile&#039;, context)&lt;br /&gt;
&lt;br /&gt;
    // It returns a promise that needs to be resoved.&lt;br /&gt;
            .then(function(html, js) {&lt;br /&gt;
                // Here eventually I have my compiled template, and any javascript that it generated.&lt;br /&gt;
                // The templates object has append, prepend and replace functions.&lt;br /&gt;
                templates.appendNodeContents(&#039;.block_looneytunes .content&#039;, source, javascript);&lt;br /&gt;
            }).fail(function(ex) {&lt;br /&gt;
                // Deal with this exception (I recommend core/notify exception function for this).&lt;br /&gt;
            });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under the hood, this did many clever things for us. It loaded the template via an ajax call if it was not cached. It found any missing lang strings in the template and loaded them in a single ajax request, it split the JS from the HTML and returned us both in easy to use way. Read on for how to nicely deal with the javascript parameter.&lt;br /&gt;
&lt;br /&gt;
Note: with some nice chaining and sugar, we can shorten the above example quite a bit:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
require([&#039;core/templates&#039;, &#039;core/notification&#039;], function(templates, notification) {&lt;br /&gt;
    var context = { name: &#039;Tweety bird&#039;, intelligence: 2 };&lt;br /&gt;
    templates.render(&#039;block_looneytunes/profile&#039;, context)&lt;br /&gt;
        .then(doneCallback)&lt;br /&gt;
        .fail(notification.exception);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== What if a template contains javascript? ==&lt;br /&gt;
&lt;br /&gt;
Sometimes a template requires that some JS be run when it is added to the page in order to give it more features. In the template we can include blocks of javascript, but we should use a special section tag that has a &amp;quot;helper&amp;quot; method registered to handle javascript carefully. &lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
profile.mustache&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;profile&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Name: {{name}}&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Intelligence: {{intelligence}}&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
{{#js}}&lt;br /&gt;
require([&#039;jquery&#039;], function($) {&lt;br /&gt;
    // Effects! Can we have &amp;quot;blink&amp;quot;?&lt;br /&gt;
    $(&#039;#profile&#039;).slideDown();&lt;br /&gt;
});&lt;br /&gt;
{{/js}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If this template is rendered by PHP, the javascript is separated from the HTML, and is appended to a special section in the footer of the page &amp;quot;after&amp;quot; requirejs has loaded. This provides the optimal page loading speed. If the template is rendered by javascript, the javascript source will be passed to the &amp;quot;done&amp;quot; handler from the promise. Then, when the &amp;quot;done&amp;quot; handler has added the template to the DOM, it can call &lt;br /&gt;
&amp;lt;code javascript&amp;gt;templates.runTemplateJS(javascript);&amp;lt;/code&amp;gt; &lt;br /&gt;
which will run the javascript (by creating a new script tag and appending it to the page head).&lt;br /&gt;
&lt;br /&gt;
== What other helpers can I use? ==&lt;br /&gt;
&lt;br /&gt;
The implementation of these helpers is in classes like [https://github.com/moodle/moodle/blob/master/lib/classes/output/mustache_string_helper.php#L31 \core\output\mustache_string_helper]. This is set up in the [https://github.com/moodle/moodle/blob/master/lib/outputrenderers.php#L100 get_mustache method in renderer_base] (There should be no need to look at the implementation, unless you are interested.) If you are considering adding a new helper, it should be limited to display logic - and you need to be able to create identical helpers for the javascript and php implementations (javascript ones go in lib/amd/src/templates.js). &lt;br /&gt;
&lt;br /&gt;
=== {{# str }} ===&lt;br /&gt;
&lt;br /&gt;
There is a string helper for loading language strings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{# str }} helloworld, mod_greeting {{/ str }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 2 parameters are the string id and the component name. So this is effectively Mustache variant of &amp;lt;code&amp;gt;get_string(&#039;helloworld&#039;, &#039;mod_greeting&#039;)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The optional third parameter defines the value for the string&#039;s &amp;lt;code&amp;gt;$a&amp;lt;/code&amp;gt; placeholder:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{# str }} iscool, mod_cool, David Beckham {{/ str }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example would effectively do what &amp;lt;code&amp;gt;get_string(&#039;iscool&#039;, &#039;mod_cool&#039;, &#039;David Beckham&#039;)&amp;lt;/code&amp;gt; does in Moodle PHP code.&lt;br /&gt;
&lt;br /&gt;
Variable tags are allowed to define the value of the &amp;lt;code&amp;gt;$a&amp;lt;/code&amp;gt; placeholder:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{# str }} iscool, mod_cool, {{ name }} {{/ str }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For strings that accept complex placeholder, see the following section.&lt;br /&gt;
&lt;br /&gt;
=== {{# quote }} ===&lt;br /&gt;
&lt;br /&gt;
As shown in the previous section, the &amp;lt;code&amp;gt;{{# str }}&amp;lt;/code&amp;gt; helper may need complex data structures passed as the value of the &amp;lt;code&amp;gt;$a&amp;lt;/code&amp;gt; placeholder. You can use a JSON object syntax in that case:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{# str }} iscool, mod_cool, { &amp;quot;firstname&amp;quot;: &amp;quot;David&amp;quot;, &amp;quot;lastname&amp;quot;: &amp;quot;Beckham&amp;quot; } {{/ str }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you wanted to use the context values instead of literal strings, you might intuitively use something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{! DO NOT DO THIS !}}&lt;br /&gt;
{{# str }} iscool, mod_cool, { &amp;quot;firstname&amp;quot;: &amp;quot;{{ firstname }}&amp;quot;, &amp;quot;lastname&amp;quot;: &amp;quot;{{ lastname }}&amp;quot; } {{/ str }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is a potential problem though. If the variable tag &amp;lt;code&amp;gt;{{ firstname }}&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;{{ lastname }}&amp;lt;/code&amp;gt; evaluates to a string containing the double quote character, that will break the JSON syntax. We need to escape the double quotes potentially appearing in the variable tags. For this, use the &amp;lt;code&amp;gt;{{# quote }}&amp;lt;/code&amp;gt; helper:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{! This is OK !}}&lt;br /&gt;
{{# str }} iscool, mod_cool, { &amp;quot;firstname&amp;quot;:  {{# quote }}{{ firstname }}{{/ quote }}, &amp;quot;lastname&amp;quot;: {{# quote }}{{ lastname }}{{/ quote }} } {{/ str }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See MDL-52136 for details.&lt;br /&gt;
=== {{# pix }} ===&lt;br /&gt;
&lt;br /&gt;
There is a pix icon helper for generating pix icon tags.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{# pix }} t/edit, core, Edit David Beckham {{/ pix }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 2 parameters are the string id and the component name, the rest is the alt text for the image.&lt;br /&gt;
&lt;br /&gt;
=== {{# userdate }} (Moodle 3.3 onwards) ===&lt;br /&gt;
{{Moodle 3.3}}&lt;br /&gt;
This mustache template helper will format unix timestamps into a given human readable date format while using the user&#039;s timezone settings configured (if any) in Moodle. The helper will accept hardcoded values, context variables, or other helpers. &lt;br /&gt;
&lt;br /&gt;
The recommended way to use this helper is to use the string helper to get one of the core Moodle formats because they have been translated into other languages so you&#039;ll get multi-lang support for free (that&#039;s a pretty good deal!).&lt;br /&gt;
&lt;br /&gt;
==== Using the string helper (recommended) ====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
// Assuming we had a context variable named &amp;quot;time&amp;quot; set to 1293876000.&lt;br /&gt;
{{#userdate}} {{time}}, {{#str}} strftimedate {{/str}} {{/userdate}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This will ask the Moodle server for the string &amp;quot;strftimedate&amp;quot; and will use the value (which in this case is &amp;quot;%d %B %Y&amp;quot;)  to format the user date. So the resulting formatted timestamp from the userdate helper will be &amp;quot;01 January 2011&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Using context variables ====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
// Assuming we had a context variable named &amp;quot;time&amp;quot; set to 1293876000.&lt;br /&gt;
{{#userdate}} {{time}}, %A, %d %B %Y, %I:%M %p {{/userdate}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Will produce &amp;quot;Saturday, 01 January 2011, 10:00 AM&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Using hardcoded values ====&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{#userdate}} 1293876000, %A, %d %B %Y, %I:%M %p {{/userdate}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Will produce &amp;quot;Saturday, 01 January 2011, 10:00 AM&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== {{# shortentext }} (Moodle 3.3 onwards) ===&lt;br /&gt;
{{Moodle 3.3}}&lt;br /&gt;
This helper can be used to shorten a large amount of text to a specified length and will append a trailing ellipsis to signify that the text has been shortened. &lt;br /&gt;
&lt;br /&gt;
The algorithm will attempt to preserve words while shortening to text. Words, for the purposes of the helper, are considered to be groups of consecutive characters broken by a space or, in the case of a multi-byte character, after the completion of the multi-byte character (rather than in the middle of the character).&lt;br /&gt;
&lt;br /&gt;
It will also attempt to preserve HTML in the text by keeping the opening and closing tags. Only text within the tags will be considered when calculating how much should be truncated to reach the desired length.&lt;br /&gt;
&lt;br /&gt;
The helper takes two comma separated arguments. The first is the desired length and the second is the text to be shortened. Both can be provided as context variables.&lt;br /&gt;
&lt;br /&gt;
==== Plain text ====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
{{#shortentext}} 30, long text without any tags blah de blah blah blah what {{/shortentext}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Will produce:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
long text without any tags ...&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== HTML text ====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
{{#shortentext}} 30, &amp;lt;div class=&#039;frog&#039;&amp;gt;&amp;lt;p&amp;gt;&amp;lt;blockquote&amp;gt;Long text with tags that will be chopped off but &amp;lt;b&amp;gt;should be added back again&amp;lt;/b&amp;gt;&amp;lt;/blockquote&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/p&amp;gt; {{/shortentext}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Will produce:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;div class=&#039;frog&#039;&amp;gt;&amp;lt;p&amp;gt;&amp;lt;blockquote&amp;gt;Long text with tags that ...&amp;lt;/blockquote&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Multi-byte text ====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
{{#shortentext}} 6, 𠮟𠮟𠮟𠮟𠮟𠮟𠮟𠮟𠮟𠮟𠮟𠮟 {{/shortentext}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Will produce:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
𠮟𠮟𠮟...&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How do I call a template from php? ==&lt;br /&gt;
&lt;br /&gt;
The templates in php are attached to the renderers. There is a renderer method &amp;quot;render_from_template($templatename, $context)&amp;quot; that does the trick.&lt;br /&gt;
&lt;br /&gt;
Note $context is nothing to do with normal Moodle &#039;contexts&#039;. It is the data passed to the template (the &#039;context&#039; mentioned in mustache documentation).&lt;br /&gt;
&lt;br /&gt;
== How do templates work with renderers? ==&lt;br /&gt;
&lt;br /&gt;
Extra care must be taken to ensure that the data passed to the context parameter is useful to the templating language. The template language cannot:&lt;br /&gt;
* Call functions&lt;br /&gt;
* Perform any boolean logic&lt;br /&gt;
* Render renderables&lt;br /&gt;
* Do capability checks&lt;br /&gt;
* Make DB queries&lt;br /&gt;
&lt;br /&gt;
So - I have &amp;quot;some&amp;quot; data in my renderable and some logic and HTML generation in my render method for that renderable - how do I refactor this to use a template?&lt;br /&gt;
&lt;br /&gt;
The first thing to note, is that you don&#039;t have to use a template if you don&#039;t want to. It just means that themers will still have to override your render method, instead of just overriding the template. But if you DO want to use a template, you will earn &amp;quot;cred&amp;quot; with themers, and you will be able to re-render parts of your interface from javascript in response to ajax requests without reloading the whole page (that&#039;s cool).&lt;br /&gt;
&lt;br /&gt;
There is a simple pattern to use to hook a template into a render method. If you make your renderable implement templatable as well as renderable - it will have to implement a new method &amp;quot;export_for_template(renderer_base $output)&amp;quot;. This method takes the data stored in the renderable and &amp;quot;flattens it&amp;quot; so it can be used in a template. If there is some nested data in the renderable (like other renderables) and they do not support templates, they can be &amp;quot;rendered&amp;quot; into the flat data structure using the renderer parameter. It should return an stdClass with properties that are only made of simple types: int, string, bool, float, stdClass or arrays of these types. Then the render method can updated to export the data and render it with the template.&lt;br /&gt;
&lt;br /&gt;
In the renderable:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
     * Export this data so it can be used as the context for a mustache template.&lt;br /&gt;
     *&lt;br /&gt;
     * @return stdClass&lt;br /&gt;
     */&lt;br /&gt;
    public function export_for_template(renderer_base $output) {&lt;br /&gt;
        $data = new stdClass();&lt;br /&gt;
        $data-&amp;gt;canmanage = $this-&amp;gt;canmanage;&lt;br /&gt;
        $data-&amp;gt;things = array();&lt;br /&gt;
        foreach ($this-&amp;gt;things as $thing) {&lt;br /&gt;
            $data-&amp;gt;things[] = $thing-&amp;gt;to_record();&lt;br /&gt;
        }&lt;br /&gt;
        $data-&amp;gt;navigation = array();&lt;br /&gt;
        foreach ($this-&amp;gt;navigation as $button) {&lt;br /&gt;
            $data-&amp;gt;navigation[] = $output-&amp;gt;render($button);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return $data;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the renderer class:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    /**&lt;br /&gt;
     * Defer to template.&lt;br /&gt;
     *&lt;br /&gt;
     * @param mywidget $widget&lt;br /&gt;
     *&lt;br /&gt;
     * @return string HTML for the page&lt;br /&gt;
     */&lt;br /&gt;
    render(mywidget $widget) {&lt;br /&gt;
        $data = $widget-&amp;gt;export_for_template($this);&lt;br /&gt;
        return $this-&amp;gt;render_from_template(&#039;mywidget&#039;, $data);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How to I override a template in my theme? ==&lt;br /&gt;
&lt;br /&gt;
Templates can be overridden a bit easier than overriding a renderer. First - find the template that you want to change. E.g. &amp;quot;mod/wiki/templates/ratingui.mustache&amp;quot;. Now, create a sub-folder under your themes &amp;quot;templates&amp;quot; directory with the component name of the plugin you are overriding. E.g &amp;quot;theme/timtam/templates/mod_wiki&amp;quot;. Finally, copy the ratingui.mustache file into the newly created &amp;quot;theme/timtam/templates/mod_wiki&amp;quot; and edit it. You should see your changes immediately if theme designer mode is on. Note: templates are cached just like CSS, so if you are not using theme designer mode you will need to purge all caches to see the latest version of an edited template. If the template you are overriding contains a documentation comment (see next section) it is recommended to remove it, it will still show the documentation in the template library.&lt;br /&gt;
&lt;br /&gt;
== Should I document my templates? ==&lt;br /&gt;
&lt;br /&gt;
Yes!!!! Theme designers need to know the limits of what they can expect to change without breaking anything. As a further benefit - your beautiful new template can be displayed in the &amp;quot;Template Library&amp;quot; tool shipped with Moodle. In order to provide nice documentation and examples for the Template Library, you should follow these conventions when documenting your template.&lt;br /&gt;
&lt;br /&gt;
=== Add a documentation comment to your template ===&lt;br /&gt;
Mustache comments look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  {{! &lt;br /&gt;
   I am a comment.&lt;br /&gt;
   I can span multiple lines.&lt;br /&gt;
  }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The template library will look for a mustache comment that contains this special marker as the documentation to display, and the source of an example context.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
@template component/templatename&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Useful things to include in the documentation for a template ====&lt;br /&gt;
===== Classes required for JS =====&lt;br /&gt;
This is a list of classes that are used by the javascript for this template. If removing a class from an element in the template will break the javascript, list it here.&lt;br /&gt;
&lt;br /&gt;
===== Data attributes required for JS =====&lt;br /&gt;
This is a list of data attributes (e.g. data-enhance=&amp;quot;true&amp;quot;) that are used by the javascript for this template. If removing a data attribute from an element in the template will break the javascript, list it here.&lt;br /&gt;
&lt;br /&gt;
===== Context variables required for this template =====&lt;br /&gt;
This is a description of the data that may be contained in the context that is passed to the template. Be explicit and document every attribute.&lt;br /&gt;
&lt;br /&gt;
===== Example context (JSON) =====&lt;br /&gt;
The Template Library will look for this data in your documentation comment as it allows it to render a &amp;quot;preview&amp;quot; of the template right in the Template Library. This is useful for theme designers to test all the available templates in their new theme to make sure they look nice in a new theme. It is also useful to make sure the template responds to different screen sizes, languages and devices. The format is a JSON-encoded object that is passed directly into the render method for this template. &lt;br /&gt;
&lt;br /&gt;
==== A full example ====&lt;br /&gt;
lib/templates/pix_icon.mustache&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  {{!                                                                                                                                 &lt;br /&gt;
    This file is part of Moodle - http://moodle.org/                                                                                &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Moodle is free software: you can redistribute it and/or modify                                                                  &lt;br /&gt;
    it under the terms of the GNU General Public License as published by                                                            &lt;br /&gt;
    the Free Software Foundation, either version 3 of the License, or                                                               &lt;br /&gt;
    (at your option) any later version.                                                                                             &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Moodle is distributed in the hope that it will be useful,                                                                       &lt;br /&gt;
    but WITHOUT ANY WARRANTY; without even the implied warranty of                                                                  &lt;br /&gt;
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                                                   &lt;br /&gt;
    GNU General Public License for more details.                                                                                    &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    You should have received a copy of the GNU General Public License                                                               &lt;br /&gt;
    along with Moodle.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.                                                                 &lt;br /&gt;
  }}                                                                                                                                  &lt;br /&gt;
  {{!                                                                                                                                 &lt;br /&gt;
    @template core/pix_icon                                                                                                         &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Moodle pix_icon template.                                                                                                       &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    The purpose of this template is to render a pix_icon.                                                                           &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Classes required for JS:                                                                                                        &lt;br /&gt;
    * none                                                                                                                          &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Data attributes required for JS:                                                                                                &lt;br /&gt;
    * none                                                                                                                          &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Context variables required for this template:                                                                                   &lt;br /&gt;
    * attributes Array of name / value pairs.                                                                                       &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Example context (json):                                                                                                         &lt;br /&gt;
    {                                                                                                                               &lt;br /&gt;
        &amp;quot;attributes&amp;quot;: [                                                                                                             &lt;br /&gt;
            { &amp;quot;name&amp;quot;: &amp;quot;src&amp;quot;, &amp;quot;value&amp;quot;: &amp;quot;http://moodle.com/wp-content/themes/moodle/images/logo-hat2.png&amp;quot; },                          &lt;br /&gt;
            { &amp;quot;name&amp;quot;: &amp;quot;class&amp;quot;, &amp;quot;value&amp;quot;: &amp;quot;iconsmall&amp;quot; }                                                                               &lt;br /&gt;
        ]                                                                                                                           &lt;br /&gt;
    }                                                                                                                               &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
  }}                                                                                                                                  &lt;br /&gt;
  &amp;lt;img {{#attributes}}{{name}}=&amp;quot;{{value}}&amp;quot; {{/attributes}}/&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Coding style for templates ==&lt;br /&gt;
This section documents some coding style guidelines to follow when writing templates. The reason for these guidelines is to promote consistency, and interoperability of the templates.&lt;br /&gt;
&lt;br /&gt;
=== Include GPL at the top of each template ===&lt;br /&gt;
&lt;br /&gt;
Templates are a form of code and it is appropriate to license them like any other code.&lt;br /&gt;
&lt;br /&gt;
===Include a documentation comment for each template===&lt;br /&gt;
&lt;br /&gt;
The exception is when you are overriding a template, if the documentation from the parent still applies, you do not need to copy it to the overridden template.&lt;br /&gt;
&lt;br /&gt;
===Use data-attributes for JS hooks===&lt;br /&gt;
&lt;br /&gt;
Data attributes are ideal for adding javascript hooks to templates because:&lt;br /&gt;
* Classes are meant for styling - theme designers should be able to change the classes at will without breaking any functionality.&lt;br /&gt;
* IDs must be unique in the page, but it is not possible to control how many times the same template might be included in the page.&lt;br /&gt;
* Data attributes can have meaningful names and can be efficiently queried with a selector&lt;br /&gt;
&lt;br /&gt;
===Avoid custom CSS for templates===&lt;br /&gt;
&lt;br /&gt;
This is not a hard rule, but a preference. We already have too much CSS in Moodle - where ever possible we should try and re-use the existing CSS instead of adding new CSS to support every new template.&lt;br /&gt;
&lt;br /&gt;
===Re-use core templates as much as possible===&lt;br /&gt;
&lt;br /&gt;
First we need to build the core set of reusable templates - but once that is in place we should always try to re-use those core templates to build interfaces. This will make Moodle more consistent, attractive and customisable.&lt;br /&gt;
&lt;br /&gt;
===Do use the CSS framework classes directly in the templates===&lt;br /&gt;
&lt;br /&gt;
We have bootstrap in core - so lets make the most of it. There is no problem using bootstrap classes in core templates, as long as the &amp;quot;base&amp;quot; theme is also tested, and an overridden template is added there if required.&lt;br /&gt;
&lt;br /&gt;
===Avoid IDs for styling or javascript===&lt;br /&gt;
&lt;br /&gt;
IDs should never evet be used for styling as they have a high CSS specificity, and so are hard to override. In addition, IDs should be unique in the page, which implies that a template could only be used once in a page. IDs are also not ideal for javascript, for the same reason (must be unique in a page).&lt;br /&gt;
&lt;br /&gt;
The only acceptable case to use an ID is you need to create a one to one connection between the JS and template. In this case use the uniqid helper to generate an ID that will not conflict with any other template on the page, and use it as part of the ID.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;{{uniqid}}-somethingspecific&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
{{#js}}&lt;br /&gt;
    callFunction(&#039;{{uniqid}}-somethingspecific&#039;);&lt;br /&gt;
{{/js}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Follow CSS coding style===&lt;br /&gt;
&lt;br /&gt;
https://docs.moodle.org/dev/CSS_coding_style&lt;br /&gt;
&lt;br /&gt;
Use hyphens as word-separators for class names. &lt;br /&gt;
Use lower case class names.&lt;br /&gt;
&lt;br /&gt;
===Wrap each template in one node with a classname that matches the template name===&lt;br /&gt;
&lt;br /&gt;
Generate a class name by combining the component and template names and separating words with underscore.&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;core_user_header&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:AJAX]]&lt;br /&gt;
[[Category:Javascript]]&lt;br /&gt;
[[Category:Output]]&lt;br /&gt;
&lt;br /&gt;
===Iterating over php arrays in a mustache template===&lt;br /&gt;
&lt;br /&gt;
Mustache treats hashes and arrays differently because of cross language compatibility&lt;br /&gt;
In php arrays and hashes are the same, but mustache treats them differently&lt;br /&gt;
It decides a php array is a hash and will not iterate over it if it is non 0 indexed and/or has a gap in the key numbers&lt;br /&gt;
so in short&lt;br /&gt;
you need to&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$datafortemplate-&amp;gt;mylist =  array_values($myarraywithnonnumerickeys)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
you could also use &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$datafortemplate-&amp;gt;mylist = new ArrayIterator($myarraywithnonnumerickeys);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
BUT this fails when $myarraywithnonnumerickeys is empty and you try to use&lt;br /&gt;
&amp;lt;code html5&amp;gt;&lt;br /&gt;
{{#mylist}}&lt;br /&gt;
with an array iterator if mylist is empty this block will not run&lt;br /&gt;
{{/mylist}}&lt;br /&gt;
{{^mylist}}&lt;br /&gt;
with an array iterator mylist will not run this block either because it is not quite empty&lt;br /&gt;
{{/mylist}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Test for not empty array in a mustache template===&lt;br /&gt;
&lt;br /&gt;
Short answer you can&#039;t. Include a specific property in the context like &amp;quot;hasusers&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
In php &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{{#users.0}} blah {{/users.0}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will work but please don&#039;t use this syntax, it will break if the template is used in javascript AND it mucks up the context.&lt;br /&gt;
&lt;br /&gt;
In javascript&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{{#users.length}} blah {{/users.length}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will work but please don&#039;t use this syntax, it will break if the template is used in php.&lt;br /&gt;
&lt;br /&gt;
===Squash whitespace in a template===&lt;br /&gt;
Sometimes whitespace is significant, for example inside a link it will show with an underline. If you want 2 mustache tags from separate lines to be rendered with no whitespace between them you can use mustache comments to squash the whitespace.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;blah&amp;quot;&amp;gt;{{!&lt;br /&gt;
}}{{icon}}{{!&lt;br /&gt;
}}{{name}}&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How do I write core templates? ==&lt;br /&gt;
Core templates should ideally be simple generic components that can be used within other templates to create more complex page layouts. They should be flexible enough for developers and themers to easily use without having to replace the template. The templates should attempt to encapsulate some core structure for the element as well as key classes while allowing the content to be easily overridden. Ultimately we want to avoid having duplicate HTML copied from template to template where possible, particularly if the HTML element has some classes associated with it.&lt;br /&gt;
&lt;br /&gt;
Mustache relies on variables to substitute context data into the template but unfortunately it&#039;s very unlikely that the the names of the context data will match what the template is expecting for all the places that the template might be used. So in order to allow easy extensibility and avoid having to duplicate templates just to rename the variables we can wrap them in block variables which would allow the template that is including our template to replace that variable with one from it&#039;s own context inline.&lt;br /&gt;
&lt;br /&gt;
There are a few key points to keep in mind when writing a core template:&lt;br /&gt;
* Consider how your template will actually be used. Try writing a test page that uses your template to help discover some of the assumptions you might have in the template.&lt;br /&gt;
* The example context you provide in the template is mostly just for showing the template in the template library and is likely not how your template will actually be used. Most uses of the template will have a different context all together.&lt;br /&gt;
* Try to enforce a core structure but avoid enforcing a specific context. Content should be overridable.&lt;br /&gt;
* Use block variables to indicate sections of your template that people are likely to want to change. Typically where they will be wanting to substitute in their own content.&lt;br /&gt;
* Try to keep any javascript that accompanies the template as decoupled from the HTML / CSS structure of the template as possible. Instead of relying on the existence of certain HTML elements or CSS classes it is generally better to leverage data-attributes which can be added to any element.&lt;br /&gt;
&lt;br /&gt;
=== An example: tabs ===&lt;br /&gt;
Let&#039;s go through an example to illustrate how you might build a core template. For the example we&#039;ll be building a tabs template, since it&#039;s a fairly complex component that requires the use of block variables and javascript.&lt;br /&gt;
&lt;br /&gt;
First we can create a basic template to get the general structure down, let&#039;s call it tabs. Here&#039;s what it might look like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;{{ uniqid }}-tab-container&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;ul role=&amp;quot;tablist&amp;quot; class=&amp;quot;nav nav-tabs&amp;quot;&amp;gt;&lt;br /&gt;
		{{# tabs }}&lt;br /&gt;
			&amp;lt;li role=&amp;quot;tab&amp;quot;&lt;br /&gt;
					data-target=&amp;quot;{{ uniqid }}-{{ id }}&amp;quot;&lt;br /&gt;
					data-selected-class=&amp;quot;active&amp;quot;&lt;br /&gt;
					aria-controls=&amp;quot;{{ uniqid }}-{{ id }}&amp;quot;&lt;br /&gt;
					aria-selected=&amp;quot;false&amp;quot; tabindex=&amp;quot;-1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
				&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;{{{ name }}}&amp;lt;/a&amp;gt;&lt;br /&gt;
			&amp;lt;/li&amp;gt;&lt;br /&gt;
		{{/ tabs }}&lt;br /&gt;
	&amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;tab-content&amp;quot;&amp;gt;&lt;br /&gt;
		{{# tabs }}&lt;br /&gt;
			&amp;lt;div role=&amp;quot;tabpanel&amp;quot;&lt;br /&gt;
				class=&amp;quot;tab-pane&amp;quot;&lt;br /&gt;
				id=&amp;quot;{{ uniqid }}-{{ id }}&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
				{{{ content }}}&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		{{/ tabs }}&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
{{#js}}&lt;br /&gt;
    require([&#039;jquery&#039;,&#039;core/tabs&#039;], function($, tabs) {&lt;br /&gt;
&lt;br /&gt;
        var container = $(&amp;quot;#{{ uniqid }}-tab-container&amp;quot;);&lt;br /&gt;
        tabs.create(container);&lt;br /&gt;
    });&lt;br /&gt;
{{/js}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The template requires a context that looks something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;tabs&amp;quot;: [&lt;br /&gt;
		{&amp;quot;id&amp;quot;:&amp;quot;tab1&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Tab 1&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;This is tab 1 content &amp;lt;a href=\&amp;quot;#\&amp;quot;&amp;gt;test&amp;lt;/a&amp;gt;&amp;quot;},&lt;br /&gt;
		{&amp;quot;id&amp;quot;:&amp;quot;tab2&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Tab 2&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;This is tab 2 content &amp;lt;a href=\&amp;quot;#\&amp;quot;&amp;gt;test&amp;lt;/a&amp;gt;&amp;quot;},&lt;br /&gt;
		{&amp;quot;id&amp;quot;:&amp;quot;tab3&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Tab 3&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;This is tab 3 content &amp;lt;a href=\&amp;quot;#\&amp;quot;&amp;gt;test&amp;lt;/a&amp;gt;&amp;quot;}&lt;br /&gt;
	]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The javascript required to power the tabs element (keyboard navigation, show / hide panels etc) is written as an AMD module and is included by the template. The javascript is a little too large to go through here, but some key points to consider when writing it are:&lt;br /&gt;
It should ideally be independent of the HTML structure, so if someone wants to completely rewrite the tabs to be different elements (e.g. buttons or a set of divs) then the same javascript can be used without needing to change it. In order to achieve this it is important to identify the key components of the template.&lt;br /&gt;
&lt;br /&gt;
In this case it is a tab list, a tab and it&#039;s content. One way to identify these components would be to inspect the structure of the DOM, for example you might say &amp;quot;find me the ul element&amp;quot; when looking for the tab list and then &amp;quot;find my the child li elements&amp;quot; to find the tabs. While this would work, it couples your javascript to the HTML structure and makes it difficult to change later. A different approach would be to use the element attributes, for example you might say &amp;quot;find my the element with the role &#039;tablist&#039;&amp;quot; to get the tab list and then &amp;quot;find me the elements with the role &#039;tab&#039;&amp;quot; to get the tabs. This allows the HTML structure to change without breaking the javascript (as long as the correct attributes are set, of course).&lt;br /&gt;
&lt;br /&gt;
Another point of consideration for this example is what class to apply to a tab when it is selected. It makes sense to just apply something like &amp;quot;active&amp;quot; in the javascript, but that once again couples it to a particular CSS framework which makes it more difficult to change without modifying the javascript. In this case I chose to add a data attribute to the element to indicate which class will be set when the tab is selected. This means the javascript doesn&#039;t have to guess what the appropriate class is, it can just get it from the template.&lt;br /&gt;
&lt;br /&gt;
Ok, so we&#039;ve got our basic template. It&#039;s time to use it! Let&#039;s say we want to create a simple user profile page that might show 2 tabs, the first tab will be the user&#039;s name and the second tab will be the user&#039;s email address (please excuse the contrived example).&lt;br /&gt;
&lt;br /&gt;
Here&#039;s what the page might look like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&amp;lt;title&amp;gt;User Profile&amp;lt;/title&amp;gt;&amp;lt;/header&amp;gt;&lt;br /&gt;
    &amp;lt;body&amp;gt;&lt;br /&gt;
        {{&amp;lt; core/tabs }}&lt;br /&gt;
    &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That looks pretty simple! The only problem is, how do I get my content there? I would have to supply a context like this in order to display the tabs I want:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;tabs&amp;quot;: [&lt;br /&gt;
		{&amp;quot;id&amp;quot;:&amp;quot;tab1&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Name&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;Your name is Mr. Test User.&amp;quot;},&lt;br /&gt;
		{&amp;quot;id&amp;quot;:&amp;quot;tab2&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Email&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;Your email is testuser@example.com&amp;quot;},&lt;br /&gt;
	]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let&#039;s assume that the context for this page doesn&#039;t match what the tabs template is expecting though (as will be the case most of the time). Let&#039;s assume the tabs template is being rendered with this context:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;name&amp;quot;:&amp;quot;Mr. Test User&amp;quot;,&lt;br /&gt;
	&amp;quot;email&amp;quot;:&amp;quot;testuser@example.com&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unfortunately, we&#039;ll almost certainly never have complete control over all of the contexts that our template will be rendered in which means we&#039;ll be expecting people to write new webservices to supply the same data in different formats every time they want to use a template. It becomes an unmanageable problem.&lt;br /&gt;
&lt;br /&gt;
Enter blocks! We can make the template more flexible by defining sections of the template that can be overriden when they are included. Pretty neat! This will allow us to enforce a certain core structure but not enforce a context on the template that is including the tabs.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s have another go at that template, this time leverging blocks:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;{{ uniqid }}-tab-container&amp;quot;&amp;gt;&lt;br /&gt;
	{{$ tabheader }}&lt;br /&gt;
		&amp;lt;ul role=&amp;quot;tablist&amp;quot; class=&amp;quot;nav nav-tabs&amp;quot;&amp;gt;&lt;br /&gt;
			{{$ tablist }}&lt;br /&gt;
				{{# tabs }}&lt;br /&gt;
					&amp;lt;li role=&amp;quot;tab&amp;quot;&lt;br /&gt;
							data-target=&amp;quot;{{ uniqid }}-{{ id }}&amp;quot;&lt;br /&gt;
							data-selected-class=&amp;quot;active&amp;quot;&lt;br /&gt;
							aria-controls=&amp;quot;{{ uniqid }}-{{ id }}&amp;quot;&lt;br /&gt;
							aria-selected=&amp;quot;false&amp;quot; tabindex=&amp;quot;-1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
						&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;{{{ name }}}&amp;lt;/a&amp;gt;&lt;br /&gt;
					&amp;lt;/li&amp;gt;&lt;br /&gt;
				{{/ tabs }}&lt;br /&gt;
			{{/ tablist }}&lt;br /&gt;
		&amp;lt;/ul&amp;gt;&lt;br /&gt;
	{{/ tabheader }}&lt;br /&gt;
	{{$ tabbody }}&lt;br /&gt;
		&amp;lt;div class=&amp;quot;tab-content&amp;quot;&amp;gt;&lt;br /&gt;
			{{$ tabcontent }}&lt;br /&gt;
				{{# tabs }}&lt;br /&gt;
					&amp;lt;div role=&amp;quot;tabpanel&amp;quot;&lt;br /&gt;
						class=&amp;quot;tab-pane&amp;quot;&lt;br /&gt;
						id=&amp;quot;{{ uniqid }}-{{ id }}&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
						{{{ content }}}&lt;br /&gt;
					&amp;lt;/div&amp;gt;&lt;br /&gt;
				{{/ tabs }}&lt;br /&gt;
			{{/ tabcontent }}&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
	{{/ tabbody }}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
{{#js}}&lt;br /&gt;
    require([&#039;jquery&#039;,&#039;core/tabs&#039;], function($, tabs) {&lt;br /&gt;
&lt;br /&gt;
        var container = $(&amp;quot;#{{ uniqid }}-tab-container&amp;quot;);&lt;br /&gt;
        tabs.create(container);&lt;br /&gt;
    });&lt;br /&gt;
{{/js}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A summary of what we&#039;ve changed:&lt;br /&gt;
* Added a $tabheader block around the tab list, in case someone wants to change the ul element to something else.&lt;br /&gt;
* Added a $tablist block around the group of tabs to allow them to be overriden on incldue.&lt;br /&gt;
* Added a $tabbody block around the content, in case someone wants to change the content elements from divs.&lt;br /&gt;
* Added a $tabcontent block around the tab variable for the content to allow the content to be overriden on inlcude.&lt;br /&gt;
&lt;br /&gt;
Now let&#039;s see what using this template looks like for your User Profile page:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&amp;lt;title&amp;gt;User Profile&amp;lt;/title&amp;gt;&amp;lt;/header&amp;gt;&lt;br /&gt;
    &amp;lt;body&amp;gt;&lt;br /&gt;
        {{&amp;gt; core/tabs }}&lt;br /&gt;
			{{$ tablist }}&lt;br /&gt;
				&amp;lt;li role=&amp;quot;tab&amp;quot;&lt;br /&gt;
						data-target=&amp;quot;{{ uniqid }}-tab1&amp;quot;&lt;br /&gt;
						data-selected-class=&amp;quot;active&amp;quot;&lt;br /&gt;
						aria-controls=&amp;quot;{{ uniqid }}-tab1&amp;quot;&lt;br /&gt;
						aria-selected=&amp;quot;false&amp;quot; tabindex=&amp;quot;-1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
					&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;Name&amp;lt;/a&amp;gt;&lt;br /&gt;
				&amp;lt;/li&amp;gt;&lt;br /&gt;
				&amp;lt;li role=&amp;quot;tab&amp;quot;&lt;br /&gt;
						data-target=&amp;quot;{{ uniqid }}-tab2&amp;quot;&lt;br /&gt;
						data-selected-class=&amp;quot;active&amp;quot;&lt;br /&gt;
						aria-controls=&amp;quot;{{ uniqid }}-tab2&amp;quot;&lt;br /&gt;
						aria-selected=&amp;quot;false&amp;quot; tabindex=&amp;quot;-1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
					&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;Email&amp;lt;/a&amp;gt;&lt;br /&gt;
				&amp;lt;/li&amp;gt;&lt;br /&gt;
			{{/ tablist }}&lt;br /&gt;
			{{$ tabcontent }}&lt;br /&gt;
				&amp;lt;div role=&amp;quot;tabpanel&amp;quot;&lt;br /&gt;
					class=&amp;quot;tab-pane&amp;quot;&lt;br /&gt;
					id=&amp;quot;{{ uniqid }}-tab1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
					Your name is {{ name }}.&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div role=&amp;quot;tabpanel&amp;quot;&lt;br /&gt;
					class=&amp;quot;tab-pane&amp;quot;&lt;br /&gt;
					id=&amp;quot;{{ uniqid }}-tab2&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
					Your email address is {{ email }}.&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
			{{/ tabcontent }}&lt;br /&gt;
		{{/ core/tabs }}&lt;br /&gt;
    &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That looks a bit better! Now we&#039;ve been able to use the blocks to successfully change the template to use the context available to this page, we no longer need a &amp;quot;tabs&amp;quot; array with &amp;quot;name&amp;quot; and &amp;quot;content&amp;quot;. Even the javascript will continue to work because we&#039;ve kept the correct element attributes. &lt;br /&gt;
&lt;br /&gt;
We&#039;ve still got a slight problem though... In order to change the data for the template we&#039;ve had to copy &amp;amp; paste the HTML from the original template into our blocks as we do the override. While this works fine in this example, it means we don&#039;t quite get the encapsulation we want within the templates since we&#039;re leaking internal implementation details. If we ever wanted to change the CSS framework we use for Moodle (say from bootstrap 2 to boostrap 3 or 4) we&#039;d have to find all the places in the code where this tabs template is used and make sure that the HTML is correct in their block overrides.&lt;br /&gt;
&lt;br /&gt;
With that in mind, let&#039;s take one more pass at this template and see if we can improve it slightly again. This time we&#039;re doing to split the template out into 3 templates.&lt;br /&gt;
&lt;br /&gt;
tabs.mustache:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;{{ uniqid }}-tab-container&amp;quot;&amp;gt;&lt;br /&gt;
	{{$ tabheader }}&lt;br /&gt;
		&amp;lt;ul role=&amp;quot;tablist&amp;quot; class=&amp;quot;nav nav-tabs&amp;quot;&amp;gt;&lt;br /&gt;
			{{$ tablist }}&lt;br /&gt;
				{{# tabs }}&lt;br /&gt;
					{{&amp;gt; core/tab_header_item }}		&lt;br /&gt;
				{{/ tabs }}&lt;br /&gt;
			{{/ tablist }}&lt;br /&gt;
		&amp;lt;/ul&amp;gt;&lt;br /&gt;
	{{/ tabheader }}&lt;br /&gt;
	{{$ tabbody }}&lt;br /&gt;
		&amp;lt;div class=&amp;quot;tab-content&amp;quot;&amp;gt;&lt;br /&gt;
			{{$ tabcontent }}&lt;br /&gt;
				{{# tabs }}&lt;br /&gt;
					{{&amp;gt; core/tab_content_item }}&lt;br /&gt;
				{{/ tabs }}&lt;br /&gt;
			{{/ tabcontent }}&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
	{{/ tabbody }}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
{{#js}}&lt;br /&gt;
    require([&#039;jquery&#039;,&#039;core/tabs&#039;], function($, tabs) {&lt;br /&gt;
&lt;br /&gt;
        var container = $(&amp;quot;#{{ uniqid }}-tab-container&amp;quot;);&lt;br /&gt;
        tabs.create(container);&lt;br /&gt;
    });&lt;br /&gt;
{{/js}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tab_header_item.mustache&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;li role=&amp;quot;tab&amp;quot;&lt;br /&gt;
		data-selected-class=&amp;quot;active&amp;quot;&lt;br /&gt;
		aria-selected=&amp;quot;false&amp;quot; tabindex=&amp;quot;-1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;{{$ tabname }}{{{ name }}}{{/ tabname }}&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tab_content_item.mustache&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div role=&amp;quot;tabpanel&amp;quot;&lt;br /&gt;
	class=&amp;quot;tab-pane&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	{{$ tabpanelcontent }}{{{ content }}}{{/ tabpanelcontent }}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A summary of the changes:&lt;br /&gt;
* Split the template into 3, moving the tab into it&#039;s own template and the content into it&#039;s own and then including them in the tabs template.&lt;br /&gt;
* Removed the ids from the tabs and content. The javascript would be updating to assign these ids at runtime so that they don&#039;t need to be provided as part of the template context.&lt;br /&gt;
* Added a $tabname block for in the tab_header_item template to make the name flexible on import.&lt;br /&gt;
* Added a $tabpanelcontant block in the tab_content_item template to make the content flexible on import.&lt;br /&gt;
&lt;br /&gt;
Cool, so let&#039;s see what that looks like in our example now:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&amp;lt;title&amp;gt;User Profile&amp;lt;/title&amp;gt;&amp;lt;/header&amp;gt;&lt;br /&gt;
    &amp;lt;body&amp;gt;&lt;br /&gt;
        {{&amp;gt; core/tabs }}&lt;br /&gt;
			{{$ tablist }}&lt;br /&gt;
				{{&amp;lt; core/tab_header_item }}&lt;br /&gt;
					{{$ tabname }}Name{{/ tabname }}&lt;br /&gt;
				{{/ core/tab_header_item }}&lt;br /&gt;
				{{&amp;lt; core/tab_header_item }}&lt;br /&gt;
					{{$ tabname }}Email{{/ tabname }}&lt;br /&gt;
				{{/ core/tab_header_item }}&lt;br /&gt;
			{{/ tablist }}&lt;br /&gt;
			{{$ tabcontent }}&lt;br /&gt;
				{{&amp;lt; core/tab_content_item }}&lt;br /&gt;
					{{$ tabpanelcontent }}Your name is {{ name }}.{{/ tabpanelcontent }}&lt;br /&gt;
				{{/ core/tab_content_item }}&lt;br /&gt;
				{{&amp;lt; core/tab_content_item }}&lt;br /&gt;
					{{$ tabpanelcontent }}Your email address is {{ email }}.{{/ tabpanelcontent }}&lt;br /&gt;
				{{/ core/tab_content_item }}&lt;br /&gt;
			{{/ tabcontent }}&lt;br /&gt;
		{{/ core/tabs }}&lt;br /&gt;
    &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And we&#039;re done! After making the changes above we&#039;ve been able to keep the benefits of the previous change to allow the context changes but we&#039;ve also removed the need to copy &amp;amp; paste the HTML everywhere. Instead we&#039;re able to use the child templates with a few additional blocks defined to get the content in there.&lt;br /&gt;
&lt;br /&gt;
Now if we want to change tabs HTML or CSS frameworks we can just change the core tabs templates and this page will receive the updates for free.&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Git_for_developers&amp;diff=51744</id>
		<title>Git for developers</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Git_for_developers&amp;diff=51744"/>
		<updated>2017-01-20T20:48:39Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Keeping your public repository up-to-date */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document is for helping you get started on Moodle development with Git. For further details of Git, see [[:Category:Git]].&lt;br /&gt;
&lt;br /&gt;
== General workflow ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;A reasonable knowledge of the Git basics is a good idea before you start to use it for development. If you are new to Git, you are encouraged to go to &#039;See also&#039; for some more general reading.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[image:git-pushpull-model.png|right|thumb|400px|Moodle development workflow with Git]]&lt;br /&gt;
Detailed explanation of the workflow can be found in the [[Process]] page. In short, the Moodle development with Git looks like this:&lt;br /&gt;
&lt;br /&gt;
* You as the contributor commit changes into your personal repository at your computer&lt;br /&gt;
* You push the changes into your public repository and publish links to your changes in the Moodle Tracker&lt;br /&gt;
* You request a peer review of your code from another developer&lt;br /&gt;
* When peer reviewer is happy they submit issue for integration&lt;br /&gt;
* Moodle integrators pull the changes from your public repository and if they like them, they put them into Moodle integration repository&lt;br /&gt;
* The integrated change is tested and finally pushed into Moodle production repository&lt;br /&gt;
* You update your local repository with all changes from the production repository and the next cycle may start again&lt;br /&gt;
&lt;br /&gt;
This workflow runs in roughly weekly cycles. The integration happens on Monday and Tuesday and the testing on Wednesday. On Thursday (or Friday if testing takes too long), the production repository moodle.git is usually updated with changes from the last development week.&lt;br /&gt;
&lt;br /&gt;
Most Moodle developers have their public repositories hosted at [http://github.com/ Github]. Alternatively you may want to try [http://gitorious.org Gitorious] or the legendary [http://repo.or.cz repo.or.cz]. In the examples in this guide we assume you&#039;ll set up your public repository at Github.&lt;br /&gt;
&lt;br /&gt;
When you first register on tracker you can not assign issues to yourself or send them for peer review. You will be added to the developers group after your first bug fix is integrated. Before that just comment on the issue with a link to your branch and component lead or another developer will send issue for peer review for you.&lt;br /&gt;
&lt;br /&gt;
== Installing Git on your computer ==&lt;br /&gt;
&lt;br /&gt;
Install Git on your computer. Most Linux distributions have Git available as a package to install. On Debian/Ubuntu, type &#039;&#039;&#039;&#039;sudo apt-get install git&#039;&#039;&#039;&#039; on the terminal. If you are on Mac, [http://code.google.com/p/git-osx-installer/ git-osx-installer] installs it in a few clicks. &lt;br /&gt;
&lt;br /&gt;
Immediately after the installation, set your name and contact e-mail. The name and e-mail will become part of your commits and they can&#039;t be changed later once your commits are accepted into the Moodle code. Therefore we ask contributors to use their real names written in capital letters, eg &amp;quot;John Smith&amp;quot; and not &amp;quot;john smith&amp;quot; or even &amp;quot;john5677&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
    git config --global user.name &amp;quot;Your Name&amp;quot;&lt;br /&gt;
    git config --global user.email yourmail@domain.tld&lt;br /&gt;
&lt;br /&gt;
Unless you are the repository maintainer, it is wise to set your Git to not push changes in file permissions:&lt;br /&gt;
&lt;br /&gt;
    git config --global core.filemode false&lt;br /&gt;
&lt;br /&gt;
Also, it&#039;s recommended to verify that the your git installation is not performing any transformation between LFs and CRLFs. All Moodle &#039;&#039;&#039;uses only LFs&#039;&#039;&#039; and you should &#039;&#039;&#039;fetch/edit and push&#039;&#039;&#039; it that way (may need to configure your editor/IDE too). Note that having any &amp;quot;magic&amp;quot; enabled is known to cause [[Common unit test problems#The_test_file_.22evolution.test.22_should_not_contain_section_named_.22.5Blots_of_content.5D.22|problems with unit tests]] execution. So we recommend you to set:&lt;br /&gt;
&lt;br /&gt;
    git config --global core.autocrlf false&lt;br /&gt;
&lt;br /&gt;
== Setting-up the public repository ==&lt;br /&gt;
&lt;br /&gt;
1. Go to [http://github.com/ Github] and create an account.&lt;br /&gt;
&lt;br /&gt;
2. Go to the [http://github.com/moodle/moodle official Moodle Github repository] and click on the Fork button. You now have your own Github Moodle repository.&lt;br /&gt;
&lt;br /&gt;
3. Now you need to set up your SSH public key, so you can push to your Github Moodle repository from your local Moodle repository. On Mac you can go on this [http://help.github.com/mac-key-setup/ Github help page]. If you are on another system, go to your Github administration page, to the section SSH Public Keys, and you should see a link to a help page. Done? Good! That was the most difficult part!&lt;br /&gt;
&lt;br /&gt;
== Setting-up the local repository at your computer  ==&lt;br /&gt;
&lt;br /&gt;
Create a local clone repository of your Github repository. In a terminal:&lt;br /&gt;
&lt;br /&gt;
    git clone git://github.com/YOUR_GITHUB_USERNAME/moodle.git LOCALDIR&lt;br /&gt;
&lt;br /&gt;
    (or:  git clone git@github.com:YOUR_GITHUB_USERNAME/moodle.git LOCALDIR)&lt;br /&gt;
&lt;br /&gt;
This command does several jobs for you. It creates a new folder, initializes an empty Git repository in it, sets your Github repository as the remote repository called &#039;origin&#039; and makes a local checkout of the branch &#039;master&#039; from it. The important point to remember now is that your Github repository is aliased as &#039;origin&#039; for your local clone.&lt;br /&gt;
&lt;br /&gt;
Note that the format of the URL here is important. In the first example, the URL starts &amp;quot;git://github.com&amp;quot; and this will give read-only access to the repository at github.com. If you use this URL, the &amp;quot;git push origin&amp;quot; command that appears later in this document will not work. Therefore, if you want to be able to update the &amp;quot;origin&amp;quot; repository, you should use the URL that starts &amp;quot;git@github.com&amp;quot;, i.e. the second of the two &amp;quot;git clone&amp;quot; commands given above. This will give you read and write access to the repository on github.com.&lt;br /&gt;
&lt;br /&gt;
== Keeping your public repository up-to-date ==&lt;br /&gt;
&lt;br /&gt;
[[image:git-sync-github.png|right|thumb|400px|Fetching changes from upstream and pushing them to github]]&lt;br /&gt;
Your fork at Github is not updated automatically. To keep it synced with the upstream Moodle repository, you have to fetch the recent changes from the official moodle.git and push them to your public repository. To avoid problems with this it is strongly recommended that you never modify the standard Moodle branches. &#039;&#039;Remember: never commit directly into master and MOODLE_xx_STABLE branches.&#039;&#039; In other words, always create topic branches to work on. In Gitspeak, the master branch and MOODLE_xx_STABLE branches should be always fast-forwardable.&lt;br /&gt;
&lt;br /&gt;
To keep your public repository up-to-date, we will register remote repository git://git.moodle.org/moodle.git under &#039;upstream&#039; alias. Then we create a script to be run regularly that fetches changes from the upstream repository and pushes them to your public repository. Note that this procedure will not affect your local working directory.&lt;br /&gt;
&lt;br /&gt;
To register the upstream remote:&lt;br /&gt;
&lt;br /&gt;
    cd moodle&lt;br /&gt;
    git remote add upstream git://git.moodle.org/moodle.git&lt;br /&gt;
&lt;br /&gt;
The following commands can be used to keep the standard Moodle branches at your Github repository synced with the upstream repository. You may wish to store them in a script so that you can run it every week after the upstream repository is updated.&lt;br /&gt;
&lt;br /&gt;
    #!/bin/bash&lt;br /&gt;
    git fetch upstream&lt;br /&gt;
    for BRANCH in MOODLE_{19..32}_STABLE master; do&lt;br /&gt;
        git push origin refs/remotes/upstream/$BRANCH:$BRANCH&lt;br /&gt;
    done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== How it works ===&lt;br /&gt;
&lt;br /&gt;
The git-fetch command does not modify your current working dir (your checkout). It just downloads all recent changes from a remote repository and stores them into so called remote-tracking branches. The git-push command takes these remote-tracking branches from upstream and pushes them to Github under the same name. Understanding this fully requires a bit knowledge of Git internals - see gitrevisions(7) man page.&lt;br /&gt;
&lt;br /&gt;
Note there is no need to switch the local branch during this. You can even execute this via cron at your machine. Just note that the upstream repository updates typically just once a week.&lt;br /&gt;
&lt;br /&gt;
=== New branches ===&lt;br /&gt;
&lt;br /&gt;
Occasionally, moodle.org will create a new branch that does not exist in your public (e.g. Github.com) repository. If you try to push this new branch, you will see an error such as the following:&lt;br /&gt;
&lt;br /&gt;
    error: unable to push to unqualified destination: MOODLE_99_STABLE&lt;br /&gt;
    The destination refspec neither matches an existing ref on the remote&lt;br /&gt;
    nor begins with refs/, and we are unable to guess a prefix based on the source ref.&lt;br /&gt;
    error: failed to push some refs to &#039;git@github.com:YOUR_GITHUB_USERNAME/moodle.git&#039;&lt;br /&gt;
&lt;br /&gt;
In the above example, &amp;quot;MOODLE_99_STABLE&amp;quot;, is the name of the new branch that does not exist in your public repository. To fix the error, you need to create the new branch on your public repository, using the following commands, replacing &amp;quot;MOODLE_99_STABLE&amp;quot; with the name of the new branch you wish to create:&lt;br /&gt;
&lt;br /&gt;
    git checkout MOODLE_99_STABLE&lt;br /&gt;
    git push origin MOODLE_99_STABLE:MOODLE_99_STABLE&lt;br /&gt;
&lt;br /&gt;
The above code will create a new copy of the &amp;quot;MOODLE_99_STABLE&amp;quot; branch in your local repository. If you do not need to keep a local copy of the new branch - and probably you do not need it, you then can remove it from your local repository as follows:&lt;br /&gt;
&lt;br /&gt;
    git checkout master&lt;br /&gt;
    git branch -D MOODLE_99_STABLE&lt;br /&gt;
&lt;br /&gt;
== Preparing a patch ==&lt;br /&gt;
&lt;br /&gt;
As said earlier at this page, you never work on standard Moodle branches directly. Every time you are going to edit something, switch to a local branch. Fork the local branch off the standard branch you think it should be merged to. So if you are working on a patch for 1.9 or 2.0, fork the branch off MOODLE_19_STABLE or MOODLE_20_STABLE, respectively. Patches for the next [[Moodle versions|major version]] should be based on the master branch.&lt;br /&gt;
&lt;br /&gt;
    git checkout -b MDL-xxxxx-nasty-bug origin/master&lt;br /&gt;
&lt;br /&gt;
Note that if you forget to specify the starting point, the branch is based on the currently checked-out branch. It may not be what you want. It is recommended to always specify the starting point.&lt;br /&gt;
&lt;br /&gt;
To check the current branch, run&lt;br /&gt;
&lt;br /&gt;
    git branch&lt;br /&gt;
&lt;br /&gt;
The current branch is highlighted.&lt;br /&gt;
&lt;br /&gt;
Now go and fix the issue with your favorite IDE. Check the status of the files, view the change to be committed and finally commit the change:&lt;br /&gt;
&lt;br /&gt;
    vim filename.php&lt;br /&gt;
    git status&lt;br /&gt;
    git diff&lt;br /&gt;
    git commit -a&lt;br /&gt;
&lt;br /&gt;
Note that this is safe as the commit is recorded just locally, nothing is sent to any server yet (as it would in CVS). To see history of the commits, use&lt;br /&gt;
&lt;br /&gt;
    git log&lt;br /&gt;
&lt;br /&gt;
Once your local branch contains the change (note that it may consists of several patches) and you are happy with it, publish the branch at your public repository:&lt;br /&gt;
&lt;br /&gt;
    git push origin MDL-xxxxx-nasty-bug&lt;br /&gt;
&lt;br /&gt;
Now as your branch is published, you can ask Moodle core developers to review it and eventually integrate it into the standard Moodle repository.&lt;br /&gt;
&lt;br /&gt;
=== Changing commit message, reordering and squashing commits ===&lt;br /&gt;
&lt;br /&gt;
It often happens that you made a mistake in your patch or in the commit message and helpful CiBot pointed it out for you. You can &amp;quot;rewrite the history&amp;quot; and change the existing commits.&lt;br /&gt;
&lt;br /&gt;
Option 1. Reset all the changes in the branch and commit again. &lt;br /&gt;
&lt;br /&gt;
    git reset --mixed origin/master&lt;br /&gt;
&lt;br /&gt;
Now all your changes are still present but all commits on top of &amp;quot;master&amp;quot; branch are gone. You can create a new commit&lt;br /&gt;
&lt;br /&gt;
Option 2. Discover &#039;&#039;&#039;git rebase&#039;&#039;&#039; - this is a powerful tool to change the sequence of commit, change the commit messages, squash commits, etc. We will not cover it here, there are many articles in the Internet about it.&lt;br /&gt;
&lt;br /&gt;
Whatever option you chose, you have &amp;quot;rewritten the history&amp;quot; and you can not simply push the changes to github again because they would need to overwrite the commits that were already pushed. If you try &amp;quot;git push MDL-xxxxx-nasty-bug&amp;quot; you will get an error message suggesting you to force push. &lt;br /&gt;
To force push the changed commits use:&lt;br /&gt;
&lt;br /&gt;
    git push -f origin MDL-xxxxx-nasty-bug&lt;br /&gt;
&lt;br /&gt;
If an error occurs because you are still using the git protocol (read only), use this command : &lt;br /&gt;
&lt;br /&gt;
    git remote set-url origin https://github.com/&amp;lt;user.name&amp;gt;/moodle.git&lt;br /&gt;
&lt;br /&gt;
A prompt will ask for your credentials, if you previously setup your SSH public key you can also use this one : &lt;br /&gt;
&lt;br /&gt;
    git remote set-url origin git@github.com:&amp;lt;user.name&amp;gt;/moodle.git&lt;br /&gt;
&lt;br /&gt;
=== Checking if a branch has already been merged ===&lt;br /&gt;
&lt;br /&gt;
After some time contributing to Moodle you would have a lot of branches both in your local repository and in your public repository. To prune their list and delete those that were accepted by upstream, use the following&lt;br /&gt;
&lt;br /&gt;
    git fetch upstream                                      (1)&lt;br /&gt;
    git branch --merged upstream/master                     (2)&lt;br /&gt;
    git branch --merged upstream/MOODLE_20_STABLE           (3)&lt;br /&gt;
&lt;br /&gt;
The command (1) fetches the changes from your upstream repository at git.moodle.org (remember that git-fetch does not modify your working dir so it is safe to run it whenever). Command (2) and (3) print all branches that are merged into the upstream master branch and MOODLE_20_STABLE branch, respectively. To delete these local branches, use&lt;br /&gt;
&lt;br /&gt;
    git branch -d MDL-xxxxx-accepted-branch&lt;br /&gt;
&lt;br /&gt;
The similar approach can be used to check the branches published at your origin repository at github.com&lt;br /&gt;
&lt;br /&gt;
    git fetch origin                                        (1)&lt;br /&gt;
    git fetch upstream&lt;br /&gt;
    git branch -r --merged upstream/master                  (2)&lt;br /&gt;
    git branch -r --merged upstream/MOODLE_20_STABLE        (3)&lt;br /&gt;
&lt;br /&gt;
The command (1) makes sure that you have all your branches from github.com recorded as the remote tracking branch locally. Commands (2) and (3) work the same as in the previous example but they list remote tracking branches only ([http://www.kernel.org/pub/software/scm/git/docs/git-branch.html see -r param]). To delete a branch at github.com, use&lt;br /&gt;
&lt;br /&gt;
    git push origin :MDL-xxxx-branch-to-delete&lt;br /&gt;
&lt;br /&gt;
This syntax may look weird to you. However it is pretty logical. The general syntax of the git-push command is&lt;br /&gt;
&lt;br /&gt;
    git push &amp;lt;repository&amp;gt; &amp;lt;source ref&amp;gt;:&amp;lt;target ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
so deleting a remote branch can be understood as pushing an &amp;quot;empty (null) reference&amp;quot; to it.&lt;br /&gt;
&lt;br /&gt;
== Peer-reviewing someone else&#039;s code ==&lt;br /&gt;
&lt;br /&gt;
To review a branch that someone else pushed into their public repository, you do not need to register a new remote (unless you work with such repository frequently, of course). Let us imagine your friend Alice pushed a work-in-progress branch called &#039;wip-feature&#039; into her Github repository and asked you to review it. You need to know the read-only address of the repository and the name of the branch.&lt;br /&gt;
&lt;br /&gt;
    git fetch git://github.com/alice/moodle.git wip-feature&lt;br /&gt;
&lt;br /&gt;
This will download all required data and will keep the pointer to the tip of the wip-feature branch in a local symbolic reference FETCH_HEAD. To see what&#039;s there on that branch, use&lt;br /&gt;
&lt;br /&gt;
    git log -p FETCH_HEAD&lt;br /&gt;
&lt;br /&gt;
To see how a particular file looks at Alice&#039;s branch&lt;br /&gt;
&lt;br /&gt;
    git show FETCH_HEAD:admin/blocks.php&lt;br /&gt;
&lt;br /&gt;
To create a new local branch called &#039;alice-wip-feature&#039; containing the work by Alice, use&lt;br /&gt;
&lt;br /&gt;
    git checkout -b alice-wip-feature FETCH_HEAD&lt;br /&gt;
&lt;br /&gt;
To merge Alice&#039;s work into your current branch:&lt;br /&gt;
&lt;br /&gt;
    git merge FETCH_HEAD&lt;br /&gt;
&lt;br /&gt;
To see what would be merged into the current branch without actually modifying anything:&lt;br /&gt;
&lt;br /&gt;
    git diff ...FETCH_HEAD&lt;br /&gt;
&lt;br /&gt;
Once you are all set and reviewing code, this [[Peer_reviewing_checklist|checklist]] should prove to be useful.&lt;br /&gt;
&lt;br /&gt;
== Rebasing a branch ==&lt;br /&gt;
&lt;br /&gt;
Rebasing is a process when you cut off the branch from its current start point and transplant it to another point. Let us assume the following history exists:&lt;br /&gt;
&lt;br /&gt;
          A---B---C topic&lt;br /&gt;
         /&lt;br /&gt;
    D---E---F---G master&lt;br /&gt;
&lt;br /&gt;
From this point, the result of the command:&lt;br /&gt;
&lt;br /&gt;
    git rebase master topic&lt;br /&gt;
&lt;br /&gt;
would be:&lt;br /&gt;
&lt;br /&gt;
                  A&#039;--B&#039;--C&#039; topic&lt;br /&gt;
                 /&lt;br /&gt;
    D---E---F---G master&lt;br /&gt;
&lt;br /&gt;
and would end with &#039;topic&#039; being your current branch.&lt;br /&gt;
&lt;br /&gt;
You may be asked to rebase your branch submitted for the integration if the submitted branch was based on an outdated commit. The typical case is if you create a new branch as a fork off the upstream master branch on Tuesday. Then on Wednesday, the upstream master branch grows as all changes from the last integration cycle are merged to it. To make diff easy on Github for next weekly pull request review, you want to rebase your branch against the updated master.&lt;br /&gt;
&lt;br /&gt;
    git rebase master MDL-xxxxx-topic-branch&lt;br /&gt;
&lt;br /&gt;
Note that rebasing effectively rewrites the history of the branch. &#039;&#039;&#039;Do not rebase the branch if there is a chance that somebody has already forked it and based their own branch on it.&#039;&#039;&#039; For this reason, many Git tutorials discourage from rebasing any branch that has been published. However in Moodle, all branches submitted for integration are potential subject of rebase (even though we try to not to do it often) and you should not base your own branches on them.&lt;br /&gt;
&lt;br /&gt;
=== Conflicts during rebase ===&lt;br /&gt;
&lt;br /&gt;
During the rebase procedure, conflicts may appear. git-status commands reports the conflicted files. Explore them carefully and fix them in your editor (like you would do with CVS). Then add the files with &#039;git add&#039; command and continue.&lt;br /&gt;
&lt;br /&gt;
    vim conflicted.php&lt;br /&gt;
    git add conflicted.php&lt;br /&gt;
    git rebase --continue&lt;br /&gt;
&lt;br /&gt;
== Applying changes from one branch to another ==&lt;br /&gt;
&lt;br /&gt;
Most bugs are fixed at a stable branch (like MOODLE_20_STABLE) and the fix must be prepared for other branches, too (like MOODLE_21_STABLE and the main development branch - master). In Moodle, we do not merge stable branches into the master one. So usually the contributor prepares at least two branches - with the fix for the stable branch(es) and with the fix for the master branch.&lt;br /&gt;
&lt;br /&gt;
If you have a patch prepared on a local branch (let us say MDL-xxxx-topic_20_STABLE), it is possible to re-apply it to another branch.&lt;br /&gt;
&lt;br /&gt;
=== Cherry-picking a single commit ===&lt;br /&gt;
&lt;br /&gt;
Let us have two local Git repositories ~/public_html/moodle21 containing local installation of Moodle 2.1 and ~/public_html/moodledev with the local installation of most recent development version of Moodle. They both use your public repository at github.com as the origin. You have a branch in moodle21 called MDL-xxxx-topic_21_STABLE that was forked off MOODLE_21_STABLE. It contains one commit. Now you want to re-apply this commit to a branch MDL-xxxx-topic in moodledev.&lt;br /&gt;
&lt;br /&gt;
    cd ~/public_html/moodledev&lt;br /&gt;
    git checkout -b MDL-xxxx-topic origin/master            (1)&lt;br /&gt;
    git fetch ../moodle21 MDL-xxxx-topic_21_STABLE          (2)&lt;br /&gt;
    git cherry-pick FETCH_HEAD                              (3)&lt;br /&gt;
&lt;br /&gt;
The command (1) creates new local branch forked off the CONTHERE The command (1) fetches all data needed to re-apply the topic branch and stores the pointer to the tip of that branch to FETCH_HEAD symbolic reference. The command (2) picks the tip of the branch (the top-most commit on it) and tries to apply it on the current branch.&lt;br /&gt;
There is also a variant of the cherry-pick command that supports multiple commits, shortly (see its man page for details): &amp;lt;code bash&amp;gt;$ git cherry-pick A^..B&amp;lt;/code&amp;gt; if you want to include from A - see &#039;&#039;&#039;^&#039;&#039;&#039; - to B, A should be older than B. We will use another approach for cherry-picking multiple commits.&lt;br /&gt;
&lt;br /&gt;
=== Applying a set of patches ===&lt;br /&gt;
&lt;br /&gt;
If the branch MDL-xxxx-topic_21_STABLE from the previous example consists of several commits, it may be easier to use git-format-patch and git-am combo to re-apply the whole set of patches (aka patchset). Firstly you will export all commits from the topic branch to files.&lt;br /&gt;
&lt;br /&gt;
    cd ~/public_html/moodle21&lt;br /&gt;
    mkdir .patches&lt;br /&gt;
    git format-patch -o .patches MOODLE_21_STABLE..MDL-xxxx-topic_21_STABLE         (1)&lt;br /&gt;
&lt;br /&gt;
The command (1) takes all commits from the topic branch that are not in MOODLE_21_STABLE and exports them one by one to the output directory .patches. Look at the generated files. They contain the patch itself (in diff format) and additional information about the commit. You could eg send these files by email to a friend of yours for peer-review. We will use them in another repository.&lt;br /&gt;
&lt;br /&gt;
    cd ~/public_html/moodledev&lt;br /&gt;
    git checkout -b MDL-xxxx-topic origin/master&lt;br /&gt;
    git am -3 ../moodle21/.patches/*                        (1)&lt;br /&gt;
&lt;br /&gt;
The command (1) applies all the files from the .patches directory. When a patch does not apply cleanly, the command tries fall back on 3-way merge (see the -3 parameter). If conflicts occur during the procedure, you can either deal with them and then use `git am --continue` or abort the whole procedure with `git am --abort`.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
; Moodle forum discussions&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=168094 GIT help needed]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=165236 Best way to manage CONTRIB code with GIT]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=167063 Handy Git tip for tracking 3rd-party modules and plugins]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=167730 Moodle Git repositories]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=183409 Git help!! I don&#039;t understand rebase enough...]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=217617 add MOODLE_24_STABLE to github.com repository]&lt;br /&gt;
&lt;br /&gt;
; External resources &lt;br /&gt;
* [http://www.kernel.org/pub/software/scm/git/docs/everyday.html Everyday GIT With 20 Commands Or So]&lt;br /&gt;
* [http://gitref.org/ Git Reference]&lt;br /&gt;
* [http://progit.org/book/ Pro Git book]&lt;br /&gt;
* [http://vimeo.com/14629850 Getting git by Scott Chacon] - an recording of an excellent 1-hour presentation that introducing git, including a simple introduction to what is going on under the hood.&lt;br /&gt;
* [http://tjhunt.blogspot.co.uk/2012/03/fixing-bug-in-moodle-core-mechanics.html Tim Hunt&#039;s blog: Fixing a bug in Moodle core: the mechanics]&lt;br /&gt;
&lt;br /&gt;
[[Category:Git]]&lt;br /&gt;
&lt;br /&gt;
[[ja:開発者用Git]]&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=LTI_Improvements_3.2_Project&amp;diff=50751</id>
		<title>LTI Improvements 3.2 Project</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=LTI_Improvements_3.2_Project&amp;diff=50751"/>
		<updated>2016-08-06T07:04:10Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Summary */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Improvements to LTI for 3.2&lt;br /&gt;
|state = Developing&lt;br /&gt;
|tracker = MDL-54679&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=xxx&lt;br /&gt;
|assignee = [[User:John Okely]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
= Summary =&lt;br /&gt;
The Learning Tools Interoperability (LTI) provider was added to Moodle 3.1 - but unfortunately our LTI provider and consumer do not support the same standards, and as such are missing important functionality, therefore they need usability improvements. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Below are a range of issues that have been identified and are being worked on for Moodle 3.2.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Improvements ==&lt;br /&gt;
The targeted improvements for 3.2 are:&lt;br /&gt;
* Offer cartridges in LTI provider&lt;br /&gt;
* &amp;lt;strike&amp;gt;Support standard icon element when importing LTI cartridges&amp;lt;/strike&amp;gt;&lt;br /&gt;
* Upgrade enrol_lti to support LTI v2.0&lt;br /&gt;
* Ensure enrol_lti member syncronisation task works as expected&lt;br /&gt;
* Content Item support&lt;br /&gt;
* Add support for LTI Outcomes Management 2 services&lt;br /&gt;
* Caliper Analytics&lt;br /&gt;
* Run the LTI Test suite against Moodle (consumer + provider) and create issues for any failures (in this Epic)&lt;br /&gt;
* Fix auto-closing LTI config window&lt;br /&gt;
* Improve interface for managing course tools&lt;br /&gt;
* Add support for services via LTI1 (LTI1.2 spec)&lt;br /&gt;
* Improve accessibility of new LTI admin screen&lt;br /&gt;
&lt;br /&gt;
To see the most recent set of issues and status of the project see https://tracker.moodle.org/browse/MDL-54679&lt;br /&gt;
&lt;br /&gt;
==Progress==&lt;br /&gt;
* Cartridges patch is completed, waiting for integration review&lt;br /&gt;
* A Content-Item patch was started by Stephen Vickers. The patch has been altered and refactored. Working on automated testing now&lt;br /&gt;
* A patch has been created using the new LTI library provided by IMS to bring the provider up to LTI 2.&lt;br /&gt;
* Membership synchronisation is being looked at in conjunction with LTI2&lt;br /&gt;
&lt;br /&gt;
==Prototype==&lt;br /&gt;
The [http://prototype.moodle.net/lti/ work in progress prototype] is available to view on the prototype site.&lt;br /&gt;
You can add tools via tool proxy, and via cartridge. You can configure a tool type when you add it using Content-item&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Theme_checklist&amp;diff=50621</id>
		<title>Theme checklist</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Theme_checklist&amp;diff=50621"/>
		<updated>2016-07-14T18:46:51Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Quiz &amp;#039;secure&amp;#039; pop-up */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}So, you think your theme is finished? Well, Moodle is a big complex system and there are lots of obscure corners that you might not know about. This page lists lots of things that you might have missed when working on your theme. To be sure your theme is really complete, you need to check these out.&lt;br /&gt;
&lt;br /&gt;
== Accessible colours ==&lt;br /&gt;
&lt;br /&gt;
Are the colours you have chosen accessible?  Is there a reasonable contrast difference between them?&lt;br /&gt;
&lt;br /&gt;
== All the different forms of the front page ==&lt;br /&gt;
&lt;br /&gt;
Depending on how many courses there are in your Moodle site, and how many of them the current user is enrolled in, the [[:en:Front_page|front page]] looks different. Have you tested all the different ways it can look?&lt;br /&gt;
&lt;br /&gt;
== Big report tables ==&lt;br /&gt;
&lt;br /&gt;
The [[:en:Gradebook|grader report]], and other similar reports like the quiz reports, are very big tables that don&#039;t fit on one screen. How does your theme cope. Is it easy for the teacher to scroll sideways to see all the data?&lt;br /&gt;
&lt;br /&gt;
== Clean install ==&lt;br /&gt;
&lt;br /&gt;
Have you installed and un-installed the theme on a &#039;pure&#039; installation?  That is an installation with no other contributed plugins.  This allows you to check for unintentional dependencies.&lt;br /&gt;
&lt;br /&gt;
== Code checker ==&lt;br /&gt;
&lt;br /&gt;
[https://moodle.org/plugins/view.php?plugin=local_codechecker Code checker] checks your code against the Moodle [https://docs.moodle.org/dev/Coding coding standards].  It is a useful tool for spotting issues and making your code readable to all who are familiar with the core code.  Do not take all messages literally, use your common sense and make changes that are sensible.&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
Have you specified the correct dependencies for both parent themes and Moodle in the &#039;[https://docs.moodle.org/dev/version.php version.php]&#039; file?&lt;br /&gt;
&lt;br /&gt;
== Fake blocks ==&lt;br /&gt;
&lt;br /&gt;
While you are looking at the quiz, pay attention to the [[:en:Using_Quiz|Quiz navigation block]]. This is not a normal block that teachers or admins can add or remove, it is a &#039;Fake block&#039; that looks like any other block but is part of the Moodle UI. Are you happy with where it appears, and how it looks?&lt;br /&gt;
&lt;br /&gt;
Other parts of Moodle that use fake blocks are the [[:en:Lesson_module|Lesson activity]] and [[:en:Calendar|the calendar UI]].&lt;br /&gt;
&lt;br /&gt;
Fake blocks are attached to the first region or the &#039;defaultregion&#039; in the &#039;regions&#039; array for the &#039;layout&#039; in the &#039;layouts&#039; array in the &#039;config.php&#039; file.  So if the order is (&#039;side-pre&#039;, &#039;side-post&#039;) and you want fake blocks to be in &#039;side-post&#039; change the &#039;defaultregion&#039; to &#039;side-post&#039; and the &#039;regions&#039; array to (&#039;side-post&#039;, &#039;side-pre&#039;).&lt;br /&gt;
&lt;br /&gt;
===Adding a fake block to each pagelayout in your theme:===&lt;br /&gt;
(add following function to theme/yourtheme/lib.php)&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function theme_yourtheme_get_html_for_settings(renderer_base $output, moodle_page $page) function:&lt;br /&gt;
&lt;br /&gt;
$bc = new block_contents();&lt;br /&gt;
$bc-&amp;gt;title = &#039;fake title&#039;;&lt;br /&gt;
$bc-&amp;gt;attributes[&#039;class&#039;] = &#039;fakeblock&#039;;&lt;br /&gt;
$bc-&amp;gt;content = &#039;fake content&#039;;&lt;br /&gt;
$page-&amp;gt;blocks-&amp;gt;add_fake_block($bc, &#039;side-pre&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Instructions ==&lt;br /&gt;
&lt;br /&gt;
Have you provided a &#039;readme&#039; file containing: Install instructions, un-install instructions, version history and contact details for when things go wrong.&lt;br /&gt;
&lt;br /&gt;
== License ==&lt;br /&gt;
&lt;br /&gt;
Is all code GPLv3 (or compatible) licensed?&lt;br /&gt;
&lt;br /&gt;
== Maturity ==&lt;br /&gt;
&lt;br /&gt;
Have you correctly stated the maturity of the theme in the &#039;[https://docs.moodle.org/dev/version.php version.php]&#039; file?  This gives users and idea of how stable the code is.&lt;br /&gt;
&lt;br /&gt;
== Quiz &#039;secure&#039; pop-up ==&lt;br /&gt;
&lt;br /&gt;
When a quiz is set to [[:en:Quiz_settings#Extra_restrictions_on_attempts|Full screen pop-up with some JavaScript security]] then the page uses a special &#039;secure&#039; layout template that should have minimal headers. NO footer and NO external links whatsoever.&lt;br /&gt;
See Clean theme secure.php [https://github.com/moodle/moodle/blob/master/theme/clean/layout/secure.php]&lt;br /&gt;
&lt;br /&gt;
== Readable fonts ==&lt;br /&gt;
&lt;br /&gt;
Are the fonts you have chosen readable?  Will they be difficult to read on small devices?&lt;br /&gt;
&lt;br /&gt;
== Right-to-left languages ==&lt;br /&gt;
&lt;br /&gt;
In languages like Hebrew or Farsi, lots of things that you made left-aligned probably need to be right-aligned instead. Moodle adds .dir-rtl or .dir-ltr class to the body element, which you can use in CSS rules.&lt;br /&gt;
&lt;br /&gt;
== Responsive ==&lt;br /&gt;
&lt;br /&gt;
Have you tested your theme for responsiveness on small devices?  Try resizing the browser window and see how it reacts.&lt;br /&gt;
&lt;br /&gt;
== Theme developer mode ==&lt;br /&gt;
&lt;br /&gt;
When &#039;Theme developer mode&#039; is &#039;on&#039;, all of the CSS files are sent individually.  When it is &#039;off&#039;, they are all combined together.  This can lead to some issues.  Check that your theme works with &#039;Theme designer mode off&#039;.&lt;br /&gt;
&lt;br /&gt;
== ... please add more things here in alphabetical order ... ==&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Theme_checklist&amp;diff=50620</id>
		<title>Theme checklist</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Theme_checklist&amp;diff=50620"/>
		<updated>2016-07-14T18:44:18Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Quiz &amp;#039;secure&amp;#039; pop-up */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}So, you think your theme is finished? Well, Moodle is a big complex system and there are lots of obscure corners that you might not know about. This page lists lots of things that you might have missed when working on your theme. To be sure your theme is really complete, you need to check these out.&lt;br /&gt;
&lt;br /&gt;
== Accessible colours ==&lt;br /&gt;
&lt;br /&gt;
Are the colours you have chosen accessible?  Is there a reasonable contrast difference between them?&lt;br /&gt;
&lt;br /&gt;
== All the different forms of the front page ==&lt;br /&gt;
&lt;br /&gt;
Depending on how many courses there are in your Moodle site, and how many of them the current user is enrolled in, the [[:en:Front_page|front page]] looks different. Have you tested all the different ways it can look?&lt;br /&gt;
&lt;br /&gt;
== Big report tables ==&lt;br /&gt;
&lt;br /&gt;
The [[:en:Gradebook|grader report]], and other similar reports like the quiz reports, are very big tables that don&#039;t fit on one screen. How does your theme cope. Is it easy for the teacher to scroll sideways to see all the data?&lt;br /&gt;
&lt;br /&gt;
== Clean install ==&lt;br /&gt;
&lt;br /&gt;
Have you installed and un-installed the theme on a &#039;pure&#039; installation?  That is an installation with no other contributed plugins.  This allows you to check for unintentional dependencies.&lt;br /&gt;
&lt;br /&gt;
== Code checker ==&lt;br /&gt;
&lt;br /&gt;
[https://moodle.org/plugins/view.php?plugin=local_codechecker Code checker] checks your code against the Moodle [https://docs.moodle.org/dev/Coding coding standards].  It is a useful tool for spotting issues and making your code readable to all who are familiar with the core code.  Do not take all messages literally, use your common sense and make changes that are sensible.&lt;br /&gt;
&lt;br /&gt;
== Dependencies ==&lt;br /&gt;
&lt;br /&gt;
Have you specified the correct dependencies for both parent themes and Moodle in the &#039;[https://docs.moodle.org/dev/version.php version.php]&#039; file?&lt;br /&gt;
&lt;br /&gt;
== Fake blocks ==&lt;br /&gt;
&lt;br /&gt;
While you are looking at the quiz, pay attention to the [[:en:Using_Quiz|Quiz navigation block]]. This is not a normal block that teachers or admins can add or remove, it is a &#039;Fake block&#039; that looks like any other block but is part of the Moodle UI. Are you happy with where it appears, and how it looks?&lt;br /&gt;
&lt;br /&gt;
Other parts of Moodle that use fake blocks are the [[:en:Lesson_module|Lesson activity]] and [[:en:Calendar|the calendar UI]].&lt;br /&gt;
&lt;br /&gt;
Fake blocks are attached to the first region or the &#039;defaultregion&#039; in the &#039;regions&#039; array for the &#039;layout&#039; in the &#039;layouts&#039; array in the &#039;config.php&#039; file.  So if the order is (&#039;side-pre&#039;, &#039;side-post&#039;) and you want fake blocks to be in &#039;side-post&#039; change the &#039;defaultregion&#039; to &#039;side-post&#039; and the &#039;regions&#039; array to (&#039;side-post&#039;, &#039;side-pre&#039;).&lt;br /&gt;
&lt;br /&gt;
===Adding a fake block to each pagelayout in your theme:===&lt;br /&gt;
(add following function to theme/yourtheme/lib.php)&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function theme_yourtheme_get_html_for_settings(renderer_base $output, moodle_page $page) function:&lt;br /&gt;
&lt;br /&gt;
$bc = new block_contents();&lt;br /&gt;
$bc-&amp;gt;title = &#039;fake title&#039;;&lt;br /&gt;
$bc-&amp;gt;attributes[&#039;class&#039;] = &#039;fakeblock&#039;;&lt;br /&gt;
$bc-&amp;gt;content = &#039;fake content&#039;;&lt;br /&gt;
$page-&amp;gt;blocks-&amp;gt;add_fake_block($bc, &#039;side-pre&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Instructions ==&lt;br /&gt;
&lt;br /&gt;
Have you provided a &#039;readme&#039; file containing: Install instructions, un-install instructions, version history and contact details for when things go wrong.&lt;br /&gt;
&lt;br /&gt;
== License ==&lt;br /&gt;
&lt;br /&gt;
Is all code GPLv3 (or compatible) licensed?&lt;br /&gt;
&lt;br /&gt;
== Maturity ==&lt;br /&gt;
&lt;br /&gt;
Have you correctly stated the maturity of the theme in the &#039;[https://docs.moodle.org/dev/version.php version.php]&#039; file?  This gives users and idea of how stable the code is.&lt;br /&gt;
&lt;br /&gt;
== Quiz &#039;secure&#039; pop-up ==&lt;br /&gt;
&lt;br /&gt;
When a quiz is set to [[:en:Quiz_settings#Extra_restrictions_on_attempts|Full screen pop-up with some JavaScript security]] then the page uses a special &#039;secure&#039; layout template that should have minimal headers and NO external links whatsoever.&lt;br /&gt;
See Clean theme secure.php [https://github.com/moodle/moodle/blob/master/theme/clean/layout/secure.php]&lt;br /&gt;
&lt;br /&gt;
== Readable fonts ==&lt;br /&gt;
&lt;br /&gt;
Are the fonts you have chosen readable?  Will they be difficult to read on small devices?&lt;br /&gt;
&lt;br /&gt;
== Right-to-left languages ==&lt;br /&gt;
&lt;br /&gt;
In languages like Hebrew or Farsi, lots of things that you made left-aligned probably need to be right-aligned instead. Moodle adds .dir-rtl or .dir-ltr class to the body element, which you can use in CSS rules.&lt;br /&gt;
&lt;br /&gt;
== Responsive ==&lt;br /&gt;
&lt;br /&gt;
Have you tested your theme for responsiveness on small devices?  Try resizing the browser window and see how it reacts.&lt;br /&gt;
&lt;br /&gt;
== Theme developer mode ==&lt;br /&gt;
&lt;br /&gt;
When &#039;Theme developer mode&#039; is &#039;on&#039;, all of the CSS files are sent individually.  When it is &#039;off&#039;, they are all combined together.  This can lead to some issues.  Check that your theme works with &#039;Theme designer mode off&#039;.&lt;br /&gt;
&lt;br /&gt;
== ... please add more things here in alphabetical order ... ==&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Theme_And_Navigation_Project_3.2&amp;diff=50520</id>
		<title>Theme And Navigation Project 3.2</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Theme_And_Navigation_Project_3.2&amp;diff=50520"/>
		<updated>2016-06-30T19:49:39Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Every page with settings should use a consistent, recognisable ui element to get to the settings */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Theme And Navigation Project 3.2&lt;br /&gt;
|state = Starting&lt;br /&gt;
|tracker = MDL-55070&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=335638&lt;br /&gt;
|assignee = [[User:Damyon Wiese]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
This page is dedicated to a set of changes for 3.2 all relating to the theme, and navigation in Moodle. &lt;br /&gt;
&lt;br /&gt;
The requirements for the new theme are:&lt;br /&gt;
* use a CSS framework that will be supported upstream for a long time&lt;br /&gt;
* testing framework needs to be theme independent&lt;br /&gt;
* make the navigation simpler and more intuitive&lt;br /&gt;
* introduce quick navigation from course to course or section to section&lt;br /&gt;
* promote the content of each page rather than the peripheral sections (blocks)&lt;br /&gt;
* the visual design of Moodle should look distinct from older versions&lt;br /&gt;
* every page with settings should use a consistent, recognisable UI element to get to the settings&lt;br /&gt;
* add lots of settings to the new theme so it can be used for many sites without installing a child-theme&lt;br /&gt;
&lt;br /&gt;
More details about each requirement follow:&lt;br /&gt;
&lt;br /&gt;
= Use a CSS framework that will be supported upstream for a long time =&lt;br /&gt;
* Users affected: theme designers&lt;br /&gt;
* The problem: bootstrap 2 is unsupported&lt;br /&gt;
* The proposed solution: create a new theme based on Bootstrap 4&lt;br /&gt;
* Criteria for success: New moodle theme using a supported CSS framework with long term support that includes features for RTL and Accessibility and is popular with theme designers, the new theme should show proper styling for all pages&lt;br /&gt;
* MDL-55071&lt;br /&gt;
&lt;br /&gt;
= Testing framework needs to be theme independent =&lt;br /&gt;
* Users affected: developers&lt;br /&gt;
* The problem: feature files are written assuming the theme will be “clean”&lt;br /&gt;
* The proposed solution: Theme specific steps need to be identified and the theme should form part of the behat context. Different step implementations should be available for different themes&lt;br /&gt;
* Criteria for success: You should be able to specify which theme to run behat with and all tests should pass&lt;br /&gt;
* MDL-55072&lt;br /&gt;
&lt;br /&gt;
= Navigation is not intuitive =&lt;br /&gt;
* Users affected: new moodle users, experienced moodle users&lt;br /&gt;
* The problem: navigation is a complex tree with inconsistent structure&lt;br /&gt;
* The proposed solution: Only show the path to the current node in the navigation, and it’s siblings as a flat list.&lt;br /&gt;
* Criteria for success: It is easier to determine your location in the navigation tree, it is easier to find pages related to the current page&lt;br /&gt;
* MDL-55073&lt;br /&gt;
&lt;br /&gt;
= Intuitively navigate from course to course or section to section =&lt;br /&gt;
* Users affected: new moodle users, experienced moodle users&lt;br /&gt;
* The problem: If the navigation tree is flattened, it is not possible to change between courses without leaving the course and entering a new one&lt;br /&gt;
* The proposed solution: Show a drop down menu for each item in the navbar&lt;br /&gt;
* Criteria for success: It is intuitive to quickly jump between courses and sections using the navbar&lt;br /&gt;
* MDL-55074&lt;br /&gt;
&lt;br /&gt;
= Promote the content of each page rather than the peripheral sections (blocks) =&lt;br /&gt;
* Users affected: new moodle users, experienced moodle users&lt;br /&gt;
* The problem: blocks displayed around the content compete for attention and real-estate in the page&lt;br /&gt;
* The proposed solution: Move the blocks regions into an expandable menu&lt;br /&gt;
* Criteria for success: the content of each page should be the first thing that grabs your focus, blocks should still be discoverable and usable if needed&lt;br /&gt;
* MDL-55075&lt;br /&gt;
&lt;br /&gt;
= The visual design of Moodle should look distinct from older versions =&lt;br /&gt;
* Users affected: new moodle users, themers&lt;br /&gt;
* The problem: We have not updated the look of the default theme in several years&lt;br /&gt;
* The proposed solution: Implement some new distinct styling in the new Moodle theme&lt;br /&gt;
* Criteria for success: The new moodle theme should look visually distinct. There should only be a minimum amount of custom styling for themers to override when extending this theme&lt;br /&gt;
* MDL-55076&lt;br /&gt;
&lt;br /&gt;
= Every page with settings should use a consistent, recognisable UI element to get to the settings =&lt;br /&gt;
* Users affected: all moodle users&lt;br /&gt;
* The problem: Settings pages are buried in the navigation tree in inconsistent locations&lt;br /&gt;
* The proposed solution: Create a settings navigation renderable that shows a gear icon on the top right of the page and takes you straight to the settings page. Update all pages with settings in moodle to use the new thing. &lt;br /&gt;
* Criteria for success: All pages with settings in Moodle should show a gear icon which will take you to the settings page when clicked.&lt;br /&gt;
* MDL-55077&lt;br /&gt;
&lt;br /&gt;
= Add lots of settings to the new theme so it can be used for many sites without installing a child-theme =&lt;br /&gt;
* Users affected: new moodle users&lt;br /&gt;
* The problem: Installing themes is hard/not possible in some environments. The new theme should be customisable enough to make it usable just by changing settings.&lt;br /&gt;
* The proposed solution: Review settings provided by community themes and add the common ones to this new theme.&lt;br /&gt;
* Criteria for success: Colours, fonts, logos should be customisable as well as additional settings supported by most community themes.&lt;br /&gt;
* MDL-55078&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Theme_And_Navigation_Project_3.2&amp;diff=50517</id>
		<title>Theme And Navigation Project 3.2</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Theme_And_Navigation_Project_3.2&amp;diff=50517"/>
		<updated>2016-06-30T19:44:37Z</updated>

		<summary type="html">&lt;p&gt;Tqr: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Theme And Navigation Project 3.2&lt;br /&gt;
|state = Starting&lt;br /&gt;
|tracker = MDL-55070&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=335638&lt;br /&gt;
|assignee = [[User:Damyon Wiese]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
This page is dedicated to a set of changes for 3.2 all relating to the theme, and navigation in Moodle. &lt;br /&gt;
&lt;br /&gt;
The requirements for the new theme are:&lt;br /&gt;
* use a CSS framework that will be supported upstream for a long time&lt;br /&gt;
* testing framework needs to be theme independent&lt;br /&gt;
* make the navigation simpler and more intuitive&lt;br /&gt;
* introduce quick navigation from course to course or section to section&lt;br /&gt;
* promote the content of each page rather than the peripheral sections (blocks)&lt;br /&gt;
* the visual design of Moodle should look distinct from older versions&lt;br /&gt;
* every page with settings should use a consistent, recognisable UI element to get to the settings&lt;br /&gt;
* add lots of settings to the new theme so it can be used for many sites without installing a child-theme&lt;br /&gt;
&lt;br /&gt;
More details about each requirement follow:&lt;br /&gt;
&lt;br /&gt;
= Use a CSS framework that will be supported upstream for a long time =&lt;br /&gt;
* Users affected: theme designers&lt;br /&gt;
* The problem: bootstrap 2 is unsupported&lt;br /&gt;
* The proposed solution: create a new theme based on Bootstrap 4&lt;br /&gt;
* Criteria for success: New moodle theme using a supported CSS framework with long term support that includes features for RTL and Accessibility and is popular with theme designers, the new theme should show proper styling for all pages&lt;br /&gt;
* MDL-55071&lt;br /&gt;
&lt;br /&gt;
= Testing framework needs to be theme independent =&lt;br /&gt;
* Users affected: developers&lt;br /&gt;
* The problem: feature files are written assuming the theme will be “clean”&lt;br /&gt;
* The proposed solution: Theme specific steps need to be identified and the theme should form part of the behat context. Different step implementations should be available for different themes&lt;br /&gt;
* Criteria for success: You should be able to specify which theme to run behat with and all tests should pass&lt;br /&gt;
* MDL-55072&lt;br /&gt;
&lt;br /&gt;
= Navigation is not intuitive =&lt;br /&gt;
* Users affected: new moodle users, experienced moodle users&lt;br /&gt;
* The problem: navigation is a complex tree with inconsistent structure&lt;br /&gt;
* The proposed solution: Only show the path to the current node in the navigation, and it’s siblings as a flat list.&lt;br /&gt;
* Criteria for success: It is easier to determine your location in the navigation tree, it is easier to find pages related to the current page&lt;br /&gt;
* MDL-55073&lt;br /&gt;
&lt;br /&gt;
= Intuitively navigate from course to course or section to section =&lt;br /&gt;
* Users affected: new moodle users, experienced moodle users&lt;br /&gt;
* The problem: If the navigation tree is flattened, it is not possible to change between courses without leaving the course and entering a new one&lt;br /&gt;
* The proposed solution: Show a drop down menu for each item in the navbar&lt;br /&gt;
* Criteria for success: It is intuitive to quickly jump between courses and sections using the navbar&lt;br /&gt;
* MDL-55074&lt;br /&gt;
&lt;br /&gt;
= Promote the content of each page rather than the peripheral sections (blocks) =&lt;br /&gt;
* Users affected: new moodle users, experienced moodle users&lt;br /&gt;
* The problem: blocks displayed around the content compete for attention and real-estate in the page&lt;br /&gt;
* The proposed solution: Move the blocks regions into an expandable menu&lt;br /&gt;
* Criteria for success: the content of each page should be the first thing that grabs your focus, blocks should still be discoverable and usable if needed&lt;br /&gt;
* MDL-55075&lt;br /&gt;
&lt;br /&gt;
= The visual design of Moodle should look distinct from older versions =&lt;br /&gt;
* Users affected: new moodle users, themers&lt;br /&gt;
* The problem: We have not updated the look of the default theme in several years&lt;br /&gt;
* The proposed solution: Implement some new distinct styling in the new Moodle theme&lt;br /&gt;
* Criteria for success: The new moodle theme should look visually distinct. There should only be a minimum amount of custom styling for themers to override when extending this theme&lt;br /&gt;
* MDL-55076&lt;br /&gt;
&lt;br /&gt;
= Every page with settings should use a consistent, recognisable ui element to get to the settings =&lt;br /&gt;
* Users affected: all moodle users&lt;br /&gt;
* The problem: Settings pages are buried in the navigation tree in inconsistent locations&lt;br /&gt;
* The proposed solution: Create a settings navigation renderable that shows a gear icon on the top right of the page and takes you straight to the settings page. Update all pages with settings in moodle to use the new thing. &lt;br /&gt;
* Criteria for success: All pages with settings in Moodle should show a gear icon which will take you to the settings page when clicked.&lt;br /&gt;
* MDL-55077&lt;br /&gt;
&lt;br /&gt;
= Add lots of settings to the new theme so it can be used for many sites without installing a child-theme =&lt;br /&gt;
* Users affected: new moodle users&lt;br /&gt;
* The problem: Installing themes is hard/not possible in some environments. The new theme should be customisable enough to make it usable just by changing settings.&lt;br /&gt;
* The proposed solution: Review settings provided by community themes and add the common ones to this new theme.&lt;br /&gt;
* Criteria for success: Colours, fonts, logos should be customisable as well as additional settings supported by most community themes.&lt;br /&gt;
* MDL-55078&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Templates&amp;diff=50383</id>
		<title>Templates</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Templates&amp;diff=50383"/>
		<updated>2016-06-06T23:56:49Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Templates */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.9}}&lt;br /&gt;
&lt;br /&gt;
= Templates =&lt;br /&gt;
&lt;br /&gt;
== What is a template? ==&lt;br /&gt;
A template is an alternative to writing blocks of html directly in javascript / php by concatenating strings. The end result is the same, but templates have a number of advantages:&lt;br /&gt;
* It is easier to see the final result of the template because the code for a template is very close to what the final HTML will look like&lt;br /&gt;
* Because the templating language is intentionally limited, it is hard to introduce complex logic into a template. This makes it far easier for a theme designer to override a template, without breaking the logic&lt;br /&gt;
* Templates can be rendered from javascript. This allows ajax operations to re-render a portion of the page.&lt;br /&gt;
&lt;br /&gt;
== How do I write a template? ==&lt;br /&gt;
Templates are written in a language called &amp;quot;[http://mustache.github.io/mustache.5.html Mustache]&amp;quot;. Mustache is written as HTML with additional tags used to format the display of the data. Mustache tags are made of 2 opening and closing curly braces &amp;lt;code xml&amp;gt;{{tag}}&amp;lt;/code&amp;gt;. There are a few variations of these tags that behave differently.&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{raiden}}&amp;lt;/code&amp;gt; This is a simple variable substitution. The variable named &amp;quot;variable&amp;quot; will be searched for in the current context (and any parent contexts) and when a value is found, the entire tag will be replaced by the variable (html escaped).&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{{galaga}}}&amp;lt;/code&amp;gt; This is an unescaped variable substitution. Instead of escaping the variable before replacing it in the template, the variable is included raw. This is useful when the variable contains a block of HTML (for example).&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{#lemmings}} jump off cliff {{/lemmings}}&amp;lt;/code&amp;gt; These are opening and closing section tags. If the lemmings variable exists and evaluates to &amp;quot;not false&amp;quot; value, the variable is pushed on the stack, the contents of the section are parsed and included in the result. If the variable does not exist, or evaluates to false - the section will be skipped. If the variable lemmings evaluates to an array, the section will be repeated for each item in the array with the items of the array on the context. This is how to output a list.&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{^lemmings}} enjoy view {{/lemmings}}&amp;lt;/code&amp;gt; Equivalent of &amp;quot;if-not&amp;quot; block, there is not &amp;quot;else&amp;quot; in mustache.&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{&amp;gt; pacman }}&amp;lt;/code&amp;gt; This is a partial. Think of it like an include. Templates can include other templates using this tag.&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{$blockvar}} ... {{/blockvar}}&amp;lt;/code&amp;gt; This is a block variable. It defines a section of the template that can be overridden when it&#039;s included in another template.&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{&amp;lt; template_name}} ... {{/template_name}}&amp;lt;/code&amp;gt; This is similar to including a partial but specifically indicates that you&#039;d like to override one or more black variables defined within the template you&#039;re including. You can override the black variables by defining a block variable within these tags that matches the name of the block variable you&#039;d like to override in the included template.&lt;br /&gt;
&lt;br /&gt;
So - putting this all together:&lt;br /&gt;
&lt;br /&gt;
recipe.mustache&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;{{recipename}}&amp;lt;/h3&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;{{description}}&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;Ingredients&amp;lt;/h4&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
{{#ingredients}}&lt;br /&gt;
&amp;lt;li&amp;gt;{{.}}&amp;lt;/li&amp;gt;&lt;br /&gt;
{{/ingredients}}&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;Steps&amp;lt;/h4&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
{{#steps}}&lt;br /&gt;
&amp;lt;li&amp;gt;{{{.}}}&amp;lt;/li&amp;gt;&lt;br /&gt;
{{/steps}}&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
{{ &amp;gt; ratethisrecipe }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When given this data:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  recipename: &amp;quot;Cheese sandwich&amp;quot;,&lt;br /&gt;
  description: &amp;quot;Who doesn&#039;t like a good cheese sandwich?&amp;quot;,&lt;br /&gt;
  ingredients: [&amp;quot;bread&amp;quot;, &amp;quot;cheese&amp;quot;, &amp;quot;butter&amp;quot;],&lt;br /&gt;
  steps: [&amp;quot;&amp;lt;p&amp;gt;Step 1 is to spread the butter on the bread&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;&amp;lt;p&amp;gt;Step 2 is to put the cheese &amp;amp;quot;in&amp;amp;quot; the bread (not on top, or underneath)&amp;lt;/p&amp;gt;&amp;quot;]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Gives this: &amp;lt;span style=&amp;quot;font-size:4em&amp;quot;&amp;gt;😋&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info - there are much clearer explanations of templates on the [http://mustache.github.io/mustache.5.html Mustache] website. Try reading those pages &amp;quot;before&amp;quot; posting on stack overflow :) .&lt;br /&gt;
&lt;br /&gt;
=== Blocks (Moodle 3.0 onwards) ===&lt;br /&gt;
Blocks are a feature of Mustache that deserves a special mention. The are used as a form of inheritance - and are crucial to building a library of re-usable templates. To use make use of &amp;quot;blocks&amp;quot; you define a parent template with replaceable sections. Each of those sections is marked with a &amp;quot;blocks&amp;quot; tag like this (A blocks tag looks like a regular tag, but the variable name is preceded with $):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;section&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;{{$sectionheading}}Default heading{{/sectionheading}}&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
{{$content}}Content for section{{/content}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now - wherever I need to re-use this template I can include it and replace the content of those sections at the same time. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{&amp;lt; section}}&lt;br /&gt;
{{$sectionheading}}Latest News{{/sectionheading}}&lt;br /&gt;
{{$content}}Nothing happened today - sorry!{{/content}}&lt;br /&gt;
{{/section}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that when I include a template and I want to make use of blocks - the include tag points the other way:&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{&amp;lt; section}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Not&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{&amp;gt; section}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Blocks support looping and many other cool things - for more info see https://github.com/bobthecow/mustache.php/wiki/BLOCKS-pragma&lt;br /&gt;
&lt;br /&gt;
== Where do I put my templates? ==&lt;br /&gt;
&lt;br /&gt;
Templates go in the &amp;lt;componentdir&amp;gt;/templates folder and must have a .mustache file extension. When loading templates the template name is &amp;lt;componentname&amp;gt;/&amp;lt;filename&amp;gt; (no file extension). &lt;br /&gt;
&lt;br /&gt;
So &amp;quot;mod_lesson/timer&amp;quot; would load the template at mod/lesson/templates/timer.mustache.&lt;br /&gt;
&lt;br /&gt;
Note: Do not try and put your templates in sub folders under the &amp;quot;/templates&amp;quot; directory. This is not supported and will not work.&lt;br /&gt;
&lt;br /&gt;
== How do I call a template from javascript? ==&lt;br /&gt;
&lt;br /&gt;
Rendering a template from javascript is fairly easy. There is a new AMD module that can load/cache and render a template for you. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
// This is AMD code for loading the &amp;quot;core/templates&amp;quot; module. see [Javascript Modules].&lt;br /&gt;
require([&#039;core/templates&#039;], function(templates) {&lt;br /&gt;
&lt;br /&gt;
    // This will be the context for our template. So {{name}} in the template will resolve to &amp;quot;Tweety bird&amp;quot;.&lt;br /&gt;
    var context = { name: &#039;Tweety bird&#039;, intelligence: 2 };&lt;br /&gt;
&lt;br /&gt;
    // This will call the function to load and render our template. &lt;br /&gt;
    var promise = templates.render(&#039;block_looneytunes/profile&#039;, context);&lt;br /&gt;
&lt;br /&gt;
    // The promise object returned by this function means &amp;quot;I&#039;ve considered your request and will finish it later - I PROMISE!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    // How we deal with promise objects is by adding callbacks.&lt;br /&gt;
    promise.done(function(source, javascript) {&lt;br /&gt;
        // Here eventually I have my compiled template, and any javascript that it generated.&lt;br /&gt;
&lt;br /&gt;
        // I can execute the javascript (probably after adding the html to the DOM) like this:&lt;br /&gt;
        templates.runTemplateJS(js);&lt;br /&gt;
    });&lt;br /&gt;
  &lt;br /&gt;
    // Sometimes things fail&lt;br /&gt;
    promise.fail(function(ex) {&lt;br /&gt;
        // Deal with this exception (I recommend core/notify exception function for this).&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under the hood, this did many clever things for us. It loaded the template via an ajax call if it was not cached. It found any missing lang strings in the template and loaded them in a single ajax request, it split the JS from the HTML and returned us both in easy to use way. Read on for how to nicely deal with the javascript parameter.&lt;br /&gt;
&lt;br /&gt;
Note: with some nice chaining and sugar, we can shorten the above example quite a bit:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
require([&#039;core/templates&#039;, &#039;core/notification&#039;], function(templates, notification) {&lt;br /&gt;
    var context = { name: &#039;Tweety bird&#039;, intelligence: 2 };&lt;br /&gt;
    templates.render(&#039;block_looneytunes/profile&#039;, context)&lt;br /&gt;
        .done(doneCallback)&lt;br /&gt;
        .fail(notification.exception);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== What if a template contains javascript? ==&lt;br /&gt;
&lt;br /&gt;
Sometimes a template requires that some JS be run when it is added to the page in order to give it more features. In the template we can include blocks of javascript, but we should use a special section tag that has a &amp;quot;helper&amp;quot; method registered to handle javascript carefully. &lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
profile.mustache&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;profile&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Name: {{name}}&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Intelligence: {{intelligence}}&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
{{#js}}&lt;br /&gt;
require(&#039;jquery&#039;, function($) {&lt;br /&gt;
    // Effects! Can we have &amp;quot;blink&amp;quot;?&lt;br /&gt;
    $(&#039;#profile&#039;).slideDown();&lt;br /&gt;
});&lt;br /&gt;
{{/js}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If this template is rendered by PHP, the javascript is separated from the HTML, and is appended to a special section in the footer of the page &amp;quot;after&amp;quot; requirejs has loaded. This provides the optimal page loading speed. If the template is rendered by javascript, the javascript source will be passed to the &amp;quot;done&amp;quot; handler from the promise. Then, when the &amp;quot;done&amp;quot; handler has added the template to the DOM, it can call &lt;br /&gt;
&amp;lt;code javascript&amp;gt;templates.runTemplateJS(javascript);&amp;lt;/code&amp;gt; &lt;br /&gt;
which will run the javascript (by creating a new script tag and appending it to the page head).&lt;br /&gt;
&lt;br /&gt;
== What other helpers can I use? ==&lt;br /&gt;
&lt;br /&gt;
=== {{# str }} ===&lt;br /&gt;
&lt;br /&gt;
There is a string helper for loading language strings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{# str }} helloworld, mod_greeting {{/ str }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 2 parameters are the string id and the component name. So this is effectively Mustache variant of &amp;lt;code&amp;gt;get_string(&#039;helloworld&#039;, &#039;mod_greeting&#039;)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The optional third parameter defines the value for the string&#039;s &amp;lt;code&amp;gt;$a&amp;lt;/code&amp;gt; placeholder:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{# str }} iscool, mod_cool, David Beckham {{/ str }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example would effectively do what &amp;lt;code&amp;gt;get_string(&#039;iscool&#039;, &#039;mod_cool&#039;, &#039;David Beckham&#039;)&amp;lt;/code&amp;gt; does in Moodle PHP code.&lt;br /&gt;
&lt;br /&gt;
Variable tags are allowed to define the value of the &amp;lt;code&amp;gt;$a&amp;lt;/code&amp;gt; placeholder:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{# str }} iscool, mod_cool, {{ name }} {{/ str }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For strings that accept complex placeholder, see the following section.&lt;br /&gt;
&lt;br /&gt;
=== {{# quote }} ===&lt;br /&gt;
&lt;br /&gt;
As shown in the previous section, the &amp;lt;code&amp;gt;{{# str }}&amp;lt;/code&amp;gt; helper may need complex data structures passed as the value of the &amp;lt;code&amp;gt;$a&amp;lt;/code&amp;gt; placeholder. You can use a JSON object syntax in that case:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{# str }} iscool, mod_cool, { &amp;quot;firstname&amp;quot;: &amp;quot;David&amp;quot;, &amp;quot;lastname&amp;quot;: &amp;quot;Beckham&amp;quot; } {{/ str }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you wanted to use the context values instead of literal strings, you might intuitively use something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{! DO NOT DO THIS !}}&lt;br /&gt;
{{# str }} iscool, mod_cool, { &amp;quot;firstname&amp;quot;: &amp;quot;{{ firstname }}&amp;quot;, &amp;quot;lastname&amp;quot;: &amp;quot;{{ lastname }}&amp;quot; } {{/ str }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is a potential problem though. If the variable tag &amp;lt;code&amp;gt;{{ firstname }}&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;{{ lastname }}&amp;lt;/code&amp;gt; evaluates to a string containing the double quote character, that will break the JSON syntax. We need to escape the double quotes potentially appearing in the variable tags. For this, use the &amp;lt;code&amp;gt;{{# quote }}&amp;lt;/code&amp;gt; helper:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{! This is OK !}}&lt;br /&gt;
{{# str }} iscool, mod_cool, { &amp;quot;firstname&amp;quot;:  {{# quote }}{{ firstname }}{{/ quote }}, &amp;quot;lastname&amp;quot;: {{# quote }}{{ lastname }}{{/ quote }} } {{/ str }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See MDL-52136 for details.&lt;br /&gt;
=== {{# pix }} ===&lt;br /&gt;
&lt;br /&gt;
There is a pix icon helper for generating pix icon tags.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{# pix }} t/edit, core, Edit David Beckham {{/ pix }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 2 parameters are the string id and the component name, the rest is the alt text for the image.&lt;br /&gt;
&lt;br /&gt;
== How do I call a template from php? ==&lt;br /&gt;
&lt;br /&gt;
The templates in php are attached to the renderers. There is a renderer method &amp;quot;render_from_template($templatename, $context)&amp;quot; that does the trick.&lt;br /&gt;
&lt;br /&gt;
== How do templates work with renderers? ==&lt;br /&gt;
&lt;br /&gt;
Extra care must be taken to ensure that the data passed to the context parameter is useful to the templating language. The template language cannot:&lt;br /&gt;
* Call functions&lt;br /&gt;
* Perform any boolean logic&lt;br /&gt;
* Render renderables&lt;br /&gt;
* Do capability checks&lt;br /&gt;
* Make DB queries&lt;br /&gt;
&lt;br /&gt;
So - I have &amp;quot;some&amp;quot; data in my renderable and some logic and html generation in my render method for that renderable - how do I refactor this to use a template?&lt;br /&gt;
&lt;br /&gt;
The first thing to note, is that you don&#039;t have to use a template if you don&#039;t want to. It just means that themers will still have to override your render method, instead of just overriding the template. But if you DO want to use a template, you will earn &amp;quot;cred&amp;quot; with themers, and you will be able to re-render parts of your interface from javascript in response to ajax requests without reloading the whole page (that&#039;s cool).&lt;br /&gt;
&lt;br /&gt;
There is a simple pattern to use to hook a template into a render method. If you make your renderable implement templatable as well as renderable - it will have to implement a new method &amp;quot;export_for_template(renderer_base $output)&amp;quot;. This method takes the data stored in the renderable and &amp;quot;flattens it&amp;quot; so it can be used in a template. If there is some nested data in the renderable (like other renderables) and they do not support templates, they can be &amp;quot;rendered&amp;quot; into the flat data structure using the renderer parameter. It should return an stdClass with properties that are only made of simple types: int, string, bool, float, stdClass or arrays of these types. Then the render method can updated to export the data and render it with the template.&lt;br /&gt;
&lt;br /&gt;
In the renderable:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
     * Export this data so it can be used as the context for a mustache template.&lt;br /&gt;
     *&lt;br /&gt;
     * @return stdClass&lt;br /&gt;
     */&lt;br /&gt;
    public function export_for_template(renderer_base $output) {&lt;br /&gt;
        $data = new stdClass();&lt;br /&gt;
        $data-&amp;gt;canmanage = $this-&amp;gt;canmanage;&lt;br /&gt;
        $data-&amp;gt;things = array();&lt;br /&gt;
        foreach ($this-&amp;gt;things as $thing) {&lt;br /&gt;
            $data-&amp;gt;things[] = $thing-&amp;gt;to_record();&lt;br /&gt;
        }&lt;br /&gt;
        $data-&amp;gt;navigation = array();&lt;br /&gt;
        foreach ($this-&amp;gt;navigation as $button) {&lt;br /&gt;
            $data-&amp;gt;navigation[] = $output-&amp;gt;render($button);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return $data;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the renderer class:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    /**&lt;br /&gt;
     * Defer to template.&lt;br /&gt;
     *&lt;br /&gt;
     * @param mywidget $widget&lt;br /&gt;
     *&lt;br /&gt;
     * @return string html for the page&lt;br /&gt;
     */&lt;br /&gt;
    render(mywidget $widget) {&lt;br /&gt;
        $data = $widget-&amp;gt;export_for_template($this);&lt;br /&gt;
        return $this-&amp;gt;render_from_template(&#039;mywidget&#039;, $data);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How to I override a template in my theme? ==&lt;br /&gt;
&lt;br /&gt;
Templates can be overridden a bit easier than overriding a renderer. First - find the template that you want to change. E.g. &amp;quot;mod/wiki/templates/ratingui.mustache&amp;quot;. Now, create a sub-folder under your themes &amp;quot;templates&amp;quot; directory with the component name of the plugin you are overriding. E.g &amp;quot;theme/timtam/templates/mod_wiki&amp;quot;. Finally, copy the ratingui.mustache file into the newly created &amp;quot;theme/timtam/templates/mod_wiki&amp;quot; and edit it. You should see your changes immediately if theme designer mode is on. Note: templates are cached just like CSS, so if you are not using theme designer mode you will need to purge all caches to see the latest version of an edited template. If the template you are overriding contains a documentation comment (see next section) it is recommended to remove it, it will still show the documentation in the template library.&lt;br /&gt;
&lt;br /&gt;
== Should I document my templates? ==&lt;br /&gt;
&lt;br /&gt;
Yes!!!! Theme designers need to know the limits of what they can expect to change without breaking anything. As a further benefit - your beautiful new template can be displayed in the &amp;quot;Template Library&amp;quot; tool shipped with Moodle. In order to provide nice documentation and examples for the Template Library, you should follow these conventions when documenting your template.&lt;br /&gt;
&lt;br /&gt;
=== Add a documentation comment to your template ===&lt;br /&gt;
Mustache comments look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  {{! &lt;br /&gt;
   I am a comment.&lt;br /&gt;
   I can span multiple lines.&lt;br /&gt;
  }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The template library will look for a mustache comment that contains this special marker as the documentation to display, and the source of an example context.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
@template component/templatename&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Useful things to include in the documentation for a template ====&lt;br /&gt;
===== Classes required for JS =====&lt;br /&gt;
This is a list of classes that are used by the javascript for this template. If removing a class from an element in the template will break the javascript, list it here.&lt;br /&gt;
&lt;br /&gt;
===== Data attributes required for JS =====&lt;br /&gt;
This is a list of data attributes (e.g. data-enhance=&amp;quot;true&amp;quot;) that are used by the javascript for this template. If removing a data attribute from an element in the template will break the javascript, list it here.&lt;br /&gt;
&lt;br /&gt;
===== Context variables required for this template =====&lt;br /&gt;
This is a description of the data that may be contained in the context that is passed to the template. Be explicit and document every attribute.&lt;br /&gt;
&lt;br /&gt;
===== Example context (json) =====&lt;br /&gt;
The Template Library will look for this data in your documentation comment as it allows it to render a &amp;quot;preview&amp;quot; of the template right in the Template Library. This is useful for theme designers to test all the available templates in their new theme to make sure they look nice in a new theme. It is also useful to make sure the template responds to different screen sizes, languages and devices. The format is a json encoded object that is passed directly into the render method for this template. &lt;br /&gt;
&lt;br /&gt;
==== A full example ====&lt;br /&gt;
lib/templates/pix_icon.mustache&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  {{!                                                                                                                                 &lt;br /&gt;
    This file is part of Moodle - http://moodle.org/                                                                                &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Moodle is free software: you can redistribute it and/or modify                                                                  &lt;br /&gt;
    it under the terms of the GNU General Public License as published by                                                            &lt;br /&gt;
    the Free Software Foundation, either version 3 of the License, or                                                               &lt;br /&gt;
    (at your option) any later version.                                                                                             &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Moodle is distributed in the hope that it will be useful,                                                                       &lt;br /&gt;
    but WITHOUT ANY WARRANTY; without even the implied warranty of                                                                  &lt;br /&gt;
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                                                   &lt;br /&gt;
    GNU General Public License for more details.                                                                                    &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    You should have received a copy of the GNU General Public License                                                               &lt;br /&gt;
    along with Moodle.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.                                                                 &lt;br /&gt;
  }}                                                                                                                                  &lt;br /&gt;
  {{!                                                                                                                                 &lt;br /&gt;
    @template core/pix_icon                                                                                                         &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Moodle pix_icon template.                                                                                                       &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    The purpose of this template is to render a pix_icon.                                                                           &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Classes required for JS:                                                                                                        &lt;br /&gt;
    * none                                                                                                                          &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Data attributes required for JS:                                                                                                &lt;br /&gt;
    * none                                                                                                                          &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Context variables required for this template:                                                                                   &lt;br /&gt;
    * attributes Array of name / value pairs.                                                                                       &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Example context (json):                                                                                                         &lt;br /&gt;
    {                                                                                                                               &lt;br /&gt;
        &amp;quot;attributes&amp;quot;: [                                                                                                             &lt;br /&gt;
            { &amp;quot;name&amp;quot;: &amp;quot;src&amp;quot;, &amp;quot;value&amp;quot;: &amp;quot;http://moodle.com/wp-content/themes/moodle/images/logo-hat2.png&amp;quot; },                          &lt;br /&gt;
            { &amp;quot;name&amp;quot;: &amp;quot;class&amp;quot;, &amp;quot;value&amp;quot;: &amp;quot;iconsmall&amp;quot; }                                                                               &lt;br /&gt;
        ]                                                                                                                           &lt;br /&gt;
    }                                                                                                                               &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
  }}                                                                                                                                  &lt;br /&gt;
  &amp;lt;img {{#attributes}}{{name}}=&amp;quot;{{value}}&amp;quot; {{/attributes}}/&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Coding style for templates ==&lt;br /&gt;
This section documents some coding style guidelines to follow when writing templates. The reason for these guidelines is to promote consistency, and interoperability of the templates.&lt;br /&gt;
&lt;br /&gt;
=== Include GPL at the top of each template ===&lt;br /&gt;
&lt;br /&gt;
Templates are a form of code and it is appropriate to license them like any other code.&lt;br /&gt;
&lt;br /&gt;
===Include a documentation comment for each template===&lt;br /&gt;
&lt;br /&gt;
The exception is when you are overriding a template, if the documentation from the parent still applies, you do not need to copy it to the overridden template.&lt;br /&gt;
&lt;br /&gt;
===Use data-attributes for JS hooks===&lt;br /&gt;
&lt;br /&gt;
Data attributes are ideal for adding javascript hooks to templates because:&lt;br /&gt;
* Classes are meant for styling - theme designers should be able to change the classes at will without breaking any functionality.&lt;br /&gt;
* IDs must be unique in the page, but it is not possible to control how many times the same template might be included in the page.&lt;br /&gt;
* Data attributes can have meaningful names and can be efficiently queried with a selector&lt;br /&gt;
&lt;br /&gt;
===Avoid custom CSS for templates===&lt;br /&gt;
&lt;br /&gt;
This is not a hard rule, but a preference. We already have too much CSS in Moodle - where ever possible we should try and re-use the existing CSS instead of adding new CSS to support every new template.&lt;br /&gt;
&lt;br /&gt;
===Re-use core templates as much as possible===&lt;br /&gt;
&lt;br /&gt;
First we need to build the core set of reusable templates - but once that is in place we should always try to re-use those core templates to build interfaces. This will make Moodle more consistent, attractive and customisable.&lt;br /&gt;
&lt;br /&gt;
===Do use the CSS framework classes directly in the templates===&lt;br /&gt;
&lt;br /&gt;
We have bootstrap in core - so lets make the most of it. There is no problem using bootstrap classes in core templates, as long as the &amp;quot;base&amp;quot; theme is also tested, and an overridden template is added there if required.&lt;br /&gt;
&lt;br /&gt;
===Avoid IDs for styling or javascript===&lt;br /&gt;
&lt;br /&gt;
IDs should never evet be used for styling as they have a high CSS specificity, and so are hard to override. In addition, IDs should be unique in the page, which implies that a template could only be used once in a page. IDs are also not ideal for javascript, for the same reason (must be unique in a page).&lt;br /&gt;
&lt;br /&gt;
The only acceptable case to use an ID is you need to create a one to one connection between the JS and template. In this case use the uniqid helper to generate an ID that will not conflict with any other template on the page, and use it as part of the ID.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;{{uniqid}}-somethingspecific&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
{{#js}}&lt;br /&gt;
    callFunction(&#039;{{uniqid}}-somethingspecific&#039;);&lt;br /&gt;
{{/js}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Follow CSS coding style===&lt;br /&gt;
&lt;br /&gt;
https://docs.moodle.org/dev/CSS_coding_style&lt;br /&gt;
&lt;br /&gt;
Use hyphens as word-separators for class names. &lt;br /&gt;
Use lower case class names.&lt;br /&gt;
&lt;br /&gt;
===Wrap each template in one node with a classname that matches the template name===&lt;br /&gt;
&lt;br /&gt;
Generate a class name by combining the component and template names and separating words with underscore.&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;core_user_header&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:AJAX]]&lt;br /&gt;
[[Category:Javascript]]&lt;br /&gt;
[[Category:Output]]&lt;br /&gt;
&lt;br /&gt;
===Iterating over php arrays in a mustache template===&lt;br /&gt;
&lt;br /&gt;
Mustache treats hashes and arrays differently because of cross language compatibility&lt;br /&gt;
In php arrays and hashes are the same, but mustache treats them differently&lt;br /&gt;
It decides a php array is a hash and will not iterate over it if it is non 0 indexed and/or has a gap in the key numbers&lt;br /&gt;
so in short&lt;br /&gt;
you need to&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$datafortemplate-&amp;gt;mylist =  array_values($myarraywithnonnumerickeys)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
you could also use &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$datafortemplate-&amp;gt;mylist = new ArrayIterator($myarraywithnonnumerickeys);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
BUT this fails when $myarraywithnonnumerickeys is empty and you try to use&lt;br /&gt;
&amp;lt;code html5&amp;gt;&lt;br /&gt;
{{#mylist}}&lt;br /&gt;
with an array iterator if mylist is empty this block will not run&lt;br /&gt;
{{/mylist}}&lt;br /&gt;
{{^mylist}}&lt;br /&gt;
with an array iterator mylist will not run this block either because it is not quite empty&lt;br /&gt;
{{/mylist}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How do I write core templates? ==&lt;br /&gt;
Core templates should ideally be simple generic components that can be used within other templates to create more complex page layouts. They should be flexible enough for developers and themers to easily use without having to replace the template. The templates should attempt to encapsulate some core structure for the element as well as key classes while allowing the content to be easily overridden. Ultimately we want to avoid having duplicate HTML copied from template to template where possible, particularly if the HTML element has some classes associated with it.&lt;br /&gt;
&lt;br /&gt;
Mustache relies on variables to substitute context data into the template but unfortunately it&#039;s very unlikely that the the names of the context data will match what the template is expecting for all the places that the template might be used. So in order to allow easy extensibility and avoid having to duplicate templates just to rename the variables we can wrap them in block variables which would allow the template that is including our template to replace that variable with one from it&#039;s own context inline.&lt;br /&gt;
&lt;br /&gt;
There are a few key points to keep in mind when writing a core template:&lt;br /&gt;
* Consider how your template will actually be used. Try writing a test page that uses your template to help discover some of the assumptions you might have in the template.&lt;br /&gt;
* The example context you provide in the template is mostly just for showing the template in the template library and is likely not how your template will actually be used. Most uses of the template will have a different context all together.&lt;br /&gt;
* Try to enforce a core structure but avoid enforcing a specific context. Content should be overridable.&lt;br /&gt;
* Use block variables to indicate sections of your template that people are likely to want to change. Typically where they will be wanting to substitute in their own content.&lt;br /&gt;
* Try to keep any javascript that accompanies the template as decoupled from the HTML / CSS structure of the template as possible. Instead of relying on the existence of certain HTML elements or CSS classes it is generally better to leverage data-attributes which can be added to any element.&lt;br /&gt;
&lt;br /&gt;
=== An example: tabs ===&lt;br /&gt;
Let&#039;s go through an example to illustrate how you might build a core template. For the example we&#039;ll be building a tabs template, since it&#039;s a fairly complex component that requires the use of block variables and javascript.&lt;br /&gt;
&lt;br /&gt;
First we can create a basic template to get the general structure down, let&#039;s call it tabs. Here&#039;s what it might look like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;{{ uniqid }}-tab-container&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;ul role=&amp;quot;tablist&amp;quot; class=&amp;quot;nav nav-tabs&amp;quot;&amp;gt;&lt;br /&gt;
		{{# tabs }}&lt;br /&gt;
			&amp;lt;li role=&amp;quot;tab&amp;quot;&lt;br /&gt;
					data-target=&amp;quot;{{ uniqid }}-{{ id }}&amp;quot;&lt;br /&gt;
					data-selected-class=&amp;quot;active&amp;quot;&lt;br /&gt;
					aria-controls=&amp;quot;{{ uniqid }}-{{ id }}&amp;quot;&lt;br /&gt;
					aria-selected=&amp;quot;false&amp;quot; tabindex=&amp;quot;-1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
				&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;{{{ name }}}&amp;lt;/a&amp;gt;&lt;br /&gt;
			&amp;lt;/li&amp;gt;&lt;br /&gt;
		{{/ tabs }}&lt;br /&gt;
	&amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;tab-content&amp;quot;&amp;gt;&lt;br /&gt;
		{{# tabs }}&lt;br /&gt;
			&amp;lt;div role=&amp;quot;tabpanel&amp;quot;&lt;br /&gt;
				class=&amp;quot;tab-pane&amp;quot;&lt;br /&gt;
				id=&amp;quot;{{ uniqid }}-{{ id }}&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
				{{{ content }}}&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		{{/ tabs }}&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
{{#js}}&lt;br /&gt;
    require([&#039;jquery&#039;,&#039;core/tabs&#039;], function($, tabs) {&lt;br /&gt;
&lt;br /&gt;
        var container = $(&amp;quot;#{{ uniqid }}-tab-container&amp;quot;);&lt;br /&gt;
        tabs.create(container);&lt;br /&gt;
    });&lt;br /&gt;
{{/js}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The template requires a context that looks something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;tabs&amp;quot;: [&lt;br /&gt;
		{&amp;quot;id&amp;quot;:&amp;quot;tab1&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Tab 1&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;This is tab 1 content &amp;lt;a href=\&amp;quot;#\&amp;quot;&amp;gt;test&amp;lt;/a&amp;gt;&amp;quot;},&lt;br /&gt;
		{&amp;quot;id&amp;quot;:&amp;quot;tab2&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Tab 2&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;This is tab 2 content &amp;lt;a href=\&amp;quot;#\&amp;quot;&amp;gt;test&amp;lt;/a&amp;gt;&amp;quot;},&lt;br /&gt;
		{&amp;quot;id&amp;quot;:&amp;quot;tab3&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Tab 3&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;This is tab 3 content &amp;lt;a href=\&amp;quot;#\&amp;quot;&amp;gt;test&amp;lt;/a&amp;gt;&amp;quot;}&lt;br /&gt;
	]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The javascript required to power the tabs element (keyboard navigation, show / hide panels etc) is written as an AMD module and is included by the template. The javascript is a little too large to go through here, but some key points to consider when writing it are:&lt;br /&gt;
It should ideally be independent of the HTML structure, so if someone wants to completely rewrite the tabs to be different elements (e.g. buttons or a set of divs) then the same javascript can be used without needing to change it. In order to achieve this it is important to identify the key components of the template.&lt;br /&gt;
&lt;br /&gt;
In this case it is a tab list, a tab and it&#039;s content. One way to identify these components would be to inspect the structure of the DOM, for example you might say &amp;quot;find me the ul element&amp;quot; when looking for the tab list and then &amp;quot;find my the child li elements&amp;quot; to find the tabs. While this would work, it couples your javascript to the HTML structure and makes it difficult to change later. A different approach would be to use the element attributes, for example you might say &amp;quot;find my the element with the role &#039;tablist&#039;&amp;quot; to get the tab list and then &amp;quot;find me the elements with the role &#039;tab&#039;&amp;quot; to get the tabs. This allows the HTML structure to change without breaking the javascript (as long as the correct attributes are set, of course).&lt;br /&gt;
&lt;br /&gt;
Another point of consideration for this example is what class to apply to a tab when it is selected. It makes sense to just apply something like &amp;quot;active&amp;quot; in the javascript, but that once again couples it to a particular CSS framework which makes it more difficult to change without modifying the javascript. In this case I chose to add a data attribute to the element to indicate which class will be set when the tab is selected. This means the javascript doesn&#039;t have to guess what the appropriate class is, it can just get it from the template.&lt;br /&gt;
&lt;br /&gt;
Ok, so we&#039;ve got our basic template. It&#039;s time to use it! Let&#039;s say we want to create a simple user profile page that might show 2 tabs, the first tab will be the user&#039;s name and the second tab will be the user&#039;s email address (please excuse the contrived example).&lt;br /&gt;
&lt;br /&gt;
Here&#039;s what the page might look like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&amp;lt;title&amp;gt;User Profile&amp;lt;/title&amp;gt;&amp;lt;/header&amp;gt;&lt;br /&gt;
    &amp;lt;body&amp;gt;&lt;br /&gt;
        {{&amp;lt; core/tabs }}&lt;br /&gt;
    &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That looks pretty simple! The only problem is, how do I get my content there? I would have to supply a context like this in order to display the tabs I want:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;tabs&amp;quot;: [&lt;br /&gt;
		{&amp;quot;id&amp;quot;:&amp;quot;tab1&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Name&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;Your name is Mr. Test User.&amp;quot;},&lt;br /&gt;
		{&amp;quot;id&amp;quot;:&amp;quot;tab2&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Email&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;Your email is testuser@example.com&amp;quot;},&lt;br /&gt;
	]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let&#039;s assume that the context for this page doesn&#039;t match what the tabs template is expecting though (as will be the case most of the time). Let&#039;s assume the tabs template is being rendered with this context:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;name&amp;quot;:&amp;quot;Mr. Test User&amp;quot;,&lt;br /&gt;
	&amp;quot;email&amp;quot;:&amp;quot;testuser@example.com&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unfortunately, we&#039;ll almost certainly never have complete control over all of the contexts that our template will be rendered in which means we&#039;ll be expecting people to write new webservices to supply the same data in different formats every time they want to use a template. It becomes an unmanageable problem.&lt;br /&gt;
&lt;br /&gt;
Enter blocks! We can make the template more flexible by defining sections of the template that can be overriden when they are included. Pretty neat! This will allow us to enforce a certain core structure but not enforce a context on the template that is including the tabs.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s have another go at that template, this time leverging blocks:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;{{ uniqid }}-tab-container&amp;quot;&amp;gt;&lt;br /&gt;
	{{$ tabheader }}&lt;br /&gt;
		&amp;lt;ul role=&amp;quot;tablist&amp;quot; class=&amp;quot;nav nav-tabs&amp;quot;&amp;gt;&lt;br /&gt;
			{{$ tablist }}&lt;br /&gt;
				{{# tabs }}&lt;br /&gt;
					&amp;lt;li role=&amp;quot;tab&amp;quot;&lt;br /&gt;
							data-target=&amp;quot;{{ uniqid }}-{{ id }}&amp;quot;&lt;br /&gt;
							data-selected-class=&amp;quot;active&amp;quot;&lt;br /&gt;
							aria-controls=&amp;quot;{{ uniqid }}-{{ id }}&amp;quot;&lt;br /&gt;
							aria-selected=&amp;quot;false&amp;quot; tabindex=&amp;quot;-1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
						&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;{{{ name }}}&amp;lt;/a&amp;gt;&lt;br /&gt;
					&amp;lt;/li&amp;gt;&lt;br /&gt;
				{{/ tabs }}&lt;br /&gt;
			{{/ tablist }}&lt;br /&gt;
		&amp;lt;/ul&amp;gt;&lt;br /&gt;
	{{/ tabheader }}&lt;br /&gt;
	{{$ tabbody }}&lt;br /&gt;
		&amp;lt;div class=&amp;quot;tab-content&amp;quot;&amp;gt;&lt;br /&gt;
			{{$ tabcontent }}&lt;br /&gt;
				{{# tabs }}&lt;br /&gt;
					&amp;lt;div role=&amp;quot;tabpanel&amp;quot;&lt;br /&gt;
						class=&amp;quot;tab-pane&amp;quot;&lt;br /&gt;
						id=&amp;quot;{{ uniqid }}-{{ id }}&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
						{{{ content }}}&lt;br /&gt;
					&amp;lt;/div&amp;gt;&lt;br /&gt;
				{{/ tabs }}&lt;br /&gt;
			{{/ tabcontent }}&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
	{{/ tabbody }}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
{{#js}}&lt;br /&gt;
    require([&#039;jquery&#039;,&#039;core/tabs&#039;], function($, tabs) {&lt;br /&gt;
&lt;br /&gt;
        var container = $(&amp;quot;#{{ uniqid }}-tab-container&amp;quot;);&lt;br /&gt;
        tabs.create(container);&lt;br /&gt;
    });&lt;br /&gt;
{{/js}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A summary of what we&#039;ve changed:&lt;br /&gt;
* Added a $tabheader block around the tab list, in case someone wants to change the ul element to something else.&lt;br /&gt;
* Added a $tablist block around the group of tabs to allow them to be overriden on incldue.&lt;br /&gt;
* Added a $tabbody block around the content, in case someone wants to change the content elements from divs.&lt;br /&gt;
* Added a $tabcontent block around the tab variable for the content to allow the content to be overriden on inlcude.&lt;br /&gt;
&lt;br /&gt;
Now let&#039;s see what using this template looks like for your User Profile page:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&amp;lt;title&amp;gt;User Profile&amp;lt;/title&amp;gt;&amp;lt;/header&amp;gt;&lt;br /&gt;
    &amp;lt;body&amp;gt;&lt;br /&gt;
        {{&amp;gt; core/tabs }}&lt;br /&gt;
			{{$ tablist }}&lt;br /&gt;
				&amp;lt;li role=&amp;quot;tab&amp;quot;&lt;br /&gt;
						data-target=&amp;quot;{{ uniqid }}-tab1&amp;quot;&lt;br /&gt;
						data-selected-class=&amp;quot;active&amp;quot;&lt;br /&gt;
						aria-controls=&amp;quot;{{ uniqid }}-tab1&amp;quot;&lt;br /&gt;
						aria-selected=&amp;quot;false&amp;quot; tabindex=&amp;quot;-1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
					&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;Name&amp;lt;/a&amp;gt;&lt;br /&gt;
				&amp;lt;/li&amp;gt;&lt;br /&gt;
				&amp;lt;li role=&amp;quot;tab&amp;quot;&lt;br /&gt;
						data-target=&amp;quot;{{ uniqid }}-tab2&amp;quot;&lt;br /&gt;
						data-selected-class=&amp;quot;active&amp;quot;&lt;br /&gt;
						aria-controls=&amp;quot;{{ uniqid }}-tab2&amp;quot;&lt;br /&gt;
						aria-selected=&amp;quot;false&amp;quot; tabindex=&amp;quot;-1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
					&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;Email&amp;lt;/a&amp;gt;&lt;br /&gt;
				&amp;lt;/li&amp;gt;&lt;br /&gt;
			{{/ tablist }}&lt;br /&gt;
			{{$ tabcontent }}&lt;br /&gt;
				&amp;lt;div role=&amp;quot;tabpanel&amp;quot;&lt;br /&gt;
					class=&amp;quot;tab-pane&amp;quot;&lt;br /&gt;
					id=&amp;quot;{{ uniqid }}-tab1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
					Your name is {{ name }}.&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div role=&amp;quot;tabpanel&amp;quot;&lt;br /&gt;
					class=&amp;quot;tab-pane&amp;quot;&lt;br /&gt;
					id=&amp;quot;{{ uniqid }}-tab2&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
					Your email address is {{ email }}.&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
			{{/ tabcontent }}&lt;br /&gt;
		{{/ core/tabs }}&lt;br /&gt;
    &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That looks a bit better! Now we&#039;ve been able to use the blocks to successfully change the template to use the context available to this page, we no longer need a &amp;quot;tabs&amp;quot; array with &amp;quot;name&amp;quot; and &amp;quot;content&amp;quot;. Even the javascript will continue to work because we&#039;ve kept the correct element attributes. &lt;br /&gt;
&lt;br /&gt;
We&#039;ve still got a slight problem though... In order to change the data for the template we&#039;ve had to copy &amp;amp; paste the HTML from the original template into our blocks as we do the override. While this works fine in this example, it means we don&#039;t quite get the encapsulation we want within the templates since we&#039;re leaking internal implementation details. If we ever wanted to change the CSS framework we use for Moodle (say from bootstrap 2 to boostrap 3 or 4) we&#039;d have to find all the places in the code where this tabs template is used and make sure that the HTML is correct in their block overrides.&lt;br /&gt;
&lt;br /&gt;
With that in mind, let&#039;s take one more pass at this template and see if we can improve it slightly again. This time we&#039;re doing to split the template out into 3 templates.&lt;br /&gt;
&lt;br /&gt;
tabs.mustache:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;{{ uniqid }}-tab-container&amp;quot;&amp;gt;&lt;br /&gt;
	{{$ tabheader }}&lt;br /&gt;
		&amp;lt;ul role=&amp;quot;tablist&amp;quot; class=&amp;quot;nav nav-tabs&amp;quot;&amp;gt;&lt;br /&gt;
			{{$ tablist }}&lt;br /&gt;
				{{# tabs }}&lt;br /&gt;
					{{&amp;lt; core/tab_header_item }}		&lt;br /&gt;
				{{/ tabs }}&lt;br /&gt;
			{{/ tablist }}&lt;br /&gt;
		&amp;lt;/ul&amp;gt;&lt;br /&gt;
	{{/ tabheader }}&lt;br /&gt;
	{{$ tabbody }}&lt;br /&gt;
		&amp;lt;div class=&amp;quot;tab-content&amp;quot;&amp;gt;&lt;br /&gt;
			{{$ tabcontent }}&lt;br /&gt;
				{{# tabs }}&lt;br /&gt;
					{{&amp;lt; core/tab_content_item }}&lt;br /&gt;
				{{/ tabs }}&lt;br /&gt;
			{{/ tabcontent }}&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
	{{/ tabbody }}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
{{#js}}&lt;br /&gt;
    require([&#039;jquery&#039;,&#039;core/tabs&#039;], function($, tabs) {&lt;br /&gt;
&lt;br /&gt;
        var container = $(&amp;quot;#{{ uniqid }}-tab-container&amp;quot;);&lt;br /&gt;
        tabs.create(container);&lt;br /&gt;
    });&lt;br /&gt;
{{/js}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tab_header_item.mustache&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;li role=&amp;quot;tab&amp;quot;&lt;br /&gt;
		data-selected-class=&amp;quot;active&amp;quot;&lt;br /&gt;
		aria-selected=&amp;quot;false&amp;quot; tabindex=&amp;quot;-1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;{{$ tabname }}{{{ name }}}{{/ tabname }}&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tab_content_item.mustache&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div role=&amp;quot;tabpanel&amp;quot;&lt;br /&gt;
	class=&amp;quot;tab-pane&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	{{$ tabpanelcontent }}{{{ content }}}{{/ tabpanelcontent }}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A summary of the changes:&lt;br /&gt;
* Split the template into 3, moving the tab into it&#039;s own template and the content into it&#039;s own and then including them in the tabs template.&lt;br /&gt;
* Removed the ids from the tabs and content. The javascript would be updating to assign these ids at runtime so that they don&#039;t need to be provided as part of the template context.&lt;br /&gt;
* Added a $tabname block for in the tab_header_item template to make the name flexible on import.&lt;br /&gt;
* Added a $tabpanelcontant block in the tab_content_item template to make the content flexible on import.&lt;br /&gt;
&lt;br /&gt;
Cool, so let&#039;s see what that looks like in our example now:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&amp;lt;title&amp;gt;User Profile&amp;lt;/title&amp;gt;&amp;lt;/header&amp;gt;&lt;br /&gt;
    &amp;lt;body&amp;gt;&lt;br /&gt;
        {{&amp;gt; core/tabs }}&lt;br /&gt;
			{{$ tablist }}&lt;br /&gt;
				{{&amp;gt; core/tab_header_item }}&lt;br /&gt;
					{{$ tabname }}Name{{/ tabname }}&lt;br /&gt;
				{{/ core/tab_header_item }}&lt;br /&gt;
				{{&amp;gt; core/tab_header_item }}&lt;br /&gt;
					{{$ tabname }}Email{{/ tabname }}&lt;br /&gt;
				{{/ core/tab_header_item }}&lt;br /&gt;
			{{/ tablist }}&lt;br /&gt;
			{{$ tabcontent }}&lt;br /&gt;
				{{&amp;gt; core/tab_content_item }}&lt;br /&gt;
					{{$ tabpanelcontent }}Your name is {{ name }}.{{/ tabpanelcontent }}&lt;br /&gt;
				{{/ core/tab_content_item }}&lt;br /&gt;
				{{&amp;gt; core/tab_content_item }}&lt;br /&gt;
					{{$ tabpanelcontent }}Your email address is {{ email }}.{{/ tabpanelcontent }}&lt;br /&gt;
				{{/ core/tab_content_item }}&lt;br /&gt;
			{{/ tabcontent }}&lt;br /&gt;
		{{/ core/tabs }}&lt;br /&gt;
    &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And we&#039;re done! After making the changes above we&#039;ve been able to keep the benefits of the previous change to allow the context changes but we&#039;ve also removed the need to copy &amp;amp; paste the HTML everywhere. Instead we&#039;re able to use the child templates with a few additional blocks defined to get the content in there.&lt;br /&gt;
&lt;br /&gt;
Now if we want to change tabs HTML or CSS frameworks we can just change the core tabs templates and this page will receive the updates for free.&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=More_theme&amp;diff=48972</id>
		<title>More theme</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=More_theme&amp;diff=48972"/>
		<updated>2015-11-11T01:05:20Z</updated>

		<summary type="html">&lt;p&gt;Tqr: Created page with &amp;quot;Place holder for More theme documentation.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Place holder for More theme documentation.&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Themes_2.2_how_to_clone_a_Moodle_2.2_theme&amp;diff=48971</id>
		<title>Themes 2.2 how to clone a Moodle 2.2 theme</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Themes_2.2_how_to_clone_a_Moodle_2.2_theme&amp;diff=48971"/>
		<updated>2015-11-11T01:01:16Z</updated>

		<summary type="html">&lt;p&gt;Tqr: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}{{Moodle 2.2}}This document describes how to clone Afterburner theme so that you can build on this to create a theme of your own. It assumes you have some understanding of how themes work within Moodle 2.2, as well as a basic understanding of HTML and CSS. Also, because of the rapid development within Moodle, resulting in a number of versions available namely 2.0.x, 2.1.x, 2.2.x, 2.3.x and soon to be announced Moodle 2.4.x, it is important to understand that this tutorial is only valid for Moodle 2.2 and 2.3 themes. For more recent themes based on Clean and More, please check out the README.txt [https://github.com/moodle/moodle/blob/master/theme/clean/README.txt] file contained in the Clean folder.&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
From your Moodle &#039;&#039;&#039;theme&#039;&#039;&#039; directory &#039;&#039;&#039;right click&#039;&#039;&#039; on &#039;&#039;&#039;afterburner&#039;&#039;&#039; and then &#039;&#039;&#039;&#039;&#039;copy&#039;&#039;&#039; and  &#039;&#039;&#039;paste&#039;&#039;&#039;&#039;&#039; back into your Moodle &#039;&#039;&#039;theme&#039;&#039;&#039; directory. You should now have a folder called &#039;&#039;&#039;Copy of afterburner&#039;&#039;&#039;. If you &#039;&#039;&#039;right click&#039;&#039;&#039; this folder you are given the option to &#039;&#039;&#039;Rename&#039;&#039;&#039; it. So rename this folder to &#039;&#039;&#039;mytheme&#039;&#039;&#039; (or to whatever name you want to call your &#039;&#039;&#039;cloned&#039;&#039;&#039; theme). &#039;&#039;&#039;It is important to use only lower case letters and underscores&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
If you open the &#039;&#039;&#039;mytheme&#039;&#039;&#039; directory you will find several directories, sub-directories and files within it.&lt;br /&gt;
&lt;br /&gt;
These are:&lt;br /&gt;
; config.php :  Where all the theme configurations are made.&lt;br /&gt;
; lib.php :  Where all the functions for the themes settings are found.&lt;br /&gt;
; renderers.php :  Where all the renderers for this theme are found.&lt;br /&gt;
; settings.php :  Where all the setting for this theme are created.&lt;br /&gt;
; version.php :  Where the version number and plugin componant information is kept.&lt;br /&gt;
; /lang/ : This directory contains all language sub-directories for other languages if and when you want to add them.&lt;br /&gt;
; /lang/en/ : This sub-directory contains your language files, in this case &#039;&#039;English&#039;&#039;.&lt;br /&gt;
; /lang/en/theme_afterburner.php : This file contains all the language strings for your theme.   &lt;br /&gt;
; /layout/ : This directory contains all the layout files for this theme.&lt;br /&gt;
; /layout/default.php : Layout file for front page and general pages combined.&lt;br /&gt;
; /layout/embedded.php : Layout file for embedded pages.&lt;br /&gt;
; /style/ : This directory contains all the CSS files for this theme.&lt;br /&gt;
; /pix/ : This directory contains a screen shot of this theme as well as a favicon and any images used in the theme.&lt;br /&gt;
; /pix_core/ :&lt;br /&gt;
; /pix_plugins/ :&lt;br /&gt;
&lt;br /&gt;
==Renaming Elements==&lt;br /&gt;
&lt;br /&gt;
The problem when &#039;&#039;&#039;cloning&#039;&#039;&#039; a theme is that &#039;&#039;you need to rename all those instances where the old theme name occurs&#039;&#039;, in this case &#039;&#039;&#039;afterburner&#039;&#039;&#039;. The first place to look is &#039;&#039;&#039;config.php&#039;&#039;&#039;, where you you need to define the name of your theme. So change &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;name = &#039;afterburner&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
to the name of your new theme.&lt;br /&gt;
 &lt;br /&gt;
You will need to change the name of &#039;&#039;&#039;lang/en/theme_afterburner.php&#039;&#039;&#039;. This file, as well as needing to be renamed, also needs some of its content renaming too. So before you forget, &#039;&#039;&#039;right click&#039;&#039;&#039; on this file and &#039;&#039;&#039;rename&#039;&#039;&#039; it to the name of your new theme before you open it.&lt;br /&gt;
&lt;br /&gt;
=== Language Strings ===&lt;br /&gt;
&lt;br /&gt;
When you open &#039;&#039;&#039;theme_mytheme.php&#039;&#039;&#039; the first thing you will see are the &#039;&#039;&#039;credits&#039;&#039;&#039; for the theme. &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Strings for component &#039;theme_afterburner&#039;, language &#039;en&#039;&lt;br /&gt;
 *&lt;br /&gt;
 * @package   theme_afterburner&lt;br /&gt;
 * @copyright 2011&lt;br /&gt;
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here you will need to change the reference from &#039;&#039;&#039;afterburner&#039;&#039;&#039; to &#039;&#039;&#039;mytheme&#039;&#039;&#039;, you can leave the rest of this as it is.&lt;br /&gt;
&lt;br /&gt;
The next things you will find in this file are what are known as the &#039;&#039;&#039;language strings&#039;&#039;&#039;. These are all the customised &#039;&#039;&#039;&#039;&#039;words&#039;&#039; or &#039;&#039;phrases&#039;&#039;&#039;&#039;&#039; used in this theme. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;configtitle&#039;] = &#039;Afterburner Custom Settings&#039;;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;Afterburner&#039;;&lt;br /&gt;
$string[&#039;region-side-post&#039;] = &#039;Right&#039;;&lt;br /&gt;
$string[&#039;region-side-pre&#039;] = &#039;Left&#039;;&lt;br /&gt;
...&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the $string section above, you will need to change ALL instances of the old theme name Afterburner to your new theme name. In this next section alone you will find seven instances of the name Afterburner to rename.&lt;br /&gt;
&lt;br /&gt;
The only section you may want to change completely is the &#039;&#039;&#039;choosereadme&#039;&#039;&#039;. You could write something like this instead.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;choosereadme&#039;] = &#039;My theme is a customised Moodle theme&lt;br /&gt;
based on the Moodle 2.2 Afterburner theme by Mary Evans.&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you have finished all the changes in this file save it and close it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Custom Settings ==&lt;br /&gt;
&lt;br /&gt;
Now that you have had a chance to search for and change all the instances in the language file, you will be more familiar for what you are looking for when you begin the mamoth task of going through the files associated with the Custom Settings for the Afterburner theme. &lt;br /&gt;
There are three files to check through. These are...&lt;br /&gt;
;settings.php&lt;br /&gt;
;renderers.php&lt;br /&gt;
;lib.php&lt;br /&gt;
&lt;br /&gt;
But do be sure to rename ALL the instances in these three files, as there are quite a number of them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Version ==&lt;br /&gt;
&lt;br /&gt;
The last file to change is version.php, here you will find the following...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Theme version info&lt;br /&gt;
 *&lt;br /&gt;
 * @package    theme&lt;br /&gt;
 * @subpackage afterburner&lt;br /&gt;
 * @copyright  2011 Mary Evans&lt;br /&gt;
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die;&lt;br /&gt;
&lt;br /&gt;
$plugin-&amp;gt;version   = 2011082400; // The current module version (Date: YYYYMMDDXX)&lt;br /&gt;
$plugin-&amp;gt;requires  = 2011081700; // Requires this Moodle version&lt;br /&gt;
$plugin-&amp;gt;component = &#039;theme_afterburner&#039;; // Full name of the plugin (used for diagnostics)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Just as long as you change the instance of afterburner to your new theme&#039;s name you will be almost ready to try out this theme in your Moodle 2.2. installation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== CSS Stylesheets ==&lt;br /&gt;
&lt;br /&gt;
If you want this theme to use the same CSS rules from the Afterburner theme, then you need to make one more change to your new theme&#039;s config.php file.&lt;br /&gt;
&lt;br /&gt;
First you will need to ADD afterburner to the parent theme array like this...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;afterburner&#039;, &#039;base&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next you can delete all these style sheets from this list bar one file...that is afterburner_settings.css. This is important as your theme will need to rely on this stylesheet for your custom settings. So delete this list...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&lt;br /&gt;
    &#039;afterburner_layout&#039;,   /** Must come first: Page layout **/&lt;br /&gt;
    &#039;afterburner_styles&#039;,   /** Must come second: default styles **/&lt;br /&gt;
    &#039;afterburner_menu&#039;,&lt;br /&gt;
    &#039;afterburner_blocks&#039;,&lt;br /&gt;
    &#039;afterburner_mod&#039;,&lt;br /&gt;
    &#039;afterburner_calendar&#039;,&lt;br /&gt;
    &#039;afterburner_dock&#039;,&lt;br /&gt;
    &#039;afterburner_settings&#039;,&lt;br /&gt;
    &#039;rtl&#039;&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
but leave afterburner_settings.css which you could just rename to settings.css.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;settings&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will then be able to delete all the stylesheets from your new theme&#039;s style directory leaving just editor.css and afterburner_settings.css which you will also need to rename to settings.css. &lt;br /&gt;
&lt;br /&gt;
So whenever you need to change the CSS for your new theme, you can do this in your theme&#039;s settings page, by going to Site Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; and choose your new theme from those names listed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Cut to the chase ==&lt;br /&gt;
&lt;br /&gt;
Patience is a virtue! :)&lt;br /&gt;
&lt;br /&gt;
If you have only just got here and not read the above Tutorial then you have missed the best part. If on the other hand you have finished this tutorial, then please let me have some feedback.  &lt;br /&gt;
&lt;br /&gt;
If after reading this you run into problems, and need more help, then do please ask in the Themes Forum, [http://moodle.org/mod/forum/view.php?id=46] where you will find lots of help with your new theme project.&lt;br /&gt;
&lt;br /&gt;
--[[User:Mary Evans 2|Mary Evans 2]] 06:03, 7 April 2012 (WST)&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Themes_2.2_how_to_clone_a_Moodle_2.2_theme&amp;diff=48970</id>
		<title>Themes 2.2 how to clone a Moodle 2.2 theme</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Themes_2.2_how_to_clone_a_Moodle_2.2_theme&amp;diff=48970"/>
		<updated>2015-11-11T00:57:59Z</updated>

		<summary type="html">&lt;p&gt;Tqr: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}{{Moodle 2.2}}This document describes how to clone Afterburner theme so that you can build on this to create a theme of your own. It assumes you have some understanding of how themes work within Moodle 2.2, as well as a basic understanding of HTML and CSS. Also, because of the rapid development within Moodle, resulting in a number of versions available namely 2.0.x, 2.1.x, 2.2.x, 2.3.x and soon to be announced Moodle 2.4.x, it is important to understand that this tutorial is only valid for Moodle 2.2 and 2.3 themes. For more recent themes based on Clean and More, please check out the [[ReadMe|https://github.com/moodle/moodle/blob/master/theme/clean/README.txt]] file contained in the Clean folder.&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
From your Moodle &#039;&#039;&#039;theme&#039;&#039;&#039; directory &#039;&#039;&#039;right click&#039;&#039;&#039; on &#039;&#039;&#039;afterburner&#039;&#039;&#039; and then &#039;&#039;&#039;&#039;&#039;copy&#039;&#039;&#039; and  &#039;&#039;&#039;paste&#039;&#039;&#039;&#039;&#039; back into your Moodle &#039;&#039;&#039;theme&#039;&#039;&#039; directory. You should now have a folder called &#039;&#039;&#039;Copy of afterburner&#039;&#039;&#039;. If you &#039;&#039;&#039;right click&#039;&#039;&#039; this folder you are given the option to &#039;&#039;&#039;Rename&#039;&#039;&#039; it. So rename this folder to &#039;&#039;&#039;mytheme&#039;&#039;&#039; (or to whatever name you want to call your &#039;&#039;&#039;cloned&#039;&#039;&#039; theme). &#039;&#039;&#039;It is important to use only lower case letters and underscores&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
If you open the &#039;&#039;&#039;mytheme&#039;&#039;&#039; directory you will find several directories, sub-directories and files within it.&lt;br /&gt;
&lt;br /&gt;
These are:&lt;br /&gt;
; config.php :  Where all the theme configurations are made.&lt;br /&gt;
; lib.php :  Where all the functions for the themes settings are found.&lt;br /&gt;
; renderers.php :  Where all the renderers for this theme are found.&lt;br /&gt;
; settings.php :  Where all the setting for this theme are created.&lt;br /&gt;
; version.php :  Where the version number and plugin componant information is kept.&lt;br /&gt;
; /lang/ : This directory contains all language sub-directories for other languages if and when you want to add them.&lt;br /&gt;
; /lang/en/ : This sub-directory contains your language files, in this case &#039;&#039;English&#039;&#039;.&lt;br /&gt;
; /lang/en/theme_afterburner.php : This file contains all the language strings for your theme.   &lt;br /&gt;
; /layout/ : This directory contains all the layout files for this theme.&lt;br /&gt;
; /layout/default.php : Layout file for front page and general pages combined.&lt;br /&gt;
; /layout/embedded.php : Layout file for embedded pages.&lt;br /&gt;
; /style/ : This directory contains all the CSS files for this theme.&lt;br /&gt;
; /pix/ : This directory contains a screen shot of this theme as well as a favicon and any images used in the theme.&lt;br /&gt;
; /pix_core/ :&lt;br /&gt;
; /pix_plugins/ :&lt;br /&gt;
&lt;br /&gt;
==Renaming Elements==&lt;br /&gt;
&lt;br /&gt;
The problem when &#039;&#039;&#039;cloning&#039;&#039;&#039; a theme is that &#039;&#039;you need to rename all those instances where the old theme name occurs&#039;&#039;, in this case &#039;&#039;&#039;afterburner&#039;&#039;&#039;. The first place to look is &#039;&#039;&#039;config.php&#039;&#039;&#039;, where you you need to define the name of your theme. So change &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;name = &#039;afterburner&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
to the name of your new theme.&lt;br /&gt;
 &lt;br /&gt;
You will need to change the name of &#039;&#039;&#039;lang/en/theme_afterburner.php&#039;&#039;&#039;. This file, as well as needing to be renamed, also needs some of its content renaming too. So before you forget, &#039;&#039;&#039;right click&#039;&#039;&#039; on this file and &#039;&#039;&#039;rename&#039;&#039;&#039; it to the name of your new theme before you open it.&lt;br /&gt;
&lt;br /&gt;
=== Language Strings ===&lt;br /&gt;
&lt;br /&gt;
When you open &#039;&#039;&#039;theme_mytheme.php&#039;&#039;&#039; the first thing you will see are the &#039;&#039;&#039;credits&#039;&#039;&#039; for the theme. &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Strings for component &#039;theme_afterburner&#039;, language &#039;en&#039;&lt;br /&gt;
 *&lt;br /&gt;
 * @package   theme_afterburner&lt;br /&gt;
 * @copyright 2011&lt;br /&gt;
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here you will need to change the reference from &#039;&#039;&#039;afterburner&#039;&#039;&#039; to &#039;&#039;&#039;mytheme&#039;&#039;&#039;, you can leave the rest of this as it is.&lt;br /&gt;
&lt;br /&gt;
The next things you will find in this file are what are known as the &#039;&#039;&#039;language strings&#039;&#039;&#039;. These are all the customised &#039;&#039;&#039;&#039;&#039;words&#039;&#039; or &#039;&#039;phrases&#039;&#039;&#039;&#039;&#039; used in this theme. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;configtitle&#039;] = &#039;Afterburner Custom Settings&#039;;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;Afterburner&#039;;&lt;br /&gt;
$string[&#039;region-side-post&#039;] = &#039;Right&#039;;&lt;br /&gt;
$string[&#039;region-side-pre&#039;] = &#039;Left&#039;;&lt;br /&gt;
...&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the $string section above, you will need to change ALL instances of the old theme name Afterburner to your new theme name. In this next section alone you will find seven instances of the name Afterburner to rename.&lt;br /&gt;
&lt;br /&gt;
The only section you may want to change completely is the &#039;&#039;&#039;choosereadme&#039;&#039;&#039;. You could write something like this instead.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;choosereadme&#039;] = &#039;My theme is a customised Moodle theme&lt;br /&gt;
based on the Moodle 2.2 Afterburner theme by Mary Evans.&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you have finished all the changes in this file save it and close it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Custom Settings ==&lt;br /&gt;
&lt;br /&gt;
Now that you have had a chance to search for and change all the instances in the language file, you will be more familiar for what you are looking for when you begin the mamoth task of going through the files associated with the Custom Settings for the Afterburner theme. &lt;br /&gt;
There are three files to check through. These are...&lt;br /&gt;
;settings.php&lt;br /&gt;
;renderers.php&lt;br /&gt;
;lib.php&lt;br /&gt;
&lt;br /&gt;
But do be sure to rename ALL the instances in these three files, as there are quite a number of them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Version ==&lt;br /&gt;
&lt;br /&gt;
The last file to change is version.php, here you will find the following...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Theme version info&lt;br /&gt;
 *&lt;br /&gt;
 * @package    theme&lt;br /&gt;
 * @subpackage afterburner&lt;br /&gt;
 * @copyright  2011 Mary Evans&lt;br /&gt;
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die;&lt;br /&gt;
&lt;br /&gt;
$plugin-&amp;gt;version   = 2011082400; // The current module version (Date: YYYYMMDDXX)&lt;br /&gt;
$plugin-&amp;gt;requires  = 2011081700; // Requires this Moodle version&lt;br /&gt;
$plugin-&amp;gt;component = &#039;theme_afterburner&#039;; // Full name of the plugin (used for diagnostics)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Just as long as you change the instance of afterburner to your new theme&#039;s name you will be almost ready to try out this theme in your Moodle 2.2. installation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== CSS Stylesheets ==&lt;br /&gt;
&lt;br /&gt;
If you want this theme to use the same CSS rules from the Afterburner theme, then you need to make one more change to your new theme&#039;s config.php file.&lt;br /&gt;
&lt;br /&gt;
First you will need to ADD afterburner to the parent theme array like this...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;afterburner&#039;, &#039;base&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next you can delete all these style sheets from this list bar one file...that is afterburner_settings.css. This is important as your theme will need to rely on this stylesheet for your custom settings. So delete this list...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&lt;br /&gt;
    &#039;afterburner_layout&#039;,   /** Must come first: Page layout **/&lt;br /&gt;
    &#039;afterburner_styles&#039;,   /** Must come second: default styles **/&lt;br /&gt;
    &#039;afterburner_menu&#039;,&lt;br /&gt;
    &#039;afterburner_blocks&#039;,&lt;br /&gt;
    &#039;afterburner_mod&#039;,&lt;br /&gt;
    &#039;afterburner_calendar&#039;,&lt;br /&gt;
    &#039;afterburner_dock&#039;,&lt;br /&gt;
    &#039;afterburner_settings&#039;,&lt;br /&gt;
    &#039;rtl&#039;&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
but leave afterburner_settings.css which you could just rename to settings.css.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;settings&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will then be able to delete all the stylesheets from your new theme&#039;s style directory leaving just editor.css and afterburner_settings.css which you will also need to rename to settings.css. &lt;br /&gt;
&lt;br /&gt;
So whenever you need to change the CSS for your new theme, you can do this in your theme&#039;s settings page, by going to Site Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; and choose your new theme from those names listed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Cut to the chase ==&lt;br /&gt;
&lt;br /&gt;
Patience is a virtue! :)&lt;br /&gt;
&lt;br /&gt;
If you have only just got here and not read the above Tutorial then you have missed the best part. If on the other hand you have finished this tutorial, then please let me have some feedback.  &lt;br /&gt;
&lt;br /&gt;
If after reading this you run into problems, and need more help, then do please ask in the Themes Forum, [http://moodle.org/mod/forum/view.php?id=46] where you will find lots of help with your new theme project.&lt;br /&gt;
&lt;br /&gt;
--[[User:Mary Evans 2|Mary Evans 2]] 06:03, 7 April 2012 (WST)&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=CSS_Coding_Style&amp;diff=48478</id>
		<title>CSS Coding Style</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=CSS_Coding_Style&amp;diff=48478"/>
		<updated>2015-08-30T23:54:25Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Values and properties */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress|forumurl=https://moodle.org/mod/forum/discuss.php?d=275476}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
&lt;br /&gt;
This document describes style guidelines for developers working on or with Moodle code. It talks purely about the mechanics of code layout and the choices we have made for Moodle. &lt;br /&gt;
&lt;br /&gt;
=== Goals ===&lt;br /&gt;
&lt;br /&gt;
Consistent coding style is important in any development project, and particularly when many developers are involved. A standard style helps to ensure that the code is easier to read and understand, which helps overall quality.&lt;br /&gt;
&lt;br /&gt;
Abstract goals we strive for: &lt;br /&gt;
&lt;br /&gt;
* simplicity&lt;br /&gt;
* readability&lt;br /&gt;
* tool friendliness&lt;br /&gt;
&lt;br /&gt;
== File naming ==&lt;br /&gt;
&lt;br /&gt;
Within plugins, CSS files are normally named &amp;lt;code&amp;gt;styles.css&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In the theme, files can be named according to the theme designer&#039;s wishes but should:&lt;br /&gt;
&lt;br /&gt;
* use lowercase letters and &#039;-&#039; to separate words&lt;br /&gt;
* be as succinct as possible&lt;br /&gt;
* be descriptive&lt;br /&gt;
* be placed in the folder &amp;lt;code&amp;gt;style/&amp;lt;/code&amp;gt; for CSS files, or in &amp;lt;code&amp;gt;less/&amp;lt;/code&amp;gt; for LESS files.&lt;br /&gt;
&lt;br /&gt;
== Blocks ==&lt;br /&gt;
&lt;br /&gt;
* Each selector should be on its own line. If there is a comma in a selector list, follow it with a line break.&lt;br /&gt;
* Property-value pairs should be on their own line, with four spaces of indentation and an ending semicolon.&lt;br /&gt;
* The closing brace should use the same level of indentation as the opening selector.&lt;br /&gt;
* Leave one line between blocks.&lt;br /&gt;
&lt;br /&gt;
=== Correct ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;@media only screen and (min-width: 768px) {&lt;br /&gt;
    .selector-one,&lt;br /&gt;
    .selector-two {&lt;br /&gt;
        color: #fff;&lt;br /&gt;
        background-color: #000;&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Incorrect ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.selector_one, .selector_two { color: #fff; background-color: #000; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selectors ==&lt;br /&gt;
&lt;br /&gt;
* Always use lower case and underscores or hyphens. Hyphens are preferred.&lt;br /&gt;
* Names should be made of simple English words.&lt;br /&gt;
* Verbosity is encouraged: names should be as illustrative as is practical to enhance understanding.&lt;br /&gt;
* Use [http://css-tricks.com/semantic-class-names/ semantic names]: names tell what this is instead of what should it look like.&lt;br /&gt;
* Avoid using IDs. They are far more difficult to maintain and override.&lt;br /&gt;
* Do not over-qualify your rules by combining a tagname with a class or ID.&lt;br /&gt;
&lt;br /&gt;
=== Correct ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.selector_name {&lt;br /&gt;
    color: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.selector-name {&lt;br /&gt;
    color: #fff;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Incorrect ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;div#selName {&lt;br /&gt;
    color: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.Color-White {&lt;br /&gt;
    color: #fff;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Properties and values ==&lt;br /&gt;
&lt;br /&gt;
* Should be separated by a colon and a single space, do not minify them.&lt;br /&gt;
* Should be lowercase, except for font names and vendor-specific properties.&lt;br /&gt;
* For color codes, lowercase is preferred and a shorthand whenever possible.&lt;br /&gt;
* For color codes, if you use HSLA or RGBA, always provide a hex fallback.&lt;br /&gt;
* Use shorthand (except when overriding styles) for background, border, font, list-style, margin, and padding values.&lt;br /&gt;
* Do not use &amp;lt;code&amp;gt;!important&amp;lt;/code&amp;gt;. If there is no alternative something is wrong with the CSS you are trying to override.&lt;br /&gt;
* Prefixed vendor-specific properties pairs should appear directly before the generic property they refer to.&lt;br /&gt;
* Indent vendor prefixed declarations so that their values are aligned&lt;br /&gt;
&lt;br /&gt;
=== Correct ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.selector {&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    -webkit-border-radius: 4px;&lt;br /&gt;
       -moz-border-radius: 4px;&lt;br /&gt;
            border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.selector {&lt;br /&gt;
    margin-top: 1px;&lt;br /&gt;
    color: #f90;&lt;br /&gt;
    color: hsla(0, 0%, 100%, 1);&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Incorrect ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;#selector {&lt;br /&gt;
    color: hsla(0, 0%, 100%, 1);&lt;br /&gt;
    -webkit-border-radius: 4px;&lt;br /&gt;
    -moz-border-radius: 4px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#selector {&lt;br /&gt;
    margin-top:1px;&lt;br /&gt;
    color :#ff9900 !important;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Units ==&lt;br /&gt;
&lt;br /&gt;
* Prefer the usage of &#039;&#039;em&#039;&#039; over &#039;&#039;px&#039;&#039;.&lt;br /&gt;
* Do not use the units &#039;&#039;pt&#039;&#039; or &#039;&#039;rem&#039;&#039;. MDL-39934&lt;br /&gt;
* Do not declare the unit when the value is 0.&lt;br /&gt;
&lt;br /&gt;
=== Correct ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.something {&lt;br /&gt;
    margin-top: 0;&lt;br /&gt;
    font-size: 1.25em;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Incorrect ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.something {&lt;br /&gt;
    margin-top: 0px;&lt;br /&gt;
    font-size: 1.25rem;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Documentation and comments ==&lt;br /&gt;
&lt;br /&gt;
Following the general [[Coding style]], comments should start with a capital letter and end with a period.&lt;br /&gt;
&lt;br /&gt;
A block-style comment at the top of the CSS file should explain the purpose of the rules in the file.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * File base.css.&lt;br /&gt;
 * Contains base styles for theme basic.&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Block-style comments can also be used to denote a section in a CSS file where all rules pertain to a specific component, view, or functionality:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * SCORM Navigation Sidebar.&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use single-line comments to provide more information to other developers about a single rule or small subset of rules:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/* Required because YUI resets add a black border to all tables */&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Progressive enhancement ==&lt;br /&gt;
&lt;br /&gt;
* Fallbacks should always be provided. For example, provide a background color fallback to background images and gradients.&lt;br /&gt;
* Use vendor prefixes only when the supported browser in question does not support the unprefixed property.&lt;br /&gt;
* The standard property should come after the vendor-prefixed property.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.selector {&lt;br /&gt;
    background-color: #444; /* Fallback for browsers that don&#039;t support gradients. */&lt;br /&gt;
    filter: progid:DXImageTransform.Microsoft.gradient(startColorStr=&#039;#444&#039;, EndColorStr=&#039;#999&#039;); /* IE6-IE9. */&lt;br /&gt;
    background-image: -webkit-gradient(linear, left top, left bottom, from(#444), to(#999)); /* Safari 4+, Chrome. */&lt;br /&gt;
    background-image: -webkit-linear-gradient(top, #444, #999); /* Chrome 10+, Safari 5.1+, iOS 5+. */&lt;br /&gt;
    background-image: -moz-linear-gradient(top, #444, #999); /* Firefox 3.6. */&lt;br /&gt;
    background-image: -ms-linear-gradient(top, #444, #999); /* IE10. */&lt;br /&gt;
    background-image: -o-linear-gradient(top, #444, #999); /* Opera 11.10+. */&lt;br /&gt;
    background-image: linear-gradient(top, #444, #999); /* W3C Standard. */&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Browser Hacks ==&lt;br /&gt;
&lt;br /&gt;
* Do not use any browser-specific hacks. Moodle provides a more appropriate way to write browser-specific CSS using classes that are added to the body element. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
.ie7 .forum-post {&lt;br /&gt;
    min-height: 1px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* It is not necessary to include hacks for versions of browsers that Moodle core does not provide support for (e.g. IE6 in Moodle 2, except legacy theme).&lt;br /&gt;
&lt;br /&gt;
== Plugins ==&lt;br /&gt;
&lt;br /&gt;
In plugins, the file names can be:&lt;br /&gt;
&lt;br /&gt;
* styles.css (Recommended)&lt;br /&gt;
* styles_&amp;lt;theme name&amp;gt;.css (Not recommended, reserved to 3rd party plugins)&lt;br /&gt;
&lt;br /&gt;
=== Barebones ===&lt;br /&gt;
&lt;br /&gt;
Plugins should define the strict minimum, no text sizes, colours, etc ... those should belong to the theme and not be hardcoded in plugins to allow for easy theming. Of course, this requires Moodle core to provide re-usable classes to style the elements. As Moodle 2.7 has made Bootstrap 2 by default we can start using their classes, but we should make sure that there is a sensible fallback for themes not extending &#039;&#039;bootstrapbase&#039;&#039;, such as &#039;&#039;base&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Right-to-left ==&lt;br /&gt;
&lt;br /&gt;
Developers always have to pay attention to RTL languages.&lt;br /&gt;
&lt;br /&gt;
=== Selector ===&lt;br /&gt;
&lt;br /&gt;
Always use the selector &amp;lt;code&amp;gt;.dir-rtl&amp;lt;/code&amp;gt; to define RTL rules. That class is set on the BODY tag, and it should be placed first if you are combining it with another BODY class. When you are using LESS, encapsulate all the rules in &amp;lt;code&amp;gt;.dir-rtl&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Correct ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.dir-rtl .something {&lt;br /&gt;
    margin-left: 0;&lt;br /&gt;
    margin-right: 1em;&lt;br /&gt;
}&lt;br /&gt;
.dir-rtl.page-mod-something p {&lt;br /&gt;
    padding-left: 0;&lt;br /&gt;
    padding-right: 1em;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.dir-rtl {&lt;br /&gt;
    &amp;amp;.page-mod-something {&lt;br /&gt;
        p {&lt;br /&gt;
            padding-left: 0;&lt;br /&gt;
            padding-right: 1em;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    .something {&lt;br /&gt;
        margin-left: 0;&lt;br /&gt;
        margin-right: 1em;&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Incorrect ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;body.dir-rtl .something {&lt;br /&gt;
    margin-left: 0;&lt;br /&gt;
    margin-right: 1em;&lt;br /&gt;
}&lt;br /&gt;
.page-mod-something.dir-rtl p {&lt;br /&gt;
    padding-left: 0;&lt;br /&gt;
    padding-right: 1em;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.dir-rtl {&lt;br /&gt;
    &amp;amp;.page-mod-something {&lt;br /&gt;
        p {&lt;br /&gt;
            padding-left: 0;&lt;br /&gt;
            padding-right: 1em;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
.dir-rtl {&lt;br /&gt;
    .something {&lt;br /&gt;
        margin-left: 0;&lt;br /&gt;
        margin-right: 1em;&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rule placement ===&lt;br /&gt;
&lt;br /&gt;
The RTL rules should be written close to the LTR ones, not in another file. Placing them close to the LTR ones helps (and reminds) the developers to fix both, without the need to search for the existence of RTL rules. If you are using LESS, it is advised to split a huge block into smaller chunks to help locating the corresponding LTR rules.&lt;br /&gt;
&lt;br /&gt;
=== Automatic compliance ===&lt;br /&gt;
&lt;br /&gt;
Whenever possible you should try to avoid writing specific RTL rules. It is more often than one would think possible to have one rule working for both LTR and RTL.&lt;br /&gt;
&lt;br /&gt;
==== Recommended ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;p {&lt;br /&gt;
    margin: 0 1em;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== To avoid ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;p {&lt;br /&gt;
    margin-left: 1em;&lt;br /&gt;
}&lt;br /&gt;
.dir-rtl p {&lt;br /&gt;
    margin-right: 1em;&lt;br /&gt;
    margin-left: 0;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What to style ===&lt;br /&gt;
&lt;br /&gt;
RTL rules should only apply to positioning properties, nothing else. And in most cases you will want to revert the LTR rules, to make sure that the rest works as expected.&lt;br /&gt;
&lt;br /&gt;
==== Correct ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.something {&lt;br /&gt;
    text-color: red;&lt;br /&gt;
    padding-left: 1em;&lt;br /&gt;
}&lt;br /&gt;
.dir-rtl .something {&lt;br /&gt;
    padding-left: 0;&lt;br /&gt;
    padding-right: 1em;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Incorrect ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
.dir-rtl .something {&lt;br /&gt;
    text-color: red;&lt;br /&gt;
    padding-right: 1em;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== LESS ==&lt;br /&gt;
&lt;br /&gt;
[http://lesscss.org/ LESS] works like CSS with some extra features. It should follow the CSS guidelines.&lt;br /&gt;
&lt;br /&gt;
=== Variables ===&lt;br /&gt;
&lt;br /&gt;
* They should use camelCase to follow Bootstrap 2 that is used in core.&lt;br /&gt;
* As for CSS selectors, use semantic names: names tell what this is instead of what should it look like.&lt;br /&gt;
* As Bootstrap 2 does, do not add the word &amp;quot;Color&amp;quot; to variables for _background_ or _border_ and their derivatives.&lt;br /&gt;
* Declaring new variables should be done sparingly, too many variables kill the purpose of using them. If you declare one, try to set its default value from another one.&lt;br /&gt;
* Do not declare more variables than necessary. E.g.: If the background color and border color are likely to always be the same, prefer one variable.&lt;br /&gt;
&lt;br /&gt;
==== Correct ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;@textColor: red;&lt;br /&gt;
@wellBackground: #ccc;&lt;br /&gt;
@tableBackground: blue;&lt;br /&gt;
@blockBackground: @wellBackground;&lt;br /&gt;
@calendarGroupEvent: #f90;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Incorrect ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;@text-color: red;&lt;br /&gt;
@wellBackground: #ccc;&lt;br /&gt;
@tableBackgrounColor: blue;&lt;br /&gt;
@blockBackground: #ccc;&lt;br /&gt;
@calendarGroupEventBackground: #f90;&lt;br /&gt;
@calendarGroupEventBorder: #f90;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Selectors ===&lt;br /&gt;
&lt;br /&gt;
* Selectors should be encapsulated rather than duplicated.&lt;br /&gt;
&lt;br /&gt;
==== Correct ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;div {&lt;br /&gt;
    .something {&lt;br /&gt;
        color: red;&lt;br /&gt;
        a {&lt;br /&gt;
            color: blue;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    .something-else a {&lt;br /&gt;
        color: green;&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Incorrect ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;div .something {&lt;br /&gt;
    color: red;&lt;br /&gt;
}&lt;br /&gt;
div .something a {&lt;br /&gt;
    color: blue;&lt;br /&gt;
}&lt;br /&gt;
div .something-else a {&lt;br /&gt;
    color: green;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Values and properties ===&lt;br /&gt;
&lt;br /&gt;
* Colours, font sizes, etc... should never be hardcoded. You should, where possible, use a variable instead.&lt;br /&gt;
* The use of &#039;mixins&#039; is encouraged instead of duplicating values and properties.&lt;br /&gt;
&lt;br /&gt;
==== Correct ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.error {&lt;br /&gt;
    font-size: @fontSizeSmall;&lt;br /&gt;
    color: @errorText;&lt;br /&gt;
    padding: 1em;&lt;br /&gt;
    background-color: @errorBackground;&lt;br /&gt;
}&lt;br /&gt;
div .form-error {&lt;br /&gt;
    .error;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Incorrect ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.error {&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    color: red;&lt;br /&gt;
    padding: 1em;&lt;br /&gt;
    background-color: white;&lt;br /&gt;
}&lt;br /&gt;
div .form-error {&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    color: red;&lt;br /&gt;
    padding: 1em;&lt;br /&gt;
    background-color: white;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Themes Clean and More ==&lt;br /&gt;
&lt;br /&gt;
Clean theme should, where possible, not contain any CSS or LESS content. More theme, in comparison, inherits CSS styles for the logo from Clean theme, but also contains a small amount of LESS as an example for when customising a theme. Both Clean and More inherit fully all the CSS from their parent theme &#039;Bootstrap Base&#039;.&lt;br /&gt;
&lt;br /&gt;
== Credits ==&lt;br /&gt;
&lt;br /&gt;
This document was drawn from the following sources:&lt;br /&gt;
&lt;br /&gt;
# The [http://codex.wordpress.org/CSS_Coding_Standards WordPress CSS Coding Standards] &lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Coding]]&lt;br /&gt;
* [[Coding_style|Coding style]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Coding guidelines|CSS Coding style]]&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=CSS_Coding_Style&amp;diff=48477</id>
		<title>CSS Coding Style</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=CSS_Coding_Style&amp;diff=48477"/>
		<updated>2015-08-30T23:47:48Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Themes Clean and More */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress|forumurl=https://moodle.org/mod/forum/discuss.php?d=275476}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
&lt;br /&gt;
This document describes style guidelines for developers working on or with Moodle code. It talks purely about the mechanics of code layout and the choices we have made for Moodle. &lt;br /&gt;
&lt;br /&gt;
=== Goals ===&lt;br /&gt;
&lt;br /&gt;
Consistent coding style is important in any development project, and particularly when many developers are involved. A standard style helps to ensure that the code is easier to read and understand, which helps overall quality.&lt;br /&gt;
&lt;br /&gt;
Abstract goals we strive for: &lt;br /&gt;
&lt;br /&gt;
* simplicity&lt;br /&gt;
* readability&lt;br /&gt;
* tool friendliness&lt;br /&gt;
&lt;br /&gt;
== File naming ==&lt;br /&gt;
&lt;br /&gt;
Within plugins, CSS files are normally named &amp;lt;code&amp;gt;styles.css&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In the theme, files can be named according to the theme designer&#039;s wishes but should:&lt;br /&gt;
&lt;br /&gt;
* use lowercase letters and &#039;-&#039; to separate words&lt;br /&gt;
* be as succinct as possible&lt;br /&gt;
* be descriptive&lt;br /&gt;
* be placed in the folder &amp;lt;code&amp;gt;style/&amp;lt;/code&amp;gt; for CSS files, or in &amp;lt;code&amp;gt;less/&amp;lt;/code&amp;gt; for LESS files.&lt;br /&gt;
&lt;br /&gt;
== Blocks ==&lt;br /&gt;
&lt;br /&gt;
* Each selector should be on its own line. If there is a comma in a selector list, follow it with a line break.&lt;br /&gt;
* Property-value pairs should be on their own line, with four spaces of indentation and an ending semicolon.&lt;br /&gt;
* The closing brace should use the same level of indentation as the opening selector.&lt;br /&gt;
* Leave one line between blocks.&lt;br /&gt;
&lt;br /&gt;
=== Correct ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;@media only screen and (min-width: 768px) {&lt;br /&gt;
    .selector-one,&lt;br /&gt;
    .selector-two {&lt;br /&gt;
        color: #fff;&lt;br /&gt;
        background-color: #000;&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Incorrect ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.selector_one, .selector_two { color: #fff; background-color: #000; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selectors ==&lt;br /&gt;
&lt;br /&gt;
* Always use lower case and underscores or hyphens. Hyphens are preferred.&lt;br /&gt;
* Names should be made of simple English words.&lt;br /&gt;
* Verbosity is encouraged: names should be as illustrative as is practical to enhance understanding.&lt;br /&gt;
* Use [http://css-tricks.com/semantic-class-names/ semantic names]: names tell what this is instead of what should it look like.&lt;br /&gt;
* Avoid using IDs. They are far more difficult to maintain and override.&lt;br /&gt;
* Do not over-qualify your rules by combining a tagname with a class or ID.&lt;br /&gt;
&lt;br /&gt;
=== Correct ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.selector_name {&lt;br /&gt;
    color: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.selector-name {&lt;br /&gt;
    color: #fff;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Incorrect ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;div#selName {&lt;br /&gt;
    color: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.Color-White {&lt;br /&gt;
    color: #fff;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Properties and values ==&lt;br /&gt;
&lt;br /&gt;
* Should be separated by a colon and a single space, do not minify them.&lt;br /&gt;
* Should be lowercase, except for font names and vendor-specific properties.&lt;br /&gt;
* For color codes, lowercase is preferred and a shorthand whenever possible.&lt;br /&gt;
* For color codes, if you use HSLA or RGBA, always provide a hex fallback.&lt;br /&gt;
* Use shorthand (except when overriding styles) for background, border, font, list-style, margin, and padding values.&lt;br /&gt;
* Do not use &amp;lt;code&amp;gt;!important&amp;lt;/code&amp;gt;. If there is no alternative something is wrong with the CSS you are trying to override.&lt;br /&gt;
* Prefixed vendor-specific properties pairs should appear directly before the generic property they refer to.&lt;br /&gt;
* Indent vendor prefixed declarations so that their values are aligned&lt;br /&gt;
&lt;br /&gt;
=== Correct ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.selector {&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    -webkit-border-radius: 4px;&lt;br /&gt;
       -moz-border-radius: 4px;&lt;br /&gt;
            border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.selector {&lt;br /&gt;
    margin-top: 1px;&lt;br /&gt;
    color: #f90;&lt;br /&gt;
    color: hsla(0, 0%, 100%, 1);&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Incorrect ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;#selector {&lt;br /&gt;
    color: hsla(0, 0%, 100%, 1);&lt;br /&gt;
    -webkit-border-radius: 4px;&lt;br /&gt;
    -moz-border-radius: 4px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#selector {&lt;br /&gt;
    margin-top:1px;&lt;br /&gt;
    color :#ff9900 !important;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Units ==&lt;br /&gt;
&lt;br /&gt;
* Prefer the usage of &#039;&#039;em&#039;&#039; over &#039;&#039;px&#039;&#039;.&lt;br /&gt;
* Do not use the units &#039;&#039;pt&#039;&#039; or &#039;&#039;rem&#039;&#039;. MDL-39934&lt;br /&gt;
* Do not declare the unit when the value is 0.&lt;br /&gt;
&lt;br /&gt;
=== Correct ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.something {&lt;br /&gt;
    margin-top: 0;&lt;br /&gt;
    font-size: 1.25em;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Incorrect ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.something {&lt;br /&gt;
    margin-top: 0px;&lt;br /&gt;
    font-size: 1.25rem;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Documentation and comments ==&lt;br /&gt;
&lt;br /&gt;
Following the general [[Coding style]], comments should start with a capital letter and end with a period.&lt;br /&gt;
&lt;br /&gt;
A block-style comment at the top of the CSS file should explain the purpose of the rules in the file.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * File base.css.&lt;br /&gt;
 * Contains base styles for theme basic.&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Block-style comments can also be used to denote a section in a CSS file where all rules pertain to a specific component, view, or functionality:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * SCORM Navigation Sidebar.&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use single-line comments to provide more information to other developers about a single rule or small subset of rules:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/* Required because YUI resets add a black border to all tables */&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Progressive enhancement ==&lt;br /&gt;
&lt;br /&gt;
* Fallbacks should always be provided. For example, provide a background color fallback to background images and gradients.&lt;br /&gt;
* Use vendor prefixes only when the supported browser in question does not support the unprefixed property.&lt;br /&gt;
* The standard property should come after the vendor-prefixed property.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.selector {&lt;br /&gt;
    background-color: #444; /* Fallback for browsers that don&#039;t support gradients. */&lt;br /&gt;
    filter: progid:DXImageTransform.Microsoft.gradient(startColorStr=&#039;#444&#039;, EndColorStr=&#039;#999&#039;); /* IE6-IE9. */&lt;br /&gt;
    background-image: -webkit-gradient(linear, left top, left bottom, from(#444), to(#999)); /* Safari 4+, Chrome. */&lt;br /&gt;
    background-image: -webkit-linear-gradient(top, #444, #999); /* Chrome 10+, Safari 5.1+, iOS 5+. */&lt;br /&gt;
    background-image: -moz-linear-gradient(top, #444, #999); /* Firefox 3.6. */&lt;br /&gt;
    background-image: -ms-linear-gradient(top, #444, #999); /* IE10. */&lt;br /&gt;
    background-image: -o-linear-gradient(top, #444, #999); /* Opera 11.10+. */&lt;br /&gt;
    background-image: linear-gradient(top, #444, #999); /* W3C Standard. */&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Browser Hacks ==&lt;br /&gt;
&lt;br /&gt;
* Do not use any browser-specific hacks. Moodle provides a more appropriate way to write browser-specific CSS using classes that are added to the body element. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
.ie7 .forum-post {&lt;br /&gt;
    min-height: 1px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* It is not necessary to include hacks for versions of browsers that Moodle core does not provide support for (e.g. IE6 in Moodle 2, except legacy theme).&lt;br /&gt;
&lt;br /&gt;
== Plugins ==&lt;br /&gt;
&lt;br /&gt;
In plugins, the file names can be:&lt;br /&gt;
&lt;br /&gt;
* styles.css (Recommended)&lt;br /&gt;
* styles_&amp;lt;theme name&amp;gt;.css (Not recommended, reserved to 3rd party plugins)&lt;br /&gt;
&lt;br /&gt;
=== Barebones ===&lt;br /&gt;
&lt;br /&gt;
Plugins should define the strict minimum, no text sizes, colours, etc ... those should belong to the theme and not be hardcoded in plugins to allow for easy theming. Of course, this requires Moodle core to provide re-usable classes to style the elements. As Moodle 2.7 has made Bootstrap 2 by default we can start using their classes, but we should make sure that there is a sensible fallback for themes not extending &#039;&#039;bootstrapbase&#039;&#039;, such as &#039;&#039;base&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Right-to-left ==&lt;br /&gt;
&lt;br /&gt;
Developers always have to pay attention to RTL languages.&lt;br /&gt;
&lt;br /&gt;
=== Selector ===&lt;br /&gt;
&lt;br /&gt;
Always use the selector &amp;lt;code&amp;gt;.dir-rtl&amp;lt;/code&amp;gt; to define RTL rules. That class is set on the BODY tag, and it should be placed first if you are combining it with another BODY class. When you are using LESS, encapsulate all the rules in &amp;lt;code&amp;gt;.dir-rtl&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Correct ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.dir-rtl .something {&lt;br /&gt;
    margin-left: 0;&lt;br /&gt;
    margin-right: 1em;&lt;br /&gt;
}&lt;br /&gt;
.dir-rtl.page-mod-something p {&lt;br /&gt;
    padding-left: 0;&lt;br /&gt;
    padding-right: 1em;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.dir-rtl {&lt;br /&gt;
    &amp;amp;.page-mod-something {&lt;br /&gt;
        p {&lt;br /&gt;
            padding-left: 0;&lt;br /&gt;
            padding-right: 1em;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    .something {&lt;br /&gt;
        margin-left: 0;&lt;br /&gt;
        margin-right: 1em;&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Incorrect ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;body.dir-rtl .something {&lt;br /&gt;
    margin-left: 0;&lt;br /&gt;
    margin-right: 1em;&lt;br /&gt;
}&lt;br /&gt;
.page-mod-something.dir-rtl p {&lt;br /&gt;
    padding-left: 0;&lt;br /&gt;
    padding-right: 1em;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.dir-rtl {&lt;br /&gt;
    &amp;amp;.page-mod-something {&lt;br /&gt;
        p {&lt;br /&gt;
            padding-left: 0;&lt;br /&gt;
            padding-right: 1em;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
.dir-rtl {&lt;br /&gt;
    .something {&lt;br /&gt;
        margin-left: 0;&lt;br /&gt;
        margin-right: 1em;&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rule placement ===&lt;br /&gt;
&lt;br /&gt;
The RTL rules should be written close to the LTR ones, not in another file. Placing them close to the LTR ones helps (and reminds) the developers to fix both, without the need to search for the existence of RTL rules. If you are using LESS, it is advised to split a huge block into smaller chunks to help locating the corresponding LTR rules.&lt;br /&gt;
&lt;br /&gt;
=== Automatic compliance ===&lt;br /&gt;
&lt;br /&gt;
Whenever possible you should try to avoid writing specific RTL rules. It is more often than one would think possible to have one rule working for both LTR and RTL.&lt;br /&gt;
&lt;br /&gt;
==== Recommended ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;p {&lt;br /&gt;
    margin: 0 1em;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== To avoid ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;p {&lt;br /&gt;
    margin-left: 1em;&lt;br /&gt;
}&lt;br /&gt;
.dir-rtl p {&lt;br /&gt;
    margin-right: 1em;&lt;br /&gt;
    margin-left: 0;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What to style ===&lt;br /&gt;
&lt;br /&gt;
RTL rules should only apply to positioning properties, nothing else. And in most cases you will want to revert the LTR rules, to make sure that the rest works as expected.&lt;br /&gt;
&lt;br /&gt;
==== Correct ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.something {&lt;br /&gt;
    text-color: red;&lt;br /&gt;
    padding-left: 1em;&lt;br /&gt;
}&lt;br /&gt;
.dir-rtl .something {&lt;br /&gt;
    padding-left: 0;&lt;br /&gt;
    padding-right: 1em;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Incorrect ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
.dir-rtl .something {&lt;br /&gt;
    text-color: red;&lt;br /&gt;
    padding-right: 1em;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== LESS ==&lt;br /&gt;
&lt;br /&gt;
[http://lesscss.org/ LESS] works like CSS with some extra features. It should follow the CSS guidelines.&lt;br /&gt;
&lt;br /&gt;
=== Variables ===&lt;br /&gt;
&lt;br /&gt;
* They should use camelCase to follow Bootstrap 2 that is used in core.&lt;br /&gt;
* As for CSS selectors, use semantic names: names tell what this is instead of what should it look like.&lt;br /&gt;
* As Bootstrap 2 does, do not add the word &amp;quot;Color&amp;quot; to variables for _background_ or _border_ and their derivatives.&lt;br /&gt;
* Declaring new variables should be done sparingly, too many variables kill the purpose of using them. If you declare one, try to set its default value from another one.&lt;br /&gt;
* Do not declare more variables than necessary. E.g.: If the background color and border color are likely to always be the same, prefer one variable.&lt;br /&gt;
&lt;br /&gt;
==== Correct ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;@textColor: red;&lt;br /&gt;
@wellBackground: #ccc;&lt;br /&gt;
@tableBackground: blue;&lt;br /&gt;
@blockBackground: @wellBackground;&lt;br /&gt;
@calendarGroupEvent: #f90;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Incorrect ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;@text-color: red;&lt;br /&gt;
@wellBackground: #ccc;&lt;br /&gt;
@tableBackgrounColor: blue;&lt;br /&gt;
@blockBackground: #ccc;&lt;br /&gt;
@calendarGroupEventBackground: #f90;&lt;br /&gt;
@calendarGroupEventBorder: #f90;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Selectors ===&lt;br /&gt;
&lt;br /&gt;
* Selectors should be encapsulated rather than duplicated.&lt;br /&gt;
&lt;br /&gt;
==== Correct ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;div {&lt;br /&gt;
    .something {&lt;br /&gt;
        color: red;&lt;br /&gt;
        a {&lt;br /&gt;
            color: blue;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    .something-else a {&lt;br /&gt;
        color: green;&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Incorrect ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;div .something {&lt;br /&gt;
    color: red;&lt;br /&gt;
}&lt;br /&gt;
div .something a {&lt;br /&gt;
    color: blue;&lt;br /&gt;
}&lt;br /&gt;
div .something-else a {&lt;br /&gt;
    color: green;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Values and properties ===&lt;br /&gt;
&lt;br /&gt;
* Colours, font sizes, etc... should never be hardcoded, use a variable instead.&lt;br /&gt;
* Use mixins instead of duplicating values and properties.&lt;br /&gt;
&lt;br /&gt;
==== Correct ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.error {&lt;br /&gt;
    font-size: @fontSizeSmall;&lt;br /&gt;
    color: @errorText;&lt;br /&gt;
    padding: 1em;&lt;br /&gt;
    background-color: @errorBackground;&lt;br /&gt;
}&lt;br /&gt;
div .form-error {&lt;br /&gt;
    .error;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Incorrect ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.error {&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    color: red;&lt;br /&gt;
    padding: 1em;&lt;br /&gt;
    background-color: white;&lt;br /&gt;
}&lt;br /&gt;
div .form-error {&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    color: red;&lt;br /&gt;
    padding: 1em;&lt;br /&gt;
    background-color: white;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Themes Clean and More ==&lt;br /&gt;
&lt;br /&gt;
Clean theme should, where possible, not contain any CSS or LESS content. More theme, in comparison, inherits CSS styles for the logo from Clean theme, but also contains a small amount of LESS as an example for when customising a theme. Both Clean and More inherit fully all the CSS from their parent theme &#039;Bootstrap Base&#039;.&lt;br /&gt;
&lt;br /&gt;
== Credits ==&lt;br /&gt;
&lt;br /&gt;
This document was drawn from the following sources:&lt;br /&gt;
&lt;br /&gt;
# The [http://codex.wordpress.org/CSS_Coding_Standards WordPress CSS Coding Standards] &lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Coding]]&lt;br /&gt;
* [[Coding_style|Coding style]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Coding guidelines|CSS Coding style]]&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=CSS_Coding_Style&amp;diff=48476</id>
		<title>CSS Coding Style</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=CSS_Coding_Style&amp;diff=48476"/>
		<updated>2015-08-30T23:36:39Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Themes Clean and More */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress|forumurl=https://moodle.org/mod/forum/discuss.php?d=275476}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
&lt;br /&gt;
This document describes style guidelines for developers working on or with Moodle code. It talks purely about the mechanics of code layout and the choices we have made for Moodle. &lt;br /&gt;
&lt;br /&gt;
=== Goals ===&lt;br /&gt;
&lt;br /&gt;
Consistent coding style is important in any development project, and particularly when many developers are involved. A standard style helps to ensure that the code is easier to read and understand, which helps overall quality.&lt;br /&gt;
&lt;br /&gt;
Abstract goals we strive for: &lt;br /&gt;
&lt;br /&gt;
* simplicity&lt;br /&gt;
* readability&lt;br /&gt;
* tool friendliness&lt;br /&gt;
&lt;br /&gt;
== File naming ==&lt;br /&gt;
&lt;br /&gt;
Within plugins, CSS files are normally named &amp;lt;code&amp;gt;styles.css&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In the theme, files can be named according to the theme designer&#039;s wishes but should:&lt;br /&gt;
&lt;br /&gt;
* use lowercase letters and &#039;-&#039; to separate words&lt;br /&gt;
* be as succinct as possible&lt;br /&gt;
* be descriptive&lt;br /&gt;
* be placed in the folder &amp;lt;code&amp;gt;style/&amp;lt;/code&amp;gt; for CSS files, or in &amp;lt;code&amp;gt;less/&amp;lt;/code&amp;gt; for LESS files.&lt;br /&gt;
&lt;br /&gt;
== Blocks ==&lt;br /&gt;
&lt;br /&gt;
* Each selector should be on its own line. If there is a comma in a selector list, follow it with a line break.&lt;br /&gt;
* Property-value pairs should be on their own line, with four spaces of indentation and an ending semicolon.&lt;br /&gt;
* The closing brace should use the same level of indentation as the opening selector.&lt;br /&gt;
* Leave one line between blocks.&lt;br /&gt;
&lt;br /&gt;
=== Correct ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;@media only screen and (min-width: 768px) {&lt;br /&gt;
    .selector-one,&lt;br /&gt;
    .selector-two {&lt;br /&gt;
        color: #fff;&lt;br /&gt;
        background-color: #000;&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Incorrect ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.selector_one, .selector_two { color: #fff; background-color: #000; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selectors ==&lt;br /&gt;
&lt;br /&gt;
* Always use lower case and underscores or hyphens. Hyphens are preferred.&lt;br /&gt;
* Names should be made of simple English words.&lt;br /&gt;
* Verbosity is encouraged: names should be as illustrative as is practical to enhance understanding.&lt;br /&gt;
* Use [http://css-tricks.com/semantic-class-names/ semantic names]: names tell what this is instead of what should it look like.&lt;br /&gt;
* Avoid using IDs. They are far more difficult to maintain and override.&lt;br /&gt;
* Do not over-qualify your rules by combining a tagname with a class or ID.&lt;br /&gt;
&lt;br /&gt;
=== Correct ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.selector_name {&lt;br /&gt;
    color: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.selector-name {&lt;br /&gt;
    color: #fff;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Incorrect ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;div#selName {&lt;br /&gt;
    color: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.Color-White {&lt;br /&gt;
    color: #fff;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Properties and values ==&lt;br /&gt;
&lt;br /&gt;
* Should be separated by a colon and a single space, do not minify them.&lt;br /&gt;
* Should be lowercase, except for font names and vendor-specific properties.&lt;br /&gt;
* For color codes, lowercase is preferred and a shorthand whenever possible.&lt;br /&gt;
* For color codes, if you use HSLA or RGBA, always provide a hex fallback.&lt;br /&gt;
* Use shorthand (except when overriding styles) for background, border, font, list-style, margin, and padding values.&lt;br /&gt;
* Do not use &amp;lt;code&amp;gt;!important&amp;lt;/code&amp;gt;. If there is no alternative something is wrong with the CSS you are trying to override.&lt;br /&gt;
* Prefixed vendor-specific properties pairs should appear directly before the generic property they refer to.&lt;br /&gt;
* Indent vendor prefixed declarations so that their values are aligned&lt;br /&gt;
&lt;br /&gt;
=== Correct ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.selector {&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    -webkit-border-radius: 4px;&lt;br /&gt;
       -moz-border-radius: 4px;&lt;br /&gt;
            border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.selector {&lt;br /&gt;
    margin-top: 1px;&lt;br /&gt;
    color: #f90;&lt;br /&gt;
    color: hsla(0, 0%, 100%, 1);&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Incorrect ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;#selector {&lt;br /&gt;
    color: hsla(0, 0%, 100%, 1);&lt;br /&gt;
    -webkit-border-radius: 4px;&lt;br /&gt;
    -moz-border-radius: 4px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#selector {&lt;br /&gt;
    margin-top:1px;&lt;br /&gt;
    color :#ff9900 !important;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Units ==&lt;br /&gt;
&lt;br /&gt;
* Prefer the usage of &#039;&#039;em&#039;&#039; over &#039;&#039;px&#039;&#039;.&lt;br /&gt;
* Do not use the units &#039;&#039;pt&#039;&#039; or &#039;&#039;rem&#039;&#039;. MDL-39934&lt;br /&gt;
* Do not declare the unit when the value is 0.&lt;br /&gt;
&lt;br /&gt;
=== Correct ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.something {&lt;br /&gt;
    margin-top: 0;&lt;br /&gt;
    font-size: 1.25em;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Incorrect ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.something {&lt;br /&gt;
    margin-top: 0px;&lt;br /&gt;
    font-size: 1.25rem;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Documentation and comments ==&lt;br /&gt;
&lt;br /&gt;
Following the general [[Coding style]], comments should start with a capital letter and end with a period.&lt;br /&gt;
&lt;br /&gt;
A block-style comment at the top of the CSS file should explain the purpose of the rules in the file.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * File base.css.&lt;br /&gt;
 * Contains base styles for theme basic.&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Block-style comments can also be used to denote a section in a CSS file where all rules pertain to a specific component, view, or functionality:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * SCORM Navigation Sidebar.&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use single-line comments to provide more information to other developers about a single rule or small subset of rules:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/* Required because YUI resets add a black border to all tables */&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Progressive enhancement ==&lt;br /&gt;
&lt;br /&gt;
* Fallbacks should always be provided. For example, provide a background color fallback to background images and gradients.&lt;br /&gt;
* Use vendor prefixes only when the supported browser in question does not support the unprefixed property.&lt;br /&gt;
* The standard property should come after the vendor-prefixed property.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.selector {&lt;br /&gt;
    background-color: #444; /* Fallback for browsers that don&#039;t support gradients. */&lt;br /&gt;
    filter: progid:DXImageTransform.Microsoft.gradient(startColorStr=&#039;#444&#039;, EndColorStr=&#039;#999&#039;); /* IE6-IE9. */&lt;br /&gt;
    background-image: -webkit-gradient(linear, left top, left bottom, from(#444), to(#999)); /* Safari 4+, Chrome. */&lt;br /&gt;
    background-image: -webkit-linear-gradient(top, #444, #999); /* Chrome 10+, Safari 5.1+, iOS 5+. */&lt;br /&gt;
    background-image: -moz-linear-gradient(top, #444, #999); /* Firefox 3.6. */&lt;br /&gt;
    background-image: -ms-linear-gradient(top, #444, #999); /* IE10. */&lt;br /&gt;
    background-image: -o-linear-gradient(top, #444, #999); /* Opera 11.10+. */&lt;br /&gt;
    background-image: linear-gradient(top, #444, #999); /* W3C Standard. */&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Browser Hacks ==&lt;br /&gt;
&lt;br /&gt;
* Do not use any browser-specific hacks. Moodle provides a more appropriate way to write browser-specific CSS using classes that are added to the body element. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
.ie7 .forum-post {&lt;br /&gt;
    min-height: 1px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* It is not necessary to include hacks for versions of browsers that Moodle core does not provide support for (e.g. IE6 in Moodle 2, except legacy theme).&lt;br /&gt;
&lt;br /&gt;
== Plugins ==&lt;br /&gt;
&lt;br /&gt;
In plugins, the file names can be:&lt;br /&gt;
&lt;br /&gt;
* styles.css (Recommended)&lt;br /&gt;
* styles_&amp;lt;theme name&amp;gt;.css (Not recommended, reserved to 3rd party plugins)&lt;br /&gt;
&lt;br /&gt;
=== Barebones ===&lt;br /&gt;
&lt;br /&gt;
Plugins should define the strict minimum, no text sizes, colours, etc ... those should belong to the theme and not be hardcoded in plugins to allow for easy theming. Of course, this requires Moodle core to provide re-usable classes to style the elements. As Moodle 2.7 has made Bootstrap 2 by default we can start using their classes, but we should make sure that there is a sensible fallback for themes not extending &#039;&#039;bootstrapbase&#039;&#039;, such as &#039;&#039;base&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Right-to-left ==&lt;br /&gt;
&lt;br /&gt;
Developers always have to pay attention to RTL languages.&lt;br /&gt;
&lt;br /&gt;
=== Selector ===&lt;br /&gt;
&lt;br /&gt;
Always use the selector &amp;lt;code&amp;gt;.dir-rtl&amp;lt;/code&amp;gt; to define RTL rules. That class is set on the BODY tag, and it should be placed first if you are combining it with another BODY class. When you are using LESS, encapsulate all the rules in &amp;lt;code&amp;gt;.dir-rtl&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Correct ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.dir-rtl .something {&lt;br /&gt;
    margin-left: 0;&lt;br /&gt;
    margin-right: 1em;&lt;br /&gt;
}&lt;br /&gt;
.dir-rtl.page-mod-something p {&lt;br /&gt;
    padding-left: 0;&lt;br /&gt;
    padding-right: 1em;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.dir-rtl {&lt;br /&gt;
    &amp;amp;.page-mod-something {&lt;br /&gt;
        p {&lt;br /&gt;
            padding-left: 0;&lt;br /&gt;
            padding-right: 1em;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    .something {&lt;br /&gt;
        margin-left: 0;&lt;br /&gt;
        margin-right: 1em;&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Incorrect ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;body.dir-rtl .something {&lt;br /&gt;
    margin-left: 0;&lt;br /&gt;
    margin-right: 1em;&lt;br /&gt;
}&lt;br /&gt;
.page-mod-something.dir-rtl p {&lt;br /&gt;
    padding-left: 0;&lt;br /&gt;
    padding-right: 1em;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.dir-rtl {&lt;br /&gt;
    &amp;amp;.page-mod-something {&lt;br /&gt;
        p {&lt;br /&gt;
            padding-left: 0;&lt;br /&gt;
            padding-right: 1em;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
.dir-rtl {&lt;br /&gt;
    .something {&lt;br /&gt;
        margin-left: 0;&lt;br /&gt;
        margin-right: 1em;&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rule placement ===&lt;br /&gt;
&lt;br /&gt;
The RTL rules should be written close to the LTR ones, not in another file. Placing them close to the LTR ones helps (and reminds) the developers to fix both, without the need to search for the existence of RTL rules. If you are using LESS, it is advised to split a huge block into smaller chunks to help locating the corresponding LTR rules.&lt;br /&gt;
&lt;br /&gt;
=== Automatic compliance ===&lt;br /&gt;
&lt;br /&gt;
Whenever possible you should try to avoid writing specific RTL rules. It is more often than one would think possible to have one rule working for both LTR and RTL.&lt;br /&gt;
&lt;br /&gt;
==== Recommended ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;p {&lt;br /&gt;
    margin: 0 1em;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== To avoid ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;p {&lt;br /&gt;
    margin-left: 1em;&lt;br /&gt;
}&lt;br /&gt;
.dir-rtl p {&lt;br /&gt;
    margin-right: 1em;&lt;br /&gt;
    margin-left: 0;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What to style ===&lt;br /&gt;
&lt;br /&gt;
RTL rules should only apply to positioning properties, nothing else. And in most cases you will want to revert the LTR rules, to make sure that the rest works as expected.&lt;br /&gt;
&lt;br /&gt;
==== Correct ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.something {&lt;br /&gt;
    text-color: red;&lt;br /&gt;
    padding-left: 1em;&lt;br /&gt;
}&lt;br /&gt;
.dir-rtl .something {&lt;br /&gt;
    padding-left: 0;&lt;br /&gt;
    padding-right: 1em;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Incorrect ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
.dir-rtl .something {&lt;br /&gt;
    text-color: red;&lt;br /&gt;
    padding-right: 1em;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== LESS ==&lt;br /&gt;
&lt;br /&gt;
[http://lesscss.org/ LESS] works like CSS with some extra features. It should follow the CSS guidelines.&lt;br /&gt;
&lt;br /&gt;
=== Variables ===&lt;br /&gt;
&lt;br /&gt;
* They should use camelCase to follow Bootstrap 2 that is used in core.&lt;br /&gt;
* As for CSS selectors, use semantic names: names tell what this is instead of what should it look like.&lt;br /&gt;
* As Bootstrap 2 does, do not add the word &amp;quot;Color&amp;quot; to variables for _background_ or _border_ and their derivatives.&lt;br /&gt;
* Declaring new variables should be done sparingly, too many variables kill the purpose of using them. If you declare one, try to set its default value from another one.&lt;br /&gt;
* Do not declare more variables than necessary. E.g.: If the background color and border color are likely to always be the same, prefer one variable.&lt;br /&gt;
&lt;br /&gt;
==== Correct ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;@textColor: red;&lt;br /&gt;
@wellBackground: #ccc;&lt;br /&gt;
@tableBackground: blue;&lt;br /&gt;
@blockBackground: @wellBackground;&lt;br /&gt;
@calendarGroupEvent: #f90;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Incorrect ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;@text-color: red;&lt;br /&gt;
@wellBackground: #ccc;&lt;br /&gt;
@tableBackgrounColor: blue;&lt;br /&gt;
@blockBackground: #ccc;&lt;br /&gt;
@calendarGroupEventBackground: #f90;&lt;br /&gt;
@calendarGroupEventBorder: #f90;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Selectors ===&lt;br /&gt;
&lt;br /&gt;
* Selectors should be encapsulated rather than duplicated.&lt;br /&gt;
&lt;br /&gt;
==== Correct ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;div {&lt;br /&gt;
    .something {&lt;br /&gt;
        color: red;&lt;br /&gt;
        a {&lt;br /&gt;
            color: blue;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    .something-else a {&lt;br /&gt;
        color: green;&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Incorrect ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;div .something {&lt;br /&gt;
    color: red;&lt;br /&gt;
}&lt;br /&gt;
div .something a {&lt;br /&gt;
    color: blue;&lt;br /&gt;
}&lt;br /&gt;
div .something-else a {&lt;br /&gt;
    color: green;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Values and properties ===&lt;br /&gt;
&lt;br /&gt;
* Colours, font sizes, etc... should never be hardcoded, use a variable instead.&lt;br /&gt;
* Use mixins instead of duplicating values and properties.&lt;br /&gt;
&lt;br /&gt;
==== Correct ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.error {&lt;br /&gt;
    font-size: @fontSizeSmall;&lt;br /&gt;
    color: @errorText;&lt;br /&gt;
    padding: 1em;&lt;br /&gt;
    background-color: @errorBackground;&lt;br /&gt;
}&lt;br /&gt;
div .form-error {&lt;br /&gt;
    .error;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Incorrect ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.error {&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    color: red;&lt;br /&gt;
    padding: 1em;&lt;br /&gt;
    background-color: white;&lt;br /&gt;
}&lt;br /&gt;
div .form-error {&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    color: red;&lt;br /&gt;
    padding: 1em;&lt;br /&gt;
    background-color: white;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Themes Clean and More ==&lt;br /&gt;
&lt;br /&gt;
Clean theme should not contain any CSS or LESS content, it should fully inherit from &#039;&#039;theme_bootstrapbase&#039;&#039;. More can contain a little portion of LESS to ensure that customization is possible, but it should be almost inherit fully from &#039;&#039;theme_bootstrapbase&#039;&#039; unless pertinent to the theme, &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
For example:&lt;br /&gt;
div.logo {&lt;br /&gt;
    background: url([[setting:logo]]) no-repeat 0 0;&lt;br /&gt;
    display: block;&lt;br /&gt;
    float: left;&lt;br /&gt;
    height: 75px;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Credits ==&lt;br /&gt;
&lt;br /&gt;
This document was drawn from the following sources:&lt;br /&gt;
&lt;br /&gt;
# The [http://codex.wordpress.org/CSS_Coding_Standards WordPress CSS Coding Standards] &lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Coding]]&lt;br /&gt;
* [[Coding_style|Coding style]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Coding guidelines|CSS Coding style]]&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=CSS_Coding_Style&amp;diff=48475</id>
		<title>CSS Coding Style</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=CSS_Coding_Style&amp;diff=48475"/>
		<updated>2015-08-30T23:35:57Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Themes Clean and More */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress|forumurl=https://moodle.org/mod/forum/discuss.php?d=275476}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
&lt;br /&gt;
This document describes style guidelines for developers working on or with Moodle code. It talks purely about the mechanics of code layout and the choices we have made for Moodle. &lt;br /&gt;
&lt;br /&gt;
=== Goals ===&lt;br /&gt;
&lt;br /&gt;
Consistent coding style is important in any development project, and particularly when many developers are involved. A standard style helps to ensure that the code is easier to read and understand, which helps overall quality.&lt;br /&gt;
&lt;br /&gt;
Abstract goals we strive for: &lt;br /&gt;
&lt;br /&gt;
* simplicity&lt;br /&gt;
* readability&lt;br /&gt;
* tool friendliness&lt;br /&gt;
&lt;br /&gt;
== File naming ==&lt;br /&gt;
&lt;br /&gt;
Within plugins, CSS files are normally named &amp;lt;code&amp;gt;styles.css&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In the theme, files can be named according to the theme designer&#039;s wishes but should:&lt;br /&gt;
&lt;br /&gt;
* use lowercase letters and &#039;-&#039; to separate words&lt;br /&gt;
* be as succinct as possible&lt;br /&gt;
* be descriptive&lt;br /&gt;
* be placed in the folder &amp;lt;code&amp;gt;style/&amp;lt;/code&amp;gt; for CSS files, or in &amp;lt;code&amp;gt;less/&amp;lt;/code&amp;gt; for LESS files.&lt;br /&gt;
&lt;br /&gt;
== Blocks ==&lt;br /&gt;
&lt;br /&gt;
* Each selector should be on its own line. If there is a comma in a selector list, follow it with a line break.&lt;br /&gt;
* Property-value pairs should be on their own line, with four spaces of indentation and an ending semicolon.&lt;br /&gt;
* The closing brace should use the same level of indentation as the opening selector.&lt;br /&gt;
* Leave one line between blocks.&lt;br /&gt;
&lt;br /&gt;
=== Correct ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;@media only screen and (min-width: 768px) {&lt;br /&gt;
    .selector-one,&lt;br /&gt;
    .selector-two {&lt;br /&gt;
        color: #fff;&lt;br /&gt;
        background-color: #000;&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Incorrect ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.selector_one, .selector_two { color: #fff; background-color: #000; }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Selectors ==&lt;br /&gt;
&lt;br /&gt;
* Always use lower case and underscores or hyphens. Hyphens are preferred.&lt;br /&gt;
* Names should be made of simple English words.&lt;br /&gt;
* Verbosity is encouraged: names should be as illustrative as is practical to enhance understanding.&lt;br /&gt;
* Use [http://css-tricks.com/semantic-class-names/ semantic names]: names tell what this is instead of what should it look like.&lt;br /&gt;
* Avoid using IDs. They are far more difficult to maintain and override.&lt;br /&gt;
* Do not over-qualify your rules by combining a tagname with a class or ID.&lt;br /&gt;
&lt;br /&gt;
=== Correct ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.selector_name {&lt;br /&gt;
    color: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.selector-name {&lt;br /&gt;
    color: #fff;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Incorrect ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;div#selName {&lt;br /&gt;
    color: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.Color-White {&lt;br /&gt;
    color: #fff;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Properties and values ==&lt;br /&gt;
&lt;br /&gt;
* Should be separated by a colon and a single space, do not minify them.&lt;br /&gt;
* Should be lowercase, except for font names and vendor-specific properties.&lt;br /&gt;
* For color codes, lowercase is preferred and a shorthand whenever possible.&lt;br /&gt;
* For color codes, if you use HSLA or RGBA, always provide a hex fallback.&lt;br /&gt;
* Use shorthand (except when overriding styles) for background, border, font, list-style, margin, and padding values.&lt;br /&gt;
* Do not use &amp;lt;code&amp;gt;!important&amp;lt;/code&amp;gt;. If there is no alternative something is wrong with the CSS you are trying to override.&lt;br /&gt;
* Prefixed vendor-specific properties pairs should appear directly before the generic property they refer to.&lt;br /&gt;
* Indent vendor prefixed declarations so that their values are aligned&lt;br /&gt;
&lt;br /&gt;
=== Correct ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.selector {&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    -webkit-border-radius: 4px;&lt;br /&gt;
       -moz-border-radius: 4px;&lt;br /&gt;
            border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.selector {&lt;br /&gt;
    margin-top: 1px;&lt;br /&gt;
    color: #f90;&lt;br /&gt;
    color: hsla(0, 0%, 100%, 1);&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Incorrect ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;#selector {&lt;br /&gt;
    color: hsla(0, 0%, 100%, 1);&lt;br /&gt;
    -webkit-border-radius: 4px;&lt;br /&gt;
    -moz-border-radius: 4px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#selector {&lt;br /&gt;
    margin-top:1px;&lt;br /&gt;
    color :#ff9900 !important;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Units ==&lt;br /&gt;
&lt;br /&gt;
* Prefer the usage of &#039;&#039;em&#039;&#039; over &#039;&#039;px&#039;&#039;.&lt;br /&gt;
* Do not use the units &#039;&#039;pt&#039;&#039; or &#039;&#039;rem&#039;&#039;. MDL-39934&lt;br /&gt;
* Do not declare the unit when the value is 0.&lt;br /&gt;
&lt;br /&gt;
=== Correct ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.something {&lt;br /&gt;
    margin-top: 0;&lt;br /&gt;
    font-size: 1.25em;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Incorrect ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.something {&lt;br /&gt;
    margin-top: 0px;&lt;br /&gt;
    font-size: 1.25rem;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Documentation and comments ==&lt;br /&gt;
&lt;br /&gt;
Following the general [[Coding style]], comments should start with a capital letter and end with a period.&lt;br /&gt;
&lt;br /&gt;
A block-style comment at the top of the CSS file should explain the purpose of the rules in the file.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * File base.css.&lt;br /&gt;
 * Contains base styles for theme basic.&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Block-style comments can also be used to denote a section in a CSS file where all rules pertain to a specific component, view, or functionality:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * SCORM Navigation Sidebar.&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use single-line comments to provide more information to other developers about a single rule or small subset of rules:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/* Required because YUI resets add a black border to all tables */&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Progressive enhancement ==&lt;br /&gt;
&lt;br /&gt;
* Fallbacks should always be provided. For example, provide a background color fallback to background images and gradients.&lt;br /&gt;
* Use vendor prefixes only when the supported browser in question does not support the unprefixed property.&lt;br /&gt;
* The standard property should come after the vendor-prefixed property.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.selector {&lt;br /&gt;
    background-color: #444; /* Fallback for browsers that don&#039;t support gradients. */&lt;br /&gt;
    filter: progid:DXImageTransform.Microsoft.gradient(startColorStr=&#039;#444&#039;, EndColorStr=&#039;#999&#039;); /* IE6-IE9. */&lt;br /&gt;
    background-image: -webkit-gradient(linear, left top, left bottom, from(#444), to(#999)); /* Safari 4+, Chrome. */&lt;br /&gt;
    background-image: -webkit-linear-gradient(top, #444, #999); /* Chrome 10+, Safari 5.1+, iOS 5+. */&lt;br /&gt;
    background-image: -moz-linear-gradient(top, #444, #999); /* Firefox 3.6. */&lt;br /&gt;
    background-image: -ms-linear-gradient(top, #444, #999); /* IE10. */&lt;br /&gt;
    background-image: -o-linear-gradient(top, #444, #999); /* Opera 11.10+. */&lt;br /&gt;
    background-image: linear-gradient(top, #444, #999); /* W3C Standard. */&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Browser Hacks ==&lt;br /&gt;
&lt;br /&gt;
* Do not use any browser-specific hacks. Moodle provides a more appropriate way to write browser-specific CSS using classes that are added to the body element. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
.ie7 .forum-post {&lt;br /&gt;
    min-height: 1px;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* It is not necessary to include hacks for versions of browsers that Moodle core does not provide support for (e.g. IE6 in Moodle 2, except legacy theme).&lt;br /&gt;
&lt;br /&gt;
== Plugins ==&lt;br /&gt;
&lt;br /&gt;
In plugins, the file names can be:&lt;br /&gt;
&lt;br /&gt;
* styles.css (Recommended)&lt;br /&gt;
* styles_&amp;lt;theme name&amp;gt;.css (Not recommended, reserved to 3rd party plugins)&lt;br /&gt;
&lt;br /&gt;
=== Barebones ===&lt;br /&gt;
&lt;br /&gt;
Plugins should define the strict minimum, no text sizes, colours, etc ... those should belong to the theme and not be hardcoded in plugins to allow for easy theming. Of course, this requires Moodle core to provide re-usable classes to style the elements. As Moodle 2.7 has made Bootstrap 2 by default we can start using their classes, but we should make sure that there is a sensible fallback for themes not extending &#039;&#039;bootstrapbase&#039;&#039;, such as &#039;&#039;base&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Right-to-left ==&lt;br /&gt;
&lt;br /&gt;
Developers always have to pay attention to RTL languages.&lt;br /&gt;
&lt;br /&gt;
=== Selector ===&lt;br /&gt;
&lt;br /&gt;
Always use the selector &amp;lt;code&amp;gt;.dir-rtl&amp;lt;/code&amp;gt; to define RTL rules. That class is set on the BODY tag, and it should be placed first if you are combining it with another BODY class. When you are using LESS, encapsulate all the rules in &amp;lt;code&amp;gt;.dir-rtl&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Correct ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.dir-rtl .something {&lt;br /&gt;
    margin-left: 0;&lt;br /&gt;
    margin-right: 1em;&lt;br /&gt;
}&lt;br /&gt;
.dir-rtl.page-mod-something p {&lt;br /&gt;
    padding-left: 0;&lt;br /&gt;
    padding-right: 1em;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.dir-rtl {&lt;br /&gt;
    &amp;amp;.page-mod-something {&lt;br /&gt;
        p {&lt;br /&gt;
            padding-left: 0;&lt;br /&gt;
            padding-right: 1em;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    .something {&lt;br /&gt;
        margin-left: 0;&lt;br /&gt;
        margin-right: 1em;&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Incorrect ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;body.dir-rtl .something {&lt;br /&gt;
    margin-left: 0;&lt;br /&gt;
    margin-right: 1em;&lt;br /&gt;
}&lt;br /&gt;
.page-mod-something.dir-rtl p {&lt;br /&gt;
    padding-left: 0;&lt;br /&gt;
    padding-right: 1em;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.dir-rtl {&lt;br /&gt;
    &amp;amp;.page-mod-something {&lt;br /&gt;
        p {&lt;br /&gt;
            padding-left: 0;&lt;br /&gt;
            padding-right: 1em;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
.dir-rtl {&lt;br /&gt;
    .something {&lt;br /&gt;
        margin-left: 0;&lt;br /&gt;
        margin-right: 1em;&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rule placement ===&lt;br /&gt;
&lt;br /&gt;
The RTL rules should be written close to the LTR ones, not in another file. Placing them close to the LTR ones helps (and reminds) the developers to fix both, without the need to search for the existence of RTL rules. If you are using LESS, it is advised to split a huge block into smaller chunks to help locating the corresponding LTR rules.&lt;br /&gt;
&lt;br /&gt;
=== Automatic compliance ===&lt;br /&gt;
&lt;br /&gt;
Whenever possible you should try to avoid writing specific RTL rules. It is more often than one would think possible to have one rule working for both LTR and RTL.&lt;br /&gt;
&lt;br /&gt;
==== Recommended ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;p {&lt;br /&gt;
    margin: 0 1em;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== To avoid ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;p {&lt;br /&gt;
    margin-left: 1em;&lt;br /&gt;
}&lt;br /&gt;
.dir-rtl p {&lt;br /&gt;
    margin-right: 1em;&lt;br /&gt;
    margin-left: 0;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What to style ===&lt;br /&gt;
&lt;br /&gt;
RTL rules should only apply to positioning properties, nothing else. And in most cases you will want to revert the LTR rules, to make sure that the rest works as expected.&lt;br /&gt;
&lt;br /&gt;
==== Correct ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.something {&lt;br /&gt;
    text-color: red;&lt;br /&gt;
    padding-left: 1em;&lt;br /&gt;
}&lt;br /&gt;
.dir-rtl .something {&lt;br /&gt;
    padding-left: 0;&lt;br /&gt;
    padding-right: 1em;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Incorrect ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
.dir-rtl .something {&lt;br /&gt;
    text-color: red;&lt;br /&gt;
    padding-right: 1em;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== LESS ==&lt;br /&gt;
&lt;br /&gt;
[http://lesscss.org/ LESS] works like CSS with some extra features. It should follow the CSS guidelines.&lt;br /&gt;
&lt;br /&gt;
=== Variables ===&lt;br /&gt;
&lt;br /&gt;
* They should use camelCase to follow Bootstrap 2 that is used in core.&lt;br /&gt;
* As for CSS selectors, use semantic names: names tell what this is instead of what should it look like.&lt;br /&gt;
* As Bootstrap 2 does, do not add the word &amp;quot;Color&amp;quot; to variables for _background_ or _border_ and their derivatives.&lt;br /&gt;
* Declaring new variables should be done sparingly, too many variables kill the purpose of using them. If you declare one, try to set its default value from another one.&lt;br /&gt;
* Do not declare more variables than necessary. E.g.: If the background color and border color are likely to always be the same, prefer one variable.&lt;br /&gt;
&lt;br /&gt;
==== Correct ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;@textColor: red;&lt;br /&gt;
@wellBackground: #ccc;&lt;br /&gt;
@tableBackground: blue;&lt;br /&gt;
@blockBackground: @wellBackground;&lt;br /&gt;
@calendarGroupEvent: #f90;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Incorrect ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;@text-color: red;&lt;br /&gt;
@wellBackground: #ccc;&lt;br /&gt;
@tableBackgrounColor: blue;&lt;br /&gt;
@blockBackground: #ccc;&lt;br /&gt;
@calendarGroupEventBackground: #f90;&lt;br /&gt;
@calendarGroupEventBorder: #f90;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Selectors ===&lt;br /&gt;
&lt;br /&gt;
* Selectors should be encapsulated rather than duplicated.&lt;br /&gt;
&lt;br /&gt;
==== Correct ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;div {&lt;br /&gt;
    .something {&lt;br /&gt;
        color: red;&lt;br /&gt;
        a {&lt;br /&gt;
            color: blue;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    .something-else a {&lt;br /&gt;
        color: green;&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Incorrect ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;div .something {&lt;br /&gt;
    color: red;&lt;br /&gt;
}&lt;br /&gt;
div .something a {&lt;br /&gt;
    color: blue;&lt;br /&gt;
}&lt;br /&gt;
div .something-else a {&lt;br /&gt;
    color: green;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Values and properties ===&lt;br /&gt;
&lt;br /&gt;
* Colours, font sizes, etc... should never be hardcoded, use a variable instead.&lt;br /&gt;
* Use mixins instead of duplicating values and properties.&lt;br /&gt;
&lt;br /&gt;
==== Correct ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.error {&lt;br /&gt;
    font-size: @fontSizeSmall;&lt;br /&gt;
    color: @errorText;&lt;br /&gt;
    padding: 1em;&lt;br /&gt;
    background-color: @errorBackground;&lt;br /&gt;
}&lt;br /&gt;
div .form-error {&lt;br /&gt;
    .error;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Incorrect ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.error {&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    color: red;&lt;br /&gt;
    padding: 1em;&lt;br /&gt;
    background-color: white;&lt;br /&gt;
}&lt;br /&gt;
div .form-error {&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    color: red;&lt;br /&gt;
    padding: 1em;&lt;br /&gt;
    background-color: white;&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Themes Clean and More ==&lt;br /&gt;
&lt;br /&gt;
Clean theme should not contain any CSS or LESS content, it should fully inherit from &#039;&#039;theme_bootstrapbase&#039;&#039;. More can contain a little portion of LESS to ensure that customization is possible, but it should be almost inherit fully from &#039;&#039;theme_bootstrapbase&#039;&#039; unless pertinent to the theme, &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
For example:&lt;br /&gt;
div.logo {&lt;br /&gt;
    background: url([[setting:logo]]) no-repeat 0 0;&lt;br /&gt;
    display: block;&lt;br /&gt;
    float: left;&lt;br /&gt;
    height: 75px;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Credits ==&lt;br /&gt;
&lt;br /&gt;
This document was drawn from the following sources:&lt;br /&gt;
&lt;br /&gt;
# The [http://codex.wordpress.org/CSS_Coding_Standards WordPress CSS Coding Standards] &lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Coding]]&lt;br /&gt;
* [[Coding_style|Coding style]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Coding guidelines|CSS Coding style]]&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=LESS&amp;diff=48463</id>
		<title>LESS</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=LESS&amp;diff=48463"/>
		<updated>2015-08-25T23:36:19Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Windows 7, 8 &amp;amp; 10 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
LESS ([http://lesscss.org lesscss.org]) extends CSS with dynamic behavior such as variables, mixins, operations and functions.  It&#039;s an advanced way of writing CSS that we use in some themes within Moodle.&lt;br /&gt;
&lt;br /&gt;
Browsers don&#039;t interpret it themselves, however, so LESS files need to be converted into normal CSS before use.&lt;br /&gt;
&lt;br /&gt;
Recess is one tool used to compile and compress LESS into CSS under *nix based systems.  There are [https://github.com/cloudhead/less.js/wiki/GUI-compilers-that-use-LESS.js many others tools for LESS].&lt;br /&gt;
&lt;br /&gt;
== The bootstrapbase theme ==&lt;br /&gt;
&lt;br /&gt;
Moodle&#039;s [[Bootstrap]] base theme has rules written using LESS.&lt;br /&gt;
&lt;br /&gt;
The main LESS file is &#039;&#039;&#039;theme/bootstrapbase/less/moodle.less&#039;&#039;&#039;, with additional files  in &#039;&#039;&#039;theme/bootstrapbase/less/moodle/&#039;&#039;&#039; imported by the main file. &lt;br /&gt;
&lt;br /&gt;
After compiling the LESS files, CSS ends up in &#039;&#039;&#039;theme/bootstrapbase/style/moodle.css&#039;&#039;&#039;.  This file should not be edited manually.&lt;br /&gt;
&lt;br /&gt;
== Installing Recess ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ubuntu ===&lt;br /&gt;
&lt;br /&gt;
The following commands should be run to install Recess&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
sudo apt-get install npm nodejs&lt;br /&gt;
# If the above fails due to the error &amp;quot;The following packages have unmet dependencies&amp;quot;,&lt;br /&gt;
# run the commands separately, ie.&lt;br /&gt;
#     sudo apt-get install npm&lt;br /&gt;
# and then&lt;br /&gt;
#     sudo apt-get install nodejs&lt;br /&gt;
npm install recess -g&lt;br /&gt;
# If the above fails with a &amp;quot;..permission denied..&amp;quot; error,&lt;br /&gt;
# run npm install with sudo:&lt;br /&gt;
#     sudo npm install recess -g&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you find problem installing nodejs with npm, you can use [http://nodejs.org/download/ node.js binaries]&lt;br /&gt;
# Download Linux Binaries [http://nodejs.org/download/ node.js binaries]&lt;br /&gt;
# untar it to your local directory and add it to the PATH.&lt;br /&gt;
You can also use following script to get latest version.&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
CURRENT=$(node -v)&lt;br /&gt;
VERSION=$(curl -L -s http://nodejs.org/dist/latest/ \&lt;br /&gt;
    | egrep -o &#039;[0-9]+\.[0-9]+\.[0-9]+&#039; \&lt;br /&gt;
    | tail -n1)&lt;br /&gt;
PLATFORM=linux&lt;br /&gt;
ARCH=x64&lt;br /&gt;
PREFIX=&amp;quot;$HOME/node-v$VERSION-$PLATFORM-$ARCH&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
if test &amp;quot;v$VERSION&amp;quot; != &amp;quot;$CURRENT&amp;quot;; then&lt;br /&gt;
    echo &amp;quot;Installing node v$VERSION ...&amp;quot;&lt;br /&gt;
    mkdir -p &amp;quot;$PREFIX&amp;quot; &amp;amp;&amp;amp; \&lt;br /&gt;
    curl -# -L http://nodejs.org/dist/v$VERSION/node-v$VERSION-$PLATFORM-$ARCH.tar.gz \&lt;br /&gt;
      | tar xzvf - --strip-components=1 -C &amp;quot;$PREFIX&amp;quot;&lt;br /&gt;
    echo &#039;export PATH=$PATH:&#039;&amp;quot;$PREFIX&amp;quot; &amp;gt;&amp;gt; $HOME/.bashrc&lt;br /&gt;
    echo &amp;quot;Latest stable version installed at $PREFIX&amp;quot;&lt;br /&gt;
else&lt;br /&gt;
    echo &amp;quot;Latest stable version of node already installed.&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt; stands for Node Package Manager, and is the equivalent of apt-get for node.js packages.&lt;br /&gt;
&lt;br /&gt;
=== Mac OS X ===&lt;br /&gt;
1. Install the basic node packages from the web site: [http://nodejs.org http://nodejs.org]   (or use your favourite package manager to install &amp;lt;code&amp;gt;node&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
2. On the command line, install recess like this:&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
npm install recess -g&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== FreeBSD ===&lt;br /&gt;
1. Install npm (will also install nodes ie nodejs as a dependency)&lt;br /&gt;
&lt;br /&gt;
Using packages on:  &amp;lt;code&amp;gt;pkg install npm&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Build port  in /usr/port/www:  &amp;lt;code&amp;gt;cd /usr/port/www/npm; make install clean&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using portmaster:  &amp;lt;code&amp;gt;portmaster npm&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. On the command line, install recess like this:  &amp;lt;code&amp;gt;npm install recess -g&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Windows 7, 8, &amp;amp; 10 ===&lt;br /&gt;
&lt;br /&gt;
In order to install Recess you need to have Node.js installed first, which is relatively simple to do.&lt;br /&gt;
&lt;br /&gt;
Go to nodejs.org click install. &lt;br /&gt;
&lt;br /&gt;
When installed go to -&amp;gt; Start -&amp;gt; All Programs -&amp;gt; type Node.js into the Search box, then select Node.js Command prompt (black icon) from the list. Now you are ready to install Recess. So at the command line prompt type the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
npm install recess -g&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt; stands for Node Package Manager, and is the equivalent of apt-get for node.js packages.&lt;br /&gt;
&lt;br /&gt;
== Using Recess ==&lt;br /&gt;
&lt;br /&gt;
After editing the LESS files, compile (minified) your CSS as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
cd theme/bootstrapbase/less/&lt;br /&gt;
recess --compile --compress moodle.less &amp;gt; ../style/moodle.css&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or if you prefer to run it from the top-level:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
recess --compile --compress theme/bootstrapbase/less/moodle.less &amp;gt; theme/bootstrapbase/style/moodle.css&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will compile and compress the moodle.less file (and all the LESS and CSS files it imports) into a single file, moodle.css, and store it in the style folder of the bootstrapbase theme.&lt;br /&gt;
&lt;br /&gt;
Alternatively if you want to view the normal (un-minified) CSS then use the following method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
recess --compile moodle.less &amp;gt; ../style/moodle.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039; if you are getting an empty moodle.css file, this is being caused by a parsing error in your LESS code. A bug in &amp;lt;code&amp;gt;recess&amp;lt;/code&amp;gt; currently prevents it giving you helpful error messages in many cases. You will need to examine what you have altered or written to make sure it is complete and the syntax is correct. The &amp;lt;code&amp;gt;lessc&amp;lt;/code&amp;gt; compiler is what is used by &amp;lt;code&amp;gt;recess&amp;lt;/code&amp;gt; to do the actual compiling and will have been installed automatically along with it. If you call it directly as &amp;lt;code&amp;gt;lessc moodle.less&amp;lt;/code&amp;gt; it should give you a helpful error message that points you to where the problem is.&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=jQuery&amp;diff=47674</id>
		<title>jQuery</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=jQuery&amp;diff=47674"/>
		<updated>2015-04-23T23:21:33Z</updated>

		<summary type="html">&lt;p&gt;Tqr: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.9}}&lt;br /&gt;
&lt;br /&gt;
Before Moodle 2.9 we used [[YUI]] to write javascript in Moodle. As of Moodle 2.9 we are transitioning to jQuery and [[Javascript Modules]] because Yahoo has ceased all new development on YUI (http://yahooeng.tumblr.com/post/96098168666/important-announcement-regarding-yui).  &lt;br /&gt;
&lt;br /&gt;
This page explains the recommended way to use jQuery in core and plugins, although other [[jQuery pre2.9|older]] methods of including jQuery will still work. &lt;br /&gt;
&lt;br /&gt;
== Why do we need JQuery? ==&lt;br /&gt;
JQuery is useful for handling browser inconsistencies, and for utility functions that would otherwise be duplicated all over the code. Some particular things that JQuery is good at are:&lt;br /&gt;
* DOM Manipulations&lt;br /&gt;
* Promises ($.Deferred)&lt;br /&gt;
* Ajax&lt;br /&gt;
&lt;br /&gt;
== How to use JQuery ==&lt;br /&gt;
As of Moodle 2.9, the recommended way to write javascript is in AMD Modules. For more information on writing AMD modules in Moodle see [[ Javascript Modules ]]. &lt;br /&gt;
&lt;br /&gt;
JQuery has been added as an AMD Module and is available to all AMD javascript. &lt;br /&gt;
&lt;br /&gt;
To make use of JQuery, either list it as a dependency of your module, or use a require call to load it. &lt;br /&gt;
&lt;br /&gt;
=== As a dependency of a module ===&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    define([&#039;jquery&#039;], function($) {&lt;br /&gt;
        // Private functions.&lt;br /&gt;
        var privateFunc = function(a) {&lt;br /&gt;
            // JQuery is available via $ if I want it&lt;br /&gt;
            return a + 1;&lt;br /&gt;
        };&lt;br /&gt;
    &lt;br /&gt;
        // Public functions.&lt;br /&gt;
        return {&lt;br /&gt;
            publicFunc: function(b) {&lt;br /&gt;
                // JQuery is available via $ if I want it&lt;br /&gt;
                return privateFunc(b) + 1;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== With a require call ===&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    require([&#039;jquery&#039;], function($) {&lt;br /&gt;
        // JQuery is available via $&lt;br /&gt;
    });&lt;br /&gt;
    // JQuery is not in scope and cannot be used.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== What about JQuery UI ? ==&lt;br /&gt;
JQuery UI is a separate project containing a library of reusable widgets that relies on JQuery. JQuery UI is available for plugins to use, but it should not be used in core code. &lt;br /&gt;
&lt;br /&gt;
The problems with JQuery UI are:&lt;br /&gt;
* It uses an entirely different themeing system for CSS that does not work well with Moodle themes&lt;br /&gt;
* It introduces CSS conflicts with bootstrap&lt;br /&gt;
* The widgets have some accessibility features - but only if used in a very specific way which is not well documented&lt;br /&gt;
&lt;br /&gt;
Over time we will build up a library of widgets in core either by wrapping a suitable library or implementing from scratch.&lt;br /&gt;
&lt;br /&gt;
If you STILL want to use JQuery UI in your plugin, it is available as an AMD module named &#039;jqueryui&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    require([&#039;jquery&#039;, &#039;jqueryui&#039;], function($, jqui) {&lt;br /&gt;
        // JQuery is available via $&lt;br /&gt;
        // JQuery UI is available via jqui&lt;br /&gt;
    });&lt;br /&gt;
    // JQuery is not in scope and cannot be used.&lt;br /&gt;
    // JQuery UI is not in scope and cannot be used.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Javascript Modules]]&lt;br /&gt;
* [[jQuery pre2.9]]&lt;br /&gt;
* [http://jquery.com jQuery]&lt;br /&gt;
* [http://jqueryui.com jQuery User Interface]&lt;br /&gt;
&lt;br /&gt;
[[Category:Javascript]]&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Javascript_Modules&amp;diff=47673</id>
		<title>Javascript Modules</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Javascript_Modules&amp;diff=47673"/>
		<updated>2015-04-23T14:15:08Z</updated>

		<summary type="html">&lt;p&gt;Tqr: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.9}}&lt;br /&gt;
&lt;br /&gt;
= Javascript Modules =&lt;br /&gt;
&lt;br /&gt;
== What is a Javascript module and why do I care? ==&lt;br /&gt;
&lt;br /&gt;
A Javascript module is nothing more than a collection of Javascript code that can be used (reliably) from other pieces of Javascript. &lt;br /&gt;
&lt;br /&gt;
== Why should I package my code as a module? ==&lt;br /&gt;
&lt;br /&gt;
By packaging your code as a module you break your code up into smaller reusable pieces. This is good because:&lt;br /&gt;
&lt;br /&gt;
a) Each smaller piece is simpler to understand / debug&lt;br /&gt;
&lt;br /&gt;
b) Each smaller piece is simpler to test&lt;br /&gt;
&lt;br /&gt;
c) You can re-use common code instead of duplicating it&lt;br /&gt;
&lt;br /&gt;
= How do I write a Javascript module in Moodle? =&lt;br /&gt;
&lt;br /&gt;
Since version 2.9(?), Moodle supports Javascript modules written using the Asynchronous Module Definition ([https://github.com/amdjs/amdjs-api/wiki/AMD AMD]) API. This is a standard API for creating Javascript modules and you will find many useful third party libraries that are already using this format. &lt;br /&gt;
&lt;br /&gt;
To edit or create an AMD module in Moodle you need to do a couple of things. &lt;br /&gt;
&lt;br /&gt;
== Install grunt ==&lt;br /&gt;
The AMD modules in Moodle must be processed by some build tools before they will be visible to your web browser. We use &amp;quot;[http://gruntjs.com/ grunt]&amp;quot; as a build tool to wrap our different processes. Grunt is a build tool written in Javascript that runs in the &amp;quot;[http://nodejs.org/ nodejs]&amp;quot; environment. This means you first have to install nodejs - and it&#039;s package manager &amp;quot;[https://www.npmjs.com/ npm]&amp;quot;. The details of how to install those packages will vary by operating system, but on Linux it&#039;s probably similar to &amp;quot;sudo apt-get install nodejs npm&amp;quot;. There are downloadable packages for other operating systems here: http://nodejs.org/download/. Once this is done, you can run the command: &amp;quot;npm install&amp;quot; from the top of the Moodle directory to install all of the required tools. &lt;br /&gt;
&lt;br /&gt;
== Running grunt ==&lt;br /&gt;
Grunt is a special node package in that it comes in 2 parts. One part is the grunt package that is installed in the node_modules folder by the &amp;quot;npm install&amp;quot; command listed in the previous section. The second part is that you also need to install the grunt-cli package globally in order to have a &amp;quot;grunt&amp;quot; command in your path. To do this run &amp;quot;npm install -g grunt-cli&amp;quot; (you may need additional permissions to do this). &lt;br /&gt;
&lt;br /&gt;
Now you can run the &amp;quot;grunt&amp;quot; command from any folder in Moodle and it should &amp;quot;build&amp;quot; all of the javascript from that directory and it&#039;s sub directories. &lt;br /&gt;
&lt;br /&gt;
When grunt runs it currently does 3 things:&lt;br /&gt;
&lt;br /&gt;
* - it runs [https://github.com/yui/shifter shifter] to build any YUI modules in the source tree. See [YUI/Shifter] for more information on shifter&lt;br /&gt;
* - it runs [http://jshint.com/ jshint] to detect invalid Javascript, or Javascript that does not comply with our coding guidelines&lt;br /&gt;
* - it runs [http://lisperator.net/uglifyjs/ uglifyjs] to reduce the size of any Javascript by removing whitespace, stripping comments, shortening variable names etc.&lt;br /&gt;
&lt;br /&gt;
You must run &amp;quot;grunt&amp;quot; after making any change to the Javascript in Moodle. &lt;br /&gt;
&lt;br /&gt;
== &amp;quot;Hello World&amp;quot; I am a Javascript Module ==&lt;br /&gt;
Lets now create a simple Javascript module so we can see how to lay things out. &lt;br /&gt;
&lt;br /&gt;
Each Javascript module is contained in a single source file in the &amp;lt;componentdir&amp;gt;/amd/src folder. The final name of the module is taken from the file name and the component name. E.g. block_overview/amd/src/helloworld.js would be a module named &amp;quot;block_overview/helloworld&amp;quot;. the name of the module is important when you want to call it from somewhere else in the code. &lt;br /&gt;
&lt;br /&gt;
After running grunt - the minified Javascript files are stored in the &amp;lt;componentdir&amp;gt;/amd/build folder. The javascript files are renamed to show that they are minified (helloworld.js becomes helloworld.min.js). &lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to add the built files (the ones in amd/build) to your git commits, or in production no-one will see your changes. &lt;br /&gt;
&lt;br /&gt;
Lets create a simple module now:&lt;br /&gt;
&lt;br /&gt;
blocks/overview/amd/src/helloworld.js&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
// Standard license block omitted.&lt;br /&gt;
/*&lt;br /&gt;
 * @package    block_overview&lt;br /&gt;
 * @copyright  2015 Someone cool&lt;br /&gt;
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * @module block_overview/helloworld&lt;br /&gt;
  */&lt;br /&gt;
define([&#039;jquery&#039;], function($) {&lt;br /&gt;
&lt;br /&gt;
     /** &lt;br /&gt;
      * Give me blue.&lt;br /&gt;
      * @access private&lt;br /&gt;
      * @return {string}&lt;br /&gt;
      */&lt;br /&gt;
     var makeItBlue = function() {&lt;br /&gt;
          // We can use our jquery dependency here.&lt;br /&gt;
          return $(&#039;.blue&#039;).show();&lt;br /&gt;
     };&lt;br /&gt;
      &lt;br /&gt;
    /**&lt;br /&gt;
     * @constructor&lt;br /&gt;
     * @alias module:block_overview/helloworld&lt;br /&gt;
     */&lt;br /&gt;
    var greeting = function() {&lt;br /&gt;
        /** @access private */&lt;br /&gt;
        var privateThoughts = &#039;I like the colour blue&#039;;&lt;br /&gt;
        &lt;br /&gt;
        /** @access public */&lt;br /&gt;
        this.publicThoughts = &#039;I like the colour orange&#039;;&lt;br /&gt;
&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * A formal greeting.&lt;br /&gt;
     * @access public&lt;br /&gt;
     * @return {string}&lt;br /&gt;
     */&lt;br /&gt;
    greeting.prototype.formal = function() {&lt;br /&gt;
        return &#039;How do you do?&#039;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * An informal greeting.&lt;br /&gt;
     * @access public&lt;br /&gt;
     * @return {string}&lt;br /&gt;
     */&lt;br /&gt;
    greeting.prototype.informal = function() {&lt;br /&gt;
        return &#039;Wassup!&#039;;&lt;br /&gt;
    };&lt;br /&gt;
    return greeting;&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The most interesting line above is:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
define([&#039;jquery&#039;], function($) {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All AMD modules must call &amp;quot;define()&amp;quot; as the first and only global scoped piece of code. This ensures the javascript code contains no global variables and will not conflict with any other loaded module. The name of the module does not need to be specified because it is determined from the filename and component (but it can be listed in a comment for JSDoc as shown here). &lt;br /&gt;
&lt;br /&gt;
The first argument to &amp;quot;define&amp;quot; is the list of dependencies for the module. This argument must be passed as an array, even if there is only one. In this example &amp;quot;jquery&amp;quot; is a dependency. &amp;quot;jquery&amp;quot; is shipped as a core module is available to all AMD modules. &lt;br /&gt;
&lt;br /&gt;
The second argument to &amp;quot;define&amp;quot; is the function that defines the module. This function will receive as arguments, each of the requested dependencies in the same order they were requested. In this example we receive JQuery as an argument and we name the variable &amp;quot;$&amp;quot; (it&#039;s a JQuery thing). We can then access JQuery normally through the $ variable which is in scope for any code in our module. &lt;br /&gt;
&lt;br /&gt;
The rest of the code in this example is a standard way to define a Javascript module with public/private variables and methods. There are many ways to do this, this is only one.&lt;br /&gt;
&lt;br /&gt;
It is important that we are returning &#039;greeting&#039;. If there is no return then your module will be declared as undefined.&lt;br /&gt;
&lt;br /&gt;
== Loading modules dynamically ==&lt;br /&gt;
What do you do if you don&#039;t know in advance which modules will be required? Stuffing all possible required modules in the define call is one solution, but it&#039;s ugly and it only works for code that is in an AMD module (what about inline code in the page?). AMD lets you load a dependency any time you like. &lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Load a new dependency.&lt;br /&gt;
require([&#039;mod_wiki/timer&#039;], function(timer) {&lt;br /&gt;
   // timer is available to do my bidding.&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Embedding AMD code in a page ==&lt;br /&gt;
So you have created lots of cool Javascript modules. Great. How do we actually call them? Any javascript code that calls an AMD module must execute AFTER the requirejs module loader has finished loading. We have provided a function &amp;quot;js_call_amd&amp;quot; that will call a single function from an AMD module with parameters.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$OUTPUT-&amp;gt;requires-&amp;gt;js_call_amd($modulename, $functionname, $params);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
that will &amp;quot;do the right thing&amp;quot; with your block of AMD code and execute it at the end of the page, after our AMD module loader has loaded. &lt;br /&gt;
Notes:&lt;br /&gt;
* the $modulename is the &#039;componentname/modulename&#039; discussed above&lt;br /&gt;
* the $functionname is the name of a public function exposed by the amd module. &lt;br /&gt;
* the $params is an array of params passed as arguments to the function. These should be simple types that can be handled by json_encode (no recursive arrays, or complex classes please). &lt;br /&gt;
* if the size of the params array is too large (&amp;gt; 1Kb), this will produce a developer warning. Do not attempt to pass large amounts of data through this function, it will pollute the page size. A preferred approach is to pass css selectors for DOM elements that contain data-attributes for any required data, or fetch data via ajax in the background.&lt;br /&gt;
&lt;br /&gt;
== But I have a mega JS file I don&#039;t want loaded on every page? ==&lt;br /&gt;
Loading all JS files at once and stuffing them in the browser cache is the right choice for MOST js files, there are probably some exceptions. For these files, you can rename the javascript file to end with the suffix &amp;quot;-lazy.js&amp;quot; which indicates that the module will not be loaded by default, it will be requested the first time it is used. There is no difference in usage for lazy loaded modules, the require() call looks exactly the same, it&#039;s just that the module name will also have the &amp;quot;-lazy&amp;quot; suffix.&lt;br /&gt;
&lt;br /&gt;
[[Category:AJAX]]&lt;br /&gt;
[[Category:Javascript]]&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Creating_a_theme&amp;diff=47616</id>
		<title>Creating a theme</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Creating_a_theme&amp;diff=47616"/>
		<updated>2015-04-20T16:57:01Z</updated>

		<summary type="html">&lt;p&gt;Tqr: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}{{Moodle 2.1}}{{Moodle 2.0}}This document describes how to create a theme for Moodle 2.0 and Moodle 2.1. ONLY. It assumes you have some understanding of how themes within Moodle work as well as a good understanding of HTML and CSS.&lt;br /&gt;
&lt;br /&gt;
For Themes in Moodle 2.2 onwards please read the tutorial about [https://docs.moodle.org/dev/Themes_2.2_how_to_clone_a_Moodle_2.2_theme How to clone a Moodle 2.2 theme]. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Theme designer mode===&lt;br /&gt;
&lt;br /&gt;
Under normal operation Moodle does several things in the name of performance, one of these is to combine all of the CSS into one file, minimize it, cache it on the server, and then serve it. After the first request the cached version is served to greatly improve page performance. &lt;br /&gt;
&lt;br /&gt;
What this means for you as a themer? When you make changes they will not be seen immediately. In fact you will need to tell Moodle to rebuild the cache that it is serving.&lt;br /&gt;
This isn&#039;t practical for designing themes of course so the &#039;&#039;&#039;theme designer mode&#039;&#039;&#039; was added. When enabled it tells Moodle not to combine or cache the CSS that gets delivered. This has the downside that page load times will take significantly longer, however you will see your changes immediately every time.&lt;br /&gt;
&lt;br /&gt;
Theme designer mode may be enabled via &#039;&#039;Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; [[Theme settings]]&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warning&#039;&#039;&#039;: Internet Explorer versions 6 and 7 have BIG problems when a site attempts to link to more than 31 stylesheets, in which case either a limited number or no styles get applied. Because Moodle sends up all of the CSS all of the time with theme designer mode turned on there is a very high chance you will get more than 31 stylesheets being included. This will, of course, cause major problems for Internet Explorer until theme designer mode is turned off.&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
The first thing you need to do is create the directories and files you will be using, the first thing to create is the actual directory for your theme. This should be the name of your theme, in my case it&#039;s &#039;excitement&#039;. The directory should be located within the theme directory of Moodle, ./moodle/theme/excitement/ will be the directory I create.&lt;br /&gt;
&lt;br /&gt;
Now within that directory we can immediately create several files that we know we are going to need. &lt;br /&gt;
&lt;br /&gt;
So the files that we want to create are:&lt;br /&gt;
; config.php :  All of our settings will go here.&lt;br /&gt;
; /style/ : This directory will contain all of our stylesheets.&lt;br /&gt;
; /style/excitement.css : All of our css will go in here.&lt;br /&gt;
; /pix/ : Into this directory we&#039;ll put a screen shot of our theme as well as our favicon and any images we use in CSS.&lt;br /&gt;
; /layout/ : Our layout files will end up in this directory.&lt;br /&gt;
; /layout/standard.php : This will be our one basic layout file.&lt;br /&gt;
; /lang/en/ : The file we put here will make our theme name show properly on the Theme Selector page. You need a few standard entries. Copy the one from the Standard theme and modify is easiest. &lt;br /&gt;
&lt;br /&gt;
So after this setup step you should have a directory structure similar to what is shown below.&lt;br /&gt;
&lt;br /&gt;
[[image:Learn_to_theme_01.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Configuring our theme==&lt;br /&gt;
&lt;br /&gt;
Open config.php in your favourite editor and start by adding the opening PHP tags &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;&amp;lt;?php&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Now we need to add the settings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;name = &#039;excitement&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Very simply this tells Moodle the name of your theme, and if you ever have several config.php files open this will help you identify which one you are looking at.&lt;br /&gt;
&lt;br /&gt;
Next, the parents for this theme.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;base&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This tells Moodle that my new theme &#039;&#039;`excitement`&#039; wants to extend the base theme. &lt;br /&gt;
&lt;br /&gt;
A theme can extend any number of themes. Rather than creating an entirely new theme and copying all of the CSS, you can simply create a new theme, extend the theme you like and just add the changes you want to your theme. &lt;br /&gt;
&lt;br /&gt;
Also worth noting is the purpose of the base theme: it provides us with a basic layout and just enough CSS to make everything fall into place.&lt;br /&gt;
&lt;br /&gt;
Now we will tell Moodle about our stylesheets:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;excitement&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final thing we need to add into our theme&#039;s config.php file is the definition of the layouts for our theme:&lt;br /&gt;
(in the code below, replace &#039;general.php&#039; with &#039;standard.php&#039; because that is the file that is previously created)&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Most backwards compatible layout without the blocks - this is the layout used by default&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&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;
    // 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;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-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // Main course page&lt;br /&gt;
    &#039;course&#039; =&amp;gt; array(&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-pre&#039;,&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;coursecategory&#039; =&amp;gt; array(&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-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // part of course, typical for modules - default page layout if $cm specified in require_login()&lt;br /&gt;
    &#039;incourse&#039; =&amp;gt; array(&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-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // The site home page.&lt;br /&gt;
    &#039;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;frontpage.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-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // Server administration scripts.&lt;br /&gt;
    &#039;admin&#039; =&amp;gt; array(&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;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // My dashboard page&lt;br /&gt;
    &#039;mydashboard&#039; =&amp;gt; array(&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-pre&#039;,&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // My public page&lt;br /&gt;
    &#039;mypublic&#039; =&amp;gt; array(&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-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;login&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    // Pages that appear in pop-up windows - no navigation, no blocks, no header.&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true, &#039;nologininfo&#039;=&amp;gt;true, &#039;nocourseheaderfooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // No blocks and minimal footer - used for legacy frame layouts only!&lt;br /&gt;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nocoursefooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible&lt;br /&gt;
    &#039;embedded&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true, &#039;nocourseheaderfooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Used during upgrade and install, and for the &#039;This site is undergoing maintenance&#039; message.&lt;br /&gt;
    // This must not have any blocks, and it is good idea if it does not have links to&lt;br /&gt;
    // other places - for example there should not be a home link in the footer...&lt;br /&gt;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true, &#039;nocourseheaderfooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Should display the content and basic headers only.&lt;br /&gt;
    &#039;print&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;false, &#039;nocustommenu&#039;=&amp;gt;true, &#039;nocourseheaderfooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // The pagelayout used when a redirection is occuring.&lt;br /&gt;
    &#039;redirect&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true, &#039;nocourseheaderfooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // The pagelayout used for reports.&lt;br /&gt;
    &#039;report&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;report.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // The pagelayout used for safebrowser and securewindow.&lt;br /&gt;
    &#039;secure&#039; =&amp;gt; array(&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-pre&#039;,&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true, &#039;nologinlinks&#039;=&amp;gt;true, &#039;nocourseheaderfooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** List of javascript files that need to be included on each page */&lt;br /&gt;
$THEME-&amp;gt;javascripts = array();&lt;br /&gt;
$THEME-&amp;gt;javascripts_footer = array();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you are looking at is the different layouts for our theme. Why are there so many? Because, that is how many there are in Moodle. There is one for every general type of page. With my &#039;&#039;`excitement`&#039;&#039; theme I have chosen to use my own layout. Unless there was a specific reason to do so, normally you would not need to create your own layouts, you could extend the base theme, and use its layouts, meaning you would only have to write CSS to achieve your desired look.&lt;br /&gt;
&lt;br /&gt;
For each layout above, you will notice the following four things are being set:&lt;br /&gt;
; file : This is the name of the layout file we want to use, it should always be located in the above themes layout directory. For us this is of course standard.php as we only have one layout file.&lt;br /&gt;
; regions : This is an array of block regions that our theme has. Each entry in here can be used to put blocks in when that layout is being used.&lt;br /&gt;
; defaultregion : If a layout has regions it should have a default region, this is where blocks get put when first added. It is also where the &amp;quot;add block&amp;quot; block is shown when editing is on.&lt;br /&gt;
; options : These are special settings, anything that gets put into the options array is available later on when we are writing our layout file.&lt;br /&gt;
&lt;br /&gt;
There are additional settings that can be defined in the config.php file - see [[Themes 2.0|Themes 2.0]] for the full list.&lt;br /&gt;
&lt;br /&gt;
==Configuring the language file==&lt;br /&gt;
Open theme_base.php file from &#039;&#039;&#039;base/lang/en/theme_base.php&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Save it as &#039;&#039;&#039;excitement/lang/en/theme_excitement.php&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Change &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;Base&#039;; &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
to&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;Excitement&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After making these changes and perhaps clearing theme caches and/or purging all caches, the new theme name should now show properly in the Theme Selector: &#039;&#039;Site Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; Theme Selector&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can also edit the theme description:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;choosereadme&#039;] = &#039;Write your theme description here.&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You need to leave the following two lines in place (you can change the wording if you need to) to avoid notices when editing blocks etc.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;region-side-post&#039;] = &#039;Right&#039;;&lt;br /&gt;
$string[&#039;region-side-pre&#039;] = &#039;Left&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Writing the layout file==&lt;br /&gt;
&lt;br /&gt;
The excitement theme has just one layout file.&lt;br /&gt;
&lt;br /&gt;
The downside of this is that I have to make the layout file do everything I want which means I need to make use of some options (as defined in the layouts in config.php). &lt;br /&gt;
&lt;br /&gt;
The upside is that I only need to maintain one file. &lt;br /&gt;
&lt;br /&gt;
Other than maintenance, using multiple layout files provides many advantages to real world themes in that you can easily tweak and customise specific layouts to achieve the goals of the organisation using the theme.&lt;br /&gt;
&lt;br /&gt;
Before learning more it is good to understand the two primary objects that will be used in your layout files: $OUTPUT and $PAGE.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;$OUTPUT&#039;&#039;&#039; is an instance of the &amp;lt;code&amp;gt;core_renderer&amp;lt;/code&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;$PAGE&#039;&#039;&#039; is an instance of the &amp;lt;code&amp;gt;moodle_page&amp;lt;/code&amp;gt; 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-&amp;gt;activityname, just like fields of an ordinary PHP object. (However, behind the scenes the value you get is produced by calling a function. Also, you cannot change these values, they are &#039;&#039;&#039;read-only&#039;&#039;&#039;. However, you don&#039;t need to understand all that if you are just using these properties in your theme.)&lt;br /&gt;
&lt;br /&gt;
So lets start writing standard.php, the layout file for my &#039;&#039;`excitement`&#039;&#039; theme.&lt;br /&gt;
&lt;br /&gt;
===The top of the layout file===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$hassidepre = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-pre&#039;, $OUTPUT);&lt;br /&gt;
$hassidepost = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-post&#039;, $OUTPUT);&lt;br /&gt;
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;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lets look at the code that goes into this section:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
echo $OUTPUT-&amp;gt;doctype(); ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is very important and is required to go at the very top of the page. This tells Moodle to print out the document type tag that is determined by the settings within Moodle.&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 open the HTML tag and then ask Moodle to print the attributes that should go inside it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&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;/code&amp;gt;&lt;br /&gt;
Simply creates the title tag and asks Moodle to fill it in.&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;
Here we are asking Moodle to print all of the other tags and content that need to go into the head. This includes stylesheets, script tags, and inline JavaScript code.&lt;br /&gt;
&lt;br /&gt;
===The page header===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php p($PAGE-&amp;gt;bodyid); ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php p($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;div id=&amp;quot;page&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading || (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar())) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-header&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;?php if ($PAGE-&amp;gt;heading) { ?&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&lt;br /&gt;
                if (method_exists($OUTPUT, &#039;user_menu&#039;)) {&lt;br /&gt;
                  echo $OUTPUT-&amp;gt;user_menu(); // user menu, for Moodle 2.8&lt;br /&gt;
                } else {&lt;br /&gt;
                  echo $OUTPUT-&amp;gt;login_info(); // login_info, Moodle 2.7 and before&lt;br /&gt;
                }&lt;br /&gt;
                if (!empty($PAGE-&amp;gt;layout_options[&#039;langmenu&#039;])) {&lt;br /&gt;
                    echo $OUTPUT-&amp;gt;lang_menu();&lt;br /&gt;
                }&lt;br /&gt;
                echo $PAGE-&amp;gt;headingmenu&lt;br /&gt;
            ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
        &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar()) { ?&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;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So there is a bit more going on here obviously.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php p($PAGE-&amp;gt;bodyid); ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php p($PAGE-&amp;gt;bodyclasses); ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Again much like what we did for the opening HTML tag in the head we have started writing the opening body tag and are then asking Moodle to give us the ID we should use for the body tag as well as the classes we should use.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_top_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This very important call writes some critical bits of JavaScript into the page. It should always be located after the body tag as soon as possible.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading || (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar())) { ?&amp;gt;&lt;br /&gt;
......&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are checking whether or not we need to print the header for the page. There are three checks we need to make here:&lt;br /&gt;
# &#039;&#039;&#039;$PAGE-&amp;gt;heading&#039;&#039;&#039; : This checks to make sure that there is a heading for the page. This will have been set by the script and normally describes the page in a couple of words.&lt;br /&gt;
# &#039;&#039;&#039;empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;])&#039;&#039;&#039; : Now this check is looking at the layout options that we set in our config.php file. It is looking to see if the layout set &#039;nonavbar&#039; =&amp;gt; true.&lt;br /&gt;
# &#039;&#039;&#039;$PAGE-&amp;gt;has_navbar()&#039;&#039;&#039; The third check is to check with the page whether it has a navigation bar to display.&lt;br /&gt;
If either there is a heading for this page or there is a navigation bar to display then we will display a heading.&lt;br /&gt;
&lt;br /&gt;
Leading on from this lets assume that there is a header to print.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading) { ?&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;
    .....&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This line is simply saying if the page has a heading print it. In this case we run the first check above again just to make sure there is a heading, we then open a heading tag that we choose and ask the page to print the heading.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;headermenu&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
    if (method_exists($OUTPUT, &#039;user_menu&#039;)) {&lt;br /&gt;
      echo $OUTPUT-&amp;gt;user_menu(); // user menu, for Moodle 2.8&lt;br /&gt;
    } else {&lt;br /&gt;
      echo $OUTPUT-&amp;gt;login_info(); // login_info, Moodle 2.7 and before&lt;br /&gt;
    }&lt;br /&gt;
    if (!empty($PAGE-&amp;gt;layout_options[&#039;langmenu&#039;])) {&lt;br /&gt;
        echo $OUTPUT-&amp;gt;lang_menu();&lt;br /&gt;
    }&lt;br /&gt;
    echo $PAGE-&amp;gt;headingmenu&lt;br /&gt;
?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are looking to print the menu and content that you see at the top of the page (usually to the right). We start by getting Moodle to print the login information for the current user. If the user is logged in this will be their name and a link to their profile, if not then it will be a link to login. Note that on Moodle 2.8 and above, a new user menu renderable is available that visually shows the same information as the login info renderable, as well as a dropdown menu with user-centric actions.&lt;br /&gt;
&lt;br /&gt;
Next we check our page options to see whether a language menu should be printed. If in the layout definition within config.php it sets &#039;&#039;&#039;langmenu =&amp;gt; true&#039;&#039;&#039; then we will print the language menu, a drop down box that lets the user change the language that Moodle displays in.&lt;br /&gt;
&lt;br /&gt;
Finally the page also has a heading menu that can be printed. This heading menu is special HTML that the page you are viewing wants to add. It can be anything from drop down boxes to buttons and any number of each.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar()) { ?&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;
The final part of the header.&lt;br /&gt;
&lt;br /&gt;
Here we want to print the navigation bar for the page if there is one. To find out if there is one we run checks number 2 and 3 again and proceed if they pass.&lt;br /&gt;
&lt;br /&gt;
Assuming there is a header then there are two things that we need to print. The first is the navigation bar. This is a component that the OUTPUT library knows about. The second is a button to show on the page.&lt;br /&gt;
&lt;br /&gt;
In both cases we choose to wrap them in a div tag with a class attribute to enable theming on those elements.&lt;br /&gt;
&lt;br /&gt;
Well that is it for the header. There is a lot of PHP compared to the other sections of the layout file but it does not change and can be copied and pasted between themes.&lt;br /&gt;
&lt;br /&gt;
===The page content===&lt;br /&gt;
&lt;br /&gt;
I am going with the default two block regions plus the main content.&lt;br /&gt;
&lt;br /&gt;
Because I have based this theme and layout file on the base theme the HTML looks a little intense. This is because it is a floating div layout where the content comes first and then we get the columns (even though one column will be to the left of the content.) Don&#039;t worry too much about it. When it comes to writing your own theme you can go about it as you choose.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;page-content&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;region-main-box&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div id=&amp;quot;region-post-box&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;div id=&amp;quot;region-main-wrap&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-main&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;?php if ($hassidepre) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-pre&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&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;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
                &lt;br /&gt;
                &amp;lt;?php if ($hassidepost) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-post&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&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;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In regards to PHP this section is very easy. There are only three lines for the whole section one to get the main content and one for each block region.&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 line prints the main content for the page.&lt;br /&gt;
PLEASE NOTE: In Moodle 2.2 onwards &amp;quot;core_renderer::MAIN_CONTENT_TOKEN&amp;quot; changed to &amp;quot;$OUTPUT-&amp;gt;main_content()&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($hassidepre) { ?&amp;gt;&lt;br /&gt;
....&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
These lines of code check the variables we created earlier on to decide whether we should show the pre block region. If you try to display a block region that isn&#039;t there or has no content then Moodle will give you an error message so these lines are very important.&lt;br /&gt;
&lt;br /&gt;
For those who get an error message if it is &amp;quot;unknown block region side-pre&amp;quot; or &amp;quot;unknown block region side-post&amp;quot; then this is the issue you are experiencing. Simply add the following lines and all will be fine.&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;
This line gets all of the blocks and more particularly the content for the block region &#039;&#039;&#039;side-pre&#039;&#039;&#039;. This block region will be displayed to the left of the content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($hassidepost) { ?&amp;gt;&lt;br /&gt;
....&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Again we should make this check for every block region as there are some pages that have no blocks what-so-ever.&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 are getting the other block region &#039;&#039;&#039;side-post&#039;&#039;&#039; which will be displayed to the right of the content.&lt;br /&gt;
&lt;br /&gt;
===The page footer===&lt;br /&gt;
Here we want to print the footer for the page, any content required by Moodle, and then close the last tags.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nofooter&#039;])) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot; class=&amp;quot;clearfix&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;/div&amp;gt;&lt;br /&gt;
    &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/div&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;
The section of code is responsible for printing the footer for the page.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nofooter&#039;])) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot; class=&amp;quot;clearfix&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;/div&amp;gt;&lt;br /&gt;
    &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The first thing we do before printing the footer is check that we actually want to print it. This is done by checking the options for the layout as defined in the config.php file. If &#039;&#039;&#039;nofooter =&amp;gt; true&#039;&#039;&#039; is set the we don&#039;t want to print the footer and should skip over this body of code.&lt;br /&gt;
&lt;br /&gt;
Assuming we want to print a footer we proceed to create a div to house its content and then print the bits of the content that will make it up.&lt;br /&gt;
There are four things that the typical page footer will want to print:&lt;br /&gt;
; echo page_doc_link(get_string(&#039;moodledocslink&#039;)) : This will print a link to the Moodle.org help page for this particular page.&lt;br /&gt;
; echo $OUTPUT-&amp;gt;login_info(); : This is the same as at the top of the page and will print the login information for the current user.&lt;br /&gt;
; echo $OUTPUT-&amp;gt;home_link(); : This prints a link back to the Moodle home page for this site.&lt;br /&gt;
; echo $OUTPUT-&amp;gt;standard_footer_html(); : This prints special HTML that is determined by the settings for the site. Things such as performance information or debugging will be printed by this line if they are turned on.&lt;br /&gt;
&lt;br /&gt;
And the final line of code for our layout file is:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_end_of_body_html(); ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is one of the most important lines of code in the layout file. It asks Moodle to print any required content into the page, and there will likely be a lot although most of it will not be visual.&lt;br /&gt;
&lt;br /&gt;
It will instead be things such as inline scripts and JavaScript files required to go at the bottom of the page. If you forget this line its likely no JavaScript will work!&lt;br /&gt;
&lt;br /&gt;
We&#039;ve now written our layout file and it is all set to go. The complete source is below for reference. Remember if you want more practical examples simply look at the layout files located within the layout directory of other themes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$hassidepre = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-pre&#039;, $OUTPUT);&lt;br /&gt;
$hassidepost = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-post&#039;, $OUTPUT);&lt;br /&gt;
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;link rel=&amp;quot;shortcut icon&amp;quot; href=&amp;quot;&amp;lt;?php echo $OUTPUT-&amp;gt;pix_url(&#039;favicon&#039;, &#039;theme&#039;)?&amp;gt;&amp;quot; /&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;
&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php p($PAGE-&amp;gt;bodyid); ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php p($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;div id=&amp;quot;page&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading || (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar())) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-header&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;?php if ($PAGE-&amp;gt;heading) { ?&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&lt;br /&gt;
            echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
            if (!empty($PAGE-&amp;gt;layout_options[&#039;langmenu&#039;])) {&lt;br /&gt;
                echo $OUTPUT-&amp;gt;lang_menu();&lt;br /&gt;
            }&lt;br /&gt;
            echo $PAGE-&amp;gt;headingmenu&lt;br /&gt;
        ?&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
        &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar()) { ?&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;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-content&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div id=&amp;quot;region-main-box&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;div id=&amp;quot;region-post-box&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-main-wrap&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div id=&amp;quot;region-main&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                            &amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
                        &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php if ($hassidepre) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-pre&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&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;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
                &lt;br /&gt;
                &amp;lt;?php if ($hassidepost) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-post&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&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;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nofooter&#039;])) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot; class=&amp;quot;clearfix&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;/div&amp;gt;&lt;br /&gt;
    &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/div&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;
==Adding some CSS==&lt;br /&gt;
With config.php and standard.php both complete the theme is now usable and starting to look like a real theme, however if you change to it using the theme selector you will notice that it still lacks any style.&lt;br /&gt;
&lt;br /&gt;
This of course is where CSS comes in. When writing code Moodle developers are strongly encouraged to not use inline styles anywhere. This is fantastic for us as themers because there is nothing (or at least very little) in Moodle that cannot be styled using CSS.&lt;br /&gt;
&lt;br /&gt;
===Moodle CSS basics===&lt;br /&gt;
&lt;br /&gt;
In Moodle 2.0 all of the CSS for the whole of Moodle is delivered all of the time! This was done for performance reasons. Moodle now reads in all of the CSS, combines it into one file, shrinks it removing any white space, caches it, and then delivers it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What this means for you as a themer?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You will need to write good CSS that won&#039;t clash with any other CSS within Moodle.&lt;br /&gt;
&lt;br /&gt;
Moodle is so big and complex,there is no way to ensure that classes don&#039;t get reused. What we can control however is the classes and id that get added to the body tag for every page. When writing CSS it is highly encouraged to make full use of these body classes, using them will help ensure the CSS you write has the least chance of causing conflicts.&lt;br /&gt;
&lt;br /&gt;
You should also take the time to look at how the Moodle themes use CSS. Look at their use of the body classes and how they separate the CSS for the theme into separate files based on the region of Moodle it applies to.&lt;br /&gt;
&lt;br /&gt;
Check out [[Themes 2.0|Themes 2.0]] and [[CSS coding style]] for more information about writing good CSS.&lt;br /&gt;
&lt;br /&gt;
===Starting to write excitement.css===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
a {&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.addcoursebutton .singlebutton {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
h1.headermain {&lt;br /&gt;
    color: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
h2.main {&lt;br /&gt;
    border-bottom: 3px solid #013D6A;&lt;br /&gt;
    color: #013D6A;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
h2.headingblock {&lt;br /&gt;
    font-size: 18pt;&lt;br /&gt;
    margin-top: 0;&lt;br /&gt;
    background-color: #013D6A;&lt;br /&gt;
    color: #FFF;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#page-header {&lt;br /&gt;
    background-color: #013D6A;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#page-header .headermenu {&lt;br /&gt;
    color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#page-header .headermenu a {&lt;br /&gt;
    color: #FDFF2A;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.navbar {&lt;br /&gt;
    padding-left: 1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.breadcrumb li {&lt;br /&gt;
    color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.breadcrumb li a {&lt;br /&gt;
    color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block {&lt;br /&gt;
    background-color: #013D6A;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block .header .title {&lt;br /&gt;
    color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block .header .title .block_action input {&lt;br /&gt;
    background-color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block .content {&lt;br /&gt;
    border: 1px solid #000;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    background-color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block .content .block_tree p {&lt;br /&gt;
    font-size: 80%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_settings_navigation_tree .content .footer {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform {&lt;br /&gt;
    margin-left: 5%;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    font-size: 9pt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform #adminsearchquery {&lt;br /&gt;
    width: 95%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .calendar-controls a {&lt;br /&gt;
    color: #013D6A;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .minicalendar td {&lt;br /&gt;
    border-color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {&lt;br /&gt;
    color: #FFF;&lt;br /&gt;
    background-color: #013D6A;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .minicalendar .day a {&lt;br /&gt;
    color: #FFF000;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays th {&lt;br /&gt;
    border-width: 0;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #013D6A;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays abbr {&lt;br /&gt;
    border-width: 0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
[[image:Learn_to_theme_02.jpg|400px|thumb|Excitement theme screenshot]]&lt;br /&gt;
This isn&#039;t all of the CSS for the theme, but just enough to style the front page when the user is not logged in.&lt;br /&gt;
Remember this theme extends the base theme so there is already CSS for layout as well.&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
* The CSS is laid out in a single line format. This is done within the core themes for Moodle. It makes it quicker to read the selectors and see what is being styled.&lt;br /&gt;
* I have written my selectors to take into account the structure of the HTML (more than just the one tag I want to style). This helps further to reduce the conflicts that I may encounter.&lt;br /&gt;
* I use generic classes like &#039;&#039;.sideblock&#039;&#039; only where I want to be generic, as soon as I want to be specific I use the unique classes such as &#039;&#039;.block_calendar_month&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:right;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Using images within CSS===&lt;br /&gt;
&lt;br /&gt;
I will add two image files to the pix directory of my theme:&lt;br /&gt;
; /theme/excitement/pix/background.png : This will be the background image for my theme.&lt;br /&gt;
; /theme/excitement/pix/gradient.jpg : This will be a gradient I use for the header and headings.&lt;br /&gt;
I quickly created both of these images using gimp and simply saved them to the pix directory.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
html {&lt;br /&gt;
    background-image: url([[pix:theme|background]]);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
h2.headingblock,&lt;br /&gt;
#page-header,&lt;br /&gt;
.sideblock,&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {&lt;br /&gt;
    background-image: url([[pix:theme|gradient]]);&lt;br /&gt;
    background-repeat: repeat-x;&lt;br /&gt;
    background-color: #0273C8;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
[[image:Learn_to_theme_03.jpg‎|400px|thumb|Excitement theme screenshot]]&lt;br /&gt;
The CSS above is the two new rules that I had to write to use my images within CSS.&lt;br /&gt;
&lt;br /&gt;
The first rule sets the background image for the page to background.png&lt;br /&gt;
&lt;br /&gt;
The second rule sets the background for headings, and the sideblocks to use gradient.jpg&lt;br /&gt;
&lt;br /&gt;
You will notice that I did not need to write a path to the image. This is because Moodle has this special syntax that can be used and will be replaced when the CSS is parsed before delivery.&lt;br /&gt;
The advantage of using this syntax over writing the path in is that the path may change depending on where you are or what theme is being used.&lt;br /&gt;
&lt;br /&gt;
Other themers may choose to extend your theme with their own; if you use this syntax then all they need to do to override the image is to create one with the same name in their themes directory.&lt;br /&gt;
&lt;br /&gt;
You will also notice that I don&#039;t need to add the image files extension. This is because Moodle is smart enough to work out what extension the file uses. It also allows themers to override images with different formats.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:right&amp;quot; /&amp;gt;&lt;br /&gt;
The following is the complete CSS for my theme:&lt;br /&gt;
&amp;lt;div style=&amp;quot;overflow:auto;height:860px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
a {text-decoration: none;}&lt;br /&gt;
.addcoursebutton .singlebutton {text-align: center;}&lt;br /&gt;
&lt;br /&gt;
h1.headermain {color: #fff;}&lt;br /&gt;
h2.main {border-bottom: 3px solid #013D6A;color: #013D6A;text-align: center;}&lt;br /&gt;
h2.headingblock {font-size: 18pt;margin-top: 0;background-color: #013D6A;color: #FFF;text-align: center;}&lt;br /&gt;
#page-header {background-color: #013D6A;border-bottom:5px solid #013D6A;}&lt;br /&gt;
#page-header .headermenu  {color: #FFF;}&lt;br /&gt;
#page-header .headermenu a {color: #FDFF2A;}&lt;br /&gt;
&lt;br /&gt;
.sideblock {background-color: #013D6A;}&lt;br /&gt;
.sideblock .header .title {color: #FFF;}&lt;br /&gt;
.sideblock .header .title .block_action input {background-color: #FFF;}&lt;br /&gt;
.sideblock .content {border: 1px solid #000;padding: 5px;background-color: #FFF;}&lt;br /&gt;
.sideblock .content .block_tree p {font-size: 80%;}&lt;br /&gt;
&lt;br /&gt;
.block_settings_navigation_tree .content .footer {text-align: center;}&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform {margin-left: 5%;width: 90%;font-size: 9pt;}&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform #adminsearchquery {width: 95%;}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .calendar-controls a {color: #013D6A;font-weight: bold;}&lt;br /&gt;
.block_calendar_month .content .minicalendar td {border-color: #FFF;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {color: #FFF;background-color: #013D6A;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .day a {color: #FFF000;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays th {border-width: 0;font-weight: bold;color: #013D6A;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays abbr {border-width: 0;text-decoration: none;}&lt;br /&gt;
&lt;br /&gt;
html {background-image:url([[pix:theme|background]]);}&lt;br /&gt;
&lt;br /&gt;
h2.headingblock,&lt;br /&gt;
#page-header,&lt;br /&gt;
.sideblock,&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {background-image:url([[pix:theme|gradient]]);&lt;br /&gt;
   background-repeat:repeat-x;background-color: #0273C8;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adding a screenshot and favicon==&lt;br /&gt;
The final thing to do at this point is add both a screenshot for this theme as well as a favicon for it.&lt;br /&gt;
The screenshot will be shown in the theme selector screen and should be named &#039;&#039;screenshot.jpg&#039;&#039;.&lt;br /&gt;
The favicon will be used when someone bookmarks this page.&lt;br /&gt;
Both images should be located in your themes pix directory as follows:&lt;br /&gt;
* /theme/excitement/pix/screenshot.jpg&lt;br /&gt;
* /theme/excitement/pix/favicon.ico&lt;br /&gt;
&lt;br /&gt;
In the case of my theme I have taken a screenshot and added it to that directory, and because I don&#039;t really want to do anything special with the favicon I have copied it from /theme/base/pix/favicon.ico so that at least it will be recognisable as Moodle.&lt;br /&gt;
&lt;br /&gt;
[[es:Desarollo:Temas 2.0 creando tu primer tema]]&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Creating_a_theme&amp;diff=47615</id>
		<title>Creating a theme</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Creating_a_theme&amp;diff=47615"/>
		<updated>2015-04-20T16:55:21Z</updated>

		<summary type="html">&lt;p&gt;Tqr: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}{{Moodle 2.0}}{{Moodle 2.1}}This document describes how to create a theme for Moodle 2.0 and Moodle 2.1. ONLY. It assumes you have some understanding of how themes within Moodle work as well as a good understanding of HTML and CSS.&lt;br /&gt;
&lt;br /&gt;
For Themes in Moodle 2.2 onwards please read the tutorial about [https://docs.moodle.org/dev/Themes_2.2_how_to_clone_a_Moodle_2.2_theme| How to clone a Moodle 2.2 theme]. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Theme designer mode===&lt;br /&gt;
&lt;br /&gt;
Under normal operation Moodle does several things in the name of performance, one of these is to combine all of the CSS into one file, minimize it, cache it on the server, and then serve it. After the first request the cached version is served to greatly improve page performance. &lt;br /&gt;
&lt;br /&gt;
What this means for you as a themer? When you make changes they will not be seen immediately. In fact you will need to tell Moodle to rebuild the cache that it is serving.&lt;br /&gt;
This isn&#039;t practical for designing themes of course so the &#039;&#039;&#039;theme designer mode&#039;&#039;&#039; was added. When enabled it tells Moodle not to combine or cache the CSS that gets delivered. This has the downside that page load times will take significantly longer, however you will see your changes immediately every time.&lt;br /&gt;
&lt;br /&gt;
Theme designer mode may be enabled via &#039;&#039;Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; [[Theme settings]]&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warning&#039;&#039;&#039;: Internet Explorer versions 6 and 7 have BIG problems when a site attempts to link to more than 31 stylesheets, in which case either a limited number or no styles get applied. Because Moodle sends up all of the CSS all of the time with theme designer mode turned on there is a very high chance you will get more than 31 stylesheets being included. This will, of course, cause major problems for Internet Explorer until theme designer mode is turned off.&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
The first thing you need to do is create the directories and files you will be using, the first thing to create is the actual directory for your theme. This should be the name of your theme, in my case it&#039;s &#039;excitement&#039;. The directory should be located within the theme directory of Moodle, ./moodle/theme/excitement/ will be the directory I create.&lt;br /&gt;
&lt;br /&gt;
Now within that directory we can immediately create several files that we know we are going to need. &lt;br /&gt;
&lt;br /&gt;
So the files that we want to create are:&lt;br /&gt;
; config.php :  All of our settings will go here.&lt;br /&gt;
; /style/ : This directory will contain all of our stylesheets.&lt;br /&gt;
; /style/excitement.css : All of our css will go in here.&lt;br /&gt;
; /pix/ : Into this directory we&#039;ll put a screen shot of our theme as well as our favicon and any images we use in CSS.&lt;br /&gt;
; /layout/ : Our layout files will end up in this directory.&lt;br /&gt;
; /layout/standard.php : This will be our one basic layout file.&lt;br /&gt;
; /lang/en/ : The file we put here will make our theme name show properly on the Theme Selector page. You need a few standard entries. Copy the one from the Standard theme and modify is easiest. &lt;br /&gt;
&lt;br /&gt;
So after this setup step you should have a directory structure similar to what is shown below.&lt;br /&gt;
&lt;br /&gt;
[[image:Learn_to_theme_01.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Configuring our theme==&lt;br /&gt;
&lt;br /&gt;
Open config.php in your favourite editor and start by adding the opening PHP tags &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;&amp;lt;?php&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Now we need to add the settings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;name = &#039;excitement&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Very simply this tells Moodle the name of your theme, and if you ever have several config.php files open this will help you identify which one you are looking at.&lt;br /&gt;
&lt;br /&gt;
Next, the parents for this theme.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;base&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This tells Moodle that my new theme &#039;&#039;`excitement`&#039; wants to extend the base theme. &lt;br /&gt;
&lt;br /&gt;
A theme can extend any number of themes. Rather than creating an entirely new theme and copying all of the CSS, you can simply create a new theme, extend the theme you like and just add the changes you want to your theme. &lt;br /&gt;
&lt;br /&gt;
Also worth noting is the purpose of the base theme: it provides us with a basic layout and just enough CSS to make everything fall into place.&lt;br /&gt;
&lt;br /&gt;
Now we will tell Moodle about our stylesheets:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;excitement&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final thing we need to add into our theme&#039;s config.php file is the definition of the layouts for our theme:&lt;br /&gt;
(in the code below, replace &#039;general.php&#039; with &#039;standard.php&#039; because that is the file that is previously created)&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Most backwards compatible layout without the blocks - this is the layout used by default&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&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;
    // 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;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-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // Main course page&lt;br /&gt;
    &#039;course&#039; =&amp;gt; array(&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-pre&#039;,&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;coursecategory&#039; =&amp;gt; array(&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-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // part of course, typical for modules - default page layout if $cm specified in require_login()&lt;br /&gt;
    &#039;incourse&#039; =&amp;gt; array(&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-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // The site home page.&lt;br /&gt;
    &#039;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;frontpage.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-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // Server administration scripts.&lt;br /&gt;
    &#039;admin&#039; =&amp;gt; array(&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;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // My dashboard page&lt;br /&gt;
    &#039;mydashboard&#039; =&amp;gt; array(&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-pre&#039;,&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // My public page&lt;br /&gt;
    &#039;mypublic&#039; =&amp;gt; array(&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-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;login&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    // Pages that appear in pop-up windows - no navigation, no blocks, no header.&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true, &#039;nologininfo&#039;=&amp;gt;true, &#039;nocourseheaderfooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // No blocks and minimal footer - used for legacy frame layouts only!&lt;br /&gt;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nocoursefooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible&lt;br /&gt;
    &#039;embedded&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true, &#039;nocourseheaderfooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Used during upgrade and install, and for the &#039;This site is undergoing maintenance&#039; message.&lt;br /&gt;
    // This must not have any blocks, and it is good idea if it does not have links to&lt;br /&gt;
    // other places - for example there should not be a home link in the footer...&lt;br /&gt;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true, &#039;nocourseheaderfooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Should display the content and basic headers only.&lt;br /&gt;
    &#039;print&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;false, &#039;nocustommenu&#039;=&amp;gt;true, &#039;nocourseheaderfooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // The pagelayout used when a redirection is occuring.&lt;br /&gt;
    &#039;redirect&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true, &#039;nocourseheaderfooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // The pagelayout used for reports.&lt;br /&gt;
    &#039;report&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;report.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // The pagelayout used for safebrowser and securewindow.&lt;br /&gt;
    &#039;secure&#039; =&amp;gt; array(&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-pre&#039;,&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true, &#039;nologinlinks&#039;=&amp;gt;true, &#039;nocourseheaderfooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** List of javascript files that need to be included on each page */&lt;br /&gt;
$THEME-&amp;gt;javascripts = array();&lt;br /&gt;
$THEME-&amp;gt;javascripts_footer = array();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you are looking at is the different layouts for our theme. Why are there so many? Because, that is how many there are in Moodle. There is one for every general type of page. With my &#039;&#039;`excitement`&#039;&#039; theme I have chosen to use my own layout. Unless there was a specific reason to do so, normally you would not need to create your own layouts, you could extend the base theme, and use its layouts, meaning you would only have to write CSS to achieve your desired look.&lt;br /&gt;
&lt;br /&gt;
For each layout above, you will notice the following four things are being set:&lt;br /&gt;
; file : This is the name of the layout file we want to use, it should always be located in the above themes layout directory. For us this is of course standard.php as we only have one layout file.&lt;br /&gt;
; regions : This is an array of block regions that our theme has. Each entry in here can be used to put blocks in when that layout is being used.&lt;br /&gt;
; defaultregion : If a layout has regions it should have a default region, this is where blocks get put when first added. It is also where the &amp;quot;add block&amp;quot; block is shown when editing is on.&lt;br /&gt;
; options : These are special settings, anything that gets put into the options array is available later on when we are writing our layout file.&lt;br /&gt;
&lt;br /&gt;
There are additional settings that can be defined in the config.php file - see [[Themes 2.0|Themes 2.0]] for the full list.&lt;br /&gt;
&lt;br /&gt;
==Configuring the language file==&lt;br /&gt;
Open theme_base.php file from &#039;&#039;&#039;base/lang/en/theme_base.php&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Save it as &#039;&#039;&#039;excitement/lang/en/theme_excitement.php&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Change &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;Base&#039;; &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
to&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;Excitement&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After making these changes and perhaps clearing theme caches and/or purging all caches, the new theme name should now show properly in the Theme Selector: &#039;&#039;Site Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; Theme Selector&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can also edit the theme description:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;choosereadme&#039;] = &#039;Write your theme description here.&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You need to leave the following two lines in place (you can change the wording if you need to) to avoid notices when editing blocks etc.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;region-side-post&#039;] = &#039;Right&#039;;&lt;br /&gt;
$string[&#039;region-side-pre&#039;] = &#039;Left&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Writing the layout file==&lt;br /&gt;
&lt;br /&gt;
The excitement theme has just one layout file.&lt;br /&gt;
&lt;br /&gt;
The downside of this is that I have to make the layout file do everything I want which means I need to make use of some options (as defined in the layouts in config.php). &lt;br /&gt;
&lt;br /&gt;
The upside is that I only need to maintain one file. &lt;br /&gt;
&lt;br /&gt;
Other than maintenance, using multiple layout files provides many advantages to real world themes in that you can easily tweak and customise specific layouts to achieve the goals of the organisation using the theme.&lt;br /&gt;
&lt;br /&gt;
Before learning more it is good to understand the two primary objects that will be used in your layout files: $OUTPUT and $PAGE.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;$OUTPUT&#039;&#039;&#039; is an instance of the &amp;lt;code&amp;gt;core_renderer&amp;lt;/code&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;$PAGE&#039;&#039;&#039; is an instance of the &amp;lt;code&amp;gt;moodle_page&amp;lt;/code&amp;gt; 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-&amp;gt;activityname, just like fields of an ordinary PHP object. (However, behind the scenes the value you get is produced by calling a function. Also, you cannot change these values, they are &#039;&#039;&#039;read-only&#039;&#039;&#039;. However, you don&#039;t need to understand all that if you are just using these properties in your theme.)&lt;br /&gt;
&lt;br /&gt;
So lets start writing standard.php, the layout file for my &#039;&#039;`excitement`&#039;&#039; theme.&lt;br /&gt;
&lt;br /&gt;
===The top of the layout file===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$hassidepre = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-pre&#039;, $OUTPUT);&lt;br /&gt;
$hassidepost = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-post&#039;, $OUTPUT);&lt;br /&gt;
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;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lets look at the code that goes into this section:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
echo $OUTPUT-&amp;gt;doctype(); ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is very important and is required to go at the very top of the page. This tells Moodle to print out the document type tag that is determined by the settings within Moodle.&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 open the HTML tag and then ask Moodle to print the attributes that should go inside it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&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;/code&amp;gt;&lt;br /&gt;
Simply creates the title tag and asks Moodle to fill it in.&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;
Here we are asking Moodle to print all of the other tags and content that need to go into the head. This includes stylesheets, script tags, and inline JavaScript code.&lt;br /&gt;
&lt;br /&gt;
===The page header===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php p($PAGE-&amp;gt;bodyid); ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php p($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;div id=&amp;quot;page&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading || (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar())) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-header&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;?php if ($PAGE-&amp;gt;heading) { ?&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&lt;br /&gt;
                if (method_exists($OUTPUT, &#039;user_menu&#039;)) {&lt;br /&gt;
                  echo $OUTPUT-&amp;gt;user_menu(); // user menu, for Moodle 2.8&lt;br /&gt;
                } else {&lt;br /&gt;
                  echo $OUTPUT-&amp;gt;login_info(); // login_info, Moodle 2.7 and before&lt;br /&gt;
                }&lt;br /&gt;
                if (!empty($PAGE-&amp;gt;layout_options[&#039;langmenu&#039;])) {&lt;br /&gt;
                    echo $OUTPUT-&amp;gt;lang_menu();&lt;br /&gt;
                }&lt;br /&gt;
                echo $PAGE-&amp;gt;headingmenu&lt;br /&gt;
            ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
        &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar()) { ?&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;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So there is a bit more going on here obviously.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php p($PAGE-&amp;gt;bodyid); ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php p($PAGE-&amp;gt;bodyclasses); ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Again much like what we did for the opening HTML tag in the head we have started writing the opening body tag and are then asking Moodle to give us the ID we should use for the body tag as well as the classes we should use.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_top_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This very important call writes some critical bits of JavaScript into the page. It should always be located after the body tag as soon as possible.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading || (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar())) { ?&amp;gt;&lt;br /&gt;
......&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are checking whether or not we need to print the header for the page. There are three checks we need to make here:&lt;br /&gt;
# &#039;&#039;&#039;$PAGE-&amp;gt;heading&#039;&#039;&#039; : This checks to make sure that there is a heading for the page. This will have been set by the script and normally describes the page in a couple of words.&lt;br /&gt;
# &#039;&#039;&#039;empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;])&#039;&#039;&#039; : Now this check is looking at the layout options that we set in our config.php file. It is looking to see if the layout set &#039;nonavbar&#039; =&amp;gt; true.&lt;br /&gt;
# &#039;&#039;&#039;$PAGE-&amp;gt;has_navbar()&#039;&#039;&#039; The third check is to check with the page whether it has a navigation bar to display.&lt;br /&gt;
If either there is a heading for this page or there is a navigation bar to display then we will display a heading.&lt;br /&gt;
&lt;br /&gt;
Leading on from this lets assume that there is a header to print.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading) { ?&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;
    .....&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This line is simply saying if the page has a heading print it. In this case we run the first check above again just to make sure there is a heading, we then open a heading tag that we choose and ask the page to print the heading.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;headermenu&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
    if (method_exists($OUTPUT, &#039;user_menu&#039;)) {&lt;br /&gt;
      echo $OUTPUT-&amp;gt;user_menu(); // user menu, for Moodle 2.8&lt;br /&gt;
    } else {&lt;br /&gt;
      echo $OUTPUT-&amp;gt;login_info(); // login_info, Moodle 2.7 and before&lt;br /&gt;
    }&lt;br /&gt;
    if (!empty($PAGE-&amp;gt;layout_options[&#039;langmenu&#039;])) {&lt;br /&gt;
        echo $OUTPUT-&amp;gt;lang_menu();&lt;br /&gt;
    }&lt;br /&gt;
    echo $PAGE-&amp;gt;headingmenu&lt;br /&gt;
?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are looking to print the menu and content that you see at the top of the page (usually to the right). We start by getting Moodle to print the login information for the current user. If the user is logged in this will be their name and a link to their profile, if not then it will be a link to login. Note that on Moodle 2.8 and above, a new user menu renderable is available that visually shows the same information as the login info renderable, as well as a dropdown menu with user-centric actions.&lt;br /&gt;
&lt;br /&gt;
Next we check our page options to see whether a language menu should be printed. If in the layout definition within config.php it sets &#039;&#039;&#039;langmenu =&amp;gt; true&#039;&#039;&#039; then we will print the language menu, a drop down box that lets the user change the language that Moodle displays in.&lt;br /&gt;
&lt;br /&gt;
Finally the page also has a heading menu that can be printed. This heading menu is special HTML that the page you are viewing wants to add. It can be anything from drop down boxes to buttons and any number of each.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar()) { ?&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;
The final part of the header.&lt;br /&gt;
&lt;br /&gt;
Here we want to print the navigation bar for the page if there is one. To find out if there is one we run checks number 2 and 3 again and proceed if they pass.&lt;br /&gt;
&lt;br /&gt;
Assuming there is a header then there are two things that we need to print. The first is the navigation bar. This is a component that the OUTPUT library knows about. The second is a button to show on the page.&lt;br /&gt;
&lt;br /&gt;
In both cases we choose to wrap them in a div tag with a class attribute to enable theming on those elements.&lt;br /&gt;
&lt;br /&gt;
Well that is it for the header. There is a lot of PHP compared to the other sections of the layout file but it does not change and can be copied and pasted between themes.&lt;br /&gt;
&lt;br /&gt;
===The page content===&lt;br /&gt;
&lt;br /&gt;
I am going with the default two block regions plus the main content.&lt;br /&gt;
&lt;br /&gt;
Because I have based this theme and layout file on the base theme the HTML looks a little intense. This is because it is a floating div layout where the content comes first and then we get the columns (even though one column will be to the left of the content.) Don&#039;t worry too much about it. When it comes to writing your own theme you can go about it as you choose.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;page-content&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;region-main-box&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div id=&amp;quot;region-post-box&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;div id=&amp;quot;region-main-wrap&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-main&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;?php if ($hassidepre) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-pre&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&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;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
                &lt;br /&gt;
                &amp;lt;?php if ($hassidepost) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-post&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&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;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In regards to PHP this section is very easy. There are only three lines for the whole section one to get the main content and one for each block region.&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 line prints the main content for the page.&lt;br /&gt;
PLEASE NOTE: In Moodle 2.2 onwards &amp;quot;core_renderer::MAIN_CONTENT_TOKEN&amp;quot; changed to &amp;quot;$OUTPUT-&amp;gt;main_content()&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($hassidepre) { ?&amp;gt;&lt;br /&gt;
....&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
These lines of code check the variables we created earlier on to decide whether we should show the pre block region. If you try to display a block region that isn&#039;t there or has no content then Moodle will give you an error message so these lines are very important.&lt;br /&gt;
&lt;br /&gt;
For those who get an error message if it is &amp;quot;unknown block region side-pre&amp;quot; or &amp;quot;unknown block region side-post&amp;quot; then this is the issue you are experiencing. Simply add the following lines and all will be fine.&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;
This line gets all of the blocks and more particularly the content for the block region &#039;&#039;&#039;side-pre&#039;&#039;&#039;. This block region will be displayed to the left of the content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($hassidepost) { ?&amp;gt;&lt;br /&gt;
....&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Again we should make this check for every block region as there are some pages that have no blocks what-so-ever.&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 are getting the other block region &#039;&#039;&#039;side-post&#039;&#039;&#039; which will be displayed to the right of the content.&lt;br /&gt;
&lt;br /&gt;
===The page footer===&lt;br /&gt;
Here we want to print the footer for the page, any content required by Moodle, and then close the last tags.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nofooter&#039;])) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot; class=&amp;quot;clearfix&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;/div&amp;gt;&lt;br /&gt;
    &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/div&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;
The section of code is responsible for printing the footer for the page.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nofooter&#039;])) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot; class=&amp;quot;clearfix&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;/div&amp;gt;&lt;br /&gt;
    &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The first thing we do before printing the footer is check that we actually want to print it. This is done by checking the options for the layout as defined in the config.php file. If &#039;&#039;&#039;nofooter =&amp;gt; true&#039;&#039;&#039; is set the we don&#039;t want to print the footer and should skip over this body of code.&lt;br /&gt;
&lt;br /&gt;
Assuming we want to print a footer we proceed to create a div to house its content and then print the bits of the content that will make it up.&lt;br /&gt;
There are four things that the typical page footer will want to print:&lt;br /&gt;
; echo page_doc_link(get_string(&#039;moodledocslink&#039;)) : This will print a link to the Moodle.org help page for this particular page.&lt;br /&gt;
; echo $OUTPUT-&amp;gt;login_info(); : This is the same as at the top of the page and will print the login information for the current user.&lt;br /&gt;
; echo $OUTPUT-&amp;gt;home_link(); : This prints a link back to the Moodle home page for this site.&lt;br /&gt;
; echo $OUTPUT-&amp;gt;standard_footer_html(); : This prints special HTML that is determined by the settings for the site. Things such as performance information or debugging will be printed by this line if they are turned on.&lt;br /&gt;
&lt;br /&gt;
And the final line of code for our layout file is:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_end_of_body_html(); ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is one of the most important lines of code in the layout file. It asks Moodle to print any required content into the page, and there will likely be a lot although most of it will not be visual.&lt;br /&gt;
&lt;br /&gt;
It will instead be things such as inline scripts and JavaScript files required to go at the bottom of the page. If you forget this line its likely no JavaScript will work!&lt;br /&gt;
&lt;br /&gt;
We&#039;ve now written our layout file and it is all set to go. The complete source is below for reference. Remember if you want more practical examples simply look at the layout files located within the layout directory of other themes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$hassidepre = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-pre&#039;, $OUTPUT);&lt;br /&gt;
$hassidepost = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-post&#039;, $OUTPUT);&lt;br /&gt;
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;link rel=&amp;quot;shortcut icon&amp;quot; href=&amp;quot;&amp;lt;?php echo $OUTPUT-&amp;gt;pix_url(&#039;favicon&#039;, &#039;theme&#039;)?&amp;gt;&amp;quot; /&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;
&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php p($PAGE-&amp;gt;bodyid); ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php p($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;div id=&amp;quot;page&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading || (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar())) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-header&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;?php if ($PAGE-&amp;gt;heading) { ?&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&lt;br /&gt;
            echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
            if (!empty($PAGE-&amp;gt;layout_options[&#039;langmenu&#039;])) {&lt;br /&gt;
                echo $OUTPUT-&amp;gt;lang_menu();&lt;br /&gt;
            }&lt;br /&gt;
            echo $PAGE-&amp;gt;headingmenu&lt;br /&gt;
        ?&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
        &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar()) { ?&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;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-content&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div id=&amp;quot;region-main-box&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;div id=&amp;quot;region-post-box&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-main-wrap&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div id=&amp;quot;region-main&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                            &amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
                        &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php if ($hassidepre) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-pre&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&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;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
                &lt;br /&gt;
                &amp;lt;?php if ($hassidepost) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-post&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&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;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nofooter&#039;])) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot; class=&amp;quot;clearfix&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;/div&amp;gt;&lt;br /&gt;
    &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/div&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;
==Adding some CSS==&lt;br /&gt;
With config.php and standard.php both complete the theme is now usable and starting to look like a real theme, however if you change to it using the theme selector you will notice that it still lacks any style.&lt;br /&gt;
&lt;br /&gt;
This of course is where CSS comes in. When writing code Moodle developers are strongly encouraged to not use inline styles anywhere. This is fantastic for us as themers because there is nothing (or at least very little) in Moodle that cannot be styled using CSS.&lt;br /&gt;
&lt;br /&gt;
===Moodle CSS basics===&lt;br /&gt;
&lt;br /&gt;
In Moodle 2.0 all of the CSS for the whole of Moodle is delivered all of the time! This was done for performance reasons. Moodle now reads in all of the CSS, combines it into one file, shrinks it removing any white space, caches it, and then delivers it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What this means for you as a themer?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You will need to write good CSS that won&#039;t clash with any other CSS within Moodle.&lt;br /&gt;
&lt;br /&gt;
Moodle is so big and complex,there is no way to ensure that classes don&#039;t get reused. What we can control however is the classes and id that get added to the body tag for every page. When writing CSS it is highly encouraged to make full use of these body classes, using them will help ensure the CSS you write has the least chance of causing conflicts.&lt;br /&gt;
&lt;br /&gt;
You should also take the time to look at how the Moodle themes use CSS. Look at their use of the body classes and how they separate the CSS for the theme into separate files based on the region of Moodle it applies to.&lt;br /&gt;
&lt;br /&gt;
Check out [[Themes 2.0|Themes 2.0]] and [[CSS coding style]] for more information about writing good CSS.&lt;br /&gt;
&lt;br /&gt;
===Starting to write excitement.css===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
a {&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.addcoursebutton .singlebutton {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
h1.headermain {&lt;br /&gt;
    color: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
h2.main {&lt;br /&gt;
    border-bottom: 3px solid #013D6A;&lt;br /&gt;
    color: #013D6A;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
h2.headingblock {&lt;br /&gt;
    font-size: 18pt;&lt;br /&gt;
    margin-top: 0;&lt;br /&gt;
    background-color: #013D6A;&lt;br /&gt;
    color: #FFF;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#page-header {&lt;br /&gt;
    background-color: #013D6A;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#page-header .headermenu {&lt;br /&gt;
    color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#page-header .headermenu a {&lt;br /&gt;
    color: #FDFF2A;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.navbar {&lt;br /&gt;
    padding-left: 1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.breadcrumb li {&lt;br /&gt;
    color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.breadcrumb li a {&lt;br /&gt;
    color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block {&lt;br /&gt;
    background-color: #013D6A;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block .header .title {&lt;br /&gt;
    color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block .header .title .block_action input {&lt;br /&gt;
    background-color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block .content {&lt;br /&gt;
    border: 1px solid #000;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    background-color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block .content .block_tree p {&lt;br /&gt;
    font-size: 80%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_settings_navigation_tree .content .footer {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform {&lt;br /&gt;
    margin-left: 5%;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    font-size: 9pt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform #adminsearchquery {&lt;br /&gt;
    width: 95%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .calendar-controls a {&lt;br /&gt;
    color: #013D6A;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .minicalendar td {&lt;br /&gt;
    border-color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {&lt;br /&gt;
    color: #FFF;&lt;br /&gt;
    background-color: #013D6A;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .minicalendar .day a {&lt;br /&gt;
    color: #FFF000;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays th {&lt;br /&gt;
    border-width: 0;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #013D6A;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays abbr {&lt;br /&gt;
    border-width: 0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
[[image:Learn_to_theme_02.jpg|400px|thumb|Excitement theme screenshot]]&lt;br /&gt;
This isn&#039;t all of the CSS for the theme, but just enough to style the front page when the user is not logged in.&lt;br /&gt;
Remember this theme extends the base theme so there is already CSS for layout as well.&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
* The CSS is laid out in a single line format. This is done within the core themes for Moodle. It makes it quicker to read the selectors and see what is being styled.&lt;br /&gt;
* I have written my selectors to take into account the structure of the HTML (more than just the one tag I want to style). This helps further to reduce the conflicts that I may encounter.&lt;br /&gt;
* I use generic classes like &#039;&#039;.sideblock&#039;&#039; only where I want to be generic, as soon as I want to be specific I use the unique classes such as &#039;&#039;.block_calendar_month&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:right;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Using images within CSS===&lt;br /&gt;
&lt;br /&gt;
I will add two image files to the pix directory of my theme:&lt;br /&gt;
; /theme/excitement/pix/background.png : This will be the background image for my theme.&lt;br /&gt;
; /theme/excitement/pix/gradient.jpg : This will be a gradient I use for the header and headings.&lt;br /&gt;
I quickly created both of these images using gimp and simply saved them to the pix directory.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
html {&lt;br /&gt;
    background-image: url([[pix:theme|background]]);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
h2.headingblock,&lt;br /&gt;
#page-header,&lt;br /&gt;
.sideblock,&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {&lt;br /&gt;
    background-image: url([[pix:theme|gradient]]);&lt;br /&gt;
    background-repeat: repeat-x;&lt;br /&gt;
    background-color: #0273C8;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
[[image:Learn_to_theme_03.jpg‎|400px|thumb|Excitement theme screenshot]]&lt;br /&gt;
The CSS above is the two new rules that I had to write to use my images within CSS.&lt;br /&gt;
&lt;br /&gt;
The first rule sets the background image for the page to background.png&lt;br /&gt;
&lt;br /&gt;
The second rule sets the background for headings, and the sideblocks to use gradient.jpg&lt;br /&gt;
&lt;br /&gt;
You will notice that I did not need to write a path to the image. This is because Moodle has this special syntax that can be used and will be replaced when the CSS is parsed before delivery.&lt;br /&gt;
The advantage of using this syntax over writing the path in is that the path may change depending on where you are or what theme is being used.&lt;br /&gt;
&lt;br /&gt;
Other themers may choose to extend your theme with their own; if you use this syntax then all they need to do to override the image is to create one with the same name in their themes directory.&lt;br /&gt;
&lt;br /&gt;
You will also notice that I don&#039;t need to add the image files extension. This is because Moodle is smart enough to work out what extension the file uses. It also allows themers to override images with different formats.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:right&amp;quot; /&amp;gt;&lt;br /&gt;
The following is the complete CSS for my theme:&lt;br /&gt;
&amp;lt;div style=&amp;quot;overflow:auto;height:860px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
a {text-decoration: none;}&lt;br /&gt;
.addcoursebutton .singlebutton {text-align: center;}&lt;br /&gt;
&lt;br /&gt;
h1.headermain {color: #fff;}&lt;br /&gt;
h2.main {border-bottom: 3px solid #013D6A;color: #013D6A;text-align: center;}&lt;br /&gt;
h2.headingblock {font-size: 18pt;margin-top: 0;background-color: #013D6A;color: #FFF;text-align: center;}&lt;br /&gt;
#page-header {background-color: #013D6A;border-bottom:5px solid #013D6A;}&lt;br /&gt;
#page-header .headermenu  {color: #FFF;}&lt;br /&gt;
#page-header .headermenu a {color: #FDFF2A;}&lt;br /&gt;
&lt;br /&gt;
.sideblock {background-color: #013D6A;}&lt;br /&gt;
.sideblock .header .title {color: #FFF;}&lt;br /&gt;
.sideblock .header .title .block_action input {background-color: #FFF;}&lt;br /&gt;
.sideblock .content {border: 1px solid #000;padding: 5px;background-color: #FFF;}&lt;br /&gt;
.sideblock .content .block_tree p {font-size: 80%;}&lt;br /&gt;
&lt;br /&gt;
.block_settings_navigation_tree .content .footer {text-align: center;}&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform {margin-left: 5%;width: 90%;font-size: 9pt;}&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform #adminsearchquery {width: 95%;}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .calendar-controls a {color: #013D6A;font-weight: bold;}&lt;br /&gt;
.block_calendar_month .content .minicalendar td {border-color: #FFF;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {color: #FFF;background-color: #013D6A;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .day a {color: #FFF000;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays th {border-width: 0;font-weight: bold;color: #013D6A;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays abbr {border-width: 0;text-decoration: none;}&lt;br /&gt;
&lt;br /&gt;
html {background-image:url([[pix:theme|background]]);}&lt;br /&gt;
&lt;br /&gt;
h2.headingblock,&lt;br /&gt;
#page-header,&lt;br /&gt;
.sideblock,&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {background-image:url([[pix:theme|gradient]]);&lt;br /&gt;
   background-repeat:repeat-x;background-color: #0273C8;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adding a screenshot and favicon==&lt;br /&gt;
The final thing to do at this point is add both a screenshot for this theme as well as a favicon for it.&lt;br /&gt;
The screenshot will be shown in the theme selector screen and should be named &#039;&#039;screenshot.jpg&#039;&#039;.&lt;br /&gt;
The favicon will be used when someone bookmarks this page.&lt;br /&gt;
Both images should be located in your themes pix directory as follows:&lt;br /&gt;
* /theme/excitement/pix/screenshot.jpg&lt;br /&gt;
* /theme/excitement/pix/favicon.ico&lt;br /&gt;
&lt;br /&gt;
In the case of my theme I have taken a screenshot and added it to that directory, and because I don&#039;t really want to do anything special with the favicon I have copied it from /theme/base/pix/favicon.ico so that at least it will be recognisable as Moodle.&lt;br /&gt;
&lt;br /&gt;
[[es:Desarollo:Temas 2.0 creando tu primer tema]]&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Creating_a_theme&amp;diff=47614</id>
		<title>Creating a theme</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Creating_a_theme&amp;diff=47614"/>
		<updated>2015-04-20T16:52:10Z</updated>

		<summary type="html">&lt;p&gt;Tqr: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}This document describes how to create a theme for Moodle 2.0 and Moodle 2.1. It assumes you have some understanding of how themes within Moodle work as well as a good understanding of HTML and CSS.&lt;br /&gt;
&lt;br /&gt;
For Themes in Moodle 2.2 onwards please read the tutorial about [https://docs.moodle.org/dev/Themes_2.2_how_to_clone_a_Moodle_2.2_theme | How to clone a Moodle 2.2 theme]. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Theme designer mode===&lt;br /&gt;
&lt;br /&gt;
Under normal operation Moodle does several things in the name of performance, one of these is to combine all of the CSS into one file, minimize it, cache it on the server, and then serve it. After the first request the cached version is served to greatly improve page performance. &lt;br /&gt;
&lt;br /&gt;
What this means for you as a themer? When you make changes they will not be seen immediately. In fact you will need to tell Moodle to rebuild the cache that it is serving.&lt;br /&gt;
This isn&#039;t practical for designing themes of course so the &#039;&#039;&#039;theme designer mode&#039;&#039;&#039; was added. When enabled it tells Moodle not to combine or cache the CSS that gets delivered. This has the downside that page load times will take significantly longer, however you will see your changes immediately every time.&lt;br /&gt;
&lt;br /&gt;
Theme designer mode may be enabled via &#039;&#039;Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; [[Theme settings]]&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warning&#039;&#039;&#039;: Internet Explorer versions 6 and 7 have BIG problems when a site attempts to link to more than 31 stylesheets, in which case either a limited number or no styles get applied. Because Moodle sends up all of the CSS all of the time with theme designer mode turned on there is a very high chance you will get more than 31 stylesheets being included. This will, of course, cause major problems for Internet Explorer until theme designer mode is turned off.&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
The first thing you need to do is create the directories and files you will be using, the first thing to create is the actual directory for your theme. This should be the name of your theme, in my case it&#039;s &#039;excitement&#039;. The directory should be located within the theme directory of Moodle, ./moodle/theme/excitement/ will be the directory I create.&lt;br /&gt;
&lt;br /&gt;
Now within that directory we can immediately create several files that we know we are going to need. &lt;br /&gt;
&lt;br /&gt;
So the files that we want to create are:&lt;br /&gt;
; config.php :  All of our settings will go here.&lt;br /&gt;
; /style/ : This directory will contain all of our stylesheets.&lt;br /&gt;
; /style/excitement.css : All of our css will go in here.&lt;br /&gt;
; /pix/ : Into this directory we&#039;ll put a screen shot of our theme as well as our favicon and any images we use in CSS.&lt;br /&gt;
; /layout/ : Our layout files will end up in this directory.&lt;br /&gt;
; /layout/standard.php : This will be our one basic layout file.&lt;br /&gt;
; /lang/en/ : The file we put here will make our theme name show properly on the Theme Selector page. You need a few standard entries. Copy the one from the Standard theme and modify is easiest. &lt;br /&gt;
&lt;br /&gt;
So after this setup step you should have a directory structure similar to what is shown below.&lt;br /&gt;
&lt;br /&gt;
[[image:Learn_to_theme_01.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Configuring our theme==&lt;br /&gt;
&lt;br /&gt;
Open config.php in your favourite editor and start by adding the opening PHP tags &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;&amp;lt;?php&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Now we need to add the settings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;name = &#039;excitement&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Very simply this tells Moodle the name of your theme, and if you ever have several config.php files open this will help you identify which one you are looking at.&lt;br /&gt;
&lt;br /&gt;
Next, the parents for this theme.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;base&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This tells Moodle that my new theme &#039;&#039;`excitement`&#039; wants to extend the base theme. &lt;br /&gt;
&lt;br /&gt;
A theme can extend any number of themes. Rather than creating an entirely new theme and copying all of the CSS, you can simply create a new theme, extend the theme you like and just add the changes you want to your theme. &lt;br /&gt;
&lt;br /&gt;
Also worth noting is the purpose of the base theme: it provides us with a basic layout and just enough CSS to make everything fall into place.&lt;br /&gt;
&lt;br /&gt;
Now we will tell Moodle about our stylesheets:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;excitement&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final thing we need to add into our theme&#039;s config.php file is the definition of the layouts for our theme:&lt;br /&gt;
(in the code below, replace &#039;general.php&#039; with &#039;standard.php&#039; because that is the file that is previously created)&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Most backwards compatible layout without the blocks - this is the layout used by default&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&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;
    // 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;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-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // Main course page&lt;br /&gt;
    &#039;course&#039; =&amp;gt; array(&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-pre&#039;,&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;coursecategory&#039; =&amp;gt; array(&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-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // part of course, typical for modules - default page layout if $cm specified in require_login()&lt;br /&gt;
    &#039;incourse&#039; =&amp;gt; array(&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-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // The site home page.&lt;br /&gt;
    &#039;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;frontpage.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-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // Server administration scripts.&lt;br /&gt;
    &#039;admin&#039; =&amp;gt; array(&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;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // My dashboard page&lt;br /&gt;
    &#039;mydashboard&#039; =&amp;gt; array(&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-pre&#039;,&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // My public page&lt;br /&gt;
    &#039;mypublic&#039; =&amp;gt; array(&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-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;login&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    // Pages that appear in pop-up windows - no navigation, no blocks, no header.&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true, &#039;nologininfo&#039;=&amp;gt;true, &#039;nocourseheaderfooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // No blocks and minimal footer - used for legacy frame layouts only!&lt;br /&gt;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nocoursefooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible&lt;br /&gt;
    &#039;embedded&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true, &#039;nocourseheaderfooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Used during upgrade and install, and for the &#039;This site is undergoing maintenance&#039; message.&lt;br /&gt;
    // This must not have any blocks, and it is good idea if it does not have links to&lt;br /&gt;
    // other places - for example there should not be a home link in the footer...&lt;br /&gt;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true, &#039;nocourseheaderfooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Should display the content and basic headers only.&lt;br /&gt;
    &#039;print&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;false, &#039;nocustommenu&#039;=&amp;gt;true, &#039;nocourseheaderfooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // The pagelayout used when a redirection is occuring.&lt;br /&gt;
    &#039;redirect&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true, &#039;nocourseheaderfooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // The pagelayout used for reports.&lt;br /&gt;
    &#039;report&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;report.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // The pagelayout used for safebrowser and securewindow.&lt;br /&gt;
    &#039;secure&#039; =&amp;gt; array(&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-pre&#039;,&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true, &#039;nologinlinks&#039;=&amp;gt;true, &#039;nocourseheaderfooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** List of javascript files that need to be included on each page */&lt;br /&gt;
$THEME-&amp;gt;javascripts = array();&lt;br /&gt;
$THEME-&amp;gt;javascripts_footer = array();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you are looking at is the different layouts for our theme. Why are there so many? Because, that is how many there are in Moodle. There is one for every general type of page. With my &#039;&#039;`excitement`&#039;&#039; theme I have chosen to use my own layout. Unless there was a specific reason to do so, normally you would not need to create your own layouts, you could extend the base theme, and use its layouts, meaning you would only have to write CSS to achieve your desired look.&lt;br /&gt;
&lt;br /&gt;
For each layout above, you will notice the following four things are being set:&lt;br /&gt;
; file : This is the name of the layout file we want to use, it should always be located in the above themes layout directory. For us this is of course standard.php as we only have one layout file.&lt;br /&gt;
; regions : This is an array of block regions that our theme has. Each entry in here can be used to put blocks in when that layout is being used.&lt;br /&gt;
; defaultregion : If a layout has regions it should have a default region, this is where blocks get put when first added. It is also where the &amp;quot;add block&amp;quot; block is shown when editing is on.&lt;br /&gt;
; options : These are special settings, anything that gets put into the options array is available later on when we are writing our layout file.&lt;br /&gt;
&lt;br /&gt;
There are additional settings that can be defined in the config.php file - see [[Themes 2.0|Themes 2.0]] for the full list.&lt;br /&gt;
&lt;br /&gt;
==Configuring the language file==&lt;br /&gt;
Open theme_base.php file from &#039;&#039;&#039;base/lang/en/theme_base.php&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Save it as &#039;&#039;&#039;excitement/lang/en/theme_excitement.php&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Change &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;Base&#039;; &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
to&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;Excitement&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After making these changes and perhaps clearing theme caches and/or purging all caches, the new theme name should now show properly in the Theme Selector: &#039;&#039;Site Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; Theme Selector&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can also edit the theme description:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;choosereadme&#039;] = &#039;Write your theme description here.&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You need to leave the following two lines in place (you can change the wording if you need to) to avoid notices when editing blocks etc.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;region-side-post&#039;] = &#039;Right&#039;;&lt;br /&gt;
$string[&#039;region-side-pre&#039;] = &#039;Left&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Writing the layout file==&lt;br /&gt;
&lt;br /&gt;
The excitement theme has just one layout file.&lt;br /&gt;
&lt;br /&gt;
The downside of this is that I have to make the layout file do everything I want which means I need to make use of some options (as defined in the layouts in config.php). &lt;br /&gt;
&lt;br /&gt;
The upside is that I only need to maintain one file. &lt;br /&gt;
&lt;br /&gt;
Other than maintenance, using multiple layout files provides many advantages to real world themes in that you can easily tweak and customise specific layouts to achieve the goals of the organisation using the theme.&lt;br /&gt;
&lt;br /&gt;
Before learning more it is good to understand the two primary objects that will be used in your layout files: $OUTPUT and $PAGE.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;$OUTPUT&#039;&#039;&#039; is an instance of the &amp;lt;code&amp;gt;core_renderer&amp;lt;/code&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;$PAGE&#039;&#039;&#039; is an instance of the &amp;lt;code&amp;gt;moodle_page&amp;lt;/code&amp;gt; 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-&amp;gt;activityname, just like fields of an ordinary PHP object. (However, behind the scenes the value you get is produced by calling a function. Also, you cannot change these values, they are &#039;&#039;&#039;read-only&#039;&#039;&#039;. However, you don&#039;t need to understand all that if you are just using these properties in your theme.)&lt;br /&gt;
&lt;br /&gt;
So lets start writing standard.php, the layout file for my &#039;&#039;`excitement`&#039;&#039; theme.&lt;br /&gt;
&lt;br /&gt;
===The top of the layout file===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$hassidepre = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-pre&#039;, $OUTPUT);&lt;br /&gt;
$hassidepost = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-post&#039;, $OUTPUT);&lt;br /&gt;
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;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lets look at the code that goes into this section:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
echo $OUTPUT-&amp;gt;doctype(); ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is very important and is required to go at the very top of the page. This tells Moodle to print out the document type tag that is determined by the settings within Moodle.&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 open the HTML tag and then ask Moodle to print the attributes that should go inside it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&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;/code&amp;gt;&lt;br /&gt;
Simply creates the title tag and asks Moodle to fill it in.&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;
Here we are asking Moodle to print all of the other tags and content that need to go into the head. This includes stylesheets, script tags, and inline JavaScript code.&lt;br /&gt;
&lt;br /&gt;
===The page header===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php p($PAGE-&amp;gt;bodyid); ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php p($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;div id=&amp;quot;page&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading || (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar())) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-header&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;?php if ($PAGE-&amp;gt;heading) { ?&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&lt;br /&gt;
                if (method_exists($OUTPUT, &#039;user_menu&#039;)) {&lt;br /&gt;
                  echo $OUTPUT-&amp;gt;user_menu(); // user menu, for Moodle 2.8&lt;br /&gt;
                } else {&lt;br /&gt;
                  echo $OUTPUT-&amp;gt;login_info(); // login_info, Moodle 2.7 and before&lt;br /&gt;
                }&lt;br /&gt;
                if (!empty($PAGE-&amp;gt;layout_options[&#039;langmenu&#039;])) {&lt;br /&gt;
                    echo $OUTPUT-&amp;gt;lang_menu();&lt;br /&gt;
                }&lt;br /&gt;
                echo $PAGE-&amp;gt;headingmenu&lt;br /&gt;
            ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
        &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar()) { ?&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;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So there is a bit more going on here obviously.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php p($PAGE-&amp;gt;bodyid); ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php p($PAGE-&amp;gt;bodyclasses); ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Again much like what we did for the opening HTML tag in the head we have started writing the opening body tag and are then asking Moodle to give us the ID we should use for the body tag as well as the classes we should use.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_top_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This very important call writes some critical bits of JavaScript into the page. It should always be located after the body tag as soon as possible.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading || (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar())) { ?&amp;gt;&lt;br /&gt;
......&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are checking whether or not we need to print the header for the page. There are three checks we need to make here:&lt;br /&gt;
# &#039;&#039;&#039;$PAGE-&amp;gt;heading&#039;&#039;&#039; : This checks to make sure that there is a heading for the page. This will have been set by the script and normally describes the page in a couple of words.&lt;br /&gt;
# &#039;&#039;&#039;empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;])&#039;&#039;&#039; : Now this check is looking at the layout options that we set in our config.php file. It is looking to see if the layout set &#039;nonavbar&#039; =&amp;gt; true.&lt;br /&gt;
# &#039;&#039;&#039;$PAGE-&amp;gt;has_navbar()&#039;&#039;&#039; The third check is to check with the page whether it has a navigation bar to display.&lt;br /&gt;
If either there is a heading for this page or there is a navigation bar to display then we will display a heading.&lt;br /&gt;
&lt;br /&gt;
Leading on from this lets assume that there is a header to print.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading) { ?&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;
    .....&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This line is simply saying if the page has a heading print it. In this case we run the first check above again just to make sure there is a heading, we then open a heading tag that we choose and ask the page to print the heading.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;headermenu&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
    if (method_exists($OUTPUT, &#039;user_menu&#039;)) {&lt;br /&gt;
      echo $OUTPUT-&amp;gt;user_menu(); // user menu, for Moodle 2.8&lt;br /&gt;
    } else {&lt;br /&gt;
      echo $OUTPUT-&amp;gt;login_info(); // login_info, Moodle 2.7 and before&lt;br /&gt;
    }&lt;br /&gt;
    if (!empty($PAGE-&amp;gt;layout_options[&#039;langmenu&#039;])) {&lt;br /&gt;
        echo $OUTPUT-&amp;gt;lang_menu();&lt;br /&gt;
    }&lt;br /&gt;
    echo $PAGE-&amp;gt;headingmenu&lt;br /&gt;
?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are looking to print the menu and content that you see at the top of the page (usually to the right). We start by getting Moodle to print the login information for the current user. If the user is logged in this will be their name and a link to their profile, if not then it will be a link to login. Note that on Moodle 2.8 and above, a new user menu renderable is available that visually shows the same information as the login info renderable, as well as a dropdown menu with user-centric actions.&lt;br /&gt;
&lt;br /&gt;
Next we check our page options to see whether a language menu should be printed. If in the layout definition within config.php it sets &#039;&#039;&#039;langmenu =&amp;gt; true&#039;&#039;&#039; then we will print the language menu, a drop down box that lets the user change the language that Moodle displays in.&lt;br /&gt;
&lt;br /&gt;
Finally the page also has a heading menu that can be printed. This heading menu is special HTML that the page you are viewing wants to add. It can be anything from drop down boxes to buttons and any number of each.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar()) { ?&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;
The final part of the header.&lt;br /&gt;
&lt;br /&gt;
Here we want to print the navigation bar for the page if there is one. To find out if there is one we run checks number 2 and 3 again and proceed if they pass.&lt;br /&gt;
&lt;br /&gt;
Assuming there is a header then there are two things that we need to print. The first is the navigation bar. This is a component that the OUTPUT library knows about. The second is a button to show on the page.&lt;br /&gt;
&lt;br /&gt;
In both cases we choose to wrap them in a div tag with a class attribute to enable theming on those elements.&lt;br /&gt;
&lt;br /&gt;
Well that is it for the header. There is a lot of PHP compared to the other sections of the layout file but it does not change and can be copied and pasted between themes.&lt;br /&gt;
&lt;br /&gt;
===The page content===&lt;br /&gt;
&lt;br /&gt;
I am going with the default two block regions plus the main content.&lt;br /&gt;
&lt;br /&gt;
Because I have based this theme and layout file on the base theme the HTML looks a little intense. This is because it is a floating div layout where the content comes first and then we get the columns (even though one column will be to the left of the content.) Don&#039;t worry too much about it. When it comes to writing your own theme you can go about it as you choose.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;page-content&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;region-main-box&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div id=&amp;quot;region-post-box&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;div id=&amp;quot;region-main-wrap&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-main&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;?php if ($hassidepre) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-pre&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&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;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
                &lt;br /&gt;
                &amp;lt;?php if ($hassidepost) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-post&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&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;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In regards to PHP this section is very easy. There are only three lines for the whole section one to get the main content and one for each block region.&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 line prints the main content for the page.&lt;br /&gt;
PLEASE NOTE: In Moodle 2.2 onwards &amp;quot;core_renderer::MAIN_CONTENT_TOKEN&amp;quot; changed to &amp;quot;$OUTPUT-&amp;gt;main_content()&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($hassidepre) { ?&amp;gt;&lt;br /&gt;
....&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
These lines of code check the variables we created earlier on to decide whether we should show the pre block region. If you try to display a block region that isn&#039;t there or has no content then Moodle will give you an error message so these lines are very important.&lt;br /&gt;
&lt;br /&gt;
For those who get an error message if it is &amp;quot;unknown block region side-pre&amp;quot; or &amp;quot;unknown block region side-post&amp;quot; then this is the issue you are experiencing. Simply add the following lines and all will be fine.&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;
This line gets all of the blocks and more particularly the content for the block region &#039;&#039;&#039;side-pre&#039;&#039;&#039;. This block region will be displayed to the left of the content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($hassidepost) { ?&amp;gt;&lt;br /&gt;
....&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Again we should make this check for every block region as there are some pages that have no blocks what-so-ever.&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 are getting the other block region &#039;&#039;&#039;side-post&#039;&#039;&#039; which will be displayed to the right of the content.&lt;br /&gt;
&lt;br /&gt;
===The page footer===&lt;br /&gt;
Here we want to print the footer for the page, any content required by Moodle, and then close the last tags.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nofooter&#039;])) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot; class=&amp;quot;clearfix&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;/div&amp;gt;&lt;br /&gt;
    &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/div&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;
The section of code is responsible for printing the footer for the page.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nofooter&#039;])) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot; class=&amp;quot;clearfix&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;/div&amp;gt;&lt;br /&gt;
    &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The first thing we do before printing the footer is check that we actually want to print it. This is done by checking the options for the layout as defined in the config.php file. If &#039;&#039;&#039;nofooter =&amp;gt; true&#039;&#039;&#039; is set the we don&#039;t want to print the footer and should skip over this body of code.&lt;br /&gt;
&lt;br /&gt;
Assuming we want to print a footer we proceed to create a div to house its content and then print the bits of the content that will make it up.&lt;br /&gt;
There are four things that the typical page footer will want to print:&lt;br /&gt;
; echo page_doc_link(get_string(&#039;moodledocslink&#039;)) : This will print a link to the Moodle.org help page for this particular page.&lt;br /&gt;
; echo $OUTPUT-&amp;gt;login_info(); : This is the same as at the top of the page and will print the login information for the current user.&lt;br /&gt;
; echo $OUTPUT-&amp;gt;home_link(); : This prints a link back to the Moodle home page for this site.&lt;br /&gt;
; echo $OUTPUT-&amp;gt;standard_footer_html(); : This prints special HTML that is determined by the settings for the site. Things such as performance information or debugging will be printed by this line if they are turned on.&lt;br /&gt;
&lt;br /&gt;
And the final line of code for our layout file is:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_end_of_body_html(); ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is one of the most important lines of code in the layout file. It asks Moodle to print any required content into the page, and there will likely be a lot although most of it will not be visual.&lt;br /&gt;
&lt;br /&gt;
It will instead be things such as inline scripts and JavaScript files required to go at the bottom of the page. If you forget this line its likely no JavaScript will work!&lt;br /&gt;
&lt;br /&gt;
We&#039;ve now written our layout file and it is all set to go. The complete source is below for reference. Remember if you want more practical examples simply look at the layout files located within the layout directory of other themes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$hassidepre = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-pre&#039;, $OUTPUT);&lt;br /&gt;
$hassidepost = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-post&#039;, $OUTPUT);&lt;br /&gt;
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;link rel=&amp;quot;shortcut icon&amp;quot; href=&amp;quot;&amp;lt;?php echo $OUTPUT-&amp;gt;pix_url(&#039;favicon&#039;, &#039;theme&#039;)?&amp;gt;&amp;quot; /&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;
&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php p($PAGE-&amp;gt;bodyid); ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php p($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;div id=&amp;quot;page&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading || (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar())) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-header&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;?php if ($PAGE-&amp;gt;heading) { ?&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&lt;br /&gt;
            echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
            if (!empty($PAGE-&amp;gt;layout_options[&#039;langmenu&#039;])) {&lt;br /&gt;
                echo $OUTPUT-&amp;gt;lang_menu();&lt;br /&gt;
            }&lt;br /&gt;
            echo $PAGE-&amp;gt;headingmenu&lt;br /&gt;
        ?&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
        &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar()) { ?&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;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-content&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div id=&amp;quot;region-main-box&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;div id=&amp;quot;region-post-box&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-main-wrap&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div id=&amp;quot;region-main&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                            &amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
                        &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php if ($hassidepre) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-pre&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&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;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
                &lt;br /&gt;
                &amp;lt;?php if ($hassidepost) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-post&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&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;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nofooter&#039;])) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot; class=&amp;quot;clearfix&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;/div&amp;gt;&lt;br /&gt;
    &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/div&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;
==Adding some CSS==&lt;br /&gt;
With config.php and standard.php both complete the theme is now usable and starting to look like a real theme, however if you change to it using the theme selector you will notice that it still lacks any style.&lt;br /&gt;
&lt;br /&gt;
This of course is where CSS comes in. When writing code Moodle developers are strongly encouraged to not use inline styles anywhere. This is fantastic for us as themers because there is nothing (or at least very little) in Moodle that cannot be styled using CSS.&lt;br /&gt;
&lt;br /&gt;
===Moodle CSS basics===&lt;br /&gt;
&lt;br /&gt;
In Moodle 2.0 all of the CSS for the whole of Moodle is delivered all of the time! This was done for performance reasons. Moodle now reads in all of the CSS, combines it into one file, shrinks it removing any white space, caches it, and then delivers it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What this means for you as a themer?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You will need to write good CSS that won&#039;t clash with any other CSS within Moodle.&lt;br /&gt;
&lt;br /&gt;
Moodle is so big and complex,there is no way to ensure that classes don&#039;t get reused. What we can control however is the classes and id that get added to the body tag for every page. When writing CSS it is highly encouraged to make full use of these body classes, using them will help ensure the CSS you write has the least chance of causing conflicts.&lt;br /&gt;
&lt;br /&gt;
You should also take the time to look at how the Moodle themes use CSS. Look at their use of the body classes and how they separate the CSS for the theme into separate files based on the region of Moodle it applies to.&lt;br /&gt;
&lt;br /&gt;
Check out [[Themes 2.0|Themes 2.0]] and [[CSS coding style]] for more information about writing good CSS.&lt;br /&gt;
&lt;br /&gt;
===Starting to write excitement.css===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
a {&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.addcoursebutton .singlebutton {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
h1.headermain {&lt;br /&gt;
    color: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
h2.main {&lt;br /&gt;
    border-bottom: 3px solid #013D6A;&lt;br /&gt;
    color: #013D6A;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
h2.headingblock {&lt;br /&gt;
    font-size: 18pt;&lt;br /&gt;
    margin-top: 0;&lt;br /&gt;
    background-color: #013D6A;&lt;br /&gt;
    color: #FFF;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#page-header {&lt;br /&gt;
    background-color: #013D6A;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#page-header .headermenu {&lt;br /&gt;
    color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#page-header .headermenu a {&lt;br /&gt;
    color: #FDFF2A;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.navbar {&lt;br /&gt;
    padding-left: 1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.breadcrumb li {&lt;br /&gt;
    color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.breadcrumb li a {&lt;br /&gt;
    color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block {&lt;br /&gt;
    background-color: #013D6A;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block .header .title {&lt;br /&gt;
    color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block .header .title .block_action input {&lt;br /&gt;
    background-color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block .content {&lt;br /&gt;
    border: 1px solid #000;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    background-color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block .content .block_tree p {&lt;br /&gt;
    font-size: 80%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_settings_navigation_tree .content .footer {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform {&lt;br /&gt;
    margin-left: 5%;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    font-size: 9pt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform #adminsearchquery {&lt;br /&gt;
    width: 95%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .calendar-controls a {&lt;br /&gt;
    color: #013D6A;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .minicalendar td {&lt;br /&gt;
    border-color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {&lt;br /&gt;
    color: #FFF;&lt;br /&gt;
    background-color: #013D6A;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .minicalendar .day a {&lt;br /&gt;
    color: #FFF000;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays th {&lt;br /&gt;
    border-width: 0;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #013D6A;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays abbr {&lt;br /&gt;
    border-width: 0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
[[image:Learn_to_theme_02.jpg|400px|thumb|Excitement theme screenshot]]&lt;br /&gt;
This isn&#039;t all of the CSS for the theme, but just enough to style the front page when the user is not logged in.&lt;br /&gt;
Remember this theme extends the base theme so there is already CSS for layout as well.&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
* The CSS is laid out in a single line format. This is done within the core themes for Moodle. It makes it quicker to read the selectors and see what is being styled.&lt;br /&gt;
* I have written my selectors to take into account the structure of the HTML (more than just the one tag I want to style). This helps further to reduce the conflicts that I may encounter.&lt;br /&gt;
* I use generic classes like &#039;&#039;.sideblock&#039;&#039; only where I want to be generic, as soon as I want to be specific I use the unique classes such as &#039;&#039;.block_calendar_month&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:right;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Using images within CSS===&lt;br /&gt;
&lt;br /&gt;
I will add two image files to the pix directory of my theme:&lt;br /&gt;
; /theme/excitement/pix/background.png : This will be the background image for my theme.&lt;br /&gt;
; /theme/excitement/pix/gradient.jpg : This will be a gradient I use for the header and headings.&lt;br /&gt;
I quickly created both of these images using gimp and simply saved them to the pix directory.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
html {&lt;br /&gt;
    background-image: url([[pix:theme|background]]);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
h2.headingblock,&lt;br /&gt;
#page-header,&lt;br /&gt;
.sideblock,&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {&lt;br /&gt;
    background-image: url([[pix:theme|gradient]]);&lt;br /&gt;
    background-repeat: repeat-x;&lt;br /&gt;
    background-color: #0273C8;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
[[image:Learn_to_theme_03.jpg‎|400px|thumb|Excitement theme screenshot]]&lt;br /&gt;
The CSS above is the two new rules that I had to write to use my images within CSS.&lt;br /&gt;
&lt;br /&gt;
The first rule sets the background image for the page to background.png&lt;br /&gt;
&lt;br /&gt;
The second rule sets the background for headings, and the sideblocks to use gradient.jpg&lt;br /&gt;
&lt;br /&gt;
You will notice that I did not need to write a path to the image. This is because Moodle has this special syntax that can be used and will be replaced when the CSS is parsed before delivery.&lt;br /&gt;
The advantage of using this syntax over writing the path in is that the path may change depending on where you are or what theme is being used.&lt;br /&gt;
&lt;br /&gt;
Other themers may choose to extend your theme with their own; if you use this syntax then all they need to do to override the image is to create one with the same name in their themes directory.&lt;br /&gt;
&lt;br /&gt;
You will also notice that I don&#039;t need to add the image files extension. This is because Moodle is smart enough to work out what extension the file uses. It also allows themers to override images with different formats.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:right&amp;quot; /&amp;gt;&lt;br /&gt;
The following is the complete CSS for my theme:&lt;br /&gt;
&amp;lt;div style=&amp;quot;overflow:auto;height:860px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
a {text-decoration: none;}&lt;br /&gt;
.addcoursebutton .singlebutton {text-align: center;}&lt;br /&gt;
&lt;br /&gt;
h1.headermain {color: #fff;}&lt;br /&gt;
h2.main {border-bottom: 3px solid #013D6A;color: #013D6A;text-align: center;}&lt;br /&gt;
h2.headingblock {font-size: 18pt;margin-top: 0;background-color: #013D6A;color: #FFF;text-align: center;}&lt;br /&gt;
#page-header {background-color: #013D6A;border-bottom:5px solid #013D6A;}&lt;br /&gt;
#page-header .headermenu  {color: #FFF;}&lt;br /&gt;
#page-header .headermenu a {color: #FDFF2A;}&lt;br /&gt;
&lt;br /&gt;
.sideblock {background-color: #013D6A;}&lt;br /&gt;
.sideblock .header .title {color: #FFF;}&lt;br /&gt;
.sideblock .header .title .block_action input {background-color: #FFF;}&lt;br /&gt;
.sideblock .content {border: 1px solid #000;padding: 5px;background-color: #FFF;}&lt;br /&gt;
.sideblock .content .block_tree p {font-size: 80%;}&lt;br /&gt;
&lt;br /&gt;
.block_settings_navigation_tree .content .footer {text-align: center;}&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform {margin-left: 5%;width: 90%;font-size: 9pt;}&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform #adminsearchquery {width: 95%;}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .calendar-controls a {color: #013D6A;font-weight: bold;}&lt;br /&gt;
.block_calendar_month .content .minicalendar td {border-color: #FFF;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {color: #FFF;background-color: #013D6A;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .day a {color: #FFF000;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays th {border-width: 0;font-weight: bold;color: #013D6A;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays abbr {border-width: 0;text-decoration: none;}&lt;br /&gt;
&lt;br /&gt;
html {background-image:url([[pix:theme|background]]);}&lt;br /&gt;
&lt;br /&gt;
h2.headingblock,&lt;br /&gt;
#page-header,&lt;br /&gt;
.sideblock,&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {background-image:url([[pix:theme|gradient]]);&lt;br /&gt;
   background-repeat:repeat-x;background-color: #0273C8;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adding a screenshot and favicon==&lt;br /&gt;
The final thing to do at this point is add both a screenshot for this theme as well as a favicon for it.&lt;br /&gt;
The screenshot will be shown in the theme selector screen and should be named &#039;&#039;screenshot.jpg&#039;&#039;.&lt;br /&gt;
The favicon will be used when someone bookmarks this page.&lt;br /&gt;
Both images should be located in your themes pix directory as follows:&lt;br /&gt;
* /theme/excitement/pix/screenshot.jpg&lt;br /&gt;
* /theme/excitement/pix/favicon.ico&lt;br /&gt;
&lt;br /&gt;
In the case of my theme I have taken a screenshot and added it to that directory, and because I don&#039;t really want to do anything special with the favicon I have copied it from /theme/base/pix/favicon.ico so that at least it will be recognisable as Moodle.&lt;br /&gt;
&lt;br /&gt;
[[es:Desarollo:Temas 2.0 creando tu primer tema]]&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Creating_a_theme_settings_page&amp;diff=46312</id>
		<title>Creating a theme settings page</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Creating_a_theme_settings_page&amp;diff=46312"/>
		<updated>2014-09-24T22:34:29Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Finishing settings.php */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}This document looks at how to create a settings page for your Moodle 2.x.x theme and how to make use of those settings within the CSS and layout files for your theme.&lt;br /&gt;
&lt;br /&gt;
This is a pretty advanced topic and will require that you have at least an intermediate knowledge of PHP, CSS, and development in general.&lt;br /&gt;
&lt;br /&gt;
==Before we begin==&lt;br /&gt;
[[Image:Theme.settings.page.03.png|350px|thumb|Our end goal. The settings page.]]&lt;br /&gt;
[[Image:Theme.settings.page.10.png|350px|thumb|And what it can do.]]&lt;br /&gt;
There is a huge body of knowledge that we must cover in following through this document and as such I think the best way to write this is as a tutorial.&lt;br /&gt;
&lt;br /&gt;
My intentions for this tutorial are to replicate the standard theme but with a settings page that allows the administrator to set a background colour, set a logo to use with the page, and probably several other minor settings to change the way in which the theme is displayed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I will start this tutorial by creating a new theme which will be largely a copy/paste of the current standard theme. I expect that anyone working through this tutorial has previously read the tutorial I wrote on [[Themes 2.0 creating your first theme|creating your first theme]]. If you haven&#039;t go read it now because I&#039;m not going to go into much detail until we get to the actual process of customising the theme and introducing the settings page.&lt;br /&gt;
&lt;br /&gt;
So before we finally get this started please ensure you can check off everything on the following requirements list.&lt;br /&gt;
* Have a Moodle installation that has already been installed and configured and is ready to use.&lt;br /&gt;
* Have full read/write access to that installation.&lt;br /&gt;
* Be prepared to delete that installation at the end of this... we will destroy it!&lt;br /&gt;
* Have a development environment prepared and ready to use. This includes:&lt;br /&gt;
** Your favourite editor installed, running, and pointed at the themes directory of your installation.&lt;br /&gt;
** Your browser open and your site visible.&lt;br /&gt;
** A bottomless coffee pot... decaf won&#039;t help you with this one.&lt;br /&gt;
* Have set the following settings:&lt;br /&gt;
** &#039;&#039;&#039;themedesignermode&#039;&#039;&#039; if you don&#039;t know what this is please read the [[Themes 2.0 creating your first theme|creating your first theme]] tutorial.&lt;br /&gt;
** &#039;&#039;&#039;allowthemechangeonurl&#039;&#039;&#039; turn this on, it allows you to change themes on the URL and is very handy when developing themes. &#039;&#039;Site Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; Theme settings&#039;&#039;&lt;br /&gt;
** &#039;&#039;&#039;langstringcache&#039;&#039;&#039; if you don&#039;t turn this off you won&#039;t see your strings when they are added. &#039;&#039;Site Administration &amp;gt; Language &amp;gt; Language settings&#039;&#039;&lt;br /&gt;
* And finally an insane ambition to create a customisable theme.&lt;br /&gt;
&lt;br /&gt;
For those interested the theme that I create throughout this tutorial can be downloaded from the forum post in which I announce this document: http://moodle.org/mod/forum/discuss.php?d=152053&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:right;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Our goals for this tutorial==&lt;br /&gt;
The following is just a list goals that I hope to achieve during this tutorial. They are laid out here so that I can easily refer back to them and so that you can easily find them.&lt;br /&gt;
# Create a new theme called &#039;&#039;&#039;demystified&#039;&#039;&#039; based upon the standard theme within Moodle 2.0.&lt;br /&gt;
# Make some minor changes to that theme to allow us to more easily see what is going on.&lt;br /&gt;
# Create a settings page for the demystified theme.&lt;br /&gt;
# Add several settings to our settings page.&lt;br /&gt;
# Use some of those settings to alter our CSS.&lt;br /&gt;
# Use the rest of those settings within our layout file..&lt;br /&gt;
# Discuss the good, the bad, and limits of what we have just created.&lt;br /&gt;
&lt;br /&gt;
So I can see you are all very excited about this point and that you would love to know what settings we are going to create; So here they are:&lt;br /&gt;
&lt;br /&gt;
A setting to ...&lt;br /&gt;
* change the background colour (CSS).&lt;br /&gt;
* set the path to an image that we will use as a logo on all pages (Layout files).&lt;br /&gt;
* override the width of the block regions (CSS).&lt;br /&gt;
* allow a note to be added to the footer of all pages (Layout files).&lt;br /&gt;
* allow custom CSS to be written to do anything the user wants. (CSS)&lt;br /&gt;
&lt;br /&gt;
==Creating the demystified theme==&lt;br /&gt;
Before we start here I want to remind you that I am going to look at this only briefly as I am making the assumption that you have read the [[Themes 2.0 creating your first theme|creating your first theme]] tutorial.&lt;br /&gt;
&lt;br /&gt;
Well lets get into it....&lt;br /&gt;
&lt;br /&gt;
The first thing we need to do is create a directory for our theme which we will call demystified. &lt;br /&gt;
&lt;br /&gt;
So within your Moodle directory create the following folder &#039;&#039;&#039;moodle/theme/demystified&#039;&#039;&#039;. At the same time you can also create the following files and folders which we will get to soon.&lt;br /&gt;
* The file &#039;&#039;&#039;moodle/theme/demystified/config.php&#039;&#039;&#039; for our config information.&lt;br /&gt;
* The directory &#039;&#039;&#039;moodle/theme/demystified/layout&#039;&#039;&#039; for our layout files.&lt;br /&gt;
* The directory &#039;&#039;&#039;moodle/theme/demystified/style&#039;&#039;&#039; for our css files.&lt;br /&gt;
* The file &#039;&#039;&#039;moodle/theme/demystified/style/core.css&#039;&#039;&#039; which will contain our special CSS.&lt;br /&gt;
&lt;br /&gt;
Next we will copy the layout files from the base theme to our new theme demystified. We are basing the demystified theme on the standard theme however that doesn&#039;t use it&#039;s own layout files it uses the base theme&#039;s layout files so those are the ones we want. &lt;br /&gt;
&lt;br /&gt;
The reason that we are coping these layout files is that later on in this tutorial we will be modifying them to make use of our new settings... so copy all of the layout files from &#039;&#039;&#039;moodle/theme/base/layout&#039;&#039;&#039; to &#039;&#039;&#039;moodle/theme/demystified/layout&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
There should be three files that you just copied:&lt;br /&gt;
# embedded.php&lt;br /&gt;
# frontpage.php&lt;br /&gt;
# general.php&lt;br /&gt;
&lt;br /&gt;
Now we need to populate demystified/config.php with the settings for our new theme. They are as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;name = &#039;demystified&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Simply sets the name of our theme.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;,&#039;base&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This theme is extending both the standard theme and the base theme. Remember when extending a theme you also need to extend its parents or things might not work correctly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;core&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This tells our theme that we want to use the file &#039;&#039;&#039;demystified/style/core.css&#039;&#039;&#039; with this theme.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;height:300px;overflow-y:scroll;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Most backwards compatible layout without the blocks - this is the layout used by default&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&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;
    // 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;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;
    // Main course page&lt;br /&gt;
    &#039;course&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;coursecategory&#039; =&amp;gt; array(&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;
    // part of course, typical for modules - default page layout if $cm specified in require_login()&lt;br /&gt;
    &#039;incourse&#039; =&amp;gt; array(&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;
    // The site home page.&lt;br /&gt;
    &#039;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;frontpage.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;
    // Server administration scripts.&lt;br /&gt;
    &#039;admin&#039; =&amp;gt; array(&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;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // My dashboard page&lt;br /&gt;
    &#039;mydashboard&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // My public page&lt;br /&gt;
    &#039;mypublic&#039; =&amp;gt; array(&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;
    &#039;login&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    // Pages that appear in pop-up windows - no navigation, no blocks, no header.&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // No blocks and minimal footer - used for legacy frame layouts only!&lt;br /&gt;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible&lt;br /&gt;
    &#039;embedded&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Used during upgrade and install, and for the &#039;This site is undergoing maintenance&#039; message.&lt;br /&gt;
    // This must not have any blocks, and it is good idea if it does not have links to&lt;br /&gt;
    // other places - for example there should not be a home link in the footer...&lt;br /&gt;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Now that all looks very complicated however its really not too bad as it is just copied from the base theme&#039;s config.php file. We can do this because we copied the layout files from the base theme to begin with and for the time being there are no changes that we wish to make. Simply open up &#039;&#039;&#039;theme/base/config.php&#039;&#039;&#039; and copy the layouts from there.&lt;br /&gt;
&lt;br /&gt;
And that is it. The config.php file for our demystified theme is complete. The full source is shown below:&lt;br /&gt;
&amp;lt;div style=&amp;quot;height:300px;overflow-y:scroll;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
// This file is part of Moodle - http://moodle.org/&lt;br /&gt;
//&lt;br /&gt;
// Moodle is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// Moodle is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with Moodle.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * The demystified theme config file&lt;br /&gt;
 *&lt;br /&gt;
 * This theme was created to document the process of adding a settings page to a theme&lt;br /&gt;
 *&lt;br /&gt;
 * @copyright 2010 Sam Hemelryk&lt;br /&gt;
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
// The name of our theme&lt;br /&gt;
$THEME-&amp;gt;name = &#039;demystified&#039;;&lt;br /&gt;
&lt;br /&gt;
// The other themes this theme extends&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;,&#039;base&#039;);&lt;br /&gt;
&lt;br /&gt;
// The CSS files this theme uses (located in the style directory)&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;core&#039;);&lt;br /&gt;
&lt;br /&gt;
// The layout definitions for this theme&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Most backwards compatible layout without the blocks - this is the layout used by default&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&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;
    // 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;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;
    // Main course page&lt;br /&gt;
    &#039;course&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;coursecategory&#039; =&amp;gt; array(&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;
    // part of course, typical for modules - default page layout if $cm specified in require_login()&lt;br /&gt;
    &#039;incourse&#039; =&amp;gt; array(&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;
    // The site home page.&lt;br /&gt;
    &#039;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;frontpage.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;
    // Server administration scripts.&lt;br /&gt;
    &#039;admin&#039; =&amp;gt; array(&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;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // My dashboard page&lt;br /&gt;
    &#039;mydashboard&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // My public page&lt;br /&gt;
    &#039;mypublic&#039; =&amp;gt; array(&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;
    &#039;login&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    // Pages that appear in pop-up windows - no navigation, no blocks, no header.&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // No blocks and minimal footer - used for legacy frame layouts only!&lt;br /&gt;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible&lt;br /&gt;
    &#039;embedded&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Used during upgrade and install, and for the &#039;This site is undergoing maintenance&#039; message.&lt;br /&gt;
    // This must not have any blocks, and it is good idea if it does not have links to&lt;br /&gt;
    // other places - for example there should not be a home link in the footer...&lt;br /&gt;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The screenshot below shows both the directory structure we have now created and the theme presently.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.01.png]]&lt;br /&gt;
&lt;br /&gt;
To view the theme so far open you browser and enter the URL of your site followed by &#039;&#039;&#039;?theme=demystified&#039;&#039;&#039;. You should see the theme that we just created which will look exactly like the base standard theme.&lt;br /&gt;
&lt;br /&gt;
The final thing that we want to do is add a little bit of CSS to the demystified theme that will both visually set this theme apart from the standard theme and second build a the base which our settings can later extend.&lt;br /&gt;
&lt;br /&gt;
I added the following snippet of CSS to the file &#039;&#039;&#039;demystified/style/core.css&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
html {background-color:#DDD;}&lt;br /&gt;
body {margin:30px;padding:0;border:1px solid #333;border-width:0 10px 0 10px;background-color:#333;}&lt;br /&gt;
body #page {background-color:#FFF;position:relative;top:-10px;}&lt;br /&gt;
.block .header {background-image:none;background-color:#0C5CAC;border:1px solid #0C5CAC;color:#FFF;}&lt;br /&gt;
.block {border-color:#4BA7FF;background-color:#DDEEFF;}&lt;br /&gt;
.block .content {background-color:#F1F8FF;}&lt;br /&gt;
a:link,&lt;br /&gt;
a:visited {color:#0C5CAC;}&lt;br /&gt;
a:hover {color:#C77500;}&lt;br /&gt;
#page #page-header {background-color:#0C5CAC;margin:0;padding:0;width:100%;color:#fff;}&lt;br /&gt;
#page #page-header a:link, #page #page-header a:visited {color:#FFAC02}&lt;br /&gt;
#page #page-header .navbar, #page #page-header .navbar a:link, #page #page-header .navbar a:visited {color:#0C5CAC;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The CSS that we have just added to our theme sets a couple of colours on the front page. Presently this is the only CSS I will add, I know it isn&#039;t complete by any means but it achieves it&#039;s purpose as the screenshot below illustrates.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.02.png|715px|thumb|left|The newly styles demystified theme]]&amp;lt;br style=&amp;quot;clear:both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And with that I will move on to the real purpose of this tutorial, creating the settings page&lt;br /&gt;
&lt;br /&gt;
==Setting up the settings page==&lt;br /&gt;
With the demystified theme set up it is time to create the settings page. This is where the real PHP fun begins.&lt;br /&gt;
&lt;br /&gt;
For those of you who happen to be familiar with development of modules, blocks or other plugin types you have probably encountered settings pages before and this is not going to be any different.&lt;br /&gt;
&lt;br /&gt;
However for those who haven&#039;t which I imagine is most of you this is going to be quite a challenge. I will try to walk through this step by step however if at any point you get stuck don&#039;t hesitate to ask in the forums as I imagine you will get a speedy response.&lt;br /&gt;
&lt;br /&gt;
===How settings pages work in Moodle===&lt;br /&gt;
Settings pages can be used by nearly every plugin type, of which themes is of course one. The way in which it all works isn&#039;t too tricky to understand. &lt;br /&gt;
&lt;br /&gt;
All of the settings for Moodle can be configured through the administrator interfaces when logged in. I am sure that everyone here has seen those pages and has changed a setting or two before so you will all know what I am talking about. Well the settings page for a theme is no different. It will be shown in the administration pages tree under &#039;&#039;&#039;Appearance &amp;gt; Themes&#039;&#039;&#039; and all we have to do is tell Moodle what settings there are.&lt;br /&gt;
&lt;br /&gt;
This is done by creating a settings.php file within our theme into which we will add code that tells Moodle about the settings we want to add/use.&lt;br /&gt;
&lt;br /&gt;
When telling Moodle about each setting we are simply creating a new &#039;&#039;admin_setting&#039;&#039; instance of the type we want and the properties we want and then adding it to our settings page.&lt;br /&gt;
&lt;br /&gt;
There is really not much more too it at this level. Things can get very complex very fast so the best thing we can do now is start creating our settings.php file for the demystified theme and see where it leads us.&lt;br /&gt;
&lt;br /&gt;
===Creating the settings page===&lt;br /&gt;
So as mentioned before we need a settings.php file which we will create now. To begin with create the file &#039;&#039;&#039;theme/demystified/settings.php&#039;&#039;&#039; and open it in your favourite editor so its ready to go.&lt;br /&gt;
&lt;br /&gt;
Before we start adding code however lets just remember the settings that we want to create:&lt;br /&gt;
* change the background colour (CSS).&lt;br /&gt;
* set the path to an image that we will use as a logo on all pages (Layout files).&lt;br /&gt;
* override the width of the block regions (CSS).&lt;br /&gt;
* allow a note to be added to the footer of all pages (Layout files).&lt;br /&gt;
* allow custom CSS to be written to do anything the user wants. (CSS)&lt;br /&gt;
&lt;br /&gt;
Alright.&lt;br /&gt;
&lt;br /&gt;
Now thinking about this the first setting is as basic as it gets, all we need is a text box that the user can type a colour into.&lt;br /&gt;
&lt;br /&gt;
The second is to allow a logo to be used in the header of each page. What we want here is a path but should it be a physical path e.g. C:/path/to/image.png or should it be a web path e.g. &amp;lt;nowiki&amp;gt;http://mysite.com/path/to/image.png&amp;lt;/nowiki&amp;gt;?&lt;br /&gt;
For the purpose of this tutorial I am going to go with a web path because it is going to be easier to code and will hopefully be a little easier to understand to begin with.&lt;br /&gt;
&lt;br /&gt;
The third setting is a little more complex. For this I want a drop down box with some specific widths that the administrator can select.&lt;br /&gt;
&lt;br /&gt;
The forth and the fifth settings are both pretty straight forward, there we want a textarea into which the user can enter what ever they want and we will do something useful with it.&lt;br /&gt;
&lt;br /&gt;
Now that we have an understanding about the settings we wish to define pull up your editor and lets start coding....&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Settings for the demystified theme&lt;br /&gt;
 */&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die;&lt;br /&gt;
&lt;br /&gt;
if ($ADMIN-&amp;gt;fulltree) {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is the first bit of code we must enter, the first line is of course just the opening php tag, secondly we have a comment that describes this file, and then we get create a new &#039;&#039;&#039;admin_settingspage object&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This admin_settingspage object that we have just created is a representation of our settings page and is the what we add our new settings to. When creating it we give it two arguments, first the name of the page which is in this case &#039;&#039;&#039;theme_&#039;&#039;themename&#039;&#039;&#039;&#039;&#039; and the title for the page which we get with the get_string method.&lt;br /&gt;
&lt;br /&gt;
At the moment I&#039;m not going to worry about adding the string, we will get to that later once we have defined all of our settings.&lt;br /&gt;
&lt;br /&gt;
====Background colour====&lt;br /&gt;
&lt;br /&gt;
With the page now created lets add our first setting: Background colour.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Background colour setting&lt;br /&gt;
$name = &#039;theme_demystified/backgroundcolor&#039;;&lt;br /&gt;
$title = get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = &#039;#DDD&#039;;&lt;br /&gt;
$setting = new admin_setting_configtext($name, $title, $description, $default, PARAM_CLEAN, 12);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Thankfully this isn&#039;t as difficult as it initially looks.&lt;br /&gt;
&lt;br /&gt;
The first line of code is creating a variable for the name of the background colour setting. In this case it is &#039;&#039;&#039;theme_demystified/backgroundcolor&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
The name is very important, for the setting to be usable we have to follow a strict naming convention. &#039;&#039;&#039;theme_&#039;&#039;themename&#039;&#039;/&#039;&#039;settingname&#039;&#039;&#039;&#039;&#039; where &#039;&#039;&#039;&#039;&#039;themename&#039;&#039;&#039;&#039;&#039; is the name of the theme the setting belongs to and &#039;&#039;&#039;&#039;&#039;settingname&#039;&#039;&#039;&#039;&#039; is the name for the setting by which we will use it.&lt;br /&gt;
&lt;br /&gt;
The second line of code creates a variable that contains the title of the setting. This is what the user sees to the right of the setting on the settings page and should be a short description of the setting. Here we are again using the &#039;&#039;get_string&#039;&#039; method so we will need to remember to add that string later on.&lt;br /&gt;
&lt;br /&gt;
The third line of code sets the description. This should describe what the setting does or how it works and again we will use the get_string method.&lt;br /&gt;
&lt;br /&gt;
The fourth line creates a variable that will be used as the default value for the setting. Because this setting is a colour we want an HTML colour to be the default value.&lt;br /&gt;
&lt;br /&gt;
The fifth line is where we put it all together. Here we create a new &#039;&#039;&#039;admin_setting_configtext&#039;&#039;&#039; object. This object will represent the background colour setting.&lt;br /&gt;
&lt;br /&gt;
When we create it we need to give it 6 different things.&lt;br /&gt;
# The name of the setting. In this case we have a variable &#039;&#039;&#039;$name&#039;&#039;&#039;.&lt;br /&gt;
# The title for this setting. We used the variable &#039;&#039;&#039;$title&#039;&#039;&#039;.&lt;br /&gt;
# The description of the setting &#039;&#039;&#039;$description&#039;&#039;&#039;.&lt;br /&gt;
# The default value for the setting. &#039;&#039;&#039;$default&#039;&#039;&#039; is the variable this.&lt;br /&gt;
# The type of value we want the user to enter. For this we have used PARAM_CLEAN which tells Moodle to get rid of any nasties from what the user enters.&lt;br /&gt;
# The size of the field. In our case 12 characters will be plenty.&lt;br /&gt;
&lt;br /&gt;
The sixth and final line of code adds our newly created setting to the administration page we created earlier.&lt;br /&gt;
&lt;br /&gt;
That is it we have successfully created and added our first setting, however there are several more to settings to do, and there are a couple of important things that you need to be aware of before we move on.&lt;br /&gt;
&lt;br /&gt;
First: There are several different types of settings that you can create and add to a page, and each one may differ in what they need you to give them. In this case it was name, title, description, default, type, and size. However other settings will likely require different things. Smart editors like Netbeans or Eclipse can tell you what is required, otherwise you will need to research it.&lt;br /&gt;
&lt;br /&gt;
Second: Normally settings are declared on one line as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$setting-&amp;gt;add(new admin_setting_configtext(&#039;theme_demystified/backgroundcolor&#039;, get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;), get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;), &#039;#DDD&#039;, PARAM_CLEAN, 12));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
While this is structurally identical as all we have done is move everything onto one line and do away with the variables it is a little harder to read when you are learning all of this.&lt;br /&gt;
&lt;br /&gt;
====The logo file====&lt;br /&gt;
Time to create the second setting that will allow the user to enter a URL to an image they wish to use as the logo on their site.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Logo file setting&lt;br /&gt;
$name = &#039;theme_demystified/logo&#039;;&lt;br /&gt;
$title = get_string(&#039;logo&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;logodesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtext($name, $title, $description, &#039;&#039;, PARAM_URL);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The first thing that you will notice about this setting that it is very similar to the first setting, in fact all we have changed is the name, title, description, and default value. We have however changed the value type from PARAM_CLEAN to PARAM_URL, this makes sure the user enters a URL. You will also notice that for this one we don&#039;t set a size for the field as we have no idea how long the URL will be.&lt;br /&gt;
&lt;br /&gt;
====Block region width====&lt;br /&gt;
The third setting should allow the user to set a width for the block regions that will be used as columns.&lt;br /&gt;
&lt;br /&gt;
For this setting I want to do something a little different from the previous two, here I want to use a select box so that the user selects a width for the column from a list I provide.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Block region width&lt;br /&gt;
$name = &#039;theme_demystified/regionwidth&#039;;&lt;br /&gt;
$title = get_string(&#039;regionwidth&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;regionwidthdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = 200;&lt;br /&gt;
$choices = array(150=&amp;gt;&#039;150px&#039;, 170=&amp;gt;&#039;170px&#039;, 200=&amp;gt;&#039;200px&#039;, 240=&amp;gt;&#039;240px&#039;, 290=&amp;gt;&#039;290px&#039;, 350=&amp;gt;&#039;350px&#039;, 420=&amp;gt;&#039;420px&#039;);&lt;br /&gt;
$setting = new admin_setting_configselect($name, $title, $description, $default, $choices);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
So looking at the code: The first four lines you will recognise. $name, $title, $description, and $default are all being set.&lt;br /&gt;
&lt;br /&gt;
The fifth line of code however introduces something new. Of course in order to have a select box we have to have options, in this case we have an array of options stored in the variable $choices.&lt;br /&gt;
&lt;br /&gt;
The array of options is constructed of a collection of &#039;&#039;&#039;&#039;&#039;value&#039;&#039;&#039; =&amp;gt; &#039;&#039;&#039;label&#039;&#039;&#039;&#039;&#039; pairs. Notice how we don&#039;t add &#039;&#039;&#039;px&#039;&#039;&#039; to the value. This is is very intentional as later on I need to do a little bit of math with that value so we need it to be a number.&lt;br /&gt;
&lt;br /&gt;
The lines after should look familiar again, the only difference being that instead of a &#039;&#039;admin_setting_configtext&#039;&#039; setting we have created a &#039;&#039;admin_setting_configselect&#039;&#039; for which we must give the choices for the select box as the fifth argument.&lt;br /&gt;
&lt;br /&gt;
Woohoo, we&#039;ve just created our first select box setting.&lt;br /&gt;
&lt;br /&gt;
====Foot note====&lt;br /&gt;
Now to create the foot note setting. Here we want the user to be able to enter some arbitrary text that will be used in the footer of the page. For this I want the user to be able to enter some HTML so I will create an editor setting.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Foot note setting&lt;br /&gt;
$name = &#039;theme_demystified/footnote&#039;;&lt;br /&gt;
$title = get_string(&#039;footnote&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;footnotedesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_confightmleditor($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
How simple is that!&lt;br /&gt;
&lt;br /&gt;
It is just about identical to the first two settings except that for this we have created a &#039;&#039;admin_setting_confightmleditor&#039;&#039; setting rather than a text setting.&lt;br /&gt;
&lt;br /&gt;
Note: You can also set the columns and rows for the editor setting using the fifth and sixth arguments.&lt;br /&gt;
&lt;br /&gt;
====Custom CSS====&lt;br /&gt;
The final setting is to allow the user to add some custom CSS to the theme that will be used on every page. I want this to be a plain textarea into which the user can enter CSS.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Custom CSS file&lt;br /&gt;
$name = &#039;theme_demystified/customcss&#039;;&lt;br /&gt;
$title = get_string(&#039;customcss&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;customcssdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtextarea($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Just like the editor or text settings. It&#039;s getting very easy now!&lt;br /&gt;
&lt;br /&gt;
====Finishing settings.php====&lt;br /&gt;
With all of our settings defined and added to our page that we created right at the beginning it is time to finish it all off.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
} // This is the closing brace that encloses all the above settings. &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The above line is the final line for the page. It is adding the page that we have created &#039;&#039;&#039;$setting&#039;&#039;&#039; to the admin tree structure. In this case it is adding it to the themes branch.&lt;br /&gt;
&lt;br /&gt;
The following is the completed source for our settings.php ..... for your copy/paste pleasure.&lt;br /&gt;
&amp;lt;div style=&#039;height:300px;overflow:auto;&#039;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Settings for the demystified theme&lt;br /&gt;
 */&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die;&lt;br /&gt;
 &lt;br /&gt;
if ($ADMIN-&amp;gt;fulltree) {&lt;br /&gt;
&lt;br /&gt;
    // Background colour setting&lt;br /&gt;
    name = &#039;theme_demystified/backgroundcolor&#039;;&lt;br /&gt;
    $title = get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
    $description = get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
    $default = &#039;#DDD&#039;;&lt;br /&gt;
    $setting = new admin_setting_configtext($name, $title, $description, $default, PARAM_CLEAN, 12);&lt;br /&gt;
    $setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
    $settings-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
    // Logo file setting.&lt;br /&gt;
    $name = &#039;theme_demystified/logo&#039;;&lt;br /&gt;
    $title = get_string(&#039;logo&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
    $description = get_string(&#039;logodesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
    $setting = new admin_setting_configtext($name, $title, $description, &#039;&#039;, PARAM_URL);&lt;br /&gt;
    $setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
    $settings-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
    // Block region width.&lt;br /&gt;
    $name = &#039;theme_demystified/regionwidth&#039;;&lt;br /&gt;
    $title = get_string(&#039;regionwidth&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
    $description = get_string(&#039;regionwidthdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
    $default = 200;&lt;br /&gt;
    $choices = array(150=&amp;gt;&#039;150px&#039;, 170=&amp;gt;&#039;170px&#039;, 200=&amp;gt;&#039;200px&#039;, 240=&amp;gt;&#039;240px&#039;, 290=&amp;gt;&#039;290px&#039;, 350=&amp;gt;&#039;350px&#039;, 420=&amp;gt;&#039;420px&#039;);&lt;br /&gt;
    $setting = new admin_setting_configselect($name, $title, $description, $default, $choices);&lt;br /&gt;
    $setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
    $settings-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
    // Foot note setting.&lt;br /&gt;
    $name = &#039;theme_demystified/footnote&#039;;&lt;br /&gt;
    $title = get_string(&#039;footnote&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
    $description = get_string(&#039;footnotedesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
    $setting = new admin_setting_confightmleditor($name, $title, $description, &#039;&#039;);&lt;br /&gt;
    $setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
    $settings-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
    // Custom CSS file.&lt;br /&gt;
    $name = &#039;theme_demystified/customcss&#039;;&lt;br /&gt;
    $title = get_string(&#039;customcss&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
    $description = get_string(&#039;customcssdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
    $setting = new admin_setting_configtextarea($name, $title, $description, &#039;&#039;);&lt;br /&gt;
    $setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
    $settings-&amp;gt;add($setting);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Creating a language file and adding our strings===&lt;br /&gt;
As I&#039;m sure none of you have forgotten, throughout the creation of the our settings.php page, we used a lot of strings that I mentioned we would set later on. Well now is the time to set those strings.&lt;br /&gt;
&lt;br /&gt;
First up create the following directories and file for our language strings:&lt;br /&gt;
* Directory &#039;&#039;&#039;theme/demystified/lang&#039;&#039;&#039;&lt;br /&gt;
* Directory &#039;&#039;&#039;theme/demystified/lang/en&#039;&#039;&#039;&lt;br /&gt;
* File &#039;&#039;&#039;theme/demystified/lang/theme_demystified.php&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
What we have created here is the required structure for Moodle to start looking for language strings.&lt;br /&gt;
&lt;br /&gt;
First Moodle locates the lang directory, once found it looks within that directory for another directory that uses the character code for the language the user has selected, by default this is &#039;&#039;&#039;en&#039;&#039;&#039; for English. Once that is found it looks for the appropriate language file, in this case &#039;&#039;&#039;theme_demystified.php&#039;&#039;&#039; from which it will load all language strings for our theme.&lt;br /&gt;
&lt;br /&gt;
If English isn&#039;t your chosen language simply replace the &#039;&#039;en&#039;&#039; directory with one that uses your chosen languages character code (two letters).&lt;br /&gt;
&lt;br /&gt;
We can now add our language strings to &#039;&#039;&#039;theme/demystified/lang/theme_demystified.php&#039;&#039;&#039;. Copy and paste the following lines of PHP into this file.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This file contains the strings used by the demystified theme&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
$string[&#039;backgroundcolor&#039;] = &#039;Background colour&#039;;&lt;br /&gt;
$string[&#039;backgroundcolordesc&#039;] = &#039;This sets the background colour for the theme.&#039;;&lt;br /&gt;
$string[&#039;configtitle&#039;] = &#039;Demystified theme&#039;;&lt;br /&gt;
$string[&#039;customcss&#039;] = &#039;Custom CSS&#039;;&lt;br /&gt;
$string[&#039;customcssdesc&#039;] = &#039;Any CSS you enter here will be added to every page allowing your to easily customise this theme.&#039;;&lt;br /&gt;
$string[&#039;footnote&#039;] = &#039;Footnote&#039;;&lt;br /&gt;
$string[&#039;footnotedesc&#039;] = &#039;The content from this textarea will be displayed in the footer of every page.&#039;;&lt;br /&gt;
$string[&#039;logo&#039;] = &#039;Logo&#039;;&lt;br /&gt;
$string[&#039;logodesc&#039;] = &#039;Enter the URL to an image to use as the logo for this site. Should be http://www.yoursite.com/path/to/logo.png&#039;;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;Demystified&#039;;&lt;br /&gt;
$string[&#039;regionwidth&#039;] = &#039;Column width&#039;;&lt;br /&gt;
$string[&#039;regionwidthdesc&#039;] = &#039;This sets the width of the two block regions that form the left and right columns.&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above lines of code I have added an entry for each language string we used within &#039;&#039;settings.php&#039;&#039;. When adding language strings like this make sure you use single quotes and try to keep things alphabetical - it helps greatly when managing strings.&lt;br /&gt;
&lt;br /&gt;
Now when we view the settings page there will not be any errors or strings missing.&lt;br /&gt;
&lt;br /&gt;
===Having a look at what we have created===&lt;br /&gt;
Now that we have created our settings page (settings.php) and added all of the language strings it is time to have a look at things in your browser.&lt;br /&gt;
&lt;br /&gt;
Open your browser and enter the URL to your site. When you arrive at your site login as an administrator.&lt;br /&gt;
&lt;br /&gt;
If you are not redirected to view the new settings change your URL to &amp;lt;nowiki&amp;gt;http://www.yoursite.com/admin/&amp;lt;/nowiki&amp;gt; and your will see a screen to set the new theme settings we have just created. This lets us know that everything has worked correctly.&lt;br /&gt;
&lt;br /&gt;
At any point now you are able to log in as administrator and within the settings block browse to &#039;&#039;&#039;Site administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; Demystified theme&#039;&#039;&#039; to change those settings.&lt;br /&gt;
&lt;br /&gt;
The screenshot below shows you what you should see at this point:&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.03.png|715px|thumb|left|The settings page we just created]]&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using the settings in CSS==&lt;br /&gt;
With the settings page now created and operational it is time to make use of our new settings. The settings that we want to use within our CSS is as follows:&lt;br /&gt;
&lt;br /&gt;
; backgroundcolor : Will be used to set the background colour in CSS.&lt;br /&gt;
; regionwidth : Will be the width of the column for CSS.&lt;br /&gt;
; customcss : Will be some custom CSS to add to our stylesheet.&lt;br /&gt;
&lt;br /&gt;
At this point those names are the names we used for our setting with the slash and everything before it having been removed.&lt;br /&gt;
&lt;br /&gt;
Before we start tearing into some code it is important that we have a look at what we are going to do and how we are going to go about it.&lt;br /&gt;
&lt;br /&gt;
===How it all works within Moodle===&lt;br /&gt;
The first thing to understand is that while Moodle allows you to create a settings page and automates it inclusion and management right into the administration interfaces there is no smart equivalent for using the settings. This is simply because there is no way to predict how people will want to use the settings.&lt;br /&gt;
&lt;br /&gt;
However don&#039;t think of this as a disadvantage, in fact it is quite the contrary. Although we can&#039;t just &#039;&#039;use&#039;&#039; our settings we can take full control over how and where we use them. It means it will take a little more code but in the end that will work to our advantage as we can do anything we want.&lt;br /&gt;
&lt;br /&gt;
Moodle does help us out a little but not in an obvious way. The first thing that Moodle does is look for a config variable &#039;&#039;&#039;csspostprocess&#039;&#039;&#039; that should be the name of a function which we want called to make any changes to the CSS after it has been prepared.&lt;br /&gt;
&lt;br /&gt;
The second thing Moodle does is include a lib.php from the theme&#039;s directory if one exists (also for the themes the current theme extends.) which ensures that as long as we write our code within &#039;&#039;&#039;theme/demystified/lib.php&#039;&#039;&#039; it will be included and ready to be used.&lt;br /&gt;
&lt;br /&gt;
The third and final thing Moodle does that will help us out here is ensure that by the time any of code is ready to execute the settings have been prepared and are ready to be used within a theme config object which is passed into our &#039;&#039;csspostprocess&#039;&#039; function.&lt;br /&gt;
&lt;br /&gt;
===Our plan===&lt;br /&gt;
As you have already probably guessed we will need to create a function to make the changes to the CSS that we want. We will then set the theme config option &#039;&#039;&#039;$THEME-&amp;gt;csspostprocess&#039;&#039;&#039; to the name of our function.&lt;br /&gt;
&lt;br /&gt;
By doing this when Moodle builds the CSS file it will call our function afterwards with the CSS and the theme object that contains our setting.&lt;br /&gt;
&lt;br /&gt;
Now we know that we will use the &#039;&#039;csspostprocess&#039;&#039; function but how are we going to change the CSS, we could get the function to add CSS, or we could get the function to replace something within the CSS. My personal preference is to replace something within the CSS, just like what is happening with images. If you want to use an image within CSS you would write &amp;lt;nowiki&amp;gt;[[pix:theme|imagename]]&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For settings I am going to use &amp;lt;nowiki&amp;gt;[[setting:settingname]]&amp;lt;/nowiki&amp;gt;, this way it looks a bit like something you are already familiar with.&lt;br /&gt;
&lt;br /&gt;
What we need to decide upon next is the best way in which to replace our settings tag with the settings that the user has set.&lt;br /&gt;
&lt;br /&gt;
There are two immediate options available to us:&lt;br /&gt;
# Make the &#039;&#039;csspostprocess&#039;&#039; function do all the work.&lt;br /&gt;
# Make the &#039;&#039;csspostprocess&#039;&#039; function call a separate function for each setting.&lt;br /&gt;
Solution 1 might sound like the simplest however it is going to result in a &#039;&#039;&#039;VERY&#039;&#039;&#039; complex function. Remember the user might have left settings blank or entered something that wouldn&#039;t be valid so we would need to make the sure there is some validation and a good default.&lt;br /&gt;
Because of this I think that solution 2 is the better solution.&lt;br /&gt;
&lt;br /&gt;
So we are going to need a &#039;&#039;csspostprocess&#039;&#039; function and then a function for each of the three settings we have that will do the replacements.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// This is our css post process function&lt;br /&gt;
function demystified_process_css($css, $theme) {};&lt;br /&gt;
// This replaces [[setting:backgroundcolor]] with the background colour&lt;br /&gt;
function demystified_set_backgroundcolor($css, $backgroundcolor) {};&lt;br /&gt;
// This replaces [[setting:regionwidth]] with the correct region width&lt;br /&gt;
function demystified_set_regionwidth() {$css, $regionwidth};&lt;br /&gt;
// This replaces [[setting:customcss]] with the custom css&lt;br /&gt;
function demystified_set_customcss() {$css, $customcss};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you should note about the above functions is that they all start with the theme&#039;s name. This is required to ensure that the functions are named uniquely as it is VERY unlikely that someone has already created these functions.&lt;br /&gt;
&lt;br /&gt;
So with our plan set out lets start writing the code.&lt;br /&gt;
&lt;br /&gt;
===Writing the code===&lt;br /&gt;
The very first thing that we need to do is create a lib.php for our theme into which our css processing functions are going to go. So please at this point create &#039;&#039;&#039;theme/demystified/lib.php&#039;&#039;&#039; and open it in your editor ready to go.&lt;br /&gt;
&lt;br /&gt;
The first bit of code we have to write is the function that will be called by Moodle to do the processing &#039;&#039;&#039;demystified_process_css&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
Before we start out please remember that the wonderful thing about coding is that there is any number of solutions to a problem. The solutions that you are seeing here in this tutorial are solutions that I have come up with to meet fulfil the needs of the tutorial without being so complex that they are hard to understand. This probably isn&#039;t how I would go about it normally but this is a little easier to understand for those who aren&#039;t overly familiar with PHP and object orientation.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_process_css====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function demystified_process_css($css, $theme) {&lt;br /&gt;
&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;backgroundcolor)) {&lt;br /&gt;
        $backgroundcolor = $theme-&amp;gt;settings-&amp;gt;backgroundcolor;&lt;br /&gt;
    } else {&lt;br /&gt;
        $backgroundcolor = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_backgroundcolor($css, $backgroundcolor);&lt;br /&gt;
&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;regionwidth)) {&lt;br /&gt;
        $regionwidth = $theme-&amp;gt;settings-&amp;gt;regionwidth;&lt;br /&gt;
    } else {&lt;br /&gt;
        $regionwidth = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_regionwidth($css, $regionwidth);&lt;br /&gt;
&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;customcss)) {&lt;br /&gt;
        $customcss = $theme-&amp;gt;settings-&amp;gt;customcss;&lt;br /&gt;
    } else {&lt;br /&gt;
        $customcss = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_customcss($css, $customcss);&lt;br /&gt;
&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So lets look at the things that make up this function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function demystified_process_css($css, $theme) {&lt;br /&gt;
    //.....&lt;br /&gt;
    return $css&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This of course is the function declaration. &lt;br /&gt;
&lt;br /&gt;
The function gets given two variables, the first &#039;&#039;&#039;$css&#039;&#039;&#039; is a pile of CSS as one big string, and the second is the theme object &#039;&#039;&#039;$theme&#039;&#039;&#039; that contains all of the configuration, options, and settings for our theme.&lt;br /&gt;
&lt;br /&gt;
It then returns the &#039;&#039;$css&#039;&#039; variable, essentially returning the modified CSS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    //...&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;backgroundcolor)) {&lt;br /&gt;
        $backgroundcolor = $theme-&amp;gt;settings-&amp;gt;backgroundcolor;&lt;br /&gt;
    } else {&lt;br /&gt;
        $backgroundcolor = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_backgroundcolor($css, $backgroundcolor);&lt;br /&gt;
    //...&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are processing our first setting &#039;&#039;backgroundcolor&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
The first thing that we need to do is check whether it has been set and whether it has a value. If it has then we store that value in &#039;&#039;&#039;$backgroundcolor&#039;&#039;&#039;. It is doesn&#039;t have a value then we set &#039;&#039;$backgroundcolor&#039;&#039; to null. This ensures that &#039;&#039;$backgroundcolor&#039;&#039; is set because if it isn&#039;t then you are going to get a notice (if you have debugging on).&lt;br /&gt;
&lt;br /&gt;
The final line of this block calls the function &#039;&#039;&#039;demystified_set_backgroundcolor&#039;&#039;&#039;. We haven&#039;t written this function yet but we will shortly. When we call it we give it the &#039;&#039;$css&#039;&#039; variable that contains all of the CSS and we give it the background colour variable &#039;&#039;$backgroundcolor&#039;&#039;. Once this function is finished it returns the &#039;&#039;$css&#039;&#039; variable with all of the changes made much like how our css processing function works.&lt;br /&gt;
&lt;br /&gt;
What you should also note about this code is this:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$theme-&amp;gt;settings-&amp;gt;backgroundcolor&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
As mentioned earlier &#039;&#039;$theme&#039;&#039; is an object that contains all of the configuration and settings for our theme. The &#039;&#039;$theme&#039;&#039; object has a $settings property which contains all of the settings for our theme, and finally the settings property contains a variable backgroundcolor that is the value the user entered for that setting. That is how we get a settings value.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($theme-&amp;gt;settings-&amp;gt;regionwidth)) {&lt;br /&gt;
    $regionwidth = $theme-&amp;gt;settings-&amp;gt;regionwidth;&lt;br /&gt;
} else {&lt;br /&gt;
    $regionwidth = null;&lt;br /&gt;
}&lt;br /&gt;
$css = demystified_set_regionwidth($css, $regionwidth);&lt;br /&gt;
&lt;br /&gt;
if (!empty($theme-&amp;gt;settings-&amp;gt;customcss)) {&lt;br /&gt;
    $customcss = $theme-&amp;gt;settings-&amp;gt;customcss;&lt;br /&gt;
} else {&lt;br /&gt;
    $customcss = null;&lt;br /&gt;
}&lt;br /&gt;
$css = demystified_set_customcss($css, $customcss);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These two routines are nearly identical to the routine above. For both the regionwidth and the customcss we make sure it has a value and then store it in a variable. We then call the relevant function to make the changes for that setting.&lt;br /&gt;
&lt;br /&gt;
Now that we have the general processing function it is time to write the three functions we have used but not written, &#039;&#039;demystified_set_backgroundcolor&#039;&#039;, &#039;&#039;demystified_set_regionwidth&#039;&#039;, &#039;&#039;demystified_set_customcss&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_set_backgroundcolor====&lt;br /&gt;
&lt;br /&gt;
First up demystified_set_backgroundcolor.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Sets the background colour variable in CSS&lt;br /&gt;
 *&lt;br /&gt;
 * @param string $css&lt;br /&gt;
 * @param mixed $backgroundcolor&lt;br /&gt;
 * @return string&lt;br /&gt;
 */&lt;br /&gt;
function demystified_set_backgroundcolor($css, $backgroundcolor) {&lt;br /&gt;
    $tag = &#039;[[setting:backgroundcolor]]&#039;;&lt;br /&gt;
    $replacement = $backgroundcolor;&lt;br /&gt;
    if (is_null($replacement)) {&lt;br /&gt;
        $replacement = &#039;#DDDDDD&#039;;&lt;br /&gt;
    }&lt;br /&gt;
    $css = str_replace($tag, $replacement, $css);&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ok so what is happening here?&lt;br /&gt;
&lt;br /&gt;
First we need a variable &#039;&#039;&#039;$tag&#039;&#039;&#039; that contains the tag we are going to replace. As mentioned earlier we are going to use tags that look like the image tags you are already familiar with &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:settingname]]&amp;lt;/nowiki&amp;gt;&#039;&#039;, in this case &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:backgroundcolor]]&amp;lt;/nowiki&amp;gt;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Next I am going to create a variable called &#039;&#039;&#039;$replacement&#039;&#039;&#039; into which I put &#039;&#039;&#039;$backgroundcolor&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;IF&#039;&#039;&#039; statement that comes next checks &#039;&#039;$replacement&#039;&#039; to make sure it is not null. If it is then we need to set it to a default value. In this case I have used &#039;&#039;#DDD&#039;&#039; as that was the default for the settings.&lt;br /&gt;
&lt;br /&gt;
The line after the IF statement puts it all together. The &#039;&#039;str_replace&#039;&#039; function that we are calling takes three arguments in this order:&lt;br /&gt;
# The text to search for.&lt;br /&gt;
# The text to replace it with.&lt;br /&gt;
# The text to do the replacement in.&lt;br /&gt;
It then returns the text with all of the replacements made. So in this case we are replacing the tag with the background colour and it is returning the changed CSS.&lt;br /&gt;
&lt;br /&gt;
The final thing is to return the &#039;&#039;$css&#039;&#039; variable which now contains the correct background colour.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_set_regionwidth====&lt;br /&gt;
&lt;br /&gt;
Next we have the demystified_set_regionwidth function.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Sets the region width variable in CSS&lt;br /&gt;
 *&lt;br /&gt;
 * @param string $css&lt;br /&gt;
 * @param mixed $regionwidth&lt;br /&gt;
 * @return string&lt;br /&gt;
 */&lt;br /&gt;
function demystified_set_regionwidth($css, $regionwidth) {&lt;br /&gt;
    $tag = &#039;[[setting:regionwidth]]&#039;;&lt;br /&gt;
    $doubletag = &#039;[[setting:regionwidthdouble]]&#039;;&lt;br /&gt;
    $replacement = $regionwidth;&lt;br /&gt;
    if (is_null($replacement)) {&lt;br /&gt;
        $replacement = 200;&lt;br /&gt;
    }&lt;br /&gt;
    $css = str_replace($tag, $replacement.&#039;px&#039;, $css);&lt;br /&gt;
    $css = str_replace($doubletag, ($replacement*2).&#039;px&#039;, $css);&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function is very similar to the above function however there is one key thing we are doing different. We are doing two replacements.&lt;br /&gt;
&lt;br /&gt;
# The first replacement is for the width that the user selected. In this case I am replacing the tag &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt;&#039;&#039; with the width.&lt;br /&gt;
# The second replacement is for the width x 2. This is because the page layout requires that the width be doubled for some of the CSS. Here I will replace &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidthdouble]]&amp;lt;/nowiki&amp;gt;&#039;&#039; with the doubled width.&lt;br /&gt;
&lt;br /&gt;
Remember because it is still just a number we need to add &#039;&#039;&#039;px&#039;&#039;&#039; to the end of each before we do the replacement.&lt;br /&gt;
&lt;br /&gt;
So the overall process of this function is:&lt;br /&gt;
# Define the two tags as &#039;&#039;&#039;$tag&#039;&#039;&#039; and &#039;&#039;&#039;$doubletag&#039;&#039;&#039;.&lt;br /&gt;
# Make &#039;&#039;&#039;$replacement&#039;&#039;&#039; the region width &#039;&#039;$regionwidth&#039;&#039;.&lt;br /&gt;
# Set &#039;&#039;$replacement&#039;&#039; to a default value of 200 is it is null.&lt;br /&gt;
# Replace &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; with the width.&lt;br /&gt;
# Replace &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidthdouble]]&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; with the width x 2.&lt;br /&gt;
# Return the changed CSS.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_set_customcss====&lt;br /&gt;
&lt;br /&gt;
The final function that we need to write is the demystified_set_customcss function.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Sets the custom css variable in CSS&lt;br /&gt;
 *&lt;br /&gt;
 * @param string $css&lt;br /&gt;
 * @param mixed $customcss&lt;br /&gt;
 * @return string&lt;br /&gt;
 */&lt;br /&gt;
function demystified_set_customcss($css, $customcss) {&lt;br /&gt;
    $tag = &#039;[[setting:customcss]]&#039;;&lt;br /&gt;
    $replacement = $customcss;&lt;br /&gt;
    if (is_null($replacement)) {&lt;br /&gt;
        $replacement = &#039;&#039;;&lt;br /&gt;
    }&lt;br /&gt;
    $css = str_replace($tag, $replacement, $css);&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function is just like the first function. I&#039;m going to let you work it out on your own.&lt;br /&gt;
&lt;br /&gt;
And that is it no more PHP... Hallelujah I can hear you yelling. The final thing we need to do is tell our theme about the functions we have written and put the settings tags into the CSS.&lt;br /&gt;
&lt;br /&gt;
===Finishing it all off===&lt;br /&gt;
&lt;br /&gt;
So there are two things we have to do in order to complete this section and have our the settings page implemented and our settings being used.&lt;br /&gt;
&lt;br /&gt;
First we need to tell our theme that we want to use the function &#039;&#039;demystified_process_css&#039;&#039; as the &#039;&#039;csspostprocess&#039;&#039; function. This is done very simply by adding the following line of PHP to the bottom of our theme&#039;s config.php file &#039;&#039;&#039;theme/demystified/config.php&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;csspostprocess = &#039;demystified_process_css&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done the only thing left is to add the settings tag into the CSS. Remember those settings tags are:&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:backgroundcolor]]&amp;lt;/nowiki&amp;gt; : We need to add this where ever we want the background colour setting to be used.&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt; : We need to add this where ever we want to set the width of the block regions.&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:regionwidthdouble]]&amp;lt;/nowiki&amp;gt; : We need to add this where ever we want to set the doubled width of the block regions.&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:customcss]]&amp;lt;/nowiki&amp;gt; : We need to add this to the bottom of the CSS file that we want the custom CSS added to.&lt;br /&gt;
&lt;br /&gt;
So lets make those changes in CSS now, open up your &#039;&#039;core.css&#039;&#039; file and replace the CSS with the CSS below:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/** Background color is a setting **/&lt;br /&gt;
html {background-color:[[setting:backgroundcolor]];}&lt;br /&gt;
body {margin:30px;padding:0;border:1px solid #333;border-width:0 10px 0 10px;background-color:#333;}&lt;br /&gt;
body #page {background-color:#FFF;position:relative;top:-10px;}&lt;br /&gt;
.block .header {background-image:none;background-color:#0C5CAC;border:1px solid #0C5CAC;color:#FFF;}&lt;br /&gt;
.block {border-color:#4BA7FF;background-color:#DDEEFF;}&lt;br /&gt;
.block .content {background-color:#F1F8FF;}&lt;br /&gt;
a:link,&lt;br /&gt;
a:visited {color:#0C5CAC;}&lt;br /&gt;
a:hover {color:#C77500;}&lt;br /&gt;
#page #page-header {background-color:#0C5CAC;margin:0;padding:0;width:100%;color:#fff;}&lt;br /&gt;
#page #page-header a:link, #page #page-header a:visited {color:#FFAC02}&lt;br /&gt;
#page #page-header .navbar, #page #page-header .navbar a:link, #page #page-header .navbar a:visited {color:#0C5CAC;}&lt;br /&gt;
/** Override the region width **/&lt;br /&gt;
#page-content #region-main-box {left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidthdouble]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-pre {width:[[setting:regionwidth]];left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-post {width:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidthdouble]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
/** Custom CSS **/&lt;br /&gt;
[[setting:customcss]]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will notice that &amp;lt;nowiki&amp;gt;[[setting:backgroundcolor]]&amp;lt;/nowiki&amp;gt; has been used for the html tags background colour:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
html {background-color:[[setting:backgroundcolor]];}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have also set the width of the block regions by adding &amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt; as the width for region-pre and region-post as shown below:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
#page-content #region-main-box {left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidthdouble]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-pre {width:[[setting:regionwidth]];left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-post {width:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidthdouble]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
You&#039;ll notice here that we have to set several different widths and margins using the regionwidth setting and make use of the special regionwidthdouble setting that we added.&lt;br /&gt;
&lt;br /&gt;
The final thing that we did was add the &amp;lt;nowiki&amp;gt;[[setting:customcss]]&amp;lt;/nowiki&amp;gt; to the bottom of the file to ensure that the custom CSS comes last (and therefore can override all other CSS).&lt;br /&gt;
&lt;br /&gt;
And with that we are finished. The screenshot below shows how this now looks in the browser if I set the background colour setting to &#039;&#039;&#039;&amp;lt;span style=&#039;color:#FFA800;&#039;&amp;gt;#FFA800&amp;lt;/span&amp;gt;&#039;&#039;&#039; and made the column width 240px;&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.04.png|715px|thumb|left|Our settings in action]]&amp;lt;br style=&amp;quot;clear:both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using the settings within our layout files==&lt;br /&gt;
Now that we have utilised the first three settings within our theme&#039;s CSS file it is time to implement the other two settings within the layout files so that they are written directly into the page.&lt;br /&gt;
&lt;br /&gt;
You&#039;ll be glad to know this is no where near as difficult as utilising settings within a CSS file although it still does require a little bit of PHP.&lt;br /&gt;
&lt;br /&gt;
First up is the logo setting. Into this setting the user is able to enter the URL to an image to use as the logo for the site. In my case I want this to be just a background logo on top of which I want to position the page header.&lt;br /&gt;
&lt;br /&gt;
Before I start there is one thing I need to do however and that is create a default logo background that gets shown if the user hasn&#039;t set a specific logo file. To do this I simply created an image &#039;&#039;&#039;logo.jpg&#039;&#039;&#039; and put it into a pix directory within the demystified theme. You should end up with &#039;&#039;&#039;theme/demystified/pix/logo.jpg&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Next open up the front-page layout file &#039;&#039;theme/demystified/layout/frontpage.php&#039;&#039;. At the top of the file is the PHP that checks what blocks regions the page has and a bit of other stuff. Well right below the existing bit of PHP we want to add the following code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;logo)) {&lt;br /&gt;
    $logourl = $PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;logo;&lt;br /&gt;
} else {&lt;br /&gt;
    $logourl = $OUTPUT-&amp;gt;pix_url(&#039;logo&#039;, &#039;theme&#039;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
What we are doing here is creating a variable called $logourl that will contain the URL to a logo file that was either entered by the user or if they left it blank is that of our default logo file.&lt;br /&gt;
&lt;br /&gt;
There are two things that you should notice about this. First the logo setting can be retrieved through &#039;&#039;&#039;$PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;logo&#039;&#039;&#039; and second we get the default logo url by calling &#039;&#039;&#039;$OUTPUT-&amp;gt;pix_url(&#039;logo&#039;, &#039;theme&#039;)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Now that we have the logo URL we are going to use we need to add an image to the header section of the page as shown below:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;page-header&amp;quot; class=&amp;quot;clearfix&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;img class=&amp;quot;sitelogo&amp;quot; src=&amp;quot;&amp;lt;?php echo $logourl;?&amp;gt;&amp;quot; alt=&amp;quot;Custom logo here&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;
....&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you save that and browse to your sites front page you will notice that the logo file is now being shown. Hooray. However it is probably not styled too nicely so lets quickly fix that. Open up the core.css file and add the following lines of CSS to the bottom of the file.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
#page-header {position:relative;min-height:100px;}&lt;br /&gt;
#page-header .sitelogo {float:left;}&lt;br /&gt;
#page-header .headermain {position:absolute;left:0.5em;top:50px;margin:0;float:none;font-size:40px;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
These three lines position the image correctly and if you now refresh everything should appear perfectly. &lt;br /&gt;
&lt;br /&gt;
With the logo done the last setting we need to deal with is the footnote setting. The idea with this setting was that the administrator could enter some text into the editor and it would be displayed in the footer of the page.&lt;br /&gt;
&lt;br /&gt;
This is probably the easiest setting to implement.&lt;br /&gt;
&lt;br /&gt;
Within the front page layout file that we edited above add the following lines below those we added previously.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;footnote)) {&lt;br /&gt;
    $footnote = $PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;footnote;&lt;br /&gt;
} else {&lt;br /&gt;
    $footnote = &#039;&amp;lt;!-- There was no custom footnote set --&amp;gt;&#039;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are just collecting the footnote into a variable &#039;&#039;&#039;$footnote&#039;&#039;&#039; and setting a default footnote comment if the user hasn&#039;t entered one.&lt;br /&gt;
&lt;br /&gt;
We can now echo the $footnote variable within the page footer. This can be done as shown below.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;!-- START OF FOOTER --&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;footnote&amp;quot;&amp;gt;&amp;lt;?php echo $footnote; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;p class=&amp;quot;helplink&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;?php echo page_doc_link(get_string(&#039;moodledocslink&#039;)) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And with that done we are finished! Congratulations if you got this far.&lt;br /&gt;
&lt;br /&gt;
The screenshot below shows the demystified theme we have just created that is styled by the settings page.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.05.png|715px|thumb|left|My finished demystified theme]]&amp;lt;br style=&amp;quot;clear:both&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing our creation==&lt;br /&gt;
Congratulations to you! If you&#039;ve made it this far you have done very well. Now it is time to have a look at what we have created and give it a quick test run.&lt;br /&gt;
&lt;br /&gt;
So in this tutorial we have achieved the following:&lt;br /&gt;
&lt;br /&gt;
* We created a theme called demystified that is based on the standard theme.&lt;br /&gt;
* We added a settings page to our new theme.&lt;br /&gt;
* We added the following settings to our settings page:&lt;br /&gt;
** We can set a background colour through the admin interface.&lt;br /&gt;
** We can change the logo of the site.&lt;br /&gt;
** We can change the block region width.&lt;br /&gt;
** We can add a footnote to the page footer&lt;br /&gt;
** We can add some custom CSS to seal the deal.&lt;br /&gt;
* Those settings were then used in the CSS files for our theme.&lt;br /&gt;
* They were also used in the layout files for our theme.&lt;br /&gt;
* And here we are testing it all.&lt;br /&gt;
&lt;br /&gt;
The screenshots below show my testing process and I change each setting and view the outcome. The great thing about this is that with theme designer mode on you see the changes as soon as the form refreshes.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.06.png|300px|thumb|left|Default settings]]&lt;br /&gt;
[[Image:Theme.settings.page.07.png|300px|thumb|left|Changed the background colour setting]]&lt;br /&gt;
[[Image:Theme.settings.page.08.png|300px|thumb|left|Changed the logo and region width]]&lt;br /&gt;
[[Image:Theme.settings.page.09.png|300px|thumb|left|Added a footnote]]&lt;br /&gt;
[[Image:Theme.settings.page.10.png|300px|thumb|left|Added some custom CSS]]&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:both&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The different settings you can use==&lt;br /&gt;
During this tutorial we use four different kinds of settings, a text box, text area, a select (dropdown) and the editor however as I&#039;m sure you have all guessed there is many more some of which will certainly be useful for theme settings.&lt;br /&gt;
&lt;br /&gt;
The following are examples of some of the different settings. I should add that these build upon what we have already done within the tutorial but are not included in the download.&lt;br /&gt;
&lt;br /&gt;
===Colour picker===&lt;br /&gt;
[[Image:Theme.settings.page.11.png|400px|thumb|The colour picker]]&lt;br /&gt;
I can hear you all asking now &#039;Why didn&#039;t you mention this one earlier?&#039; well the answer is simple it didn&#039;t exist when I first wrote the tutorial. It is an admin setting that I wrote several days after because of the fantastic effort people were putting into trying out settings pages.&lt;br /&gt;
&lt;br /&gt;
A bit about the colour picker. First up it is a text box that when the page loads turns into a colour picker that can be used to select a colour and can even preview the selected colour in the page (by clicking the preview button). It is designed to be very easy to use and the code is just about as simple as creating a normal text box setting.&lt;br /&gt;
&lt;br /&gt;
In the image to the left I have replaced the background colour setting we created during the tutorial with the colour picker. Lets have a look at the code involved for that.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Background colour setting&lt;br /&gt;
$name = &#039;theme_demystified/backgroundcolor&#039;;&lt;br /&gt;
$title = get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = &#039;#DDD&#039;;&lt;br /&gt;
$previewconfig = array(&#039;selector&#039;=&amp;gt;&#039;html&#039;, &#039;style&#039;=&amp;gt;&#039;backgroundColor&#039;);&lt;br /&gt;
$setting = new admin_setting_configcolourpicker($name, $title, $description, $default, $previewconfig);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
So first thing you should notice is that the first four lines of code have not changed at all!&lt;br /&gt;
&lt;br /&gt;
The first change we have is to create a variable &#039;&#039;&#039;$previewconfig&#039;&#039;&#039;. &lt;br /&gt;
This variable is used to tell the colour picker what to do when the user clicks the preview button. It should be an array that contains two things, first a selector, and second a style. &lt;br /&gt;
# The selector is a CSS selector like &#039;&#039;.page .header h2&#039;&#039;.&lt;br /&gt;
# The style is a what should change, there are two immediate values it can be, either &#039;&#039;&#039;backgroundColor&#039;&#039;&#039; or &#039;&#039;&#039;color&#039;&#039;&#039;.&lt;br /&gt;
In my case the selector is &#039;&#039;&#039;html&#039;&#039;&#039; to target the html tag and the style is backgroundColor to change the background colour.&lt;br /&gt;
&lt;br /&gt;
The second change is to use &#039;&#039;&#039;admin_setting_configcolourpicker&#039;&#039;&#039; instead of &#039;&#039;admin_setting_configtext&#039;&#039;. The arguments are nearly identical as well except that there is an extra argument to which we give the &#039;&#039;&#039;$previewconfig&#039;&#039;&#039; variable.&lt;br /&gt;
&lt;br /&gt;
And that is it! it is all you need to get the colour picker up and running.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Extra note:&#039;&#039;&#039; The $previewconfig variable is optional. If you don&#039;t want a preview button the simply set &#039;&#039;$previewconfig = null&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Common pitfalls and useful notes==&lt;br /&gt;
&lt;br /&gt;
This section is really just a collection of pointers, tips, notes, and other short useful stuff that may be of use to those attempting this tutorial.&lt;br /&gt;
&lt;br /&gt;
# First up and most importantly there are very few limitations to what you achieve in this fashion.&lt;br /&gt;
# If you get stuck or need a hand ask in the forums, there&#039;s always someone round who can help.&lt;br /&gt;
# If you do something really cool let us know, I know everyone in the community loves finding our what others are achieving.&lt;br /&gt;
# You don&#039;t have to use &#039;&#039;admin_settingpage&#039;&#039; you can also use &#039;&#039;&#039;admin_externalpage&#039;&#039;&#039; if you prefer. It should be noted however that it is not the preferred way to do it as admin_externalpage&#039;s were only left in Moodle 2.0 for backwards compatibility (although they are more flexible one day they will be deprecated or removed). Thank you to Darryl for raising this.&lt;br /&gt;
# If you find that your language strings aren&#039;t being used (you are getting language string notices) and you have double checked that you have turned &#039;&#039;&#039;langstringcache&#039;&#039;&#039; off then you may need to delete the language cache directory. This is located in the moodledata directory for you installation: moodledata/cache/lang/*. You should delete the directory for your chosen language by default &#039;&#039;en&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Adding theme upgrade code]]&lt;br /&gt;
* [[Styling and customising the dock]]&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/discuss.php?d=152053 Theme 2.0: Adding a settings page to your theme] forum discussion&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Creating_a_theme_settings_page&amp;diff=46311</id>
		<title>Creating a theme settings page</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Creating_a_theme_settings_page&amp;diff=46311"/>
		<updated>2014-09-24T22:33:30Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Finishing settings.php */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}This document looks at how to create a settings page for your Moodle 2.x.x theme and how to make use of those settings within the CSS and layout files for your theme.&lt;br /&gt;
&lt;br /&gt;
This is a pretty advanced topic and will require that you have at least an intermediate knowledge of PHP, CSS, and development in general.&lt;br /&gt;
&lt;br /&gt;
==Before we begin==&lt;br /&gt;
[[Image:Theme.settings.page.03.png|350px|thumb|Our end goal. The settings page.]]&lt;br /&gt;
[[Image:Theme.settings.page.10.png|350px|thumb|And what it can do.]]&lt;br /&gt;
There is a huge body of knowledge that we must cover in following through this document and as such I think the best way to write this is as a tutorial.&lt;br /&gt;
&lt;br /&gt;
My intentions for this tutorial are to replicate the standard theme but with a settings page that allows the administrator to set a background colour, set a logo to use with the page, and probably several other minor settings to change the way in which the theme is displayed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I will start this tutorial by creating a new theme which will be largely a copy/paste of the current standard theme. I expect that anyone working through this tutorial has previously read the tutorial I wrote on [[Themes 2.0 creating your first theme|creating your first theme]]. If you haven&#039;t go read it now because I&#039;m not going to go into much detail until we get to the actual process of customising the theme and introducing the settings page.&lt;br /&gt;
&lt;br /&gt;
So before we finally get this started please ensure you can check off everything on the following requirements list.&lt;br /&gt;
* Have a Moodle installation that has already been installed and configured and is ready to use.&lt;br /&gt;
* Have full read/write access to that installation.&lt;br /&gt;
* Be prepared to delete that installation at the end of this... we will destroy it!&lt;br /&gt;
* Have a development environment prepared and ready to use. This includes:&lt;br /&gt;
** Your favourite editor installed, running, and pointed at the themes directory of your installation.&lt;br /&gt;
** Your browser open and your site visible.&lt;br /&gt;
** A bottomless coffee pot... decaf won&#039;t help you with this one.&lt;br /&gt;
* Have set the following settings:&lt;br /&gt;
** &#039;&#039;&#039;themedesignermode&#039;&#039;&#039; if you don&#039;t know what this is please read the [[Themes 2.0 creating your first theme|creating your first theme]] tutorial.&lt;br /&gt;
** &#039;&#039;&#039;allowthemechangeonurl&#039;&#039;&#039; turn this on, it allows you to change themes on the URL and is very handy when developing themes. &#039;&#039;Site Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; Theme settings&#039;&#039;&lt;br /&gt;
** &#039;&#039;&#039;langstringcache&#039;&#039;&#039; if you don&#039;t turn this off you won&#039;t see your strings when they are added. &#039;&#039;Site Administration &amp;gt; Language &amp;gt; Language settings&#039;&#039;&lt;br /&gt;
* And finally an insane ambition to create a customisable theme.&lt;br /&gt;
&lt;br /&gt;
For those interested the theme that I create throughout this tutorial can be downloaded from the forum post in which I announce this document: http://moodle.org/mod/forum/discuss.php?d=152053&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:right;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Our goals for this tutorial==&lt;br /&gt;
The following is just a list goals that I hope to achieve during this tutorial. They are laid out here so that I can easily refer back to them and so that you can easily find them.&lt;br /&gt;
# Create a new theme called &#039;&#039;&#039;demystified&#039;&#039;&#039; based upon the standard theme within Moodle 2.0.&lt;br /&gt;
# Make some minor changes to that theme to allow us to more easily see what is going on.&lt;br /&gt;
# Create a settings page for the demystified theme.&lt;br /&gt;
# Add several settings to our settings page.&lt;br /&gt;
# Use some of those settings to alter our CSS.&lt;br /&gt;
# Use the rest of those settings within our layout file..&lt;br /&gt;
# Discuss the good, the bad, and limits of what we have just created.&lt;br /&gt;
&lt;br /&gt;
So I can see you are all very excited about this point and that you would love to know what settings we are going to create; So here they are:&lt;br /&gt;
&lt;br /&gt;
A setting to ...&lt;br /&gt;
* change the background colour (CSS).&lt;br /&gt;
* set the path to an image that we will use as a logo on all pages (Layout files).&lt;br /&gt;
* override the width of the block regions (CSS).&lt;br /&gt;
* allow a note to be added to the footer of all pages (Layout files).&lt;br /&gt;
* allow custom CSS to be written to do anything the user wants. (CSS)&lt;br /&gt;
&lt;br /&gt;
==Creating the demystified theme==&lt;br /&gt;
Before we start here I want to remind you that I am going to look at this only briefly as I am making the assumption that you have read the [[Themes 2.0 creating your first theme|creating your first theme]] tutorial.&lt;br /&gt;
&lt;br /&gt;
Well lets get into it....&lt;br /&gt;
&lt;br /&gt;
The first thing we need to do is create a directory for our theme which we will call demystified. &lt;br /&gt;
&lt;br /&gt;
So within your Moodle directory create the following folder &#039;&#039;&#039;moodle/theme/demystified&#039;&#039;&#039;. At the same time you can also create the following files and folders which we will get to soon.&lt;br /&gt;
* The file &#039;&#039;&#039;moodle/theme/demystified/config.php&#039;&#039;&#039; for our config information.&lt;br /&gt;
* The directory &#039;&#039;&#039;moodle/theme/demystified/layout&#039;&#039;&#039; for our layout files.&lt;br /&gt;
* The directory &#039;&#039;&#039;moodle/theme/demystified/style&#039;&#039;&#039; for our css files.&lt;br /&gt;
* The file &#039;&#039;&#039;moodle/theme/demystified/style/core.css&#039;&#039;&#039; which will contain our special CSS.&lt;br /&gt;
&lt;br /&gt;
Next we will copy the layout files from the base theme to our new theme demystified. We are basing the demystified theme on the standard theme however that doesn&#039;t use it&#039;s own layout files it uses the base theme&#039;s layout files so those are the ones we want. &lt;br /&gt;
&lt;br /&gt;
The reason that we are coping these layout files is that later on in this tutorial we will be modifying them to make use of our new settings... so copy all of the layout files from &#039;&#039;&#039;moodle/theme/base/layout&#039;&#039;&#039; to &#039;&#039;&#039;moodle/theme/demystified/layout&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
There should be three files that you just copied:&lt;br /&gt;
# embedded.php&lt;br /&gt;
# frontpage.php&lt;br /&gt;
# general.php&lt;br /&gt;
&lt;br /&gt;
Now we need to populate demystified/config.php with the settings for our new theme. They are as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;name = &#039;demystified&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Simply sets the name of our theme.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;,&#039;base&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This theme is extending both the standard theme and the base theme. Remember when extending a theme you also need to extend its parents or things might not work correctly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;core&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This tells our theme that we want to use the file &#039;&#039;&#039;demystified/style/core.css&#039;&#039;&#039; with this theme.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;height:300px;overflow-y:scroll;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Most backwards compatible layout without the blocks - this is the layout used by default&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&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;
    // 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;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;
    // Main course page&lt;br /&gt;
    &#039;course&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;coursecategory&#039; =&amp;gt; array(&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;
    // part of course, typical for modules - default page layout if $cm specified in require_login()&lt;br /&gt;
    &#039;incourse&#039; =&amp;gt; array(&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;
    // The site home page.&lt;br /&gt;
    &#039;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;frontpage.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;
    // Server administration scripts.&lt;br /&gt;
    &#039;admin&#039; =&amp;gt; array(&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;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // My dashboard page&lt;br /&gt;
    &#039;mydashboard&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // My public page&lt;br /&gt;
    &#039;mypublic&#039; =&amp;gt; array(&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;
    &#039;login&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    // Pages that appear in pop-up windows - no navigation, no blocks, no header.&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // No blocks and minimal footer - used for legacy frame layouts only!&lt;br /&gt;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible&lt;br /&gt;
    &#039;embedded&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Used during upgrade and install, and for the &#039;This site is undergoing maintenance&#039; message.&lt;br /&gt;
    // This must not have any blocks, and it is good idea if it does not have links to&lt;br /&gt;
    // other places - for example there should not be a home link in the footer...&lt;br /&gt;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Now that all looks very complicated however its really not too bad as it is just copied from the base theme&#039;s config.php file. We can do this because we copied the layout files from the base theme to begin with and for the time being there are no changes that we wish to make. Simply open up &#039;&#039;&#039;theme/base/config.php&#039;&#039;&#039; and copy the layouts from there.&lt;br /&gt;
&lt;br /&gt;
And that is it. The config.php file for our demystified theme is complete. The full source is shown below:&lt;br /&gt;
&amp;lt;div style=&amp;quot;height:300px;overflow-y:scroll;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
// This file is part of Moodle - http://moodle.org/&lt;br /&gt;
//&lt;br /&gt;
// Moodle is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// Moodle is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with Moodle.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * The demystified theme config file&lt;br /&gt;
 *&lt;br /&gt;
 * This theme was created to document the process of adding a settings page to a theme&lt;br /&gt;
 *&lt;br /&gt;
 * @copyright 2010 Sam Hemelryk&lt;br /&gt;
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
// The name of our theme&lt;br /&gt;
$THEME-&amp;gt;name = &#039;demystified&#039;;&lt;br /&gt;
&lt;br /&gt;
// The other themes this theme extends&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;,&#039;base&#039;);&lt;br /&gt;
&lt;br /&gt;
// The CSS files this theme uses (located in the style directory)&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;core&#039;);&lt;br /&gt;
&lt;br /&gt;
// The layout definitions for this theme&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Most backwards compatible layout without the blocks - this is the layout used by default&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&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;
    // 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;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;
    // Main course page&lt;br /&gt;
    &#039;course&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;coursecategory&#039; =&amp;gt; array(&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;
    // part of course, typical for modules - default page layout if $cm specified in require_login()&lt;br /&gt;
    &#039;incourse&#039; =&amp;gt; array(&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;
    // The site home page.&lt;br /&gt;
    &#039;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;frontpage.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;
    // Server administration scripts.&lt;br /&gt;
    &#039;admin&#039; =&amp;gt; array(&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;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // My dashboard page&lt;br /&gt;
    &#039;mydashboard&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // My public page&lt;br /&gt;
    &#039;mypublic&#039; =&amp;gt; array(&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;
    &#039;login&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    // Pages that appear in pop-up windows - no navigation, no blocks, no header.&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // No blocks and minimal footer - used for legacy frame layouts only!&lt;br /&gt;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible&lt;br /&gt;
    &#039;embedded&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Used during upgrade and install, and for the &#039;This site is undergoing maintenance&#039; message.&lt;br /&gt;
    // This must not have any blocks, and it is good idea if it does not have links to&lt;br /&gt;
    // other places - for example there should not be a home link in the footer...&lt;br /&gt;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The screenshot below shows both the directory structure we have now created and the theme presently.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.01.png]]&lt;br /&gt;
&lt;br /&gt;
To view the theme so far open you browser and enter the URL of your site followed by &#039;&#039;&#039;?theme=demystified&#039;&#039;&#039;. You should see the theme that we just created which will look exactly like the base standard theme.&lt;br /&gt;
&lt;br /&gt;
The final thing that we want to do is add a little bit of CSS to the demystified theme that will both visually set this theme apart from the standard theme and second build a the base which our settings can later extend.&lt;br /&gt;
&lt;br /&gt;
I added the following snippet of CSS to the file &#039;&#039;&#039;demystified/style/core.css&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
html {background-color:#DDD;}&lt;br /&gt;
body {margin:30px;padding:0;border:1px solid #333;border-width:0 10px 0 10px;background-color:#333;}&lt;br /&gt;
body #page {background-color:#FFF;position:relative;top:-10px;}&lt;br /&gt;
.block .header {background-image:none;background-color:#0C5CAC;border:1px solid #0C5CAC;color:#FFF;}&lt;br /&gt;
.block {border-color:#4BA7FF;background-color:#DDEEFF;}&lt;br /&gt;
.block .content {background-color:#F1F8FF;}&lt;br /&gt;
a:link,&lt;br /&gt;
a:visited {color:#0C5CAC;}&lt;br /&gt;
a:hover {color:#C77500;}&lt;br /&gt;
#page #page-header {background-color:#0C5CAC;margin:0;padding:0;width:100%;color:#fff;}&lt;br /&gt;
#page #page-header a:link, #page #page-header a:visited {color:#FFAC02}&lt;br /&gt;
#page #page-header .navbar, #page #page-header .navbar a:link, #page #page-header .navbar a:visited {color:#0C5CAC;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The CSS that we have just added to our theme sets a couple of colours on the front page. Presently this is the only CSS I will add, I know it isn&#039;t complete by any means but it achieves it&#039;s purpose as the screenshot below illustrates.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.02.png|715px|thumb|left|The newly styles demystified theme]]&amp;lt;br style=&amp;quot;clear:both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And with that I will move on to the real purpose of this tutorial, creating the settings page&lt;br /&gt;
&lt;br /&gt;
==Setting up the settings page==&lt;br /&gt;
With the demystified theme set up it is time to create the settings page. This is where the real PHP fun begins.&lt;br /&gt;
&lt;br /&gt;
For those of you who happen to be familiar with development of modules, blocks or other plugin types you have probably encountered settings pages before and this is not going to be any different.&lt;br /&gt;
&lt;br /&gt;
However for those who haven&#039;t which I imagine is most of you this is going to be quite a challenge. I will try to walk through this step by step however if at any point you get stuck don&#039;t hesitate to ask in the forums as I imagine you will get a speedy response.&lt;br /&gt;
&lt;br /&gt;
===How settings pages work in Moodle===&lt;br /&gt;
Settings pages can be used by nearly every plugin type, of which themes is of course one. The way in which it all works isn&#039;t too tricky to understand. &lt;br /&gt;
&lt;br /&gt;
All of the settings for Moodle can be configured through the administrator interfaces when logged in. I am sure that everyone here has seen those pages and has changed a setting or two before so you will all know what I am talking about. Well the settings page for a theme is no different. It will be shown in the administration pages tree under &#039;&#039;&#039;Appearance &amp;gt; Themes&#039;&#039;&#039; and all we have to do is tell Moodle what settings there are.&lt;br /&gt;
&lt;br /&gt;
This is done by creating a settings.php file within our theme into which we will add code that tells Moodle about the settings we want to add/use.&lt;br /&gt;
&lt;br /&gt;
When telling Moodle about each setting we are simply creating a new &#039;&#039;admin_setting&#039;&#039; instance of the type we want and the properties we want and then adding it to our settings page.&lt;br /&gt;
&lt;br /&gt;
There is really not much more too it at this level. Things can get very complex very fast so the best thing we can do now is start creating our settings.php file for the demystified theme and see where it leads us.&lt;br /&gt;
&lt;br /&gt;
===Creating the settings page===&lt;br /&gt;
So as mentioned before we need a settings.php file which we will create now. To begin with create the file &#039;&#039;&#039;theme/demystified/settings.php&#039;&#039;&#039; and open it in your favourite editor so its ready to go.&lt;br /&gt;
&lt;br /&gt;
Before we start adding code however lets just remember the settings that we want to create:&lt;br /&gt;
* change the background colour (CSS).&lt;br /&gt;
* set the path to an image that we will use as a logo on all pages (Layout files).&lt;br /&gt;
* override the width of the block regions (CSS).&lt;br /&gt;
* allow a note to be added to the footer of all pages (Layout files).&lt;br /&gt;
* allow custom CSS to be written to do anything the user wants. (CSS)&lt;br /&gt;
&lt;br /&gt;
Alright.&lt;br /&gt;
&lt;br /&gt;
Now thinking about this the first setting is as basic as it gets, all we need is a text box that the user can type a colour into.&lt;br /&gt;
&lt;br /&gt;
The second is to allow a logo to be used in the header of each page. What we want here is a path but should it be a physical path e.g. C:/path/to/image.png or should it be a web path e.g. &amp;lt;nowiki&amp;gt;http://mysite.com/path/to/image.png&amp;lt;/nowiki&amp;gt;?&lt;br /&gt;
For the purpose of this tutorial I am going to go with a web path because it is going to be easier to code and will hopefully be a little easier to understand to begin with.&lt;br /&gt;
&lt;br /&gt;
The third setting is a little more complex. For this I want a drop down box with some specific widths that the administrator can select.&lt;br /&gt;
&lt;br /&gt;
The forth and the fifth settings are both pretty straight forward, there we want a textarea into which the user can enter what ever they want and we will do something useful with it.&lt;br /&gt;
&lt;br /&gt;
Now that we have an understanding about the settings we wish to define pull up your editor and lets start coding....&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Settings for the demystified theme&lt;br /&gt;
 */&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die;&lt;br /&gt;
&lt;br /&gt;
if ($ADMIN-&amp;gt;fulltree) {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is the first bit of code we must enter, the first line is of course just the opening php tag, secondly we have a comment that describes this file, and then we get create a new &#039;&#039;&#039;admin_settingspage object&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This admin_settingspage object that we have just created is a representation of our settings page and is the what we add our new settings to. When creating it we give it two arguments, first the name of the page which is in this case &#039;&#039;&#039;theme_&#039;&#039;themename&#039;&#039;&#039;&#039;&#039; and the title for the page which we get with the get_string method.&lt;br /&gt;
&lt;br /&gt;
At the moment I&#039;m not going to worry about adding the string, we will get to that later once we have defined all of our settings.&lt;br /&gt;
&lt;br /&gt;
====Background colour====&lt;br /&gt;
&lt;br /&gt;
With the page now created lets add our first setting: Background colour.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Background colour setting&lt;br /&gt;
$name = &#039;theme_demystified/backgroundcolor&#039;;&lt;br /&gt;
$title = get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = &#039;#DDD&#039;;&lt;br /&gt;
$setting = new admin_setting_configtext($name, $title, $description, $default, PARAM_CLEAN, 12);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Thankfully this isn&#039;t as difficult as it initially looks.&lt;br /&gt;
&lt;br /&gt;
The first line of code is creating a variable for the name of the background colour setting. In this case it is &#039;&#039;&#039;theme_demystified/backgroundcolor&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
The name is very important, for the setting to be usable we have to follow a strict naming convention. &#039;&#039;&#039;theme_&#039;&#039;themename&#039;&#039;/&#039;&#039;settingname&#039;&#039;&#039;&#039;&#039; where &#039;&#039;&#039;&#039;&#039;themename&#039;&#039;&#039;&#039;&#039; is the name of the theme the setting belongs to and &#039;&#039;&#039;&#039;&#039;settingname&#039;&#039;&#039;&#039;&#039; is the name for the setting by which we will use it.&lt;br /&gt;
&lt;br /&gt;
The second line of code creates a variable that contains the title of the setting. This is what the user sees to the right of the setting on the settings page and should be a short description of the setting. Here we are again using the &#039;&#039;get_string&#039;&#039; method so we will need to remember to add that string later on.&lt;br /&gt;
&lt;br /&gt;
The third line of code sets the description. This should describe what the setting does or how it works and again we will use the get_string method.&lt;br /&gt;
&lt;br /&gt;
The fourth line creates a variable that will be used as the default value for the setting. Because this setting is a colour we want an HTML colour to be the default value.&lt;br /&gt;
&lt;br /&gt;
The fifth line is where we put it all together. Here we create a new &#039;&#039;&#039;admin_setting_configtext&#039;&#039;&#039; object. This object will represent the background colour setting.&lt;br /&gt;
&lt;br /&gt;
When we create it we need to give it 6 different things.&lt;br /&gt;
# The name of the setting. In this case we have a variable &#039;&#039;&#039;$name&#039;&#039;&#039;.&lt;br /&gt;
# The title for this setting. We used the variable &#039;&#039;&#039;$title&#039;&#039;&#039;.&lt;br /&gt;
# The description of the setting &#039;&#039;&#039;$description&#039;&#039;&#039;.&lt;br /&gt;
# The default value for the setting. &#039;&#039;&#039;$default&#039;&#039;&#039; is the variable this.&lt;br /&gt;
# The type of value we want the user to enter. For this we have used PARAM_CLEAN which tells Moodle to get rid of any nasties from what the user enters.&lt;br /&gt;
# The size of the field. In our case 12 characters will be plenty.&lt;br /&gt;
&lt;br /&gt;
The sixth and final line of code adds our newly created setting to the administration page we created earlier.&lt;br /&gt;
&lt;br /&gt;
That is it we have successfully created and added our first setting, however there are several more to settings to do, and there are a couple of important things that you need to be aware of before we move on.&lt;br /&gt;
&lt;br /&gt;
First: There are several different types of settings that you can create and add to a page, and each one may differ in what they need you to give them. In this case it was name, title, description, default, type, and size. However other settings will likely require different things. Smart editors like Netbeans or Eclipse can tell you what is required, otherwise you will need to research it.&lt;br /&gt;
&lt;br /&gt;
Second: Normally settings are declared on one line as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$setting-&amp;gt;add(new admin_setting_configtext(&#039;theme_demystified/backgroundcolor&#039;, get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;), get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;), &#039;#DDD&#039;, PARAM_CLEAN, 12));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
While this is structurally identical as all we have done is move everything onto one line and do away with the variables it is a little harder to read when you are learning all of this.&lt;br /&gt;
&lt;br /&gt;
====The logo file====&lt;br /&gt;
Time to create the second setting that will allow the user to enter a URL to an image they wish to use as the logo on their site.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Logo file setting&lt;br /&gt;
$name = &#039;theme_demystified/logo&#039;;&lt;br /&gt;
$title = get_string(&#039;logo&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;logodesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtext($name, $title, $description, &#039;&#039;, PARAM_URL);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The first thing that you will notice about this setting that it is very similar to the first setting, in fact all we have changed is the name, title, description, and default value. We have however changed the value type from PARAM_CLEAN to PARAM_URL, this makes sure the user enters a URL. You will also notice that for this one we don&#039;t set a size for the field as we have no idea how long the URL will be.&lt;br /&gt;
&lt;br /&gt;
====Block region width====&lt;br /&gt;
The third setting should allow the user to set a width for the block regions that will be used as columns.&lt;br /&gt;
&lt;br /&gt;
For this setting I want to do something a little different from the previous two, here I want to use a select box so that the user selects a width for the column from a list I provide.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Block region width&lt;br /&gt;
$name = &#039;theme_demystified/regionwidth&#039;;&lt;br /&gt;
$title = get_string(&#039;regionwidth&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;regionwidthdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = 200;&lt;br /&gt;
$choices = array(150=&amp;gt;&#039;150px&#039;, 170=&amp;gt;&#039;170px&#039;, 200=&amp;gt;&#039;200px&#039;, 240=&amp;gt;&#039;240px&#039;, 290=&amp;gt;&#039;290px&#039;, 350=&amp;gt;&#039;350px&#039;, 420=&amp;gt;&#039;420px&#039;);&lt;br /&gt;
$setting = new admin_setting_configselect($name, $title, $description, $default, $choices);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
So looking at the code: The first four lines you will recognise. $name, $title, $description, and $default are all being set.&lt;br /&gt;
&lt;br /&gt;
The fifth line of code however introduces something new. Of course in order to have a select box we have to have options, in this case we have an array of options stored in the variable $choices.&lt;br /&gt;
&lt;br /&gt;
The array of options is constructed of a collection of &#039;&#039;&#039;&#039;&#039;value&#039;&#039;&#039; =&amp;gt; &#039;&#039;&#039;label&#039;&#039;&#039;&#039;&#039; pairs. Notice how we don&#039;t add &#039;&#039;&#039;px&#039;&#039;&#039; to the value. This is is very intentional as later on I need to do a little bit of math with that value so we need it to be a number.&lt;br /&gt;
&lt;br /&gt;
The lines after should look familiar again, the only difference being that instead of a &#039;&#039;admin_setting_configtext&#039;&#039; setting we have created a &#039;&#039;admin_setting_configselect&#039;&#039; for which we must give the choices for the select box as the fifth argument.&lt;br /&gt;
&lt;br /&gt;
Woohoo, we&#039;ve just created our first select box setting.&lt;br /&gt;
&lt;br /&gt;
====Foot note====&lt;br /&gt;
Now to create the foot note setting. Here we want the user to be able to enter some arbitrary text that will be used in the footer of the page. For this I want the user to be able to enter some HTML so I will create an editor setting.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Foot note setting&lt;br /&gt;
$name = &#039;theme_demystified/footnote&#039;;&lt;br /&gt;
$title = get_string(&#039;footnote&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;footnotedesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_confightmleditor($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
How simple is that!&lt;br /&gt;
&lt;br /&gt;
It is just about identical to the first two settings except that for this we have created a &#039;&#039;admin_setting_confightmleditor&#039;&#039; setting rather than a text setting.&lt;br /&gt;
&lt;br /&gt;
Note: You can also set the columns and rows for the editor setting using the fifth and sixth arguments.&lt;br /&gt;
&lt;br /&gt;
====Custom CSS====&lt;br /&gt;
The final setting is to allow the user to add some custom CSS to the theme that will be used on every page. I want this to be a plain textarea into which the user can enter CSS.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Custom CSS file&lt;br /&gt;
$name = &#039;theme_demystified/customcss&#039;;&lt;br /&gt;
$title = get_string(&#039;customcss&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;customcssdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtextarea($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Just like the editor or text settings. It&#039;s getting very easy now!&lt;br /&gt;
&lt;br /&gt;
====Finishing settings.php====&lt;br /&gt;
With all of our settings defined and added to our page that we created right at the beginning it is time to finish it all off.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
} // This is the closing brace that encloses all the above settings. &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The above line is the final line for the page. It is adding the page that we have created &#039;&#039;&#039;$setting&#039;&#039;&#039; to the admin tree structure. In this case it is adding it to the themes branch.&lt;br /&gt;
&lt;br /&gt;
The following is the completed source for our settings.php ..... for your copy/paste pleasure.&lt;br /&gt;
&amp;lt;div style=&#039;height:300px;width:90%;overflow:auto;&#039;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Settings for the demystified theme&lt;br /&gt;
 */&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die;&lt;br /&gt;
 &lt;br /&gt;
if ($ADMIN-&amp;gt;fulltree) {&lt;br /&gt;
&lt;br /&gt;
    // Background colour setting&lt;br /&gt;
    name = &#039;theme_demystified/backgroundcolor&#039;;&lt;br /&gt;
    $title = get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
    $description = get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
    $default = &#039;#DDD&#039;;&lt;br /&gt;
    $setting = new admin_setting_configtext($name, $title, $description, $default, PARAM_CLEAN, 12);&lt;br /&gt;
    $setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
    $settings-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
    // Logo file setting.&lt;br /&gt;
    $name = &#039;theme_demystified/logo&#039;;&lt;br /&gt;
    $title = get_string(&#039;logo&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
    $description = get_string(&#039;logodesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
    $setting = new admin_setting_configtext($name, $title, $description, &#039;&#039;, PARAM_URL);&lt;br /&gt;
    $setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
    $settings-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
    // Block region width.&lt;br /&gt;
    $name = &#039;theme_demystified/regionwidth&#039;;&lt;br /&gt;
    $title = get_string(&#039;regionwidth&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
    $description = get_string(&#039;regionwidthdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
    $default = 200;&lt;br /&gt;
    $choices = array(150=&amp;gt;&#039;150px&#039;, 170=&amp;gt;&#039;170px&#039;, 200=&amp;gt;&#039;200px&#039;, 240=&amp;gt;&#039;240px&#039;, 290=&amp;gt;&#039;290px&#039;, 350=&amp;gt;&#039;350px&#039;, 420=&amp;gt;&#039;420px&#039;);&lt;br /&gt;
    $setting = new admin_setting_configselect($name, $title, $description, $default, $choices);&lt;br /&gt;
    $setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
    $settings-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
    // Foot note setting.&lt;br /&gt;
    $name = &#039;theme_demystified/footnote&#039;;&lt;br /&gt;
    $title = get_string(&#039;footnote&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
    $description = get_string(&#039;footnotedesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
    $setting = new admin_setting_confightmleditor($name, $title, $description, &#039;&#039;);&lt;br /&gt;
    $setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
    $settings-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
    // Custom CSS file.&lt;br /&gt;
    $name = &#039;theme_demystified/customcss&#039;;&lt;br /&gt;
    $title = get_string(&#039;customcss&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
    $description = get_string(&#039;customcssdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
    $setting = new admin_setting_configtextarea($name, $title, $description, &#039;&#039;);&lt;br /&gt;
    $setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
    $settings-&amp;gt;add($setting);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Creating a language file and adding our strings===&lt;br /&gt;
As I&#039;m sure none of you have forgotten, throughout the creation of the our settings.php page, we used a lot of strings that I mentioned we would set later on. Well now is the time to set those strings.&lt;br /&gt;
&lt;br /&gt;
First up create the following directories and file for our language strings:&lt;br /&gt;
* Directory &#039;&#039;&#039;theme/demystified/lang&#039;&#039;&#039;&lt;br /&gt;
* Directory &#039;&#039;&#039;theme/demystified/lang/en&#039;&#039;&#039;&lt;br /&gt;
* File &#039;&#039;&#039;theme/demystified/lang/theme_demystified.php&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
What we have created here is the required structure for Moodle to start looking for language strings.&lt;br /&gt;
&lt;br /&gt;
First Moodle locates the lang directory, once found it looks within that directory for another directory that uses the character code for the language the user has selected, by default this is &#039;&#039;&#039;en&#039;&#039;&#039; for English. Once that is found it looks for the appropriate language file, in this case &#039;&#039;&#039;theme_demystified.php&#039;&#039;&#039; from which it will load all language strings for our theme.&lt;br /&gt;
&lt;br /&gt;
If English isn&#039;t your chosen language simply replace the &#039;&#039;en&#039;&#039; directory with one that uses your chosen languages character code (two letters).&lt;br /&gt;
&lt;br /&gt;
We can now add our language strings to &#039;&#039;&#039;theme/demystified/lang/theme_demystified.php&#039;&#039;&#039;. Copy and paste the following lines of PHP into this file.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This file contains the strings used by the demystified theme&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
$string[&#039;backgroundcolor&#039;] = &#039;Background colour&#039;;&lt;br /&gt;
$string[&#039;backgroundcolordesc&#039;] = &#039;This sets the background colour for the theme.&#039;;&lt;br /&gt;
$string[&#039;configtitle&#039;] = &#039;Demystified theme&#039;;&lt;br /&gt;
$string[&#039;customcss&#039;] = &#039;Custom CSS&#039;;&lt;br /&gt;
$string[&#039;customcssdesc&#039;] = &#039;Any CSS you enter here will be added to every page allowing your to easily customise this theme.&#039;;&lt;br /&gt;
$string[&#039;footnote&#039;] = &#039;Footnote&#039;;&lt;br /&gt;
$string[&#039;footnotedesc&#039;] = &#039;The content from this textarea will be displayed in the footer of every page.&#039;;&lt;br /&gt;
$string[&#039;logo&#039;] = &#039;Logo&#039;;&lt;br /&gt;
$string[&#039;logodesc&#039;] = &#039;Enter the URL to an image to use as the logo for this site. Should be http://www.yoursite.com/path/to/logo.png&#039;;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;Demystified&#039;;&lt;br /&gt;
$string[&#039;regionwidth&#039;] = &#039;Column width&#039;;&lt;br /&gt;
$string[&#039;regionwidthdesc&#039;] = &#039;This sets the width of the two block regions that form the left and right columns.&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above lines of code I have added an entry for each language string we used within &#039;&#039;settings.php&#039;&#039;. When adding language strings like this make sure you use single quotes and try to keep things alphabetical - it helps greatly when managing strings.&lt;br /&gt;
&lt;br /&gt;
Now when we view the settings page there will not be any errors or strings missing.&lt;br /&gt;
&lt;br /&gt;
===Having a look at what we have created===&lt;br /&gt;
Now that we have created our settings page (settings.php) and added all of the language strings it is time to have a look at things in your browser.&lt;br /&gt;
&lt;br /&gt;
Open your browser and enter the URL to your site. When you arrive at your site login as an administrator.&lt;br /&gt;
&lt;br /&gt;
If you are not redirected to view the new settings change your URL to &amp;lt;nowiki&amp;gt;http://www.yoursite.com/admin/&amp;lt;/nowiki&amp;gt; and your will see a screen to set the new theme settings we have just created. This lets us know that everything has worked correctly.&lt;br /&gt;
&lt;br /&gt;
At any point now you are able to log in as administrator and within the settings block browse to &#039;&#039;&#039;Site administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; Demystified theme&#039;&#039;&#039; to change those settings.&lt;br /&gt;
&lt;br /&gt;
The screenshot below shows you what you should see at this point:&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.03.png|715px|thumb|left|The settings page we just created]]&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using the settings in CSS==&lt;br /&gt;
With the settings page now created and operational it is time to make use of our new settings. The settings that we want to use within our CSS is as follows:&lt;br /&gt;
&lt;br /&gt;
; backgroundcolor : Will be used to set the background colour in CSS.&lt;br /&gt;
; regionwidth : Will be the width of the column for CSS.&lt;br /&gt;
; customcss : Will be some custom CSS to add to our stylesheet.&lt;br /&gt;
&lt;br /&gt;
At this point those names are the names we used for our setting with the slash and everything before it having been removed.&lt;br /&gt;
&lt;br /&gt;
Before we start tearing into some code it is important that we have a look at what we are going to do and how we are going to go about it.&lt;br /&gt;
&lt;br /&gt;
===How it all works within Moodle===&lt;br /&gt;
The first thing to understand is that while Moodle allows you to create a settings page and automates it inclusion and management right into the administration interfaces there is no smart equivalent for using the settings. This is simply because there is no way to predict how people will want to use the settings.&lt;br /&gt;
&lt;br /&gt;
However don&#039;t think of this as a disadvantage, in fact it is quite the contrary. Although we can&#039;t just &#039;&#039;use&#039;&#039; our settings we can take full control over how and where we use them. It means it will take a little more code but in the end that will work to our advantage as we can do anything we want.&lt;br /&gt;
&lt;br /&gt;
Moodle does help us out a little but not in an obvious way. The first thing that Moodle does is look for a config variable &#039;&#039;&#039;csspostprocess&#039;&#039;&#039; that should be the name of a function which we want called to make any changes to the CSS after it has been prepared.&lt;br /&gt;
&lt;br /&gt;
The second thing Moodle does is include a lib.php from the theme&#039;s directory if one exists (also for the themes the current theme extends.) which ensures that as long as we write our code within &#039;&#039;&#039;theme/demystified/lib.php&#039;&#039;&#039; it will be included and ready to be used.&lt;br /&gt;
&lt;br /&gt;
The third and final thing Moodle does that will help us out here is ensure that by the time any of code is ready to execute the settings have been prepared and are ready to be used within a theme config object which is passed into our &#039;&#039;csspostprocess&#039;&#039; function.&lt;br /&gt;
&lt;br /&gt;
===Our plan===&lt;br /&gt;
As you have already probably guessed we will need to create a function to make the changes to the CSS that we want. We will then set the theme config option &#039;&#039;&#039;$THEME-&amp;gt;csspostprocess&#039;&#039;&#039; to the name of our function.&lt;br /&gt;
&lt;br /&gt;
By doing this when Moodle builds the CSS file it will call our function afterwards with the CSS and the theme object that contains our setting.&lt;br /&gt;
&lt;br /&gt;
Now we know that we will use the &#039;&#039;csspostprocess&#039;&#039; function but how are we going to change the CSS, we could get the function to add CSS, or we could get the function to replace something within the CSS. My personal preference is to replace something within the CSS, just like what is happening with images. If you want to use an image within CSS you would write &amp;lt;nowiki&amp;gt;[[pix:theme|imagename]]&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For settings I am going to use &amp;lt;nowiki&amp;gt;[[setting:settingname]]&amp;lt;/nowiki&amp;gt;, this way it looks a bit like something you are already familiar with.&lt;br /&gt;
&lt;br /&gt;
What we need to decide upon next is the best way in which to replace our settings tag with the settings that the user has set.&lt;br /&gt;
&lt;br /&gt;
There are two immediate options available to us:&lt;br /&gt;
# Make the &#039;&#039;csspostprocess&#039;&#039; function do all the work.&lt;br /&gt;
# Make the &#039;&#039;csspostprocess&#039;&#039; function call a separate function for each setting.&lt;br /&gt;
Solution 1 might sound like the simplest however it is going to result in a &#039;&#039;&#039;VERY&#039;&#039;&#039; complex function. Remember the user might have left settings blank or entered something that wouldn&#039;t be valid so we would need to make the sure there is some validation and a good default.&lt;br /&gt;
Because of this I think that solution 2 is the better solution.&lt;br /&gt;
&lt;br /&gt;
So we are going to need a &#039;&#039;csspostprocess&#039;&#039; function and then a function for each of the three settings we have that will do the replacements.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// This is our css post process function&lt;br /&gt;
function demystified_process_css($css, $theme) {};&lt;br /&gt;
// This replaces [[setting:backgroundcolor]] with the background colour&lt;br /&gt;
function demystified_set_backgroundcolor($css, $backgroundcolor) {};&lt;br /&gt;
// This replaces [[setting:regionwidth]] with the correct region width&lt;br /&gt;
function demystified_set_regionwidth() {$css, $regionwidth};&lt;br /&gt;
// This replaces [[setting:customcss]] with the custom css&lt;br /&gt;
function demystified_set_customcss() {$css, $customcss};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you should note about the above functions is that they all start with the theme&#039;s name. This is required to ensure that the functions are named uniquely as it is VERY unlikely that someone has already created these functions.&lt;br /&gt;
&lt;br /&gt;
So with our plan set out lets start writing the code.&lt;br /&gt;
&lt;br /&gt;
===Writing the code===&lt;br /&gt;
The very first thing that we need to do is create a lib.php for our theme into which our css processing functions are going to go. So please at this point create &#039;&#039;&#039;theme/demystified/lib.php&#039;&#039;&#039; and open it in your editor ready to go.&lt;br /&gt;
&lt;br /&gt;
The first bit of code we have to write is the function that will be called by Moodle to do the processing &#039;&#039;&#039;demystified_process_css&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
Before we start out please remember that the wonderful thing about coding is that there is any number of solutions to a problem. The solutions that you are seeing here in this tutorial are solutions that I have come up with to meet fulfil the needs of the tutorial without being so complex that they are hard to understand. This probably isn&#039;t how I would go about it normally but this is a little easier to understand for those who aren&#039;t overly familiar with PHP and object orientation.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_process_css====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function demystified_process_css($css, $theme) {&lt;br /&gt;
&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;backgroundcolor)) {&lt;br /&gt;
        $backgroundcolor = $theme-&amp;gt;settings-&amp;gt;backgroundcolor;&lt;br /&gt;
    } else {&lt;br /&gt;
        $backgroundcolor = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_backgroundcolor($css, $backgroundcolor);&lt;br /&gt;
&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;regionwidth)) {&lt;br /&gt;
        $regionwidth = $theme-&amp;gt;settings-&amp;gt;regionwidth;&lt;br /&gt;
    } else {&lt;br /&gt;
        $regionwidth = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_regionwidth($css, $regionwidth);&lt;br /&gt;
&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;customcss)) {&lt;br /&gt;
        $customcss = $theme-&amp;gt;settings-&amp;gt;customcss;&lt;br /&gt;
    } else {&lt;br /&gt;
        $customcss = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_customcss($css, $customcss);&lt;br /&gt;
&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So lets look at the things that make up this function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function demystified_process_css($css, $theme) {&lt;br /&gt;
    //.....&lt;br /&gt;
    return $css&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This of course is the function declaration. &lt;br /&gt;
&lt;br /&gt;
The function gets given two variables, the first &#039;&#039;&#039;$css&#039;&#039;&#039; is a pile of CSS as one big string, and the second is the theme object &#039;&#039;&#039;$theme&#039;&#039;&#039; that contains all of the configuration, options, and settings for our theme.&lt;br /&gt;
&lt;br /&gt;
It then returns the &#039;&#039;$css&#039;&#039; variable, essentially returning the modified CSS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    //...&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;backgroundcolor)) {&lt;br /&gt;
        $backgroundcolor = $theme-&amp;gt;settings-&amp;gt;backgroundcolor;&lt;br /&gt;
    } else {&lt;br /&gt;
        $backgroundcolor = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_backgroundcolor($css, $backgroundcolor);&lt;br /&gt;
    //...&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are processing our first setting &#039;&#039;backgroundcolor&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
The first thing that we need to do is check whether it has been set and whether it has a value. If it has then we store that value in &#039;&#039;&#039;$backgroundcolor&#039;&#039;&#039;. It is doesn&#039;t have a value then we set &#039;&#039;$backgroundcolor&#039;&#039; to null. This ensures that &#039;&#039;$backgroundcolor&#039;&#039; is set because if it isn&#039;t then you are going to get a notice (if you have debugging on).&lt;br /&gt;
&lt;br /&gt;
The final line of this block calls the function &#039;&#039;&#039;demystified_set_backgroundcolor&#039;&#039;&#039;. We haven&#039;t written this function yet but we will shortly. When we call it we give it the &#039;&#039;$css&#039;&#039; variable that contains all of the CSS and we give it the background colour variable &#039;&#039;$backgroundcolor&#039;&#039;. Once this function is finished it returns the &#039;&#039;$css&#039;&#039; variable with all of the changes made much like how our css processing function works.&lt;br /&gt;
&lt;br /&gt;
What you should also note about this code is this:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$theme-&amp;gt;settings-&amp;gt;backgroundcolor&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
As mentioned earlier &#039;&#039;$theme&#039;&#039; is an object that contains all of the configuration and settings for our theme. The &#039;&#039;$theme&#039;&#039; object has a $settings property which contains all of the settings for our theme, and finally the settings property contains a variable backgroundcolor that is the value the user entered for that setting. That is how we get a settings value.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($theme-&amp;gt;settings-&amp;gt;regionwidth)) {&lt;br /&gt;
    $regionwidth = $theme-&amp;gt;settings-&amp;gt;regionwidth;&lt;br /&gt;
} else {&lt;br /&gt;
    $regionwidth = null;&lt;br /&gt;
}&lt;br /&gt;
$css = demystified_set_regionwidth($css, $regionwidth);&lt;br /&gt;
&lt;br /&gt;
if (!empty($theme-&amp;gt;settings-&amp;gt;customcss)) {&lt;br /&gt;
    $customcss = $theme-&amp;gt;settings-&amp;gt;customcss;&lt;br /&gt;
} else {&lt;br /&gt;
    $customcss = null;&lt;br /&gt;
}&lt;br /&gt;
$css = demystified_set_customcss($css, $customcss);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These two routines are nearly identical to the routine above. For both the regionwidth and the customcss we make sure it has a value and then store it in a variable. We then call the relevant function to make the changes for that setting.&lt;br /&gt;
&lt;br /&gt;
Now that we have the general processing function it is time to write the three functions we have used but not written, &#039;&#039;demystified_set_backgroundcolor&#039;&#039;, &#039;&#039;demystified_set_regionwidth&#039;&#039;, &#039;&#039;demystified_set_customcss&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_set_backgroundcolor====&lt;br /&gt;
&lt;br /&gt;
First up demystified_set_backgroundcolor.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Sets the background colour variable in CSS&lt;br /&gt;
 *&lt;br /&gt;
 * @param string $css&lt;br /&gt;
 * @param mixed $backgroundcolor&lt;br /&gt;
 * @return string&lt;br /&gt;
 */&lt;br /&gt;
function demystified_set_backgroundcolor($css, $backgroundcolor) {&lt;br /&gt;
    $tag = &#039;[[setting:backgroundcolor]]&#039;;&lt;br /&gt;
    $replacement = $backgroundcolor;&lt;br /&gt;
    if (is_null($replacement)) {&lt;br /&gt;
        $replacement = &#039;#DDDDDD&#039;;&lt;br /&gt;
    }&lt;br /&gt;
    $css = str_replace($tag, $replacement, $css);&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ok so what is happening here?&lt;br /&gt;
&lt;br /&gt;
First we need a variable &#039;&#039;&#039;$tag&#039;&#039;&#039; that contains the tag we are going to replace. As mentioned earlier we are going to use tags that look like the image tags you are already familiar with &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:settingname]]&amp;lt;/nowiki&amp;gt;&#039;&#039;, in this case &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:backgroundcolor]]&amp;lt;/nowiki&amp;gt;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Next I am going to create a variable called &#039;&#039;&#039;$replacement&#039;&#039;&#039; into which I put &#039;&#039;&#039;$backgroundcolor&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;IF&#039;&#039;&#039; statement that comes next checks &#039;&#039;$replacement&#039;&#039; to make sure it is not null. If it is then we need to set it to a default value. In this case I have used &#039;&#039;#DDD&#039;&#039; as that was the default for the settings.&lt;br /&gt;
&lt;br /&gt;
The line after the IF statement puts it all together. The &#039;&#039;str_replace&#039;&#039; function that we are calling takes three arguments in this order:&lt;br /&gt;
# The text to search for.&lt;br /&gt;
# The text to replace it with.&lt;br /&gt;
# The text to do the replacement in.&lt;br /&gt;
It then returns the text with all of the replacements made. So in this case we are replacing the tag with the background colour and it is returning the changed CSS.&lt;br /&gt;
&lt;br /&gt;
The final thing is to return the &#039;&#039;$css&#039;&#039; variable which now contains the correct background colour.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_set_regionwidth====&lt;br /&gt;
&lt;br /&gt;
Next we have the demystified_set_regionwidth function.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Sets the region width variable in CSS&lt;br /&gt;
 *&lt;br /&gt;
 * @param string $css&lt;br /&gt;
 * @param mixed $regionwidth&lt;br /&gt;
 * @return string&lt;br /&gt;
 */&lt;br /&gt;
function demystified_set_regionwidth($css, $regionwidth) {&lt;br /&gt;
    $tag = &#039;[[setting:regionwidth]]&#039;;&lt;br /&gt;
    $doubletag = &#039;[[setting:regionwidthdouble]]&#039;;&lt;br /&gt;
    $replacement = $regionwidth;&lt;br /&gt;
    if (is_null($replacement)) {&lt;br /&gt;
        $replacement = 200;&lt;br /&gt;
    }&lt;br /&gt;
    $css = str_replace($tag, $replacement.&#039;px&#039;, $css);&lt;br /&gt;
    $css = str_replace($doubletag, ($replacement*2).&#039;px&#039;, $css);&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function is very similar to the above function however there is one key thing we are doing different. We are doing two replacements.&lt;br /&gt;
&lt;br /&gt;
# The first replacement is for the width that the user selected. In this case I am replacing the tag &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt;&#039;&#039; with the width.&lt;br /&gt;
# The second replacement is for the width x 2. This is because the page layout requires that the width be doubled for some of the CSS. Here I will replace &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidthdouble]]&amp;lt;/nowiki&amp;gt;&#039;&#039; with the doubled width.&lt;br /&gt;
&lt;br /&gt;
Remember because it is still just a number we need to add &#039;&#039;&#039;px&#039;&#039;&#039; to the end of each before we do the replacement.&lt;br /&gt;
&lt;br /&gt;
So the overall process of this function is:&lt;br /&gt;
# Define the two tags as &#039;&#039;&#039;$tag&#039;&#039;&#039; and &#039;&#039;&#039;$doubletag&#039;&#039;&#039;.&lt;br /&gt;
# Make &#039;&#039;&#039;$replacement&#039;&#039;&#039; the region width &#039;&#039;$regionwidth&#039;&#039;.&lt;br /&gt;
# Set &#039;&#039;$replacement&#039;&#039; to a default value of 200 is it is null.&lt;br /&gt;
# Replace &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; with the width.&lt;br /&gt;
# Replace &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidthdouble]]&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; with the width x 2.&lt;br /&gt;
# Return the changed CSS.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_set_customcss====&lt;br /&gt;
&lt;br /&gt;
The final function that we need to write is the demystified_set_customcss function.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Sets the custom css variable in CSS&lt;br /&gt;
 *&lt;br /&gt;
 * @param string $css&lt;br /&gt;
 * @param mixed $customcss&lt;br /&gt;
 * @return string&lt;br /&gt;
 */&lt;br /&gt;
function demystified_set_customcss($css, $customcss) {&lt;br /&gt;
    $tag = &#039;[[setting:customcss]]&#039;;&lt;br /&gt;
    $replacement = $customcss;&lt;br /&gt;
    if (is_null($replacement)) {&lt;br /&gt;
        $replacement = &#039;&#039;;&lt;br /&gt;
    }&lt;br /&gt;
    $css = str_replace($tag, $replacement, $css);&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function is just like the first function. I&#039;m going to let you work it out on your own.&lt;br /&gt;
&lt;br /&gt;
And that is it no more PHP... Hallelujah I can hear you yelling. The final thing we need to do is tell our theme about the functions we have written and put the settings tags into the CSS.&lt;br /&gt;
&lt;br /&gt;
===Finishing it all off===&lt;br /&gt;
&lt;br /&gt;
So there are two things we have to do in order to complete this section and have our the settings page implemented and our settings being used.&lt;br /&gt;
&lt;br /&gt;
First we need to tell our theme that we want to use the function &#039;&#039;demystified_process_css&#039;&#039; as the &#039;&#039;csspostprocess&#039;&#039; function. This is done very simply by adding the following line of PHP to the bottom of our theme&#039;s config.php file &#039;&#039;&#039;theme/demystified/config.php&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;csspostprocess = &#039;demystified_process_css&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done the only thing left is to add the settings tag into the CSS. Remember those settings tags are:&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:backgroundcolor]]&amp;lt;/nowiki&amp;gt; : We need to add this where ever we want the background colour setting to be used.&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt; : We need to add this where ever we want to set the width of the block regions.&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:regionwidthdouble]]&amp;lt;/nowiki&amp;gt; : We need to add this where ever we want to set the doubled width of the block regions.&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:customcss]]&amp;lt;/nowiki&amp;gt; : We need to add this to the bottom of the CSS file that we want the custom CSS added to.&lt;br /&gt;
&lt;br /&gt;
So lets make those changes in CSS now, open up your &#039;&#039;core.css&#039;&#039; file and replace the CSS with the CSS below:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/** Background color is a setting **/&lt;br /&gt;
html {background-color:[[setting:backgroundcolor]];}&lt;br /&gt;
body {margin:30px;padding:0;border:1px solid #333;border-width:0 10px 0 10px;background-color:#333;}&lt;br /&gt;
body #page {background-color:#FFF;position:relative;top:-10px;}&lt;br /&gt;
.block .header {background-image:none;background-color:#0C5CAC;border:1px solid #0C5CAC;color:#FFF;}&lt;br /&gt;
.block {border-color:#4BA7FF;background-color:#DDEEFF;}&lt;br /&gt;
.block .content {background-color:#F1F8FF;}&lt;br /&gt;
a:link,&lt;br /&gt;
a:visited {color:#0C5CAC;}&lt;br /&gt;
a:hover {color:#C77500;}&lt;br /&gt;
#page #page-header {background-color:#0C5CAC;margin:0;padding:0;width:100%;color:#fff;}&lt;br /&gt;
#page #page-header a:link, #page #page-header a:visited {color:#FFAC02}&lt;br /&gt;
#page #page-header .navbar, #page #page-header .navbar a:link, #page #page-header .navbar a:visited {color:#0C5CAC;}&lt;br /&gt;
/** Override the region width **/&lt;br /&gt;
#page-content #region-main-box {left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidthdouble]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-pre {width:[[setting:regionwidth]];left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-post {width:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidthdouble]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
/** Custom CSS **/&lt;br /&gt;
[[setting:customcss]]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will notice that &amp;lt;nowiki&amp;gt;[[setting:backgroundcolor]]&amp;lt;/nowiki&amp;gt; has been used for the html tags background colour:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
html {background-color:[[setting:backgroundcolor]];}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have also set the width of the block regions by adding &amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt; as the width for region-pre and region-post as shown below:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
#page-content #region-main-box {left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidthdouble]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-pre {width:[[setting:regionwidth]];left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-post {width:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidthdouble]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
You&#039;ll notice here that we have to set several different widths and margins using the regionwidth setting and make use of the special regionwidthdouble setting that we added.&lt;br /&gt;
&lt;br /&gt;
The final thing that we did was add the &amp;lt;nowiki&amp;gt;[[setting:customcss]]&amp;lt;/nowiki&amp;gt; to the bottom of the file to ensure that the custom CSS comes last (and therefore can override all other CSS).&lt;br /&gt;
&lt;br /&gt;
And with that we are finished. The screenshot below shows how this now looks in the browser if I set the background colour setting to &#039;&#039;&#039;&amp;lt;span style=&#039;color:#FFA800;&#039;&amp;gt;#FFA800&amp;lt;/span&amp;gt;&#039;&#039;&#039; and made the column width 240px;&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.04.png|715px|thumb|left|Our settings in action]]&amp;lt;br style=&amp;quot;clear:both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using the settings within our layout files==&lt;br /&gt;
Now that we have utilised the first three settings within our theme&#039;s CSS file it is time to implement the other two settings within the layout files so that they are written directly into the page.&lt;br /&gt;
&lt;br /&gt;
You&#039;ll be glad to know this is no where near as difficult as utilising settings within a CSS file although it still does require a little bit of PHP.&lt;br /&gt;
&lt;br /&gt;
First up is the logo setting. Into this setting the user is able to enter the URL to an image to use as the logo for the site. In my case I want this to be just a background logo on top of which I want to position the page header.&lt;br /&gt;
&lt;br /&gt;
Before I start there is one thing I need to do however and that is create a default logo background that gets shown if the user hasn&#039;t set a specific logo file. To do this I simply created an image &#039;&#039;&#039;logo.jpg&#039;&#039;&#039; and put it into a pix directory within the demystified theme. You should end up with &#039;&#039;&#039;theme/demystified/pix/logo.jpg&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Next open up the front-page layout file &#039;&#039;theme/demystified/layout/frontpage.php&#039;&#039;. At the top of the file is the PHP that checks what blocks regions the page has and a bit of other stuff. Well right below the existing bit of PHP we want to add the following code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;logo)) {&lt;br /&gt;
    $logourl = $PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;logo;&lt;br /&gt;
} else {&lt;br /&gt;
    $logourl = $OUTPUT-&amp;gt;pix_url(&#039;logo&#039;, &#039;theme&#039;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
What we are doing here is creating a variable called $logourl that will contain the URL to a logo file that was either entered by the user or if they left it blank is that of our default logo file.&lt;br /&gt;
&lt;br /&gt;
There are two things that you should notice about this. First the logo setting can be retrieved through &#039;&#039;&#039;$PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;logo&#039;&#039;&#039; and second we get the default logo url by calling &#039;&#039;&#039;$OUTPUT-&amp;gt;pix_url(&#039;logo&#039;, &#039;theme&#039;)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Now that we have the logo URL we are going to use we need to add an image to the header section of the page as shown below:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;page-header&amp;quot; class=&amp;quot;clearfix&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;img class=&amp;quot;sitelogo&amp;quot; src=&amp;quot;&amp;lt;?php echo $logourl;?&amp;gt;&amp;quot; alt=&amp;quot;Custom logo here&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;
....&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you save that and browse to your sites front page you will notice that the logo file is now being shown. Hooray. However it is probably not styled too nicely so lets quickly fix that. Open up the core.css file and add the following lines of CSS to the bottom of the file.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
#page-header {position:relative;min-height:100px;}&lt;br /&gt;
#page-header .sitelogo {float:left;}&lt;br /&gt;
#page-header .headermain {position:absolute;left:0.5em;top:50px;margin:0;float:none;font-size:40px;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
These three lines position the image correctly and if you now refresh everything should appear perfectly. &lt;br /&gt;
&lt;br /&gt;
With the logo done the last setting we need to deal with is the footnote setting. The idea with this setting was that the administrator could enter some text into the editor and it would be displayed in the footer of the page.&lt;br /&gt;
&lt;br /&gt;
This is probably the easiest setting to implement.&lt;br /&gt;
&lt;br /&gt;
Within the front page layout file that we edited above add the following lines below those we added previously.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;footnote)) {&lt;br /&gt;
    $footnote = $PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;footnote;&lt;br /&gt;
} else {&lt;br /&gt;
    $footnote = &#039;&amp;lt;!-- There was no custom footnote set --&amp;gt;&#039;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are just collecting the footnote into a variable &#039;&#039;&#039;$footnote&#039;&#039;&#039; and setting a default footnote comment if the user hasn&#039;t entered one.&lt;br /&gt;
&lt;br /&gt;
We can now echo the $footnote variable within the page footer. This can be done as shown below.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;!-- START OF FOOTER --&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;footnote&amp;quot;&amp;gt;&amp;lt;?php echo $footnote; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;p class=&amp;quot;helplink&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;?php echo page_doc_link(get_string(&#039;moodledocslink&#039;)) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And with that done we are finished! Congratulations if you got this far.&lt;br /&gt;
&lt;br /&gt;
The screenshot below shows the demystified theme we have just created that is styled by the settings page.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.05.png|715px|thumb|left|My finished demystified theme]]&amp;lt;br style=&amp;quot;clear:both&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing our creation==&lt;br /&gt;
Congratulations to you! If you&#039;ve made it this far you have done very well. Now it is time to have a look at what we have created and give it a quick test run.&lt;br /&gt;
&lt;br /&gt;
So in this tutorial we have achieved the following:&lt;br /&gt;
&lt;br /&gt;
* We created a theme called demystified that is based on the standard theme.&lt;br /&gt;
* We added a settings page to our new theme.&lt;br /&gt;
* We added the following settings to our settings page:&lt;br /&gt;
** We can set a background colour through the admin interface.&lt;br /&gt;
** We can change the logo of the site.&lt;br /&gt;
** We can change the block region width.&lt;br /&gt;
** We can add a footnote to the page footer&lt;br /&gt;
** We can add some custom CSS to seal the deal.&lt;br /&gt;
* Those settings were then used in the CSS files for our theme.&lt;br /&gt;
* They were also used in the layout files for our theme.&lt;br /&gt;
* And here we are testing it all.&lt;br /&gt;
&lt;br /&gt;
The screenshots below show my testing process and I change each setting and view the outcome. The great thing about this is that with theme designer mode on you see the changes as soon as the form refreshes.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.06.png|300px|thumb|left|Default settings]]&lt;br /&gt;
[[Image:Theme.settings.page.07.png|300px|thumb|left|Changed the background colour setting]]&lt;br /&gt;
[[Image:Theme.settings.page.08.png|300px|thumb|left|Changed the logo and region width]]&lt;br /&gt;
[[Image:Theme.settings.page.09.png|300px|thumb|left|Added a footnote]]&lt;br /&gt;
[[Image:Theme.settings.page.10.png|300px|thumb|left|Added some custom CSS]]&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:both&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The different settings you can use==&lt;br /&gt;
During this tutorial we use four different kinds of settings, a text box, text area, a select (dropdown) and the editor however as I&#039;m sure you have all guessed there is many more some of which will certainly be useful for theme settings.&lt;br /&gt;
&lt;br /&gt;
The following are examples of some of the different settings. I should add that these build upon what we have already done within the tutorial but are not included in the download.&lt;br /&gt;
&lt;br /&gt;
===Colour picker===&lt;br /&gt;
[[Image:Theme.settings.page.11.png|400px|thumb|The colour picker]]&lt;br /&gt;
I can hear you all asking now &#039;Why didn&#039;t you mention this one earlier?&#039; well the answer is simple it didn&#039;t exist when I first wrote the tutorial. It is an admin setting that I wrote several days after because of the fantastic effort people were putting into trying out settings pages.&lt;br /&gt;
&lt;br /&gt;
A bit about the colour picker. First up it is a text box that when the page loads turns into a colour picker that can be used to select a colour and can even preview the selected colour in the page (by clicking the preview button). It is designed to be very easy to use and the code is just about as simple as creating a normal text box setting.&lt;br /&gt;
&lt;br /&gt;
In the image to the left I have replaced the background colour setting we created during the tutorial with the colour picker. Lets have a look at the code involved for that.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Background colour setting&lt;br /&gt;
$name = &#039;theme_demystified/backgroundcolor&#039;;&lt;br /&gt;
$title = get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = &#039;#DDD&#039;;&lt;br /&gt;
$previewconfig = array(&#039;selector&#039;=&amp;gt;&#039;html&#039;, &#039;style&#039;=&amp;gt;&#039;backgroundColor&#039;);&lt;br /&gt;
$setting = new admin_setting_configcolourpicker($name, $title, $description, $default, $previewconfig);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
So first thing you should notice is that the first four lines of code have not changed at all!&lt;br /&gt;
&lt;br /&gt;
The first change we have is to create a variable &#039;&#039;&#039;$previewconfig&#039;&#039;&#039;. &lt;br /&gt;
This variable is used to tell the colour picker what to do when the user clicks the preview button. It should be an array that contains two things, first a selector, and second a style. &lt;br /&gt;
# The selector is a CSS selector like &#039;&#039;.page .header h2&#039;&#039;.&lt;br /&gt;
# The style is a what should change, there are two immediate values it can be, either &#039;&#039;&#039;backgroundColor&#039;&#039;&#039; or &#039;&#039;&#039;color&#039;&#039;&#039;.&lt;br /&gt;
In my case the selector is &#039;&#039;&#039;html&#039;&#039;&#039; to target the html tag and the style is backgroundColor to change the background colour.&lt;br /&gt;
&lt;br /&gt;
The second change is to use &#039;&#039;&#039;admin_setting_configcolourpicker&#039;&#039;&#039; instead of &#039;&#039;admin_setting_configtext&#039;&#039;. The arguments are nearly identical as well except that there is an extra argument to which we give the &#039;&#039;&#039;$previewconfig&#039;&#039;&#039; variable.&lt;br /&gt;
&lt;br /&gt;
And that is it! it is all you need to get the colour picker up and running.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Extra note:&#039;&#039;&#039; The $previewconfig variable is optional. If you don&#039;t want a preview button the simply set &#039;&#039;$previewconfig = null&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Common pitfalls and useful notes==&lt;br /&gt;
&lt;br /&gt;
This section is really just a collection of pointers, tips, notes, and other short useful stuff that may be of use to those attempting this tutorial.&lt;br /&gt;
&lt;br /&gt;
# First up and most importantly there are very few limitations to what you achieve in this fashion.&lt;br /&gt;
# If you get stuck or need a hand ask in the forums, there&#039;s always someone round who can help.&lt;br /&gt;
# If you do something really cool let us know, I know everyone in the community loves finding our what others are achieving.&lt;br /&gt;
# You don&#039;t have to use &#039;&#039;admin_settingpage&#039;&#039; you can also use &#039;&#039;&#039;admin_externalpage&#039;&#039;&#039; if you prefer. It should be noted however that it is not the preferred way to do it as admin_externalpage&#039;s were only left in Moodle 2.0 for backwards compatibility (although they are more flexible one day they will be deprecated or removed). Thank you to Darryl for raising this.&lt;br /&gt;
# If you find that your language strings aren&#039;t being used (you are getting language string notices) and you have double checked that you have turned &#039;&#039;&#039;langstringcache&#039;&#039;&#039; off then you may need to delete the language cache directory. This is located in the moodledata directory for you installation: moodledata/cache/lang/*. You should delete the directory for your chosen language by default &#039;&#039;en&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Adding theme upgrade code]]&lt;br /&gt;
* [[Styling and customising the dock]]&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/discuss.php?d=152053 Theme 2.0: Adding a settings page to your theme] forum discussion&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Creating_a_theme_settings_page&amp;diff=46310</id>
		<title>Creating a theme settings page</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Creating_a_theme_settings_page&amp;diff=46310"/>
		<updated>2014-09-24T22:31:03Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Finishing settings.php */ finalising updates.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}This document looks at how to create a settings page for your Moodle 2.x.x theme and how to make use of those settings within the CSS and layout files for your theme.&lt;br /&gt;
&lt;br /&gt;
This is a pretty advanced topic and will require that you have at least an intermediate knowledge of PHP, CSS, and development in general.&lt;br /&gt;
&lt;br /&gt;
==Before we begin==&lt;br /&gt;
[[Image:Theme.settings.page.03.png|350px|thumb|Our end goal. The settings page.]]&lt;br /&gt;
[[Image:Theme.settings.page.10.png|350px|thumb|And what it can do.]]&lt;br /&gt;
There is a huge body of knowledge that we must cover in following through this document and as such I think the best way to write this is as a tutorial.&lt;br /&gt;
&lt;br /&gt;
My intentions for this tutorial are to replicate the standard theme but with a settings page that allows the administrator to set a background colour, set a logo to use with the page, and probably several other minor settings to change the way in which the theme is displayed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I will start this tutorial by creating a new theme which will be largely a copy/paste of the current standard theme. I expect that anyone working through this tutorial has previously read the tutorial I wrote on [[Themes 2.0 creating your first theme|creating your first theme]]. If you haven&#039;t go read it now because I&#039;m not going to go into much detail until we get to the actual process of customising the theme and introducing the settings page.&lt;br /&gt;
&lt;br /&gt;
So before we finally get this started please ensure you can check off everything on the following requirements list.&lt;br /&gt;
* Have a Moodle installation that has already been installed and configured and is ready to use.&lt;br /&gt;
* Have full read/write access to that installation.&lt;br /&gt;
* Be prepared to delete that installation at the end of this... we will destroy it!&lt;br /&gt;
* Have a development environment prepared and ready to use. This includes:&lt;br /&gt;
** Your favourite editor installed, running, and pointed at the themes directory of your installation.&lt;br /&gt;
** Your browser open and your site visible.&lt;br /&gt;
** A bottomless coffee pot... decaf won&#039;t help you with this one.&lt;br /&gt;
* Have set the following settings:&lt;br /&gt;
** &#039;&#039;&#039;themedesignermode&#039;&#039;&#039; if you don&#039;t know what this is please read the [[Themes 2.0 creating your first theme|creating your first theme]] tutorial.&lt;br /&gt;
** &#039;&#039;&#039;allowthemechangeonurl&#039;&#039;&#039; turn this on, it allows you to change themes on the URL and is very handy when developing themes. &#039;&#039;Site Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; Theme settings&#039;&#039;&lt;br /&gt;
** &#039;&#039;&#039;langstringcache&#039;&#039;&#039; if you don&#039;t turn this off you won&#039;t see your strings when they are added. &#039;&#039;Site Administration &amp;gt; Language &amp;gt; Language settings&#039;&#039;&lt;br /&gt;
* And finally an insane ambition to create a customisable theme.&lt;br /&gt;
&lt;br /&gt;
For those interested the theme that I create throughout this tutorial can be downloaded from the forum post in which I announce this document: http://moodle.org/mod/forum/discuss.php?d=152053&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:right;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Our goals for this tutorial==&lt;br /&gt;
The following is just a list goals that I hope to achieve during this tutorial. They are laid out here so that I can easily refer back to them and so that you can easily find them.&lt;br /&gt;
# Create a new theme called &#039;&#039;&#039;demystified&#039;&#039;&#039; based upon the standard theme within Moodle 2.0.&lt;br /&gt;
# Make some minor changes to that theme to allow us to more easily see what is going on.&lt;br /&gt;
# Create a settings page for the demystified theme.&lt;br /&gt;
# Add several settings to our settings page.&lt;br /&gt;
# Use some of those settings to alter our CSS.&lt;br /&gt;
# Use the rest of those settings within our layout file..&lt;br /&gt;
# Discuss the good, the bad, and limits of what we have just created.&lt;br /&gt;
&lt;br /&gt;
So I can see you are all very excited about this point and that you would love to know what settings we are going to create; So here they are:&lt;br /&gt;
&lt;br /&gt;
A setting to ...&lt;br /&gt;
* change the background colour (CSS).&lt;br /&gt;
* set the path to an image that we will use as a logo on all pages (Layout files).&lt;br /&gt;
* override the width of the block regions (CSS).&lt;br /&gt;
* allow a note to be added to the footer of all pages (Layout files).&lt;br /&gt;
* allow custom CSS to be written to do anything the user wants. (CSS)&lt;br /&gt;
&lt;br /&gt;
==Creating the demystified theme==&lt;br /&gt;
Before we start here I want to remind you that I am going to look at this only briefly as I am making the assumption that you have read the [[Themes 2.0 creating your first theme|creating your first theme]] tutorial.&lt;br /&gt;
&lt;br /&gt;
Well lets get into it....&lt;br /&gt;
&lt;br /&gt;
The first thing we need to do is create a directory for our theme which we will call demystified. &lt;br /&gt;
&lt;br /&gt;
So within your Moodle directory create the following folder &#039;&#039;&#039;moodle/theme/demystified&#039;&#039;&#039;. At the same time you can also create the following files and folders which we will get to soon.&lt;br /&gt;
* The file &#039;&#039;&#039;moodle/theme/demystified/config.php&#039;&#039;&#039; for our config information.&lt;br /&gt;
* The directory &#039;&#039;&#039;moodle/theme/demystified/layout&#039;&#039;&#039; for our layout files.&lt;br /&gt;
* The directory &#039;&#039;&#039;moodle/theme/demystified/style&#039;&#039;&#039; for our css files.&lt;br /&gt;
* The file &#039;&#039;&#039;moodle/theme/demystified/style/core.css&#039;&#039;&#039; which will contain our special CSS.&lt;br /&gt;
&lt;br /&gt;
Next we will copy the layout files from the base theme to our new theme demystified. We are basing the demystified theme on the standard theme however that doesn&#039;t use it&#039;s own layout files it uses the base theme&#039;s layout files so those are the ones we want. &lt;br /&gt;
&lt;br /&gt;
The reason that we are coping these layout files is that later on in this tutorial we will be modifying them to make use of our new settings... so copy all of the layout files from &#039;&#039;&#039;moodle/theme/base/layout&#039;&#039;&#039; to &#039;&#039;&#039;moodle/theme/demystified/layout&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
There should be three files that you just copied:&lt;br /&gt;
# embedded.php&lt;br /&gt;
# frontpage.php&lt;br /&gt;
# general.php&lt;br /&gt;
&lt;br /&gt;
Now we need to populate demystified/config.php with the settings for our new theme. They are as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;name = &#039;demystified&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Simply sets the name of our theme.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;,&#039;base&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This theme is extending both the standard theme and the base theme. Remember when extending a theme you also need to extend its parents or things might not work correctly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;core&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This tells our theme that we want to use the file &#039;&#039;&#039;demystified/style/core.css&#039;&#039;&#039; with this theme.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;height:300px;overflow-y:scroll;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Most backwards compatible layout without the blocks - this is the layout used by default&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&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;
    // 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;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;
    // Main course page&lt;br /&gt;
    &#039;course&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;coursecategory&#039; =&amp;gt; array(&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;
    // part of course, typical for modules - default page layout if $cm specified in require_login()&lt;br /&gt;
    &#039;incourse&#039; =&amp;gt; array(&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;
    // The site home page.&lt;br /&gt;
    &#039;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;frontpage.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;
    // Server administration scripts.&lt;br /&gt;
    &#039;admin&#039; =&amp;gt; array(&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;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // My dashboard page&lt;br /&gt;
    &#039;mydashboard&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // My public page&lt;br /&gt;
    &#039;mypublic&#039; =&amp;gt; array(&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;
    &#039;login&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    // Pages that appear in pop-up windows - no navigation, no blocks, no header.&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // No blocks and minimal footer - used for legacy frame layouts only!&lt;br /&gt;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible&lt;br /&gt;
    &#039;embedded&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Used during upgrade and install, and for the &#039;This site is undergoing maintenance&#039; message.&lt;br /&gt;
    // This must not have any blocks, and it is good idea if it does not have links to&lt;br /&gt;
    // other places - for example there should not be a home link in the footer...&lt;br /&gt;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Now that all looks very complicated however its really not too bad as it is just copied from the base theme&#039;s config.php file. We can do this because we copied the layout files from the base theme to begin with and for the time being there are no changes that we wish to make. Simply open up &#039;&#039;&#039;theme/base/config.php&#039;&#039;&#039; and copy the layouts from there.&lt;br /&gt;
&lt;br /&gt;
And that is it. The config.php file for our demystified theme is complete. The full source is shown below:&lt;br /&gt;
&amp;lt;div style=&amp;quot;height:300px;overflow-y:scroll;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
// This file is part of Moodle - http://moodle.org/&lt;br /&gt;
//&lt;br /&gt;
// Moodle is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// Moodle is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with Moodle.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * The demystified theme config file&lt;br /&gt;
 *&lt;br /&gt;
 * This theme was created to document the process of adding a settings page to a theme&lt;br /&gt;
 *&lt;br /&gt;
 * @copyright 2010 Sam Hemelryk&lt;br /&gt;
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
// The name of our theme&lt;br /&gt;
$THEME-&amp;gt;name = &#039;demystified&#039;;&lt;br /&gt;
&lt;br /&gt;
// The other themes this theme extends&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;,&#039;base&#039;);&lt;br /&gt;
&lt;br /&gt;
// The CSS files this theme uses (located in the style directory)&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;core&#039;);&lt;br /&gt;
&lt;br /&gt;
// The layout definitions for this theme&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Most backwards compatible layout without the blocks - this is the layout used by default&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&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;
    // 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;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;
    // Main course page&lt;br /&gt;
    &#039;course&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;coursecategory&#039; =&amp;gt; array(&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;
    // part of course, typical for modules - default page layout if $cm specified in require_login()&lt;br /&gt;
    &#039;incourse&#039; =&amp;gt; array(&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;
    // The site home page.&lt;br /&gt;
    &#039;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;frontpage.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;
    // Server administration scripts.&lt;br /&gt;
    &#039;admin&#039; =&amp;gt; array(&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;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // My dashboard page&lt;br /&gt;
    &#039;mydashboard&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // My public page&lt;br /&gt;
    &#039;mypublic&#039; =&amp;gt; array(&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;
    &#039;login&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    // Pages that appear in pop-up windows - no navigation, no blocks, no header.&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // No blocks and minimal footer - used for legacy frame layouts only!&lt;br /&gt;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible&lt;br /&gt;
    &#039;embedded&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Used during upgrade and install, and for the &#039;This site is undergoing maintenance&#039; message.&lt;br /&gt;
    // This must not have any blocks, and it is good idea if it does not have links to&lt;br /&gt;
    // other places - for example there should not be a home link in the footer...&lt;br /&gt;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The screenshot below shows both the directory structure we have now created and the theme presently.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.01.png]]&lt;br /&gt;
&lt;br /&gt;
To view the theme so far open you browser and enter the URL of your site followed by &#039;&#039;&#039;?theme=demystified&#039;&#039;&#039;. You should see the theme that we just created which will look exactly like the base standard theme.&lt;br /&gt;
&lt;br /&gt;
The final thing that we want to do is add a little bit of CSS to the demystified theme that will both visually set this theme apart from the standard theme and second build a the base which our settings can later extend.&lt;br /&gt;
&lt;br /&gt;
I added the following snippet of CSS to the file &#039;&#039;&#039;demystified/style/core.css&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
html {background-color:#DDD;}&lt;br /&gt;
body {margin:30px;padding:0;border:1px solid #333;border-width:0 10px 0 10px;background-color:#333;}&lt;br /&gt;
body #page {background-color:#FFF;position:relative;top:-10px;}&lt;br /&gt;
.block .header {background-image:none;background-color:#0C5CAC;border:1px solid #0C5CAC;color:#FFF;}&lt;br /&gt;
.block {border-color:#4BA7FF;background-color:#DDEEFF;}&lt;br /&gt;
.block .content {background-color:#F1F8FF;}&lt;br /&gt;
a:link,&lt;br /&gt;
a:visited {color:#0C5CAC;}&lt;br /&gt;
a:hover {color:#C77500;}&lt;br /&gt;
#page #page-header {background-color:#0C5CAC;margin:0;padding:0;width:100%;color:#fff;}&lt;br /&gt;
#page #page-header a:link, #page #page-header a:visited {color:#FFAC02}&lt;br /&gt;
#page #page-header .navbar, #page #page-header .navbar a:link, #page #page-header .navbar a:visited {color:#0C5CAC;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The CSS that we have just added to our theme sets a couple of colours on the front page. Presently this is the only CSS I will add, I know it isn&#039;t complete by any means but it achieves it&#039;s purpose as the screenshot below illustrates.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.02.png|715px|thumb|left|The newly styles demystified theme]]&amp;lt;br style=&amp;quot;clear:both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And with that I will move on to the real purpose of this tutorial, creating the settings page&lt;br /&gt;
&lt;br /&gt;
==Setting up the settings page==&lt;br /&gt;
With the demystified theme set up it is time to create the settings page. This is where the real PHP fun begins.&lt;br /&gt;
&lt;br /&gt;
For those of you who happen to be familiar with development of modules, blocks or other plugin types you have probably encountered settings pages before and this is not going to be any different.&lt;br /&gt;
&lt;br /&gt;
However for those who haven&#039;t which I imagine is most of you this is going to be quite a challenge. I will try to walk through this step by step however if at any point you get stuck don&#039;t hesitate to ask in the forums as I imagine you will get a speedy response.&lt;br /&gt;
&lt;br /&gt;
===How settings pages work in Moodle===&lt;br /&gt;
Settings pages can be used by nearly every plugin type, of which themes is of course one. The way in which it all works isn&#039;t too tricky to understand. &lt;br /&gt;
&lt;br /&gt;
All of the settings for Moodle can be configured through the administrator interfaces when logged in. I am sure that everyone here has seen those pages and has changed a setting or two before so you will all know what I am talking about. Well the settings page for a theme is no different. It will be shown in the administration pages tree under &#039;&#039;&#039;Appearance &amp;gt; Themes&#039;&#039;&#039; and all we have to do is tell Moodle what settings there are.&lt;br /&gt;
&lt;br /&gt;
This is done by creating a settings.php file within our theme into which we will add code that tells Moodle about the settings we want to add/use.&lt;br /&gt;
&lt;br /&gt;
When telling Moodle about each setting we are simply creating a new &#039;&#039;admin_setting&#039;&#039; instance of the type we want and the properties we want and then adding it to our settings page.&lt;br /&gt;
&lt;br /&gt;
There is really not much more too it at this level. Things can get very complex very fast so the best thing we can do now is start creating our settings.php file for the demystified theme and see where it leads us.&lt;br /&gt;
&lt;br /&gt;
===Creating the settings page===&lt;br /&gt;
So as mentioned before we need a settings.php file which we will create now. To begin with create the file &#039;&#039;&#039;theme/demystified/settings.php&#039;&#039;&#039; and open it in your favourite editor so its ready to go.&lt;br /&gt;
&lt;br /&gt;
Before we start adding code however lets just remember the settings that we want to create:&lt;br /&gt;
* change the background colour (CSS).&lt;br /&gt;
* set the path to an image that we will use as a logo on all pages (Layout files).&lt;br /&gt;
* override the width of the block regions (CSS).&lt;br /&gt;
* allow a note to be added to the footer of all pages (Layout files).&lt;br /&gt;
* allow custom CSS to be written to do anything the user wants. (CSS)&lt;br /&gt;
&lt;br /&gt;
Alright.&lt;br /&gt;
&lt;br /&gt;
Now thinking about this the first setting is as basic as it gets, all we need is a text box that the user can type a colour into.&lt;br /&gt;
&lt;br /&gt;
The second is to allow a logo to be used in the header of each page. What we want here is a path but should it be a physical path e.g. C:/path/to/image.png or should it be a web path e.g. &amp;lt;nowiki&amp;gt;http://mysite.com/path/to/image.png&amp;lt;/nowiki&amp;gt;?&lt;br /&gt;
For the purpose of this tutorial I am going to go with a web path because it is going to be easier to code and will hopefully be a little easier to understand to begin with.&lt;br /&gt;
&lt;br /&gt;
The third setting is a little more complex. For this I want a drop down box with some specific widths that the administrator can select.&lt;br /&gt;
&lt;br /&gt;
The forth and the fifth settings are both pretty straight forward, there we want a textarea into which the user can enter what ever they want and we will do something useful with it.&lt;br /&gt;
&lt;br /&gt;
Now that we have an understanding about the settings we wish to define pull up your editor and lets start coding....&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Settings for the demystified theme&lt;br /&gt;
 */&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die;&lt;br /&gt;
&lt;br /&gt;
if ($ADMIN-&amp;gt;fulltree) {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is the first bit of code we must enter, the first line is of course just the opening php tag, secondly we have a comment that describes this file, and then we get create a new &#039;&#039;&#039;admin_settingspage object&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This admin_settingspage object that we have just created is a representation of our settings page and is the what we add our new settings to. When creating it we give it two arguments, first the name of the page which is in this case &#039;&#039;&#039;theme_&#039;&#039;themename&#039;&#039;&#039;&#039;&#039; and the title for the page which we get with the get_string method.&lt;br /&gt;
&lt;br /&gt;
At the moment I&#039;m not going to worry about adding the string, we will get to that later once we have defined all of our settings.&lt;br /&gt;
&lt;br /&gt;
====Background colour====&lt;br /&gt;
&lt;br /&gt;
With the page now created lets add our first setting: Background colour.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Background colour setting&lt;br /&gt;
$name = &#039;theme_demystified/backgroundcolor&#039;;&lt;br /&gt;
$title = get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = &#039;#DDD&#039;;&lt;br /&gt;
$setting = new admin_setting_configtext($name, $title, $description, $default, PARAM_CLEAN, 12);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Thankfully this isn&#039;t as difficult as it initially looks.&lt;br /&gt;
&lt;br /&gt;
The first line of code is creating a variable for the name of the background colour setting. In this case it is &#039;&#039;&#039;theme_demystified/backgroundcolor&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
The name is very important, for the setting to be usable we have to follow a strict naming convention. &#039;&#039;&#039;theme_&#039;&#039;themename&#039;&#039;/&#039;&#039;settingname&#039;&#039;&#039;&#039;&#039; where &#039;&#039;&#039;&#039;&#039;themename&#039;&#039;&#039;&#039;&#039; is the name of the theme the setting belongs to and &#039;&#039;&#039;&#039;&#039;settingname&#039;&#039;&#039;&#039;&#039; is the name for the setting by which we will use it.&lt;br /&gt;
&lt;br /&gt;
The second line of code creates a variable that contains the title of the setting. This is what the user sees to the right of the setting on the settings page and should be a short description of the setting. Here we are again using the &#039;&#039;get_string&#039;&#039; method so we will need to remember to add that string later on.&lt;br /&gt;
&lt;br /&gt;
The third line of code sets the description. This should describe what the setting does or how it works and again we will use the get_string method.&lt;br /&gt;
&lt;br /&gt;
The fourth line creates a variable that will be used as the default value for the setting. Because this setting is a colour we want an HTML colour to be the default value.&lt;br /&gt;
&lt;br /&gt;
The fifth line is where we put it all together. Here we create a new &#039;&#039;&#039;admin_setting_configtext&#039;&#039;&#039; object. This object will represent the background colour setting.&lt;br /&gt;
&lt;br /&gt;
When we create it we need to give it 6 different things.&lt;br /&gt;
# The name of the setting. In this case we have a variable &#039;&#039;&#039;$name&#039;&#039;&#039;.&lt;br /&gt;
# The title for this setting. We used the variable &#039;&#039;&#039;$title&#039;&#039;&#039;.&lt;br /&gt;
# The description of the setting &#039;&#039;&#039;$description&#039;&#039;&#039;.&lt;br /&gt;
# The default value for the setting. &#039;&#039;&#039;$default&#039;&#039;&#039; is the variable this.&lt;br /&gt;
# The type of value we want the user to enter. For this we have used PARAM_CLEAN which tells Moodle to get rid of any nasties from what the user enters.&lt;br /&gt;
# The size of the field. In our case 12 characters will be plenty.&lt;br /&gt;
&lt;br /&gt;
The sixth and final line of code adds our newly created setting to the administration page we created earlier.&lt;br /&gt;
&lt;br /&gt;
That is it we have successfully created and added our first setting, however there are several more to settings to do, and there are a couple of important things that you need to be aware of before we move on.&lt;br /&gt;
&lt;br /&gt;
First: There are several different types of settings that you can create and add to a page, and each one may differ in what they need you to give them. In this case it was name, title, description, default, type, and size. However other settings will likely require different things. Smart editors like Netbeans or Eclipse can tell you what is required, otherwise you will need to research it.&lt;br /&gt;
&lt;br /&gt;
Second: Normally settings are declared on one line as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$setting-&amp;gt;add(new admin_setting_configtext(&#039;theme_demystified/backgroundcolor&#039;, get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;), get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;), &#039;#DDD&#039;, PARAM_CLEAN, 12));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
While this is structurally identical as all we have done is move everything onto one line and do away with the variables it is a little harder to read when you are learning all of this.&lt;br /&gt;
&lt;br /&gt;
====The logo file====&lt;br /&gt;
Time to create the second setting that will allow the user to enter a URL to an image they wish to use as the logo on their site.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Logo file setting&lt;br /&gt;
$name = &#039;theme_demystified/logo&#039;;&lt;br /&gt;
$title = get_string(&#039;logo&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;logodesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtext($name, $title, $description, &#039;&#039;, PARAM_URL);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The first thing that you will notice about this setting that it is very similar to the first setting, in fact all we have changed is the name, title, description, and default value. We have however changed the value type from PARAM_CLEAN to PARAM_URL, this makes sure the user enters a URL. You will also notice that for this one we don&#039;t set a size for the field as we have no idea how long the URL will be.&lt;br /&gt;
&lt;br /&gt;
====Block region width====&lt;br /&gt;
The third setting should allow the user to set a width for the block regions that will be used as columns.&lt;br /&gt;
&lt;br /&gt;
For this setting I want to do something a little different from the previous two, here I want to use a select box so that the user selects a width for the column from a list I provide.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Block region width&lt;br /&gt;
$name = &#039;theme_demystified/regionwidth&#039;;&lt;br /&gt;
$title = get_string(&#039;regionwidth&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;regionwidthdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = 200;&lt;br /&gt;
$choices = array(150=&amp;gt;&#039;150px&#039;, 170=&amp;gt;&#039;170px&#039;, 200=&amp;gt;&#039;200px&#039;, 240=&amp;gt;&#039;240px&#039;, 290=&amp;gt;&#039;290px&#039;, 350=&amp;gt;&#039;350px&#039;, 420=&amp;gt;&#039;420px&#039;);&lt;br /&gt;
$setting = new admin_setting_configselect($name, $title, $description, $default, $choices);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
So looking at the code: The first four lines you will recognise. $name, $title, $description, and $default are all being set.&lt;br /&gt;
&lt;br /&gt;
The fifth line of code however introduces something new. Of course in order to have a select box we have to have options, in this case we have an array of options stored in the variable $choices.&lt;br /&gt;
&lt;br /&gt;
The array of options is constructed of a collection of &#039;&#039;&#039;&#039;&#039;value&#039;&#039;&#039; =&amp;gt; &#039;&#039;&#039;label&#039;&#039;&#039;&#039;&#039; pairs. Notice how we don&#039;t add &#039;&#039;&#039;px&#039;&#039;&#039; to the value. This is is very intentional as later on I need to do a little bit of math with that value so we need it to be a number.&lt;br /&gt;
&lt;br /&gt;
The lines after should look familiar again, the only difference being that instead of a &#039;&#039;admin_setting_configtext&#039;&#039; setting we have created a &#039;&#039;admin_setting_configselect&#039;&#039; for which we must give the choices for the select box as the fifth argument.&lt;br /&gt;
&lt;br /&gt;
Woohoo, we&#039;ve just created our first select box setting.&lt;br /&gt;
&lt;br /&gt;
====Foot note====&lt;br /&gt;
Now to create the foot note setting. Here we want the user to be able to enter some arbitrary text that will be used in the footer of the page. For this I want the user to be able to enter some HTML so I will create an editor setting.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Foot note setting&lt;br /&gt;
$name = &#039;theme_demystified/footnote&#039;;&lt;br /&gt;
$title = get_string(&#039;footnote&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;footnotedesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_confightmleditor($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
How simple is that!&lt;br /&gt;
&lt;br /&gt;
It is just about identical to the first two settings except that for this we have created a &#039;&#039;admin_setting_confightmleditor&#039;&#039; setting rather than a text setting.&lt;br /&gt;
&lt;br /&gt;
Note: You can also set the columns and rows for the editor setting using the fifth and sixth arguments.&lt;br /&gt;
&lt;br /&gt;
====Custom CSS====&lt;br /&gt;
The final setting is to allow the user to add some custom CSS to the theme that will be used on every page. I want this to be a plain textarea into which the user can enter CSS.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Custom CSS file&lt;br /&gt;
$name = &#039;theme_demystified/customcss&#039;;&lt;br /&gt;
$title = get_string(&#039;customcss&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;customcssdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtextarea($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Just like the editor or text settings. It&#039;s getting very easy now!&lt;br /&gt;
&lt;br /&gt;
====Finishing settings.php====&lt;br /&gt;
With all of our settings defined and added to our page that we created right at the beginning it is time to finish it all off.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
} // This is the closing brace that encloses all the above settings. &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The above line is the final line for the page. It is adding the page that we have created &#039;&#039;&#039;$setting&#039;&#039;&#039; to the admin tree structure. In this case it is adding it to the themes branch.&lt;br /&gt;
&lt;br /&gt;
The following is the completed source for our settings.php ..... for your copy/paste pleasure.&lt;br /&gt;
&amp;lt;div style=&#039;height:300px;overflow:auto;&#039;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Settings for the demystified theme&lt;br /&gt;
 */&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die;&lt;br /&gt;
 &lt;br /&gt;
if ($ADMIN-&amp;gt;fulltree) {&lt;br /&gt;
&lt;br /&gt;
    // Background colour setting&lt;br /&gt;
    name = &#039;theme_demystified/backgroundcolor&#039;;&lt;br /&gt;
    $title = get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
    $description = get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
    $default = &#039;#DDD&#039;;&lt;br /&gt;
    $setting = new admin_setting_configtext($name, $title, $description, $default, PARAM_CLEAN, 12);&lt;br /&gt;
    $setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
    $settings-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
    // Logo file setting.&lt;br /&gt;
    $name = &#039;theme_demystified/logo&#039;;&lt;br /&gt;
    $title = get_string(&#039;logo&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
    $description = get_string(&#039;logodesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
    $setting = new admin_setting_configtext($name, $title, $description, &#039;&#039;, PARAM_URL);&lt;br /&gt;
    $setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
    $settings-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
    // Block region width.&lt;br /&gt;
    $name = &#039;theme_demystified/regionwidth&#039;;&lt;br /&gt;
    $title = get_string(&#039;regionwidth&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
    $description = get_string(&#039;regionwidthdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
    $default = 200;&lt;br /&gt;
    $choices = array(150=&amp;gt;&#039;150px&#039;, 170=&amp;gt;&#039;170px&#039;, 200=&amp;gt;&#039;200px&#039;, 240=&amp;gt;&#039;240px&#039;, 290=&amp;gt;&#039;290px&#039;, 350=&amp;gt;&#039;350px&#039;, 420=&amp;gt;&#039;420px&#039;);&lt;br /&gt;
    $setting = new admin_setting_configselect($name, $title, $description, $default, $choices);&lt;br /&gt;
    $setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
    $settings-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
    // Foot note setting.&lt;br /&gt;
    $name = &#039;theme_demystified/footnote&#039;;&lt;br /&gt;
    $title = get_string(&#039;footnote&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
    $description = get_string(&#039;footnotedesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
    $setting = new admin_setting_confightmleditor($name, $title, $description, &#039;&#039;);&lt;br /&gt;
    $setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
    $settings-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
    // Custom CSS file.&lt;br /&gt;
    $name = &#039;theme_demystified/customcss&#039;;&lt;br /&gt;
    $title = get_string(&#039;customcss&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
    $description = get_string(&#039;customcssdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
    $setting = new admin_setting_configtextarea($name, $title, $description, &#039;&#039;);&lt;br /&gt;
    $setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
    $settings-&amp;gt;add($setting);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Creating a language file and adding our strings===&lt;br /&gt;
As I&#039;m sure none of you have forgotten, throughout the creation of the our settings.php page, we used a lot of strings that I mentioned we would set later on. Well now is the time to set those strings.&lt;br /&gt;
&lt;br /&gt;
First up create the following directories and file for our language strings:&lt;br /&gt;
* Directory &#039;&#039;&#039;theme/demystified/lang&#039;&#039;&#039;&lt;br /&gt;
* Directory &#039;&#039;&#039;theme/demystified/lang/en&#039;&#039;&#039;&lt;br /&gt;
* File &#039;&#039;&#039;theme/demystified/lang/theme_demystified.php&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
What we have created here is the required structure for Moodle to start looking for language strings.&lt;br /&gt;
&lt;br /&gt;
First Moodle locates the lang directory, once found it looks within that directory for another directory that uses the character code for the language the user has selected, by default this is &#039;&#039;&#039;en&#039;&#039;&#039; for English. Once that is found it looks for the appropriate language file, in this case &#039;&#039;&#039;theme_demystified.php&#039;&#039;&#039; from which it will load all language strings for our theme.&lt;br /&gt;
&lt;br /&gt;
If English isn&#039;t your chosen language simply replace the &#039;&#039;en&#039;&#039; directory with one that uses your chosen languages character code (two letters).&lt;br /&gt;
&lt;br /&gt;
We can now add our language strings to &#039;&#039;&#039;theme/demystified/lang/theme_demystified.php&#039;&#039;&#039;. Copy and paste the following lines of PHP into this file.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This file contains the strings used by the demystified theme&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
$string[&#039;backgroundcolor&#039;] = &#039;Background colour&#039;;&lt;br /&gt;
$string[&#039;backgroundcolordesc&#039;] = &#039;This sets the background colour for the theme.&#039;;&lt;br /&gt;
$string[&#039;configtitle&#039;] = &#039;Demystified theme&#039;;&lt;br /&gt;
$string[&#039;customcss&#039;] = &#039;Custom CSS&#039;;&lt;br /&gt;
$string[&#039;customcssdesc&#039;] = &#039;Any CSS you enter here will be added to every page allowing your to easily customise this theme.&#039;;&lt;br /&gt;
$string[&#039;footnote&#039;] = &#039;Footnote&#039;;&lt;br /&gt;
$string[&#039;footnotedesc&#039;] = &#039;The content from this textarea will be displayed in the footer of every page.&#039;;&lt;br /&gt;
$string[&#039;logo&#039;] = &#039;Logo&#039;;&lt;br /&gt;
$string[&#039;logodesc&#039;] = &#039;Enter the URL to an image to use as the logo for this site. Should be http://www.yoursite.com/path/to/logo.png&#039;;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;Demystified&#039;;&lt;br /&gt;
$string[&#039;regionwidth&#039;] = &#039;Column width&#039;;&lt;br /&gt;
$string[&#039;regionwidthdesc&#039;] = &#039;This sets the width of the two block regions that form the left and right columns.&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above lines of code I have added an entry for each language string we used within &#039;&#039;settings.php&#039;&#039;. When adding language strings like this make sure you use single quotes and try to keep things alphabetical - it helps greatly when managing strings.&lt;br /&gt;
&lt;br /&gt;
Now when we view the settings page there will not be any errors or strings missing.&lt;br /&gt;
&lt;br /&gt;
===Having a look at what we have created===&lt;br /&gt;
Now that we have created our settings page (settings.php) and added all of the language strings it is time to have a look at things in your browser.&lt;br /&gt;
&lt;br /&gt;
Open your browser and enter the URL to your site. When you arrive at your site login as an administrator.&lt;br /&gt;
&lt;br /&gt;
If you are not redirected to view the new settings change your URL to &amp;lt;nowiki&amp;gt;http://www.yoursite.com/admin/&amp;lt;/nowiki&amp;gt; and your will see a screen to set the new theme settings we have just created. This lets us know that everything has worked correctly.&lt;br /&gt;
&lt;br /&gt;
At any point now you are able to log in as administrator and within the settings block browse to &#039;&#039;&#039;Site administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; Demystified theme&#039;&#039;&#039; to change those settings.&lt;br /&gt;
&lt;br /&gt;
The screenshot below shows you what you should see at this point:&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.03.png|715px|thumb|left|The settings page we just created]]&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using the settings in CSS==&lt;br /&gt;
With the settings page now created and operational it is time to make use of our new settings. The settings that we want to use within our CSS is as follows:&lt;br /&gt;
&lt;br /&gt;
; backgroundcolor : Will be used to set the background colour in CSS.&lt;br /&gt;
; regionwidth : Will be the width of the column for CSS.&lt;br /&gt;
; customcss : Will be some custom CSS to add to our stylesheet.&lt;br /&gt;
&lt;br /&gt;
At this point those names are the names we used for our setting with the slash and everything before it having been removed.&lt;br /&gt;
&lt;br /&gt;
Before we start tearing into some code it is important that we have a look at what we are going to do and how we are going to go about it.&lt;br /&gt;
&lt;br /&gt;
===How it all works within Moodle===&lt;br /&gt;
The first thing to understand is that while Moodle allows you to create a settings page and automates it inclusion and management right into the administration interfaces there is no smart equivalent for using the settings. This is simply because there is no way to predict how people will want to use the settings.&lt;br /&gt;
&lt;br /&gt;
However don&#039;t think of this as a disadvantage, in fact it is quite the contrary. Although we can&#039;t just &#039;&#039;use&#039;&#039; our settings we can take full control over how and where we use them. It means it will take a little more code but in the end that will work to our advantage as we can do anything we want.&lt;br /&gt;
&lt;br /&gt;
Moodle does help us out a little but not in an obvious way. The first thing that Moodle does is look for a config variable &#039;&#039;&#039;csspostprocess&#039;&#039;&#039; that should be the name of a function which we want called to make any changes to the CSS after it has been prepared.&lt;br /&gt;
&lt;br /&gt;
The second thing Moodle does is include a lib.php from the theme&#039;s directory if one exists (also for the themes the current theme extends.) which ensures that as long as we write our code within &#039;&#039;&#039;theme/demystified/lib.php&#039;&#039;&#039; it will be included and ready to be used.&lt;br /&gt;
&lt;br /&gt;
The third and final thing Moodle does that will help us out here is ensure that by the time any of code is ready to execute the settings have been prepared and are ready to be used within a theme config object which is passed into our &#039;&#039;csspostprocess&#039;&#039; function.&lt;br /&gt;
&lt;br /&gt;
===Our plan===&lt;br /&gt;
As you have already probably guessed we will need to create a function to make the changes to the CSS that we want. We will then set the theme config option &#039;&#039;&#039;$THEME-&amp;gt;csspostprocess&#039;&#039;&#039; to the name of our function.&lt;br /&gt;
&lt;br /&gt;
By doing this when Moodle builds the CSS file it will call our function afterwards with the CSS and the theme object that contains our setting.&lt;br /&gt;
&lt;br /&gt;
Now we know that we will use the &#039;&#039;csspostprocess&#039;&#039; function but how are we going to change the CSS, we could get the function to add CSS, or we could get the function to replace something within the CSS. My personal preference is to replace something within the CSS, just like what is happening with images. If you want to use an image within CSS you would write &amp;lt;nowiki&amp;gt;[[pix:theme|imagename]]&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For settings I am going to use &amp;lt;nowiki&amp;gt;[[setting:settingname]]&amp;lt;/nowiki&amp;gt;, this way it looks a bit like something you are already familiar with.&lt;br /&gt;
&lt;br /&gt;
What we need to decide upon next is the best way in which to replace our settings tag with the settings that the user has set.&lt;br /&gt;
&lt;br /&gt;
There are two immediate options available to us:&lt;br /&gt;
# Make the &#039;&#039;csspostprocess&#039;&#039; function do all the work.&lt;br /&gt;
# Make the &#039;&#039;csspostprocess&#039;&#039; function call a separate function for each setting.&lt;br /&gt;
Solution 1 might sound like the simplest however it is going to result in a &#039;&#039;&#039;VERY&#039;&#039;&#039; complex function. Remember the user might have left settings blank or entered something that wouldn&#039;t be valid so we would need to make the sure there is some validation and a good default.&lt;br /&gt;
Because of this I think that solution 2 is the better solution.&lt;br /&gt;
&lt;br /&gt;
So we are going to need a &#039;&#039;csspostprocess&#039;&#039; function and then a function for each of the three settings we have that will do the replacements.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// This is our css post process function&lt;br /&gt;
function demystified_process_css($css, $theme) {};&lt;br /&gt;
// This replaces [[setting:backgroundcolor]] with the background colour&lt;br /&gt;
function demystified_set_backgroundcolor($css, $backgroundcolor) {};&lt;br /&gt;
// This replaces [[setting:regionwidth]] with the correct region width&lt;br /&gt;
function demystified_set_regionwidth() {$css, $regionwidth};&lt;br /&gt;
// This replaces [[setting:customcss]] with the custom css&lt;br /&gt;
function demystified_set_customcss() {$css, $customcss};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you should note about the above functions is that they all start with the theme&#039;s name. This is required to ensure that the functions are named uniquely as it is VERY unlikely that someone has already created these functions.&lt;br /&gt;
&lt;br /&gt;
So with our plan set out lets start writing the code.&lt;br /&gt;
&lt;br /&gt;
===Writing the code===&lt;br /&gt;
The very first thing that we need to do is create a lib.php for our theme into which our css processing functions are going to go. So please at this point create &#039;&#039;&#039;theme/demystified/lib.php&#039;&#039;&#039; and open it in your editor ready to go.&lt;br /&gt;
&lt;br /&gt;
The first bit of code we have to write is the function that will be called by Moodle to do the processing &#039;&#039;&#039;demystified_process_css&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
Before we start out please remember that the wonderful thing about coding is that there is any number of solutions to a problem. The solutions that you are seeing here in this tutorial are solutions that I have come up with to meet fulfil the needs of the tutorial without being so complex that they are hard to understand. This probably isn&#039;t how I would go about it normally but this is a little easier to understand for those who aren&#039;t overly familiar with PHP and object orientation.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_process_css====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function demystified_process_css($css, $theme) {&lt;br /&gt;
&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;backgroundcolor)) {&lt;br /&gt;
        $backgroundcolor = $theme-&amp;gt;settings-&amp;gt;backgroundcolor;&lt;br /&gt;
    } else {&lt;br /&gt;
        $backgroundcolor = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_backgroundcolor($css, $backgroundcolor);&lt;br /&gt;
&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;regionwidth)) {&lt;br /&gt;
        $regionwidth = $theme-&amp;gt;settings-&amp;gt;regionwidth;&lt;br /&gt;
    } else {&lt;br /&gt;
        $regionwidth = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_regionwidth($css, $regionwidth);&lt;br /&gt;
&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;customcss)) {&lt;br /&gt;
        $customcss = $theme-&amp;gt;settings-&amp;gt;customcss;&lt;br /&gt;
    } else {&lt;br /&gt;
        $customcss = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_customcss($css, $customcss);&lt;br /&gt;
&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So lets look at the things that make up this function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function demystified_process_css($css, $theme) {&lt;br /&gt;
    //.....&lt;br /&gt;
    return $css&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This of course is the function declaration. &lt;br /&gt;
&lt;br /&gt;
The function gets given two variables, the first &#039;&#039;&#039;$css&#039;&#039;&#039; is a pile of CSS as one big string, and the second is the theme object &#039;&#039;&#039;$theme&#039;&#039;&#039; that contains all of the configuration, options, and settings for our theme.&lt;br /&gt;
&lt;br /&gt;
It then returns the &#039;&#039;$css&#039;&#039; variable, essentially returning the modified CSS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    //...&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;backgroundcolor)) {&lt;br /&gt;
        $backgroundcolor = $theme-&amp;gt;settings-&amp;gt;backgroundcolor;&lt;br /&gt;
    } else {&lt;br /&gt;
        $backgroundcolor = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_backgroundcolor($css, $backgroundcolor);&lt;br /&gt;
    //...&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are processing our first setting &#039;&#039;backgroundcolor&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
The first thing that we need to do is check whether it has been set and whether it has a value. If it has then we store that value in &#039;&#039;&#039;$backgroundcolor&#039;&#039;&#039;. It is doesn&#039;t have a value then we set &#039;&#039;$backgroundcolor&#039;&#039; to null. This ensures that &#039;&#039;$backgroundcolor&#039;&#039; is set because if it isn&#039;t then you are going to get a notice (if you have debugging on).&lt;br /&gt;
&lt;br /&gt;
The final line of this block calls the function &#039;&#039;&#039;demystified_set_backgroundcolor&#039;&#039;&#039;. We haven&#039;t written this function yet but we will shortly. When we call it we give it the &#039;&#039;$css&#039;&#039; variable that contains all of the CSS and we give it the background colour variable &#039;&#039;$backgroundcolor&#039;&#039;. Once this function is finished it returns the &#039;&#039;$css&#039;&#039; variable with all of the changes made much like how our css processing function works.&lt;br /&gt;
&lt;br /&gt;
What you should also note about this code is this:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$theme-&amp;gt;settings-&amp;gt;backgroundcolor&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
As mentioned earlier &#039;&#039;$theme&#039;&#039; is an object that contains all of the configuration and settings for our theme. The &#039;&#039;$theme&#039;&#039; object has a $settings property which contains all of the settings for our theme, and finally the settings property contains a variable backgroundcolor that is the value the user entered for that setting. That is how we get a settings value.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($theme-&amp;gt;settings-&amp;gt;regionwidth)) {&lt;br /&gt;
    $regionwidth = $theme-&amp;gt;settings-&amp;gt;regionwidth;&lt;br /&gt;
} else {&lt;br /&gt;
    $regionwidth = null;&lt;br /&gt;
}&lt;br /&gt;
$css = demystified_set_regionwidth($css, $regionwidth);&lt;br /&gt;
&lt;br /&gt;
if (!empty($theme-&amp;gt;settings-&amp;gt;customcss)) {&lt;br /&gt;
    $customcss = $theme-&amp;gt;settings-&amp;gt;customcss;&lt;br /&gt;
} else {&lt;br /&gt;
    $customcss = null;&lt;br /&gt;
}&lt;br /&gt;
$css = demystified_set_customcss($css, $customcss);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These two routines are nearly identical to the routine above. For both the regionwidth and the customcss we make sure it has a value and then store it in a variable. We then call the relevant function to make the changes for that setting.&lt;br /&gt;
&lt;br /&gt;
Now that we have the general processing function it is time to write the three functions we have used but not written, &#039;&#039;demystified_set_backgroundcolor&#039;&#039;, &#039;&#039;demystified_set_regionwidth&#039;&#039;, &#039;&#039;demystified_set_customcss&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_set_backgroundcolor====&lt;br /&gt;
&lt;br /&gt;
First up demystified_set_backgroundcolor.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Sets the background colour variable in CSS&lt;br /&gt;
 *&lt;br /&gt;
 * @param string $css&lt;br /&gt;
 * @param mixed $backgroundcolor&lt;br /&gt;
 * @return string&lt;br /&gt;
 */&lt;br /&gt;
function demystified_set_backgroundcolor($css, $backgroundcolor) {&lt;br /&gt;
    $tag = &#039;[[setting:backgroundcolor]]&#039;;&lt;br /&gt;
    $replacement = $backgroundcolor;&lt;br /&gt;
    if (is_null($replacement)) {&lt;br /&gt;
        $replacement = &#039;#DDDDDD&#039;;&lt;br /&gt;
    }&lt;br /&gt;
    $css = str_replace($tag, $replacement, $css);&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ok so what is happening here?&lt;br /&gt;
&lt;br /&gt;
First we need a variable &#039;&#039;&#039;$tag&#039;&#039;&#039; that contains the tag we are going to replace. As mentioned earlier we are going to use tags that look like the image tags you are already familiar with &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:settingname]]&amp;lt;/nowiki&amp;gt;&#039;&#039;, in this case &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:backgroundcolor]]&amp;lt;/nowiki&amp;gt;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Next I am going to create a variable called &#039;&#039;&#039;$replacement&#039;&#039;&#039; into which I put &#039;&#039;&#039;$backgroundcolor&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;IF&#039;&#039;&#039; statement that comes next checks &#039;&#039;$replacement&#039;&#039; to make sure it is not null. If it is then we need to set it to a default value. In this case I have used &#039;&#039;#DDD&#039;&#039; as that was the default for the settings.&lt;br /&gt;
&lt;br /&gt;
The line after the IF statement puts it all together. The &#039;&#039;str_replace&#039;&#039; function that we are calling takes three arguments in this order:&lt;br /&gt;
# The text to search for.&lt;br /&gt;
# The text to replace it with.&lt;br /&gt;
# The text to do the replacement in.&lt;br /&gt;
It then returns the text with all of the replacements made. So in this case we are replacing the tag with the background colour and it is returning the changed CSS.&lt;br /&gt;
&lt;br /&gt;
The final thing is to return the &#039;&#039;$css&#039;&#039; variable which now contains the correct background colour.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_set_regionwidth====&lt;br /&gt;
&lt;br /&gt;
Next we have the demystified_set_regionwidth function.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Sets the region width variable in CSS&lt;br /&gt;
 *&lt;br /&gt;
 * @param string $css&lt;br /&gt;
 * @param mixed $regionwidth&lt;br /&gt;
 * @return string&lt;br /&gt;
 */&lt;br /&gt;
function demystified_set_regionwidth($css, $regionwidth) {&lt;br /&gt;
    $tag = &#039;[[setting:regionwidth]]&#039;;&lt;br /&gt;
    $doubletag = &#039;[[setting:regionwidthdouble]]&#039;;&lt;br /&gt;
    $replacement = $regionwidth;&lt;br /&gt;
    if (is_null($replacement)) {&lt;br /&gt;
        $replacement = 200;&lt;br /&gt;
    }&lt;br /&gt;
    $css = str_replace($tag, $replacement.&#039;px&#039;, $css);&lt;br /&gt;
    $css = str_replace($doubletag, ($replacement*2).&#039;px&#039;, $css);&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function is very similar to the above function however there is one key thing we are doing different. We are doing two replacements.&lt;br /&gt;
&lt;br /&gt;
# The first replacement is for the width that the user selected. In this case I am replacing the tag &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt;&#039;&#039; with the width.&lt;br /&gt;
# The second replacement is for the width x 2. This is because the page layout requires that the width be doubled for some of the CSS. Here I will replace &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidthdouble]]&amp;lt;/nowiki&amp;gt;&#039;&#039; with the doubled width.&lt;br /&gt;
&lt;br /&gt;
Remember because it is still just a number we need to add &#039;&#039;&#039;px&#039;&#039;&#039; to the end of each before we do the replacement.&lt;br /&gt;
&lt;br /&gt;
So the overall process of this function is:&lt;br /&gt;
# Define the two tags as &#039;&#039;&#039;$tag&#039;&#039;&#039; and &#039;&#039;&#039;$doubletag&#039;&#039;&#039;.&lt;br /&gt;
# Make &#039;&#039;&#039;$replacement&#039;&#039;&#039; the region width &#039;&#039;$regionwidth&#039;&#039;.&lt;br /&gt;
# Set &#039;&#039;$replacement&#039;&#039; to a default value of 200 is it is null.&lt;br /&gt;
# Replace &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; with the width.&lt;br /&gt;
# Replace &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidthdouble]]&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; with the width x 2.&lt;br /&gt;
# Return the changed CSS.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_set_customcss====&lt;br /&gt;
&lt;br /&gt;
The final function that we need to write is the demystified_set_customcss function.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Sets the custom css variable in CSS&lt;br /&gt;
 *&lt;br /&gt;
 * @param string $css&lt;br /&gt;
 * @param mixed $customcss&lt;br /&gt;
 * @return string&lt;br /&gt;
 */&lt;br /&gt;
function demystified_set_customcss($css, $customcss) {&lt;br /&gt;
    $tag = &#039;[[setting:customcss]]&#039;;&lt;br /&gt;
    $replacement = $customcss;&lt;br /&gt;
    if (is_null($replacement)) {&lt;br /&gt;
        $replacement = &#039;&#039;;&lt;br /&gt;
    }&lt;br /&gt;
    $css = str_replace($tag, $replacement, $css);&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function is just like the first function. I&#039;m going to let you work it out on your own.&lt;br /&gt;
&lt;br /&gt;
And that is it no more PHP... Hallelujah I can hear you yelling. The final thing we need to do is tell our theme about the functions we have written and put the settings tags into the CSS.&lt;br /&gt;
&lt;br /&gt;
===Finishing it all off===&lt;br /&gt;
&lt;br /&gt;
So there are two things we have to do in order to complete this section and have our the settings page implemented and our settings being used.&lt;br /&gt;
&lt;br /&gt;
First we need to tell our theme that we want to use the function &#039;&#039;demystified_process_css&#039;&#039; as the &#039;&#039;csspostprocess&#039;&#039; function. This is done very simply by adding the following line of PHP to the bottom of our theme&#039;s config.php file &#039;&#039;&#039;theme/demystified/config.php&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;csspostprocess = &#039;demystified_process_css&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done the only thing left is to add the settings tag into the CSS. Remember those settings tags are:&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:backgroundcolor]]&amp;lt;/nowiki&amp;gt; : We need to add this where ever we want the background colour setting to be used.&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt; : We need to add this where ever we want to set the width of the block regions.&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:regionwidthdouble]]&amp;lt;/nowiki&amp;gt; : We need to add this where ever we want to set the doubled width of the block regions.&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:customcss]]&amp;lt;/nowiki&amp;gt; : We need to add this to the bottom of the CSS file that we want the custom CSS added to.&lt;br /&gt;
&lt;br /&gt;
So lets make those changes in CSS now, open up your &#039;&#039;core.css&#039;&#039; file and replace the CSS with the CSS below:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/** Background color is a setting **/&lt;br /&gt;
html {background-color:[[setting:backgroundcolor]];}&lt;br /&gt;
body {margin:30px;padding:0;border:1px solid #333;border-width:0 10px 0 10px;background-color:#333;}&lt;br /&gt;
body #page {background-color:#FFF;position:relative;top:-10px;}&lt;br /&gt;
.block .header {background-image:none;background-color:#0C5CAC;border:1px solid #0C5CAC;color:#FFF;}&lt;br /&gt;
.block {border-color:#4BA7FF;background-color:#DDEEFF;}&lt;br /&gt;
.block .content {background-color:#F1F8FF;}&lt;br /&gt;
a:link,&lt;br /&gt;
a:visited {color:#0C5CAC;}&lt;br /&gt;
a:hover {color:#C77500;}&lt;br /&gt;
#page #page-header {background-color:#0C5CAC;margin:0;padding:0;width:100%;color:#fff;}&lt;br /&gt;
#page #page-header a:link, #page #page-header a:visited {color:#FFAC02}&lt;br /&gt;
#page #page-header .navbar, #page #page-header .navbar a:link, #page #page-header .navbar a:visited {color:#0C5CAC;}&lt;br /&gt;
/** Override the region width **/&lt;br /&gt;
#page-content #region-main-box {left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidthdouble]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-pre {width:[[setting:regionwidth]];left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-post {width:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidthdouble]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
/** Custom CSS **/&lt;br /&gt;
[[setting:customcss]]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will notice that &amp;lt;nowiki&amp;gt;[[setting:backgroundcolor]]&amp;lt;/nowiki&amp;gt; has been used for the html tags background colour:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
html {background-color:[[setting:backgroundcolor]];}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have also set the width of the block regions by adding &amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt; as the width for region-pre and region-post as shown below:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
#page-content #region-main-box {left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidthdouble]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-pre {width:[[setting:regionwidth]];left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-post {width:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidthdouble]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
You&#039;ll notice here that we have to set several different widths and margins using the regionwidth setting and make use of the special regionwidthdouble setting that we added.&lt;br /&gt;
&lt;br /&gt;
The final thing that we did was add the &amp;lt;nowiki&amp;gt;[[setting:customcss]]&amp;lt;/nowiki&amp;gt; to the bottom of the file to ensure that the custom CSS comes last (and therefore can override all other CSS).&lt;br /&gt;
&lt;br /&gt;
And with that we are finished. The screenshot below shows how this now looks in the browser if I set the background colour setting to &#039;&#039;&#039;&amp;lt;span style=&#039;color:#FFA800;&#039;&amp;gt;#FFA800&amp;lt;/span&amp;gt;&#039;&#039;&#039; and made the column width 240px;&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.04.png|715px|thumb|left|Our settings in action]]&amp;lt;br style=&amp;quot;clear:both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using the settings within our layout files==&lt;br /&gt;
Now that we have utilised the first three settings within our theme&#039;s CSS file it is time to implement the other two settings within the layout files so that they are written directly into the page.&lt;br /&gt;
&lt;br /&gt;
You&#039;ll be glad to know this is no where near as difficult as utilising settings within a CSS file although it still does require a little bit of PHP.&lt;br /&gt;
&lt;br /&gt;
First up is the logo setting. Into this setting the user is able to enter the URL to an image to use as the logo for the site. In my case I want this to be just a background logo on top of which I want to position the page header.&lt;br /&gt;
&lt;br /&gt;
Before I start there is one thing I need to do however and that is create a default logo background that gets shown if the user hasn&#039;t set a specific logo file. To do this I simply created an image &#039;&#039;&#039;logo.jpg&#039;&#039;&#039; and put it into a pix directory within the demystified theme. You should end up with &#039;&#039;&#039;theme/demystified/pix/logo.jpg&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Next open up the front-page layout file &#039;&#039;theme/demystified/layout/frontpage.php&#039;&#039;. At the top of the file is the PHP that checks what blocks regions the page has and a bit of other stuff. Well right below the existing bit of PHP we want to add the following code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;logo)) {&lt;br /&gt;
    $logourl = $PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;logo;&lt;br /&gt;
} else {&lt;br /&gt;
    $logourl = $OUTPUT-&amp;gt;pix_url(&#039;logo&#039;, &#039;theme&#039;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
What we are doing here is creating a variable called $logourl that will contain the URL to a logo file that was either entered by the user or if they left it blank is that of our default logo file.&lt;br /&gt;
&lt;br /&gt;
There are two things that you should notice about this. First the logo setting can be retrieved through &#039;&#039;&#039;$PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;logo&#039;&#039;&#039; and second we get the default logo url by calling &#039;&#039;&#039;$OUTPUT-&amp;gt;pix_url(&#039;logo&#039;, &#039;theme&#039;)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Now that we have the logo URL we are going to use we need to add an image to the header section of the page as shown below:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;page-header&amp;quot; class=&amp;quot;clearfix&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;img class=&amp;quot;sitelogo&amp;quot; src=&amp;quot;&amp;lt;?php echo $logourl;?&amp;gt;&amp;quot; alt=&amp;quot;Custom logo here&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;
....&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you save that and browse to your sites front page you will notice that the logo file is now being shown. Hooray. However it is probably not styled too nicely so lets quickly fix that. Open up the core.css file and add the following lines of CSS to the bottom of the file.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
#page-header {position:relative;min-height:100px;}&lt;br /&gt;
#page-header .sitelogo {float:left;}&lt;br /&gt;
#page-header .headermain {position:absolute;left:0.5em;top:50px;margin:0;float:none;font-size:40px;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
These three lines position the image correctly and if you now refresh everything should appear perfectly. &lt;br /&gt;
&lt;br /&gt;
With the logo done the last setting we need to deal with is the footnote setting. The idea with this setting was that the administrator could enter some text into the editor and it would be displayed in the footer of the page.&lt;br /&gt;
&lt;br /&gt;
This is probably the easiest setting to implement.&lt;br /&gt;
&lt;br /&gt;
Within the front page layout file that we edited above add the following lines below those we added previously.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;footnote)) {&lt;br /&gt;
    $footnote = $PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;footnote;&lt;br /&gt;
} else {&lt;br /&gt;
    $footnote = &#039;&amp;lt;!-- There was no custom footnote set --&amp;gt;&#039;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are just collecting the footnote into a variable &#039;&#039;&#039;$footnote&#039;&#039;&#039; and setting a default footnote comment if the user hasn&#039;t entered one.&lt;br /&gt;
&lt;br /&gt;
We can now echo the $footnote variable within the page footer. This can be done as shown below.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;!-- START OF FOOTER --&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;footnote&amp;quot;&amp;gt;&amp;lt;?php echo $footnote; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;p class=&amp;quot;helplink&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;?php echo page_doc_link(get_string(&#039;moodledocslink&#039;)) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And with that done we are finished! Congratulations if you got this far.&lt;br /&gt;
&lt;br /&gt;
The screenshot below shows the demystified theme we have just created that is styled by the settings page.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.05.png|715px|thumb|left|My finished demystified theme]]&amp;lt;br style=&amp;quot;clear:both&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing our creation==&lt;br /&gt;
Congratulations to you! If you&#039;ve made it this far you have done very well. Now it is time to have a look at what we have created and give it a quick test run.&lt;br /&gt;
&lt;br /&gt;
So in this tutorial we have achieved the following:&lt;br /&gt;
&lt;br /&gt;
* We created a theme called demystified that is based on the standard theme.&lt;br /&gt;
* We added a settings page to our new theme.&lt;br /&gt;
* We added the following settings to our settings page:&lt;br /&gt;
** We can set a background colour through the admin interface.&lt;br /&gt;
** We can change the logo of the site.&lt;br /&gt;
** We can change the block region width.&lt;br /&gt;
** We can add a footnote to the page footer&lt;br /&gt;
** We can add some custom CSS to seal the deal.&lt;br /&gt;
* Those settings were then used in the CSS files for our theme.&lt;br /&gt;
* They were also used in the layout files for our theme.&lt;br /&gt;
* And here we are testing it all.&lt;br /&gt;
&lt;br /&gt;
The screenshots below show my testing process and I change each setting and view the outcome. The great thing about this is that with theme designer mode on you see the changes as soon as the form refreshes.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.06.png|300px|thumb|left|Default settings]]&lt;br /&gt;
[[Image:Theme.settings.page.07.png|300px|thumb|left|Changed the background colour setting]]&lt;br /&gt;
[[Image:Theme.settings.page.08.png|300px|thumb|left|Changed the logo and region width]]&lt;br /&gt;
[[Image:Theme.settings.page.09.png|300px|thumb|left|Added a footnote]]&lt;br /&gt;
[[Image:Theme.settings.page.10.png|300px|thumb|left|Added some custom CSS]]&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:both&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The different settings you can use==&lt;br /&gt;
During this tutorial we use four different kinds of settings, a text box, text area, a select (dropdown) and the editor however as I&#039;m sure you have all guessed there is many more some of which will certainly be useful for theme settings.&lt;br /&gt;
&lt;br /&gt;
The following are examples of some of the different settings. I should add that these build upon what we have already done within the tutorial but are not included in the download.&lt;br /&gt;
&lt;br /&gt;
===Colour picker===&lt;br /&gt;
[[Image:Theme.settings.page.11.png|400px|thumb|The colour picker]]&lt;br /&gt;
I can hear you all asking now &#039;Why didn&#039;t you mention this one earlier?&#039; well the answer is simple it didn&#039;t exist when I first wrote the tutorial. It is an admin setting that I wrote several days after because of the fantastic effort people were putting into trying out settings pages.&lt;br /&gt;
&lt;br /&gt;
A bit about the colour picker. First up it is a text box that when the page loads turns into a colour picker that can be used to select a colour and can even preview the selected colour in the page (by clicking the preview button). It is designed to be very easy to use and the code is just about as simple as creating a normal text box setting.&lt;br /&gt;
&lt;br /&gt;
In the image to the left I have replaced the background colour setting we created during the tutorial with the colour picker. Lets have a look at the code involved for that.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Background colour setting&lt;br /&gt;
$name = &#039;theme_demystified/backgroundcolor&#039;;&lt;br /&gt;
$title = get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = &#039;#DDD&#039;;&lt;br /&gt;
$previewconfig = array(&#039;selector&#039;=&amp;gt;&#039;html&#039;, &#039;style&#039;=&amp;gt;&#039;backgroundColor&#039;);&lt;br /&gt;
$setting = new admin_setting_configcolourpicker($name, $title, $description, $default, $previewconfig);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
So first thing you should notice is that the first four lines of code have not changed at all!&lt;br /&gt;
&lt;br /&gt;
The first change we have is to create a variable &#039;&#039;&#039;$previewconfig&#039;&#039;&#039;. &lt;br /&gt;
This variable is used to tell the colour picker what to do when the user clicks the preview button. It should be an array that contains two things, first a selector, and second a style. &lt;br /&gt;
# The selector is a CSS selector like &#039;&#039;.page .header h2&#039;&#039;.&lt;br /&gt;
# The style is a what should change, there are two immediate values it can be, either &#039;&#039;&#039;backgroundColor&#039;&#039;&#039; or &#039;&#039;&#039;color&#039;&#039;&#039;.&lt;br /&gt;
In my case the selector is &#039;&#039;&#039;html&#039;&#039;&#039; to target the html tag and the style is backgroundColor to change the background colour.&lt;br /&gt;
&lt;br /&gt;
The second change is to use &#039;&#039;&#039;admin_setting_configcolourpicker&#039;&#039;&#039; instead of &#039;&#039;admin_setting_configtext&#039;&#039;. The arguments are nearly identical as well except that there is an extra argument to which we give the &#039;&#039;&#039;$previewconfig&#039;&#039;&#039; variable.&lt;br /&gt;
&lt;br /&gt;
And that is it! it is all you need to get the colour picker up and running.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Extra note:&#039;&#039;&#039; The $previewconfig variable is optional. If you don&#039;t want a preview button the simply set &#039;&#039;$previewconfig = null&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Common pitfalls and useful notes==&lt;br /&gt;
&lt;br /&gt;
This section is really just a collection of pointers, tips, notes, and other short useful stuff that may be of use to those attempting this tutorial.&lt;br /&gt;
&lt;br /&gt;
# First up and most importantly there are very few limitations to what you achieve in this fashion.&lt;br /&gt;
# If you get stuck or need a hand ask in the forums, there&#039;s always someone round who can help.&lt;br /&gt;
# If you do something really cool let us know, I know everyone in the community loves finding our what others are achieving.&lt;br /&gt;
# You don&#039;t have to use &#039;&#039;admin_settingpage&#039;&#039; you can also use &#039;&#039;&#039;admin_externalpage&#039;&#039;&#039; if you prefer. It should be noted however that it is not the preferred way to do it as admin_externalpage&#039;s were only left in Moodle 2.0 for backwards compatibility (although they are more flexible one day they will be deprecated or removed). Thank you to Darryl for raising this.&lt;br /&gt;
# If you find that your language strings aren&#039;t being used (you are getting language string notices) and you have double checked that you have turned &#039;&#039;&#039;langstringcache&#039;&#039;&#039; off then you may need to delete the language cache directory. This is located in the moodledata directory for you installation: moodledata/cache/lang/*. You should delete the directory for your chosen language by default &#039;&#039;en&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Adding theme upgrade code]]&lt;br /&gt;
* [[Styling and customising the dock]]&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/discuss.php?d=152053 Theme 2.0: Adding a settings page to your theme] forum discussion&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Creating_a_theme_settings_page&amp;diff=46309</id>
		<title>Creating a theme settings page</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Creating_a_theme_settings_page&amp;diff=46309"/>
		<updated>2014-09-24T22:22:44Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Finishing settings.php */ - update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}This document looks at how to create a settings page for your Moodle 2.x.x theme and how to make use of those settings within the CSS and layout files for your theme.&lt;br /&gt;
&lt;br /&gt;
This is a pretty advanced topic and will require that you have at least an intermediate knowledge of PHP, CSS, and development in general.&lt;br /&gt;
&lt;br /&gt;
==Before we begin==&lt;br /&gt;
[[Image:Theme.settings.page.03.png|350px|thumb|Our end goal. The settings page.]]&lt;br /&gt;
[[Image:Theme.settings.page.10.png|350px|thumb|And what it can do.]]&lt;br /&gt;
There is a huge body of knowledge that we must cover in following through this document and as such I think the best way to write this is as a tutorial.&lt;br /&gt;
&lt;br /&gt;
My intentions for this tutorial are to replicate the standard theme but with a settings page that allows the administrator to set a background colour, set a logo to use with the page, and probably several other minor settings to change the way in which the theme is displayed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I will start this tutorial by creating a new theme which will be largely a copy/paste of the current standard theme. I expect that anyone working through this tutorial has previously read the tutorial I wrote on [[Themes 2.0 creating your first theme|creating your first theme]]. If you haven&#039;t go read it now because I&#039;m not going to go into much detail until we get to the actual process of customising the theme and introducing the settings page.&lt;br /&gt;
&lt;br /&gt;
So before we finally get this started please ensure you can check off everything on the following requirements list.&lt;br /&gt;
* Have a Moodle installation that has already been installed and configured and is ready to use.&lt;br /&gt;
* Have full read/write access to that installation.&lt;br /&gt;
* Be prepared to delete that installation at the end of this... we will destroy it!&lt;br /&gt;
* Have a development environment prepared and ready to use. This includes:&lt;br /&gt;
** Your favourite editor installed, running, and pointed at the themes directory of your installation.&lt;br /&gt;
** Your browser open and your site visible.&lt;br /&gt;
** A bottomless coffee pot... decaf won&#039;t help you with this one.&lt;br /&gt;
* Have set the following settings:&lt;br /&gt;
** &#039;&#039;&#039;themedesignermode&#039;&#039;&#039; if you don&#039;t know what this is please read the [[Themes 2.0 creating your first theme|creating your first theme]] tutorial.&lt;br /&gt;
** &#039;&#039;&#039;allowthemechangeonurl&#039;&#039;&#039; turn this on, it allows you to change themes on the URL and is very handy when developing themes. &#039;&#039;Site Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; Theme settings&#039;&#039;&lt;br /&gt;
** &#039;&#039;&#039;langstringcache&#039;&#039;&#039; if you don&#039;t turn this off you won&#039;t see your strings when they are added. &#039;&#039;Site Administration &amp;gt; Language &amp;gt; Language settings&#039;&#039;&lt;br /&gt;
* And finally an insane ambition to create a customisable theme.&lt;br /&gt;
&lt;br /&gt;
For those interested the theme that I create throughout this tutorial can be downloaded from the forum post in which I announce this document: http://moodle.org/mod/forum/discuss.php?d=152053&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:right;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Our goals for this tutorial==&lt;br /&gt;
The following is just a list goals that I hope to achieve during this tutorial. They are laid out here so that I can easily refer back to them and so that you can easily find them.&lt;br /&gt;
# Create a new theme called &#039;&#039;&#039;demystified&#039;&#039;&#039; based upon the standard theme within Moodle 2.0.&lt;br /&gt;
# Make some minor changes to that theme to allow us to more easily see what is going on.&lt;br /&gt;
# Create a settings page for the demystified theme.&lt;br /&gt;
# Add several settings to our settings page.&lt;br /&gt;
# Use some of those settings to alter our CSS.&lt;br /&gt;
# Use the rest of those settings within our layout file..&lt;br /&gt;
# Discuss the good, the bad, and limits of what we have just created.&lt;br /&gt;
&lt;br /&gt;
So I can see you are all very excited about this point and that you would love to know what settings we are going to create; So here they are:&lt;br /&gt;
&lt;br /&gt;
A setting to ...&lt;br /&gt;
* change the background colour (CSS).&lt;br /&gt;
* set the path to an image that we will use as a logo on all pages (Layout files).&lt;br /&gt;
* override the width of the block regions (CSS).&lt;br /&gt;
* allow a note to be added to the footer of all pages (Layout files).&lt;br /&gt;
* allow custom CSS to be written to do anything the user wants. (CSS)&lt;br /&gt;
&lt;br /&gt;
==Creating the demystified theme==&lt;br /&gt;
Before we start here I want to remind you that I am going to look at this only briefly as I am making the assumption that you have read the [[Themes 2.0 creating your first theme|creating your first theme]] tutorial.&lt;br /&gt;
&lt;br /&gt;
Well lets get into it....&lt;br /&gt;
&lt;br /&gt;
The first thing we need to do is create a directory for our theme which we will call demystified. &lt;br /&gt;
&lt;br /&gt;
So within your Moodle directory create the following folder &#039;&#039;&#039;moodle/theme/demystified&#039;&#039;&#039;. At the same time you can also create the following files and folders which we will get to soon.&lt;br /&gt;
* The file &#039;&#039;&#039;moodle/theme/demystified/config.php&#039;&#039;&#039; for our config information.&lt;br /&gt;
* The directory &#039;&#039;&#039;moodle/theme/demystified/layout&#039;&#039;&#039; for our layout files.&lt;br /&gt;
* The directory &#039;&#039;&#039;moodle/theme/demystified/style&#039;&#039;&#039; for our css files.&lt;br /&gt;
* The file &#039;&#039;&#039;moodle/theme/demystified/style/core.css&#039;&#039;&#039; which will contain our special CSS.&lt;br /&gt;
&lt;br /&gt;
Next we will copy the layout files from the base theme to our new theme demystified. We are basing the demystified theme on the standard theme however that doesn&#039;t use it&#039;s own layout files it uses the base theme&#039;s layout files so those are the ones we want. &lt;br /&gt;
&lt;br /&gt;
The reason that we are coping these layout files is that later on in this tutorial we will be modifying them to make use of our new settings... so copy all of the layout files from &#039;&#039;&#039;moodle/theme/base/layout&#039;&#039;&#039; to &#039;&#039;&#039;moodle/theme/demystified/layout&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
There should be three files that you just copied:&lt;br /&gt;
# embedded.php&lt;br /&gt;
# frontpage.php&lt;br /&gt;
# general.php&lt;br /&gt;
&lt;br /&gt;
Now we need to populate demystified/config.php with the settings for our new theme. They are as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;name = &#039;demystified&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Simply sets the name of our theme.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;,&#039;base&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This theme is extending both the standard theme and the base theme. Remember when extending a theme you also need to extend its parents or things might not work correctly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;core&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This tells our theme that we want to use the file &#039;&#039;&#039;demystified/style/core.css&#039;&#039;&#039; with this theme.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;height:300px;overflow-y:scroll;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Most backwards compatible layout without the blocks - this is the layout used by default&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&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;
    // 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;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;
    // Main course page&lt;br /&gt;
    &#039;course&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;coursecategory&#039; =&amp;gt; array(&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;
    // part of course, typical for modules - default page layout if $cm specified in require_login()&lt;br /&gt;
    &#039;incourse&#039; =&amp;gt; array(&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;
    // The site home page.&lt;br /&gt;
    &#039;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;frontpage.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;
    // Server administration scripts.&lt;br /&gt;
    &#039;admin&#039; =&amp;gt; array(&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;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // My dashboard page&lt;br /&gt;
    &#039;mydashboard&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // My public page&lt;br /&gt;
    &#039;mypublic&#039; =&amp;gt; array(&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;
    &#039;login&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    // Pages that appear in pop-up windows - no navigation, no blocks, no header.&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // No blocks and minimal footer - used for legacy frame layouts only!&lt;br /&gt;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible&lt;br /&gt;
    &#039;embedded&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Used during upgrade and install, and for the &#039;This site is undergoing maintenance&#039; message.&lt;br /&gt;
    // This must not have any blocks, and it is good idea if it does not have links to&lt;br /&gt;
    // other places - for example there should not be a home link in the footer...&lt;br /&gt;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Now that all looks very complicated however its really not too bad as it is just copied from the base theme&#039;s config.php file. We can do this because we copied the layout files from the base theme to begin with and for the time being there are no changes that we wish to make. Simply open up &#039;&#039;&#039;theme/base/config.php&#039;&#039;&#039; and copy the layouts from there.&lt;br /&gt;
&lt;br /&gt;
And that is it. The config.php file for our demystified theme is complete. The full source is shown below:&lt;br /&gt;
&amp;lt;div style=&amp;quot;height:300px;overflow-y:scroll;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
// This file is part of Moodle - http://moodle.org/&lt;br /&gt;
//&lt;br /&gt;
// Moodle is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// Moodle is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with Moodle.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * The demystified theme config file&lt;br /&gt;
 *&lt;br /&gt;
 * This theme was created to document the process of adding a settings page to a theme&lt;br /&gt;
 *&lt;br /&gt;
 * @copyright 2010 Sam Hemelryk&lt;br /&gt;
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
// The name of our theme&lt;br /&gt;
$THEME-&amp;gt;name = &#039;demystified&#039;;&lt;br /&gt;
&lt;br /&gt;
// The other themes this theme extends&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;,&#039;base&#039;);&lt;br /&gt;
&lt;br /&gt;
// The CSS files this theme uses (located in the style directory)&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;core&#039;);&lt;br /&gt;
&lt;br /&gt;
// The layout definitions for this theme&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Most backwards compatible layout without the blocks - this is the layout used by default&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&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;
    // 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;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;
    // Main course page&lt;br /&gt;
    &#039;course&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;coursecategory&#039; =&amp;gt; array(&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;
    // part of course, typical for modules - default page layout if $cm specified in require_login()&lt;br /&gt;
    &#039;incourse&#039; =&amp;gt; array(&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;
    // The site home page.&lt;br /&gt;
    &#039;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;frontpage.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;
    // Server administration scripts.&lt;br /&gt;
    &#039;admin&#039; =&amp;gt; array(&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;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // My dashboard page&lt;br /&gt;
    &#039;mydashboard&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // My public page&lt;br /&gt;
    &#039;mypublic&#039; =&amp;gt; array(&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;
    &#039;login&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    // Pages that appear in pop-up windows - no navigation, no blocks, no header.&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // No blocks and minimal footer - used for legacy frame layouts only!&lt;br /&gt;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible&lt;br /&gt;
    &#039;embedded&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Used during upgrade and install, and for the &#039;This site is undergoing maintenance&#039; message.&lt;br /&gt;
    // This must not have any blocks, and it is good idea if it does not have links to&lt;br /&gt;
    // other places - for example there should not be a home link in the footer...&lt;br /&gt;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The screenshot below shows both the directory structure we have now created and the theme presently.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.01.png]]&lt;br /&gt;
&lt;br /&gt;
To view the theme so far open you browser and enter the URL of your site followed by &#039;&#039;&#039;?theme=demystified&#039;&#039;&#039;. You should see the theme that we just created which will look exactly like the base standard theme.&lt;br /&gt;
&lt;br /&gt;
The final thing that we want to do is add a little bit of CSS to the demystified theme that will both visually set this theme apart from the standard theme and second build a the base which our settings can later extend.&lt;br /&gt;
&lt;br /&gt;
I added the following snippet of CSS to the file &#039;&#039;&#039;demystified/style/core.css&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
html {background-color:#DDD;}&lt;br /&gt;
body {margin:30px;padding:0;border:1px solid #333;border-width:0 10px 0 10px;background-color:#333;}&lt;br /&gt;
body #page {background-color:#FFF;position:relative;top:-10px;}&lt;br /&gt;
.block .header {background-image:none;background-color:#0C5CAC;border:1px solid #0C5CAC;color:#FFF;}&lt;br /&gt;
.block {border-color:#4BA7FF;background-color:#DDEEFF;}&lt;br /&gt;
.block .content {background-color:#F1F8FF;}&lt;br /&gt;
a:link,&lt;br /&gt;
a:visited {color:#0C5CAC;}&lt;br /&gt;
a:hover {color:#C77500;}&lt;br /&gt;
#page #page-header {background-color:#0C5CAC;margin:0;padding:0;width:100%;color:#fff;}&lt;br /&gt;
#page #page-header a:link, #page #page-header a:visited {color:#FFAC02}&lt;br /&gt;
#page #page-header .navbar, #page #page-header .navbar a:link, #page #page-header .navbar a:visited {color:#0C5CAC;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The CSS that we have just added to our theme sets a couple of colours on the front page. Presently this is the only CSS I will add, I know it isn&#039;t complete by any means but it achieves it&#039;s purpose as the screenshot below illustrates.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.02.png|715px|thumb|left|The newly styles demystified theme]]&amp;lt;br style=&amp;quot;clear:both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And with that I will move on to the real purpose of this tutorial, creating the settings page&lt;br /&gt;
&lt;br /&gt;
==Setting up the settings page==&lt;br /&gt;
With the demystified theme set up it is time to create the settings page. This is where the real PHP fun begins.&lt;br /&gt;
&lt;br /&gt;
For those of you who happen to be familiar with development of modules, blocks or other plugin types you have probably encountered settings pages before and this is not going to be any different.&lt;br /&gt;
&lt;br /&gt;
However for those who haven&#039;t which I imagine is most of you this is going to be quite a challenge. I will try to walk through this step by step however if at any point you get stuck don&#039;t hesitate to ask in the forums as I imagine you will get a speedy response.&lt;br /&gt;
&lt;br /&gt;
===How settings pages work in Moodle===&lt;br /&gt;
Settings pages can be used by nearly every plugin type, of which themes is of course one. The way in which it all works isn&#039;t too tricky to understand. &lt;br /&gt;
&lt;br /&gt;
All of the settings for Moodle can be configured through the administrator interfaces when logged in. I am sure that everyone here has seen those pages and has changed a setting or two before so you will all know what I am talking about. Well the settings page for a theme is no different. It will be shown in the administration pages tree under &#039;&#039;&#039;Appearance &amp;gt; Themes&#039;&#039;&#039; and all we have to do is tell Moodle what settings there are.&lt;br /&gt;
&lt;br /&gt;
This is done by creating a settings.php file within our theme into which we will add code that tells Moodle about the settings we want to add/use.&lt;br /&gt;
&lt;br /&gt;
When telling Moodle about each setting we are simply creating a new &#039;&#039;admin_setting&#039;&#039; instance of the type we want and the properties we want and then adding it to our settings page.&lt;br /&gt;
&lt;br /&gt;
There is really not much more too it at this level. Things can get very complex very fast so the best thing we can do now is start creating our settings.php file for the demystified theme and see where it leads us.&lt;br /&gt;
&lt;br /&gt;
===Creating the settings page===&lt;br /&gt;
So as mentioned before we need a settings.php file which we will create now. To begin with create the file &#039;&#039;&#039;theme/demystified/settings.php&#039;&#039;&#039; and open it in your favourite editor so its ready to go.&lt;br /&gt;
&lt;br /&gt;
Before we start adding code however lets just remember the settings that we want to create:&lt;br /&gt;
* change the background colour (CSS).&lt;br /&gt;
* set the path to an image that we will use as a logo on all pages (Layout files).&lt;br /&gt;
* override the width of the block regions (CSS).&lt;br /&gt;
* allow a note to be added to the footer of all pages (Layout files).&lt;br /&gt;
* allow custom CSS to be written to do anything the user wants. (CSS)&lt;br /&gt;
&lt;br /&gt;
Alright.&lt;br /&gt;
&lt;br /&gt;
Now thinking about this the first setting is as basic as it gets, all we need is a text box that the user can type a colour into.&lt;br /&gt;
&lt;br /&gt;
The second is to allow a logo to be used in the header of each page. What we want here is a path but should it be a physical path e.g. C:/path/to/image.png or should it be a web path e.g. &amp;lt;nowiki&amp;gt;http://mysite.com/path/to/image.png&amp;lt;/nowiki&amp;gt;?&lt;br /&gt;
For the purpose of this tutorial I am going to go with a web path because it is going to be easier to code and will hopefully be a little easier to understand to begin with.&lt;br /&gt;
&lt;br /&gt;
The third setting is a little more complex. For this I want a drop down box with some specific widths that the administrator can select.&lt;br /&gt;
&lt;br /&gt;
The forth and the fifth settings are both pretty straight forward, there we want a textarea into which the user can enter what ever they want and we will do something useful with it.&lt;br /&gt;
&lt;br /&gt;
Now that we have an understanding about the settings we wish to define pull up your editor and lets start coding....&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Settings for the demystified theme&lt;br /&gt;
 */&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die;&lt;br /&gt;
&lt;br /&gt;
if ($ADMIN-&amp;gt;fulltree) {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is the first bit of code we must enter, the first line is of course just the opening php tag, secondly we have a comment that describes this file, and then we get create a new &#039;&#039;&#039;admin_settingspage object&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This admin_settingspage object that we have just created is a representation of our settings page and is the what we add our new settings to. When creating it we give it two arguments, first the name of the page which is in this case &#039;&#039;&#039;theme_&#039;&#039;themename&#039;&#039;&#039;&#039;&#039; and the title for the page which we get with the get_string method.&lt;br /&gt;
&lt;br /&gt;
At the moment I&#039;m not going to worry about adding the string, we will get to that later once we have defined all of our settings.&lt;br /&gt;
&lt;br /&gt;
====Background colour====&lt;br /&gt;
&lt;br /&gt;
With the page now created lets add our first setting: Background colour.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Background colour setting&lt;br /&gt;
$name = &#039;theme_demystified/backgroundcolor&#039;;&lt;br /&gt;
$title = get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = &#039;#DDD&#039;;&lt;br /&gt;
$setting = new admin_setting_configtext($name, $title, $description, $default, PARAM_CLEAN, 12);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Thankfully this isn&#039;t as difficult as it initially looks.&lt;br /&gt;
&lt;br /&gt;
The first line of code is creating a variable for the name of the background colour setting. In this case it is &#039;&#039;&#039;theme_demystified/backgroundcolor&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
The name is very important, for the setting to be usable we have to follow a strict naming convention. &#039;&#039;&#039;theme_&#039;&#039;themename&#039;&#039;/&#039;&#039;settingname&#039;&#039;&#039;&#039;&#039; where &#039;&#039;&#039;&#039;&#039;themename&#039;&#039;&#039;&#039;&#039; is the name of the theme the setting belongs to and &#039;&#039;&#039;&#039;&#039;settingname&#039;&#039;&#039;&#039;&#039; is the name for the setting by which we will use it.&lt;br /&gt;
&lt;br /&gt;
The second line of code creates a variable that contains the title of the setting. This is what the user sees to the right of the setting on the settings page and should be a short description of the setting. Here we are again using the &#039;&#039;get_string&#039;&#039; method so we will need to remember to add that string later on.&lt;br /&gt;
&lt;br /&gt;
The third line of code sets the description. This should describe what the setting does or how it works and again we will use the get_string method.&lt;br /&gt;
&lt;br /&gt;
The fourth line creates a variable that will be used as the default value for the setting. Because this setting is a colour we want an HTML colour to be the default value.&lt;br /&gt;
&lt;br /&gt;
The fifth line is where we put it all together. Here we create a new &#039;&#039;&#039;admin_setting_configtext&#039;&#039;&#039; object. This object will represent the background colour setting.&lt;br /&gt;
&lt;br /&gt;
When we create it we need to give it 6 different things.&lt;br /&gt;
# The name of the setting. In this case we have a variable &#039;&#039;&#039;$name&#039;&#039;&#039;.&lt;br /&gt;
# The title for this setting. We used the variable &#039;&#039;&#039;$title&#039;&#039;&#039;.&lt;br /&gt;
# The description of the setting &#039;&#039;&#039;$description&#039;&#039;&#039;.&lt;br /&gt;
# The default value for the setting. &#039;&#039;&#039;$default&#039;&#039;&#039; is the variable this.&lt;br /&gt;
# The type of value we want the user to enter. For this we have used PARAM_CLEAN which tells Moodle to get rid of any nasties from what the user enters.&lt;br /&gt;
# The size of the field. In our case 12 characters will be plenty.&lt;br /&gt;
&lt;br /&gt;
The sixth and final line of code adds our newly created setting to the administration page we created earlier.&lt;br /&gt;
&lt;br /&gt;
That is it we have successfully created and added our first setting, however there are several more to settings to do, and there are a couple of important things that you need to be aware of before we move on.&lt;br /&gt;
&lt;br /&gt;
First: There are several different types of settings that you can create and add to a page, and each one may differ in what they need you to give them. In this case it was name, title, description, default, type, and size. However other settings will likely require different things. Smart editors like Netbeans or Eclipse can tell you what is required, otherwise you will need to research it.&lt;br /&gt;
&lt;br /&gt;
Second: Normally settings are declared on one line as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$setting-&amp;gt;add(new admin_setting_configtext(&#039;theme_demystified/backgroundcolor&#039;, get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;), get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;), &#039;#DDD&#039;, PARAM_CLEAN, 12));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
While this is structurally identical as all we have done is move everything onto one line and do away with the variables it is a little harder to read when you are learning all of this.&lt;br /&gt;
&lt;br /&gt;
====The logo file====&lt;br /&gt;
Time to create the second setting that will allow the user to enter a URL to an image they wish to use as the logo on their site.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Logo file setting&lt;br /&gt;
$name = &#039;theme_demystified/logo&#039;;&lt;br /&gt;
$title = get_string(&#039;logo&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;logodesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtext($name, $title, $description, &#039;&#039;, PARAM_URL);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The first thing that you will notice about this setting that it is very similar to the first setting, in fact all we have changed is the name, title, description, and default value. We have however changed the value type from PARAM_CLEAN to PARAM_URL, this makes sure the user enters a URL. You will also notice that for this one we don&#039;t set a size for the field as we have no idea how long the URL will be.&lt;br /&gt;
&lt;br /&gt;
====Block region width====&lt;br /&gt;
The third setting should allow the user to set a width for the block regions that will be used as columns.&lt;br /&gt;
&lt;br /&gt;
For this setting I want to do something a little different from the previous two, here I want to use a select box so that the user selects a width for the column from a list I provide.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Block region width&lt;br /&gt;
$name = &#039;theme_demystified/regionwidth&#039;;&lt;br /&gt;
$title = get_string(&#039;regionwidth&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;regionwidthdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = 200;&lt;br /&gt;
$choices = array(150=&amp;gt;&#039;150px&#039;, 170=&amp;gt;&#039;170px&#039;, 200=&amp;gt;&#039;200px&#039;, 240=&amp;gt;&#039;240px&#039;, 290=&amp;gt;&#039;290px&#039;, 350=&amp;gt;&#039;350px&#039;, 420=&amp;gt;&#039;420px&#039;);&lt;br /&gt;
$setting = new admin_setting_configselect($name, $title, $description, $default, $choices);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
So looking at the code: The first four lines you will recognise. $name, $title, $description, and $default are all being set.&lt;br /&gt;
&lt;br /&gt;
The fifth line of code however introduces something new. Of course in order to have a select box we have to have options, in this case we have an array of options stored in the variable $choices.&lt;br /&gt;
&lt;br /&gt;
The array of options is constructed of a collection of &#039;&#039;&#039;&#039;&#039;value&#039;&#039;&#039; =&amp;gt; &#039;&#039;&#039;label&#039;&#039;&#039;&#039;&#039; pairs. Notice how we don&#039;t add &#039;&#039;&#039;px&#039;&#039;&#039; to the value. This is is very intentional as later on I need to do a little bit of math with that value so we need it to be a number.&lt;br /&gt;
&lt;br /&gt;
The lines after should look familiar again, the only difference being that instead of a &#039;&#039;admin_setting_configtext&#039;&#039; setting we have created a &#039;&#039;admin_setting_configselect&#039;&#039; for which we must give the choices for the select box as the fifth argument.&lt;br /&gt;
&lt;br /&gt;
Woohoo, we&#039;ve just created our first select box setting.&lt;br /&gt;
&lt;br /&gt;
====Foot note====&lt;br /&gt;
Now to create the foot note setting. Here we want the user to be able to enter some arbitrary text that will be used in the footer of the page. For this I want the user to be able to enter some HTML so I will create an editor setting.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Foot note setting&lt;br /&gt;
$name = &#039;theme_demystified/footnote&#039;;&lt;br /&gt;
$title = get_string(&#039;footnote&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;footnotedesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_confightmleditor($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
How simple is that!&lt;br /&gt;
&lt;br /&gt;
It is just about identical to the first two settings except that for this we have created a &#039;&#039;admin_setting_confightmleditor&#039;&#039; setting rather than a text setting.&lt;br /&gt;
&lt;br /&gt;
Note: You can also set the columns and rows for the editor setting using the fifth and sixth arguments.&lt;br /&gt;
&lt;br /&gt;
====Custom CSS====&lt;br /&gt;
The final setting is to allow the user to add some custom CSS to the theme that will be used on every page. I want this to be a plain textarea into which the user can enter CSS.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Custom CSS file&lt;br /&gt;
$name = &#039;theme_demystified/customcss&#039;;&lt;br /&gt;
$title = get_string(&#039;customcss&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;customcssdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtextarea($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Just like the editor or text settings. It&#039;s getting very easy now!&lt;br /&gt;
&lt;br /&gt;
====Finishing settings.php====&lt;br /&gt;
With all of our settings defined and added to our page that we created right at the beginning it is time to finish it all off.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
} // This is the closing brace that encloses all the above settings. &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The above line is the final line for the page. It is adding the page that we have created &#039;&#039;&#039;$setting&#039;&#039;&#039; to the admin tree structure. In this case it is adding it to the themes branch.&lt;br /&gt;
&lt;br /&gt;
The following is the completed source for our settings.php ..... for your copy/paste pleasure.&lt;br /&gt;
&amp;lt;div style=&#039;height:300px;overflow:auto;&#039;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Settings for the demystified theme&lt;br /&gt;
 */&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die;&lt;br /&gt;
 &lt;br /&gt;
if ($ADMIN-&amp;gt;fulltree) {&lt;br /&gt;
&lt;br /&gt;
    // Background colour setting&lt;br /&gt;
    name = &#039;theme_demystified/backgroundcolor&#039;;&lt;br /&gt;
    $title = get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
    $description = get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
    $default = &#039;#DDD&#039;;&lt;br /&gt;
    $setting = new admin_setting_configtext($name, $title, $description, $default, PARAM_CLEAN, 12);&lt;br /&gt;
    $setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
    $settings-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
// Logo file setting.&lt;br /&gt;
$name = &#039;theme_demystified/logo&#039;;&lt;br /&gt;
$title = get_string(&#039;logo&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;logodesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtext($name, $title, $description, &#039;&#039;, PARAM_URL);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
// Block region width.&lt;br /&gt;
$name = &#039;theme_demystified/regionwidth&#039;;&lt;br /&gt;
$title = get_string(&#039;regionwidth&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;regionwidthdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = 200;&lt;br /&gt;
$choices = array(150=&amp;gt;&#039;150px&#039;, 170=&amp;gt;&#039;170px&#039;, 200=&amp;gt;&#039;200px&#039;, 240=&amp;gt;&#039;240px&#039;, 290=&amp;gt;&#039;290px&#039;, 350=&amp;gt;&#039;350px&#039;, 420=&amp;gt;&#039;420px&#039;);&lt;br /&gt;
$setting = new admin_setting_configselect($name, $title, $description, $default, $choices);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
// Foot note setting.&lt;br /&gt;
$name = &#039;theme_demystified/footnote&#039;;&lt;br /&gt;
$title = get_string(&#039;footnote&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;footnotedesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_confightmleditor($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
// Custom CSS file.&lt;br /&gt;
$name = &#039;theme_demystified/customcss&#039;;&lt;br /&gt;
$title = get_string(&#039;customcss&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;customcssdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtextarea($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Creating a language file and adding our strings===&lt;br /&gt;
As I&#039;m sure none of you have forgotten, throughout the creation of the our settings.php page, we used a lot of strings that I mentioned we would set later on. Well now is the time to set those strings.&lt;br /&gt;
&lt;br /&gt;
First up create the following directories and file for our language strings:&lt;br /&gt;
* Directory &#039;&#039;&#039;theme/demystified/lang&#039;&#039;&#039;&lt;br /&gt;
* Directory &#039;&#039;&#039;theme/demystified/lang/en&#039;&#039;&#039;&lt;br /&gt;
* File &#039;&#039;&#039;theme/demystified/lang/theme_demystified.php&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
What we have created here is the required structure for Moodle to start looking for language strings.&lt;br /&gt;
&lt;br /&gt;
First Moodle locates the lang directory, once found it looks within that directory for another directory that uses the character code for the language the user has selected, by default this is &#039;&#039;&#039;en&#039;&#039;&#039; for English. Once that is found it looks for the appropriate language file, in this case &#039;&#039;&#039;theme_demystified.php&#039;&#039;&#039; from which it will load all language strings for our theme.&lt;br /&gt;
&lt;br /&gt;
If English isn&#039;t your chosen language simply replace the &#039;&#039;en&#039;&#039; directory with one that uses your chosen languages character code (two letters).&lt;br /&gt;
&lt;br /&gt;
We can now add our language strings to &#039;&#039;&#039;theme/demystified/lang/theme_demystified.php&#039;&#039;&#039;. Copy and paste the following lines of PHP into this file.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This file contains the strings used by the demystified theme&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
$string[&#039;backgroundcolor&#039;] = &#039;Background colour&#039;;&lt;br /&gt;
$string[&#039;backgroundcolordesc&#039;] = &#039;This sets the background colour for the theme.&#039;;&lt;br /&gt;
$string[&#039;configtitle&#039;] = &#039;Demystified theme&#039;;&lt;br /&gt;
$string[&#039;customcss&#039;] = &#039;Custom CSS&#039;;&lt;br /&gt;
$string[&#039;customcssdesc&#039;] = &#039;Any CSS you enter here will be added to every page allowing your to easily customise this theme.&#039;;&lt;br /&gt;
$string[&#039;footnote&#039;] = &#039;Footnote&#039;;&lt;br /&gt;
$string[&#039;footnotedesc&#039;] = &#039;The content from this textarea will be displayed in the footer of every page.&#039;;&lt;br /&gt;
$string[&#039;logo&#039;] = &#039;Logo&#039;;&lt;br /&gt;
$string[&#039;logodesc&#039;] = &#039;Enter the URL to an image to use as the logo for this site. Should be http://www.yoursite.com/path/to/logo.png&#039;;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;Demystified&#039;;&lt;br /&gt;
$string[&#039;regionwidth&#039;] = &#039;Column width&#039;;&lt;br /&gt;
$string[&#039;regionwidthdesc&#039;] = &#039;This sets the width of the two block regions that form the left and right columns.&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above lines of code I have added an entry for each language string we used within &#039;&#039;settings.php&#039;&#039;. When adding language strings like this make sure you use single quotes and try to keep things alphabetical - it helps greatly when managing strings.&lt;br /&gt;
&lt;br /&gt;
Now when we view the settings page there will not be any errors or strings missing.&lt;br /&gt;
&lt;br /&gt;
===Having a look at what we have created===&lt;br /&gt;
Now that we have created our settings page (settings.php) and added all of the language strings it is time to have a look at things in your browser.&lt;br /&gt;
&lt;br /&gt;
Open your browser and enter the URL to your site. When you arrive at your site login as an administrator.&lt;br /&gt;
&lt;br /&gt;
If you are not redirected to view the new settings change your URL to &amp;lt;nowiki&amp;gt;http://www.yoursite.com/admin/&amp;lt;/nowiki&amp;gt; and your will see a screen to set the new theme settings we have just created. This lets us know that everything has worked correctly.&lt;br /&gt;
&lt;br /&gt;
At any point now you are able to log in as administrator and within the settings block browse to &#039;&#039;&#039;Site administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; Demystified theme&#039;&#039;&#039; to change those settings.&lt;br /&gt;
&lt;br /&gt;
The screenshot below shows you what you should see at this point:&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.03.png|715px|thumb|left|The settings page we just created]]&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using the settings in CSS==&lt;br /&gt;
With the settings page now created and operational it is time to make use of our new settings. The settings that we want to use within our CSS is as follows:&lt;br /&gt;
&lt;br /&gt;
; backgroundcolor : Will be used to set the background colour in CSS.&lt;br /&gt;
; regionwidth : Will be the width of the column for CSS.&lt;br /&gt;
; customcss : Will be some custom CSS to add to our stylesheet.&lt;br /&gt;
&lt;br /&gt;
At this point those names are the names we used for our setting with the slash and everything before it having been removed.&lt;br /&gt;
&lt;br /&gt;
Before we start tearing into some code it is important that we have a look at what we are going to do and how we are going to go about it.&lt;br /&gt;
&lt;br /&gt;
===How it all works within Moodle===&lt;br /&gt;
The first thing to understand is that while Moodle allows you to create a settings page and automates it inclusion and management right into the administration interfaces there is no smart equivalent for using the settings. This is simply because there is no way to predict how people will want to use the settings.&lt;br /&gt;
&lt;br /&gt;
However don&#039;t think of this as a disadvantage, in fact it is quite the contrary. Although we can&#039;t just &#039;&#039;use&#039;&#039; our settings we can take full control over how and where we use them. It means it will take a little more code but in the end that will work to our advantage as we can do anything we want.&lt;br /&gt;
&lt;br /&gt;
Moodle does help us out a little but not in an obvious way. The first thing that Moodle does is look for a config variable &#039;&#039;&#039;csspostprocess&#039;&#039;&#039; that should be the name of a function which we want called to make any changes to the CSS after it has been prepared.&lt;br /&gt;
&lt;br /&gt;
The second thing Moodle does is include a lib.php from the theme&#039;s directory if one exists (also for the themes the current theme extends.) which ensures that as long as we write our code within &#039;&#039;&#039;theme/demystified/lib.php&#039;&#039;&#039; it will be included and ready to be used.&lt;br /&gt;
&lt;br /&gt;
The third and final thing Moodle does that will help us out here is ensure that by the time any of code is ready to execute the settings have been prepared and are ready to be used within a theme config object which is passed into our &#039;&#039;csspostprocess&#039;&#039; function.&lt;br /&gt;
&lt;br /&gt;
===Our plan===&lt;br /&gt;
As you have already probably guessed we will need to create a function to make the changes to the CSS that we want. We will then set the theme config option &#039;&#039;&#039;$THEME-&amp;gt;csspostprocess&#039;&#039;&#039; to the name of our function.&lt;br /&gt;
&lt;br /&gt;
By doing this when Moodle builds the CSS file it will call our function afterwards with the CSS and the theme object that contains our setting.&lt;br /&gt;
&lt;br /&gt;
Now we know that we will use the &#039;&#039;csspostprocess&#039;&#039; function but how are we going to change the CSS, we could get the function to add CSS, or we could get the function to replace something within the CSS. My personal preference is to replace something within the CSS, just like what is happening with images. If you want to use an image within CSS you would write &amp;lt;nowiki&amp;gt;[[pix:theme|imagename]]&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For settings I am going to use &amp;lt;nowiki&amp;gt;[[setting:settingname]]&amp;lt;/nowiki&amp;gt;, this way it looks a bit like something you are already familiar with.&lt;br /&gt;
&lt;br /&gt;
What we need to decide upon next is the best way in which to replace our settings tag with the settings that the user has set.&lt;br /&gt;
&lt;br /&gt;
There are two immediate options available to us:&lt;br /&gt;
# Make the &#039;&#039;csspostprocess&#039;&#039; function do all the work.&lt;br /&gt;
# Make the &#039;&#039;csspostprocess&#039;&#039; function call a separate function for each setting.&lt;br /&gt;
Solution 1 might sound like the simplest however it is going to result in a &#039;&#039;&#039;VERY&#039;&#039;&#039; complex function. Remember the user might have left settings blank or entered something that wouldn&#039;t be valid so we would need to make the sure there is some validation and a good default.&lt;br /&gt;
Because of this I think that solution 2 is the better solution.&lt;br /&gt;
&lt;br /&gt;
So we are going to need a &#039;&#039;csspostprocess&#039;&#039; function and then a function for each of the three settings we have that will do the replacements.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// This is our css post process function&lt;br /&gt;
function demystified_process_css($css, $theme) {};&lt;br /&gt;
// This replaces [[setting:backgroundcolor]] with the background colour&lt;br /&gt;
function demystified_set_backgroundcolor($css, $backgroundcolor) {};&lt;br /&gt;
// This replaces [[setting:regionwidth]] with the correct region width&lt;br /&gt;
function demystified_set_regionwidth() {$css, $regionwidth};&lt;br /&gt;
// This replaces [[setting:customcss]] with the custom css&lt;br /&gt;
function demystified_set_customcss() {$css, $customcss};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you should note about the above functions is that they all start with the theme&#039;s name. This is required to ensure that the functions are named uniquely as it is VERY unlikely that someone has already created these functions.&lt;br /&gt;
&lt;br /&gt;
So with our plan set out lets start writing the code.&lt;br /&gt;
&lt;br /&gt;
===Writing the code===&lt;br /&gt;
The very first thing that we need to do is create a lib.php for our theme into which our css processing functions are going to go. So please at this point create &#039;&#039;&#039;theme/demystified/lib.php&#039;&#039;&#039; and open it in your editor ready to go.&lt;br /&gt;
&lt;br /&gt;
The first bit of code we have to write is the function that will be called by Moodle to do the processing &#039;&#039;&#039;demystified_process_css&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
Before we start out please remember that the wonderful thing about coding is that there is any number of solutions to a problem. The solutions that you are seeing here in this tutorial are solutions that I have come up with to meet fulfil the needs of the tutorial without being so complex that they are hard to understand. This probably isn&#039;t how I would go about it normally but this is a little easier to understand for those who aren&#039;t overly familiar with PHP and object orientation.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_process_css====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function demystified_process_css($css, $theme) {&lt;br /&gt;
&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;backgroundcolor)) {&lt;br /&gt;
        $backgroundcolor = $theme-&amp;gt;settings-&amp;gt;backgroundcolor;&lt;br /&gt;
    } else {&lt;br /&gt;
        $backgroundcolor = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_backgroundcolor($css, $backgroundcolor);&lt;br /&gt;
&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;regionwidth)) {&lt;br /&gt;
        $regionwidth = $theme-&amp;gt;settings-&amp;gt;regionwidth;&lt;br /&gt;
    } else {&lt;br /&gt;
        $regionwidth = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_regionwidth($css, $regionwidth);&lt;br /&gt;
&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;customcss)) {&lt;br /&gt;
        $customcss = $theme-&amp;gt;settings-&amp;gt;customcss;&lt;br /&gt;
    } else {&lt;br /&gt;
        $customcss = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_customcss($css, $customcss);&lt;br /&gt;
&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So lets look at the things that make up this function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function demystified_process_css($css, $theme) {&lt;br /&gt;
    //.....&lt;br /&gt;
    return $css&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This of course is the function declaration. &lt;br /&gt;
&lt;br /&gt;
The function gets given two variables, the first &#039;&#039;&#039;$css&#039;&#039;&#039; is a pile of CSS as one big string, and the second is the theme object &#039;&#039;&#039;$theme&#039;&#039;&#039; that contains all of the configuration, options, and settings for our theme.&lt;br /&gt;
&lt;br /&gt;
It then returns the &#039;&#039;$css&#039;&#039; variable, essentially returning the modified CSS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    //...&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;backgroundcolor)) {&lt;br /&gt;
        $backgroundcolor = $theme-&amp;gt;settings-&amp;gt;backgroundcolor;&lt;br /&gt;
    } else {&lt;br /&gt;
        $backgroundcolor = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_backgroundcolor($css, $backgroundcolor);&lt;br /&gt;
    //...&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are processing our first setting &#039;&#039;backgroundcolor&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
The first thing that we need to do is check whether it has been set and whether it has a value. If it has then we store that value in &#039;&#039;&#039;$backgroundcolor&#039;&#039;&#039;. It is doesn&#039;t have a value then we set &#039;&#039;$backgroundcolor&#039;&#039; to null. This ensures that &#039;&#039;$backgroundcolor&#039;&#039; is set because if it isn&#039;t then you are going to get a notice (if you have debugging on).&lt;br /&gt;
&lt;br /&gt;
The final line of this block calls the function &#039;&#039;&#039;demystified_set_backgroundcolor&#039;&#039;&#039;. We haven&#039;t written this function yet but we will shortly. When we call it we give it the &#039;&#039;$css&#039;&#039; variable that contains all of the CSS and we give it the background colour variable &#039;&#039;$backgroundcolor&#039;&#039;. Once this function is finished it returns the &#039;&#039;$css&#039;&#039; variable with all of the changes made much like how our css processing function works.&lt;br /&gt;
&lt;br /&gt;
What you should also note about this code is this:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$theme-&amp;gt;settings-&amp;gt;backgroundcolor&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
As mentioned earlier &#039;&#039;$theme&#039;&#039; is an object that contains all of the configuration and settings for our theme. The &#039;&#039;$theme&#039;&#039; object has a $settings property which contains all of the settings for our theme, and finally the settings property contains a variable backgroundcolor that is the value the user entered for that setting. That is how we get a settings value.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($theme-&amp;gt;settings-&amp;gt;regionwidth)) {&lt;br /&gt;
    $regionwidth = $theme-&amp;gt;settings-&amp;gt;regionwidth;&lt;br /&gt;
} else {&lt;br /&gt;
    $regionwidth = null;&lt;br /&gt;
}&lt;br /&gt;
$css = demystified_set_regionwidth($css, $regionwidth);&lt;br /&gt;
&lt;br /&gt;
if (!empty($theme-&amp;gt;settings-&amp;gt;customcss)) {&lt;br /&gt;
    $customcss = $theme-&amp;gt;settings-&amp;gt;customcss;&lt;br /&gt;
} else {&lt;br /&gt;
    $customcss = null;&lt;br /&gt;
}&lt;br /&gt;
$css = demystified_set_customcss($css, $customcss);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These two routines are nearly identical to the routine above. For both the regionwidth and the customcss we make sure it has a value and then store it in a variable. We then call the relevant function to make the changes for that setting.&lt;br /&gt;
&lt;br /&gt;
Now that we have the general processing function it is time to write the three functions we have used but not written, &#039;&#039;demystified_set_backgroundcolor&#039;&#039;, &#039;&#039;demystified_set_regionwidth&#039;&#039;, &#039;&#039;demystified_set_customcss&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_set_backgroundcolor====&lt;br /&gt;
&lt;br /&gt;
First up demystified_set_backgroundcolor.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Sets the background colour variable in CSS&lt;br /&gt;
 *&lt;br /&gt;
 * @param string $css&lt;br /&gt;
 * @param mixed $backgroundcolor&lt;br /&gt;
 * @return string&lt;br /&gt;
 */&lt;br /&gt;
function demystified_set_backgroundcolor($css, $backgroundcolor) {&lt;br /&gt;
    $tag = &#039;[[setting:backgroundcolor]]&#039;;&lt;br /&gt;
    $replacement = $backgroundcolor;&lt;br /&gt;
    if (is_null($replacement)) {&lt;br /&gt;
        $replacement = &#039;#DDDDDD&#039;;&lt;br /&gt;
    }&lt;br /&gt;
    $css = str_replace($tag, $replacement, $css);&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ok so what is happening here?&lt;br /&gt;
&lt;br /&gt;
First we need a variable &#039;&#039;&#039;$tag&#039;&#039;&#039; that contains the tag we are going to replace. As mentioned earlier we are going to use tags that look like the image tags you are already familiar with &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:settingname]]&amp;lt;/nowiki&amp;gt;&#039;&#039;, in this case &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:backgroundcolor]]&amp;lt;/nowiki&amp;gt;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Next I am going to create a variable called &#039;&#039;&#039;$replacement&#039;&#039;&#039; into which I put &#039;&#039;&#039;$backgroundcolor&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;IF&#039;&#039;&#039; statement that comes next checks &#039;&#039;$replacement&#039;&#039; to make sure it is not null. If it is then we need to set it to a default value. In this case I have used &#039;&#039;#DDD&#039;&#039; as that was the default for the settings.&lt;br /&gt;
&lt;br /&gt;
The line after the IF statement puts it all together. The &#039;&#039;str_replace&#039;&#039; function that we are calling takes three arguments in this order:&lt;br /&gt;
# The text to search for.&lt;br /&gt;
# The text to replace it with.&lt;br /&gt;
# The text to do the replacement in.&lt;br /&gt;
It then returns the text with all of the replacements made. So in this case we are replacing the tag with the background colour and it is returning the changed CSS.&lt;br /&gt;
&lt;br /&gt;
The final thing is to return the &#039;&#039;$css&#039;&#039; variable which now contains the correct background colour.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_set_regionwidth====&lt;br /&gt;
&lt;br /&gt;
Next we have the demystified_set_regionwidth function.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Sets the region width variable in CSS&lt;br /&gt;
 *&lt;br /&gt;
 * @param string $css&lt;br /&gt;
 * @param mixed $regionwidth&lt;br /&gt;
 * @return string&lt;br /&gt;
 */&lt;br /&gt;
function demystified_set_regionwidth($css, $regionwidth) {&lt;br /&gt;
    $tag = &#039;[[setting:regionwidth]]&#039;;&lt;br /&gt;
    $doubletag = &#039;[[setting:regionwidthdouble]]&#039;;&lt;br /&gt;
    $replacement = $regionwidth;&lt;br /&gt;
    if (is_null($replacement)) {&lt;br /&gt;
        $replacement = 200;&lt;br /&gt;
    }&lt;br /&gt;
    $css = str_replace($tag, $replacement.&#039;px&#039;, $css);&lt;br /&gt;
    $css = str_replace($doubletag, ($replacement*2).&#039;px&#039;, $css);&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function is very similar to the above function however there is one key thing we are doing different. We are doing two replacements.&lt;br /&gt;
&lt;br /&gt;
# The first replacement is for the width that the user selected. In this case I am replacing the tag &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt;&#039;&#039; with the width.&lt;br /&gt;
# The second replacement is for the width x 2. This is because the page layout requires that the width be doubled for some of the CSS. Here I will replace &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidthdouble]]&amp;lt;/nowiki&amp;gt;&#039;&#039; with the doubled width.&lt;br /&gt;
&lt;br /&gt;
Remember because it is still just a number we need to add &#039;&#039;&#039;px&#039;&#039;&#039; to the end of each before we do the replacement.&lt;br /&gt;
&lt;br /&gt;
So the overall process of this function is:&lt;br /&gt;
# Define the two tags as &#039;&#039;&#039;$tag&#039;&#039;&#039; and &#039;&#039;&#039;$doubletag&#039;&#039;&#039;.&lt;br /&gt;
# Make &#039;&#039;&#039;$replacement&#039;&#039;&#039; the region width &#039;&#039;$regionwidth&#039;&#039;.&lt;br /&gt;
# Set &#039;&#039;$replacement&#039;&#039; to a default value of 200 is it is null.&lt;br /&gt;
# Replace &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; with the width.&lt;br /&gt;
# Replace &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidthdouble]]&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; with the width x 2.&lt;br /&gt;
# Return the changed CSS.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_set_customcss====&lt;br /&gt;
&lt;br /&gt;
The final function that we need to write is the demystified_set_customcss function.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Sets the custom css variable in CSS&lt;br /&gt;
 *&lt;br /&gt;
 * @param string $css&lt;br /&gt;
 * @param mixed $customcss&lt;br /&gt;
 * @return string&lt;br /&gt;
 */&lt;br /&gt;
function demystified_set_customcss($css, $customcss) {&lt;br /&gt;
    $tag = &#039;[[setting:customcss]]&#039;;&lt;br /&gt;
    $replacement = $customcss;&lt;br /&gt;
    if (is_null($replacement)) {&lt;br /&gt;
        $replacement = &#039;&#039;;&lt;br /&gt;
    }&lt;br /&gt;
    $css = str_replace($tag, $replacement, $css);&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function is just like the first function. I&#039;m going to let you work it out on your own.&lt;br /&gt;
&lt;br /&gt;
And that is it no more PHP... Hallelujah I can hear you yelling. The final thing we need to do is tell our theme about the functions we have written and put the settings tags into the CSS.&lt;br /&gt;
&lt;br /&gt;
===Finishing it all off===&lt;br /&gt;
&lt;br /&gt;
So there are two things we have to do in order to complete this section and have our the settings page implemented and our settings being used.&lt;br /&gt;
&lt;br /&gt;
First we need to tell our theme that we want to use the function &#039;&#039;demystified_process_css&#039;&#039; as the &#039;&#039;csspostprocess&#039;&#039; function. This is done very simply by adding the following line of PHP to the bottom of our theme&#039;s config.php file &#039;&#039;&#039;theme/demystified/config.php&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;csspostprocess = &#039;demystified_process_css&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done the only thing left is to add the settings tag into the CSS. Remember those settings tags are:&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:backgroundcolor]]&amp;lt;/nowiki&amp;gt; : We need to add this where ever we want the background colour setting to be used.&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt; : We need to add this where ever we want to set the width of the block regions.&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:regionwidthdouble]]&amp;lt;/nowiki&amp;gt; : We need to add this where ever we want to set the doubled width of the block regions.&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:customcss]]&amp;lt;/nowiki&amp;gt; : We need to add this to the bottom of the CSS file that we want the custom CSS added to.&lt;br /&gt;
&lt;br /&gt;
So lets make those changes in CSS now, open up your &#039;&#039;core.css&#039;&#039; file and replace the CSS with the CSS below:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/** Background color is a setting **/&lt;br /&gt;
html {background-color:[[setting:backgroundcolor]];}&lt;br /&gt;
body {margin:30px;padding:0;border:1px solid #333;border-width:0 10px 0 10px;background-color:#333;}&lt;br /&gt;
body #page {background-color:#FFF;position:relative;top:-10px;}&lt;br /&gt;
.block .header {background-image:none;background-color:#0C5CAC;border:1px solid #0C5CAC;color:#FFF;}&lt;br /&gt;
.block {border-color:#4BA7FF;background-color:#DDEEFF;}&lt;br /&gt;
.block .content {background-color:#F1F8FF;}&lt;br /&gt;
a:link,&lt;br /&gt;
a:visited {color:#0C5CAC;}&lt;br /&gt;
a:hover {color:#C77500;}&lt;br /&gt;
#page #page-header {background-color:#0C5CAC;margin:0;padding:0;width:100%;color:#fff;}&lt;br /&gt;
#page #page-header a:link, #page #page-header a:visited {color:#FFAC02}&lt;br /&gt;
#page #page-header .navbar, #page #page-header .navbar a:link, #page #page-header .navbar a:visited {color:#0C5CAC;}&lt;br /&gt;
/** Override the region width **/&lt;br /&gt;
#page-content #region-main-box {left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidthdouble]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-pre {width:[[setting:regionwidth]];left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-post {width:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidthdouble]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
/** Custom CSS **/&lt;br /&gt;
[[setting:customcss]]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will notice that &amp;lt;nowiki&amp;gt;[[setting:backgroundcolor]]&amp;lt;/nowiki&amp;gt; has been used for the html tags background colour:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
html {background-color:[[setting:backgroundcolor]];}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have also set the width of the block regions by adding &amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt; as the width for region-pre and region-post as shown below:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
#page-content #region-main-box {left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidthdouble]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-pre {width:[[setting:regionwidth]];left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-post {width:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidthdouble]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
You&#039;ll notice here that we have to set several different widths and margins using the regionwidth setting and make use of the special regionwidthdouble setting that we added.&lt;br /&gt;
&lt;br /&gt;
The final thing that we did was add the &amp;lt;nowiki&amp;gt;[[setting:customcss]]&amp;lt;/nowiki&amp;gt; to the bottom of the file to ensure that the custom CSS comes last (and therefore can override all other CSS).&lt;br /&gt;
&lt;br /&gt;
And with that we are finished. The screenshot below shows how this now looks in the browser if I set the background colour setting to &#039;&#039;&#039;&amp;lt;span style=&#039;color:#FFA800;&#039;&amp;gt;#FFA800&amp;lt;/span&amp;gt;&#039;&#039;&#039; and made the column width 240px;&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.04.png|715px|thumb|left|Our settings in action]]&amp;lt;br style=&amp;quot;clear:both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using the settings within our layout files==&lt;br /&gt;
Now that we have utilised the first three settings within our theme&#039;s CSS file it is time to implement the other two settings within the layout files so that they are written directly into the page.&lt;br /&gt;
&lt;br /&gt;
You&#039;ll be glad to know this is no where near as difficult as utilising settings within a CSS file although it still does require a little bit of PHP.&lt;br /&gt;
&lt;br /&gt;
First up is the logo setting. Into this setting the user is able to enter the URL to an image to use as the logo for the site. In my case I want this to be just a background logo on top of which I want to position the page header.&lt;br /&gt;
&lt;br /&gt;
Before I start there is one thing I need to do however and that is create a default logo background that gets shown if the user hasn&#039;t set a specific logo file. To do this I simply created an image &#039;&#039;&#039;logo.jpg&#039;&#039;&#039; and put it into a pix directory within the demystified theme. You should end up with &#039;&#039;&#039;theme/demystified/pix/logo.jpg&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Next open up the front-page layout file &#039;&#039;theme/demystified/layout/frontpage.php&#039;&#039;. At the top of the file is the PHP that checks what blocks regions the page has and a bit of other stuff. Well right below the existing bit of PHP we want to add the following code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;logo)) {&lt;br /&gt;
    $logourl = $PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;logo;&lt;br /&gt;
} else {&lt;br /&gt;
    $logourl = $OUTPUT-&amp;gt;pix_url(&#039;logo&#039;, &#039;theme&#039;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
What we are doing here is creating a variable called $logourl that will contain the URL to a logo file that was either entered by the user or if they left it blank is that of our default logo file.&lt;br /&gt;
&lt;br /&gt;
There are two things that you should notice about this. First the logo setting can be retrieved through &#039;&#039;&#039;$PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;logo&#039;&#039;&#039; and second we get the default logo url by calling &#039;&#039;&#039;$OUTPUT-&amp;gt;pix_url(&#039;logo&#039;, &#039;theme&#039;)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Now that we have the logo URL we are going to use we need to add an image to the header section of the page as shown below:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;page-header&amp;quot; class=&amp;quot;clearfix&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;img class=&amp;quot;sitelogo&amp;quot; src=&amp;quot;&amp;lt;?php echo $logourl;?&amp;gt;&amp;quot; alt=&amp;quot;Custom logo here&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;
....&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you save that and browse to your sites front page you will notice that the logo file is now being shown. Hooray. However it is probably not styled too nicely so lets quickly fix that. Open up the core.css file and add the following lines of CSS to the bottom of the file.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
#page-header {position:relative;min-height:100px;}&lt;br /&gt;
#page-header .sitelogo {float:left;}&lt;br /&gt;
#page-header .headermain {position:absolute;left:0.5em;top:50px;margin:0;float:none;font-size:40px;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
These three lines position the image correctly and if you now refresh everything should appear perfectly. &lt;br /&gt;
&lt;br /&gt;
With the logo done the last setting we need to deal with is the footnote setting. The idea with this setting was that the administrator could enter some text into the editor and it would be displayed in the footer of the page.&lt;br /&gt;
&lt;br /&gt;
This is probably the easiest setting to implement.&lt;br /&gt;
&lt;br /&gt;
Within the front page layout file that we edited above add the following lines below those we added previously.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;footnote)) {&lt;br /&gt;
    $footnote = $PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;footnote;&lt;br /&gt;
} else {&lt;br /&gt;
    $footnote = &#039;&amp;lt;!-- There was no custom footnote set --&amp;gt;&#039;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are just collecting the footnote into a variable &#039;&#039;&#039;$footnote&#039;&#039;&#039; and setting a default footnote comment if the user hasn&#039;t entered one.&lt;br /&gt;
&lt;br /&gt;
We can now echo the $footnote variable within the page footer. This can be done as shown below.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;!-- START OF FOOTER --&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;footnote&amp;quot;&amp;gt;&amp;lt;?php echo $footnote; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;p class=&amp;quot;helplink&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;?php echo page_doc_link(get_string(&#039;moodledocslink&#039;)) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And with that done we are finished! Congratulations if you got this far.&lt;br /&gt;
&lt;br /&gt;
The screenshot below shows the demystified theme we have just created that is styled by the settings page.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.05.png|715px|thumb|left|My finished demystified theme]]&amp;lt;br style=&amp;quot;clear:both&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing our creation==&lt;br /&gt;
Congratulations to you! If you&#039;ve made it this far you have done very well. Now it is time to have a look at what we have created and give it a quick test run.&lt;br /&gt;
&lt;br /&gt;
So in this tutorial we have achieved the following:&lt;br /&gt;
&lt;br /&gt;
* We created a theme called demystified that is based on the standard theme.&lt;br /&gt;
* We added a settings page to our new theme.&lt;br /&gt;
* We added the following settings to our settings page:&lt;br /&gt;
** We can set a background colour through the admin interface.&lt;br /&gt;
** We can change the logo of the site.&lt;br /&gt;
** We can change the block region width.&lt;br /&gt;
** We can add a footnote to the page footer&lt;br /&gt;
** We can add some custom CSS to seal the deal.&lt;br /&gt;
* Those settings were then used in the CSS files for our theme.&lt;br /&gt;
* They were also used in the layout files for our theme.&lt;br /&gt;
* And here we are testing it all.&lt;br /&gt;
&lt;br /&gt;
The screenshots below show my testing process and I change each setting and view the outcome. The great thing about this is that with theme designer mode on you see the changes as soon as the form refreshes.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.06.png|300px|thumb|left|Default settings]]&lt;br /&gt;
[[Image:Theme.settings.page.07.png|300px|thumb|left|Changed the background colour setting]]&lt;br /&gt;
[[Image:Theme.settings.page.08.png|300px|thumb|left|Changed the logo and region width]]&lt;br /&gt;
[[Image:Theme.settings.page.09.png|300px|thumb|left|Added a footnote]]&lt;br /&gt;
[[Image:Theme.settings.page.10.png|300px|thumb|left|Added some custom CSS]]&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:both&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The different settings you can use==&lt;br /&gt;
During this tutorial we use four different kinds of settings, a text box, text area, a select (dropdown) and the editor however as I&#039;m sure you have all guessed there is many more some of which will certainly be useful for theme settings.&lt;br /&gt;
&lt;br /&gt;
The following are examples of some of the different settings. I should add that these build upon what we have already done within the tutorial but are not included in the download.&lt;br /&gt;
&lt;br /&gt;
===Colour picker===&lt;br /&gt;
[[Image:Theme.settings.page.11.png|400px|thumb|The colour picker]]&lt;br /&gt;
I can hear you all asking now &#039;Why didn&#039;t you mention this one earlier?&#039; well the answer is simple it didn&#039;t exist when I first wrote the tutorial. It is an admin setting that I wrote several days after because of the fantastic effort people were putting into trying out settings pages.&lt;br /&gt;
&lt;br /&gt;
A bit about the colour picker. First up it is a text box that when the page loads turns into a colour picker that can be used to select a colour and can even preview the selected colour in the page (by clicking the preview button). It is designed to be very easy to use and the code is just about as simple as creating a normal text box setting.&lt;br /&gt;
&lt;br /&gt;
In the image to the left I have replaced the background colour setting we created during the tutorial with the colour picker. Lets have a look at the code involved for that.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Background colour setting&lt;br /&gt;
$name = &#039;theme_demystified/backgroundcolor&#039;;&lt;br /&gt;
$title = get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = &#039;#DDD&#039;;&lt;br /&gt;
$previewconfig = array(&#039;selector&#039;=&amp;gt;&#039;html&#039;, &#039;style&#039;=&amp;gt;&#039;backgroundColor&#039;);&lt;br /&gt;
$setting = new admin_setting_configcolourpicker($name, $title, $description, $default, $previewconfig);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
So first thing you should notice is that the first four lines of code have not changed at all!&lt;br /&gt;
&lt;br /&gt;
The first change we have is to create a variable &#039;&#039;&#039;$previewconfig&#039;&#039;&#039;. &lt;br /&gt;
This variable is used to tell the colour picker what to do when the user clicks the preview button. It should be an array that contains two things, first a selector, and second a style. &lt;br /&gt;
# The selector is a CSS selector like &#039;&#039;.page .header h2&#039;&#039;.&lt;br /&gt;
# The style is a what should change, there are two immediate values it can be, either &#039;&#039;&#039;backgroundColor&#039;&#039;&#039; or &#039;&#039;&#039;color&#039;&#039;&#039;.&lt;br /&gt;
In my case the selector is &#039;&#039;&#039;html&#039;&#039;&#039; to target the html tag and the style is backgroundColor to change the background colour.&lt;br /&gt;
&lt;br /&gt;
The second change is to use &#039;&#039;&#039;admin_setting_configcolourpicker&#039;&#039;&#039; instead of &#039;&#039;admin_setting_configtext&#039;&#039;. The arguments are nearly identical as well except that there is an extra argument to which we give the &#039;&#039;&#039;$previewconfig&#039;&#039;&#039; variable.&lt;br /&gt;
&lt;br /&gt;
And that is it! it is all you need to get the colour picker up and running.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Extra note:&#039;&#039;&#039; The $previewconfig variable is optional. If you don&#039;t want a preview button the simply set &#039;&#039;$previewconfig = null&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Common pitfalls and useful notes==&lt;br /&gt;
&lt;br /&gt;
This section is really just a collection of pointers, tips, notes, and other short useful stuff that may be of use to those attempting this tutorial.&lt;br /&gt;
&lt;br /&gt;
# First up and most importantly there are very few limitations to what you achieve in this fashion.&lt;br /&gt;
# If you get stuck or need a hand ask in the forums, there&#039;s always someone round who can help.&lt;br /&gt;
# If you do something really cool let us know, I know everyone in the community loves finding our what others are achieving.&lt;br /&gt;
# You don&#039;t have to use &#039;&#039;admin_settingpage&#039;&#039; you can also use &#039;&#039;&#039;admin_externalpage&#039;&#039;&#039; if you prefer. It should be noted however that it is not the preferred way to do it as admin_externalpage&#039;s were only left in Moodle 2.0 for backwards compatibility (although they are more flexible one day they will be deprecated or removed). Thank you to Darryl for raising this.&lt;br /&gt;
# If you find that your language strings aren&#039;t being used (you are getting language string notices) and you have double checked that you have turned &#039;&#039;&#039;langstringcache&#039;&#039;&#039; off then you may need to delete the language cache directory. This is located in the moodledata directory for you installation: moodledata/cache/lang/*. You should delete the directory for your chosen language by default &#039;&#039;en&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Adding theme upgrade code]]&lt;br /&gt;
* [[Styling and customising the dock]]&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/discuss.php?d=152053 Theme 2.0: Adding a settings page to your theme] forum discussion&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Creating_a_theme_settings_page&amp;diff=46308</id>
		<title>Creating a theme settings page</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Creating_a_theme_settings_page&amp;diff=46308"/>
		<updated>2014-09-24T22:05:31Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Finishing settings.php */ -updating&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}This document looks at how to create a settings page for your Moodle 2.x.x theme and how to make use of those settings within the CSS and layout files for your theme.&lt;br /&gt;
&lt;br /&gt;
This is a pretty advanced topic and will require that you have at least an intermediate knowledge of PHP, CSS, and development in general.&lt;br /&gt;
&lt;br /&gt;
==Before we begin==&lt;br /&gt;
[[Image:Theme.settings.page.03.png|350px|thumb|Our end goal. The settings page.]]&lt;br /&gt;
[[Image:Theme.settings.page.10.png|350px|thumb|And what it can do.]]&lt;br /&gt;
There is a huge body of knowledge that we must cover in following through this document and as such I think the best way to write this is as a tutorial.&lt;br /&gt;
&lt;br /&gt;
My intentions for this tutorial are to replicate the standard theme but with a settings page that allows the administrator to set a background colour, set a logo to use with the page, and probably several other minor settings to change the way in which the theme is displayed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I will start this tutorial by creating a new theme which will be largely a copy/paste of the current standard theme. I expect that anyone working through this tutorial has previously read the tutorial I wrote on [[Themes 2.0 creating your first theme|creating your first theme]]. If you haven&#039;t go read it now because I&#039;m not going to go into much detail until we get to the actual process of customising the theme and introducing the settings page.&lt;br /&gt;
&lt;br /&gt;
So before we finally get this started please ensure you can check off everything on the following requirements list.&lt;br /&gt;
* Have a Moodle installation that has already been installed and configured and is ready to use.&lt;br /&gt;
* Have full read/write access to that installation.&lt;br /&gt;
* Be prepared to delete that installation at the end of this... we will destroy it!&lt;br /&gt;
* Have a development environment prepared and ready to use. This includes:&lt;br /&gt;
** Your favourite editor installed, running, and pointed at the themes directory of your installation.&lt;br /&gt;
** Your browser open and your site visible.&lt;br /&gt;
** A bottomless coffee pot... decaf won&#039;t help you with this one.&lt;br /&gt;
* Have set the following settings:&lt;br /&gt;
** &#039;&#039;&#039;themedesignermode&#039;&#039;&#039; if you don&#039;t know what this is please read the [[Themes 2.0 creating your first theme|creating your first theme]] tutorial.&lt;br /&gt;
** &#039;&#039;&#039;allowthemechangeonurl&#039;&#039;&#039; turn this on, it allows you to change themes on the URL and is very handy when developing themes. &#039;&#039;Site Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; Theme settings&#039;&#039;&lt;br /&gt;
** &#039;&#039;&#039;langstringcache&#039;&#039;&#039; if you don&#039;t turn this off you won&#039;t see your strings when they are added. &#039;&#039;Site Administration &amp;gt; Language &amp;gt; Language settings&#039;&#039;&lt;br /&gt;
* And finally an insane ambition to create a customisable theme.&lt;br /&gt;
&lt;br /&gt;
For those interested the theme that I create throughout this tutorial can be downloaded from the forum post in which I announce this document: http://moodle.org/mod/forum/discuss.php?d=152053&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:right;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Our goals for this tutorial==&lt;br /&gt;
The following is just a list goals that I hope to achieve during this tutorial. They are laid out here so that I can easily refer back to them and so that you can easily find them.&lt;br /&gt;
# Create a new theme called &#039;&#039;&#039;demystified&#039;&#039;&#039; based upon the standard theme within Moodle 2.0.&lt;br /&gt;
# Make some minor changes to that theme to allow us to more easily see what is going on.&lt;br /&gt;
# Create a settings page for the demystified theme.&lt;br /&gt;
# Add several settings to our settings page.&lt;br /&gt;
# Use some of those settings to alter our CSS.&lt;br /&gt;
# Use the rest of those settings within our layout file..&lt;br /&gt;
# Discuss the good, the bad, and limits of what we have just created.&lt;br /&gt;
&lt;br /&gt;
So I can see you are all very excited about this point and that you would love to know what settings we are going to create; So here they are:&lt;br /&gt;
&lt;br /&gt;
A setting to ...&lt;br /&gt;
* change the background colour (CSS).&lt;br /&gt;
* set the path to an image that we will use as a logo on all pages (Layout files).&lt;br /&gt;
* override the width of the block regions (CSS).&lt;br /&gt;
* allow a note to be added to the footer of all pages (Layout files).&lt;br /&gt;
* allow custom CSS to be written to do anything the user wants. (CSS)&lt;br /&gt;
&lt;br /&gt;
==Creating the demystified theme==&lt;br /&gt;
Before we start here I want to remind you that I am going to look at this only briefly as I am making the assumption that you have read the [[Themes 2.0 creating your first theme|creating your first theme]] tutorial.&lt;br /&gt;
&lt;br /&gt;
Well lets get into it....&lt;br /&gt;
&lt;br /&gt;
The first thing we need to do is create a directory for our theme which we will call demystified. &lt;br /&gt;
&lt;br /&gt;
So within your Moodle directory create the following folder &#039;&#039;&#039;moodle/theme/demystified&#039;&#039;&#039;. At the same time you can also create the following files and folders which we will get to soon.&lt;br /&gt;
* The file &#039;&#039;&#039;moodle/theme/demystified/config.php&#039;&#039;&#039; for our config information.&lt;br /&gt;
* The directory &#039;&#039;&#039;moodle/theme/demystified/layout&#039;&#039;&#039; for our layout files.&lt;br /&gt;
* The directory &#039;&#039;&#039;moodle/theme/demystified/style&#039;&#039;&#039; for our css files.&lt;br /&gt;
* The file &#039;&#039;&#039;moodle/theme/demystified/style/core.css&#039;&#039;&#039; which will contain our special CSS.&lt;br /&gt;
&lt;br /&gt;
Next we will copy the layout files from the base theme to our new theme demystified. We are basing the demystified theme on the standard theme however that doesn&#039;t use it&#039;s own layout files it uses the base theme&#039;s layout files so those are the ones we want. &lt;br /&gt;
&lt;br /&gt;
The reason that we are coping these layout files is that later on in this tutorial we will be modifying them to make use of our new settings... so copy all of the layout files from &#039;&#039;&#039;moodle/theme/base/layout&#039;&#039;&#039; to &#039;&#039;&#039;moodle/theme/demystified/layout&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
There should be three files that you just copied:&lt;br /&gt;
# embedded.php&lt;br /&gt;
# frontpage.php&lt;br /&gt;
# general.php&lt;br /&gt;
&lt;br /&gt;
Now we need to populate demystified/config.php with the settings for our new theme. They are as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;name = &#039;demystified&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Simply sets the name of our theme.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;,&#039;base&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This theme is extending both the standard theme and the base theme. Remember when extending a theme you also need to extend its parents or things might not work correctly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;core&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This tells our theme that we want to use the file &#039;&#039;&#039;demystified/style/core.css&#039;&#039;&#039; with this theme.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;height:300px;overflow-y:scroll;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Most backwards compatible layout without the blocks - this is the layout used by default&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&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;
    // 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;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;
    // Main course page&lt;br /&gt;
    &#039;course&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;coursecategory&#039; =&amp;gt; array(&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;
    // part of course, typical for modules - default page layout if $cm specified in require_login()&lt;br /&gt;
    &#039;incourse&#039; =&amp;gt; array(&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;
    // The site home page.&lt;br /&gt;
    &#039;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;frontpage.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;
    // Server administration scripts.&lt;br /&gt;
    &#039;admin&#039; =&amp;gt; array(&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;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // My dashboard page&lt;br /&gt;
    &#039;mydashboard&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // My public page&lt;br /&gt;
    &#039;mypublic&#039; =&amp;gt; array(&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;
    &#039;login&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    // Pages that appear in pop-up windows - no navigation, no blocks, no header.&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // No blocks and minimal footer - used for legacy frame layouts only!&lt;br /&gt;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible&lt;br /&gt;
    &#039;embedded&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Used during upgrade and install, and for the &#039;This site is undergoing maintenance&#039; message.&lt;br /&gt;
    // This must not have any blocks, and it is good idea if it does not have links to&lt;br /&gt;
    // other places - for example there should not be a home link in the footer...&lt;br /&gt;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Now that all looks very complicated however its really not too bad as it is just copied from the base theme&#039;s config.php file. We can do this because we copied the layout files from the base theme to begin with and for the time being there are no changes that we wish to make. Simply open up &#039;&#039;&#039;theme/base/config.php&#039;&#039;&#039; and copy the layouts from there.&lt;br /&gt;
&lt;br /&gt;
And that is it. The config.php file for our demystified theme is complete. The full source is shown below:&lt;br /&gt;
&amp;lt;div style=&amp;quot;height:300px;overflow-y:scroll;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
// This file is part of Moodle - http://moodle.org/&lt;br /&gt;
//&lt;br /&gt;
// Moodle is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// Moodle is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with Moodle.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * The demystified theme config file&lt;br /&gt;
 *&lt;br /&gt;
 * This theme was created to document the process of adding a settings page to a theme&lt;br /&gt;
 *&lt;br /&gt;
 * @copyright 2010 Sam Hemelryk&lt;br /&gt;
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
// The name of our theme&lt;br /&gt;
$THEME-&amp;gt;name = &#039;demystified&#039;;&lt;br /&gt;
&lt;br /&gt;
// The other themes this theme extends&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;,&#039;base&#039;);&lt;br /&gt;
&lt;br /&gt;
// The CSS files this theme uses (located in the style directory)&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;core&#039;);&lt;br /&gt;
&lt;br /&gt;
// The layout definitions for this theme&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Most backwards compatible layout without the blocks - this is the layout used by default&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&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;
    // 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;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;
    // Main course page&lt;br /&gt;
    &#039;course&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;coursecategory&#039; =&amp;gt; array(&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;
    // part of course, typical for modules - default page layout if $cm specified in require_login()&lt;br /&gt;
    &#039;incourse&#039; =&amp;gt; array(&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;
    // The site home page.&lt;br /&gt;
    &#039;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;frontpage.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;
    // Server administration scripts.&lt;br /&gt;
    &#039;admin&#039; =&amp;gt; array(&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;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // My dashboard page&lt;br /&gt;
    &#039;mydashboard&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // My public page&lt;br /&gt;
    &#039;mypublic&#039; =&amp;gt; array(&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;
    &#039;login&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    // Pages that appear in pop-up windows - no navigation, no blocks, no header.&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // No blocks and minimal footer - used for legacy frame layouts only!&lt;br /&gt;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible&lt;br /&gt;
    &#039;embedded&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Used during upgrade and install, and for the &#039;This site is undergoing maintenance&#039; message.&lt;br /&gt;
    // This must not have any blocks, and it is good idea if it does not have links to&lt;br /&gt;
    // other places - for example there should not be a home link in the footer...&lt;br /&gt;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The screenshot below shows both the directory structure we have now created and the theme presently.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.01.png]]&lt;br /&gt;
&lt;br /&gt;
To view the theme so far open you browser and enter the URL of your site followed by &#039;&#039;&#039;?theme=demystified&#039;&#039;&#039;. You should see the theme that we just created which will look exactly like the base standard theme.&lt;br /&gt;
&lt;br /&gt;
The final thing that we want to do is add a little bit of CSS to the demystified theme that will both visually set this theme apart from the standard theme and second build a the base which our settings can later extend.&lt;br /&gt;
&lt;br /&gt;
I added the following snippet of CSS to the file &#039;&#039;&#039;demystified/style/core.css&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
html {background-color:#DDD;}&lt;br /&gt;
body {margin:30px;padding:0;border:1px solid #333;border-width:0 10px 0 10px;background-color:#333;}&lt;br /&gt;
body #page {background-color:#FFF;position:relative;top:-10px;}&lt;br /&gt;
.block .header {background-image:none;background-color:#0C5CAC;border:1px solid #0C5CAC;color:#FFF;}&lt;br /&gt;
.block {border-color:#4BA7FF;background-color:#DDEEFF;}&lt;br /&gt;
.block .content {background-color:#F1F8FF;}&lt;br /&gt;
a:link,&lt;br /&gt;
a:visited {color:#0C5CAC;}&lt;br /&gt;
a:hover {color:#C77500;}&lt;br /&gt;
#page #page-header {background-color:#0C5CAC;margin:0;padding:0;width:100%;color:#fff;}&lt;br /&gt;
#page #page-header a:link, #page #page-header a:visited {color:#FFAC02}&lt;br /&gt;
#page #page-header .navbar, #page #page-header .navbar a:link, #page #page-header .navbar a:visited {color:#0C5CAC;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The CSS that we have just added to our theme sets a couple of colours on the front page. Presently this is the only CSS I will add, I know it isn&#039;t complete by any means but it achieves it&#039;s purpose as the screenshot below illustrates.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.02.png|715px|thumb|left|The newly styles demystified theme]]&amp;lt;br style=&amp;quot;clear:both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And with that I will move on to the real purpose of this tutorial, creating the settings page&lt;br /&gt;
&lt;br /&gt;
==Setting up the settings page==&lt;br /&gt;
With the demystified theme set up it is time to create the settings page. This is where the real PHP fun begins.&lt;br /&gt;
&lt;br /&gt;
For those of you who happen to be familiar with development of modules, blocks or other plugin types you have probably encountered settings pages before and this is not going to be any different.&lt;br /&gt;
&lt;br /&gt;
However for those who haven&#039;t which I imagine is most of you this is going to be quite a challenge. I will try to walk through this step by step however if at any point you get stuck don&#039;t hesitate to ask in the forums as I imagine you will get a speedy response.&lt;br /&gt;
&lt;br /&gt;
===How settings pages work in Moodle===&lt;br /&gt;
Settings pages can be used by nearly every plugin type, of which themes is of course one. The way in which it all works isn&#039;t too tricky to understand. &lt;br /&gt;
&lt;br /&gt;
All of the settings for Moodle can be configured through the administrator interfaces when logged in. I am sure that everyone here has seen those pages and has changed a setting or two before so you will all know what I am talking about. Well the settings page for a theme is no different. It will be shown in the administration pages tree under &#039;&#039;&#039;Appearance &amp;gt; Themes&#039;&#039;&#039; and all we have to do is tell Moodle what settings there are.&lt;br /&gt;
&lt;br /&gt;
This is done by creating a settings.php file within our theme into which we will add code that tells Moodle about the settings we want to add/use.&lt;br /&gt;
&lt;br /&gt;
When telling Moodle about each setting we are simply creating a new &#039;&#039;admin_setting&#039;&#039; instance of the type we want and the properties we want and then adding it to our settings page.&lt;br /&gt;
&lt;br /&gt;
There is really not much more too it at this level. Things can get very complex very fast so the best thing we can do now is start creating our settings.php file for the demystified theme and see where it leads us.&lt;br /&gt;
&lt;br /&gt;
===Creating the settings page===&lt;br /&gt;
So as mentioned before we need a settings.php file which we will create now. To begin with create the file &#039;&#039;&#039;theme/demystified/settings.php&#039;&#039;&#039; and open it in your favourite editor so its ready to go.&lt;br /&gt;
&lt;br /&gt;
Before we start adding code however lets just remember the settings that we want to create:&lt;br /&gt;
* change the background colour (CSS).&lt;br /&gt;
* set the path to an image that we will use as a logo on all pages (Layout files).&lt;br /&gt;
* override the width of the block regions (CSS).&lt;br /&gt;
* allow a note to be added to the footer of all pages (Layout files).&lt;br /&gt;
* allow custom CSS to be written to do anything the user wants. (CSS)&lt;br /&gt;
&lt;br /&gt;
Alright.&lt;br /&gt;
&lt;br /&gt;
Now thinking about this the first setting is as basic as it gets, all we need is a text box that the user can type a colour into.&lt;br /&gt;
&lt;br /&gt;
The second is to allow a logo to be used in the header of each page. What we want here is a path but should it be a physical path e.g. C:/path/to/image.png or should it be a web path e.g. &amp;lt;nowiki&amp;gt;http://mysite.com/path/to/image.png&amp;lt;/nowiki&amp;gt;?&lt;br /&gt;
For the purpose of this tutorial I am going to go with a web path because it is going to be easier to code and will hopefully be a little easier to understand to begin with.&lt;br /&gt;
&lt;br /&gt;
The third setting is a little more complex. For this I want a drop down box with some specific widths that the administrator can select.&lt;br /&gt;
&lt;br /&gt;
The forth and the fifth settings are both pretty straight forward, there we want a textarea into which the user can enter what ever they want and we will do something useful with it.&lt;br /&gt;
&lt;br /&gt;
Now that we have an understanding about the settings we wish to define pull up your editor and lets start coding....&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Settings for the demystified theme&lt;br /&gt;
 */&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die;&lt;br /&gt;
&lt;br /&gt;
if ($ADMIN-&amp;gt;fulltree) {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is the first bit of code we must enter, the first line is of course just the opening php tag, secondly we have a comment that describes this file, and then we get create a new &#039;&#039;&#039;admin_settingspage object&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This admin_settingspage object that we have just created is a representation of our settings page and is the what we add our new settings to. When creating it we give it two arguments, first the name of the page which is in this case &#039;&#039;&#039;theme_&#039;&#039;themename&#039;&#039;&#039;&#039;&#039; and the title for the page which we get with the get_string method.&lt;br /&gt;
&lt;br /&gt;
At the moment I&#039;m not going to worry about adding the string, we will get to that later once we have defined all of our settings.&lt;br /&gt;
&lt;br /&gt;
====Background colour====&lt;br /&gt;
&lt;br /&gt;
With the page now created lets add our first setting: Background colour.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Background colour setting&lt;br /&gt;
$name = &#039;theme_demystified/backgroundcolor&#039;;&lt;br /&gt;
$title = get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = &#039;#DDD&#039;;&lt;br /&gt;
$setting = new admin_setting_configtext($name, $title, $description, $default, PARAM_CLEAN, 12);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Thankfully this isn&#039;t as difficult as it initially looks.&lt;br /&gt;
&lt;br /&gt;
The first line of code is creating a variable for the name of the background colour setting. In this case it is &#039;&#039;&#039;theme_demystified/backgroundcolor&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
The name is very important, for the setting to be usable we have to follow a strict naming convention. &#039;&#039;&#039;theme_&#039;&#039;themename&#039;&#039;/&#039;&#039;settingname&#039;&#039;&#039;&#039;&#039; where &#039;&#039;&#039;&#039;&#039;themename&#039;&#039;&#039;&#039;&#039; is the name of the theme the setting belongs to and &#039;&#039;&#039;&#039;&#039;settingname&#039;&#039;&#039;&#039;&#039; is the name for the setting by which we will use it.&lt;br /&gt;
&lt;br /&gt;
The second line of code creates a variable that contains the title of the setting. This is what the user sees to the right of the setting on the settings page and should be a short description of the setting. Here we are again using the &#039;&#039;get_string&#039;&#039; method so we will need to remember to add that string later on.&lt;br /&gt;
&lt;br /&gt;
The third line of code sets the description. This should describe what the setting does or how it works and again we will use the get_string method.&lt;br /&gt;
&lt;br /&gt;
The fourth line creates a variable that will be used as the default value for the setting. Because this setting is a colour we want an HTML colour to be the default value.&lt;br /&gt;
&lt;br /&gt;
The fifth line is where we put it all together. Here we create a new &#039;&#039;&#039;admin_setting_configtext&#039;&#039;&#039; object. This object will represent the background colour setting.&lt;br /&gt;
&lt;br /&gt;
When we create it we need to give it 6 different things.&lt;br /&gt;
# The name of the setting. In this case we have a variable &#039;&#039;&#039;$name&#039;&#039;&#039;.&lt;br /&gt;
# The title for this setting. We used the variable &#039;&#039;&#039;$title&#039;&#039;&#039;.&lt;br /&gt;
# The description of the setting &#039;&#039;&#039;$description&#039;&#039;&#039;.&lt;br /&gt;
# The default value for the setting. &#039;&#039;&#039;$default&#039;&#039;&#039; is the variable this.&lt;br /&gt;
# The type of value we want the user to enter. For this we have used PARAM_CLEAN which tells Moodle to get rid of any nasties from what the user enters.&lt;br /&gt;
# The size of the field. In our case 12 characters will be plenty.&lt;br /&gt;
&lt;br /&gt;
The sixth and final line of code adds our newly created setting to the administration page we created earlier.&lt;br /&gt;
&lt;br /&gt;
That is it we have successfully created and added our first setting, however there are several more to settings to do, and there are a couple of important things that you need to be aware of before we move on.&lt;br /&gt;
&lt;br /&gt;
First: There are several different types of settings that you can create and add to a page, and each one may differ in what they need you to give them. In this case it was name, title, description, default, type, and size. However other settings will likely require different things. Smart editors like Netbeans or Eclipse can tell you what is required, otherwise you will need to research it.&lt;br /&gt;
&lt;br /&gt;
Second: Normally settings are declared on one line as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$setting-&amp;gt;add(new admin_setting_configtext(&#039;theme_demystified/backgroundcolor&#039;, get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;), get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;), &#039;#DDD&#039;, PARAM_CLEAN, 12));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
While this is structurally identical as all we have done is move everything onto one line and do away with the variables it is a little harder to read when you are learning all of this.&lt;br /&gt;
&lt;br /&gt;
====The logo file====&lt;br /&gt;
Time to create the second setting that will allow the user to enter a URL to an image they wish to use as the logo on their site.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Logo file setting&lt;br /&gt;
$name = &#039;theme_demystified/logo&#039;;&lt;br /&gt;
$title = get_string(&#039;logo&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;logodesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtext($name, $title, $description, &#039;&#039;, PARAM_URL);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The first thing that you will notice about this setting that it is very similar to the first setting, in fact all we have changed is the name, title, description, and default value. We have however changed the value type from PARAM_CLEAN to PARAM_URL, this makes sure the user enters a URL. You will also notice that for this one we don&#039;t set a size for the field as we have no idea how long the URL will be.&lt;br /&gt;
&lt;br /&gt;
====Block region width====&lt;br /&gt;
The third setting should allow the user to set a width for the block regions that will be used as columns.&lt;br /&gt;
&lt;br /&gt;
For this setting I want to do something a little different from the previous two, here I want to use a select box so that the user selects a width for the column from a list I provide.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Block region width&lt;br /&gt;
$name = &#039;theme_demystified/regionwidth&#039;;&lt;br /&gt;
$title = get_string(&#039;regionwidth&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;regionwidthdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = 200;&lt;br /&gt;
$choices = array(150=&amp;gt;&#039;150px&#039;, 170=&amp;gt;&#039;170px&#039;, 200=&amp;gt;&#039;200px&#039;, 240=&amp;gt;&#039;240px&#039;, 290=&amp;gt;&#039;290px&#039;, 350=&amp;gt;&#039;350px&#039;, 420=&amp;gt;&#039;420px&#039;);&lt;br /&gt;
$setting = new admin_setting_configselect($name, $title, $description, $default, $choices);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
So looking at the code: The first four lines you will recognise. $name, $title, $description, and $default are all being set.&lt;br /&gt;
&lt;br /&gt;
The fifth line of code however introduces something new. Of course in order to have a select box we have to have options, in this case we have an array of options stored in the variable $choices.&lt;br /&gt;
&lt;br /&gt;
The array of options is constructed of a collection of &#039;&#039;&#039;&#039;&#039;value&#039;&#039;&#039; =&amp;gt; &#039;&#039;&#039;label&#039;&#039;&#039;&#039;&#039; pairs. Notice how we don&#039;t add &#039;&#039;&#039;px&#039;&#039;&#039; to the value. This is is very intentional as later on I need to do a little bit of math with that value so we need it to be a number.&lt;br /&gt;
&lt;br /&gt;
The lines after should look familiar again, the only difference being that instead of a &#039;&#039;admin_setting_configtext&#039;&#039; setting we have created a &#039;&#039;admin_setting_configselect&#039;&#039; for which we must give the choices for the select box as the fifth argument.&lt;br /&gt;
&lt;br /&gt;
Woohoo, we&#039;ve just created our first select box setting.&lt;br /&gt;
&lt;br /&gt;
====Foot note====&lt;br /&gt;
Now to create the foot note setting. Here we want the user to be able to enter some arbitrary text that will be used in the footer of the page. For this I want the user to be able to enter some HTML so I will create an editor setting.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Foot note setting&lt;br /&gt;
$name = &#039;theme_demystified/footnote&#039;;&lt;br /&gt;
$title = get_string(&#039;footnote&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;footnotedesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_confightmleditor($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
How simple is that!&lt;br /&gt;
&lt;br /&gt;
It is just about identical to the first two settings except that for this we have created a &#039;&#039;admin_setting_confightmleditor&#039;&#039; setting rather than a text setting.&lt;br /&gt;
&lt;br /&gt;
Note: You can also set the columns and rows for the editor setting using the fifth and sixth arguments.&lt;br /&gt;
&lt;br /&gt;
====Custom CSS====&lt;br /&gt;
The final setting is to allow the user to add some custom CSS to the theme that will be used on every page. I want this to be a plain textarea into which the user can enter CSS.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Custom CSS file&lt;br /&gt;
$name = &#039;theme_demystified/customcss&#039;;&lt;br /&gt;
$title = get_string(&#039;customcss&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;customcssdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtextarea($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Just like the editor or text settings. It&#039;s getting very easy now!&lt;br /&gt;
&lt;br /&gt;
====Finishing settings.php====&lt;br /&gt;
With all of our settings defined and added to our page that we created right at the beginning it is time to finish it all off.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Add our page to the structure of the admin tree&lt;br /&gt;
$ADMIN-&amp;gt;add(&#039;themes&#039;, $temp);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The above line of code is the final line for the page. It is adding the page that we have created &#039;&#039;&#039;$temp&#039;&#039;&#039; to the admin tree structure. In this case it is adding it to the themes branch.&lt;br /&gt;
&lt;br /&gt;
The following is the completed source for our settings.php ..... for your copy/paste pleasure.&lt;br /&gt;
&amp;lt;div style=&#039;height:300px;overflow:auto;&#039;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * Settings for the demystified theme&lt;br /&gt;
 */&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die;&lt;br /&gt;
 &lt;br /&gt;
if ($ADMIN-&amp;gt;fulltree) {&lt;br /&gt;
&lt;br /&gt;
// Background colour setting&lt;br /&gt;
$name = &#039;theme_demystified/backgroundcolor&#039;;&lt;br /&gt;
$title = get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = &#039;#DDD&#039;;&lt;br /&gt;
$setting = new admin_setting_configtext($name, $title, $description, $default, PARAM_CLEAN, 12);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
// Logo file setting&lt;br /&gt;
$name = &#039;theme_demystified/logo&#039;;&lt;br /&gt;
$title = get_string(&#039;logo&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;logodesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtext($name, $title, $description, &#039;&#039;, PARAM_URL);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
// Block region width&lt;br /&gt;
$name = &#039;theme_demystified/regionwidth&#039;;&lt;br /&gt;
$title = get_string(&#039;regionwidth&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;regionwidthdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = 200;&lt;br /&gt;
$choices = array(150=&amp;gt;&#039;150px&#039;, 170=&amp;gt;&#039;170px&#039;, 200=&amp;gt;&#039;200px&#039;, 240=&amp;gt;&#039;240px&#039;, 290=&amp;gt;&#039;290px&#039;, 350=&amp;gt;&#039;350px&#039;, 420=&amp;gt;&#039;420px&#039;);&lt;br /&gt;
$setting = new admin_setting_configselect($name, $title, $description, $default, $choices);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
// Foot note setting&lt;br /&gt;
$name = &#039;theme_demystified/footnote&#039;;&lt;br /&gt;
$title = get_string(&#039;footnote&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;footnotedesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_confightmleditor($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
// Custom CSS file&lt;br /&gt;
$name = &#039;theme_demystified/customcss&#039;;&lt;br /&gt;
$title = get_string(&#039;customcss&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;customcssdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtextarea($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
// Add our page to the structure of the admin tree&lt;br /&gt;
$ADMIN-&amp;gt;add(&#039;themes&#039;, $temp);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Creating a language file and adding our strings===&lt;br /&gt;
As I&#039;m sure none of you have forgotten, throughout the creation of the our settings.php page, we used a lot of strings that I mentioned we would set later on. Well now is the time to set those strings.&lt;br /&gt;
&lt;br /&gt;
First up create the following directories and file for our language strings:&lt;br /&gt;
* Directory &#039;&#039;&#039;theme/demystified/lang&#039;&#039;&#039;&lt;br /&gt;
* Directory &#039;&#039;&#039;theme/demystified/lang/en&#039;&#039;&#039;&lt;br /&gt;
* File &#039;&#039;&#039;theme/demystified/lang/theme_demystified.php&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
What we have created here is the required structure for Moodle to start looking for language strings.&lt;br /&gt;
&lt;br /&gt;
First Moodle locates the lang directory, once found it looks within that directory for another directory that uses the character code for the language the user has selected, by default this is &#039;&#039;&#039;en&#039;&#039;&#039; for English. Once that is found it looks for the appropriate language file, in this case &#039;&#039;&#039;theme_demystified.php&#039;&#039;&#039; from which it will load all language strings for our theme.&lt;br /&gt;
&lt;br /&gt;
If English isn&#039;t your chosen language simply replace the &#039;&#039;en&#039;&#039; directory with one that uses your chosen languages character code (two letters).&lt;br /&gt;
&lt;br /&gt;
We can now add our language strings to &#039;&#039;&#039;theme/demystified/lang/theme_demystified.php&#039;&#039;&#039;. Copy and paste the following lines of PHP into this file.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This file contains the strings used by the demystified theme&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
$string[&#039;backgroundcolor&#039;] = &#039;Background colour&#039;;&lt;br /&gt;
$string[&#039;backgroundcolordesc&#039;] = &#039;This sets the background colour for the theme.&#039;;&lt;br /&gt;
$string[&#039;configtitle&#039;] = &#039;Demystified theme&#039;;&lt;br /&gt;
$string[&#039;customcss&#039;] = &#039;Custom CSS&#039;;&lt;br /&gt;
$string[&#039;customcssdesc&#039;] = &#039;Any CSS you enter here will be added to every page allowing your to easily customise this theme.&#039;;&lt;br /&gt;
$string[&#039;footnote&#039;] = &#039;Footnote&#039;;&lt;br /&gt;
$string[&#039;footnotedesc&#039;] = &#039;The content from this textarea will be displayed in the footer of every page.&#039;;&lt;br /&gt;
$string[&#039;logo&#039;] = &#039;Logo&#039;;&lt;br /&gt;
$string[&#039;logodesc&#039;] = &#039;Enter the URL to an image to use as the logo for this site. Should be http://www.yoursite.com/path/to/logo.png&#039;;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;Demystified&#039;;&lt;br /&gt;
$string[&#039;regionwidth&#039;] = &#039;Column width&#039;;&lt;br /&gt;
$string[&#039;regionwidthdesc&#039;] = &#039;This sets the width of the two block regions that form the left and right columns.&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above lines of code I have added an entry for each language string we used within &#039;&#039;settings.php&#039;&#039;. When adding language strings like this make sure you use single quotes and try to keep things alphabetical - it helps greatly when managing strings.&lt;br /&gt;
&lt;br /&gt;
Now when we view the settings page there will not be any errors or strings missing.&lt;br /&gt;
&lt;br /&gt;
===Having a look at what we have created===&lt;br /&gt;
Now that we have created our settings page (settings.php) and added all of the language strings it is time to have a look at things in your browser.&lt;br /&gt;
&lt;br /&gt;
Open your browser and enter the URL to your site. When you arrive at your site login as an administrator.&lt;br /&gt;
&lt;br /&gt;
If you are not redirected to view the new settings change your URL to &amp;lt;nowiki&amp;gt;http://www.yoursite.com/admin/&amp;lt;/nowiki&amp;gt; and your will see a screen to set the new theme settings we have just created. This lets us know that everything has worked correctly.&lt;br /&gt;
&lt;br /&gt;
At any point now you are able to log in as administrator and within the settings block browse to &#039;&#039;&#039;Site administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; Demystified theme&#039;&#039;&#039; to change those settings.&lt;br /&gt;
&lt;br /&gt;
The screenshot below shows you what you should see at this point:&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.03.png|715px|thumb|left|The settings page we just created]]&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using the settings in CSS==&lt;br /&gt;
With the settings page now created and operational it is time to make use of our new settings. The settings that we want to use within our CSS is as follows:&lt;br /&gt;
&lt;br /&gt;
; backgroundcolor : Will be used to set the background colour in CSS.&lt;br /&gt;
; regionwidth : Will be the width of the column for CSS.&lt;br /&gt;
; customcss : Will be some custom CSS to add to our stylesheet.&lt;br /&gt;
&lt;br /&gt;
At this point those names are the names we used for our setting with the slash and everything before it having been removed.&lt;br /&gt;
&lt;br /&gt;
Before we start tearing into some code it is important that we have a look at what we are going to do and how we are going to go about it.&lt;br /&gt;
&lt;br /&gt;
===How it all works within Moodle===&lt;br /&gt;
The first thing to understand is that while Moodle allows you to create a settings page and automates it inclusion and management right into the administration interfaces there is no smart equivalent for using the settings. This is simply because there is no way to predict how people will want to use the settings.&lt;br /&gt;
&lt;br /&gt;
However don&#039;t think of this as a disadvantage, in fact it is quite the contrary. Although we can&#039;t just &#039;&#039;use&#039;&#039; our settings we can take full control over how and where we use them. It means it will take a little more code but in the end that will work to our advantage as we can do anything we want.&lt;br /&gt;
&lt;br /&gt;
Moodle does help us out a little but not in an obvious way. The first thing that Moodle does is look for a config variable &#039;&#039;&#039;csspostprocess&#039;&#039;&#039; that should be the name of a function which we want called to make any changes to the CSS after it has been prepared.&lt;br /&gt;
&lt;br /&gt;
The second thing Moodle does is include a lib.php from the theme&#039;s directory if one exists (also for the themes the current theme extends.) which ensures that as long as we write our code within &#039;&#039;&#039;theme/demystified/lib.php&#039;&#039;&#039; it will be included and ready to be used.&lt;br /&gt;
&lt;br /&gt;
The third and final thing Moodle does that will help us out here is ensure that by the time any of code is ready to execute the settings have been prepared and are ready to be used within a theme config object which is passed into our &#039;&#039;csspostprocess&#039;&#039; function.&lt;br /&gt;
&lt;br /&gt;
===Our plan===&lt;br /&gt;
As you have already probably guessed we will need to create a function to make the changes to the CSS that we want. We will then set the theme config option &#039;&#039;&#039;$THEME-&amp;gt;csspostprocess&#039;&#039;&#039; to the name of our function.&lt;br /&gt;
&lt;br /&gt;
By doing this when Moodle builds the CSS file it will call our function afterwards with the CSS and the theme object that contains our setting.&lt;br /&gt;
&lt;br /&gt;
Now we know that we will use the &#039;&#039;csspostprocess&#039;&#039; function but how are we going to change the CSS, we could get the function to add CSS, or we could get the function to replace something within the CSS. My personal preference is to replace something within the CSS, just like what is happening with images. If you want to use an image within CSS you would write &amp;lt;nowiki&amp;gt;[[pix:theme|imagename]]&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For settings I am going to use &amp;lt;nowiki&amp;gt;[[setting:settingname]]&amp;lt;/nowiki&amp;gt;, this way it looks a bit like something you are already familiar with.&lt;br /&gt;
&lt;br /&gt;
What we need to decide upon next is the best way in which to replace our settings tag with the settings that the user has set.&lt;br /&gt;
&lt;br /&gt;
There are two immediate options available to us:&lt;br /&gt;
# Make the &#039;&#039;csspostprocess&#039;&#039; function do all the work.&lt;br /&gt;
# Make the &#039;&#039;csspostprocess&#039;&#039; function call a separate function for each setting.&lt;br /&gt;
Solution 1 might sound like the simplest however it is going to result in a &#039;&#039;&#039;VERY&#039;&#039;&#039; complex function. Remember the user might have left settings blank or entered something that wouldn&#039;t be valid so we would need to make the sure there is some validation and a good default.&lt;br /&gt;
Because of this I think that solution 2 is the better solution.&lt;br /&gt;
&lt;br /&gt;
So we are going to need a &#039;&#039;csspostprocess&#039;&#039; function and then a function for each of the three settings we have that will do the replacements.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// This is our css post process function&lt;br /&gt;
function demystified_process_css($css, $theme) {};&lt;br /&gt;
// This replaces [[setting:backgroundcolor]] with the background colour&lt;br /&gt;
function demystified_set_backgroundcolor($css, $backgroundcolor) {};&lt;br /&gt;
// This replaces [[setting:regionwidth]] with the correct region width&lt;br /&gt;
function demystified_set_regionwidth() {$css, $regionwidth};&lt;br /&gt;
// This replaces [[setting:customcss]] with the custom css&lt;br /&gt;
function demystified_set_customcss() {$css, $customcss};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you should note about the above functions is that they all start with the theme&#039;s name. This is required to ensure that the functions are named uniquely as it is VERY unlikely that someone has already created these functions.&lt;br /&gt;
&lt;br /&gt;
So with our plan set out lets start writing the code.&lt;br /&gt;
&lt;br /&gt;
===Writing the code===&lt;br /&gt;
The very first thing that we need to do is create a lib.php for our theme into which our css processing functions are going to go. So please at this point create &#039;&#039;&#039;theme/demystified/lib.php&#039;&#039;&#039; and open it in your editor ready to go.&lt;br /&gt;
&lt;br /&gt;
The first bit of code we have to write is the function that will be called by Moodle to do the processing &#039;&#039;&#039;demystified_process_css&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
Before we start out please remember that the wonderful thing about coding is that there is any number of solutions to a problem. The solutions that you are seeing here in this tutorial are solutions that I have come up with to meet fulfil the needs of the tutorial without being so complex that they are hard to understand. This probably isn&#039;t how I would go about it normally but this is a little easier to understand for those who aren&#039;t overly familiar with PHP and object orientation.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_process_css====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function demystified_process_css($css, $theme) {&lt;br /&gt;
&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;backgroundcolor)) {&lt;br /&gt;
        $backgroundcolor = $theme-&amp;gt;settings-&amp;gt;backgroundcolor;&lt;br /&gt;
    } else {&lt;br /&gt;
        $backgroundcolor = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_backgroundcolor($css, $backgroundcolor);&lt;br /&gt;
&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;regionwidth)) {&lt;br /&gt;
        $regionwidth = $theme-&amp;gt;settings-&amp;gt;regionwidth;&lt;br /&gt;
    } else {&lt;br /&gt;
        $regionwidth = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_regionwidth($css, $regionwidth);&lt;br /&gt;
&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;customcss)) {&lt;br /&gt;
        $customcss = $theme-&amp;gt;settings-&amp;gt;customcss;&lt;br /&gt;
    } else {&lt;br /&gt;
        $customcss = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_customcss($css, $customcss);&lt;br /&gt;
&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So lets look at the things that make up this function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function demystified_process_css($css, $theme) {&lt;br /&gt;
    //.....&lt;br /&gt;
    return $css&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This of course is the function declaration. &lt;br /&gt;
&lt;br /&gt;
The function gets given two variables, the first &#039;&#039;&#039;$css&#039;&#039;&#039; is a pile of CSS as one big string, and the second is the theme object &#039;&#039;&#039;$theme&#039;&#039;&#039; that contains all of the configuration, options, and settings for our theme.&lt;br /&gt;
&lt;br /&gt;
It then returns the &#039;&#039;$css&#039;&#039; variable, essentially returning the modified CSS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    //...&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;backgroundcolor)) {&lt;br /&gt;
        $backgroundcolor = $theme-&amp;gt;settings-&amp;gt;backgroundcolor;&lt;br /&gt;
    } else {&lt;br /&gt;
        $backgroundcolor = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_backgroundcolor($css, $backgroundcolor);&lt;br /&gt;
    //...&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are processing our first setting &#039;&#039;backgroundcolor&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
The first thing that we need to do is check whether it has been set and whether it has a value. If it has then we store that value in &#039;&#039;&#039;$backgroundcolor&#039;&#039;&#039;. It is doesn&#039;t have a value then we set &#039;&#039;$backgroundcolor&#039;&#039; to null. This ensures that &#039;&#039;$backgroundcolor&#039;&#039; is set because if it isn&#039;t then you are going to get a notice (if you have debugging on).&lt;br /&gt;
&lt;br /&gt;
The final line of this block calls the function &#039;&#039;&#039;demystified_set_backgroundcolor&#039;&#039;&#039;. We haven&#039;t written this function yet but we will shortly. When we call it we give it the &#039;&#039;$css&#039;&#039; variable that contains all of the CSS and we give it the background colour variable &#039;&#039;$backgroundcolor&#039;&#039;. Once this function is finished it returns the &#039;&#039;$css&#039;&#039; variable with all of the changes made much like how our css processing function works.&lt;br /&gt;
&lt;br /&gt;
What you should also note about this code is this:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$theme-&amp;gt;settings-&amp;gt;backgroundcolor&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
As mentioned earlier &#039;&#039;$theme&#039;&#039; is an object that contains all of the configuration and settings for our theme. The &#039;&#039;$theme&#039;&#039; object has a $settings property which contains all of the settings for our theme, and finally the settings property contains a variable backgroundcolor that is the value the user entered for that setting. That is how we get a settings value.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($theme-&amp;gt;settings-&amp;gt;regionwidth)) {&lt;br /&gt;
    $regionwidth = $theme-&amp;gt;settings-&amp;gt;regionwidth;&lt;br /&gt;
} else {&lt;br /&gt;
    $regionwidth = null;&lt;br /&gt;
}&lt;br /&gt;
$css = demystified_set_regionwidth($css, $regionwidth);&lt;br /&gt;
&lt;br /&gt;
if (!empty($theme-&amp;gt;settings-&amp;gt;customcss)) {&lt;br /&gt;
    $customcss = $theme-&amp;gt;settings-&amp;gt;customcss;&lt;br /&gt;
} else {&lt;br /&gt;
    $customcss = null;&lt;br /&gt;
}&lt;br /&gt;
$css = demystified_set_customcss($css, $customcss);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These two routines are nearly identical to the routine above. For both the regionwidth and the customcss we make sure it has a value and then store it in a variable. We then call the relevant function to make the changes for that setting.&lt;br /&gt;
&lt;br /&gt;
Now that we have the general processing function it is time to write the three functions we have used but not written, &#039;&#039;demystified_set_backgroundcolor&#039;&#039;, &#039;&#039;demystified_set_regionwidth&#039;&#039;, &#039;&#039;demystified_set_customcss&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_set_backgroundcolor====&lt;br /&gt;
&lt;br /&gt;
First up demystified_set_backgroundcolor.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Sets the background colour variable in CSS&lt;br /&gt;
 *&lt;br /&gt;
 * @param string $css&lt;br /&gt;
 * @param mixed $backgroundcolor&lt;br /&gt;
 * @return string&lt;br /&gt;
 */&lt;br /&gt;
function demystified_set_backgroundcolor($css, $backgroundcolor) {&lt;br /&gt;
    $tag = &#039;[[setting:backgroundcolor]]&#039;;&lt;br /&gt;
    $replacement = $backgroundcolor;&lt;br /&gt;
    if (is_null($replacement)) {&lt;br /&gt;
        $replacement = &#039;#DDDDDD&#039;;&lt;br /&gt;
    }&lt;br /&gt;
    $css = str_replace($tag, $replacement, $css);&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ok so what is happening here?&lt;br /&gt;
&lt;br /&gt;
First we need a variable &#039;&#039;&#039;$tag&#039;&#039;&#039; that contains the tag we are going to replace. As mentioned earlier we are going to use tags that look like the image tags you are already familiar with &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:settingname]]&amp;lt;/nowiki&amp;gt;&#039;&#039;, in this case &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:backgroundcolor]]&amp;lt;/nowiki&amp;gt;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Next I am going to create a variable called &#039;&#039;&#039;$replacement&#039;&#039;&#039; into which I put &#039;&#039;&#039;$backgroundcolor&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;IF&#039;&#039;&#039; statement that comes next checks &#039;&#039;$replacement&#039;&#039; to make sure it is not null. If it is then we need to set it to a default value. In this case I have used &#039;&#039;#DDD&#039;&#039; as that was the default for the settings.&lt;br /&gt;
&lt;br /&gt;
The line after the IF statement puts it all together. The &#039;&#039;str_replace&#039;&#039; function that we are calling takes three arguments in this order:&lt;br /&gt;
# The text to search for.&lt;br /&gt;
# The text to replace it with.&lt;br /&gt;
# The text to do the replacement in.&lt;br /&gt;
It then returns the text with all of the replacements made. So in this case we are replacing the tag with the background colour and it is returning the changed CSS.&lt;br /&gt;
&lt;br /&gt;
The final thing is to return the &#039;&#039;$css&#039;&#039; variable which now contains the correct background colour.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_set_regionwidth====&lt;br /&gt;
&lt;br /&gt;
Next we have the demystified_set_regionwidth function.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Sets the region width variable in CSS&lt;br /&gt;
 *&lt;br /&gt;
 * @param string $css&lt;br /&gt;
 * @param mixed $regionwidth&lt;br /&gt;
 * @return string&lt;br /&gt;
 */&lt;br /&gt;
function demystified_set_regionwidth($css, $regionwidth) {&lt;br /&gt;
    $tag = &#039;[[setting:regionwidth]]&#039;;&lt;br /&gt;
    $doubletag = &#039;[[setting:regionwidthdouble]]&#039;;&lt;br /&gt;
    $replacement = $regionwidth;&lt;br /&gt;
    if (is_null($replacement)) {&lt;br /&gt;
        $replacement = 200;&lt;br /&gt;
    }&lt;br /&gt;
    $css = str_replace($tag, $replacement.&#039;px&#039;, $css);&lt;br /&gt;
    $css = str_replace($doubletag, ($replacement*2).&#039;px&#039;, $css);&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function is very similar to the above function however there is one key thing we are doing different. We are doing two replacements.&lt;br /&gt;
&lt;br /&gt;
# The first replacement is for the width that the user selected. In this case I am replacing the tag &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt;&#039;&#039; with the width.&lt;br /&gt;
# The second replacement is for the width x 2. This is because the page layout requires that the width be doubled for some of the CSS. Here I will replace &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidthdouble]]&amp;lt;/nowiki&amp;gt;&#039;&#039; with the doubled width.&lt;br /&gt;
&lt;br /&gt;
Remember because it is still just a number we need to add &#039;&#039;&#039;px&#039;&#039;&#039; to the end of each before we do the replacement.&lt;br /&gt;
&lt;br /&gt;
So the overall process of this function is:&lt;br /&gt;
# Define the two tags as &#039;&#039;&#039;$tag&#039;&#039;&#039; and &#039;&#039;&#039;$doubletag&#039;&#039;&#039;.&lt;br /&gt;
# Make &#039;&#039;&#039;$replacement&#039;&#039;&#039; the region width &#039;&#039;$regionwidth&#039;&#039;.&lt;br /&gt;
# Set &#039;&#039;$replacement&#039;&#039; to a default value of 200 is it is null.&lt;br /&gt;
# Replace &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; with the width.&lt;br /&gt;
# Replace &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidthdouble]]&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; with the width x 2.&lt;br /&gt;
# Return the changed CSS.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_set_customcss====&lt;br /&gt;
&lt;br /&gt;
The final function that we need to write is the demystified_set_customcss function.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Sets the custom css variable in CSS&lt;br /&gt;
 *&lt;br /&gt;
 * @param string $css&lt;br /&gt;
 * @param mixed $customcss&lt;br /&gt;
 * @return string&lt;br /&gt;
 */&lt;br /&gt;
function demystified_set_customcss($css, $customcss) {&lt;br /&gt;
    $tag = &#039;[[setting:customcss]]&#039;;&lt;br /&gt;
    $replacement = $customcss;&lt;br /&gt;
    if (is_null($replacement)) {&lt;br /&gt;
        $replacement = &#039;&#039;;&lt;br /&gt;
    }&lt;br /&gt;
    $css = str_replace($tag, $replacement, $css);&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function is just like the first function. I&#039;m going to let you work it out on your own.&lt;br /&gt;
&lt;br /&gt;
And that is it no more PHP... Hallelujah I can hear you yelling. The final thing we need to do is tell our theme about the functions we have written and put the settings tags into the CSS.&lt;br /&gt;
&lt;br /&gt;
===Finishing it all off===&lt;br /&gt;
&lt;br /&gt;
So there are two things we have to do in order to complete this section and have our the settings page implemented and our settings being used.&lt;br /&gt;
&lt;br /&gt;
First we need to tell our theme that we want to use the function &#039;&#039;demystified_process_css&#039;&#039; as the &#039;&#039;csspostprocess&#039;&#039; function. This is done very simply by adding the following line of PHP to the bottom of our theme&#039;s config.php file &#039;&#039;&#039;theme/demystified/config.php&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;csspostprocess = &#039;demystified_process_css&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done the only thing left is to add the settings tag into the CSS. Remember those settings tags are:&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:backgroundcolor]]&amp;lt;/nowiki&amp;gt; : We need to add this where ever we want the background colour setting to be used.&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt; : We need to add this where ever we want to set the width of the block regions.&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:regionwidthdouble]]&amp;lt;/nowiki&amp;gt; : We need to add this where ever we want to set the doubled width of the block regions.&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:customcss]]&amp;lt;/nowiki&amp;gt; : We need to add this to the bottom of the CSS file that we want the custom CSS added to.&lt;br /&gt;
&lt;br /&gt;
So lets make those changes in CSS now, open up your &#039;&#039;core.css&#039;&#039; file and replace the CSS with the CSS below:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/** Background color is a setting **/&lt;br /&gt;
html {background-color:[[setting:backgroundcolor]];}&lt;br /&gt;
body {margin:30px;padding:0;border:1px solid #333;border-width:0 10px 0 10px;background-color:#333;}&lt;br /&gt;
body #page {background-color:#FFF;position:relative;top:-10px;}&lt;br /&gt;
.block .header {background-image:none;background-color:#0C5CAC;border:1px solid #0C5CAC;color:#FFF;}&lt;br /&gt;
.block {border-color:#4BA7FF;background-color:#DDEEFF;}&lt;br /&gt;
.block .content {background-color:#F1F8FF;}&lt;br /&gt;
a:link,&lt;br /&gt;
a:visited {color:#0C5CAC;}&lt;br /&gt;
a:hover {color:#C77500;}&lt;br /&gt;
#page #page-header {background-color:#0C5CAC;margin:0;padding:0;width:100%;color:#fff;}&lt;br /&gt;
#page #page-header a:link, #page #page-header a:visited {color:#FFAC02}&lt;br /&gt;
#page #page-header .navbar, #page #page-header .navbar a:link, #page #page-header .navbar a:visited {color:#0C5CAC;}&lt;br /&gt;
/** Override the region width **/&lt;br /&gt;
#page-content #region-main-box {left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidthdouble]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-pre {width:[[setting:regionwidth]];left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-post {width:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidthdouble]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
/** Custom CSS **/&lt;br /&gt;
[[setting:customcss]]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will notice that &amp;lt;nowiki&amp;gt;[[setting:backgroundcolor]]&amp;lt;/nowiki&amp;gt; has been used for the html tags background colour:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
html {background-color:[[setting:backgroundcolor]];}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have also set the width of the block regions by adding &amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt; as the width for region-pre and region-post as shown below:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
#page-content #region-main-box {left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidthdouble]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-pre {width:[[setting:regionwidth]];left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-post {width:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidthdouble]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
You&#039;ll notice here that we have to set several different widths and margins using the regionwidth setting and make use of the special regionwidthdouble setting that we added.&lt;br /&gt;
&lt;br /&gt;
The final thing that we did was add the &amp;lt;nowiki&amp;gt;[[setting:customcss]]&amp;lt;/nowiki&amp;gt; to the bottom of the file to ensure that the custom CSS comes last (and therefore can override all other CSS).&lt;br /&gt;
&lt;br /&gt;
And with that we are finished. The screenshot below shows how this now looks in the browser if I set the background colour setting to &#039;&#039;&#039;&amp;lt;span style=&#039;color:#FFA800;&#039;&amp;gt;#FFA800&amp;lt;/span&amp;gt;&#039;&#039;&#039; and made the column width 240px;&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.04.png|715px|thumb|left|Our settings in action]]&amp;lt;br style=&amp;quot;clear:both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using the settings within our layout files==&lt;br /&gt;
Now that we have utilised the first three settings within our theme&#039;s CSS file it is time to implement the other two settings within the layout files so that they are written directly into the page.&lt;br /&gt;
&lt;br /&gt;
You&#039;ll be glad to know this is no where near as difficult as utilising settings within a CSS file although it still does require a little bit of PHP.&lt;br /&gt;
&lt;br /&gt;
First up is the logo setting. Into this setting the user is able to enter the URL to an image to use as the logo for the site. In my case I want this to be just a background logo on top of which I want to position the page header.&lt;br /&gt;
&lt;br /&gt;
Before I start there is one thing I need to do however and that is create a default logo background that gets shown if the user hasn&#039;t set a specific logo file. To do this I simply created an image &#039;&#039;&#039;logo.jpg&#039;&#039;&#039; and put it into a pix directory within the demystified theme. You should end up with &#039;&#039;&#039;theme/demystified/pix/logo.jpg&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Next open up the front-page layout file &#039;&#039;theme/demystified/layout/frontpage.php&#039;&#039;. At the top of the file is the PHP that checks what blocks regions the page has and a bit of other stuff. Well right below the existing bit of PHP we want to add the following code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;logo)) {&lt;br /&gt;
    $logourl = $PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;logo;&lt;br /&gt;
} else {&lt;br /&gt;
    $logourl = $OUTPUT-&amp;gt;pix_url(&#039;logo&#039;, &#039;theme&#039;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
What we are doing here is creating a variable called $logourl that will contain the URL to a logo file that was either entered by the user or if they left it blank is that of our default logo file.&lt;br /&gt;
&lt;br /&gt;
There are two things that you should notice about this. First the logo setting can be retrieved through &#039;&#039;&#039;$PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;logo&#039;&#039;&#039; and second we get the default logo url by calling &#039;&#039;&#039;$OUTPUT-&amp;gt;pix_url(&#039;logo&#039;, &#039;theme&#039;)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Now that we have the logo URL we are going to use we need to add an image to the header section of the page as shown below:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;page-header&amp;quot; class=&amp;quot;clearfix&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;img class=&amp;quot;sitelogo&amp;quot; src=&amp;quot;&amp;lt;?php echo $logourl;?&amp;gt;&amp;quot; alt=&amp;quot;Custom logo here&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;
....&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you save that and browse to your sites front page you will notice that the logo file is now being shown. Hooray. However it is probably not styled too nicely so lets quickly fix that. Open up the core.css file and add the following lines of CSS to the bottom of the file.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
#page-header {position:relative;min-height:100px;}&lt;br /&gt;
#page-header .sitelogo {float:left;}&lt;br /&gt;
#page-header .headermain {position:absolute;left:0.5em;top:50px;margin:0;float:none;font-size:40px;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
These three lines position the image correctly and if you now refresh everything should appear perfectly. &lt;br /&gt;
&lt;br /&gt;
With the logo done the last setting we need to deal with is the footnote setting. The idea with this setting was that the administrator could enter some text into the editor and it would be displayed in the footer of the page.&lt;br /&gt;
&lt;br /&gt;
This is probably the easiest setting to implement.&lt;br /&gt;
&lt;br /&gt;
Within the front page layout file that we edited above add the following lines below those we added previously.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;footnote)) {&lt;br /&gt;
    $footnote = $PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;footnote;&lt;br /&gt;
} else {&lt;br /&gt;
    $footnote = &#039;&amp;lt;!-- There was no custom footnote set --&amp;gt;&#039;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are just collecting the footnote into a variable &#039;&#039;&#039;$footnote&#039;&#039;&#039; and setting a default footnote comment if the user hasn&#039;t entered one.&lt;br /&gt;
&lt;br /&gt;
We can now echo the $footnote variable within the page footer. This can be done as shown below.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;!-- START OF FOOTER --&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;footnote&amp;quot;&amp;gt;&amp;lt;?php echo $footnote; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;p class=&amp;quot;helplink&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;?php echo page_doc_link(get_string(&#039;moodledocslink&#039;)) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And with that done we are finished! Congratulations if you got this far.&lt;br /&gt;
&lt;br /&gt;
The screenshot below shows the demystified theme we have just created that is styled by the settings page.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.05.png|715px|thumb|left|My finished demystified theme]]&amp;lt;br style=&amp;quot;clear:both&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing our creation==&lt;br /&gt;
Congratulations to you! If you&#039;ve made it this far you have done very well. Now it is time to have a look at what we have created and give it a quick test run.&lt;br /&gt;
&lt;br /&gt;
So in this tutorial we have achieved the following:&lt;br /&gt;
&lt;br /&gt;
* We created a theme called demystified that is based on the standard theme.&lt;br /&gt;
* We added a settings page to our new theme.&lt;br /&gt;
* We added the following settings to our settings page:&lt;br /&gt;
** We can set a background colour through the admin interface.&lt;br /&gt;
** We can change the logo of the site.&lt;br /&gt;
** We can change the block region width.&lt;br /&gt;
** We can add a footnote to the page footer&lt;br /&gt;
** We can add some custom CSS to seal the deal.&lt;br /&gt;
* Those settings were then used in the CSS files for our theme.&lt;br /&gt;
* They were also used in the layout files for our theme.&lt;br /&gt;
* And here we are testing it all.&lt;br /&gt;
&lt;br /&gt;
The screenshots below show my testing process and I change each setting and view the outcome. The great thing about this is that with theme designer mode on you see the changes as soon as the form refreshes.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.06.png|300px|thumb|left|Default settings]]&lt;br /&gt;
[[Image:Theme.settings.page.07.png|300px|thumb|left|Changed the background colour setting]]&lt;br /&gt;
[[Image:Theme.settings.page.08.png|300px|thumb|left|Changed the logo and region width]]&lt;br /&gt;
[[Image:Theme.settings.page.09.png|300px|thumb|left|Added a footnote]]&lt;br /&gt;
[[Image:Theme.settings.page.10.png|300px|thumb|left|Added some custom CSS]]&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:both&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The different settings you can use==&lt;br /&gt;
During this tutorial we use four different kinds of settings, a text box, text area, a select (dropdown) and the editor however as I&#039;m sure you have all guessed there is many more some of which will certainly be useful for theme settings.&lt;br /&gt;
&lt;br /&gt;
The following are examples of some of the different settings. I should add that these build upon what we have already done within the tutorial but are not included in the download.&lt;br /&gt;
&lt;br /&gt;
===Colour picker===&lt;br /&gt;
[[Image:Theme.settings.page.11.png|400px|thumb|The colour picker]]&lt;br /&gt;
I can hear you all asking now &#039;Why didn&#039;t you mention this one earlier?&#039; well the answer is simple it didn&#039;t exist when I first wrote the tutorial. It is an admin setting that I wrote several days after because of the fantastic effort people were putting into trying out settings pages.&lt;br /&gt;
&lt;br /&gt;
A bit about the colour picker. First up it is a text box that when the page loads turns into a colour picker that can be used to select a colour and can even preview the selected colour in the page (by clicking the preview button). It is designed to be very easy to use and the code is just about as simple as creating a normal text box setting.&lt;br /&gt;
&lt;br /&gt;
In the image to the left I have replaced the background colour setting we created during the tutorial with the colour picker. Lets have a look at the code involved for that.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Background colour setting&lt;br /&gt;
$name = &#039;theme_demystified/backgroundcolor&#039;;&lt;br /&gt;
$title = get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = &#039;#DDD&#039;;&lt;br /&gt;
$previewconfig = array(&#039;selector&#039;=&amp;gt;&#039;html&#039;, &#039;style&#039;=&amp;gt;&#039;backgroundColor&#039;);&lt;br /&gt;
$setting = new admin_setting_configcolourpicker($name, $title, $description, $default, $previewconfig);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
So first thing you should notice is that the first four lines of code have not changed at all!&lt;br /&gt;
&lt;br /&gt;
The first change we have is to create a variable &#039;&#039;&#039;$previewconfig&#039;&#039;&#039;. &lt;br /&gt;
This variable is used to tell the colour picker what to do when the user clicks the preview button. It should be an array that contains two things, first a selector, and second a style. &lt;br /&gt;
# The selector is a CSS selector like &#039;&#039;.page .header h2&#039;&#039;.&lt;br /&gt;
# The style is a what should change, there are two immediate values it can be, either &#039;&#039;&#039;backgroundColor&#039;&#039;&#039; or &#039;&#039;&#039;color&#039;&#039;&#039;.&lt;br /&gt;
In my case the selector is &#039;&#039;&#039;html&#039;&#039;&#039; to target the html tag and the style is backgroundColor to change the background colour.&lt;br /&gt;
&lt;br /&gt;
The second change is to use &#039;&#039;&#039;admin_setting_configcolourpicker&#039;&#039;&#039; instead of &#039;&#039;admin_setting_configtext&#039;&#039;. The arguments are nearly identical as well except that there is an extra argument to which we give the &#039;&#039;&#039;$previewconfig&#039;&#039;&#039; variable.&lt;br /&gt;
&lt;br /&gt;
And that is it! it is all you need to get the colour picker up and running.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Extra note:&#039;&#039;&#039; The $previewconfig variable is optional. If you don&#039;t want a preview button the simply set &#039;&#039;$previewconfig = null&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Common pitfalls and useful notes==&lt;br /&gt;
&lt;br /&gt;
This section is really just a collection of pointers, tips, notes, and other short useful stuff that may be of use to those attempting this tutorial.&lt;br /&gt;
&lt;br /&gt;
# First up and most importantly there are very few limitations to what you achieve in this fashion.&lt;br /&gt;
# If you get stuck or need a hand ask in the forums, there&#039;s always someone round who can help.&lt;br /&gt;
# If you do something really cool let us know, I know everyone in the community loves finding our what others are achieving.&lt;br /&gt;
# You don&#039;t have to use &#039;&#039;admin_settingpage&#039;&#039; you can also use &#039;&#039;&#039;admin_externalpage&#039;&#039;&#039; if you prefer. It should be noted however that it is not the preferred way to do it as admin_externalpage&#039;s were only left in Moodle 2.0 for backwards compatibility (although they are more flexible one day they will be deprecated or removed). Thank you to Darryl for raising this.&lt;br /&gt;
# If you find that your language strings aren&#039;t being used (you are getting language string notices) and you have double checked that you have turned &#039;&#039;&#039;langstringcache&#039;&#039;&#039; off then you may need to delete the language cache directory. This is located in the moodledata directory for you installation: moodledata/cache/lang/*. You should delete the directory for your chosen language by default &#039;&#039;en&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Adding theme upgrade code]]&lt;br /&gt;
* [[Styling and customising the dock]]&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/discuss.php?d=152053 Theme 2.0: Adding a settings page to your theme] forum discussion&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Creating_a_theme_settings_page&amp;diff=46307</id>
		<title>Creating a theme settings page</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Creating_a_theme_settings_page&amp;diff=46307"/>
		<updated>2014-09-24T21:59:49Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Custom CSS */ - updating&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}This document looks at how to create a settings page for your Moodle 2.x.x theme and how to make use of those settings within the CSS and layout files for your theme.&lt;br /&gt;
&lt;br /&gt;
This is a pretty advanced topic and will require that you have at least an intermediate knowledge of PHP, CSS, and development in general.&lt;br /&gt;
&lt;br /&gt;
==Before we begin==&lt;br /&gt;
[[Image:Theme.settings.page.03.png|350px|thumb|Our end goal. The settings page.]]&lt;br /&gt;
[[Image:Theme.settings.page.10.png|350px|thumb|And what it can do.]]&lt;br /&gt;
There is a huge body of knowledge that we must cover in following through this document and as such I think the best way to write this is as a tutorial.&lt;br /&gt;
&lt;br /&gt;
My intentions for this tutorial are to replicate the standard theme but with a settings page that allows the administrator to set a background colour, set a logo to use with the page, and probably several other minor settings to change the way in which the theme is displayed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I will start this tutorial by creating a new theme which will be largely a copy/paste of the current standard theme. I expect that anyone working through this tutorial has previously read the tutorial I wrote on [[Themes 2.0 creating your first theme|creating your first theme]]. If you haven&#039;t go read it now because I&#039;m not going to go into much detail until we get to the actual process of customising the theme and introducing the settings page.&lt;br /&gt;
&lt;br /&gt;
So before we finally get this started please ensure you can check off everything on the following requirements list.&lt;br /&gt;
* Have a Moodle installation that has already been installed and configured and is ready to use.&lt;br /&gt;
* Have full read/write access to that installation.&lt;br /&gt;
* Be prepared to delete that installation at the end of this... we will destroy it!&lt;br /&gt;
* Have a development environment prepared and ready to use. This includes:&lt;br /&gt;
** Your favourite editor installed, running, and pointed at the themes directory of your installation.&lt;br /&gt;
** Your browser open and your site visible.&lt;br /&gt;
** A bottomless coffee pot... decaf won&#039;t help you with this one.&lt;br /&gt;
* Have set the following settings:&lt;br /&gt;
** &#039;&#039;&#039;themedesignermode&#039;&#039;&#039; if you don&#039;t know what this is please read the [[Themes 2.0 creating your first theme|creating your first theme]] tutorial.&lt;br /&gt;
** &#039;&#039;&#039;allowthemechangeonurl&#039;&#039;&#039; turn this on, it allows you to change themes on the URL and is very handy when developing themes. &#039;&#039;Site Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; Theme settings&#039;&#039;&lt;br /&gt;
** &#039;&#039;&#039;langstringcache&#039;&#039;&#039; if you don&#039;t turn this off you won&#039;t see your strings when they are added. &#039;&#039;Site Administration &amp;gt; Language &amp;gt; Language settings&#039;&#039;&lt;br /&gt;
* And finally an insane ambition to create a customisable theme.&lt;br /&gt;
&lt;br /&gt;
For those interested the theme that I create throughout this tutorial can be downloaded from the forum post in which I announce this document: http://moodle.org/mod/forum/discuss.php?d=152053&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:right;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Our goals for this tutorial==&lt;br /&gt;
The following is just a list goals that I hope to achieve during this tutorial. They are laid out here so that I can easily refer back to them and so that you can easily find them.&lt;br /&gt;
# Create a new theme called &#039;&#039;&#039;demystified&#039;&#039;&#039; based upon the standard theme within Moodle 2.0.&lt;br /&gt;
# Make some minor changes to that theme to allow us to more easily see what is going on.&lt;br /&gt;
# Create a settings page for the demystified theme.&lt;br /&gt;
# Add several settings to our settings page.&lt;br /&gt;
# Use some of those settings to alter our CSS.&lt;br /&gt;
# Use the rest of those settings within our layout file..&lt;br /&gt;
# Discuss the good, the bad, and limits of what we have just created.&lt;br /&gt;
&lt;br /&gt;
So I can see you are all very excited about this point and that you would love to know what settings we are going to create; So here they are:&lt;br /&gt;
&lt;br /&gt;
A setting to ...&lt;br /&gt;
* change the background colour (CSS).&lt;br /&gt;
* set the path to an image that we will use as a logo on all pages (Layout files).&lt;br /&gt;
* override the width of the block regions (CSS).&lt;br /&gt;
* allow a note to be added to the footer of all pages (Layout files).&lt;br /&gt;
* allow custom CSS to be written to do anything the user wants. (CSS)&lt;br /&gt;
&lt;br /&gt;
==Creating the demystified theme==&lt;br /&gt;
Before we start here I want to remind you that I am going to look at this only briefly as I am making the assumption that you have read the [[Themes 2.0 creating your first theme|creating your first theme]] tutorial.&lt;br /&gt;
&lt;br /&gt;
Well lets get into it....&lt;br /&gt;
&lt;br /&gt;
The first thing we need to do is create a directory for our theme which we will call demystified. &lt;br /&gt;
&lt;br /&gt;
So within your Moodle directory create the following folder &#039;&#039;&#039;moodle/theme/demystified&#039;&#039;&#039;. At the same time you can also create the following files and folders which we will get to soon.&lt;br /&gt;
* The file &#039;&#039;&#039;moodle/theme/demystified/config.php&#039;&#039;&#039; for our config information.&lt;br /&gt;
* The directory &#039;&#039;&#039;moodle/theme/demystified/layout&#039;&#039;&#039; for our layout files.&lt;br /&gt;
* The directory &#039;&#039;&#039;moodle/theme/demystified/style&#039;&#039;&#039; for our css files.&lt;br /&gt;
* The file &#039;&#039;&#039;moodle/theme/demystified/style/core.css&#039;&#039;&#039; which will contain our special CSS.&lt;br /&gt;
&lt;br /&gt;
Next we will copy the layout files from the base theme to our new theme demystified. We are basing the demystified theme on the standard theme however that doesn&#039;t use it&#039;s own layout files it uses the base theme&#039;s layout files so those are the ones we want. &lt;br /&gt;
&lt;br /&gt;
The reason that we are coping these layout files is that later on in this tutorial we will be modifying them to make use of our new settings... so copy all of the layout files from &#039;&#039;&#039;moodle/theme/base/layout&#039;&#039;&#039; to &#039;&#039;&#039;moodle/theme/demystified/layout&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
There should be three files that you just copied:&lt;br /&gt;
# embedded.php&lt;br /&gt;
# frontpage.php&lt;br /&gt;
# general.php&lt;br /&gt;
&lt;br /&gt;
Now we need to populate demystified/config.php with the settings for our new theme. They are as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;name = &#039;demystified&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Simply sets the name of our theme.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;,&#039;base&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This theme is extending both the standard theme and the base theme. Remember when extending a theme you also need to extend its parents or things might not work correctly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;core&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This tells our theme that we want to use the file &#039;&#039;&#039;demystified/style/core.css&#039;&#039;&#039; with this theme.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;height:300px;overflow-y:scroll;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Most backwards compatible layout without the blocks - this is the layout used by default&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&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;
    // 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;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;
    // Main course page&lt;br /&gt;
    &#039;course&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;coursecategory&#039; =&amp;gt; array(&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;
    // part of course, typical for modules - default page layout if $cm specified in require_login()&lt;br /&gt;
    &#039;incourse&#039; =&amp;gt; array(&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;
    // The site home page.&lt;br /&gt;
    &#039;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;frontpage.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;
    // Server administration scripts.&lt;br /&gt;
    &#039;admin&#039; =&amp;gt; array(&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;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // My dashboard page&lt;br /&gt;
    &#039;mydashboard&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // My public page&lt;br /&gt;
    &#039;mypublic&#039; =&amp;gt; array(&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;
    &#039;login&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    // Pages that appear in pop-up windows - no navigation, no blocks, no header.&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // No blocks and minimal footer - used for legacy frame layouts only!&lt;br /&gt;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible&lt;br /&gt;
    &#039;embedded&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Used during upgrade and install, and for the &#039;This site is undergoing maintenance&#039; message.&lt;br /&gt;
    // This must not have any blocks, and it is good idea if it does not have links to&lt;br /&gt;
    // other places - for example there should not be a home link in the footer...&lt;br /&gt;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Now that all looks very complicated however its really not too bad as it is just copied from the base theme&#039;s config.php file. We can do this because we copied the layout files from the base theme to begin with and for the time being there are no changes that we wish to make. Simply open up &#039;&#039;&#039;theme/base/config.php&#039;&#039;&#039; and copy the layouts from there.&lt;br /&gt;
&lt;br /&gt;
And that is it. The config.php file for our demystified theme is complete. The full source is shown below:&lt;br /&gt;
&amp;lt;div style=&amp;quot;height:300px;overflow-y:scroll;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
// This file is part of Moodle - http://moodle.org/&lt;br /&gt;
//&lt;br /&gt;
// Moodle is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// Moodle is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with Moodle.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * The demystified theme config file&lt;br /&gt;
 *&lt;br /&gt;
 * This theme was created to document the process of adding a settings page to a theme&lt;br /&gt;
 *&lt;br /&gt;
 * @copyright 2010 Sam Hemelryk&lt;br /&gt;
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
// The name of our theme&lt;br /&gt;
$THEME-&amp;gt;name = &#039;demystified&#039;;&lt;br /&gt;
&lt;br /&gt;
// The other themes this theme extends&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;,&#039;base&#039;);&lt;br /&gt;
&lt;br /&gt;
// The CSS files this theme uses (located in the style directory)&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;core&#039;);&lt;br /&gt;
&lt;br /&gt;
// The layout definitions for this theme&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Most backwards compatible layout without the blocks - this is the layout used by default&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&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;
    // 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;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;
    // Main course page&lt;br /&gt;
    &#039;course&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;coursecategory&#039; =&amp;gt; array(&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;
    // part of course, typical for modules - default page layout if $cm specified in require_login()&lt;br /&gt;
    &#039;incourse&#039; =&amp;gt; array(&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;
    // The site home page.&lt;br /&gt;
    &#039;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;frontpage.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;
    // Server administration scripts.&lt;br /&gt;
    &#039;admin&#039; =&amp;gt; array(&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;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // My dashboard page&lt;br /&gt;
    &#039;mydashboard&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // My public page&lt;br /&gt;
    &#039;mypublic&#039; =&amp;gt; array(&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;
    &#039;login&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    // Pages that appear in pop-up windows - no navigation, no blocks, no header.&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // No blocks and minimal footer - used for legacy frame layouts only!&lt;br /&gt;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible&lt;br /&gt;
    &#039;embedded&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Used during upgrade and install, and for the &#039;This site is undergoing maintenance&#039; message.&lt;br /&gt;
    // This must not have any blocks, and it is good idea if it does not have links to&lt;br /&gt;
    // other places - for example there should not be a home link in the footer...&lt;br /&gt;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The screenshot below shows both the directory structure we have now created and the theme presently.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.01.png]]&lt;br /&gt;
&lt;br /&gt;
To view the theme so far open you browser and enter the URL of your site followed by &#039;&#039;&#039;?theme=demystified&#039;&#039;&#039;. You should see the theme that we just created which will look exactly like the base standard theme.&lt;br /&gt;
&lt;br /&gt;
The final thing that we want to do is add a little bit of CSS to the demystified theme that will both visually set this theme apart from the standard theme and second build a the base which our settings can later extend.&lt;br /&gt;
&lt;br /&gt;
I added the following snippet of CSS to the file &#039;&#039;&#039;demystified/style/core.css&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
html {background-color:#DDD;}&lt;br /&gt;
body {margin:30px;padding:0;border:1px solid #333;border-width:0 10px 0 10px;background-color:#333;}&lt;br /&gt;
body #page {background-color:#FFF;position:relative;top:-10px;}&lt;br /&gt;
.block .header {background-image:none;background-color:#0C5CAC;border:1px solid #0C5CAC;color:#FFF;}&lt;br /&gt;
.block {border-color:#4BA7FF;background-color:#DDEEFF;}&lt;br /&gt;
.block .content {background-color:#F1F8FF;}&lt;br /&gt;
a:link,&lt;br /&gt;
a:visited {color:#0C5CAC;}&lt;br /&gt;
a:hover {color:#C77500;}&lt;br /&gt;
#page #page-header {background-color:#0C5CAC;margin:0;padding:0;width:100%;color:#fff;}&lt;br /&gt;
#page #page-header a:link, #page #page-header a:visited {color:#FFAC02}&lt;br /&gt;
#page #page-header .navbar, #page #page-header .navbar a:link, #page #page-header .navbar a:visited {color:#0C5CAC;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The CSS that we have just added to our theme sets a couple of colours on the front page. Presently this is the only CSS I will add, I know it isn&#039;t complete by any means but it achieves it&#039;s purpose as the screenshot below illustrates.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.02.png|715px|thumb|left|The newly styles demystified theme]]&amp;lt;br style=&amp;quot;clear:both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And with that I will move on to the real purpose of this tutorial, creating the settings page&lt;br /&gt;
&lt;br /&gt;
==Setting up the settings page==&lt;br /&gt;
With the demystified theme set up it is time to create the settings page. This is where the real PHP fun begins.&lt;br /&gt;
&lt;br /&gt;
For those of you who happen to be familiar with development of modules, blocks or other plugin types you have probably encountered settings pages before and this is not going to be any different.&lt;br /&gt;
&lt;br /&gt;
However for those who haven&#039;t which I imagine is most of you this is going to be quite a challenge. I will try to walk through this step by step however if at any point you get stuck don&#039;t hesitate to ask in the forums as I imagine you will get a speedy response.&lt;br /&gt;
&lt;br /&gt;
===How settings pages work in Moodle===&lt;br /&gt;
Settings pages can be used by nearly every plugin type, of which themes is of course one. The way in which it all works isn&#039;t too tricky to understand. &lt;br /&gt;
&lt;br /&gt;
All of the settings for Moodle can be configured through the administrator interfaces when logged in. I am sure that everyone here has seen those pages and has changed a setting or two before so you will all know what I am talking about. Well the settings page for a theme is no different. It will be shown in the administration pages tree under &#039;&#039;&#039;Appearance &amp;gt; Themes&#039;&#039;&#039; and all we have to do is tell Moodle what settings there are.&lt;br /&gt;
&lt;br /&gt;
This is done by creating a settings.php file within our theme into which we will add code that tells Moodle about the settings we want to add/use.&lt;br /&gt;
&lt;br /&gt;
When telling Moodle about each setting we are simply creating a new &#039;&#039;admin_setting&#039;&#039; instance of the type we want and the properties we want and then adding it to our settings page.&lt;br /&gt;
&lt;br /&gt;
There is really not much more too it at this level. Things can get very complex very fast so the best thing we can do now is start creating our settings.php file for the demystified theme and see where it leads us.&lt;br /&gt;
&lt;br /&gt;
===Creating the settings page===&lt;br /&gt;
So as mentioned before we need a settings.php file which we will create now. To begin with create the file &#039;&#039;&#039;theme/demystified/settings.php&#039;&#039;&#039; and open it in your favourite editor so its ready to go.&lt;br /&gt;
&lt;br /&gt;
Before we start adding code however lets just remember the settings that we want to create:&lt;br /&gt;
* change the background colour (CSS).&lt;br /&gt;
* set the path to an image that we will use as a logo on all pages (Layout files).&lt;br /&gt;
* override the width of the block regions (CSS).&lt;br /&gt;
* allow a note to be added to the footer of all pages (Layout files).&lt;br /&gt;
* allow custom CSS to be written to do anything the user wants. (CSS)&lt;br /&gt;
&lt;br /&gt;
Alright.&lt;br /&gt;
&lt;br /&gt;
Now thinking about this the first setting is as basic as it gets, all we need is a text box that the user can type a colour into.&lt;br /&gt;
&lt;br /&gt;
The second is to allow a logo to be used in the header of each page. What we want here is a path but should it be a physical path e.g. C:/path/to/image.png or should it be a web path e.g. &amp;lt;nowiki&amp;gt;http://mysite.com/path/to/image.png&amp;lt;/nowiki&amp;gt;?&lt;br /&gt;
For the purpose of this tutorial I am going to go with a web path because it is going to be easier to code and will hopefully be a little easier to understand to begin with.&lt;br /&gt;
&lt;br /&gt;
The third setting is a little more complex. For this I want a drop down box with some specific widths that the administrator can select.&lt;br /&gt;
&lt;br /&gt;
The forth and the fifth settings are both pretty straight forward, there we want a textarea into which the user can enter what ever they want and we will do something useful with it.&lt;br /&gt;
&lt;br /&gt;
Now that we have an understanding about the settings we wish to define pull up your editor and lets start coding....&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Settings for the demystified theme&lt;br /&gt;
 */&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die;&lt;br /&gt;
&lt;br /&gt;
if ($ADMIN-&amp;gt;fulltree) {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is the first bit of code we must enter, the first line is of course just the opening php tag, secondly we have a comment that describes this file, and then we get create a new &#039;&#039;&#039;admin_settingspage object&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This admin_settingspage object that we have just created is a representation of our settings page and is the what we add our new settings to. When creating it we give it two arguments, first the name of the page which is in this case &#039;&#039;&#039;theme_&#039;&#039;themename&#039;&#039;&#039;&#039;&#039; and the title for the page which we get with the get_string method.&lt;br /&gt;
&lt;br /&gt;
At the moment I&#039;m not going to worry about adding the string, we will get to that later once we have defined all of our settings.&lt;br /&gt;
&lt;br /&gt;
====Background colour====&lt;br /&gt;
&lt;br /&gt;
With the page now created lets add our first setting: Background colour.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Background colour setting&lt;br /&gt;
$name = &#039;theme_demystified/backgroundcolor&#039;;&lt;br /&gt;
$title = get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = &#039;#DDD&#039;;&lt;br /&gt;
$setting = new admin_setting_configtext($name, $title, $description, $default, PARAM_CLEAN, 12);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Thankfully this isn&#039;t as difficult as it initially looks.&lt;br /&gt;
&lt;br /&gt;
The first line of code is creating a variable for the name of the background colour setting. In this case it is &#039;&#039;&#039;theme_demystified/backgroundcolor&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
The name is very important, for the setting to be usable we have to follow a strict naming convention. &#039;&#039;&#039;theme_&#039;&#039;themename&#039;&#039;/&#039;&#039;settingname&#039;&#039;&#039;&#039;&#039; where &#039;&#039;&#039;&#039;&#039;themename&#039;&#039;&#039;&#039;&#039; is the name of the theme the setting belongs to and &#039;&#039;&#039;&#039;&#039;settingname&#039;&#039;&#039;&#039;&#039; is the name for the setting by which we will use it.&lt;br /&gt;
&lt;br /&gt;
The second line of code creates a variable that contains the title of the setting. This is what the user sees to the right of the setting on the settings page and should be a short description of the setting. Here we are again using the &#039;&#039;get_string&#039;&#039; method so we will need to remember to add that string later on.&lt;br /&gt;
&lt;br /&gt;
The third line of code sets the description. This should describe what the setting does or how it works and again we will use the get_string method.&lt;br /&gt;
&lt;br /&gt;
The fourth line creates a variable that will be used as the default value for the setting. Because this setting is a colour we want an HTML colour to be the default value.&lt;br /&gt;
&lt;br /&gt;
The fifth line is where we put it all together. Here we create a new &#039;&#039;&#039;admin_setting_configtext&#039;&#039;&#039; object. This object will represent the background colour setting.&lt;br /&gt;
&lt;br /&gt;
When we create it we need to give it 6 different things.&lt;br /&gt;
# The name of the setting. In this case we have a variable &#039;&#039;&#039;$name&#039;&#039;&#039;.&lt;br /&gt;
# The title for this setting. We used the variable &#039;&#039;&#039;$title&#039;&#039;&#039;.&lt;br /&gt;
# The description of the setting &#039;&#039;&#039;$description&#039;&#039;&#039;.&lt;br /&gt;
# The default value for the setting. &#039;&#039;&#039;$default&#039;&#039;&#039; is the variable this.&lt;br /&gt;
# The type of value we want the user to enter. For this we have used PARAM_CLEAN which tells Moodle to get rid of any nasties from what the user enters.&lt;br /&gt;
# The size of the field. In our case 12 characters will be plenty.&lt;br /&gt;
&lt;br /&gt;
The sixth and final line of code adds our newly created setting to the administration page we created earlier.&lt;br /&gt;
&lt;br /&gt;
That is it we have successfully created and added our first setting, however there are several more to settings to do, and there are a couple of important things that you need to be aware of before we move on.&lt;br /&gt;
&lt;br /&gt;
First: There are several different types of settings that you can create and add to a page, and each one may differ in what they need you to give them. In this case it was name, title, description, default, type, and size. However other settings will likely require different things. Smart editors like Netbeans or Eclipse can tell you what is required, otherwise you will need to research it.&lt;br /&gt;
&lt;br /&gt;
Second: Normally settings are declared on one line as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$setting-&amp;gt;add(new admin_setting_configtext(&#039;theme_demystified/backgroundcolor&#039;, get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;), get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;), &#039;#DDD&#039;, PARAM_CLEAN, 12));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
While this is structurally identical as all we have done is move everything onto one line and do away with the variables it is a little harder to read when you are learning all of this.&lt;br /&gt;
&lt;br /&gt;
====The logo file====&lt;br /&gt;
Time to create the second setting that will allow the user to enter a URL to an image they wish to use as the logo on their site.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Logo file setting&lt;br /&gt;
$name = &#039;theme_demystified/logo&#039;;&lt;br /&gt;
$title = get_string(&#039;logo&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;logodesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtext($name, $title, $description, &#039;&#039;, PARAM_URL);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The first thing that you will notice about this setting that it is very similar to the first setting, in fact all we have changed is the name, title, description, and default value. We have however changed the value type from PARAM_CLEAN to PARAM_URL, this makes sure the user enters a URL. You will also notice that for this one we don&#039;t set a size for the field as we have no idea how long the URL will be.&lt;br /&gt;
&lt;br /&gt;
====Block region width====&lt;br /&gt;
The third setting should allow the user to set a width for the block regions that will be used as columns.&lt;br /&gt;
&lt;br /&gt;
For this setting I want to do something a little different from the previous two, here I want to use a select box so that the user selects a width for the column from a list I provide.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Block region width&lt;br /&gt;
$name = &#039;theme_demystified/regionwidth&#039;;&lt;br /&gt;
$title = get_string(&#039;regionwidth&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;regionwidthdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = 200;&lt;br /&gt;
$choices = array(150=&amp;gt;&#039;150px&#039;, 170=&amp;gt;&#039;170px&#039;, 200=&amp;gt;&#039;200px&#039;, 240=&amp;gt;&#039;240px&#039;, 290=&amp;gt;&#039;290px&#039;, 350=&amp;gt;&#039;350px&#039;, 420=&amp;gt;&#039;420px&#039;);&lt;br /&gt;
$setting = new admin_setting_configselect($name, $title, $description, $default, $choices);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
So looking at the code: The first four lines you will recognise. $name, $title, $description, and $default are all being set.&lt;br /&gt;
&lt;br /&gt;
The fifth line of code however introduces something new. Of course in order to have a select box we have to have options, in this case we have an array of options stored in the variable $choices.&lt;br /&gt;
&lt;br /&gt;
The array of options is constructed of a collection of &#039;&#039;&#039;&#039;&#039;value&#039;&#039;&#039; =&amp;gt; &#039;&#039;&#039;label&#039;&#039;&#039;&#039;&#039; pairs. Notice how we don&#039;t add &#039;&#039;&#039;px&#039;&#039;&#039; to the value. This is is very intentional as later on I need to do a little bit of math with that value so we need it to be a number.&lt;br /&gt;
&lt;br /&gt;
The lines after should look familiar again, the only difference being that instead of a &#039;&#039;admin_setting_configtext&#039;&#039; setting we have created a &#039;&#039;admin_setting_configselect&#039;&#039; for which we must give the choices for the select box as the fifth argument.&lt;br /&gt;
&lt;br /&gt;
Woohoo, we&#039;ve just created our first select box setting.&lt;br /&gt;
&lt;br /&gt;
====Foot note====&lt;br /&gt;
Now to create the foot note setting. Here we want the user to be able to enter some arbitrary text that will be used in the footer of the page. For this I want the user to be able to enter some HTML so I will create an editor setting.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Foot note setting&lt;br /&gt;
$name = &#039;theme_demystified/footnote&#039;;&lt;br /&gt;
$title = get_string(&#039;footnote&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;footnotedesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_confightmleditor($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
How simple is that!&lt;br /&gt;
&lt;br /&gt;
It is just about identical to the first two settings except that for this we have created a &#039;&#039;admin_setting_confightmleditor&#039;&#039; setting rather than a text setting.&lt;br /&gt;
&lt;br /&gt;
Note: You can also set the columns and rows for the editor setting using the fifth and sixth arguments.&lt;br /&gt;
&lt;br /&gt;
====Custom CSS====&lt;br /&gt;
The final setting is to allow the user to add some custom CSS to the theme that will be used on every page. I want this to be a plain textarea into which the user can enter CSS.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Custom CSS file&lt;br /&gt;
$name = &#039;theme_demystified/customcss&#039;;&lt;br /&gt;
$title = get_string(&#039;customcss&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;customcssdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtextarea($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Just like the editor or text settings. It&#039;s getting very easy now!&lt;br /&gt;
&lt;br /&gt;
====Finishing settings.php====&lt;br /&gt;
With all of our settings defined and added to our page that we created right at the beginning it is time to finish it all off.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Add our page to the structure of the admin tree&lt;br /&gt;
$ADMIN-&amp;gt;add(&#039;themes&#039;, $temp);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The above line of code is the final line for the page. It is adding the page that we have created &#039;&#039;&#039;$temp&#039;&#039;&#039; to the admin tree structure. In this case it is adding it to the themes branch.&lt;br /&gt;
&lt;br /&gt;
The following is the completed source for our settings.php ..... for your copy/paste pleasure.&lt;br /&gt;
&amp;lt;div style=&#039;height:300px;overflow:auto;&#039;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Settings for the demystified theme&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
// Create our admin page&lt;br /&gt;
$temp = new admin_settingpage(&#039;theme_demystified&#039;, get_string(&#039;configtitle&#039;,&#039;theme_demystified&#039;));&lt;br /&gt;
&lt;br /&gt;
// Background colour setting&lt;br /&gt;
$name = &#039;theme_demystified/backgroundcolor&#039;;&lt;br /&gt;
$title = get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = &#039;#DDD&#039;;&lt;br /&gt;
$setting = new admin_setting_configtext($name, $title, $description, $default, PARAM_CLEAN, 12);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
// Logo file setting&lt;br /&gt;
$name = &#039;theme_demystified/logo&#039;;&lt;br /&gt;
$title = get_string(&#039;logo&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;logodesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtext($name, $title, $description, &#039;&#039;, PARAM_URL);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
// Block region width&lt;br /&gt;
$name = &#039;theme_demystified/regionwidth&#039;;&lt;br /&gt;
$title = get_string(&#039;regionwidth&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;regionwidthdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = 200;&lt;br /&gt;
$choices = array(150=&amp;gt;&#039;150px&#039;, 170=&amp;gt;&#039;170px&#039;, 200=&amp;gt;&#039;200px&#039;, 240=&amp;gt;&#039;240px&#039;, 290=&amp;gt;&#039;290px&#039;, 350=&amp;gt;&#039;350px&#039;, 420=&amp;gt;&#039;420px&#039;);&lt;br /&gt;
$setting = new admin_setting_configselect($name, $title, $description, $default, $choices);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
// Foot note setting&lt;br /&gt;
$name = &#039;theme_demystified/footnote&#039;;&lt;br /&gt;
$title = get_string(&#039;footnote&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;footnotedesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_confightmleditor($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
// Custom CSS file&lt;br /&gt;
$name = &#039;theme_demystified/customcss&#039;;&lt;br /&gt;
$title = get_string(&#039;customcss&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;customcssdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtextarea($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
// Add our page to the structure of the admin tree&lt;br /&gt;
$ADMIN-&amp;gt;add(&#039;themes&#039;, $temp);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Creating a language file and adding our strings===&lt;br /&gt;
As I&#039;m sure none of you have forgotten, throughout the creation of the our settings.php page, we used a lot of strings that I mentioned we would set later on. Well now is the time to set those strings.&lt;br /&gt;
&lt;br /&gt;
First up create the following directories and file for our language strings:&lt;br /&gt;
* Directory &#039;&#039;&#039;theme/demystified/lang&#039;&#039;&#039;&lt;br /&gt;
* Directory &#039;&#039;&#039;theme/demystified/lang/en&#039;&#039;&#039;&lt;br /&gt;
* File &#039;&#039;&#039;theme/demystified/lang/theme_demystified.php&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
What we have created here is the required structure for Moodle to start looking for language strings.&lt;br /&gt;
&lt;br /&gt;
First Moodle locates the lang directory, once found it looks within that directory for another directory that uses the character code for the language the user has selected, by default this is &#039;&#039;&#039;en&#039;&#039;&#039; for English. Once that is found it looks for the appropriate language file, in this case &#039;&#039;&#039;theme_demystified.php&#039;&#039;&#039; from which it will load all language strings for our theme.&lt;br /&gt;
&lt;br /&gt;
If English isn&#039;t your chosen language simply replace the &#039;&#039;en&#039;&#039; directory with one that uses your chosen languages character code (two letters).&lt;br /&gt;
&lt;br /&gt;
We can now add our language strings to &#039;&#039;&#039;theme/demystified/lang/theme_demystified.php&#039;&#039;&#039;. Copy and paste the following lines of PHP into this file.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This file contains the strings used by the demystified theme&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
$string[&#039;backgroundcolor&#039;] = &#039;Background colour&#039;;&lt;br /&gt;
$string[&#039;backgroundcolordesc&#039;] = &#039;This sets the background colour for the theme.&#039;;&lt;br /&gt;
$string[&#039;configtitle&#039;] = &#039;Demystified theme&#039;;&lt;br /&gt;
$string[&#039;customcss&#039;] = &#039;Custom CSS&#039;;&lt;br /&gt;
$string[&#039;customcssdesc&#039;] = &#039;Any CSS you enter here will be added to every page allowing your to easily customise this theme.&#039;;&lt;br /&gt;
$string[&#039;footnote&#039;] = &#039;Footnote&#039;;&lt;br /&gt;
$string[&#039;footnotedesc&#039;] = &#039;The content from this textarea will be displayed in the footer of every page.&#039;;&lt;br /&gt;
$string[&#039;logo&#039;] = &#039;Logo&#039;;&lt;br /&gt;
$string[&#039;logodesc&#039;] = &#039;Enter the URL to an image to use as the logo for this site. Should be http://www.yoursite.com/path/to/logo.png&#039;;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;Demystified&#039;;&lt;br /&gt;
$string[&#039;regionwidth&#039;] = &#039;Column width&#039;;&lt;br /&gt;
$string[&#039;regionwidthdesc&#039;] = &#039;This sets the width of the two block regions that form the left and right columns.&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above lines of code I have added an entry for each language string we used within &#039;&#039;settings.php&#039;&#039;. When adding language strings like this make sure you use single quotes and try to keep things alphabetical - it helps greatly when managing strings.&lt;br /&gt;
&lt;br /&gt;
Now when we view the settings page there will not be any errors or strings missing.&lt;br /&gt;
&lt;br /&gt;
===Having a look at what we have created===&lt;br /&gt;
Now that we have created our settings page (settings.php) and added all of the language strings it is time to have a look at things in your browser.&lt;br /&gt;
&lt;br /&gt;
Open your browser and enter the URL to your site. When you arrive at your site login as an administrator.&lt;br /&gt;
&lt;br /&gt;
If you are not redirected to view the new settings change your URL to &amp;lt;nowiki&amp;gt;http://www.yoursite.com/admin/&amp;lt;/nowiki&amp;gt; and your will see a screen to set the new theme settings we have just created. This lets us know that everything has worked correctly.&lt;br /&gt;
&lt;br /&gt;
At any point now you are able to log in as administrator and within the settings block browse to &#039;&#039;&#039;Site administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; Demystified theme&#039;&#039;&#039; to change those settings.&lt;br /&gt;
&lt;br /&gt;
The screenshot below shows you what you should see at this point:&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.03.png|715px|thumb|left|The settings page we just created]]&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using the settings in CSS==&lt;br /&gt;
With the settings page now created and operational it is time to make use of our new settings. The settings that we want to use within our CSS is as follows:&lt;br /&gt;
&lt;br /&gt;
; backgroundcolor : Will be used to set the background colour in CSS.&lt;br /&gt;
; regionwidth : Will be the width of the column for CSS.&lt;br /&gt;
; customcss : Will be some custom CSS to add to our stylesheet.&lt;br /&gt;
&lt;br /&gt;
At this point those names are the names we used for our setting with the slash and everything before it having been removed.&lt;br /&gt;
&lt;br /&gt;
Before we start tearing into some code it is important that we have a look at what we are going to do and how we are going to go about it.&lt;br /&gt;
&lt;br /&gt;
===How it all works within Moodle===&lt;br /&gt;
The first thing to understand is that while Moodle allows you to create a settings page and automates it inclusion and management right into the administration interfaces there is no smart equivalent for using the settings. This is simply because there is no way to predict how people will want to use the settings.&lt;br /&gt;
&lt;br /&gt;
However don&#039;t think of this as a disadvantage, in fact it is quite the contrary. Although we can&#039;t just &#039;&#039;use&#039;&#039; our settings we can take full control over how and where we use them. It means it will take a little more code but in the end that will work to our advantage as we can do anything we want.&lt;br /&gt;
&lt;br /&gt;
Moodle does help us out a little but not in an obvious way. The first thing that Moodle does is look for a config variable &#039;&#039;&#039;csspostprocess&#039;&#039;&#039; that should be the name of a function which we want called to make any changes to the CSS after it has been prepared.&lt;br /&gt;
&lt;br /&gt;
The second thing Moodle does is include a lib.php from the theme&#039;s directory if one exists (also for the themes the current theme extends.) which ensures that as long as we write our code within &#039;&#039;&#039;theme/demystified/lib.php&#039;&#039;&#039; it will be included and ready to be used.&lt;br /&gt;
&lt;br /&gt;
The third and final thing Moodle does that will help us out here is ensure that by the time any of code is ready to execute the settings have been prepared and are ready to be used within a theme config object which is passed into our &#039;&#039;csspostprocess&#039;&#039; function.&lt;br /&gt;
&lt;br /&gt;
===Our plan===&lt;br /&gt;
As you have already probably guessed we will need to create a function to make the changes to the CSS that we want. We will then set the theme config option &#039;&#039;&#039;$THEME-&amp;gt;csspostprocess&#039;&#039;&#039; to the name of our function.&lt;br /&gt;
&lt;br /&gt;
By doing this when Moodle builds the CSS file it will call our function afterwards with the CSS and the theme object that contains our setting.&lt;br /&gt;
&lt;br /&gt;
Now we know that we will use the &#039;&#039;csspostprocess&#039;&#039; function but how are we going to change the CSS, we could get the function to add CSS, or we could get the function to replace something within the CSS. My personal preference is to replace something within the CSS, just like what is happening with images. If you want to use an image within CSS you would write &amp;lt;nowiki&amp;gt;[[pix:theme|imagename]]&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For settings I am going to use &amp;lt;nowiki&amp;gt;[[setting:settingname]]&amp;lt;/nowiki&amp;gt;, this way it looks a bit like something you are already familiar with.&lt;br /&gt;
&lt;br /&gt;
What we need to decide upon next is the best way in which to replace our settings tag with the settings that the user has set.&lt;br /&gt;
&lt;br /&gt;
There are two immediate options available to us:&lt;br /&gt;
# Make the &#039;&#039;csspostprocess&#039;&#039; function do all the work.&lt;br /&gt;
# Make the &#039;&#039;csspostprocess&#039;&#039; function call a separate function for each setting.&lt;br /&gt;
Solution 1 might sound like the simplest however it is going to result in a &#039;&#039;&#039;VERY&#039;&#039;&#039; complex function. Remember the user might have left settings blank or entered something that wouldn&#039;t be valid so we would need to make the sure there is some validation and a good default.&lt;br /&gt;
Because of this I think that solution 2 is the better solution.&lt;br /&gt;
&lt;br /&gt;
So we are going to need a &#039;&#039;csspostprocess&#039;&#039; function and then a function for each of the three settings we have that will do the replacements.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// This is our css post process function&lt;br /&gt;
function demystified_process_css($css, $theme) {};&lt;br /&gt;
// This replaces [[setting:backgroundcolor]] with the background colour&lt;br /&gt;
function demystified_set_backgroundcolor($css, $backgroundcolor) {};&lt;br /&gt;
// This replaces [[setting:regionwidth]] with the correct region width&lt;br /&gt;
function demystified_set_regionwidth() {$css, $regionwidth};&lt;br /&gt;
// This replaces [[setting:customcss]] with the custom css&lt;br /&gt;
function demystified_set_customcss() {$css, $customcss};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you should note about the above functions is that they all start with the theme&#039;s name. This is required to ensure that the functions are named uniquely as it is VERY unlikely that someone has already created these functions.&lt;br /&gt;
&lt;br /&gt;
So with our plan set out lets start writing the code.&lt;br /&gt;
&lt;br /&gt;
===Writing the code===&lt;br /&gt;
The very first thing that we need to do is create a lib.php for our theme into which our css processing functions are going to go. So please at this point create &#039;&#039;&#039;theme/demystified/lib.php&#039;&#039;&#039; and open it in your editor ready to go.&lt;br /&gt;
&lt;br /&gt;
The first bit of code we have to write is the function that will be called by Moodle to do the processing &#039;&#039;&#039;demystified_process_css&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
Before we start out please remember that the wonderful thing about coding is that there is any number of solutions to a problem. The solutions that you are seeing here in this tutorial are solutions that I have come up with to meet fulfil the needs of the tutorial without being so complex that they are hard to understand. This probably isn&#039;t how I would go about it normally but this is a little easier to understand for those who aren&#039;t overly familiar with PHP and object orientation.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_process_css====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function demystified_process_css($css, $theme) {&lt;br /&gt;
&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;backgroundcolor)) {&lt;br /&gt;
        $backgroundcolor = $theme-&amp;gt;settings-&amp;gt;backgroundcolor;&lt;br /&gt;
    } else {&lt;br /&gt;
        $backgroundcolor = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_backgroundcolor($css, $backgroundcolor);&lt;br /&gt;
&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;regionwidth)) {&lt;br /&gt;
        $regionwidth = $theme-&amp;gt;settings-&amp;gt;regionwidth;&lt;br /&gt;
    } else {&lt;br /&gt;
        $regionwidth = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_regionwidth($css, $regionwidth);&lt;br /&gt;
&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;customcss)) {&lt;br /&gt;
        $customcss = $theme-&amp;gt;settings-&amp;gt;customcss;&lt;br /&gt;
    } else {&lt;br /&gt;
        $customcss = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_customcss($css, $customcss);&lt;br /&gt;
&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So lets look at the things that make up this function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function demystified_process_css($css, $theme) {&lt;br /&gt;
    //.....&lt;br /&gt;
    return $css&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This of course is the function declaration. &lt;br /&gt;
&lt;br /&gt;
The function gets given two variables, the first &#039;&#039;&#039;$css&#039;&#039;&#039; is a pile of CSS as one big string, and the second is the theme object &#039;&#039;&#039;$theme&#039;&#039;&#039; that contains all of the configuration, options, and settings for our theme.&lt;br /&gt;
&lt;br /&gt;
It then returns the &#039;&#039;$css&#039;&#039; variable, essentially returning the modified CSS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    //...&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;backgroundcolor)) {&lt;br /&gt;
        $backgroundcolor = $theme-&amp;gt;settings-&amp;gt;backgroundcolor;&lt;br /&gt;
    } else {&lt;br /&gt;
        $backgroundcolor = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_backgroundcolor($css, $backgroundcolor);&lt;br /&gt;
    //...&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are processing our first setting &#039;&#039;backgroundcolor&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
The first thing that we need to do is check whether it has been set and whether it has a value. If it has then we store that value in &#039;&#039;&#039;$backgroundcolor&#039;&#039;&#039;. It is doesn&#039;t have a value then we set &#039;&#039;$backgroundcolor&#039;&#039; to null. This ensures that &#039;&#039;$backgroundcolor&#039;&#039; is set because if it isn&#039;t then you are going to get a notice (if you have debugging on).&lt;br /&gt;
&lt;br /&gt;
The final line of this block calls the function &#039;&#039;&#039;demystified_set_backgroundcolor&#039;&#039;&#039;. We haven&#039;t written this function yet but we will shortly. When we call it we give it the &#039;&#039;$css&#039;&#039; variable that contains all of the CSS and we give it the background colour variable &#039;&#039;$backgroundcolor&#039;&#039;. Once this function is finished it returns the &#039;&#039;$css&#039;&#039; variable with all of the changes made much like how our css processing function works.&lt;br /&gt;
&lt;br /&gt;
What you should also note about this code is this:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$theme-&amp;gt;settings-&amp;gt;backgroundcolor&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
As mentioned earlier &#039;&#039;$theme&#039;&#039; is an object that contains all of the configuration and settings for our theme. The &#039;&#039;$theme&#039;&#039; object has a $settings property which contains all of the settings for our theme, and finally the settings property contains a variable backgroundcolor that is the value the user entered for that setting. That is how we get a settings value.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($theme-&amp;gt;settings-&amp;gt;regionwidth)) {&lt;br /&gt;
    $regionwidth = $theme-&amp;gt;settings-&amp;gt;regionwidth;&lt;br /&gt;
} else {&lt;br /&gt;
    $regionwidth = null;&lt;br /&gt;
}&lt;br /&gt;
$css = demystified_set_regionwidth($css, $regionwidth);&lt;br /&gt;
&lt;br /&gt;
if (!empty($theme-&amp;gt;settings-&amp;gt;customcss)) {&lt;br /&gt;
    $customcss = $theme-&amp;gt;settings-&amp;gt;customcss;&lt;br /&gt;
} else {&lt;br /&gt;
    $customcss = null;&lt;br /&gt;
}&lt;br /&gt;
$css = demystified_set_customcss($css, $customcss);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These two routines are nearly identical to the routine above. For both the regionwidth and the customcss we make sure it has a value and then store it in a variable. We then call the relevant function to make the changes for that setting.&lt;br /&gt;
&lt;br /&gt;
Now that we have the general processing function it is time to write the three functions we have used but not written, &#039;&#039;demystified_set_backgroundcolor&#039;&#039;, &#039;&#039;demystified_set_regionwidth&#039;&#039;, &#039;&#039;demystified_set_customcss&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_set_backgroundcolor====&lt;br /&gt;
&lt;br /&gt;
First up demystified_set_backgroundcolor.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Sets the background colour variable in CSS&lt;br /&gt;
 *&lt;br /&gt;
 * @param string $css&lt;br /&gt;
 * @param mixed $backgroundcolor&lt;br /&gt;
 * @return string&lt;br /&gt;
 */&lt;br /&gt;
function demystified_set_backgroundcolor($css, $backgroundcolor) {&lt;br /&gt;
    $tag = &#039;[[setting:backgroundcolor]]&#039;;&lt;br /&gt;
    $replacement = $backgroundcolor;&lt;br /&gt;
    if (is_null($replacement)) {&lt;br /&gt;
        $replacement = &#039;#DDDDDD&#039;;&lt;br /&gt;
    }&lt;br /&gt;
    $css = str_replace($tag, $replacement, $css);&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ok so what is happening here?&lt;br /&gt;
&lt;br /&gt;
First we need a variable &#039;&#039;&#039;$tag&#039;&#039;&#039; that contains the tag we are going to replace. As mentioned earlier we are going to use tags that look like the image tags you are already familiar with &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:settingname]]&amp;lt;/nowiki&amp;gt;&#039;&#039;, in this case &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:backgroundcolor]]&amp;lt;/nowiki&amp;gt;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Next I am going to create a variable called &#039;&#039;&#039;$replacement&#039;&#039;&#039; into which I put &#039;&#039;&#039;$backgroundcolor&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;IF&#039;&#039;&#039; statement that comes next checks &#039;&#039;$replacement&#039;&#039; to make sure it is not null. If it is then we need to set it to a default value. In this case I have used &#039;&#039;#DDD&#039;&#039; as that was the default for the settings.&lt;br /&gt;
&lt;br /&gt;
The line after the IF statement puts it all together. The &#039;&#039;str_replace&#039;&#039; function that we are calling takes three arguments in this order:&lt;br /&gt;
# The text to search for.&lt;br /&gt;
# The text to replace it with.&lt;br /&gt;
# The text to do the replacement in.&lt;br /&gt;
It then returns the text with all of the replacements made. So in this case we are replacing the tag with the background colour and it is returning the changed CSS.&lt;br /&gt;
&lt;br /&gt;
The final thing is to return the &#039;&#039;$css&#039;&#039; variable which now contains the correct background colour.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_set_regionwidth====&lt;br /&gt;
&lt;br /&gt;
Next we have the demystified_set_regionwidth function.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Sets the region width variable in CSS&lt;br /&gt;
 *&lt;br /&gt;
 * @param string $css&lt;br /&gt;
 * @param mixed $regionwidth&lt;br /&gt;
 * @return string&lt;br /&gt;
 */&lt;br /&gt;
function demystified_set_regionwidth($css, $regionwidth) {&lt;br /&gt;
    $tag = &#039;[[setting:regionwidth]]&#039;;&lt;br /&gt;
    $doubletag = &#039;[[setting:regionwidthdouble]]&#039;;&lt;br /&gt;
    $replacement = $regionwidth;&lt;br /&gt;
    if (is_null($replacement)) {&lt;br /&gt;
        $replacement = 200;&lt;br /&gt;
    }&lt;br /&gt;
    $css = str_replace($tag, $replacement.&#039;px&#039;, $css);&lt;br /&gt;
    $css = str_replace($doubletag, ($replacement*2).&#039;px&#039;, $css);&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function is very similar to the above function however there is one key thing we are doing different. We are doing two replacements.&lt;br /&gt;
&lt;br /&gt;
# The first replacement is for the width that the user selected. In this case I am replacing the tag &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt;&#039;&#039; with the width.&lt;br /&gt;
# The second replacement is for the width x 2. This is because the page layout requires that the width be doubled for some of the CSS. Here I will replace &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidthdouble]]&amp;lt;/nowiki&amp;gt;&#039;&#039; with the doubled width.&lt;br /&gt;
&lt;br /&gt;
Remember because it is still just a number we need to add &#039;&#039;&#039;px&#039;&#039;&#039; to the end of each before we do the replacement.&lt;br /&gt;
&lt;br /&gt;
So the overall process of this function is:&lt;br /&gt;
# Define the two tags as &#039;&#039;&#039;$tag&#039;&#039;&#039; and &#039;&#039;&#039;$doubletag&#039;&#039;&#039;.&lt;br /&gt;
# Make &#039;&#039;&#039;$replacement&#039;&#039;&#039; the region width &#039;&#039;$regionwidth&#039;&#039;.&lt;br /&gt;
# Set &#039;&#039;$replacement&#039;&#039; to a default value of 200 is it is null.&lt;br /&gt;
# Replace &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; with the width.&lt;br /&gt;
# Replace &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidthdouble]]&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; with the width x 2.&lt;br /&gt;
# Return the changed CSS.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_set_customcss====&lt;br /&gt;
&lt;br /&gt;
The final function that we need to write is the demystified_set_customcss function.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Sets the custom css variable in CSS&lt;br /&gt;
 *&lt;br /&gt;
 * @param string $css&lt;br /&gt;
 * @param mixed $customcss&lt;br /&gt;
 * @return string&lt;br /&gt;
 */&lt;br /&gt;
function demystified_set_customcss($css, $customcss) {&lt;br /&gt;
    $tag = &#039;[[setting:customcss]]&#039;;&lt;br /&gt;
    $replacement = $customcss;&lt;br /&gt;
    if (is_null($replacement)) {&lt;br /&gt;
        $replacement = &#039;&#039;;&lt;br /&gt;
    }&lt;br /&gt;
    $css = str_replace($tag, $replacement, $css);&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function is just like the first function. I&#039;m going to let you work it out on your own.&lt;br /&gt;
&lt;br /&gt;
And that is it no more PHP... Hallelujah I can hear you yelling. The final thing we need to do is tell our theme about the functions we have written and put the settings tags into the CSS.&lt;br /&gt;
&lt;br /&gt;
===Finishing it all off===&lt;br /&gt;
&lt;br /&gt;
So there are two things we have to do in order to complete this section and have our the settings page implemented and our settings being used.&lt;br /&gt;
&lt;br /&gt;
First we need to tell our theme that we want to use the function &#039;&#039;demystified_process_css&#039;&#039; as the &#039;&#039;csspostprocess&#039;&#039; function. This is done very simply by adding the following line of PHP to the bottom of our theme&#039;s config.php file &#039;&#039;&#039;theme/demystified/config.php&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;csspostprocess = &#039;demystified_process_css&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done the only thing left is to add the settings tag into the CSS. Remember those settings tags are:&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:backgroundcolor]]&amp;lt;/nowiki&amp;gt; : We need to add this where ever we want the background colour setting to be used.&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt; : We need to add this where ever we want to set the width of the block regions.&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:regionwidthdouble]]&amp;lt;/nowiki&amp;gt; : We need to add this where ever we want to set the doubled width of the block regions.&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:customcss]]&amp;lt;/nowiki&amp;gt; : We need to add this to the bottom of the CSS file that we want the custom CSS added to.&lt;br /&gt;
&lt;br /&gt;
So lets make those changes in CSS now, open up your &#039;&#039;core.css&#039;&#039; file and replace the CSS with the CSS below:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/** Background color is a setting **/&lt;br /&gt;
html {background-color:[[setting:backgroundcolor]];}&lt;br /&gt;
body {margin:30px;padding:0;border:1px solid #333;border-width:0 10px 0 10px;background-color:#333;}&lt;br /&gt;
body #page {background-color:#FFF;position:relative;top:-10px;}&lt;br /&gt;
.block .header {background-image:none;background-color:#0C5CAC;border:1px solid #0C5CAC;color:#FFF;}&lt;br /&gt;
.block {border-color:#4BA7FF;background-color:#DDEEFF;}&lt;br /&gt;
.block .content {background-color:#F1F8FF;}&lt;br /&gt;
a:link,&lt;br /&gt;
a:visited {color:#0C5CAC;}&lt;br /&gt;
a:hover {color:#C77500;}&lt;br /&gt;
#page #page-header {background-color:#0C5CAC;margin:0;padding:0;width:100%;color:#fff;}&lt;br /&gt;
#page #page-header a:link, #page #page-header a:visited {color:#FFAC02}&lt;br /&gt;
#page #page-header .navbar, #page #page-header .navbar a:link, #page #page-header .navbar a:visited {color:#0C5CAC;}&lt;br /&gt;
/** Override the region width **/&lt;br /&gt;
#page-content #region-main-box {left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidthdouble]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-pre {width:[[setting:regionwidth]];left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-post {width:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidthdouble]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
/** Custom CSS **/&lt;br /&gt;
[[setting:customcss]]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will notice that &amp;lt;nowiki&amp;gt;[[setting:backgroundcolor]]&amp;lt;/nowiki&amp;gt; has been used for the html tags background colour:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
html {background-color:[[setting:backgroundcolor]];}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have also set the width of the block regions by adding &amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt; as the width for region-pre and region-post as shown below:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
#page-content #region-main-box {left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidthdouble]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-pre {width:[[setting:regionwidth]];left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-post {width:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidthdouble]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
You&#039;ll notice here that we have to set several different widths and margins using the regionwidth setting and make use of the special regionwidthdouble setting that we added.&lt;br /&gt;
&lt;br /&gt;
The final thing that we did was add the &amp;lt;nowiki&amp;gt;[[setting:customcss]]&amp;lt;/nowiki&amp;gt; to the bottom of the file to ensure that the custom CSS comes last (and therefore can override all other CSS).&lt;br /&gt;
&lt;br /&gt;
And with that we are finished. The screenshot below shows how this now looks in the browser if I set the background colour setting to &#039;&#039;&#039;&amp;lt;span style=&#039;color:#FFA800;&#039;&amp;gt;#FFA800&amp;lt;/span&amp;gt;&#039;&#039;&#039; and made the column width 240px;&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.04.png|715px|thumb|left|Our settings in action]]&amp;lt;br style=&amp;quot;clear:both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using the settings within our layout files==&lt;br /&gt;
Now that we have utilised the first three settings within our theme&#039;s CSS file it is time to implement the other two settings within the layout files so that they are written directly into the page.&lt;br /&gt;
&lt;br /&gt;
You&#039;ll be glad to know this is no where near as difficult as utilising settings within a CSS file although it still does require a little bit of PHP.&lt;br /&gt;
&lt;br /&gt;
First up is the logo setting. Into this setting the user is able to enter the URL to an image to use as the logo for the site. In my case I want this to be just a background logo on top of which I want to position the page header.&lt;br /&gt;
&lt;br /&gt;
Before I start there is one thing I need to do however and that is create a default logo background that gets shown if the user hasn&#039;t set a specific logo file. To do this I simply created an image &#039;&#039;&#039;logo.jpg&#039;&#039;&#039; and put it into a pix directory within the demystified theme. You should end up with &#039;&#039;&#039;theme/demystified/pix/logo.jpg&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Next open up the front-page layout file &#039;&#039;theme/demystified/layout/frontpage.php&#039;&#039;. At the top of the file is the PHP that checks what blocks regions the page has and a bit of other stuff. Well right below the existing bit of PHP we want to add the following code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;logo)) {&lt;br /&gt;
    $logourl = $PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;logo;&lt;br /&gt;
} else {&lt;br /&gt;
    $logourl = $OUTPUT-&amp;gt;pix_url(&#039;logo&#039;, &#039;theme&#039;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
What we are doing here is creating a variable called $logourl that will contain the URL to a logo file that was either entered by the user or if they left it blank is that of our default logo file.&lt;br /&gt;
&lt;br /&gt;
There are two things that you should notice about this. First the logo setting can be retrieved through &#039;&#039;&#039;$PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;logo&#039;&#039;&#039; and second we get the default logo url by calling &#039;&#039;&#039;$OUTPUT-&amp;gt;pix_url(&#039;logo&#039;, &#039;theme&#039;)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Now that we have the logo URL we are going to use we need to add an image to the header section of the page as shown below:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;page-header&amp;quot; class=&amp;quot;clearfix&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;img class=&amp;quot;sitelogo&amp;quot; src=&amp;quot;&amp;lt;?php echo $logourl;?&amp;gt;&amp;quot; alt=&amp;quot;Custom logo here&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;
....&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you save that and browse to your sites front page you will notice that the logo file is now being shown. Hooray. However it is probably not styled too nicely so lets quickly fix that. Open up the core.css file and add the following lines of CSS to the bottom of the file.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
#page-header {position:relative;min-height:100px;}&lt;br /&gt;
#page-header .sitelogo {float:left;}&lt;br /&gt;
#page-header .headermain {position:absolute;left:0.5em;top:50px;margin:0;float:none;font-size:40px;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
These three lines position the image correctly and if you now refresh everything should appear perfectly. &lt;br /&gt;
&lt;br /&gt;
With the logo done the last setting we need to deal with is the footnote setting. The idea with this setting was that the administrator could enter some text into the editor and it would be displayed in the footer of the page.&lt;br /&gt;
&lt;br /&gt;
This is probably the easiest setting to implement.&lt;br /&gt;
&lt;br /&gt;
Within the front page layout file that we edited above add the following lines below those we added previously.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;footnote)) {&lt;br /&gt;
    $footnote = $PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;footnote;&lt;br /&gt;
} else {&lt;br /&gt;
    $footnote = &#039;&amp;lt;!-- There was no custom footnote set --&amp;gt;&#039;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are just collecting the footnote into a variable &#039;&#039;&#039;$footnote&#039;&#039;&#039; and setting a default footnote comment if the user hasn&#039;t entered one.&lt;br /&gt;
&lt;br /&gt;
We can now echo the $footnote variable within the page footer. This can be done as shown below.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;!-- START OF FOOTER --&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;footnote&amp;quot;&amp;gt;&amp;lt;?php echo $footnote; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;p class=&amp;quot;helplink&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;?php echo page_doc_link(get_string(&#039;moodledocslink&#039;)) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And with that done we are finished! Congratulations if you got this far.&lt;br /&gt;
&lt;br /&gt;
The screenshot below shows the demystified theme we have just created that is styled by the settings page.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.05.png|715px|thumb|left|My finished demystified theme]]&amp;lt;br style=&amp;quot;clear:both&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing our creation==&lt;br /&gt;
Congratulations to you! If you&#039;ve made it this far you have done very well. Now it is time to have a look at what we have created and give it a quick test run.&lt;br /&gt;
&lt;br /&gt;
So in this tutorial we have achieved the following:&lt;br /&gt;
&lt;br /&gt;
* We created a theme called demystified that is based on the standard theme.&lt;br /&gt;
* We added a settings page to our new theme.&lt;br /&gt;
* We added the following settings to our settings page:&lt;br /&gt;
** We can set a background colour through the admin interface.&lt;br /&gt;
** We can change the logo of the site.&lt;br /&gt;
** We can change the block region width.&lt;br /&gt;
** We can add a footnote to the page footer&lt;br /&gt;
** We can add some custom CSS to seal the deal.&lt;br /&gt;
* Those settings were then used in the CSS files for our theme.&lt;br /&gt;
* They were also used in the layout files for our theme.&lt;br /&gt;
* And here we are testing it all.&lt;br /&gt;
&lt;br /&gt;
The screenshots below show my testing process and I change each setting and view the outcome. The great thing about this is that with theme designer mode on you see the changes as soon as the form refreshes.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.06.png|300px|thumb|left|Default settings]]&lt;br /&gt;
[[Image:Theme.settings.page.07.png|300px|thumb|left|Changed the background colour setting]]&lt;br /&gt;
[[Image:Theme.settings.page.08.png|300px|thumb|left|Changed the logo and region width]]&lt;br /&gt;
[[Image:Theme.settings.page.09.png|300px|thumb|left|Added a footnote]]&lt;br /&gt;
[[Image:Theme.settings.page.10.png|300px|thumb|left|Added some custom CSS]]&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:both&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The different settings you can use==&lt;br /&gt;
During this tutorial we use four different kinds of settings, a text box, text area, a select (dropdown) and the editor however as I&#039;m sure you have all guessed there is many more some of which will certainly be useful for theme settings.&lt;br /&gt;
&lt;br /&gt;
The following are examples of some of the different settings. I should add that these build upon what we have already done within the tutorial but are not included in the download.&lt;br /&gt;
&lt;br /&gt;
===Colour picker===&lt;br /&gt;
[[Image:Theme.settings.page.11.png|400px|thumb|The colour picker]]&lt;br /&gt;
I can hear you all asking now &#039;Why didn&#039;t you mention this one earlier?&#039; well the answer is simple it didn&#039;t exist when I first wrote the tutorial. It is an admin setting that I wrote several days after because of the fantastic effort people were putting into trying out settings pages.&lt;br /&gt;
&lt;br /&gt;
A bit about the colour picker. First up it is a text box that when the page loads turns into a colour picker that can be used to select a colour and can even preview the selected colour in the page (by clicking the preview button). It is designed to be very easy to use and the code is just about as simple as creating a normal text box setting.&lt;br /&gt;
&lt;br /&gt;
In the image to the left I have replaced the background colour setting we created during the tutorial with the colour picker. Lets have a look at the code involved for that.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Background colour setting&lt;br /&gt;
$name = &#039;theme_demystified/backgroundcolor&#039;;&lt;br /&gt;
$title = get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = &#039;#DDD&#039;;&lt;br /&gt;
$previewconfig = array(&#039;selector&#039;=&amp;gt;&#039;html&#039;, &#039;style&#039;=&amp;gt;&#039;backgroundColor&#039;);&lt;br /&gt;
$setting = new admin_setting_configcolourpicker($name, $title, $description, $default, $previewconfig);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
So first thing you should notice is that the first four lines of code have not changed at all!&lt;br /&gt;
&lt;br /&gt;
The first change we have is to create a variable &#039;&#039;&#039;$previewconfig&#039;&#039;&#039;. &lt;br /&gt;
This variable is used to tell the colour picker what to do when the user clicks the preview button. It should be an array that contains two things, first a selector, and second a style. &lt;br /&gt;
# The selector is a CSS selector like &#039;&#039;.page .header h2&#039;&#039;.&lt;br /&gt;
# The style is a what should change, there are two immediate values it can be, either &#039;&#039;&#039;backgroundColor&#039;&#039;&#039; or &#039;&#039;&#039;color&#039;&#039;&#039;.&lt;br /&gt;
In my case the selector is &#039;&#039;&#039;html&#039;&#039;&#039; to target the html tag and the style is backgroundColor to change the background colour.&lt;br /&gt;
&lt;br /&gt;
The second change is to use &#039;&#039;&#039;admin_setting_configcolourpicker&#039;&#039;&#039; instead of &#039;&#039;admin_setting_configtext&#039;&#039;. The arguments are nearly identical as well except that there is an extra argument to which we give the &#039;&#039;&#039;$previewconfig&#039;&#039;&#039; variable.&lt;br /&gt;
&lt;br /&gt;
And that is it! it is all you need to get the colour picker up and running.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Extra note:&#039;&#039;&#039; The $previewconfig variable is optional. If you don&#039;t want a preview button the simply set &#039;&#039;$previewconfig = null&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Common pitfalls and useful notes==&lt;br /&gt;
&lt;br /&gt;
This section is really just a collection of pointers, tips, notes, and other short useful stuff that may be of use to those attempting this tutorial.&lt;br /&gt;
&lt;br /&gt;
# First up and most importantly there are very few limitations to what you achieve in this fashion.&lt;br /&gt;
# If you get stuck or need a hand ask in the forums, there&#039;s always someone round who can help.&lt;br /&gt;
# If you do something really cool let us know, I know everyone in the community loves finding our what others are achieving.&lt;br /&gt;
# You don&#039;t have to use &#039;&#039;admin_settingpage&#039;&#039; you can also use &#039;&#039;&#039;admin_externalpage&#039;&#039;&#039; if you prefer. It should be noted however that it is not the preferred way to do it as admin_externalpage&#039;s were only left in Moodle 2.0 for backwards compatibility (although they are more flexible one day they will be deprecated or removed). Thank you to Darryl for raising this.&lt;br /&gt;
# If you find that your language strings aren&#039;t being used (you are getting language string notices) and you have double checked that you have turned &#039;&#039;&#039;langstringcache&#039;&#039;&#039; off then you may need to delete the language cache directory. This is located in the moodledata directory for you installation: moodledata/cache/lang/*. You should delete the directory for your chosen language by default &#039;&#039;en&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Adding theme upgrade code]]&lt;br /&gt;
* [[Styling and customising the dock]]&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/discuss.php?d=152053 Theme 2.0: Adding a settings page to your theme] forum discussion&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Creating_a_theme_settings_page&amp;diff=46306</id>
		<title>Creating a theme settings page</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Creating_a_theme_settings_page&amp;diff=46306"/>
		<updated>2014-09-24T21:58:44Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Foot note */ - updating&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}This document looks at how to create a settings page for your Moodle 2.x.x theme and how to make use of those settings within the CSS and layout files for your theme.&lt;br /&gt;
&lt;br /&gt;
This is a pretty advanced topic and will require that you have at least an intermediate knowledge of PHP, CSS, and development in general.&lt;br /&gt;
&lt;br /&gt;
==Before we begin==&lt;br /&gt;
[[Image:Theme.settings.page.03.png|350px|thumb|Our end goal. The settings page.]]&lt;br /&gt;
[[Image:Theme.settings.page.10.png|350px|thumb|And what it can do.]]&lt;br /&gt;
There is a huge body of knowledge that we must cover in following through this document and as such I think the best way to write this is as a tutorial.&lt;br /&gt;
&lt;br /&gt;
My intentions for this tutorial are to replicate the standard theme but with a settings page that allows the administrator to set a background colour, set a logo to use with the page, and probably several other minor settings to change the way in which the theme is displayed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I will start this tutorial by creating a new theme which will be largely a copy/paste of the current standard theme. I expect that anyone working through this tutorial has previously read the tutorial I wrote on [[Themes 2.0 creating your first theme|creating your first theme]]. If you haven&#039;t go read it now because I&#039;m not going to go into much detail until we get to the actual process of customising the theme and introducing the settings page.&lt;br /&gt;
&lt;br /&gt;
So before we finally get this started please ensure you can check off everything on the following requirements list.&lt;br /&gt;
* Have a Moodle installation that has already been installed and configured and is ready to use.&lt;br /&gt;
* Have full read/write access to that installation.&lt;br /&gt;
* Be prepared to delete that installation at the end of this... we will destroy it!&lt;br /&gt;
* Have a development environment prepared and ready to use. This includes:&lt;br /&gt;
** Your favourite editor installed, running, and pointed at the themes directory of your installation.&lt;br /&gt;
** Your browser open and your site visible.&lt;br /&gt;
** A bottomless coffee pot... decaf won&#039;t help you with this one.&lt;br /&gt;
* Have set the following settings:&lt;br /&gt;
** &#039;&#039;&#039;themedesignermode&#039;&#039;&#039; if you don&#039;t know what this is please read the [[Themes 2.0 creating your first theme|creating your first theme]] tutorial.&lt;br /&gt;
** &#039;&#039;&#039;allowthemechangeonurl&#039;&#039;&#039; turn this on, it allows you to change themes on the URL and is very handy when developing themes. &#039;&#039;Site Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; Theme settings&#039;&#039;&lt;br /&gt;
** &#039;&#039;&#039;langstringcache&#039;&#039;&#039; if you don&#039;t turn this off you won&#039;t see your strings when they are added. &#039;&#039;Site Administration &amp;gt; Language &amp;gt; Language settings&#039;&#039;&lt;br /&gt;
* And finally an insane ambition to create a customisable theme.&lt;br /&gt;
&lt;br /&gt;
For those interested the theme that I create throughout this tutorial can be downloaded from the forum post in which I announce this document: http://moodle.org/mod/forum/discuss.php?d=152053&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:right;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Our goals for this tutorial==&lt;br /&gt;
The following is just a list goals that I hope to achieve during this tutorial. They are laid out here so that I can easily refer back to them and so that you can easily find them.&lt;br /&gt;
# Create a new theme called &#039;&#039;&#039;demystified&#039;&#039;&#039; based upon the standard theme within Moodle 2.0.&lt;br /&gt;
# Make some minor changes to that theme to allow us to more easily see what is going on.&lt;br /&gt;
# Create a settings page for the demystified theme.&lt;br /&gt;
# Add several settings to our settings page.&lt;br /&gt;
# Use some of those settings to alter our CSS.&lt;br /&gt;
# Use the rest of those settings within our layout file..&lt;br /&gt;
# Discuss the good, the bad, and limits of what we have just created.&lt;br /&gt;
&lt;br /&gt;
So I can see you are all very excited about this point and that you would love to know what settings we are going to create; So here they are:&lt;br /&gt;
&lt;br /&gt;
A setting to ...&lt;br /&gt;
* change the background colour (CSS).&lt;br /&gt;
* set the path to an image that we will use as a logo on all pages (Layout files).&lt;br /&gt;
* override the width of the block regions (CSS).&lt;br /&gt;
* allow a note to be added to the footer of all pages (Layout files).&lt;br /&gt;
* allow custom CSS to be written to do anything the user wants. (CSS)&lt;br /&gt;
&lt;br /&gt;
==Creating the demystified theme==&lt;br /&gt;
Before we start here I want to remind you that I am going to look at this only briefly as I am making the assumption that you have read the [[Themes 2.0 creating your first theme|creating your first theme]] tutorial.&lt;br /&gt;
&lt;br /&gt;
Well lets get into it....&lt;br /&gt;
&lt;br /&gt;
The first thing we need to do is create a directory for our theme which we will call demystified. &lt;br /&gt;
&lt;br /&gt;
So within your Moodle directory create the following folder &#039;&#039;&#039;moodle/theme/demystified&#039;&#039;&#039;. At the same time you can also create the following files and folders which we will get to soon.&lt;br /&gt;
* The file &#039;&#039;&#039;moodle/theme/demystified/config.php&#039;&#039;&#039; for our config information.&lt;br /&gt;
* The directory &#039;&#039;&#039;moodle/theme/demystified/layout&#039;&#039;&#039; for our layout files.&lt;br /&gt;
* The directory &#039;&#039;&#039;moodle/theme/demystified/style&#039;&#039;&#039; for our css files.&lt;br /&gt;
* The file &#039;&#039;&#039;moodle/theme/demystified/style/core.css&#039;&#039;&#039; which will contain our special CSS.&lt;br /&gt;
&lt;br /&gt;
Next we will copy the layout files from the base theme to our new theme demystified. We are basing the demystified theme on the standard theme however that doesn&#039;t use it&#039;s own layout files it uses the base theme&#039;s layout files so those are the ones we want. &lt;br /&gt;
&lt;br /&gt;
The reason that we are coping these layout files is that later on in this tutorial we will be modifying them to make use of our new settings... so copy all of the layout files from &#039;&#039;&#039;moodle/theme/base/layout&#039;&#039;&#039; to &#039;&#039;&#039;moodle/theme/demystified/layout&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
There should be three files that you just copied:&lt;br /&gt;
# embedded.php&lt;br /&gt;
# frontpage.php&lt;br /&gt;
# general.php&lt;br /&gt;
&lt;br /&gt;
Now we need to populate demystified/config.php with the settings for our new theme. They are as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;name = &#039;demystified&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Simply sets the name of our theme.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;,&#039;base&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This theme is extending both the standard theme and the base theme. Remember when extending a theme you also need to extend its parents or things might not work correctly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;core&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This tells our theme that we want to use the file &#039;&#039;&#039;demystified/style/core.css&#039;&#039;&#039; with this theme.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;height:300px;overflow-y:scroll;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Most backwards compatible layout without the blocks - this is the layout used by default&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&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;
    // 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;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;
    // Main course page&lt;br /&gt;
    &#039;course&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;coursecategory&#039; =&amp;gt; array(&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;
    // part of course, typical for modules - default page layout if $cm specified in require_login()&lt;br /&gt;
    &#039;incourse&#039; =&amp;gt; array(&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;
    // The site home page.&lt;br /&gt;
    &#039;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;frontpage.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;
    // Server administration scripts.&lt;br /&gt;
    &#039;admin&#039; =&amp;gt; array(&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;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // My dashboard page&lt;br /&gt;
    &#039;mydashboard&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // My public page&lt;br /&gt;
    &#039;mypublic&#039; =&amp;gt; array(&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;
    &#039;login&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    // Pages that appear in pop-up windows - no navigation, no blocks, no header.&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // No blocks and minimal footer - used for legacy frame layouts only!&lt;br /&gt;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible&lt;br /&gt;
    &#039;embedded&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Used during upgrade and install, and for the &#039;This site is undergoing maintenance&#039; message.&lt;br /&gt;
    // This must not have any blocks, and it is good idea if it does not have links to&lt;br /&gt;
    // other places - for example there should not be a home link in the footer...&lt;br /&gt;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Now that all looks very complicated however its really not too bad as it is just copied from the base theme&#039;s config.php file. We can do this because we copied the layout files from the base theme to begin with and for the time being there are no changes that we wish to make. Simply open up &#039;&#039;&#039;theme/base/config.php&#039;&#039;&#039; and copy the layouts from there.&lt;br /&gt;
&lt;br /&gt;
And that is it. The config.php file for our demystified theme is complete. The full source is shown below:&lt;br /&gt;
&amp;lt;div style=&amp;quot;height:300px;overflow-y:scroll;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
// This file is part of Moodle - http://moodle.org/&lt;br /&gt;
//&lt;br /&gt;
// Moodle is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// Moodle is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with Moodle.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * The demystified theme config file&lt;br /&gt;
 *&lt;br /&gt;
 * This theme was created to document the process of adding a settings page to a theme&lt;br /&gt;
 *&lt;br /&gt;
 * @copyright 2010 Sam Hemelryk&lt;br /&gt;
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
// The name of our theme&lt;br /&gt;
$THEME-&amp;gt;name = &#039;demystified&#039;;&lt;br /&gt;
&lt;br /&gt;
// The other themes this theme extends&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;,&#039;base&#039;);&lt;br /&gt;
&lt;br /&gt;
// The CSS files this theme uses (located in the style directory)&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;core&#039;);&lt;br /&gt;
&lt;br /&gt;
// The layout definitions for this theme&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Most backwards compatible layout without the blocks - this is the layout used by default&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&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;
    // 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;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;
    // Main course page&lt;br /&gt;
    &#039;course&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;coursecategory&#039; =&amp;gt; array(&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;
    // part of course, typical for modules - default page layout if $cm specified in require_login()&lt;br /&gt;
    &#039;incourse&#039; =&amp;gt; array(&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;
    // The site home page.&lt;br /&gt;
    &#039;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;frontpage.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;
    // Server administration scripts.&lt;br /&gt;
    &#039;admin&#039; =&amp;gt; array(&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;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // My dashboard page&lt;br /&gt;
    &#039;mydashboard&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // My public page&lt;br /&gt;
    &#039;mypublic&#039; =&amp;gt; array(&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;
    &#039;login&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    // Pages that appear in pop-up windows - no navigation, no blocks, no header.&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // No blocks and minimal footer - used for legacy frame layouts only!&lt;br /&gt;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible&lt;br /&gt;
    &#039;embedded&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Used during upgrade and install, and for the &#039;This site is undergoing maintenance&#039; message.&lt;br /&gt;
    // This must not have any blocks, and it is good idea if it does not have links to&lt;br /&gt;
    // other places - for example there should not be a home link in the footer...&lt;br /&gt;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The screenshot below shows both the directory structure we have now created and the theme presently.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.01.png]]&lt;br /&gt;
&lt;br /&gt;
To view the theme so far open you browser and enter the URL of your site followed by &#039;&#039;&#039;?theme=demystified&#039;&#039;&#039;. You should see the theme that we just created which will look exactly like the base standard theme.&lt;br /&gt;
&lt;br /&gt;
The final thing that we want to do is add a little bit of CSS to the demystified theme that will both visually set this theme apart from the standard theme and second build a the base which our settings can later extend.&lt;br /&gt;
&lt;br /&gt;
I added the following snippet of CSS to the file &#039;&#039;&#039;demystified/style/core.css&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
html {background-color:#DDD;}&lt;br /&gt;
body {margin:30px;padding:0;border:1px solid #333;border-width:0 10px 0 10px;background-color:#333;}&lt;br /&gt;
body #page {background-color:#FFF;position:relative;top:-10px;}&lt;br /&gt;
.block .header {background-image:none;background-color:#0C5CAC;border:1px solid #0C5CAC;color:#FFF;}&lt;br /&gt;
.block {border-color:#4BA7FF;background-color:#DDEEFF;}&lt;br /&gt;
.block .content {background-color:#F1F8FF;}&lt;br /&gt;
a:link,&lt;br /&gt;
a:visited {color:#0C5CAC;}&lt;br /&gt;
a:hover {color:#C77500;}&lt;br /&gt;
#page #page-header {background-color:#0C5CAC;margin:0;padding:0;width:100%;color:#fff;}&lt;br /&gt;
#page #page-header a:link, #page #page-header a:visited {color:#FFAC02}&lt;br /&gt;
#page #page-header .navbar, #page #page-header .navbar a:link, #page #page-header .navbar a:visited {color:#0C5CAC;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The CSS that we have just added to our theme sets a couple of colours on the front page. Presently this is the only CSS I will add, I know it isn&#039;t complete by any means but it achieves it&#039;s purpose as the screenshot below illustrates.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.02.png|715px|thumb|left|The newly styles demystified theme]]&amp;lt;br style=&amp;quot;clear:both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And with that I will move on to the real purpose of this tutorial, creating the settings page&lt;br /&gt;
&lt;br /&gt;
==Setting up the settings page==&lt;br /&gt;
With the demystified theme set up it is time to create the settings page. This is where the real PHP fun begins.&lt;br /&gt;
&lt;br /&gt;
For those of you who happen to be familiar with development of modules, blocks or other plugin types you have probably encountered settings pages before and this is not going to be any different.&lt;br /&gt;
&lt;br /&gt;
However for those who haven&#039;t which I imagine is most of you this is going to be quite a challenge. I will try to walk through this step by step however if at any point you get stuck don&#039;t hesitate to ask in the forums as I imagine you will get a speedy response.&lt;br /&gt;
&lt;br /&gt;
===How settings pages work in Moodle===&lt;br /&gt;
Settings pages can be used by nearly every plugin type, of which themes is of course one. The way in which it all works isn&#039;t too tricky to understand. &lt;br /&gt;
&lt;br /&gt;
All of the settings for Moodle can be configured through the administrator interfaces when logged in. I am sure that everyone here has seen those pages and has changed a setting or two before so you will all know what I am talking about. Well the settings page for a theme is no different. It will be shown in the administration pages tree under &#039;&#039;&#039;Appearance &amp;gt; Themes&#039;&#039;&#039; and all we have to do is tell Moodle what settings there are.&lt;br /&gt;
&lt;br /&gt;
This is done by creating a settings.php file within our theme into which we will add code that tells Moodle about the settings we want to add/use.&lt;br /&gt;
&lt;br /&gt;
When telling Moodle about each setting we are simply creating a new &#039;&#039;admin_setting&#039;&#039; instance of the type we want and the properties we want and then adding it to our settings page.&lt;br /&gt;
&lt;br /&gt;
There is really not much more too it at this level. Things can get very complex very fast so the best thing we can do now is start creating our settings.php file for the demystified theme and see where it leads us.&lt;br /&gt;
&lt;br /&gt;
===Creating the settings page===&lt;br /&gt;
So as mentioned before we need a settings.php file which we will create now. To begin with create the file &#039;&#039;&#039;theme/demystified/settings.php&#039;&#039;&#039; and open it in your favourite editor so its ready to go.&lt;br /&gt;
&lt;br /&gt;
Before we start adding code however lets just remember the settings that we want to create:&lt;br /&gt;
* change the background colour (CSS).&lt;br /&gt;
* set the path to an image that we will use as a logo on all pages (Layout files).&lt;br /&gt;
* override the width of the block regions (CSS).&lt;br /&gt;
* allow a note to be added to the footer of all pages (Layout files).&lt;br /&gt;
* allow custom CSS to be written to do anything the user wants. (CSS)&lt;br /&gt;
&lt;br /&gt;
Alright.&lt;br /&gt;
&lt;br /&gt;
Now thinking about this the first setting is as basic as it gets, all we need is a text box that the user can type a colour into.&lt;br /&gt;
&lt;br /&gt;
The second is to allow a logo to be used in the header of each page. What we want here is a path but should it be a physical path e.g. C:/path/to/image.png or should it be a web path e.g. &amp;lt;nowiki&amp;gt;http://mysite.com/path/to/image.png&amp;lt;/nowiki&amp;gt;?&lt;br /&gt;
For the purpose of this tutorial I am going to go with a web path because it is going to be easier to code and will hopefully be a little easier to understand to begin with.&lt;br /&gt;
&lt;br /&gt;
The third setting is a little more complex. For this I want a drop down box with some specific widths that the administrator can select.&lt;br /&gt;
&lt;br /&gt;
The forth and the fifth settings are both pretty straight forward, there we want a textarea into which the user can enter what ever they want and we will do something useful with it.&lt;br /&gt;
&lt;br /&gt;
Now that we have an understanding about the settings we wish to define pull up your editor and lets start coding....&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Settings for the demystified theme&lt;br /&gt;
 */&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die;&lt;br /&gt;
&lt;br /&gt;
if ($ADMIN-&amp;gt;fulltree) {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is the first bit of code we must enter, the first line is of course just the opening php tag, secondly we have a comment that describes this file, and then we get create a new &#039;&#039;&#039;admin_settingspage object&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This admin_settingspage object that we have just created is a representation of our settings page and is the what we add our new settings to. When creating it we give it two arguments, first the name of the page which is in this case &#039;&#039;&#039;theme_&#039;&#039;themename&#039;&#039;&#039;&#039;&#039; and the title for the page which we get with the get_string method.&lt;br /&gt;
&lt;br /&gt;
At the moment I&#039;m not going to worry about adding the string, we will get to that later once we have defined all of our settings.&lt;br /&gt;
&lt;br /&gt;
====Background colour====&lt;br /&gt;
&lt;br /&gt;
With the page now created lets add our first setting: Background colour.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Background colour setting&lt;br /&gt;
$name = &#039;theme_demystified/backgroundcolor&#039;;&lt;br /&gt;
$title = get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = &#039;#DDD&#039;;&lt;br /&gt;
$setting = new admin_setting_configtext($name, $title, $description, $default, PARAM_CLEAN, 12);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Thankfully this isn&#039;t as difficult as it initially looks.&lt;br /&gt;
&lt;br /&gt;
The first line of code is creating a variable for the name of the background colour setting. In this case it is &#039;&#039;&#039;theme_demystified/backgroundcolor&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
The name is very important, for the setting to be usable we have to follow a strict naming convention. &#039;&#039;&#039;theme_&#039;&#039;themename&#039;&#039;/&#039;&#039;settingname&#039;&#039;&#039;&#039;&#039; where &#039;&#039;&#039;&#039;&#039;themename&#039;&#039;&#039;&#039;&#039; is the name of the theme the setting belongs to and &#039;&#039;&#039;&#039;&#039;settingname&#039;&#039;&#039;&#039;&#039; is the name for the setting by which we will use it.&lt;br /&gt;
&lt;br /&gt;
The second line of code creates a variable that contains the title of the setting. This is what the user sees to the right of the setting on the settings page and should be a short description of the setting. Here we are again using the &#039;&#039;get_string&#039;&#039; method so we will need to remember to add that string later on.&lt;br /&gt;
&lt;br /&gt;
The third line of code sets the description. This should describe what the setting does or how it works and again we will use the get_string method.&lt;br /&gt;
&lt;br /&gt;
The fourth line creates a variable that will be used as the default value for the setting. Because this setting is a colour we want an HTML colour to be the default value.&lt;br /&gt;
&lt;br /&gt;
The fifth line is where we put it all together. Here we create a new &#039;&#039;&#039;admin_setting_configtext&#039;&#039;&#039; object. This object will represent the background colour setting.&lt;br /&gt;
&lt;br /&gt;
When we create it we need to give it 6 different things.&lt;br /&gt;
# The name of the setting. In this case we have a variable &#039;&#039;&#039;$name&#039;&#039;&#039;.&lt;br /&gt;
# The title for this setting. We used the variable &#039;&#039;&#039;$title&#039;&#039;&#039;.&lt;br /&gt;
# The description of the setting &#039;&#039;&#039;$description&#039;&#039;&#039;.&lt;br /&gt;
# The default value for the setting. &#039;&#039;&#039;$default&#039;&#039;&#039; is the variable this.&lt;br /&gt;
# The type of value we want the user to enter. For this we have used PARAM_CLEAN which tells Moodle to get rid of any nasties from what the user enters.&lt;br /&gt;
# The size of the field. In our case 12 characters will be plenty.&lt;br /&gt;
&lt;br /&gt;
The sixth and final line of code adds our newly created setting to the administration page we created earlier.&lt;br /&gt;
&lt;br /&gt;
That is it we have successfully created and added our first setting, however there are several more to settings to do, and there are a couple of important things that you need to be aware of before we move on.&lt;br /&gt;
&lt;br /&gt;
First: There are several different types of settings that you can create and add to a page, and each one may differ in what they need you to give them. In this case it was name, title, description, default, type, and size. However other settings will likely require different things. Smart editors like Netbeans or Eclipse can tell you what is required, otherwise you will need to research it.&lt;br /&gt;
&lt;br /&gt;
Second: Normally settings are declared on one line as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$setting-&amp;gt;add(new admin_setting_configtext(&#039;theme_demystified/backgroundcolor&#039;, get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;), get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;), &#039;#DDD&#039;, PARAM_CLEAN, 12));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
While this is structurally identical as all we have done is move everything onto one line and do away with the variables it is a little harder to read when you are learning all of this.&lt;br /&gt;
&lt;br /&gt;
====The logo file====&lt;br /&gt;
Time to create the second setting that will allow the user to enter a URL to an image they wish to use as the logo on their site.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Logo file setting&lt;br /&gt;
$name = &#039;theme_demystified/logo&#039;;&lt;br /&gt;
$title = get_string(&#039;logo&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;logodesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtext($name, $title, $description, &#039;&#039;, PARAM_URL);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The first thing that you will notice about this setting that it is very similar to the first setting, in fact all we have changed is the name, title, description, and default value. We have however changed the value type from PARAM_CLEAN to PARAM_URL, this makes sure the user enters a URL. You will also notice that for this one we don&#039;t set a size for the field as we have no idea how long the URL will be.&lt;br /&gt;
&lt;br /&gt;
====Block region width====&lt;br /&gt;
The third setting should allow the user to set a width for the block regions that will be used as columns.&lt;br /&gt;
&lt;br /&gt;
For this setting I want to do something a little different from the previous two, here I want to use a select box so that the user selects a width for the column from a list I provide.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Block region width&lt;br /&gt;
$name = &#039;theme_demystified/regionwidth&#039;;&lt;br /&gt;
$title = get_string(&#039;regionwidth&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;regionwidthdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = 200;&lt;br /&gt;
$choices = array(150=&amp;gt;&#039;150px&#039;, 170=&amp;gt;&#039;170px&#039;, 200=&amp;gt;&#039;200px&#039;, 240=&amp;gt;&#039;240px&#039;, 290=&amp;gt;&#039;290px&#039;, 350=&amp;gt;&#039;350px&#039;, 420=&amp;gt;&#039;420px&#039;);&lt;br /&gt;
$setting = new admin_setting_configselect($name, $title, $description, $default, $choices);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
So looking at the code: The first four lines you will recognise. $name, $title, $description, and $default are all being set.&lt;br /&gt;
&lt;br /&gt;
The fifth line of code however introduces something new. Of course in order to have a select box we have to have options, in this case we have an array of options stored in the variable $choices.&lt;br /&gt;
&lt;br /&gt;
The array of options is constructed of a collection of &#039;&#039;&#039;&#039;&#039;value&#039;&#039;&#039; =&amp;gt; &#039;&#039;&#039;label&#039;&#039;&#039;&#039;&#039; pairs. Notice how we don&#039;t add &#039;&#039;&#039;px&#039;&#039;&#039; to the value. This is is very intentional as later on I need to do a little bit of math with that value so we need it to be a number.&lt;br /&gt;
&lt;br /&gt;
The lines after should look familiar again, the only difference being that instead of a &#039;&#039;admin_setting_configtext&#039;&#039; setting we have created a &#039;&#039;admin_setting_configselect&#039;&#039; for which we must give the choices for the select box as the fifth argument.&lt;br /&gt;
&lt;br /&gt;
Woohoo, we&#039;ve just created our first select box setting.&lt;br /&gt;
&lt;br /&gt;
====Foot note====&lt;br /&gt;
Now to create the foot note setting. Here we want the user to be able to enter some arbitrary text that will be used in the footer of the page. For this I want the user to be able to enter some HTML so I will create an editor setting.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Foot note setting&lt;br /&gt;
$name = &#039;theme_demystified/footnote&#039;;&lt;br /&gt;
$title = get_string(&#039;footnote&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;footnotedesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_confightmleditor($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
How simple is that!&lt;br /&gt;
&lt;br /&gt;
It is just about identical to the first two settings except that for this we have created a &#039;&#039;admin_setting_confightmleditor&#039;&#039; setting rather than a text setting.&lt;br /&gt;
&lt;br /&gt;
Note: You can also set the columns and rows for the editor setting using the fifth and sixth arguments.&lt;br /&gt;
&lt;br /&gt;
====Custom CSS====&lt;br /&gt;
The final setting is to allow the user to add some custom CSS to the theme that will be used on every page. I want this to be a plain textarea into which the user can enter CSS.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Custom CSS file&lt;br /&gt;
$name = &#039;theme_demystified/customcss&#039;;&lt;br /&gt;
$title = get_string(&#039;customcss&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;customcssdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtextarea($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Just like the editor or text settings. It&#039;s getting very easy now!&lt;br /&gt;
&lt;br /&gt;
====Finishing settings.php====&lt;br /&gt;
With all of our settings defined and added to our page that we created right at the beginning it is time to finish it all off.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Add our page to the structure of the admin tree&lt;br /&gt;
$ADMIN-&amp;gt;add(&#039;themes&#039;, $temp);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The above line of code is the final line for the page. It is adding the page that we have created &#039;&#039;&#039;$temp&#039;&#039;&#039; to the admin tree structure. In this case it is adding it to the themes branch.&lt;br /&gt;
&lt;br /&gt;
The following is the completed source for our settings.php ..... for your copy/paste pleasure.&lt;br /&gt;
&amp;lt;div style=&#039;height:300px;overflow:auto;&#039;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Settings for the demystified theme&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
// Create our admin page&lt;br /&gt;
$temp = new admin_settingpage(&#039;theme_demystified&#039;, get_string(&#039;configtitle&#039;,&#039;theme_demystified&#039;));&lt;br /&gt;
&lt;br /&gt;
// Background colour setting&lt;br /&gt;
$name = &#039;theme_demystified/backgroundcolor&#039;;&lt;br /&gt;
$title = get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = &#039;#DDD&#039;;&lt;br /&gt;
$setting = new admin_setting_configtext($name, $title, $description, $default, PARAM_CLEAN, 12);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
// Logo file setting&lt;br /&gt;
$name = &#039;theme_demystified/logo&#039;;&lt;br /&gt;
$title = get_string(&#039;logo&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;logodesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtext($name, $title, $description, &#039;&#039;, PARAM_URL);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
// Block region width&lt;br /&gt;
$name = &#039;theme_demystified/regionwidth&#039;;&lt;br /&gt;
$title = get_string(&#039;regionwidth&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;regionwidthdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = 200;&lt;br /&gt;
$choices = array(150=&amp;gt;&#039;150px&#039;, 170=&amp;gt;&#039;170px&#039;, 200=&amp;gt;&#039;200px&#039;, 240=&amp;gt;&#039;240px&#039;, 290=&amp;gt;&#039;290px&#039;, 350=&amp;gt;&#039;350px&#039;, 420=&amp;gt;&#039;420px&#039;);&lt;br /&gt;
$setting = new admin_setting_configselect($name, $title, $description, $default, $choices);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
// Foot note setting&lt;br /&gt;
$name = &#039;theme_demystified/footnote&#039;;&lt;br /&gt;
$title = get_string(&#039;footnote&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;footnotedesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_confightmleditor($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
// Custom CSS file&lt;br /&gt;
$name = &#039;theme_demystified/customcss&#039;;&lt;br /&gt;
$title = get_string(&#039;customcss&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;customcssdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtextarea($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
// Add our page to the structure of the admin tree&lt;br /&gt;
$ADMIN-&amp;gt;add(&#039;themes&#039;, $temp);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Creating a language file and adding our strings===&lt;br /&gt;
As I&#039;m sure none of you have forgotten, throughout the creation of the our settings.php page, we used a lot of strings that I mentioned we would set later on. Well now is the time to set those strings.&lt;br /&gt;
&lt;br /&gt;
First up create the following directories and file for our language strings:&lt;br /&gt;
* Directory &#039;&#039;&#039;theme/demystified/lang&#039;&#039;&#039;&lt;br /&gt;
* Directory &#039;&#039;&#039;theme/demystified/lang/en&#039;&#039;&#039;&lt;br /&gt;
* File &#039;&#039;&#039;theme/demystified/lang/theme_demystified.php&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
What we have created here is the required structure for Moodle to start looking for language strings.&lt;br /&gt;
&lt;br /&gt;
First Moodle locates the lang directory, once found it looks within that directory for another directory that uses the character code for the language the user has selected, by default this is &#039;&#039;&#039;en&#039;&#039;&#039; for English. Once that is found it looks for the appropriate language file, in this case &#039;&#039;&#039;theme_demystified.php&#039;&#039;&#039; from which it will load all language strings for our theme.&lt;br /&gt;
&lt;br /&gt;
If English isn&#039;t your chosen language simply replace the &#039;&#039;en&#039;&#039; directory with one that uses your chosen languages character code (two letters).&lt;br /&gt;
&lt;br /&gt;
We can now add our language strings to &#039;&#039;&#039;theme/demystified/lang/theme_demystified.php&#039;&#039;&#039;. Copy and paste the following lines of PHP into this file.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This file contains the strings used by the demystified theme&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
$string[&#039;backgroundcolor&#039;] = &#039;Background colour&#039;;&lt;br /&gt;
$string[&#039;backgroundcolordesc&#039;] = &#039;This sets the background colour for the theme.&#039;;&lt;br /&gt;
$string[&#039;configtitle&#039;] = &#039;Demystified theme&#039;;&lt;br /&gt;
$string[&#039;customcss&#039;] = &#039;Custom CSS&#039;;&lt;br /&gt;
$string[&#039;customcssdesc&#039;] = &#039;Any CSS you enter here will be added to every page allowing your to easily customise this theme.&#039;;&lt;br /&gt;
$string[&#039;footnote&#039;] = &#039;Footnote&#039;;&lt;br /&gt;
$string[&#039;footnotedesc&#039;] = &#039;The content from this textarea will be displayed in the footer of every page.&#039;;&lt;br /&gt;
$string[&#039;logo&#039;] = &#039;Logo&#039;;&lt;br /&gt;
$string[&#039;logodesc&#039;] = &#039;Enter the URL to an image to use as the logo for this site. Should be http://www.yoursite.com/path/to/logo.png&#039;;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;Demystified&#039;;&lt;br /&gt;
$string[&#039;regionwidth&#039;] = &#039;Column width&#039;;&lt;br /&gt;
$string[&#039;regionwidthdesc&#039;] = &#039;This sets the width of the two block regions that form the left and right columns.&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above lines of code I have added an entry for each language string we used within &#039;&#039;settings.php&#039;&#039;. When adding language strings like this make sure you use single quotes and try to keep things alphabetical - it helps greatly when managing strings.&lt;br /&gt;
&lt;br /&gt;
Now when we view the settings page there will not be any errors or strings missing.&lt;br /&gt;
&lt;br /&gt;
===Having a look at what we have created===&lt;br /&gt;
Now that we have created our settings page (settings.php) and added all of the language strings it is time to have a look at things in your browser.&lt;br /&gt;
&lt;br /&gt;
Open your browser and enter the URL to your site. When you arrive at your site login as an administrator.&lt;br /&gt;
&lt;br /&gt;
If you are not redirected to view the new settings change your URL to &amp;lt;nowiki&amp;gt;http://www.yoursite.com/admin/&amp;lt;/nowiki&amp;gt; and your will see a screen to set the new theme settings we have just created. This lets us know that everything has worked correctly.&lt;br /&gt;
&lt;br /&gt;
At any point now you are able to log in as administrator and within the settings block browse to &#039;&#039;&#039;Site administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; Demystified theme&#039;&#039;&#039; to change those settings.&lt;br /&gt;
&lt;br /&gt;
The screenshot below shows you what you should see at this point:&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.03.png|715px|thumb|left|The settings page we just created]]&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using the settings in CSS==&lt;br /&gt;
With the settings page now created and operational it is time to make use of our new settings. The settings that we want to use within our CSS is as follows:&lt;br /&gt;
&lt;br /&gt;
; backgroundcolor : Will be used to set the background colour in CSS.&lt;br /&gt;
; regionwidth : Will be the width of the column for CSS.&lt;br /&gt;
; customcss : Will be some custom CSS to add to our stylesheet.&lt;br /&gt;
&lt;br /&gt;
At this point those names are the names we used for our setting with the slash and everything before it having been removed.&lt;br /&gt;
&lt;br /&gt;
Before we start tearing into some code it is important that we have a look at what we are going to do and how we are going to go about it.&lt;br /&gt;
&lt;br /&gt;
===How it all works within Moodle===&lt;br /&gt;
The first thing to understand is that while Moodle allows you to create a settings page and automates it inclusion and management right into the administration interfaces there is no smart equivalent for using the settings. This is simply because there is no way to predict how people will want to use the settings.&lt;br /&gt;
&lt;br /&gt;
However don&#039;t think of this as a disadvantage, in fact it is quite the contrary. Although we can&#039;t just &#039;&#039;use&#039;&#039; our settings we can take full control over how and where we use them. It means it will take a little more code but in the end that will work to our advantage as we can do anything we want.&lt;br /&gt;
&lt;br /&gt;
Moodle does help us out a little but not in an obvious way. The first thing that Moodle does is look for a config variable &#039;&#039;&#039;csspostprocess&#039;&#039;&#039; that should be the name of a function which we want called to make any changes to the CSS after it has been prepared.&lt;br /&gt;
&lt;br /&gt;
The second thing Moodle does is include a lib.php from the theme&#039;s directory if one exists (also for the themes the current theme extends.) which ensures that as long as we write our code within &#039;&#039;&#039;theme/demystified/lib.php&#039;&#039;&#039; it will be included and ready to be used.&lt;br /&gt;
&lt;br /&gt;
The third and final thing Moodle does that will help us out here is ensure that by the time any of code is ready to execute the settings have been prepared and are ready to be used within a theme config object which is passed into our &#039;&#039;csspostprocess&#039;&#039; function.&lt;br /&gt;
&lt;br /&gt;
===Our plan===&lt;br /&gt;
As you have already probably guessed we will need to create a function to make the changes to the CSS that we want. We will then set the theme config option &#039;&#039;&#039;$THEME-&amp;gt;csspostprocess&#039;&#039;&#039; to the name of our function.&lt;br /&gt;
&lt;br /&gt;
By doing this when Moodle builds the CSS file it will call our function afterwards with the CSS and the theme object that contains our setting.&lt;br /&gt;
&lt;br /&gt;
Now we know that we will use the &#039;&#039;csspostprocess&#039;&#039; function but how are we going to change the CSS, we could get the function to add CSS, or we could get the function to replace something within the CSS. My personal preference is to replace something within the CSS, just like what is happening with images. If you want to use an image within CSS you would write &amp;lt;nowiki&amp;gt;[[pix:theme|imagename]]&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For settings I am going to use &amp;lt;nowiki&amp;gt;[[setting:settingname]]&amp;lt;/nowiki&amp;gt;, this way it looks a bit like something you are already familiar with.&lt;br /&gt;
&lt;br /&gt;
What we need to decide upon next is the best way in which to replace our settings tag with the settings that the user has set.&lt;br /&gt;
&lt;br /&gt;
There are two immediate options available to us:&lt;br /&gt;
# Make the &#039;&#039;csspostprocess&#039;&#039; function do all the work.&lt;br /&gt;
# Make the &#039;&#039;csspostprocess&#039;&#039; function call a separate function for each setting.&lt;br /&gt;
Solution 1 might sound like the simplest however it is going to result in a &#039;&#039;&#039;VERY&#039;&#039;&#039; complex function. Remember the user might have left settings blank or entered something that wouldn&#039;t be valid so we would need to make the sure there is some validation and a good default.&lt;br /&gt;
Because of this I think that solution 2 is the better solution.&lt;br /&gt;
&lt;br /&gt;
So we are going to need a &#039;&#039;csspostprocess&#039;&#039; function and then a function for each of the three settings we have that will do the replacements.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// This is our css post process function&lt;br /&gt;
function demystified_process_css($css, $theme) {};&lt;br /&gt;
// This replaces [[setting:backgroundcolor]] with the background colour&lt;br /&gt;
function demystified_set_backgroundcolor($css, $backgroundcolor) {};&lt;br /&gt;
// This replaces [[setting:regionwidth]] with the correct region width&lt;br /&gt;
function demystified_set_regionwidth() {$css, $regionwidth};&lt;br /&gt;
// This replaces [[setting:customcss]] with the custom css&lt;br /&gt;
function demystified_set_customcss() {$css, $customcss};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you should note about the above functions is that they all start with the theme&#039;s name. This is required to ensure that the functions are named uniquely as it is VERY unlikely that someone has already created these functions.&lt;br /&gt;
&lt;br /&gt;
So with our plan set out lets start writing the code.&lt;br /&gt;
&lt;br /&gt;
===Writing the code===&lt;br /&gt;
The very first thing that we need to do is create a lib.php for our theme into which our css processing functions are going to go. So please at this point create &#039;&#039;&#039;theme/demystified/lib.php&#039;&#039;&#039; and open it in your editor ready to go.&lt;br /&gt;
&lt;br /&gt;
The first bit of code we have to write is the function that will be called by Moodle to do the processing &#039;&#039;&#039;demystified_process_css&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
Before we start out please remember that the wonderful thing about coding is that there is any number of solutions to a problem. The solutions that you are seeing here in this tutorial are solutions that I have come up with to meet fulfil the needs of the tutorial without being so complex that they are hard to understand. This probably isn&#039;t how I would go about it normally but this is a little easier to understand for those who aren&#039;t overly familiar with PHP and object orientation.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_process_css====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function demystified_process_css($css, $theme) {&lt;br /&gt;
&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;backgroundcolor)) {&lt;br /&gt;
        $backgroundcolor = $theme-&amp;gt;settings-&amp;gt;backgroundcolor;&lt;br /&gt;
    } else {&lt;br /&gt;
        $backgroundcolor = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_backgroundcolor($css, $backgroundcolor);&lt;br /&gt;
&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;regionwidth)) {&lt;br /&gt;
        $regionwidth = $theme-&amp;gt;settings-&amp;gt;regionwidth;&lt;br /&gt;
    } else {&lt;br /&gt;
        $regionwidth = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_regionwidth($css, $regionwidth);&lt;br /&gt;
&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;customcss)) {&lt;br /&gt;
        $customcss = $theme-&amp;gt;settings-&amp;gt;customcss;&lt;br /&gt;
    } else {&lt;br /&gt;
        $customcss = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_customcss($css, $customcss);&lt;br /&gt;
&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So lets look at the things that make up this function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function demystified_process_css($css, $theme) {&lt;br /&gt;
    //.....&lt;br /&gt;
    return $css&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This of course is the function declaration. &lt;br /&gt;
&lt;br /&gt;
The function gets given two variables, the first &#039;&#039;&#039;$css&#039;&#039;&#039; is a pile of CSS as one big string, and the second is the theme object &#039;&#039;&#039;$theme&#039;&#039;&#039; that contains all of the configuration, options, and settings for our theme.&lt;br /&gt;
&lt;br /&gt;
It then returns the &#039;&#039;$css&#039;&#039; variable, essentially returning the modified CSS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    //...&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;backgroundcolor)) {&lt;br /&gt;
        $backgroundcolor = $theme-&amp;gt;settings-&amp;gt;backgroundcolor;&lt;br /&gt;
    } else {&lt;br /&gt;
        $backgroundcolor = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_backgroundcolor($css, $backgroundcolor);&lt;br /&gt;
    //...&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are processing our first setting &#039;&#039;backgroundcolor&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
The first thing that we need to do is check whether it has been set and whether it has a value. If it has then we store that value in &#039;&#039;&#039;$backgroundcolor&#039;&#039;&#039;. It is doesn&#039;t have a value then we set &#039;&#039;$backgroundcolor&#039;&#039; to null. This ensures that &#039;&#039;$backgroundcolor&#039;&#039; is set because if it isn&#039;t then you are going to get a notice (if you have debugging on).&lt;br /&gt;
&lt;br /&gt;
The final line of this block calls the function &#039;&#039;&#039;demystified_set_backgroundcolor&#039;&#039;&#039;. We haven&#039;t written this function yet but we will shortly. When we call it we give it the &#039;&#039;$css&#039;&#039; variable that contains all of the CSS and we give it the background colour variable &#039;&#039;$backgroundcolor&#039;&#039;. Once this function is finished it returns the &#039;&#039;$css&#039;&#039; variable with all of the changes made much like how our css processing function works.&lt;br /&gt;
&lt;br /&gt;
What you should also note about this code is this:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$theme-&amp;gt;settings-&amp;gt;backgroundcolor&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
As mentioned earlier &#039;&#039;$theme&#039;&#039; is an object that contains all of the configuration and settings for our theme. The &#039;&#039;$theme&#039;&#039; object has a $settings property which contains all of the settings for our theme, and finally the settings property contains a variable backgroundcolor that is the value the user entered for that setting. That is how we get a settings value.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($theme-&amp;gt;settings-&amp;gt;regionwidth)) {&lt;br /&gt;
    $regionwidth = $theme-&amp;gt;settings-&amp;gt;regionwidth;&lt;br /&gt;
} else {&lt;br /&gt;
    $regionwidth = null;&lt;br /&gt;
}&lt;br /&gt;
$css = demystified_set_regionwidth($css, $regionwidth);&lt;br /&gt;
&lt;br /&gt;
if (!empty($theme-&amp;gt;settings-&amp;gt;customcss)) {&lt;br /&gt;
    $customcss = $theme-&amp;gt;settings-&amp;gt;customcss;&lt;br /&gt;
} else {&lt;br /&gt;
    $customcss = null;&lt;br /&gt;
}&lt;br /&gt;
$css = demystified_set_customcss($css, $customcss);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These two routines are nearly identical to the routine above. For both the regionwidth and the customcss we make sure it has a value and then store it in a variable. We then call the relevant function to make the changes for that setting.&lt;br /&gt;
&lt;br /&gt;
Now that we have the general processing function it is time to write the three functions we have used but not written, &#039;&#039;demystified_set_backgroundcolor&#039;&#039;, &#039;&#039;demystified_set_regionwidth&#039;&#039;, &#039;&#039;demystified_set_customcss&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_set_backgroundcolor====&lt;br /&gt;
&lt;br /&gt;
First up demystified_set_backgroundcolor.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Sets the background colour variable in CSS&lt;br /&gt;
 *&lt;br /&gt;
 * @param string $css&lt;br /&gt;
 * @param mixed $backgroundcolor&lt;br /&gt;
 * @return string&lt;br /&gt;
 */&lt;br /&gt;
function demystified_set_backgroundcolor($css, $backgroundcolor) {&lt;br /&gt;
    $tag = &#039;[[setting:backgroundcolor]]&#039;;&lt;br /&gt;
    $replacement = $backgroundcolor;&lt;br /&gt;
    if (is_null($replacement)) {&lt;br /&gt;
        $replacement = &#039;#DDDDDD&#039;;&lt;br /&gt;
    }&lt;br /&gt;
    $css = str_replace($tag, $replacement, $css);&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ok so what is happening here?&lt;br /&gt;
&lt;br /&gt;
First we need a variable &#039;&#039;&#039;$tag&#039;&#039;&#039; that contains the tag we are going to replace. As mentioned earlier we are going to use tags that look like the image tags you are already familiar with &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:settingname]]&amp;lt;/nowiki&amp;gt;&#039;&#039;, in this case &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:backgroundcolor]]&amp;lt;/nowiki&amp;gt;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Next I am going to create a variable called &#039;&#039;&#039;$replacement&#039;&#039;&#039; into which I put &#039;&#039;&#039;$backgroundcolor&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;IF&#039;&#039;&#039; statement that comes next checks &#039;&#039;$replacement&#039;&#039; to make sure it is not null. If it is then we need to set it to a default value. In this case I have used &#039;&#039;#DDD&#039;&#039; as that was the default for the settings.&lt;br /&gt;
&lt;br /&gt;
The line after the IF statement puts it all together. The &#039;&#039;str_replace&#039;&#039; function that we are calling takes three arguments in this order:&lt;br /&gt;
# The text to search for.&lt;br /&gt;
# The text to replace it with.&lt;br /&gt;
# The text to do the replacement in.&lt;br /&gt;
It then returns the text with all of the replacements made. So in this case we are replacing the tag with the background colour and it is returning the changed CSS.&lt;br /&gt;
&lt;br /&gt;
The final thing is to return the &#039;&#039;$css&#039;&#039; variable which now contains the correct background colour.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_set_regionwidth====&lt;br /&gt;
&lt;br /&gt;
Next we have the demystified_set_regionwidth function.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Sets the region width variable in CSS&lt;br /&gt;
 *&lt;br /&gt;
 * @param string $css&lt;br /&gt;
 * @param mixed $regionwidth&lt;br /&gt;
 * @return string&lt;br /&gt;
 */&lt;br /&gt;
function demystified_set_regionwidth($css, $regionwidth) {&lt;br /&gt;
    $tag = &#039;[[setting:regionwidth]]&#039;;&lt;br /&gt;
    $doubletag = &#039;[[setting:regionwidthdouble]]&#039;;&lt;br /&gt;
    $replacement = $regionwidth;&lt;br /&gt;
    if (is_null($replacement)) {&lt;br /&gt;
        $replacement = 200;&lt;br /&gt;
    }&lt;br /&gt;
    $css = str_replace($tag, $replacement.&#039;px&#039;, $css);&lt;br /&gt;
    $css = str_replace($doubletag, ($replacement*2).&#039;px&#039;, $css);&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function is very similar to the above function however there is one key thing we are doing different. We are doing two replacements.&lt;br /&gt;
&lt;br /&gt;
# The first replacement is for the width that the user selected. In this case I am replacing the tag &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt;&#039;&#039; with the width.&lt;br /&gt;
# The second replacement is for the width x 2. This is because the page layout requires that the width be doubled for some of the CSS. Here I will replace &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidthdouble]]&amp;lt;/nowiki&amp;gt;&#039;&#039; with the doubled width.&lt;br /&gt;
&lt;br /&gt;
Remember because it is still just a number we need to add &#039;&#039;&#039;px&#039;&#039;&#039; to the end of each before we do the replacement.&lt;br /&gt;
&lt;br /&gt;
So the overall process of this function is:&lt;br /&gt;
# Define the two tags as &#039;&#039;&#039;$tag&#039;&#039;&#039; and &#039;&#039;&#039;$doubletag&#039;&#039;&#039;.&lt;br /&gt;
# Make &#039;&#039;&#039;$replacement&#039;&#039;&#039; the region width &#039;&#039;$regionwidth&#039;&#039;.&lt;br /&gt;
# Set &#039;&#039;$replacement&#039;&#039; to a default value of 200 is it is null.&lt;br /&gt;
# Replace &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; with the width.&lt;br /&gt;
# Replace &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidthdouble]]&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; with the width x 2.&lt;br /&gt;
# Return the changed CSS.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_set_customcss====&lt;br /&gt;
&lt;br /&gt;
The final function that we need to write is the demystified_set_customcss function.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Sets the custom css variable in CSS&lt;br /&gt;
 *&lt;br /&gt;
 * @param string $css&lt;br /&gt;
 * @param mixed $customcss&lt;br /&gt;
 * @return string&lt;br /&gt;
 */&lt;br /&gt;
function demystified_set_customcss($css, $customcss) {&lt;br /&gt;
    $tag = &#039;[[setting:customcss]]&#039;;&lt;br /&gt;
    $replacement = $customcss;&lt;br /&gt;
    if (is_null($replacement)) {&lt;br /&gt;
        $replacement = &#039;&#039;;&lt;br /&gt;
    }&lt;br /&gt;
    $css = str_replace($tag, $replacement, $css);&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function is just like the first function. I&#039;m going to let you work it out on your own.&lt;br /&gt;
&lt;br /&gt;
And that is it no more PHP... Hallelujah I can hear you yelling. The final thing we need to do is tell our theme about the functions we have written and put the settings tags into the CSS.&lt;br /&gt;
&lt;br /&gt;
===Finishing it all off===&lt;br /&gt;
&lt;br /&gt;
So there are two things we have to do in order to complete this section and have our the settings page implemented and our settings being used.&lt;br /&gt;
&lt;br /&gt;
First we need to tell our theme that we want to use the function &#039;&#039;demystified_process_css&#039;&#039; as the &#039;&#039;csspostprocess&#039;&#039; function. This is done very simply by adding the following line of PHP to the bottom of our theme&#039;s config.php file &#039;&#039;&#039;theme/demystified/config.php&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;csspostprocess = &#039;demystified_process_css&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done the only thing left is to add the settings tag into the CSS. Remember those settings tags are:&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:backgroundcolor]]&amp;lt;/nowiki&amp;gt; : We need to add this where ever we want the background colour setting to be used.&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt; : We need to add this where ever we want to set the width of the block regions.&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:regionwidthdouble]]&amp;lt;/nowiki&amp;gt; : We need to add this where ever we want to set the doubled width of the block regions.&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:customcss]]&amp;lt;/nowiki&amp;gt; : We need to add this to the bottom of the CSS file that we want the custom CSS added to.&lt;br /&gt;
&lt;br /&gt;
So lets make those changes in CSS now, open up your &#039;&#039;core.css&#039;&#039; file and replace the CSS with the CSS below:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/** Background color is a setting **/&lt;br /&gt;
html {background-color:[[setting:backgroundcolor]];}&lt;br /&gt;
body {margin:30px;padding:0;border:1px solid #333;border-width:0 10px 0 10px;background-color:#333;}&lt;br /&gt;
body #page {background-color:#FFF;position:relative;top:-10px;}&lt;br /&gt;
.block .header {background-image:none;background-color:#0C5CAC;border:1px solid #0C5CAC;color:#FFF;}&lt;br /&gt;
.block {border-color:#4BA7FF;background-color:#DDEEFF;}&lt;br /&gt;
.block .content {background-color:#F1F8FF;}&lt;br /&gt;
a:link,&lt;br /&gt;
a:visited {color:#0C5CAC;}&lt;br /&gt;
a:hover {color:#C77500;}&lt;br /&gt;
#page #page-header {background-color:#0C5CAC;margin:0;padding:0;width:100%;color:#fff;}&lt;br /&gt;
#page #page-header a:link, #page #page-header a:visited {color:#FFAC02}&lt;br /&gt;
#page #page-header .navbar, #page #page-header .navbar a:link, #page #page-header .navbar a:visited {color:#0C5CAC;}&lt;br /&gt;
/** Override the region width **/&lt;br /&gt;
#page-content #region-main-box {left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidthdouble]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-pre {width:[[setting:regionwidth]];left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-post {width:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidthdouble]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
/** Custom CSS **/&lt;br /&gt;
[[setting:customcss]]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will notice that &amp;lt;nowiki&amp;gt;[[setting:backgroundcolor]]&amp;lt;/nowiki&amp;gt; has been used for the html tags background colour:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
html {background-color:[[setting:backgroundcolor]];}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have also set the width of the block regions by adding &amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt; as the width for region-pre and region-post as shown below:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
#page-content #region-main-box {left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidthdouble]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-pre {width:[[setting:regionwidth]];left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-post {width:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidthdouble]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
You&#039;ll notice here that we have to set several different widths and margins using the regionwidth setting and make use of the special regionwidthdouble setting that we added.&lt;br /&gt;
&lt;br /&gt;
The final thing that we did was add the &amp;lt;nowiki&amp;gt;[[setting:customcss]]&amp;lt;/nowiki&amp;gt; to the bottom of the file to ensure that the custom CSS comes last (and therefore can override all other CSS).&lt;br /&gt;
&lt;br /&gt;
And with that we are finished. The screenshot below shows how this now looks in the browser if I set the background colour setting to &#039;&#039;&#039;&amp;lt;span style=&#039;color:#FFA800;&#039;&amp;gt;#FFA800&amp;lt;/span&amp;gt;&#039;&#039;&#039; and made the column width 240px;&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.04.png|715px|thumb|left|Our settings in action]]&amp;lt;br style=&amp;quot;clear:both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using the settings within our layout files==&lt;br /&gt;
Now that we have utilised the first three settings within our theme&#039;s CSS file it is time to implement the other two settings within the layout files so that they are written directly into the page.&lt;br /&gt;
&lt;br /&gt;
You&#039;ll be glad to know this is no where near as difficult as utilising settings within a CSS file although it still does require a little bit of PHP.&lt;br /&gt;
&lt;br /&gt;
First up is the logo setting. Into this setting the user is able to enter the URL to an image to use as the logo for the site. In my case I want this to be just a background logo on top of which I want to position the page header.&lt;br /&gt;
&lt;br /&gt;
Before I start there is one thing I need to do however and that is create a default logo background that gets shown if the user hasn&#039;t set a specific logo file. To do this I simply created an image &#039;&#039;&#039;logo.jpg&#039;&#039;&#039; and put it into a pix directory within the demystified theme. You should end up with &#039;&#039;&#039;theme/demystified/pix/logo.jpg&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Next open up the front-page layout file &#039;&#039;theme/demystified/layout/frontpage.php&#039;&#039;. At the top of the file is the PHP that checks what blocks regions the page has and a bit of other stuff. Well right below the existing bit of PHP we want to add the following code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;logo)) {&lt;br /&gt;
    $logourl = $PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;logo;&lt;br /&gt;
} else {&lt;br /&gt;
    $logourl = $OUTPUT-&amp;gt;pix_url(&#039;logo&#039;, &#039;theme&#039;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
What we are doing here is creating a variable called $logourl that will contain the URL to a logo file that was either entered by the user or if they left it blank is that of our default logo file.&lt;br /&gt;
&lt;br /&gt;
There are two things that you should notice about this. First the logo setting can be retrieved through &#039;&#039;&#039;$PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;logo&#039;&#039;&#039; and second we get the default logo url by calling &#039;&#039;&#039;$OUTPUT-&amp;gt;pix_url(&#039;logo&#039;, &#039;theme&#039;)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Now that we have the logo URL we are going to use we need to add an image to the header section of the page as shown below:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;page-header&amp;quot; class=&amp;quot;clearfix&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;img class=&amp;quot;sitelogo&amp;quot; src=&amp;quot;&amp;lt;?php echo $logourl;?&amp;gt;&amp;quot; alt=&amp;quot;Custom logo here&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;
....&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you save that and browse to your sites front page you will notice that the logo file is now being shown. Hooray. However it is probably not styled too nicely so lets quickly fix that. Open up the core.css file and add the following lines of CSS to the bottom of the file.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
#page-header {position:relative;min-height:100px;}&lt;br /&gt;
#page-header .sitelogo {float:left;}&lt;br /&gt;
#page-header .headermain {position:absolute;left:0.5em;top:50px;margin:0;float:none;font-size:40px;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
These three lines position the image correctly and if you now refresh everything should appear perfectly. &lt;br /&gt;
&lt;br /&gt;
With the logo done the last setting we need to deal with is the footnote setting. The idea with this setting was that the administrator could enter some text into the editor and it would be displayed in the footer of the page.&lt;br /&gt;
&lt;br /&gt;
This is probably the easiest setting to implement.&lt;br /&gt;
&lt;br /&gt;
Within the front page layout file that we edited above add the following lines below those we added previously.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;footnote)) {&lt;br /&gt;
    $footnote = $PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;footnote;&lt;br /&gt;
} else {&lt;br /&gt;
    $footnote = &#039;&amp;lt;!-- There was no custom footnote set --&amp;gt;&#039;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are just collecting the footnote into a variable &#039;&#039;&#039;$footnote&#039;&#039;&#039; and setting a default footnote comment if the user hasn&#039;t entered one.&lt;br /&gt;
&lt;br /&gt;
We can now echo the $footnote variable within the page footer. This can be done as shown below.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;!-- START OF FOOTER --&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;footnote&amp;quot;&amp;gt;&amp;lt;?php echo $footnote; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;p class=&amp;quot;helplink&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;?php echo page_doc_link(get_string(&#039;moodledocslink&#039;)) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And with that done we are finished! Congratulations if you got this far.&lt;br /&gt;
&lt;br /&gt;
The screenshot below shows the demystified theme we have just created that is styled by the settings page.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.05.png|715px|thumb|left|My finished demystified theme]]&amp;lt;br style=&amp;quot;clear:both&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing our creation==&lt;br /&gt;
Congratulations to you! If you&#039;ve made it this far you have done very well. Now it is time to have a look at what we have created and give it a quick test run.&lt;br /&gt;
&lt;br /&gt;
So in this tutorial we have achieved the following:&lt;br /&gt;
&lt;br /&gt;
* We created a theme called demystified that is based on the standard theme.&lt;br /&gt;
* We added a settings page to our new theme.&lt;br /&gt;
* We added the following settings to our settings page:&lt;br /&gt;
** We can set a background colour through the admin interface.&lt;br /&gt;
** We can change the logo of the site.&lt;br /&gt;
** We can change the block region width.&lt;br /&gt;
** We can add a footnote to the page footer&lt;br /&gt;
** We can add some custom CSS to seal the deal.&lt;br /&gt;
* Those settings were then used in the CSS files for our theme.&lt;br /&gt;
* They were also used in the layout files for our theme.&lt;br /&gt;
* And here we are testing it all.&lt;br /&gt;
&lt;br /&gt;
The screenshots below show my testing process and I change each setting and view the outcome. The great thing about this is that with theme designer mode on you see the changes as soon as the form refreshes.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.06.png|300px|thumb|left|Default settings]]&lt;br /&gt;
[[Image:Theme.settings.page.07.png|300px|thumb|left|Changed the background colour setting]]&lt;br /&gt;
[[Image:Theme.settings.page.08.png|300px|thumb|left|Changed the logo and region width]]&lt;br /&gt;
[[Image:Theme.settings.page.09.png|300px|thumb|left|Added a footnote]]&lt;br /&gt;
[[Image:Theme.settings.page.10.png|300px|thumb|left|Added some custom CSS]]&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:both&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The different settings you can use==&lt;br /&gt;
During this tutorial we use four different kinds of settings, a text box, text area, a select (dropdown) and the editor however as I&#039;m sure you have all guessed there is many more some of which will certainly be useful for theme settings.&lt;br /&gt;
&lt;br /&gt;
The following are examples of some of the different settings. I should add that these build upon what we have already done within the tutorial but are not included in the download.&lt;br /&gt;
&lt;br /&gt;
===Colour picker===&lt;br /&gt;
[[Image:Theme.settings.page.11.png|400px|thumb|The colour picker]]&lt;br /&gt;
I can hear you all asking now &#039;Why didn&#039;t you mention this one earlier?&#039; well the answer is simple it didn&#039;t exist when I first wrote the tutorial. It is an admin setting that I wrote several days after because of the fantastic effort people were putting into trying out settings pages.&lt;br /&gt;
&lt;br /&gt;
A bit about the colour picker. First up it is a text box that when the page loads turns into a colour picker that can be used to select a colour and can even preview the selected colour in the page (by clicking the preview button). It is designed to be very easy to use and the code is just about as simple as creating a normal text box setting.&lt;br /&gt;
&lt;br /&gt;
In the image to the left I have replaced the background colour setting we created during the tutorial with the colour picker. Lets have a look at the code involved for that.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Background colour setting&lt;br /&gt;
$name = &#039;theme_demystified/backgroundcolor&#039;;&lt;br /&gt;
$title = get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = &#039;#DDD&#039;;&lt;br /&gt;
$previewconfig = array(&#039;selector&#039;=&amp;gt;&#039;html&#039;, &#039;style&#039;=&amp;gt;&#039;backgroundColor&#039;);&lt;br /&gt;
$setting = new admin_setting_configcolourpicker($name, $title, $description, $default, $previewconfig);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
So first thing you should notice is that the first four lines of code have not changed at all!&lt;br /&gt;
&lt;br /&gt;
The first change we have is to create a variable &#039;&#039;&#039;$previewconfig&#039;&#039;&#039;. &lt;br /&gt;
This variable is used to tell the colour picker what to do when the user clicks the preview button. It should be an array that contains two things, first a selector, and second a style. &lt;br /&gt;
# The selector is a CSS selector like &#039;&#039;.page .header h2&#039;&#039;.&lt;br /&gt;
# The style is a what should change, there are two immediate values it can be, either &#039;&#039;&#039;backgroundColor&#039;&#039;&#039; or &#039;&#039;&#039;color&#039;&#039;&#039;.&lt;br /&gt;
In my case the selector is &#039;&#039;&#039;html&#039;&#039;&#039; to target the html tag and the style is backgroundColor to change the background colour.&lt;br /&gt;
&lt;br /&gt;
The second change is to use &#039;&#039;&#039;admin_setting_configcolourpicker&#039;&#039;&#039; instead of &#039;&#039;admin_setting_configtext&#039;&#039;. The arguments are nearly identical as well except that there is an extra argument to which we give the &#039;&#039;&#039;$previewconfig&#039;&#039;&#039; variable.&lt;br /&gt;
&lt;br /&gt;
And that is it! it is all you need to get the colour picker up and running.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Extra note:&#039;&#039;&#039; The $previewconfig variable is optional. If you don&#039;t want a preview button the simply set &#039;&#039;$previewconfig = null&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Common pitfalls and useful notes==&lt;br /&gt;
&lt;br /&gt;
This section is really just a collection of pointers, tips, notes, and other short useful stuff that may be of use to those attempting this tutorial.&lt;br /&gt;
&lt;br /&gt;
# First up and most importantly there are very few limitations to what you achieve in this fashion.&lt;br /&gt;
# If you get stuck or need a hand ask in the forums, there&#039;s always someone round who can help.&lt;br /&gt;
# If you do something really cool let us know, I know everyone in the community loves finding our what others are achieving.&lt;br /&gt;
# You don&#039;t have to use &#039;&#039;admin_settingpage&#039;&#039; you can also use &#039;&#039;&#039;admin_externalpage&#039;&#039;&#039; if you prefer. It should be noted however that it is not the preferred way to do it as admin_externalpage&#039;s were only left in Moodle 2.0 for backwards compatibility (although they are more flexible one day they will be deprecated or removed). Thank you to Darryl for raising this.&lt;br /&gt;
# If you find that your language strings aren&#039;t being used (you are getting language string notices) and you have double checked that you have turned &#039;&#039;&#039;langstringcache&#039;&#039;&#039; off then you may need to delete the language cache directory. This is located in the moodledata directory for you installation: moodledata/cache/lang/*. You should delete the directory for your chosen language by default &#039;&#039;en&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Adding theme upgrade code]]&lt;br /&gt;
* [[Styling and customising the dock]]&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/discuss.php?d=152053 Theme 2.0: Adding a settings page to your theme] forum discussion&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Creating_a_theme_settings_page&amp;diff=46305</id>
		<title>Creating a theme settings page</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Creating_a_theme_settings_page&amp;diff=46305"/>
		<updated>2014-09-24T21:55:29Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Creating the settings page */  - updating to current methods&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}This document looks at how to create a settings page for your Moodle 2.x.x theme and how to make use of those settings within the CSS and layout files for your theme.&lt;br /&gt;
&lt;br /&gt;
This is a pretty advanced topic and will require that you have at least an intermediate knowledge of PHP, CSS, and development in general.&lt;br /&gt;
&lt;br /&gt;
==Before we begin==&lt;br /&gt;
[[Image:Theme.settings.page.03.png|350px|thumb|Our end goal. The settings page.]]&lt;br /&gt;
[[Image:Theme.settings.page.10.png|350px|thumb|And what it can do.]]&lt;br /&gt;
There is a huge body of knowledge that we must cover in following through this document and as such I think the best way to write this is as a tutorial.&lt;br /&gt;
&lt;br /&gt;
My intentions for this tutorial are to replicate the standard theme but with a settings page that allows the administrator to set a background colour, set a logo to use with the page, and probably several other minor settings to change the way in which the theme is displayed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I will start this tutorial by creating a new theme which will be largely a copy/paste of the current standard theme. I expect that anyone working through this tutorial has previously read the tutorial I wrote on [[Themes 2.0 creating your first theme|creating your first theme]]. If you haven&#039;t go read it now because I&#039;m not going to go into much detail until we get to the actual process of customising the theme and introducing the settings page.&lt;br /&gt;
&lt;br /&gt;
So before we finally get this started please ensure you can check off everything on the following requirements list.&lt;br /&gt;
* Have a Moodle installation that has already been installed and configured and is ready to use.&lt;br /&gt;
* Have full read/write access to that installation.&lt;br /&gt;
* Be prepared to delete that installation at the end of this... we will destroy it!&lt;br /&gt;
* Have a development environment prepared and ready to use. This includes:&lt;br /&gt;
** Your favourite editor installed, running, and pointed at the themes directory of your installation.&lt;br /&gt;
** Your browser open and your site visible.&lt;br /&gt;
** A bottomless coffee pot... decaf won&#039;t help you with this one.&lt;br /&gt;
* Have set the following settings:&lt;br /&gt;
** &#039;&#039;&#039;themedesignermode&#039;&#039;&#039; if you don&#039;t know what this is please read the [[Themes 2.0 creating your first theme|creating your first theme]] tutorial.&lt;br /&gt;
** &#039;&#039;&#039;allowthemechangeonurl&#039;&#039;&#039; turn this on, it allows you to change themes on the URL and is very handy when developing themes. &#039;&#039;Site Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; Theme settings&#039;&#039;&lt;br /&gt;
** &#039;&#039;&#039;langstringcache&#039;&#039;&#039; if you don&#039;t turn this off you won&#039;t see your strings when they are added. &#039;&#039;Site Administration &amp;gt; Language &amp;gt; Language settings&#039;&#039;&lt;br /&gt;
* And finally an insane ambition to create a customisable theme.&lt;br /&gt;
&lt;br /&gt;
For those interested the theme that I create throughout this tutorial can be downloaded from the forum post in which I announce this document: http://moodle.org/mod/forum/discuss.php?d=152053&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:right;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Our goals for this tutorial==&lt;br /&gt;
The following is just a list goals that I hope to achieve during this tutorial. They are laid out here so that I can easily refer back to them and so that you can easily find them.&lt;br /&gt;
# Create a new theme called &#039;&#039;&#039;demystified&#039;&#039;&#039; based upon the standard theme within Moodle 2.0.&lt;br /&gt;
# Make some minor changes to that theme to allow us to more easily see what is going on.&lt;br /&gt;
# Create a settings page for the demystified theme.&lt;br /&gt;
# Add several settings to our settings page.&lt;br /&gt;
# Use some of those settings to alter our CSS.&lt;br /&gt;
# Use the rest of those settings within our layout file..&lt;br /&gt;
# Discuss the good, the bad, and limits of what we have just created.&lt;br /&gt;
&lt;br /&gt;
So I can see you are all very excited about this point and that you would love to know what settings we are going to create; So here they are:&lt;br /&gt;
&lt;br /&gt;
A setting to ...&lt;br /&gt;
* change the background colour (CSS).&lt;br /&gt;
* set the path to an image that we will use as a logo on all pages (Layout files).&lt;br /&gt;
* override the width of the block regions (CSS).&lt;br /&gt;
* allow a note to be added to the footer of all pages (Layout files).&lt;br /&gt;
* allow custom CSS to be written to do anything the user wants. (CSS)&lt;br /&gt;
&lt;br /&gt;
==Creating the demystified theme==&lt;br /&gt;
Before we start here I want to remind you that I am going to look at this only briefly as I am making the assumption that you have read the [[Themes 2.0 creating your first theme|creating your first theme]] tutorial.&lt;br /&gt;
&lt;br /&gt;
Well lets get into it....&lt;br /&gt;
&lt;br /&gt;
The first thing we need to do is create a directory for our theme which we will call demystified. &lt;br /&gt;
&lt;br /&gt;
So within your Moodle directory create the following folder &#039;&#039;&#039;moodle/theme/demystified&#039;&#039;&#039;. At the same time you can also create the following files and folders which we will get to soon.&lt;br /&gt;
* The file &#039;&#039;&#039;moodle/theme/demystified/config.php&#039;&#039;&#039; for our config information.&lt;br /&gt;
* The directory &#039;&#039;&#039;moodle/theme/demystified/layout&#039;&#039;&#039; for our layout files.&lt;br /&gt;
* The directory &#039;&#039;&#039;moodle/theme/demystified/style&#039;&#039;&#039; for our css files.&lt;br /&gt;
* The file &#039;&#039;&#039;moodle/theme/demystified/style/core.css&#039;&#039;&#039; which will contain our special CSS.&lt;br /&gt;
&lt;br /&gt;
Next we will copy the layout files from the base theme to our new theme demystified. We are basing the demystified theme on the standard theme however that doesn&#039;t use it&#039;s own layout files it uses the base theme&#039;s layout files so those are the ones we want. &lt;br /&gt;
&lt;br /&gt;
The reason that we are coping these layout files is that later on in this tutorial we will be modifying them to make use of our new settings... so copy all of the layout files from &#039;&#039;&#039;moodle/theme/base/layout&#039;&#039;&#039; to &#039;&#039;&#039;moodle/theme/demystified/layout&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
There should be three files that you just copied:&lt;br /&gt;
# embedded.php&lt;br /&gt;
# frontpage.php&lt;br /&gt;
# general.php&lt;br /&gt;
&lt;br /&gt;
Now we need to populate demystified/config.php with the settings for our new theme. They are as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;name = &#039;demystified&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Simply sets the name of our theme.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;,&#039;base&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This theme is extending both the standard theme and the base theme. Remember when extending a theme you also need to extend its parents or things might not work correctly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;core&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This tells our theme that we want to use the file &#039;&#039;&#039;demystified/style/core.css&#039;&#039;&#039; with this theme.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;height:300px;overflow-y:scroll;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Most backwards compatible layout without the blocks - this is the layout used by default&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&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;
    // 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;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;
    // Main course page&lt;br /&gt;
    &#039;course&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;coursecategory&#039; =&amp;gt; array(&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;
    // part of course, typical for modules - default page layout if $cm specified in require_login()&lt;br /&gt;
    &#039;incourse&#039; =&amp;gt; array(&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;
    // The site home page.&lt;br /&gt;
    &#039;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;frontpage.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;
    // Server administration scripts.&lt;br /&gt;
    &#039;admin&#039; =&amp;gt; array(&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;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // My dashboard page&lt;br /&gt;
    &#039;mydashboard&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // My public page&lt;br /&gt;
    &#039;mypublic&#039; =&amp;gt; array(&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;
    &#039;login&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    // Pages that appear in pop-up windows - no navigation, no blocks, no header.&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // No blocks and minimal footer - used for legacy frame layouts only!&lt;br /&gt;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible&lt;br /&gt;
    &#039;embedded&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Used during upgrade and install, and for the &#039;This site is undergoing maintenance&#039; message.&lt;br /&gt;
    // This must not have any blocks, and it is good idea if it does not have links to&lt;br /&gt;
    // other places - for example there should not be a home link in the footer...&lt;br /&gt;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Now that all looks very complicated however its really not too bad as it is just copied from the base theme&#039;s config.php file. We can do this because we copied the layout files from the base theme to begin with and for the time being there are no changes that we wish to make. Simply open up &#039;&#039;&#039;theme/base/config.php&#039;&#039;&#039; and copy the layouts from there.&lt;br /&gt;
&lt;br /&gt;
And that is it. The config.php file for our demystified theme is complete. The full source is shown below:&lt;br /&gt;
&amp;lt;div style=&amp;quot;height:300px;overflow-y:scroll;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
// This file is part of Moodle - http://moodle.org/&lt;br /&gt;
//&lt;br /&gt;
// Moodle is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// Moodle is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with Moodle.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * The demystified theme config file&lt;br /&gt;
 *&lt;br /&gt;
 * This theme was created to document the process of adding a settings page to a theme&lt;br /&gt;
 *&lt;br /&gt;
 * @copyright 2010 Sam Hemelryk&lt;br /&gt;
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
// The name of our theme&lt;br /&gt;
$THEME-&amp;gt;name = &#039;demystified&#039;;&lt;br /&gt;
&lt;br /&gt;
// The other themes this theme extends&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;,&#039;base&#039;);&lt;br /&gt;
&lt;br /&gt;
// The CSS files this theme uses (located in the style directory)&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;core&#039;);&lt;br /&gt;
&lt;br /&gt;
// The layout definitions for this theme&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Most backwards compatible layout without the blocks - this is the layout used by default&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&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;
    // 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;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;
    // Main course page&lt;br /&gt;
    &#039;course&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;coursecategory&#039; =&amp;gt; array(&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;
    // part of course, typical for modules - default page layout if $cm specified in require_login()&lt;br /&gt;
    &#039;incourse&#039; =&amp;gt; array(&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;
    // The site home page.&lt;br /&gt;
    &#039;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;frontpage.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;
    // Server administration scripts.&lt;br /&gt;
    &#039;admin&#039; =&amp;gt; array(&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;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // My dashboard page&lt;br /&gt;
    &#039;mydashboard&#039; =&amp;gt; array(&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;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // My public page&lt;br /&gt;
    &#039;mypublic&#039; =&amp;gt; array(&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;
    &#039;login&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    // Pages that appear in pop-up windows - no navigation, no blocks, no header.&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // No blocks and minimal footer - used for legacy frame layouts only!&lt;br /&gt;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible&lt;br /&gt;
    &#039;embedded&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Used during upgrade and install, and for the &#039;This site is undergoing maintenance&#039; message.&lt;br /&gt;
    // This must not have any blocks, and it is good idea if it does not have links to&lt;br /&gt;
    // other places - for example there should not be a home link in the footer...&lt;br /&gt;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The screenshot below shows both the directory structure we have now created and the theme presently.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.01.png]]&lt;br /&gt;
&lt;br /&gt;
To view the theme so far open you browser and enter the URL of your site followed by &#039;&#039;&#039;?theme=demystified&#039;&#039;&#039;. You should see the theme that we just created which will look exactly like the base standard theme.&lt;br /&gt;
&lt;br /&gt;
The final thing that we want to do is add a little bit of CSS to the demystified theme that will both visually set this theme apart from the standard theme and second build a the base which our settings can later extend.&lt;br /&gt;
&lt;br /&gt;
I added the following snippet of CSS to the file &#039;&#039;&#039;demystified/style/core.css&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
html {background-color:#DDD;}&lt;br /&gt;
body {margin:30px;padding:0;border:1px solid #333;border-width:0 10px 0 10px;background-color:#333;}&lt;br /&gt;
body #page {background-color:#FFF;position:relative;top:-10px;}&lt;br /&gt;
.block .header {background-image:none;background-color:#0C5CAC;border:1px solid #0C5CAC;color:#FFF;}&lt;br /&gt;
.block {border-color:#4BA7FF;background-color:#DDEEFF;}&lt;br /&gt;
.block .content {background-color:#F1F8FF;}&lt;br /&gt;
a:link,&lt;br /&gt;
a:visited {color:#0C5CAC;}&lt;br /&gt;
a:hover {color:#C77500;}&lt;br /&gt;
#page #page-header {background-color:#0C5CAC;margin:0;padding:0;width:100%;color:#fff;}&lt;br /&gt;
#page #page-header a:link, #page #page-header a:visited {color:#FFAC02}&lt;br /&gt;
#page #page-header .navbar, #page #page-header .navbar a:link, #page #page-header .navbar a:visited {color:#0C5CAC;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The CSS that we have just added to our theme sets a couple of colours on the front page. Presently this is the only CSS I will add, I know it isn&#039;t complete by any means but it achieves it&#039;s purpose as the screenshot below illustrates.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.02.png|715px|thumb|left|The newly styles demystified theme]]&amp;lt;br style=&amp;quot;clear:both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And with that I will move on to the real purpose of this tutorial, creating the settings page&lt;br /&gt;
&lt;br /&gt;
==Setting up the settings page==&lt;br /&gt;
With the demystified theme set up it is time to create the settings page. This is where the real PHP fun begins.&lt;br /&gt;
&lt;br /&gt;
For those of you who happen to be familiar with development of modules, blocks or other plugin types you have probably encountered settings pages before and this is not going to be any different.&lt;br /&gt;
&lt;br /&gt;
However for those who haven&#039;t which I imagine is most of you this is going to be quite a challenge. I will try to walk through this step by step however if at any point you get stuck don&#039;t hesitate to ask in the forums as I imagine you will get a speedy response.&lt;br /&gt;
&lt;br /&gt;
===How settings pages work in Moodle===&lt;br /&gt;
Settings pages can be used by nearly every plugin type, of which themes is of course one. The way in which it all works isn&#039;t too tricky to understand. &lt;br /&gt;
&lt;br /&gt;
All of the settings for Moodle can be configured through the administrator interfaces when logged in. I am sure that everyone here has seen those pages and has changed a setting or two before so you will all know what I am talking about. Well the settings page for a theme is no different. It will be shown in the administration pages tree under &#039;&#039;&#039;Appearance &amp;gt; Themes&#039;&#039;&#039; and all we have to do is tell Moodle what settings there are.&lt;br /&gt;
&lt;br /&gt;
This is done by creating a settings.php file within our theme into which we will add code that tells Moodle about the settings we want to add/use.&lt;br /&gt;
&lt;br /&gt;
When telling Moodle about each setting we are simply creating a new &#039;&#039;admin_setting&#039;&#039; instance of the type we want and the properties we want and then adding it to our settings page.&lt;br /&gt;
&lt;br /&gt;
There is really not much more too it at this level. Things can get very complex very fast so the best thing we can do now is start creating our settings.php file for the demystified theme and see where it leads us.&lt;br /&gt;
&lt;br /&gt;
===Creating the settings page===&lt;br /&gt;
So as mentioned before we need a settings.php file which we will create now. To begin with create the file &#039;&#039;&#039;theme/demystified/settings.php&#039;&#039;&#039; and open it in your favourite editor so its ready to go.&lt;br /&gt;
&lt;br /&gt;
Before we start adding code however lets just remember the settings that we want to create:&lt;br /&gt;
* change the background colour (CSS).&lt;br /&gt;
* set the path to an image that we will use as a logo on all pages (Layout files).&lt;br /&gt;
* override the width of the block regions (CSS).&lt;br /&gt;
* allow a note to be added to the footer of all pages (Layout files).&lt;br /&gt;
* allow custom CSS to be written to do anything the user wants. (CSS)&lt;br /&gt;
&lt;br /&gt;
Alright.&lt;br /&gt;
&lt;br /&gt;
Now thinking about this the first setting is as basic as it gets, all we need is a text box that the user can type a colour into.&lt;br /&gt;
&lt;br /&gt;
The second is to allow a logo to be used in the header of each page. What we want here is a path but should it be a physical path e.g. C:/path/to/image.png or should it be a web path e.g. &amp;lt;nowiki&amp;gt;http://mysite.com/path/to/image.png&amp;lt;/nowiki&amp;gt;?&lt;br /&gt;
For the purpose of this tutorial I am going to go with a web path because it is going to be easier to code and will hopefully be a little easier to understand to begin with.&lt;br /&gt;
&lt;br /&gt;
The third setting is a little more complex. For this I want a drop down box with some specific widths that the administrator can select.&lt;br /&gt;
&lt;br /&gt;
The forth and the fifth settings are both pretty straight forward, there we want a textarea into which the user can enter what ever they want and we will do something useful with it.&lt;br /&gt;
&lt;br /&gt;
Now that we have an understanding about the settings we wish to define pull up your editor and lets start coding....&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Settings for the demystified theme&lt;br /&gt;
 */&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die;&lt;br /&gt;
&lt;br /&gt;
if ($ADMIN-&amp;gt;fulltree) {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is the first bit of code we must enter, the first line is of course just the opening php tag, secondly we have a comment that describes this file, and then we get create a new &#039;&#039;&#039;admin_settingspage object&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This admin_settingspage object that we have just created is a representation of our settings page and is the what we add our new settings to. When creating it we give it two arguments, first the name of the page which is in this case &#039;&#039;&#039;theme_&#039;&#039;themename&#039;&#039;&#039;&#039;&#039; and the title for the page which we get with the get_string method.&lt;br /&gt;
&lt;br /&gt;
At the moment I&#039;m not going to worry about adding the string, we will get to that later once we have defined all of our settings.&lt;br /&gt;
&lt;br /&gt;
====Background colour====&lt;br /&gt;
&lt;br /&gt;
With the page now created lets add our first setting: Background colour.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Background colour setting&lt;br /&gt;
$name = &#039;theme_demystified/backgroundcolor&#039;;&lt;br /&gt;
$title = get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = &#039;#DDD&#039;;&lt;br /&gt;
$setting = new admin_setting_configtext($name, $title, $description, $default, PARAM_CLEAN, 12);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Thankfully this isn&#039;t as difficult as it initially looks.&lt;br /&gt;
&lt;br /&gt;
The first line of code is creating a variable for the name of the background colour setting. In this case it is &#039;&#039;&#039;theme_demystified/backgroundcolor&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
The name is very important, for the setting to be usable we have to follow a strict naming convention. &#039;&#039;&#039;theme_&#039;&#039;themename&#039;&#039;/&#039;&#039;settingname&#039;&#039;&#039;&#039;&#039; where &#039;&#039;&#039;&#039;&#039;themename&#039;&#039;&#039;&#039;&#039; is the name of the theme the setting belongs to and &#039;&#039;&#039;&#039;&#039;settingname&#039;&#039;&#039;&#039;&#039; is the name for the setting by which we will use it.&lt;br /&gt;
&lt;br /&gt;
The second line of code creates a variable that contains the title of the setting. This is what the user sees to the right of the setting on the settings page and should be a short description of the setting. Here we are again using the &#039;&#039;get_string&#039;&#039; method so we will need to remember to add that string later on.&lt;br /&gt;
&lt;br /&gt;
The third line of code sets the description. This should describe what the setting does or how it works and again we will use the get_string method.&lt;br /&gt;
&lt;br /&gt;
The fourth line creates a variable that will be used as the default value for the setting. Because this setting is a colour we want an HTML colour to be the default value.&lt;br /&gt;
&lt;br /&gt;
The fifth line is where we put it all together. Here we create a new &#039;&#039;&#039;admin_setting_configtext&#039;&#039;&#039; object. This object will represent the background colour setting.&lt;br /&gt;
&lt;br /&gt;
When we create it we need to give it 6 different things.&lt;br /&gt;
# The name of the setting. In this case we have a variable &#039;&#039;&#039;$name&#039;&#039;&#039;.&lt;br /&gt;
# The title for this setting. We used the variable &#039;&#039;&#039;$title&#039;&#039;&#039;.&lt;br /&gt;
# The description of the setting &#039;&#039;&#039;$description&#039;&#039;&#039;.&lt;br /&gt;
# The default value for the setting. &#039;&#039;&#039;$default&#039;&#039;&#039; is the variable this.&lt;br /&gt;
# The type of value we want the user to enter. For this we have used PARAM_CLEAN which tells Moodle to get rid of any nasties from what the user enters.&lt;br /&gt;
# The size of the field. In our case 12 characters will be plenty.&lt;br /&gt;
&lt;br /&gt;
The sixth and final line of code adds our newly created setting to the administration page we created earlier.&lt;br /&gt;
&lt;br /&gt;
That is it we have successfully created and added our first setting, however there are several more to settings to do, and there are a couple of important things that you need to be aware of before we move on.&lt;br /&gt;
&lt;br /&gt;
First: There are several different types of settings that you can create and add to a page, and each one may differ in what they need you to give them. In this case it was name, title, description, default, type, and size. However other settings will likely require different things. Smart editors like Netbeans or Eclipse can tell you what is required, otherwise you will need to research it.&lt;br /&gt;
&lt;br /&gt;
Second: Normally settings are declared on one line as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$setting-&amp;gt;add(new admin_setting_configtext(&#039;theme_demystified/backgroundcolor&#039;, get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;), get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;), &#039;#DDD&#039;, PARAM_CLEAN, 12));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
While this is structurally identical as all we have done is move everything onto one line and do away with the variables it is a little harder to read when you are learning all of this.&lt;br /&gt;
&lt;br /&gt;
====The logo file====&lt;br /&gt;
Time to create the second setting that will allow the user to enter a URL to an image they wish to use as the logo on their site.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Logo file setting&lt;br /&gt;
$name = &#039;theme_demystified/logo&#039;;&lt;br /&gt;
$title = get_string(&#039;logo&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;logodesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtext($name, $title, $description, &#039;&#039;, PARAM_URL);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The first thing that you will notice about this setting that it is very similar to the first setting, in fact all we have changed is the name, title, description, and default value. We have however changed the value type from PARAM_CLEAN to PARAM_URL, this makes sure the user enters a URL. You will also notice that for this one we don&#039;t set a size for the field as we have no idea how long the URL will be.&lt;br /&gt;
&lt;br /&gt;
====Block region width====&lt;br /&gt;
The third setting should allow the user to set a width for the block regions that will be used as columns.&lt;br /&gt;
&lt;br /&gt;
For this setting I want to do something a little different from the previous two, here I want to use a select box so that the user selects a width for the column from a list I provide.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Block region width&lt;br /&gt;
$name = &#039;theme_demystified/regionwidth&#039;;&lt;br /&gt;
$title = get_string(&#039;regionwidth&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;regionwidthdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = 200;&lt;br /&gt;
$choices = array(150=&amp;gt;&#039;150px&#039;, 170=&amp;gt;&#039;170px&#039;, 200=&amp;gt;&#039;200px&#039;, 240=&amp;gt;&#039;240px&#039;, 290=&amp;gt;&#039;290px&#039;, 350=&amp;gt;&#039;350px&#039;, 420=&amp;gt;&#039;420px&#039;);&lt;br /&gt;
$setting = new admin_setting_configselect($name, $title, $description, $default, $choices);&lt;br /&gt;
$setting-&amp;gt;set_updatedcallback(&#039;theme_reset_all_caches&#039;);&lt;br /&gt;
$settings-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
So looking at the code: The first four lines you will recognise. $name, $title, $description, and $default are all being set.&lt;br /&gt;
&lt;br /&gt;
The fifth line of code however introduces something new. Of course in order to have a select box we have to have options, in this case we have an array of options stored in the variable $choices.&lt;br /&gt;
&lt;br /&gt;
The array of options is constructed of a collection of &#039;&#039;&#039;&#039;&#039;value&#039;&#039;&#039; =&amp;gt; &#039;&#039;&#039;label&#039;&#039;&#039;&#039;&#039; pairs. Notice how we don&#039;t add &#039;&#039;&#039;px&#039;&#039;&#039; to the value. This is is very intentional as later on I need to do a little bit of math with that value so we need it to be a number.&lt;br /&gt;
&lt;br /&gt;
The lines after should look familiar again, the only difference being that instead of a &#039;&#039;admin_setting_configtext&#039;&#039; setting we have created a &#039;&#039;admin_setting_configselect&#039;&#039; for which we must give the choices for the select box as the fifth argument.&lt;br /&gt;
&lt;br /&gt;
Woohoo, we&#039;ve just created our first select box setting.&lt;br /&gt;
&lt;br /&gt;
====Foot note====&lt;br /&gt;
Now to create the foot note setting. Here we want the user to be able to enter some arbitrary text that will be used in the footer of the page. For this I want the user to be able to enter some HTML so I will create an editor setting.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Foot note setting&lt;br /&gt;
$name = &#039;theme_demystified/footnote&#039;;&lt;br /&gt;
$title = get_string(&#039;footnote&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;footnotedesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_confightmleditor($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
How simple is that!&lt;br /&gt;
&lt;br /&gt;
It is just about identical to the first two settings except that for this we have created a &#039;&#039;admin_setting_confightmleditor&#039;&#039; setting rather than a text setting.&lt;br /&gt;
&lt;br /&gt;
Note: You can also set the columns and rows for the editor setting using the fifth and sixth arguments.&lt;br /&gt;
&lt;br /&gt;
====Custom CSS====&lt;br /&gt;
The final setting is to allow the user to add some custom CSS to the theme that will be used on every page. I want this to be a plain textarea into which the user can enter CSS.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Custom CSS file&lt;br /&gt;
$name = &#039;theme_demystified/customcss&#039;;&lt;br /&gt;
$title = get_string(&#039;customcss&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;customcssdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtextarea($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Just like the editor or text settings. It&#039;s getting very easy now!&lt;br /&gt;
&lt;br /&gt;
====Finishing settings.php====&lt;br /&gt;
With all of our settings defined and added to our page that we created right at the beginning it is time to finish it all off.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Add our page to the structure of the admin tree&lt;br /&gt;
$ADMIN-&amp;gt;add(&#039;themes&#039;, $temp);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The above line of code is the final line for the page. It is adding the page that we have created &#039;&#039;&#039;$temp&#039;&#039;&#039; to the admin tree structure. In this case it is adding it to the themes branch.&lt;br /&gt;
&lt;br /&gt;
The following is the completed source for our settings.php ..... for your copy/paste pleasure.&lt;br /&gt;
&amp;lt;div style=&#039;height:300px;overflow:auto;&#039;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Settings for the demystified theme&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
// Create our admin page&lt;br /&gt;
$temp = new admin_settingpage(&#039;theme_demystified&#039;, get_string(&#039;configtitle&#039;,&#039;theme_demystified&#039;));&lt;br /&gt;
&lt;br /&gt;
// Background colour setting&lt;br /&gt;
$name = &#039;theme_demystified/backgroundcolor&#039;;&lt;br /&gt;
$title = get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = &#039;#DDD&#039;;&lt;br /&gt;
$setting = new admin_setting_configtext($name, $title, $description, $default, PARAM_CLEAN, 12);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
// Logo file setting&lt;br /&gt;
$name = &#039;theme_demystified/logo&#039;;&lt;br /&gt;
$title = get_string(&#039;logo&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;logodesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtext($name, $title, $description, &#039;&#039;, PARAM_URL);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
// Block region width&lt;br /&gt;
$name = &#039;theme_demystified/regionwidth&#039;;&lt;br /&gt;
$title = get_string(&#039;regionwidth&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;regionwidthdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = 200;&lt;br /&gt;
$choices = array(150=&amp;gt;&#039;150px&#039;, 170=&amp;gt;&#039;170px&#039;, 200=&amp;gt;&#039;200px&#039;, 240=&amp;gt;&#039;240px&#039;, 290=&amp;gt;&#039;290px&#039;, 350=&amp;gt;&#039;350px&#039;, 420=&amp;gt;&#039;420px&#039;);&lt;br /&gt;
$setting = new admin_setting_configselect($name, $title, $description, $default, $choices);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
// Foot note setting&lt;br /&gt;
$name = &#039;theme_demystified/footnote&#039;;&lt;br /&gt;
$title = get_string(&#039;footnote&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;footnotedesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_confightmleditor($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
// Custom CSS file&lt;br /&gt;
$name = &#039;theme_demystified/customcss&#039;;&lt;br /&gt;
$title = get_string(&#039;customcss&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;customcssdesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$setting = new admin_setting_configtextarea($name, $title, $description, &#039;&#039;);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&lt;br /&gt;
// Add our page to the structure of the admin tree&lt;br /&gt;
$ADMIN-&amp;gt;add(&#039;themes&#039;, $temp);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Creating a language file and adding our strings===&lt;br /&gt;
As I&#039;m sure none of you have forgotten, throughout the creation of the our settings.php page, we used a lot of strings that I mentioned we would set later on. Well now is the time to set those strings.&lt;br /&gt;
&lt;br /&gt;
First up create the following directories and file for our language strings:&lt;br /&gt;
* Directory &#039;&#039;&#039;theme/demystified/lang&#039;&#039;&#039;&lt;br /&gt;
* Directory &#039;&#039;&#039;theme/demystified/lang/en&#039;&#039;&#039;&lt;br /&gt;
* File &#039;&#039;&#039;theme/demystified/lang/theme_demystified.php&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
What we have created here is the required structure for Moodle to start looking for language strings.&lt;br /&gt;
&lt;br /&gt;
First Moodle locates the lang directory, once found it looks within that directory for another directory that uses the character code for the language the user has selected, by default this is &#039;&#039;&#039;en&#039;&#039;&#039; for English. Once that is found it looks for the appropriate language file, in this case &#039;&#039;&#039;theme_demystified.php&#039;&#039;&#039; from which it will load all language strings for our theme.&lt;br /&gt;
&lt;br /&gt;
If English isn&#039;t your chosen language simply replace the &#039;&#039;en&#039;&#039; directory with one that uses your chosen languages character code (two letters).&lt;br /&gt;
&lt;br /&gt;
We can now add our language strings to &#039;&#039;&#039;theme/demystified/lang/theme_demystified.php&#039;&#039;&#039;. Copy and paste the following lines of PHP into this file.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This file contains the strings used by the demystified theme&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
$string[&#039;backgroundcolor&#039;] = &#039;Background colour&#039;;&lt;br /&gt;
$string[&#039;backgroundcolordesc&#039;] = &#039;This sets the background colour for the theme.&#039;;&lt;br /&gt;
$string[&#039;configtitle&#039;] = &#039;Demystified theme&#039;;&lt;br /&gt;
$string[&#039;customcss&#039;] = &#039;Custom CSS&#039;;&lt;br /&gt;
$string[&#039;customcssdesc&#039;] = &#039;Any CSS you enter here will be added to every page allowing your to easily customise this theme.&#039;;&lt;br /&gt;
$string[&#039;footnote&#039;] = &#039;Footnote&#039;;&lt;br /&gt;
$string[&#039;footnotedesc&#039;] = &#039;The content from this textarea will be displayed in the footer of every page.&#039;;&lt;br /&gt;
$string[&#039;logo&#039;] = &#039;Logo&#039;;&lt;br /&gt;
$string[&#039;logodesc&#039;] = &#039;Enter the URL to an image to use as the logo for this site. Should be http://www.yoursite.com/path/to/logo.png&#039;;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;Demystified&#039;;&lt;br /&gt;
$string[&#039;regionwidth&#039;] = &#039;Column width&#039;;&lt;br /&gt;
$string[&#039;regionwidthdesc&#039;] = &#039;This sets the width of the two block regions that form the left and right columns.&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above lines of code I have added an entry for each language string we used within &#039;&#039;settings.php&#039;&#039;. When adding language strings like this make sure you use single quotes and try to keep things alphabetical - it helps greatly when managing strings.&lt;br /&gt;
&lt;br /&gt;
Now when we view the settings page there will not be any errors or strings missing.&lt;br /&gt;
&lt;br /&gt;
===Having a look at what we have created===&lt;br /&gt;
Now that we have created our settings page (settings.php) and added all of the language strings it is time to have a look at things in your browser.&lt;br /&gt;
&lt;br /&gt;
Open your browser and enter the URL to your site. When you arrive at your site login as an administrator.&lt;br /&gt;
&lt;br /&gt;
If you are not redirected to view the new settings change your URL to &amp;lt;nowiki&amp;gt;http://www.yoursite.com/admin/&amp;lt;/nowiki&amp;gt; and your will see a screen to set the new theme settings we have just created. This lets us know that everything has worked correctly.&lt;br /&gt;
&lt;br /&gt;
At any point now you are able to log in as administrator and within the settings block browse to &#039;&#039;&#039;Site administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; Demystified theme&#039;&#039;&#039; to change those settings.&lt;br /&gt;
&lt;br /&gt;
The screenshot below shows you what you should see at this point:&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.03.png|715px|thumb|left|The settings page we just created]]&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using the settings in CSS==&lt;br /&gt;
With the settings page now created and operational it is time to make use of our new settings. The settings that we want to use within our CSS is as follows:&lt;br /&gt;
&lt;br /&gt;
; backgroundcolor : Will be used to set the background colour in CSS.&lt;br /&gt;
; regionwidth : Will be the width of the column for CSS.&lt;br /&gt;
; customcss : Will be some custom CSS to add to our stylesheet.&lt;br /&gt;
&lt;br /&gt;
At this point those names are the names we used for our setting with the slash and everything before it having been removed.&lt;br /&gt;
&lt;br /&gt;
Before we start tearing into some code it is important that we have a look at what we are going to do and how we are going to go about it.&lt;br /&gt;
&lt;br /&gt;
===How it all works within Moodle===&lt;br /&gt;
The first thing to understand is that while Moodle allows you to create a settings page and automates it inclusion and management right into the administration interfaces there is no smart equivalent for using the settings. This is simply because there is no way to predict how people will want to use the settings.&lt;br /&gt;
&lt;br /&gt;
However don&#039;t think of this as a disadvantage, in fact it is quite the contrary. Although we can&#039;t just &#039;&#039;use&#039;&#039; our settings we can take full control over how and where we use them. It means it will take a little more code but in the end that will work to our advantage as we can do anything we want.&lt;br /&gt;
&lt;br /&gt;
Moodle does help us out a little but not in an obvious way. The first thing that Moodle does is look for a config variable &#039;&#039;&#039;csspostprocess&#039;&#039;&#039; that should be the name of a function which we want called to make any changes to the CSS after it has been prepared.&lt;br /&gt;
&lt;br /&gt;
The second thing Moodle does is include a lib.php from the theme&#039;s directory if one exists (also for the themes the current theme extends.) which ensures that as long as we write our code within &#039;&#039;&#039;theme/demystified/lib.php&#039;&#039;&#039; it will be included and ready to be used.&lt;br /&gt;
&lt;br /&gt;
The third and final thing Moodle does that will help us out here is ensure that by the time any of code is ready to execute the settings have been prepared and are ready to be used within a theme config object which is passed into our &#039;&#039;csspostprocess&#039;&#039; function.&lt;br /&gt;
&lt;br /&gt;
===Our plan===&lt;br /&gt;
As you have already probably guessed we will need to create a function to make the changes to the CSS that we want. We will then set the theme config option &#039;&#039;&#039;$THEME-&amp;gt;csspostprocess&#039;&#039;&#039; to the name of our function.&lt;br /&gt;
&lt;br /&gt;
By doing this when Moodle builds the CSS file it will call our function afterwards with the CSS and the theme object that contains our setting.&lt;br /&gt;
&lt;br /&gt;
Now we know that we will use the &#039;&#039;csspostprocess&#039;&#039; function but how are we going to change the CSS, we could get the function to add CSS, or we could get the function to replace something within the CSS. My personal preference is to replace something within the CSS, just like what is happening with images. If you want to use an image within CSS you would write &amp;lt;nowiki&amp;gt;[[pix:theme|imagename]]&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For settings I am going to use &amp;lt;nowiki&amp;gt;[[setting:settingname]]&amp;lt;/nowiki&amp;gt;, this way it looks a bit like something you are already familiar with.&lt;br /&gt;
&lt;br /&gt;
What we need to decide upon next is the best way in which to replace our settings tag with the settings that the user has set.&lt;br /&gt;
&lt;br /&gt;
There are two immediate options available to us:&lt;br /&gt;
# Make the &#039;&#039;csspostprocess&#039;&#039; function do all the work.&lt;br /&gt;
# Make the &#039;&#039;csspostprocess&#039;&#039; function call a separate function for each setting.&lt;br /&gt;
Solution 1 might sound like the simplest however it is going to result in a &#039;&#039;&#039;VERY&#039;&#039;&#039; complex function. Remember the user might have left settings blank or entered something that wouldn&#039;t be valid so we would need to make the sure there is some validation and a good default.&lt;br /&gt;
Because of this I think that solution 2 is the better solution.&lt;br /&gt;
&lt;br /&gt;
So we are going to need a &#039;&#039;csspostprocess&#039;&#039; function and then a function for each of the three settings we have that will do the replacements.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// This is our css post process function&lt;br /&gt;
function demystified_process_css($css, $theme) {};&lt;br /&gt;
// This replaces [[setting:backgroundcolor]] with the background colour&lt;br /&gt;
function demystified_set_backgroundcolor($css, $backgroundcolor) {};&lt;br /&gt;
// This replaces [[setting:regionwidth]] with the correct region width&lt;br /&gt;
function demystified_set_regionwidth() {$css, $regionwidth};&lt;br /&gt;
// This replaces [[setting:customcss]] with the custom css&lt;br /&gt;
function demystified_set_customcss() {$css, $customcss};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you should note about the above functions is that they all start with the theme&#039;s name. This is required to ensure that the functions are named uniquely as it is VERY unlikely that someone has already created these functions.&lt;br /&gt;
&lt;br /&gt;
So with our plan set out lets start writing the code.&lt;br /&gt;
&lt;br /&gt;
===Writing the code===&lt;br /&gt;
The very first thing that we need to do is create a lib.php for our theme into which our css processing functions are going to go. So please at this point create &#039;&#039;&#039;theme/demystified/lib.php&#039;&#039;&#039; and open it in your editor ready to go.&lt;br /&gt;
&lt;br /&gt;
The first bit of code we have to write is the function that will be called by Moodle to do the processing &#039;&#039;&#039;demystified_process_css&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
Before we start out please remember that the wonderful thing about coding is that there is any number of solutions to a problem. The solutions that you are seeing here in this tutorial are solutions that I have come up with to meet fulfil the needs of the tutorial without being so complex that they are hard to understand. This probably isn&#039;t how I would go about it normally but this is a little easier to understand for those who aren&#039;t overly familiar with PHP and object orientation.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_process_css====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function demystified_process_css($css, $theme) {&lt;br /&gt;
&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;backgroundcolor)) {&lt;br /&gt;
        $backgroundcolor = $theme-&amp;gt;settings-&amp;gt;backgroundcolor;&lt;br /&gt;
    } else {&lt;br /&gt;
        $backgroundcolor = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_backgroundcolor($css, $backgroundcolor);&lt;br /&gt;
&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;regionwidth)) {&lt;br /&gt;
        $regionwidth = $theme-&amp;gt;settings-&amp;gt;regionwidth;&lt;br /&gt;
    } else {&lt;br /&gt;
        $regionwidth = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_regionwidth($css, $regionwidth);&lt;br /&gt;
&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;customcss)) {&lt;br /&gt;
        $customcss = $theme-&amp;gt;settings-&amp;gt;customcss;&lt;br /&gt;
    } else {&lt;br /&gt;
        $customcss = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_customcss($css, $customcss);&lt;br /&gt;
&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So lets look at the things that make up this function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function demystified_process_css($css, $theme) {&lt;br /&gt;
    //.....&lt;br /&gt;
    return $css&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This of course is the function declaration. &lt;br /&gt;
&lt;br /&gt;
The function gets given two variables, the first &#039;&#039;&#039;$css&#039;&#039;&#039; is a pile of CSS as one big string, and the second is the theme object &#039;&#039;&#039;$theme&#039;&#039;&#039; that contains all of the configuration, options, and settings for our theme.&lt;br /&gt;
&lt;br /&gt;
It then returns the &#039;&#039;$css&#039;&#039; variable, essentially returning the modified CSS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    //...&lt;br /&gt;
    if (!empty($theme-&amp;gt;settings-&amp;gt;backgroundcolor)) {&lt;br /&gt;
        $backgroundcolor = $theme-&amp;gt;settings-&amp;gt;backgroundcolor;&lt;br /&gt;
    } else {&lt;br /&gt;
        $backgroundcolor = null;&lt;br /&gt;
    }&lt;br /&gt;
    $css = demystified_set_backgroundcolor($css, $backgroundcolor);&lt;br /&gt;
    //...&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are processing our first setting &#039;&#039;backgroundcolor&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
The first thing that we need to do is check whether it has been set and whether it has a value. If it has then we store that value in &#039;&#039;&#039;$backgroundcolor&#039;&#039;&#039;. It is doesn&#039;t have a value then we set &#039;&#039;$backgroundcolor&#039;&#039; to null. This ensures that &#039;&#039;$backgroundcolor&#039;&#039; is set because if it isn&#039;t then you are going to get a notice (if you have debugging on).&lt;br /&gt;
&lt;br /&gt;
The final line of this block calls the function &#039;&#039;&#039;demystified_set_backgroundcolor&#039;&#039;&#039;. We haven&#039;t written this function yet but we will shortly. When we call it we give it the &#039;&#039;$css&#039;&#039; variable that contains all of the CSS and we give it the background colour variable &#039;&#039;$backgroundcolor&#039;&#039;. Once this function is finished it returns the &#039;&#039;$css&#039;&#039; variable with all of the changes made much like how our css processing function works.&lt;br /&gt;
&lt;br /&gt;
What you should also note about this code is this:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$theme-&amp;gt;settings-&amp;gt;backgroundcolor&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
As mentioned earlier &#039;&#039;$theme&#039;&#039; is an object that contains all of the configuration and settings for our theme. The &#039;&#039;$theme&#039;&#039; object has a $settings property which contains all of the settings for our theme, and finally the settings property contains a variable backgroundcolor that is the value the user entered for that setting. That is how we get a settings value.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($theme-&amp;gt;settings-&amp;gt;regionwidth)) {&lt;br /&gt;
    $regionwidth = $theme-&amp;gt;settings-&amp;gt;regionwidth;&lt;br /&gt;
} else {&lt;br /&gt;
    $regionwidth = null;&lt;br /&gt;
}&lt;br /&gt;
$css = demystified_set_regionwidth($css, $regionwidth);&lt;br /&gt;
&lt;br /&gt;
if (!empty($theme-&amp;gt;settings-&amp;gt;customcss)) {&lt;br /&gt;
    $customcss = $theme-&amp;gt;settings-&amp;gt;customcss;&lt;br /&gt;
} else {&lt;br /&gt;
    $customcss = null;&lt;br /&gt;
}&lt;br /&gt;
$css = demystified_set_customcss($css, $customcss);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These two routines are nearly identical to the routine above. For both the regionwidth and the customcss we make sure it has a value and then store it in a variable. We then call the relevant function to make the changes for that setting.&lt;br /&gt;
&lt;br /&gt;
Now that we have the general processing function it is time to write the three functions we have used but not written, &#039;&#039;demystified_set_backgroundcolor&#039;&#039;, &#039;&#039;demystified_set_regionwidth&#039;&#039;, &#039;&#039;demystified_set_customcss&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_set_backgroundcolor====&lt;br /&gt;
&lt;br /&gt;
First up demystified_set_backgroundcolor.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Sets the background colour variable in CSS&lt;br /&gt;
 *&lt;br /&gt;
 * @param string $css&lt;br /&gt;
 * @param mixed $backgroundcolor&lt;br /&gt;
 * @return string&lt;br /&gt;
 */&lt;br /&gt;
function demystified_set_backgroundcolor($css, $backgroundcolor) {&lt;br /&gt;
    $tag = &#039;[[setting:backgroundcolor]]&#039;;&lt;br /&gt;
    $replacement = $backgroundcolor;&lt;br /&gt;
    if (is_null($replacement)) {&lt;br /&gt;
        $replacement = &#039;#DDDDDD&#039;;&lt;br /&gt;
    }&lt;br /&gt;
    $css = str_replace($tag, $replacement, $css);&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ok so what is happening here?&lt;br /&gt;
&lt;br /&gt;
First we need a variable &#039;&#039;&#039;$tag&#039;&#039;&#039; that contains the tag we are going to replace. As mentioned earlier we are going to use tags that look like the image tags you are already familiar with &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:settingname]]&amp;lt;/nowiki&amp;gt;&#039;&#039;, in this case &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:backgroundcolor]]&amp;lt;/nowiki&amp;gt;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Next I am going to create a variable called &#039;&#039;&#039;$replacement&#039;&#039;&#039; into which I put &#039;&#039;&#039;$backgroundcolor&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;IF&#039;&#039;&#039; statement that comes next checks &#039;&#039;$replacement&#039;&#039; to make sure it is not null. If it is then we need to set it to a default value. In this case I have used &#039;&#039;#DDD&#039;&#039; as that was the default for the settings.&lt;br /&gt;
&lt;br /&gt;
The line after the IF statement puts it all together. The &#039;&#039;str_replace&#039;&#039; function that we are calling takes three arguments in this order:&lt;br /&gt;
# The text to search for.&lt;br /&gt;
# The text to replace it with.&lt;br /&gt;
# The text to do the replacement in.&lt;br /&gt;
It then returns the text with all of the replacements made. So in this case we are replacing the tag with the background colour and it is returning the changed CSS.&lt;br /&gt;
&lt;br /&gt;
The final thing is to return the &#039;&#039;$css&#039;&#039; variable which now contains the correct background colour.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_set_regionwidth====&lt;br /&gt;
&lt;br /&gt;
Next we have the demystified_set_regionwidth function.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Sets the region width variable in CSS&lt;br /&gt;
 *&lt;br /&gt;
 * @param string $css&lt;br /&gt;
 * @param mixed $regionwidth&lt;br /&gt;
 * @return string&lt;br /&gt;
 */&lt;br /&gt;
function demystified_set_regionwidth($css, $regionwidth) {&lt;br /&gt;
    $tag = &#039;[[setting:regionwidth]]&#039;;&lt;br /&gt;
    $doubletag = &#039;[[setting:regionwidthdouble]]&#039;;&lt;br /&gt;
    $replacement = $regionwidth;&lt;br /&gt;
    if (is_null($replacement)) {&lt;br /&gt;
        $replacement = 200;&lt;br /&gt;
    }&lt;br /&gt;
    $css = str_replace($tag, $replacement.&#039;px&#039;, $css);&lt;br /&gt;
    $css = str_replace($doubletag, ($replacement*2).&#039;px&#039;, $css);&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function is very similar to the above function however there is one key thing we are doing different. We are doing two replacements.&lt;br /&gt;
&lt;br /&gt;
# The first replacement is for the width that the user selected. In this case I am replacing the tag &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt;&#039;&#039; with the width.&lt;br /&gt;
# The second replacement is for the width x 2. This is because the page layout requires that the width be doubled for some of the CSS. Here I will replace &#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidthdouble]]&amp;lt;/nowiki&amp;gt;&#039;&#039; with the doubled width.&lt;br /&gt;
&lt;br /&gt;
Remember because it is still just a number we need to add &#039;&#039;&#039;px&#039;&#039;&#039; to the end of each before we do the replacement.&lt;br /&gt;
&lt;br /&gt;
So the overall process of this function is:&lt;br /&gt;
# Define the two tags as &#039;&#039;&#039;$tag&#039;&#039;&#039; and &#039;&#039;&#039;$doubletag&#039;&#039;&#039;.&lt;br /&gt;
# Make &#039;&#039;&#039;$replacement&#039;&#039;&#039; the region width &#039;&#039;$regionwidth&#039;&#039;.&lt;br /&gt;
# Set &#039;&#039;$replacement&#039;&#039; to a default value of 200 is it is null.&lt;br /&gt;
# Replace &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; with the width.&lt;br /&gt;
# Replace &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;[[setting:regionwidthdouble]]&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; with the width x 2.&lt;br /&gt;
# Return the changed CSS.&lt;br /&gt;
&lt;br /&gt;
====The function: demystified_set_customcss====&lt;br /&gt;
&lt;br /&gt;
The final function that we need to write is the demystified_set_customcss function.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Sets the custom css variable in CSS&lt;br /&gt;
 *&lt;br /&gt;
 * @param string $css&lt;br /&gt;
 * @param mixed $customcss&lt;br /&gt;
 * @return string&lt;br /&gt;
 */&lt;br /&gt;
function demystified_set_customcss($css, $customcss) {&lt;br /&gt;
    $tag = &#039;[[setting:customcss]]&#039;;&lt;br /&gt;
    $replacement = $customcss;&lt;br /&gt;
    if (is_null($replacement)) {&lt;br /&gt;
        $replacement = &#039;&#039;;&lt;br /&gt;
    }&lt;br /&gt;
    $css = str_replace($tag, $replacement, $css);&lt;br /&gt;
    return $css;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function is just like the first function. I&#039;m going to let you work it out on your own.&lt;br /&gt;
&lt;br /&gt;
And that is it no more PHP... Hallelujah I can hear you yelling. The final thing we need to do is tell our theme about the functions we have written and put the settings tags into the CSS.&lt;br /&gt;
&lt;br /&gt;
===Finishing it all off===&lt;br /&gt;
&lt;br /&gt;
So there are two things we have to do in order to complete this section and have our the settings page implemented and our settings being used.&lt;br /&gt;
&lt;br /&gt;
First we need to tell our theme that we want to use the function &#039;&#039;demystified_process_css&#039;&#039; as the &#039;&#039;csspostprocess&#039;&#039; function. This is done very simply by adding the following line of PHP to the bottom of our theme&#039;s config.php file &#039;&#039;&#039;theme/demystified/config.php&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;csspostprocess = &#039;demystified_process_css&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done the only thing left is to add the settings tag into the CSS. Remember those settings tags are:&lt;br /&gt;
&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:backgroundcolor]]&amp;lt;/nowiki&amp;gt; : We need to add this where ever we want the background colour setting to be used.&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt; : We need to add this where ever we want to set the width of the block regions.&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:regionwidthdouble]]&amp;lt;/nowiki&amp;gt; : We need to add this where ever we want to set the doubled width of the block regions.&lt;br /&gt;
; &amp;lt;nowiki&amp;gt;[[setting:customcss]]&amp;lt;/nowiki&amp;gt; : We need to add this to the bottom of the CSS file that we want the custom CSS added to.&lt;br /&gt;
&lt;br /&gt;
So lets make those changes in CSS now, open up your &#039;&#039;core.css&#039;&#039; file and replace the CSS with the CSS below:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/** Background color is a setting **/&lt;br /&gt;
html {background-color:[[setting:backgroundcolor]];}&lt;br /&gt;
body {margin:30px;padding:0;border:1px solid #333;border-width:0 10px 0 10px;background-color:#333;}&lt;br /&gt;
body #page {background-color:#FFF;position:relative;top:-10px;}&lt;br /&gt;
.block .header {background-image:none;background-color:#0C5CAC;border:1px solid #0C5CAC;color:#FFF;}&lt;br /&gt;
.block {border-color:#4BA7FF;background-color:#DDEEFF;}&lt;br /&gt;
.block .content {background-color:#F1F8FF;}&lt;br /&gt;
a:link,&lt;br /&gt;
a:visited {color:#0C5CAC;}&lt;br /&gt;
a:hover {color:#C77500;}&lt;br /&gt;
#page #page-header {background-color:#0C5CAC;margin:0;padding:0;width:100%;color:#fff;}&lt;br /&gt;
#page #page-header a:link, #page #page-header a:visited {color:#FFAC02}&lt;br /&gt;
#page #page-header .navbar, #page #page-header .navbar a:link, #page #page-header .navbar a:visited {color:#0C5CAC;}&lt;br /&gt;
/** Override the region width **/&lt;br /&gt;
#page-content #region-main-box {left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidthdouble]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-pre {width:[[setting:regionwidth]];left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-post {width:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidthdouble]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
/** Custom CSS **/&lt;br /&gt;
[[setting:customcss]]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will notice that &amp;lt;nowiki&amp;gt;[[setting:backgroundcolor]]&amp;lt;/nowiki&amp;gt; has been used for the html tags background colour:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
html {background-color:[[setting:backgroundcolor]];}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have also set the width of the block regions by adding &amp;lt;nowiki&amp;gt;[[setting:regionwidth]]&amp;lt;/nowiki&amp;gt; as the width for region-pre and region-post as shown below:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
#page-content #region-main-box {left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidthdouble]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-pre {width:[[setting:regionwidth]];left:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-post {width:[[setting:regionwidth]];}&lt;br /&gt;
#page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidthdouble]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-pre-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box {margin-left:-[[setting:regionwidth]];}&lt;br /&gt;
.side-post-only #page-content #region-main-box #region-post-box #region-main-wrap #region-main {margin-left:[[setting:regionwidth]];}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
You&#039;ll notice here that we have to set several different widths and margins using the regionwidth setting and make use of the special regionwidthdouble setting that we added.&lt;br /&gt;
&lt;br /&gt;
The final thing that we did was add the &amp;lt;nowiki&amp;gt;[[setting:customcss]]&amp;lt;/nowiki&amp;gt; to the bottom of the file to ensure that the custom CSS comes last (and therefore can override all other CSS).&lt;br /&gt;
&lt;br /&gt;
And with that we are finished. The screenshot below shows how this now looks in the browser if I set the background colour setting to &#039;&#039;&#039;&amp;lt;span style=&#039;color:#FFA800;&#039;&amp;gt;#FFA800&amp;lt;/span&amp;gt;&#039;&#039;&#039; and made the column width 240px;&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.04.png|715px|thumb|left|Our settings in action]]&amp;lt;br style=&amp;quot;clear:both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using the settings within our layout files==&lt;br /&gt;
Now that we have utilised the first three settings within our theme&#039;s CSS file it is time to implement the other two settings within the layout files so that they are written directly into the page.&lt;br /&gt;
&lt;br /&gt;
You&#039;ll be glad to know this is no where near as difficult as utilising settings within a CSS file although it still does require a little bit of PHP.&lt;br /&gt;
&lt;br /&gt;
First up is the logo setting. Into this setting the user is able to enter the URL to an image to use as the logo for the site. In my case I want this to be just a background logo on top of which I want to position the page header.&lt;br /&gt;
&lt;br /&gt;
Before I start there is one thing I need to do however and that is create a default logo background that gets shown if the user hasn&#039;t set a specific logo file. To do this I simply created an image &#039;&#039;&#039;logo.jpg&#039;&#039;&#039; and put it into a pix directory within the demystified theme. You should end up with &#039;&#039;&#039;theme/demystified/pix/logo.jpg&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Next open up the front-page layout file &#039;&#039;theme/demystified/layout/frontpage.php&#039;&#039;. At the top of the file is the PHP that checks what blocks regions the page has and a bit of other stuff. Well right below the existing bit of PHP we want to add the following code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;logo)) {&lt;br /&gt;
    $logourl = $PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;logo;&lt;br /&gt;
} else {&lt;br /&gt;
    $logourl = $OUTPUT-&amp;gt;pix_url(&#039;logo&#039;, &#039;theme&#039;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
What we are doing here is creating a variable called $logourl that will contain the URL to a logo file that was either entered by the user or if they left it blank is that of our default logo file.&lt;br /&gt;
&lt;br /&gt;
There are two things that you should notice about this. First the logo setting can be retrieved through &#039;&#039;&#039;$PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;logo&#039;&#039;&#039; and second we get the default logo url by calling &#039;&#039;&#039;$OUTPUT-&amp;gt;pix_url(&#039;logo&#039;, &#039;theme&#039;)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Now that we have the logo URL we are going to use we need to add an image to the header section of the page as shown below:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;page-header&amp;quot; class=&amp;quot;clearfix&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;img class=&amp;quot;sitelogo&amp;quot; src=&amp;quot;&amp;lt;?php echo $logourl;?&amp;gt;&amp;quot; alt=&amp;quot;Custom logo here&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;
....&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you save that and browse to your sites front page you will notice that the logo file is now being shown. Hooray. However it is probably not styled too nicely so lets quickly fix that. Open up the core.css file and add the following lines of CSS to the bottom of the file.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
#page-header {position:relative;min-height:100px;}&lt;br /&gt;
#page-header .sitelogo {float:left;}&lt;br /&gt;
#page-header .headermain {position:absolute;left:0.5em;top:50px;margin:0;float:none;font-size:40px;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
These three lines position the image correctly and if you now refresh everything should appear perfectly. &lt;br /&gt;
&lt;br /&gt;
With the logo done the last setting we need to deal with is the footnote setting. The idea with this setting was that the administrator could enter some text into the editor and it would be displayed in the footer of the page.&lt;br /&gt;
&lt;br /&gt;
This is probably the easiest setting to implement.&lt;br /&gt;
&lt;br /&gt;
Within the front page layout file that we edited above add the following lines below those we added previously.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;footnote)) {&lt;br /&gt;
    $footnote = $PAGE-&amp;gt;theme-&amp;gt;settings-&amp;gt;footnote;&lt;br /&gt;
} else {&lt;br /&gt;
    $footnote = &#039;&amp;lt;!-- There was no custom footnote set --&amp;gt;&#039;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are just collecting the footnote into a variable &#039;&#039;&#039;$footnote&#039;&#039;&#039; and setting a default footnote comment if the user hasn&#039;t entered one.&lt;br /&gt;
&lt;br /&gt;
We can now echo the $footnote variable within the page footer. This can be done as shown below.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;!-- START OF FOOTER --&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;footnote&amp;quot;&amp;gt;&amp;lt;?php echo $footnote; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;p class=&amp;quot;helplink&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;?php echo page_doc_link(get_string(&#039;moodledocslink&#039;)) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And with that done we are finished! Congratulations if you got this far.&lt;br /&gt;
&lt;br /&gt;
The screenshot below shows the demystified theme we have just created that is styled by the settings page.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.05.png|715px|thumb|left|My finished demystified theme]]&amp;lt;br style=&amp;quot;clear:both&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing our creation==&lt;br /&gt;
Congratulations to you! If you&#039;ve made it this far you have done very well. Now it is time to have a look at what we have created and give it a quick test run.&lt;br /&gt;
&lt;br /&gt;
So in this tutorial we have achieved the following:&lt;br /&gt;
&lt;br /&gt;
* We created a theme called demystified that is based on the standard theme.&lt;br /&gt;
* We added a settings page to our new theme.&lt;br /&gt;
* We added the following settings to our settings page:&lt;br /&gt;
** We can set a background colour through the admin interface.&lt;br /&gt;
** We can change the logo of the site.&lt;br /&gt;
** We can change the block region width.&lt;br /&gt;
** We can add a footnote to the page footer&lt;br /&gt;
** We can add some custom CSS to seal the deal.&lt;br /&gt;
* Those settings were then used in the CSS files for our theme.&lt;br /&gt;
* They were also used in the layout files for our theme.&lt;br /&gt;
* And here we are testing it all.&lt;br /&gt;
&lt;br /&gt;
The screenshots below show my testing process and I change each setting and view the outcome. The great thing about this is that with theme designer mode on you see the changes as soon as the form refreshes.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.06.png|300px|thumb|left|Default settings]]&lt;br /&gt;
[[Image:Theme.settings.page.07.png|300px|thumb|left|Changed the background colour setting]]&lt;br /&gt;
[[Image:Theme.settings.page.08.png|300px|thumb|left|Changed the logo and region width]]&lt;br /&gt;
[[Image:Theme.settings.page.09.png|300px|thumb|left|Added a footnote]]&lt;br /&gt;
[[Image:Theme.settings.page.10.png|300px|thumb|left|Added some custom CSS]]&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:both&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The different settings you can use==&lt;br /&gt;
During this tutorial we use four different kinds of settings, a text box, text area, a select (dropdown) and the editor however as I&#039;m sure you have all guessed there is many more some of which will certainly be useful for theme settings.&lt;br /&gt;
&lt;br /&gt;
The following are examples of some of the different settings. I should add that these build upon what we have already done within the tutorial but are not included in the download.&lt;br /&gt;
&lt;br /&gt;
===Colour picker===&lt;br /&gt;
[[Image:Theme.settings.page.11.png|400px|thumb|The colour picker]]&lt;br /&gt;
I can hear you all asking now &#039;Why didn&#039;t you mention this one earlier?&#039; well the answer is simple it didn&#039;t exist when I first wrote the tutorial. It is an admin setting that I wrote several days after because of the fantastic effort people were putting into trying out settings pages.&lt;br /&gt;
&lt;br /&gt;
A bit about the colour picker. First up it is a text box that when the page loads turns into a colour picker that can be used to select a colour and can even preview the selected colour in the page (by clicking the preview button). It is designed to be very easy to use and the code is just about as simple as creating a normal text box setting.&lt;br /&gt;
&lt;br /&gt;
In the image to the left I have replaced the background colour setting we created during the tutorial with the colour picker. Lets have a look at the code involved for that.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Background colour setting&lt;br /&gt;
$name = &#039;theme_demystified/backgroundcolor&#039;;&lt;br /&gt;
$title = get_string(&#039;backgroundcolor&#039;,&#039;theme_demystified&#039;);&lt;br /&gt;
$description = get_string(&#039;backgroundcolordesc&#039;, &#039;theme_demystified&#039;);&lt;br /&gt;
$default = &#039;#DDD&#039;;&lt;br /&gt;
$previewconfig = array(&#039;selector&#039;=&amp;gt;&#039;html&#039;, &#039;style&#039;=&amp;gt;&#039;backgroundColor&#039;);&lt;br /&gt;
$setting = new admin_setting_configcolourpicker($name, $title, $description, $default, $previewconfig);&lt;br /&gt;
$temp-&amp;gt;add($setting);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
So first thing you should notice is that the first four lines of code have not changed at all!&lt;br /&gt;
&lt;br /&gt;
The first change we have is to create a variable &#039;&#039;&#039;$previewconfig&#039;&#039;&#039;. &lt;br /&gt;
This variable is used to tell the colour picker what to do when the user clicks the preview button. It should be an array that contains two things, first a selector, and second a style. &lt;br /&gt;
# The selector is a CSS selector like &#039;&#039;.page .header h2&#039;&#039;.&lt;br /&gt;
# The style is a what should change, there are two immediate values it can be, either &#039;&#039;&#039;backgroundColor&#039;&#039;&#039; or &#039;&#039;&#039;color&#039;&#039;&#039;.&lt;br /&gt;
In my case the selector is &#039;&#039;&#039;html&#039;&#039;&#039; to target the html tag and the style is backgroundColor to change the background colour.&lt;br /&gt;
&lt;br /&gt;
The second change is to use &#039;&#039;&#039;admin_setting_configcolourpicker&#039;&#039;&#039; instead of &#039;&#039;admin_setting_configtext&#039;&#039;. The arguments are nearly identical as well except that there is an extra argument to which we give the &#039;&#039;&#039;$previewconfig&#039;&#039;&#039; variable.&lt;br /&gt;
&lt;br /&gt;
And that is it! it is all you need to get the colour picker up and running.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Extra note:&#039;&#039;&#039; The $previewconfig variable is optional. If you don&#039;t want a preview button the simply set &#039;&#039;$previewconfig = null&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Common pitfalls and useful notes==&lt;br /&gt;
&lt;br /&gt;
This section is really just a collection of pointers, tips, notes, and other short useful stuff that may be of use to those attempting this tutorial.&lt;br /&gt;
&lt;br /&gt;
# First up and most importantly there are very few limitations to what you achieve in this fashion.&lt;br /&gt;
# If you get stuck or need a hand ask in the forums, there&#039;s always someone round who can help.&lt;br /&gt;
# If you do something really cool let us know, I know everyone in the community loves finding our what others are achieving.&lt;br /&gt;
# You don&#039;t have to use &#039;&#039;admin_settingpage&#039;&#039; you can also use &#039;&#039;&#039;admin_externalpage&#039;&#039;&#039; if you prefer. It should be noted however that it is not the preferred way to do it as admin_externalpage&#039;s were only left in Moodle 2.0 for backwards compatibility (although they are more flexible one day they will be deprecated or removed). Thank you to Darryl for raising this.&lt;br /&gt;
# If you find that your language strings aren&#039;t being used (you are getting language string notices) and you have double checked that you have turned &#039;&#039;&#039;langstringcache&#039;&#039;&#039; off then you may need to delete the language cache directory. This is located in the moodledata directory for you installation: moodledata/cache/lang/*. You should delete the directory for your chosen language by default &#039;&#039;en&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Adding theme upgrade code]]&lt;br /&gt;
* [[Styling and customising the dock]]&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/discuss.php?d=152053 Theme 2.0: Adding a settings page to your theme] forum discussion&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Moodle.org_forums_help&amp;diff=43733</id>
		<title>Moodle.org forums help</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Moodle.org_forums_help&amp;diff=43733"/>
		<updated>2014-02-06T11:42:04Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Example of new post */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Moodle Forums are a tremendous resource. For a new user, they can be confusing and overpowering. This page will provide more details to points raised in the [[Forums code of conduct]].&lt;br /&gt;
&lt;br /&gt;
The 3 most important things to remember: Ask your question in the right place, write a good discussion/subject title, include information that will help solve the problem, and enjoy Moodling.&lt;br /&gt;
:Ooops, classic writing always has 3 things that are important but enjoying life is right up there for most Moodlers. &lt;br /&gt;
&lt;br /&gt;
==The basics==&lt;br /&gt;
=== Ask your question in the right forum===&lt;br /&gt;
The first important thing you need to do is find the right forum to ask the question.  We recommend the [http://moodle.org/mod/forum/search.php?search=&amp;amp;id=5 Forum search tool] or even the [https://docs.moodle.org/en/Main_Page?search=&amp;amp;go=Go &amp;quot;Search moodle.org&amp;quot; tool] found on most pages in the upper right corner.   At least look over the [http://moodle.org/course/view.php?id=5 list of forums] and remember there are [http://moodle.org/course/category.php?id=3 forums in many other languages] besides English or check [[:Category:FAQ|the list of frequently asked questions categories]]&lt;br /&gt;
&lt;br /&gt;
If you really do not know which forum to post in, go to the [http://moodle.org/mod/forum/view.php?id=50 General help forum].&lt;br /&gt;
&lt;br /&gt;
===Write a subject line (discussion topic) that is a one-line summary of your question=== &lt;br /&gt;
&lt;br /&gt;
The subject line or a discussion topic is like a advertisement.  You want experts who know how to solve your problem to give you the answer.   Helpful Moodlers, or those looking for a solution to a problem just like yours,  do not always read every post.  They do scan the subject lines on a forum.  The subject line should let them know what your problem is about.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;TIP:&#039;&#039;  People already know you need help because you took the time to post :) &lt;br /&gt;
&lt;br /&gt;
:For example, you are having trouble locating newly created course topics in your Moodle installation, a subject line like &amp;quot;Help My Moodle is broken!&amp;quot; or &amp;quot;PLEASE HELP ME!!!&amp;quot; is less likely to encourage people to read and answer your question than a subject line like: &amp;quot;Moodle 1.8.4, new course topics missing.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Things to include in the content of your post===&lt;br /&gt;
Now that you have interested Moodlers opening your post, you can speed up the process that will give you a solution by including information in the initial post.   Many times a helpful Moodler will ask you for this information or make a wrong assumption.   All this takes time to get the basics. In the best of all possible worlds, you want the solution yesterday, not after 3 or 4 replies that go into next week :)&lt;br /&gt;
&lt;br /&gt;
====Your question should contain====&lt;br /&gt;
:&#039;&#039;TIP:&#039;&#039; If you don&#039;t have all this information, fill in as much as you can.&lt;br /&gt;
&lt;br /&gt;
* The version of Moodle used (or upgraded To or From). &#039;&#039;&#039; Most important information&#039;&#039;&#039;&lt;br /&gt;
* The server operating system and version [e.g. RedHat Linux 9.1, Mac OS X 1.4, Windows 2000, etc.]&lt;br /&gt;
* The web server used [e.g. Apache 1.3.18, Apache 2.0.63, IIS 5, IIS 6, etc]&lt;br /&gt;
* The PHP version used [e.g. 4.47, 5.23. 5.25, etc]&lt;br /&gt;
* The database used [MySQL 5.0.41, PostgresQL 7.4, Windows Sequel 2000, etc]&lt;br /&gt;
* The version of the addin or special feature you are trying to use, if any&lt;br /&gt;
&lt;br /&gt;
*And of course your post should contain your question.  See heading below.&lt;br /&gt;
&lt;br /&gt;
====Remember to keep the story simple====&lt;br /&gt;
Your question should be more like a (very) short story than a novel.  It should be direct and to the point.  Like any good report or story, tell what you did leading up to the problem, what the problem looked like and perhaps things you did to try to solve it.  &lt;br /&gt;
&lt;br /&gt;
Many problems have happened before and helpful Moodlers will recognize these right away.  So try to keep the story simple.  &lt;br /&gt;
&lt;br /&gt;
:And remember, helpful Moodlers do understand frustrations, deadlines and what is like to use a program for the first time and/or not have it cooperate.  If you must vent, a simple &amp;quot;I am frustrated&amp;quot; is enough detail.&lt;br /&gt;
&lt;br /&gt;
==Good post==&lt;br /&gt;
Several helpful Moodlers have suggested examples of a good post. &lt;br /&gt;
===Example of new post ===&lt;br /&gt;
[[Image:Forum Post Example edit mode2.png|frame|center|New post example.  This teacher is also a site administrator, so they know about their Moodle site.  The Moodle version is the minimum requirement.]]&lt;br /&gt;
&lt;br /&gt;
===Explanation of Example===&lt;br /&gt;
The subject line describes the problem.  The poster knows that other versions of Moodle did not have this problem and included it in the subject line.  &lt;br /&gt;
&lt;br /&gt;
This question first lists the Moodle version, server operating system, web server software, PHP version and MySQL database version. It might include information about the computer and versions of add-in modules.  Some like to put this basic info at the bottom of their post. As we have said before, put what you know.&lt;br /&gt;
&lt;br /&gt;
The short story includes: the events leading up to the problem, the problem itself, and a request for a resource that might help the questioner solve his own problem.&lt;br /&gt;
Knowledgeable Moodlers with experience or insight into that particular problem may even offer solutions in lieu of, or in addition to, any available resources  that the questioner requested.&lt;br /&gt;
&lt;br /&gt;
===How it looks in a forum list===&lt;br /&gt;
[[Image:Forum Post Discussion List.png|center|frame|Help people who know find your problem. We added the NOT and Check icons.]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;If you are a volunteer Helpful Moodler with limited time, you will first look at the topics you know something about.&#039;&#039;&#039;  &amp;quot;Please help me&amp;quot; will not be at the top of that list. In fact the &amp;quot;Please help me!!!&amp;quot; could contain the same content as any of the other 3 discussion threads.&lt;br /&gt;
&lt;br /&gt;
==Editing your message in the Forum==&lt;br /&gt;
&lt;br /&gt;
Sometimes after posting a question in the Forum you may realize that you&#039;ve  omitted some important information, left out a word or phrase, or made  some typographical error that needs to be corrected.  For the first 30 minutes after you posted your question you can simply click on the Edit link at the lower right side of your message and return to the Moodle editor to make corrections,  You can edit both the body of your Forum posting and the Subject line until the time period expires.&lt;br /&gt;
== Posting a Follow-up Message ==&lt;br /&gt;
&lt;br /&gt;
===Reply to your own message to update its content===&lt;br /&gt;
Replying to your own message is a good way to update information or even suggest an answer to your original question.    &lt;br /&gt;
&lt;br /&gt;
Many Forum users read the messages using a &amp;quot;threaded&amp;quot; view.  In the &amp;quot;threaded&amp;quot; view messages are grouped according to their Subject line. Each message descends from its parent message according to its date.  The oldest messages are at the top of the thread and each reply is nested below the original message.  When you reply to your own message and keep the Subject intact, you not only have the opportunity to change or clarify the original question (or other information) that you posted, but you ensure its position in the thread by keeping it directly below your original posting.  In that position people are more likely to see your messages, read through the thread and reply to your most recent post.  If you change your Subject line, the message will still be available in the threaded view beneath your original post, but that change may make the message&#039;s context less obvious and lessen the likelihood that you&#039;ll receive a helpful reply.&lt;br /&gt;
&lt;br /&gt;
Forum users who read messages in a &amp;quot;list&amp;quot; view, see messages vertically descending from oldest to newest with replies descending vertically from original messages.  Quite often a reader must scroll down the page to follow the replies.  These message postings and their replies are not grouped by subject but stacked below the oldest messages.  A long scroll down a page can make it difficult to follow a message and its replies; a long scroll down a page to a message with a new subject makes it extremely difficult to follow the context of the original message and (if you can find them) the original message&#039;s replies.&lt;br /&gt;
&lt;br /&gt;
===Quote sparingly from your original message===&lt;br /&gt;
&lt;br /&gt;
If you need to highlight inaccurate or incomplete information in your original message, quote just that specific information at the top of your message. There is no need to quote your entire original message.  &lt;br /&gt;
&lt;br /&gt;
There are many different ways to quote original content in a reply.  We recommend the single &amp;quot;greater-than&amp;quot; sign (the &amp;gt; symbol) at the beginning of each line you are quoting. &lt;br /&gt;
&lt;br /&gt;
:&amp;gt; Why doesn&#039;t the screen show the changes I made?&lt;br /&gt;
&lt;br /&gt;
Some people will quote previous message segments by using italics to highlight the quote, but this method (and any method that uses stylized test) may make it difficult for people using an adaptive technology method (screen reader software) to read the message and determine what is a quote from a previous message and what is actually new information.  &lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;Tip:&#039;&#039; If you have kept your Subject line intact, the original post will still be available in the thread or the message listing.&lt;br /&gt;
&lt;br /&gt;
===Topic creep - recognize when you are asking a new question===&lt;br /&gt;
Sometimes one question will naturally lead to another in a reply post.  Sometimes it is best to start a new topic and consider if the current forum is the best place to ask the new question.  For example, you might ask about different ways to score a muliple choice question in the Lesson forum, but then ask about how questions are scored and graded in a Quiz.  &lt;br /&gt;
&lt;br /&gt;
Forum threads can be split and moved to new forums.    Some Moodlers will ignore questions when they are off topic or belong in another forum.&lt;br /&gt;
&lt;br /&gt;
==Good manners==&lt;br /&gt;
=== Patience is still a Virtue so, please, be virtuous===&lt;br /&gt;
&lt;br /&gt;
If you post a message that needs additional clarification it is likely that there may be some additional delay before the message receives a reply.  Forum readers are likely to initially skip questions that are missing  important information --it is difficult to provide an accurate answer when the question, itself, is unclear.  Please wait at least 48 hours before you post another message on the same subject.  Please remember that Forum readers are from all around the world and the time zone differences may delay even immediate responses by 12 to 14 hours.&lt;br /&gt;
&lt;br /&gt;
If you require urgent help, or have a complicated problem, you may wish to consider paid support from a Moodle Partner.&lt;br /&gt;
&lt;br /&gt;
===Try to resist emailing or messaging users directly===&lt;br /&gt;
&lt;br /&gt;
It might be tempting to email the maintainer of the module you have a question about. You are almost always better asking questions in a forum as the audience is much bigger.  Remember that Moodle contributors take holidays (sometimes).  And some helpful Moodlers like to answer the simple questions, so that those with more technical knowledge have time to answer the tougher questions.&lt;br /&gt;
&lt;br /&gt;
However, do not worry about &amp;quot;clogging&amp;quot; up the forums or asking a stupid question in public.  There are so many users in Moodle Land that someone has probably seen a similar issue and your question will help them clarify their issues, or suggest to someone they need to add some words to Moodle Docs.&lt;br /&gt;
&lt;br /&gt;
===Bad behavior ===&lt;br /&gt;
Questions and comments which are rude, incomprehensible or inappropriate in a multi cultural, world wide environment will not be tolerated.  In short, be respectful.&lt;br /&gt;
&lt;br /&gt;
Mistakes and misunderstandings happen. It is your actions and words that people will remember, and others are no different than yourself.   A brief apology is always acceptable even when you intended no harm but believe someone else reacted unexpectedly to your post.   &lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;Tip:&#039;&#039;  If you are frustrated by your experience and feel the need to rant (as we all do sometimes), please remember that these Help forums are not the place for diatribes or flames.  If you feel the need to address an aspect of Moodle or the online digital environment with other Moodle users that doesn&#039;t fit into any of the Help topics, you can use the Lounge (the Social Forum) for general discussions. But even in the Lounge, civil discourse is the Rule of the Day.&lt;br /&gt;
&lt;br /&gt;
==Who answers those posts==&lt;br /&gt;
The Moodle Forums are  free, community-supported, resources.  Almost all of the participants donate their time and brain-power to the further refining of Moodle. These resources have made Moodle an excellent and evolving learning management system.   &lt;br /&gt;
&lt;br /&gt;
Moodle itself is provided without license fees to the general public and the Moodle community contributes to its success.&lt;br /&gt;
&lt;br /&gt;
The Moodle Forums are a tremendous resource in the world of open source community-supported learning management systems.  They will continue to evolve and improve as long as all of the participants also continue to be dedicated to their own improvement and that of the entire Moodle community.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Forums code of conduct]]&lt;br /&gt;
* [http://catb.org/~esr/faqs/smart-questions.html How To Ask Questions The Smart Way] by Eric Raymond, is a classic, if opinionated essay on this subject.&lt;br /&gt;
&lt;br /&gt;
[[Category:Moodle.org]]&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Theme_checklist&amp;diff=43542</id>
		<title>Theme checklist</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Theme_checklist&amp;diff=43542"/>
		<updated>2014-01-16T00:06:20Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Right-to-left languages */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}So, you think your theme is finished? Well, Moodle is a big complex beast, and there are lots of obscure corners, that you might not know about. This page lists lots of things that you might have missed when working on your theme. To be sure your theme is really complete, you need to check these out.&lt;br /&gt;
&lt;br /&gt;
== All the different forms of the front page ==&lt;br /&gt;
&lt;br /&gt;
Depending on how many courses there are in your Moodle site, and how many of them the current user is enrolled in, the [[:en:Front_page|front page]] looks different. Have you tested all the different ways it can look?&lt;br /&gt;
&lt;br /&gt;
== Big report tables ==&lt;br /&gt;
&lt;br /&gt;
The [[:en:Gradebook|grader report]], and other similar reports like the quiz reports, are very big tables that don&#039;t fit on one screen. How does your theme cope. Is it easy for the teacher to scroll sideways to see all the data?&lt;br /&gt;
&lt;br /&gt;
== Quiz &#039;secure&#039; pop-up ==&lt;br /&gt;
&lt;br /&gt;
When a quiz set to [[:en:Quiz_settings#Extra_restrictions_on_attempts|Full screen pop-up with some JavaScript security]] then the page uses a special &#039;secure&#039; layout template that should have minimal headers or links.&lt;br /&gt;
&lt;br /&gt;
== Fake blocks ==&lt;br /&gt;
&lt;br /&gt;
While you are looking at the quiz, pay attention to the [[:en:Using_Quiz|Quiz navigation block]]. This is not a normal block that teachers or admins can add or remove, it is a &#039;Fake block&#039; that looks like any other block but is part of the Moodle UI. Are you happy with where it appears, and how it looks?&lt;br /&gt;
&lt;br /&gt;
Other parts of Moodle that use fake blocks are the [[:en:Lesson_module|Lesson activity]] and [[:en:Calendar|the calendar UI]].&lt;br /&gt;
&lt;br /&gt;
== Right-to-left languages ==&lt;br /&gt;
&lt;br /&gt;
In languages like Hebrew or Farsi, lots of things that you made left-aligned probably need to be right-aligned instead. Moodle adds .dir-rtl or .dir-ltr class to the body element, which you can use in CSS rules.&lt;br /&gt;
&lt;br /&gt;
== ... please add more things here ... ==&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Clean_theme&amp;diff=42838</id>
		<title>Clean theme</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Clean_theme&amp;diff=42838"/>
		<updated>2013-11-02T12:52:52Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Include a renderer in a bootstrap based theme */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}{{Moodle 2.5}}This document describes how to copy and customise the Clean (bootstrapbase) theme so that you can build on this to create a theme of your own. It assumes you have some understanding of how themes work within Moodle 2.5, as well as a basic understanding of HTML and CSS. Also, because of the rapid development within Moodle, resulting in a number of versions available namely 2.3.x and 2.4.x, and 2.5.x it is important to understand that this tutorial is only valid for the Moodle 2.5+ Clean theme.&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
From your Moodle &#039;&#039;&#039;theme&#039;&#039;&#039; directory &#039;&#039;&#039;right click&#039;&#039;&#039; on the &#039;&#039;&#039;clean&#039;&#039;&#039; theme and then &#039;&#039;&#039;&#039;&#039;copy&#039;&#039;&#039; and  &#039;&#039;&#039;paste&#039;&#039;&#039;&#039;&#039; back into your Moodle &#039;&#039;&#039;theme&#039;&#039;&#039; directory. You should now have a folder called &#039;&#039;&#039;Copy of clean&#039;&#039;&#039;. If you &#039;&#039;&#039;right click&#039;&#039;&#039; this folder you are given the option to &#039;&#039;&#039;Rename&#039;&#039;&#039; it. So rename this folder to your choosen theme name, using only lower case letters, and if needed, underscores. For the purpose of this tutorial we will call the theme &#039;cleantheme&#039;.&lt;br /&gt;
&lt;br /&gt;
On opening &#039;cleantheme&#039; you will find several files and sub-directories which have files within them.&lt;br /&gt;
&lt;br /&gt;
These are:&lt;br /&gt;
; config.php :  Where all the theme configurations are made. &#039;&#039;(contains some elements that require renaming)&#039;&#039;&lt;br /&gt;
; lib.php :  Where all the functions for the themes settings are found. &#039;&#039;(contains some elements that require renaming)&#039;&#039;&lt;br /&gt;
; settings.php :  Where all the setting for this theme are created. &#039;&#039;(contains some elements that require renaming)&#039;&#039;&lt;br /&gt;
; version.php :  Where the version number and plugin componant information is kept. &#039;&#039;(contains some elements that require renaming)&#039;&#039;&lt;br /&gt;
; /lang/ : This directory contains all language sub-directories for other languages if and when you want to add them.&lt;br /&gt;
; /lang/en/ : This sub-directory contains your language files, in this case &#039;&#039;English&#039;&#039;.&lt;br /&gt;
; /lang/en/theme_clean.php : This file contains all the language strings for your theme. &#039;&#039;(contains some elements that require renaming as well as the filename itself)&#039;&#039;  &lt;br /&gt;
; /layout/ : This directory contains all the layout files for this theme.&lt;br /&gt;
; /layout/columns1.php : Layout file for a one column layout (content only).&lt;br /&gt;
; /layout/columns2.php : Layout file for a two column layout (side-pre and content).&lt;br /&gt;
; /layout/columns3.php : Layout file for a three column layout (side-pre, content and side-post) and the front page.&lt;br /&gt;
; /layout/embedded.php : Embedded layout file for embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible.&lt;br /&gt;
; /layout/maintenance.php : Maintenance layout file which does not have any blocks, links, or API calls that would lead to database or cache interaction.&lt;br /&gt;
; /layout/secure.php : Secure layout file for safebrowser and securewindow.&lt;br /&gt;
; /style/ : This directory contains all the CSS files for this theme.&lt;br /&gt;
; /style/custom.css : This is where all the settings CSS is generated.&lt;br /&gt;
; /pix/ : This directory contains a screen shot of this theme as well as a favicon and any images used in the theme.&lt;br /&gt;
&lt;br /&gt;
==Renaming Elements==&lt;br /&gt;
&lt;br /&gt;
The problem when &#039;&#039;&#039;cloning&#039;&#039;&#039; a theme is that you need to rename all those instances where the old theme name occurs, in this case &#039;&#039;&#039;clean&#039;&#039;&#039;. So using the above list as a guide, search through and change all the instances of the theme name &#039;clean&#039; to &#039;cleantheme&#039;. This includes the filename of the lang/en/theme_clean.php. You need to change this to &#039;theme_cleantheme.php&#039;.&lt;br /&gt;
&lt;br /&gt;
==Installing your theme==&lt;br /&gt;
&lt;br /&gt;
Once all the changes to the name have been made, you can safely install the theme. If you are already logged in just refreshing the browser should trigger your Moodle site to begin the install &#039;Plugins Check&#039;. If not then navigate to Administration &amp;gt; Notifications.&lt;br /&gt;
&lt;br /&gt;
Once your theme is successfully installed you can select it and begin to modify it using the custom settings page found by navigating to Administration &amp;gt; Site Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt;&amp;gt; and then click on (Cleantheme) or whatever you renamed your theme to, from the list of theme names that appear at this point in the side block.&lt;br /&gt;
&lt;br /&gt;
==Include a renderer in a bootstrap based theme==&lt;br /&gt;
&lt;br /&gt;
If you need to override any renderers in your theme, then make sure you override the renderers by extending the parent theme renderers, which in this case is bootstrapbase. For example the class that you need to start your renderer with is as follows...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
class theme_yourtheme_core_renderer extends theme_bootstrapbase_core_renderer {&lt;br /&gt;
 &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...where &#039;&#039;&#039;&#039;yourtheme&#039;&#039;&#039;&#039; requires you to change it to your theme name otherwise it will not work.&lt;br /&gt;
&lt;br /&gt;
(Please note: The normal recipe &amp;lt;tt&amp;gt;class theme_&#039;&#039;&#039;yourtheme&#039;&#039;&#039;_core_renderer extends core_renderer&amp;lt;/tt&amp;gt; is wrong for themes whose parent theme uses renderers, because this method will ultimately conflict with the parent theme&#039;s renderers.)&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [http://www.somerandomthoughts.com/blog/2013/05/08/moodle-2-5-and-the-bootstrap-based-theme-clean/ Moodle 2.5 and the Bootstrap based theme – Clean] blog post by Gavin Henrick&lt;br /&gt;
* [http://basbrands.nl/blog/2013/05/21/building-with-bootstrap/ Building With Bootstrap] blog post by Bas Brands&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Clean_theme&amp;diff=42837</id>
		<title>Clean theme</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Clean_theme&amp;diff=42837"/>
		<updated>2013-11-02T12:50:22Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Include a renderer in a bootstrap based theme */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}{{Moodle 2.5}}This document describes how to copy and customise the Clean (bootstrapbase) theme so that you can build on this to create a theme of your own. It assumes you have some understanding of how themes work within Moodle 2.5, as well as a basic understanding of HTML and CSS. Also, because of the rapid development within Moodle, resulting in a number of versions available namely 2.3.x and 2.4.x, and 2.5.x it is important to understand that this tutorial is only valid for the Moodle 2.5+ Clean theme.&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
From your Moodle &#039;&#039;&#039;theme&#039;&#039;&#039; directory &#039;&#039;&#039;right click&#039;&#039;&#039; on the &#039;&#039;&#039;clean&#039;&#039;&#039; theme and then &#039;&#039;&#039;&#039;&#039;copy&#039;&#039;&#039; and  &#039;&#039;&#039;paste&#039;&#039;&#039;&#039;&#039; back into your Moodle &#039;&#039;&#039;theme&#039;&#039;&#039; directory. You should now have a folder called &#039;&#039;&#039;Copy of clean&#039;&#039;&#039;. If you &#039;&#039;&#039;right click&#039;&#039;&#039; this folder you are given the option to &#039;&#039;&#039;Rename&#039;&#039;&#039; it. So rename this folder to your choosen theme name, using only lower case letters, and if needed, underscores. For the purpose of this tutorial we will call the theme &#039;cleantheme&#039;.&lt;br /&gt;
&lt;br /&gt;
On opening &#039;cleantheme&#039; you will find several files and sub-directories which have files within them.&lt;br /&gt;
&lt;br /&gt;
These are:&lt;br /&gt;
; config.php :  Where all the theme configurations are made. &#039;&#039;(contains some elements that require renaming)&#039;&#039;&lt;br /&gt;
; lib.php :  Where all the functions for the themes settings are found. &#039;&#039;(contains some elements that require renaming)&#039;&#039;&lt;br /&gt;
; settings.php :  Where all the setting for this theme are created. &#039;&#039;(contains some elements that require renaming)&#039;&#039;&lt;br /&gt;
; version.php :  Where the version number and plugin componant information is kept. &#039;&#039;(contains some elements that require renaming)&#039;&#039;&lt;br /&gt;
; /lang/ : This directory contains all language sub-directories for other languages if and when you want to add them.&lt;br /&gt;
; /lang/en/ : This sub-directory contains your language files, in this case &#039;&#039;English&#039;&#039;.&lt;br /&gt;
; /lang/en/theme_clean.php : This file contains all the language strings for your theme. &#039;&#039;(contains some elements that require renaming as well as the filename itself)&#039;&#039;  &lt;br /&gt;
; /layout/ : This directory contains all the layout files for this theme.&lt;br /&gt;
; /layout/columns1.php : Layout file for a one column layout (content only).&lt;br /&gt;
; /layout/columns2.php : Layout file for a two column layout (side-pre and content).&lt;br /&gt;
; /layout/columns3.php : Layout file for a three column layout (side-pre, content and side-post) and the front page.&lt;br /&gt;
; /layout/embedded.php : Embedded layout file for embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible.&lt;br /&gt;
; /layout/maintenance.php : Maintenance layout file which does not have any blocks, links, or API calls that would lead to database or cache interaction.&lt;br /&gt;
; /layout/secure.php : Secure layout file for safebrowser and securewindow.&lt;br /&gt;
; /style/ : This directory contains all the CSS files for this theme.&lt;br /&gt;
; /style/custom.css : This is where all the settings CSS is generated.&lt;br /&gt;
; /pix/ : This directory contains a screen shot of this theme as well as a favicon and any images used in the theme.&lt;br /&gt;
&lt;br /&gt;
==Renaming Elements==&lt;br /&gt;
&lt;br /&gt;
The problem when &#039;&#039;&#039;cloning&#039;&#039;&#039; a theme is that you need to rename all those instances where the old theme name occurs, in this case &#039;&#039;&#039;clean&#039;&#039;&#039;. So using the above list as a guide, search through and change all the instances of the theme name &#039;clean&#039; to &#039;cleantheme&#039;. This includes the filename of the lang/en/theme_clean.php. You need to change this to &#039;theme_cleantheme.php&#039;.&lt;br /&gt;
&lt;br /&gt;
==Installing your theme==&lt;br /&gt;
&lt;br /&gt;
Once all the changes to the name have been made, you can safely install the theme. If you are already logged in just refreshing the browser should trigger your Moodle site to begin the install &#039;Plugins Check&#039;. If not then navigate to Administration &amp;gt; Notifications.&lt;br /&gt;
&lt;br /&gt;
Once your theme is successfully installed you can select it and begin to modify it using the custom settings page found by navigating to Administration &amp;gt; Site Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt;&amp;gt; and then click on (Cleantheme) or whatever you renamed your theme to, from the list of theme names that appear at this point in the side block.&lt;br /&gt;
&lt;br /&gt;
==Include a renderer in a bootstrap based theme==&lt;br /&gt;
&lt;br /&gt;
If you need to override any renderers in your theme, then make sure you override the renderers by extending the parent theme renderers, which in this case is bootstrapbase. For example the class that you need to start your renderer with is as follows...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
class theme_yourtheme_core_renderer extends theme_bootstrapbase_core_renderer {&lt;br /&gt;
 &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...where &#039;*yourtheme*&#039; requires you to change that to the your theme name otherwise it will not work.&lt;br /&gt;
&lt;br /&gt;
(Please note: The normal recipe &amp;lt;tt&amp;gt;class theme_*yourtheme*_core_renderer extends core_renderer&amp;lt;/tt&amp;gt; is wrong for themes whose parent theme uses renderers, because this method will ultimately conflict with the parent theme&#039;s renderers.)&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [http://www.somerandomthoughts.com/blog/2013/05/08/moodle-2-5-and-the-bootstrap-based-theme-clean/ Moodle 2.5 and the Bootstrap based theme – Clean] blog post by Gavin Henrick&lt;br /&gt;
* [http://basbrands.nl/blog/2013/05/21/building-with-bootstrap/ Building With Bootstrap] blog post by Bas Brands&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Creating_a_theme&amp;diff=41830</id>
		<title>Creating a theme</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Creating_a_theme&amp;diff=41830"/>
		<updated>2013-08-07T22:19:51Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Configuring our theme */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}This document describes how to create a theme for Moodle 2.x.x. It assumes you have some understanding of how themes within Moodle work as well as a good understanding of HTML and CSS.&lt;br /&gt;
&lt;br /&gt;
===Theme designer mode===&lt;br /&gt;
&lt;br /&gt;
Under normal operation Moodle does several things in the name of performance, one of these is to combine all of the CSS into one file, minimize it, cache it on the server, and then serve it. After the first request the cached version is served to greatly improve page performance. &lt;br /&gt;
&lt;br /&gt;
What this means for you as a themer? When you make changes they will not be seen immediately. In fact you will need to tell Moodle to rebuild the cache that it is serving.&lt;br /&gt;
This isn&#039;t practical for designing themes of course so the &#039;&#039;&#039;theme designer mode&#039;&#039;&#039; was added. When enabled it tells Moodle not to combine or cache the CSS that gets delivered. This has the downside that page load times will take significantly longer, however you will see your changes immediately every time.&lt;br /&gt;
&lt;br /&gt;
Theme designer mode may be enabled via &#039;&#039;Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; [[Theme settings]]&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warning&#039;&#039;&#039;: Internet Explorer versions 6 and 7 have BIG problems when a site attempts to link to more than 31 stylesheets, in which case either a limited number or no styles get applied. Because Moodle sends up all of the CSS all of the time with theme designer mode turned on there is a very high chance you will get more than 31 stylesheets being included. This will, of course, cause major problems for Internet Explorer until theme designer mode is turned off.&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
The first thing you need to do is create the directories and files you will be using, the first thing to create is the actual directory for your theme. This should be the name of your theme, in my case it&#039;s &#039;excitement&#039;. The directory should be located within the theme directory of Moodle, ./moodle/theme/excitement/ will be the directory I create.&lt;br /&gt;
&lt;br /&gt;
Now within that directory we can immediately create several files that we know we are going to need. &lt;br /&gt;
&lt;br /&gt;
So the files that we want to create are:&lt;br /&gt;
; config.php :  All of our settings will go here.&lt;br /&gt;
; /style/ : This directory will contain all of our stylesheets.&lt;br /&gt;
; /style/excitement.css : All of our css will go in here.&lt;br /&gt;
; /pix/ : Into this directory we&#039;ll put a screen shot of our theme as well as our favicon and any images we use in CSS.&lt;br /&gt;
; /layout/ : Our layout files will end up in this directory.&lt;br /&gt;
; /layout/standard.php : This will be our one basic layout file.&lt;br /&gt;
; /lang/en/ : The file we put here will make our theme name show properly on the Theme Selector page. You need a few standard entries. Copy the one from the Standard theme and modify is easiest. &lt;br /&gt;
&lt;br /&gt;
So after this setup step you should have a directory structure similar to what is shown below.&lt;br /&gt;
&lt;br /&gt;
[[image:Learn_to_theme_01.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Configuring our theme==&lt;br /&gt;
&lt;br /&gt;
Open config.php in your favourite editor and start by adding the opening PHP tags &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;&amp;lt;?php&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Now we need to add the settings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;name = &#039;excitement&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Very simply this tells Moodle the name of your theme, and if you ever have several config.php files open this will help you identify which one you are looking at.&lt;br /&gt;
&lt;br /&gt;
Next, the parents for this theme.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;base&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This tells Moodle that my new theme &#039;&#039;`excitement`&#039; wants to extend the base theme. &lt;br /&gt;
&lt;br /&gt;
A theme can extend any number of themes. Rather than creating an entirely new theme and copying all of the CSS, you can simply create a new theme, extend the theme you like and just add the changes you want to your theme. &lt;br /&gt;
&lt;br /&gt;
Also worth noting is the purpose of the base theme: it provides us with a basic layout and just enough CSS to make everything fall into place.&lt;br /&gt;
&lt;br /&gt;
Now we will tell Moodle about our stylesheets:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;excitement&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final thing we need to add into our theme&#039;s config.php file is the definition of the layouts for our theme:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Most backwards compatible layout without the blocks - this is the layout used by default&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&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;
    // 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;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-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // Main course page&lt;br /&gt;
    &#039;course&#039; =&amp;gt; array(&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-pre&#039;,&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;coursecategory&#039; =&amp;gt; array(&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-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // part of course, typical for modules - default page layout if $cm specified in require_login()&lt;br /&gt;
    &#039;incourse&#039; =&amp;gt; array(&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-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // The site home page.&lt;br /&gt;
    &#039;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;frontpage.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-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // Server administration scripts.&lt;br /&gt;
    &#039;admin&#039; =&amp;gt; array(&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;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // My dashboard page&lt;br /&gt;
    &#039;mydashboard&#039; =&amp;gt; array(&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-pre&#039;,&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // My public page&lt;br /&gt;
    &#039;mypublic&#039; =&amp;gt; array(&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-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;login&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    // Pages that appear in pop-up windows - no navigation, no blocks, no header.&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true, &#039;nologininfo&#039;=&amp;gt;true, &#039;nocourseheaderfooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // No blocks and minimal footer - used for legacy frame layouts only!&lt;br /&gt;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nocoursefooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible&lt;br /&gt;
    &#039;embedded&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true, &#039;nocourseheaderfooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Used during upgrade and install, and for the &#039;This site is undergoing maintenance&#039; message.&lt;br /&gt;
    // This must not have any blocks, and it is good idea if it does not have links to&lt;br /&gt;
    // other places - for example there should not be a home link in the footer...&lt;br /&gt;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true, &#039;nocourseheaderfooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Should display the content and basic headers only.&lt;br /&gt;
    &#039;print&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;false, &#039;nocustommenu&#039;=&amp;gt;true, &#039;nocourseheaderfooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // The pagelayout used when a redirection is occuring.&lt;br /&gt;
    &#039;redirect&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true, &#039;nocourseheaderfooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // The pagelayout used for reports.&lt;br /&gt;
    &#039;report&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;report.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // The pagelayout used for safebrowser and securewindow.&lt;br /&gt;
    &#039;secure&#039; =&amp;gt; array(&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-pre&#039;,&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true, &#039;nologinlinks&#039;=&amp;gt;true, &#039;nocourseheaderfooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/** List of javascript files that need to be included on each page */&lt;br /&gt;
$THEME-&amp;gt;javascripts = array();&lt;br /&gt;
$THEME-&amp;gt;javascripts_footer = array();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you are looking at is the different layouts for our theme. Why are there so many? Because, that is how many there are in Moodle. There is one for every general type of page. With my &#039;&#039;`excitement`&#039;&#039; theme I have chosen to use my own layout. Unless there was a specific reason to do so, normally you would not need to create your own layouts, you could extend the base theme, and use its layouts, meaning you would only have to write CSS to achieve your desired look.&lt;br /&gt;
&lt;br /&gt;
For each layout above, you will notice the following four things are being set:&lt;br /&gt;
; file : This is the name of the layout file we want to use, it should always be located in the above themes layout directory. For us this is of course standard.php as we only have one layout file.&lt;br /&gt;
; regions : This is an array of block regions that our theme has. Each entry in here can be used to put blocks in when that layout is being used.&lt;br /&gt;
; defaultregion : If a layout has regions it should have a default region, this is where blocks get put when first added. It is also where the &amp;quot;add block&amp;quot; block is shown when editing is on.&lt;br /&gt;
; options : These are special settings, anything that gets put into the options array is available later on when we are writing our layout file.&lt;br /&gt;
&lt;br /&gt;
There are additional settings that can be defined in the config.php file - see [[Themes 2.0|Themes 2.0]] for the full list.&lt;br /&gt;
&lt;br /&gt;
==Configuring the language file==&lt;br /&gt;
Open theme_base.php file from &#039;&#039;&#039;base/lang/en/theme_base.php&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Save it as &#039;&#039;&#039;excitement/lang/en/theme_excitement.php&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Change &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;Base&#039;; &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
to&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;Excitement&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After making these changes and perhaps clearing theme caches and/or purging all caches, the new theme name should now show properly in the Theme Selector: &#039;&#039;Site Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; Theme Selector&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can also edit the theme description:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;choosereadme&#039;] = &#039;Write your theme description here.&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You need to leave the following two lines in place (you can change the wording if you need to) to avoid notices when editing blocks etc.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;region-side-post&#039;] = &#039;Right&#039;;&lt;br /&gt;
$string[&#039;region-side-pre&#039;] = &#039;Left&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Writing the layout file==&lt;br /&gt;
&lt;br /&gt;
The excitement theme has just one layout file.&lt;br /&gt;
&lt;br /&gt;
The downside of this is that I have to make the layout file do everything I want which means I need to make use of some options (as defined in the layouts in config.php). &lt;br /&gt;
&lt;br /&gt;
The upside is that I only need to maintain one file. &lt;br /&gt;
&lt;br /&gt;
Other than maintenance, using multiple layout files provides many advantages to real world themes in that you can easily tweak and customise specific layouts to achieve the goals of the organisation using the theme.&lt;br /&gt;
&lt;br /&gt;
Before learning more it is good to understand the two primary objects that will be used in your layout files: $OUTPUT and $PAGE.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;$OUTPUT&#039;&#039;&#039; is an instance of the &amp;lt;code&amp;gt;core_renderer&amp;lt;/code&amp;gt; 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.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;$PAGE&#039;&#039;&#039; is an instance of the &amp;lt;code&amp;gt;moodle_page&amp;lt;/code&amp;gt; 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-&amp;gt;activityname, just like fields of an ordinary PHP object. (However, behind the scenes the value you get is produced by calling a function. Also, you cannot change these values, they are &#039;&#039;&#039;read-only&#039;&#039;&#039;. However, you don&#039;t need to understand all that if you are just using these properties in your theme.)&lt;br /&gt;
&lt;br /&gt;
So lets start writing standard.php, the layout file for my &#039;&#039;`excitement`&#039;&#039; theme.&lt;br /&gt;
&lt;br /&gt;
===The top of the layout file===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$hassidepre = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-pre&#039;, $OUTPUT);&lt;br /&gt;
$hassidepost = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-post&#039;, $OUTPUT);&lt;br /&gt;
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;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lets look at the code that goes into this section:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
echo $OUTPUT-&amp;gt;doctype(); ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is very important and is required to go at the very top of the page. This tells Moodle to print out the document type tag that is determined by the settings within Moodle.&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 open the HTML tag and then ask Moodle to print the attributes that should go inside it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&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;/code&amp;gt;&lt;br /&gt;
Simply creates the title tag and asks Moodle to fill it in.&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;
Here we are asking Moodle to print all of the other tags and content that need to go into the head. This includes stylesheets, script tags, and inline JavaScript code.&lt;br /&gt;
&lt;br /&gt;
===The page header===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php p($PAGE-&amp;gt;bodyid); ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php p($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;div id=&amp;quot;page&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading || (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar())) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-header&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;?php if ($PAGE-&amp;gt;heading) { ?&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&lt;br /&gt;
                echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
                if (!empty($PAGE-&amp;gt;layout_options[&#039;langmenu&#039;])) {&lt;br /&gt;
                    echo $OUTPUT-&amp;gt;lang_menu();&lt;br /&gt;
                }&lt;br /&gt;
                echo $PAGE-&amp;gt;headingmenu&lt;br /&gt;
            ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
        &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar()) { ?&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;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So there is a bit more going on here obviously.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php p($PAGE-&amp;gt;bodyid); ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php p($PAGE-&amp;gt;bodyclasses); ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Again much like what we did for the opening HTML tag in the head we have started writing the opening body tag and are then asking Moodle to give us the ID we should use for the body tag as well as the classes we should use.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_top_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This very important call writes some critical bits of JavaScript into the page. It should always be located after the body tag as soon as possible.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading || (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar())) { ?&amp;gt;&lt;br /&gt;
......&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are checking whether or not we need to print the header for the page. There are three checks we need to make here:&lt;br /&gt;
# &#039;&#039;&#039;$PAGE-&amp;gt;heading&#039;&#039;&#039; : This checks to make sure that there is a heading for the page. This will have been set by the script and normally describes the page in a couple of words.&lt;br /&gt;
# &#039;&#039;&#039;empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;])&#039;&#039;&#039; : Now this check is looking at the layout options that we set in our config.php file. It is looking to see if the layout set &#039;nonavbar&#039; =&amp;gt; true.&lt;br /&gt;
# &#039;&#039;&#039;$PAGE-&amp;gt;has_navbar()&#039;&#039;&#039; The third check is to check with the page whether it has a navigation bar to display.&lt;br /&gt;
If either there is a heading for this page or there is a navigation bar to display then we will display a heading.&lt;br /&gt;
&lt;br /&gt;
Leading on from this lets assume that there is a header to print.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading) { ?&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;
    .....&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This line is simply saying if the page has a heading print it. In this case we run the first check above again just to make sute there is a heading, we then open a heading tag that we choose and ask the page to print the heading.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;headermenu&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
    echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
    if (!empty($PAGE-&amp;gt;layout_options[&#039;langmenu&#039;])) {&lt;br /&gt;
        echo $OUTPUT-&amp;gt;lang_menu();&lt;br /&gt;
    }&lt;br /&gt;
    echo $PAGE-&amp;gt;headingmenu&lt;br /&gt;
?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are looking to print the menu and content that you see at the top of the page (usually to the right). We start by getting Moodle to print the login information for the current user. If the user is logged in this will be their name and a link to their profile, if not then it will be a link to login.&lt;br /&gt;
&lt;br /&gt;
Next we check our page options to see whether a language menu should be printed. If in the layout definition within config.php it sets &#039;&#039;&#039;langmenu =&amp;gt; true&#039;&#039;&#039; then we will print the language menu, a drop down box that lets the user change the language that Moodle displays in.&lt;br /&gt;
&lt;br /&gt;
Finally the page also has a heading menu that can be printed. This heading menu is special HTML that the page you are viewing wants to add. It can be anything from drop down boxes to buttons and any number of each.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar()) { ?&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;
The final part of the header.&lt;br /&gt;
&lt;br /&gt;
Here we want to print the navigation bar for the page if there is one. To find out if there is one we run checks number 2 and 3 again and proceed if they pass.&lt;br /&gt;
&lt;br /&gt;
Assuming there is a header then there are two things that we need to print. The first is the navigation bar. This is a component that the OUTPUT library knows about. The second is a button to show on the page.&lt;br /&gt;
&lt;br /&gt;
In both cases we choose to wrap them in a div tag with a class attribute to enable theming on those elements.&lt;br /&gt;
&lt;br /&gt;
Well that is it for the header. There is a lot of PHP compared to the other sections of the layout file but it does not change and can be copied and pasted between themes.&lt;br /&gt;
&lt;br /&gt;
===The page content===&lt;br /&gt;
&lt;br /&gt;
I am going with the default two block regions plus the main content.&lt;br /&gt;
&lt;br /&gt;
Because I have based this theme and layout file on the base theme the HTML looks a little intense. This is because it is a floating div layout where the content comes first and then we get the columns (even though one column will be to the left of the content.) Don&#039;t worry too much about it. When it comes to writing your own theme you can go about it as you choose.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;page-content&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;region-main-box&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div id=&amp;quot;region-post-box&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;div id=&amp;quot;region-main-wrap&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-main&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;?php if ($hassidepre) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-pre&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&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;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
                &lt;br /&gt;
                &amp;lt;?php if ($hassidepost) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-post&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&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;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In regards to PHP this section is very easy. There are only three lines for the whole section one to get the main content and one for each block region.&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 line prints the main content for the page.&lt;br /&gt;
PLEASE NOTE: In Moodle 2.2 onwards &amp;quot;core_renderer::MAIN_CONTENT_TOKEN&amp;quot; changed to &amp;quot;$OUTPUT-&amp;gt;main_content()&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($hassidepre) { ?&amp;gt;&lt;br /&gt;
....&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
These lines of code check the variables we created earlier on to decide whether we should show the pre block region. If you try to display a block region that isn&#039;t there or has no content then Moodle will give you an error message so these lines are very important.&lt;br /&gt;
&lt;br /&gt;
For those who get an error message if it is &amp;quot;unknown block region side-pre&amp;quot; or &amp;quot;unknown block region side-post&amp;quot; then this is the issue you are experiencing. Simply add the following lines and all will be fine.&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;
This line gets all of the blocks and more particularly the content for the block region &#039;&#039;&#039;side-pre&#039;&#039;&#039;. This block region will be displayed to the left of the content.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($hassidepost) { ?&amp;gt;&lt;br /&gt;
....&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Again we should make this check for every block region as there are some pages that have no blocks what-so-ever.&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 are getting the other block region &#039;&#039;&#039;side-post&#039;&#039;&#039; which will be displayed to the right of the content.&lt;br /&gt;
&lt;br /&gt;
===The page footer===&lt;br /&gt;
Here we want to print the footer for the page, any content required by Moodle, and then close the last tags.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nofooter&#039;])) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot; class=&amp;quot;clearfix&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;/div&amp;gt;&lt;br /&gt;
    &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/div&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;
The section of code is responsible for printing the footer for the page.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nofooter&#039;])) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot; class=&amp;quot;clearfix&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;/div&amp;gt;&lt;br /&gt;
    &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The first thing we do before printing the footer is check that we actually want to print it. This is done by checking the options for the layout as defined in the config.php file. If &#039;&#039;&#039;nofooter =&amp;gt; true&#039;&#039;&#039; is set the we don&#039;t want to print the footer and should skip over this body of code.&lt;br /&gt;
&lt;br /&gt;
Assuming we want to print a footer we proceed to create a div to house its content and then print the bits of the content that will make it up.&lt;br /&gt;
There are four things that the typical page footer will want to print:&lt;br /&gt;
; echo page_doc_link(get_string(&#039;moodledocslink&#039;)) : This will print a link to the Moodle.org help page for this particular page.&lt;br /&gt;
; echo $OUTPUT-&amp;gt;login_info(); : This is the same as at the top of the page and will print the login information for the current user.&lt;br /&gt;
; echo $OUTPUT-&amp;gt;home_link(); : This prints a link back to the Moodle home page for this site.&lt;br /&gt;
; echo $OUTPUT-&amp;gt;standard_footer_html(); : This prints special HTML that is determined by the settings for the site. Things such as performance information or debugging will be printed by this line if they are turned on.&lt;br /&gt;
&lt;br /&gt;
And the final line of code for our layout file is:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_end_of_body_html(); ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is one of the most important lines of code in the layout file. It asks Moodle to print any required content into the page, and there will likely be a lot although most of it will not be visual.&lt;br /&gt;
&lt;br /&gt;
It will instead be things such as inline scripts and JavaScript files required to go at the bottom of the page. If you forget this line its likely no JavaScript will work!&lt;br /&gt;
&lt;br /&gt;
We&#039;ve now written our layout file and it is all set to go. The complete source is below for reference. Remember if you want more practical examples simply look at the layout files located within the layout directory of other themes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$hassidepre = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-pre&#039;, $OUTPUT);&lt;br /&gt;
$hassidepost = $PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-post&#039;, $OUTPUT);&lt;br /&gt;
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;link rel=&amp;quot;shortcut icon&amp;quot; href=&amp;quot;&amp;lt;?php echo $OUTPUT-&amp;gt;pix_url(&#039;favicon&#039;, &#039;theme&#039;)?&amp;gt;&amp;quot; /&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;
&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php p($PAGE-&amp;gt;bodyid); ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php p($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;div id=&amp;quot;page&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;heading || (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar())) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-header&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;?php if ($PAGE-&amp;gt;heading) { ?&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&lt;br /&gt;
            echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
            if (!empty($PAGE-&amp;gt;layout_options[&#039;langmenu&#039;])) {&lt;br /&gt;
                echo $OUTPUT-&amp;gt;lang_menu();&lt;br /&gt;
            }&lt;br /&gt;
            echo $PAGE-&amp;gt;headingmenu&lt;br /&gt;
        ?&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
        &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar()) { ?&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;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-content&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div id=&amp;quot;region-main-box&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;div id=&amp;quot;region-post-box&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-main-wrap&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div id=&amp;quot;region-main&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div class=&amp;quot;region-content&amp;quot;&amp;gt;&lt;br /&gt;
                            &amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
                        &amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php if ($hassidepre) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-pre&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&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;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
                &lt;br /&gt;
                &amp;lt;?php if ($hassidepost) { ?&amp;gt;&lt;br /&gt;
                &amp;lt;div id=&amp;quot;region-post&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;region-content&amp;quot;&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;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;?php if (empty($PAGE-&amp;gt;layout_options[&#039;nofooter&#039;])) { ?&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;page-footer&amp;quot; class=&amp;quot;clearfix&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;/div&amp;gt;&lt;br /&gt;
    &amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/div&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;
==Adding some CSS==&lt;br /&gt;
With config.php and standard.php both complete the theme is now usable and starting to look like a real theme, however if you change to it using the theme selector you will notice that it still lacks any style.&lt;br /&gt;
&lt;br /&gt;
This of course is where CSS comes in. When writing code Moodle developers are strongly encouraged to not use inline styles anywhere. This is fantastic for us as themers because there is nothing (or at least very little) in Moodle that cannot be styled using CSS.&lt;br /&gt;
&lt;br /&gt;
===Moodle CSS basics===&lt;br /&gt;
&lt;br /&gt;
In Moodle 2.0 all of the CSS for the whole of Moodle is delivered all of the time! This was done for performance reasons. Moodle now reads in all of the CSS, combines it into one file, shrinks it removing any white space, caches it, and then delivers it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What this means for you as a themer?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You will need to write good CSS that won&#039;t clash with any other CSS within Moodle.&lt;br /&gt;
&lt;br /&gt;
Moodle is so big and complex,there is no way to ensure that classes don&#039;t get reused. What we can control however is the classes and id that get added to the body tag for every page. When writing CSS it is highly encouraged to make full use of these body classes, using them will help ensure the CSS you write has the least chance of causing conflicts.&lt;br /&gt;
&lt;br /&gt;
You should also take the time to look at how the Moodle themes use CSS. Look at their use of the body classes and how they separate the CSS for the theme into separate files based on the region of Moodle it applies to.&lt;br /&gt;
&lt;br /&gt;
Check out [[Themes 2.0|Themes 2.0]] and [[CSS coding style]] for more information about writing good CSS.&lt;br /&gt;
&lt;br /&gt;
===Starting to write excitement.css===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
a {&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.addcoursebutton .singlebutton {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
h1.headermain {&lt;br /&gt;
    color: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
h2.main {&lt;br /&gt;
    border-bottom: 3px solid #013D6A;&lt;br /&gt;
    color: #013D6A;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
h2.headingblock {&lt;br /&gt;
    font-size: 18pt;&lt;br /&gt;
    margin-top: 0;&lt;br /&gt;
    background-color: #013D6A;&lt;br /&gt;
    color: #FFF;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#page-header {&lt;br /&gt;
    background-color: #013D6A;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#page-header .headermenu {&lt;br /&gt;
    color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#page-header .headermenu a {&lt;br /&gt;
    color: #FDFF2A;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.navbar {&lt;br /&gt;
    padding-left: 1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.breadcrumb li {&lt;br /&gt;
    color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.breadcrumb li a {&lt;br /&gt;
    color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block {&lt;br /&gt;
    background-color: #013D6A;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block .header .title {&lt;br /&gt;
    color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block .header .title .block_action input {&lt;br /&gt;
    background-color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block .content {&lt;br /&gt;
    border: 1px solid #000;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    background-color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block .content .block_tree p {&lt;br /&gt;
    font-size: 80%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_settings_navigation_tree .content .footer {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform {&lt;br /&gt;
    margin-left: 5%;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    font-size: 9pt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform #adminsearchquery {&lt;br /&gt;
    width: 95%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .calendar-controls a {&lt;br /&gt;
    color: #013D6A;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .minicalendar td {&lt;br /&gt;
    border-color: #FFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {&lt;br /&gt;
    color: #FFF;&lt;br /&gt;
    background-color: #013D6A;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .minicalendar .day a {&lt;br /&gt;
    color: #FFF000;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays th {&lt;br /&gt;
    border-width: 0;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #013D6A;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays abbr {&lt;br /&gt;
    border-width: 0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
[[image:Learn_to_theme_02.jpg|400px|thumb|Excitement theme screenshot]]&lt;br /&gt;
This isn&#039;t all of the CSS for the theme, but just enough to style the front page when the user is not logged in.&lt;br /&gt;
Remember this theme extends the base theme so there is already CSS for layout as well.&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
* The CSS is laid out in a single line format. This is done within the core themes for Moodle. It makes it quicker to read the selectors and see what is being styled.&lt;br /&gt;
* I have written my selectors to take into account the structure of the HTML (more than just the one tag I want to style). This helps further to reduce the conflicts that I may encounter.&lt;br /&gt;
* I use generic classes like &#039;&#039;.sideblock&#039;&#039; only where I want to be generic, as soon as I want to be specific I use the unique classes such as &#039;&#039;.block_calendar_month&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:right;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Using images within CSS===&lt;br /&gt;
&lt;br /&gt;
I will add two image files to the pix directory of my theme:&lt;br /&gt;
; /theme/excitement/pix/background.png : This will be the background image for my theme.&lt;br /&gt;
; /theme/excitement/pix/gradient.jpg : This will be a gradient I use for the header and headings.&lt;br /&gt;
I quickly created both of these images using gimp and simply saved them to the pix directory.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
html {&lt;br /&gt;
    background-image: url([[pix:theme|background]]);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
h2.headingblock,&lt;br /&gt;
#page-header,&lt;br /&gt;
.sideblock,&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {&lt;br /&gt;
    background-image: url([[pix:theme|gradient]]);&lt;br /&gt;
    background-repeat: repeat-x;&lt;br /&gt;
    background-color: #0273C8;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
[[image:Learn_to_theme_03.jpg‎|400px|thumb|Excitement theme screenshot]]&lt;br /&gt;
The CSS above is the two new rules that I had to write to use my images within CSS.&lt;br /&gt;
&lt;br /&gt;
The first rule sets the background image for the page to background.png&lt;br /&gt;
&lt;br /&gt;
The second rule sets the background for headings, and the sideblocks to use gradient.jpg&lt;br /&gt;
&lt;br /&gt;
You will notice that I did not need to write a path to the image. This is because Moodle has this special syntax that can be used and will be replaced when the CSS is parsed before delivery.&lt;br /&gt;
The advantage of using this syntax over writing the path in is that the path may change depending on where you are or what theme is being used.&lt;br /&gt;
&lt;br /&gt;
Other themers may choose to extend your theme with their own; if you use this syntax then all they need to do to override the image is to create one with the same name in their themes directory.&lt;br /&gt;
&lt;br /&gt;
You will also notice that I don&#039;t need to add the image files extension. This is because Moodle is smart enough to work out what extension the file uses. It also allows themers to override images with different formats.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:right&amp;quot; /&amp;gt;&lt;br /&gt;
The following is the complete CSS for my theme:&lt;br /&gt;
&amp;lt;div style=&amp;quot;overflow:auto;height:860px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
a {text-decoration: none;}&lt;br /&gt;
.addcoursebutton .singlebutton {text-align: center;}&lt;br /&gt;
&lt;br /&gt;
h1.headermain {color: #fff;}&lt;br /&gt;
h2.main {border-bottom: 3px solid #013D6A;color: #013D6A;text-align: center;}&lt;br /&gt;
h2.headingblock {font-size: 18pt;margin-top: 0;background-color: #013D6A;color: #FFF;text-align: center;}&lt;br /&gt;
#page-header {background-color: #013D6A;border-bottom:5px solid #013D6A;}&lt;br /&gt;
#page-header .headermenu  {color: #FFF;}&lt;br /&gt;
#page-header .headermenu a {color: #FDFF2A;}&lt;br /&gt;
&lt;br /&gt;
.sideblock {background-color: #013D6A;}&lt;br /&gt;
.sideblock .header .title {color: #FFF;}&lt;br /&gt;
.sideblock .header .title .block_action input {background-color: #FFF;}&lt;br /&gt;
.sideblock .content {border: 1px solid #000;padding: 5px;background-color: #FFF;}&lt;br /&gt;
.sideblock .content .block_tree p {font-size: 80%;}&lt;br /&gt;
&lt;br /&gt;
.block_settings_navigation_tree .content .footer {text-align: center;}&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform {margin-left: 5%;width: 90%;font-size: 9pt;}&lt;br /&gt;
.block_settings_navigation_tree .content .footer .adminsearchform #adminsearchquery {width: 95%;}&lt;br /&gt;
&lt;br /&gt;
.block_calendar_month .content .calendar-controls a {color: #013D6A;font-weight: bold;}&lt;br /&gt;
.block_calendar_month .content .minicalendar td {border-color: #FFF;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {color: #FFF;background-color: #013D6A;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .day a {color: #FFF000;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays th {border-width: 0;font-weight: bold;color: #013D6A;}&lt;br /&gt;
.block_calendar_month .content .minicalendar .weekdays abbr {border-width: 0;text-decoration: none;}&lt;br /&gt;
&lt;br /&gt;
html {background-image:url([[pix:theme|background]]);}&lt;br /&gt;
&lt;br /&gt;
h2.headingblock,&lt;br /&gt;
#page-header,&lt;br /&gt;
.sideblock,&lt;br /&gt;
.block_calendar_month .content .minicalendar .day {background-image:url([[pix:theme|gradient]]);&lt;br /&gt;
   background-repeat:repeat-x;background-color: #0273C8;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Adding a screenshot and favicon==&lt;br /&gt;
The final thing to do at this point is add both a screenshot for this theme as well as a favicon for it.&lt;br /&gt;
The screenshot will be shown in the theme selector screen and should be named &#039;&#039;screenshot.jpg&#039;&#039;.&lt;br /&gt;
The favicon will be used when someone bookmarks this page.&lt;br /&gt;
Both images should be located in your themes pix directory as follows:&lt;br /&gt;
* /theme/excitement/pix/screenshot.jpg&lt;br /&gt;
* /theme/excitement/pix/favicon.ico&lt;br /&gt;
&lt;br /&gt;
In the case of my theme I have taken a screenshot and added it to that directory, and because I don&#039;t really want to do anything special with the favicon I have copied it from /theme/base/pix/favicon.ico so that at least it will be recognisable as Moodle.&lt;br /&gt;
&lt;br /&gt;
[[es:Desarollo:Temas 2.0 creando tu primer tema]]&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=LESS&amp;diff=40178</id>
		<title>LESS</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=LESS&amp;diff=40178"/>
		<updated>2013-05-24T18:25:13Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Using Recess */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
LESS ([http://lesscss.org lesscss.org]) extends CSS with dynamic behavior such as variables, mixins, operations and functions.  It&#039;s an advanced way of writing CSS that we use in some themes within Moodle.&lt;br /&gt;
&lt;br /&gt;
Browsers don&#039;t interpret it themselves, however, so LESS files need to be converted into normal CSS before use.&lt;br /&gt;
&lt;br /&gt;
Recess is one tool used to compile and compress LESS into CSS under *nix based systems.  There are [https://github.com/cloudhead/less.js/wiki/GUI-compilers-that-use-LESS.js many others tools for LESS].&lt;br /&gt;
&lt;br /&gt;
== The bootstrapbase theme ==&lt;br /&gt;
&lt;br /&gt;
Moodle&#039;s [[Bootstrap]] base theme has rules written using LESS.&lt;br /&gt;
&lt;br /&gt;
The main LESS file is &#039;&#039;&#039;theme/bootstrapbase/less/moodle.less&#039;&#039;&#039;, with additional files  in &#039;&#039;&#039;theme/bootstrapbase/less/moodle/&#039;&#039;&#039; imported by the main file. &lt;br /&gt;
&lt;br /&gt;
After compiling the LESS files, CSS ends up in &#039;&#039;&#039;theme/bootstrapbase/style/moodle.css&#039;&#039;&#039;.  This file should not be edited manually.&lt;br /&gt;
&lt;br /&gt;
== Compilers ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Recess ===&lt;br /&gt;
==== Installing Recess under Ubuntu ====&lt;br /&gt;
The following commands should be run to install Recess&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. sudo apt-get install npm node&lt;br /&gt;
   (if the above fails due to the error &amp;quot;The following packages have unmet dependencies&amp;quot;, run the commands separately, ie. sudo apt-get install npm and then sudo apt-get install node)&lt;br /&gt;
2. npm install recess -g&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt; stands for Node Package Manager, and is the equivalent of apt-get for node.js packages.&lt;br /&gt;
&lt;br /&gt;
==== Installing Recess on Mac OS X ====&lt;br /&gt;
1. Install the basic node packages from the web site: [http://nodejs.org http://nodejs.org]   (or use your favourite package manager to install &amp;lt;code&amp;gt;node&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
2. On the command line, install recess like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    npm install recess -g&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installing Recess under Windows7 ====&lt;br /&gt;
&lt;br /&gt;
In order to install Recess you need to have Node.js installed first, which is relatively simple to do.&lt;br /&gt;
&lt;br /&gt;
====Install Node.js====  &lt;br /&gt;
&lt;br /&gt;
These instructions are for Windows 7 64 bit.&lt;br /&gt;
&lt;br /&gt;
Go to nodejs.org click install. &lt;br /&gt;
&lt;br /&gt;
When installed go to -&amp;gt; Start -&amp;gt; All Programs -&amp;gt; type Node.js into the Search box, then select Node.js Command prompt (black icon) from the list. Now you are ready to install Recess. So at the command line prompt type the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 npm install recess -g&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt; stands for Node Package Manager, and is the equivalent of apt-get for node.js packages.&lt;br /&gt;
&lt;br /&gt;
==== Using Recess ====&lt;br /&gt;
&lt;br /&gt;
After editing the LESS files, compile (minified) your CSS as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd theme/bootstrapbase/less/&lt;br /&gt;
recess --compile --compress moodle.less &amp;gt; ../style/moodle.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will compile and compress the moodle.less file (and all the LESS and CSS files it imports) into a single file, moodle.css, and store it in the style folder of the bootstrapbase theme.&lt;br /&gt;
&lt;br /&gt;
Alternatively if you want to view the normal (un-minified) CSS then use the following method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
recess --compile moodle.less &amp;gt; ../style/moodle.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039; if you are getting an empty moodle.css file, this is being caused by a parsing error in your LESS code. A bug in &amp;lt;code&amp;gt;recess&amp;lt;/code&amp;gt; currently prevents it giving you helpful error messages in many cases. You will need to examine what you have altered or written to make sure it is complete and the syntax is correct. The &amp;lt;code&amp;gt;lessc&amp;lt;/code&amp;gt; compiler is what is used by &amp;lt;code&amp;gt;recess&amp;lt;/code&amp;gt; to do the actual compiling and will have been installed automatically along with it. If you call it directly as &amp;lt;code&amp;gt;lessc moodle.less&amp;lt;/code&amp;gt; it should give you a helpful error message that points you to where the problem is.&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=LESS&amp;diff=40177</id>
		<title>LESS</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=LESS&amp;diff=40177"/>
		<updated>2013-05-24T18:21:38Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Using Recess */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
LESS ([http://lesscss.org lesscss.org]) extends CSS with dynamic behavior such as variables, mixins, operations and functions.  It&#039;s an advanced way of writing CSS that we use in some themes within Moodle.&lt;br /&gt;
&lt;br /&gt;
Browsers don&#039;t interpret it themselves, however, so LESS files need to be converted into normal CSS before use.&lt;br /&gt;
&lt;br /&gt;
Recess is one tool used to compile and compress LESS into CSS under *nix based systems.  There are [https://github.com/cloudhead/less.js/wiki/GUI-compilers-that-use-LESS.js many others tools for LESS].&lt;br /&gt;
&lt;br /&gt;
== The bootstrapbase theme ==&lt;br /&gt;
&lt;br /&gt;
Moodle&#039;s [[Bootstrap]] base theme has rules written using LESS.&lt;br /&gt;
&lt;br /&gt;
The main LESS file is &#039;&#039;&#039;theme/bootstrapbase/less/moodle.less&#039;&#039;&#039;, with additional files  in &#039;&#039;&#039;theme/bootstrapbase/less/moodle/&#039;&#039;&#039; imported by the main file. &lt;br /&gt;
&lt;br /&gt;
After compiling the LESS files, CSS ends up in &#039;&#039;&#039;theme/bootstrapbase/style/moodle.css&#039;&#039;&#039;.  This file should not be edited manually.&lt;br /&gt;
&lt;br /&gt;
== Compilers ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Recess ===&lt;br /&gt;
==== Installing Recess under Ubuntu ====&lt;br /&gt;
The following commands should be run to install Recess&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. sudo apt-get install npm node&lt;br /&gt;
   (if the above fails due to the error &amp;quot;The following packages have unmet dependencies&amp;quot;, run the commands separately, ie. sudo apt-get install npm and then sudo apt-get install node)&lt;br /&gt;
2. npm install recess -g&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt; stands for Node Package Manager, and is the equivalent of apt-get for node.js packages.&lt;br /&gt;
&lt;br /&gt;
==== Installing Recess on Mac OS X ====&lt;br /&gt;
1. Install the basic node packages from the web site: [http://nodejs.org http://nodejs.org]   (or use your favourite package manager to install &amp;lt;code&amp;gt;node&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
2. On the command line, install recess like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    npm install recess -g&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installing Recess under Windows7 ====&lt;br /&gt;
&lt;br /&gt;
In order to install Recess you need to have Node.js installed first, which is relatively simple to do.&lt;br /&gt;
&lt;br /&gt;
====Install Node.js====  &lt;br /&gt;
&lt;br /&gt;
These instructions are for Windows 7 64 bit.&lt;br /&gt;
&lt;br /&gt;
Go to nodejs.org click install. &lt;br /&gt;
&lt;br /&gt;
When installed go to -&amp;gt; Start -&amp;gt; All Programs -&amp;gt; type Node.js into the Search box, then select Node.js Command prompt (black icon) from the list. Now you are ready to install Recess. So at the command line prompt type the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 npm install recess -g&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt; stands for Node Package Manager, and is the equivalent of apt-get for node.js packages.&lt;br /&gt;
&lt;br /&gt;
==== Using Recess ====&lt;br /&gt;
&lt;br /&gt;
After editing the LESS files, compile (minified) your CSS as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd theme/bootstrapbase/less/&lt;br /&gt;
recess --compile --compress moodle.less &amp;gt; ../style/moodle.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternatively if you want to view the normal (un-minified) CSS then use the following method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
recess --compile moodle.less &amp;gt; ../style/moodle.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will compile and compress the moodle.less file (and all the LESS and CSS files it imports) into a single file, moodle.css, and store it in the style folder of the bootstrapbase theme.&lt;br /&gt;
&lt;br /&gt;
NOTE: if you are getting empty moodle.css files, this is being caused by a parsing error in your LESS code. A bug in &amp;lt;code&amp;gt;recess&amp;lt;/code&amp;gt; currently prevents it giving you helpful error messages in many cases. You will need to examine what you have altered or written to make sure it is complete and the syntax is correct. The &amp;lt;code&amp;gt;lessc&amp;lt;/code&amp;gt; compiler is what is used by &amp;lt;code&amp;gt;recess&amp;lt;/code&amp;gt; to do the actual compiling and will have been installed automatically along with it. If you call it directly as &amp;lt;code&amp;gt;lessc moodle.less&amp;lt;/code&amp;gt; it should give you a helpful error message that points you to where the problem is.&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=LESS&amp;diff=40131</id>
		<title>LESS</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=LESS&amp;diff=40131"/>
		<updated>2013-05-24T00:08:11Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* The bootstrap theme */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
LESS ([http://lesscss.org lesscss.org]) extends CSS with dynamic behavior such as variables, mixins, operations and functions.  It&#039;s an advanced way of writing CSS that we use in some themes within Moodle.&lt;br /&gt;
&lt;br /&gt;
Browsers don&#039;t interpret it themselves, however, so LESS files need to be converted into normal CSS before use.&lt;br /&gt;
&lt;br /&gt;
Recess is one tool used to compile and compress LESS into CSS under *nix based systems.  There are [https://github.com/cloudhead/less.js/wiki/GUI-compilers-that-use-LESS.js many others tools for LESS].&lt;br /&gt;
&lt;br /&gt;
== The bootstrapbase theme ==&lt;br /&gt;
&lt;br /&gt;
Moodle&#039;s [[Bootstrap]] base theme has rules written using LESS.&lt;br /&gt;
&lt;br /&gt;
The main LESS file is &#039;&#039;&#039;theme/bootstrapbase/less/moodle.less&#039;&#039;&#039;, with additional files  in &#039;&#039;&#039;theme/bootstrapbase/less/moodle/&#039;&#039;&#039; imported by the main file. &lt;br /&gt;
&lt;br /&gt;
After compiling the LESS files, CSS ends up in &#039;&#039;&#039;theme/bootstrapbase/style/moodle.css&#039;&#039;&#039;.  This file should not be edited manually.&lt;br /&gt;
&lt;br /&gt;
== Compilers ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Recess ===&lt;br /&gt;
==== Installing Recess under Ubuntu ====&lt;br /&gt;
The following commands should be run to install Recess&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. sudo apt-get install npm node&lt;br /&gt;
   (if the above fails due to the error &amp;quot;The following packages have unmet dependencies&amp;quot;, run the commands separately, ie. sudo apt-get install npm and then sudo apt-get install node)&lt;br /&gt;
2. npm install recess -g&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt; stands for Node Package Manager, and is the equivalent of apt-get for node.js packages.&lt;br /&gt;
&lt;br /&gt;
==== Installing Recess on Mac OS X ====&lt;br /&gt;
1. Install the basic node packages from the web site: [http://nodejs.org http://nodejs.org]   (or use your favourite package manager to install &amp;lt;code&amp;gt;node&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
2. On the command line, install recess like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    npm install recess -g&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installing Recess under Windows7 ====&lt;br /&gt;
&lt;br /&gt;
In order to install Recess you need to have Node.js installed first, which is relatively simple to do.&lt;br /&gt;
&lt;br /&gt;
====Install Node.js====  &lt;br /&gt;
&lt;br /&gt;
These instructions are for Windows 7 64 bit.&lt;br /&gt;
&lt;br /&gt;
Go to nodejs.org click install. &lt;br /&gt;
&lt;br /&gt;
When installed go to -&amp;gt; Start -&amp;gt; All Programs -&amp;gt; type Node.js into the Search box, then select Node.js Command prompt (black icon) from the list. Now you are ready to install Recess. So at the command line prompt type the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 npm install recess -g&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt; stands for Node Package Manager, and is the equivalent of apt-get for node.js packages.&lt;br /&gt;
&lt;br /&gt;
==== Using Recess ====&lt;br /&gt;
&lt;br /&gt;
After editing the LESS files, compile your CSS as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd theme/bootstrapbase/less/&lt;br /&gt;
recess --compile --compress moodle.less &amp;gt; ../style/moodle.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will compile and compress the moodle.less file (and all the LESS and CSS files it imports) into a single file, moodle.css, and store it in the style folder of the bootstrapbase theme.&lt;br /&gt;
&lt;br /&gt;
NOTE: if you are getting empty moodle.css files, this is being caused by a parsing error in your LESS code. A bug in &amp;lt;code&amp;gt;recess&amp;lt;/code&amp;gt; currently prevents it giving you helpful error messages in many cases. You will need to examine what you have altered or written to make sure it is complete and the syntax is correct. The &amp;lt;code&amp;gt;lessc&amp;lt;/code&amp;gt; compiler is what is used by &amp;lt;code&amp;gt;recess&amp;lt;/code&amp;gt; to do the actual compiling and will have been installed automatically along with it. If you call it directly as &amp;lt;code&amp;gt;lessc moodle.less&amp;lt;/code&amp;gt; it should give you a helpful error message that points you to where the problem is.&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=LESS&amp;diff=40130</id>
		<title>LESS</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=LESS&amp;diff=40130"/>
		<updated>2013-05-24T00:07:12Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* The bootstrap theme */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
LESS ([http://lesscss.org lesscss.org]) extends CSS with dynamic behavior such as variables, mixins, operations and functions.  It&#039;s an advanced way of writing CSS that we use in some themes within Moodle.&lt;br /&gt;
&lt;br /&gt;
Browsers don&#039;t interpret it themselves, however, so LESS files need to be converted into normal CSS before use.&lt;br /&gt;
&lt;br /&gt;
Recess is one tool used to compile and compress LESS into CSS under *nix based systems.  There are [https://github.com/cloudhead/less.js/wiki/GUI-compilers-that-use-LESS.js many others tools for LESS].&lt;br /&gt;
&lt;br /&gt;
== The bootstrap theme ==&lt;br /&gt;
&lt;br /&gt;
Moodle&#039;s [[Bootstrap]] base theme has rules written using LESS.&lt;br /&gt;
&lt;br /&gt;
The main LESS file is &#039;&#039;&#039;theme/bootstrapbase/less/moodle.less&#039;&#039;&#039;, with additional files  in &#039;&#039;&#039;theme/bootstrapbase/less/moodle/&#039;&#039;&#039; imported by the main file. &lt;br /&gt;
&lt;br /&gt;
After compiling the LESS files, CSS ends up in &#039;&#039;&#039;theme/bootstrapbase/style/moodle.css&#039;&#039;&#039;.  This file should not be edited manually.&lt;br /&gt;
&lt;br /&gt;
== Compilers ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Recess ===&lt;br /&gt;
==== Installing Recess under Ubuntu ====&lt;br /&gt;
The following commands should be run to install Recess&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. sudo apt-get install npm node&lt;br /&gt;
   (if the above fails due to the error &amp;quot;The following packages have unmet dependencies&amp;quot;, run the commands separately, ie. sudo apt-get install npm and then sudo apt-get install node)&lt;br /&gt;
2. npm install recess -g&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt; stands for Node Package Manager, and is the equivalent of apt-get for node.js packages.&lt;br /&gt;
&lt;br /&gt;
==== Installing Recess on Mac OS X ====&lt;br /&gt;
1. Install the basic node packages from the web site: [http://nodejs.org http://nodejs.org]   (or use your favourite package manager to install &amp;lt;code&amp;gt;node&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
2. On the command line, install recess like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    npm install recess -g&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installing Recess under Windows7 ====&lt;br /&gt;
&lt;br /&gt;
In order to install Recess you need to have Node.js installed first, which is relatively simple to do.&lt;br /&gt;
&lt;br /&gt;
====Install Node.js====  &lt;br /&gt;
&lt;br /&gt;
These instructions are for Windows 7 64 bit.&lt;br /&gt;
&lt;br /&gt;
Go to nodejs.org click install. &lt;br /&gt;
&lt;br /&gt;
When installed go to -&amp;gt; Start -&amp;gt; All Programs -&amp;gt; type Node.js into the Search box, then select Node.js Command prompt (black icon) from the list. Now you are ready to install Recess. So at the command line prompt type the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 npm install recess -g&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt; stands for Node Package Manager, and is the equivalent of apt-get for node.js packages.&lt;br /&gt;
&lt;br /&gt;
==== Using Recess ====&lt;br /&gt;
&lt;br /&gt;
After editing the LESS files, compile your CSS as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd theme/bootstrapbase/less/&lt;br /&gt;
recess --compile --compress moodle.less &amp;gt; ../style/moodle.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will compile and compress the moodle.less file (and all the LESS and CSS files it imports) into a single file, moodle.css, and store it in the style folder of the bootstrapbase theme.&lt;br /&gt;
&lt;br /&gt;
NOTE: if you are getting empty moodle.css files, this is being caused by a parsing error in your LESS code. A bug in &amp;lt;code&amp;gt;recess&amp;lt;/code&amp;gt; currently prevents it giving you helpful error messages in many cases. You will need to examine what you have altered or written to make sure it is complete and the syntax is correct. The &amp;lt;code&amp;gt;lessc&amp;lt;/code&amp;gt; compiler is what is used by &amp;lt;code&amp;gt;recess&amp;lt;/code&amp;gt; to do the actual compiling and will have been installed automatically along with it. If you call it directly as &amp;lt;code&amp;gt;lessc moodle.less&amp;lt;/code&amp;gt; it should give you a helpful error message that points you to where the problem is.&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=LESS&amp;diff=40129</id>
		<title>LESS</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=LESS&amp;diff=40129"/>
		<updated>2013-05-24T00:05:33Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Using Recess */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
LESS ([http://lesscss.org lesscss.org]) extends CSS with dynamic behavior such as variables, mixins, operations and functions.  It&#039;s an advanced way of writing CSS that we use in some themes within Moodle.&lt;br /&gt;
&lt;br /&gt;
Browsers don&#039;t interpret it themselves, however, so LESS files need to be converted into normal CSS before use.&lt;br /&gt;
&lt;br /&gt;
Recess is one tool used to compile and compress LESS into CSS under *nix based systems.  There are [https://github.com/cloudhead/less.js/wiki/GUI-compilers-that-use-LESS.js many others tools for LESS].&lt;br /&gt;
&lt;br /&gt;
== The bootstrap theme ==&lt;br /&gt;
&lt;br /&gt;
Moodle&#039;s [[Bootstrap]] base theme has rules written using LESS.&lt;br /&gt;
&lt;br /&gt;
The main LESS file is &#039;&#039;&#039;theme/bootstrap/less/moodle.less&#039;&#039;&#039;, with additional files  in &#039;&#039;&#039;theme/bootstrap/less/moodle/&#039;&#039;&#039; imported by the main file. &lt;br /&gt;
&lt;br /&gt;
After compiling the LESS files, CSS ends up in &#039;&#039;&#039;theme/bootstrapbase/style/moodle.css&#039;&#039;&#039;.  This file should not be edited manually.&lt;br /&gt;
&lt;br /&gt;
== Compilers ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Recess ===&lt;br /&gt;
==== Installing Recess under Ubuntu ====&lt;br /&gt;
The following commands should be run to install Recess&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. sudo apt-get install npm node&lt;br /&gt;
   (if the above fails due to the error &amp;quot;The following packages have unmet dependencies&amp;quot;, run the commands separately, ie. sudo apt-get install npm and then sudo apt-get install node)&lt;br /&gt;
2. npm install recess -g&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt; stands for Node Package Manager, and is the equivalent of apt-get for node.js packages.&lt;br /&gt;
&lt;br /&gt;
==== Installing Recess on Mac OS X ====&lt;br /&gt;
1. Install the basic node packages from the web site: [http://nodejs.org http://nodejs.org]   (or use your favourite package manager to install &amp;lt;code&amp;gt;node&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
2. On the command line, install recess like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    npm install recess -g&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installing Recess under Windows7 ====&lt;br /&gt;
&lt;br /&gt;
In order to install Recess you need to have Node.js installed first, which is relatively simple to do.&lt;br /&gt;
&lt;br /&gt;
====Install Node.js====  &lt;br /&gt;
&lt;br /&gt;
These instructions are for Windows 7 64 bit.&lt;br /&gt;
&lt;br /&gt;
Go to nodejs.org click install. &lt;br /&gt;
&lt;br /&gt;
When installed go to -&amp;gt; Start -&amp;gt; All Programs -&amp;gt; type Node.js into the Search box, then select Node.js Command prompt (black icon) from the list. Now you are ready to install Recess. So at the command line prompt type the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 npm install recess -g&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt; stands for Node Package Manager, and is the equivalent of apt-get for node.js packages.&lt;br /&gt;
&lt;br /&gt;
==== Using Recess ====&lt;br /&gt;
&lt;br /&gt;
After editing the LESS files, compile your CSS as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd theme/bootstrapbase/less/&lt;br /&gt;
recess --compile --compress moodle.less &amp;gt; ../style/moodle.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will compile and compress the moodle.less file (and all the LESS and CSS files it imports) into a single file, moodle.css, and store it in the style folder of the bootstrapbase theme.&lt;br /&gt;
&lt;br /&gt;
NOTE: if you are getting empty moodle.css files, this is being caused by a parsing error in your LESS code. A bug in &amp;lt;code&amp;gt;recess&amp;lt;/code&amp;gt; currently prevents it giving you helpful error messages in many cases. You will need to examine what you have altered or written to make sure it is complete and the syntax is correct. The &amp;lt;code&amp;gt;lessc&amp;lt;/code&amp;gt; compiler is what is used by &amp;lt;code&amp;gt;recess&amp;lt;/code&amp;gt; to do the actual compiling and will have been installed automatically along with it. If you call it directly as &amp;lt;code&amp;gt;lessc moodle.less&amp;lt;/code&amp;gt; it should give you a helpful error message that points you to where the problem is.&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Clean_theme&amp;diff=39518</id>
		<title>Clean theme</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Clean_theme&amp;diff=39518"/>
		<updated>2013-05-05T12:44:23Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Renaming Elements */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}{{Moodle 2.5}}This document describes how to copy and customise the Clean (bootstrapbase) theme so that you can build on this to create a theme of your own. It assumes you have some understanding of how themes work within Moodle 2.5, as well as a basic understanding of HTML and CSS. Also, because of the rapid development within Moodle, resulting in a number of versions available namely 2.3.x and 2.4.x, and 2.5.x it is important to understand that this tutorial is only valid for the Moodle 2.5+ Clean theme.&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
From your Moodle &#039;&#039;&#039;theme&#039;&#039;&#039; directory &#039;&#039;&#039;right click&#039;&#039;&#039; on the &#039;&#039;&#039;clean&#039;&#039;&#039; theme and then &#039;&#039;&#039;&#039;&#039;copy&#039;&#039;&#039; and  &#039;&#039;&#039;paste&#039;&#039;&#039;&#039;&#039; back into your Moodle &#039;&#039;&#039;theme&#039;&#039;&#039; directory. You should now have a folder called &#039;&#039;&#039;Copy of clean&#039;&#039;&#039;. If you &#039;&#039;&#039;right click&#039;&#039;&#039; this folder you are given the option to &#039;&#039;&#039;Rename&#039;&#039;&#039; it. So rename this folder to your choosen theme name, using only lower case letters, and if needed, underscores. For the purpose of this tutorial we will call the theme &#039;cleantheme&#039;.&lt;br /&gt;
&lt;br /&gt;
On opening &#039;cleantheme&#039; you will find several files and sub-directories which have files within them.&lt;br /&gt;
&lt;br /&gt;
These are:&lt;br /&gt;
; config.php :  Where all the theme configurations are made. &#039;&#039;(contains some elements that require renaming)&#039;&#039;&lt;br /&gt;
; lib.php :  Where all the functions for the themes settings are found. &#039;&#039;(contains some elements that require renaming)&#039;&#039;&lt;br /&gt;
; settings.php :  Where all the setting for this theme are created. &#039;&#039;(contains some elements that require renaming)&#039;&#039;&lt;br /&gt;
; version.php :  Where the version number and plugin componant information is kept. &#039;&#039;(contains some elements that require renaming)&#039;&#039;&lt;br /&gt;
; /lang/ : This directory contains all language sub-directories for other languages if and when you want to add them.&lt;br /&gt;
; /lang/en/ : This sub-directory contains your language files, in this case &#039;&#039;English&#039;&#039;.&lt;br /&gt;
; /lang/en/theme_clean.php : This file contains all the language strings for your theme. &#039;&#039;(contains some elements that require renaming as well as the filename itself)&#039;&#039;  &lt;br /&gt;
; /layout/ : This directory contains all the layout files for this theme.&lt;br /&gt;
; /layout/general.php : Layout file for front page and general pages combined.&lt;br /&gt;
; /style/ : This directory contains all the CSS files for this theme.&lt;br /&gt;
; /style/custom.css : This is where all the settings CSS is generated.&lt;br /&gt;
; /pix/ : This directory contains a screen shot of this theme as well as a favicon and any images used in the theme.&lt;br /&gt;
&lt;br /&gt;
==Renaming Elements==&lt;br /&gt;
&lt;br /&gt;
The problem when &#039;&#039;&#039;cloning&#039;&#039;&#039; a theme is that you need to rename all those instances where the old theme name occurs, in this case &#039;&#039;&#039;clean&#039;&#039;&#039;. So using the above list as a guide, search through and change all the instances of the theme name &#039;clean&#039; to &#039;cleantheme&#039;. This includes the filename of the lang/en/theme_clean.php. You need to change this to &#039;theme_cleantheme.php&#039;.&lt;br /&gt;
&lt;br /&gt;
==Installing your theme==&lt;br /&gt;
&lt;br /&gt;
Once all the changes to the name have been made, you can safely install the theme. If you are already logged in just refreshing the browser should trigger your Moodle site to begin the install &#039;Plugins Check&#039;. If not then navigate to Administration &amp;gt; Notifications.&lt;br /&gt;
&lt;br /&gt;
Once your theme is successfully installed you can select it and begin to modify it using the custom settings page found by navigating to Administration &amp;gt; Site Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt;&amp;gt; and then click on (Cleantheme) or whatever you renamed your theme to, from the list of theme names that appear at this point in the side block.&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Clean_theme&amp;diff=39517</id>
		<title>Clean theme</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Clean_theme&amp;diff=39517"/>
		<updated>2013-05-05T12:42:47Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Getting started */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}{{Moodle 2.5}}This document describes how to copy and customise the Clean (bootstrapbase) theme so that you can build on this to create a theme of your own. It assumes you have some understanding of how themes work within Moodle 2.5, as well as a basic understanding of HTML and CSS. Also, because of the rapid development within Moodle, resulting in a number of versions available namely 2.3.x and 2.4.x, and 2.5.x it is important to understand that this tutorial is only valid for the Moodle 2.5+ Clean theme.&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
From your Moodle &#039;&#039;&#039;theme&#039;&#039;&#039; directory &#039;&#039;&#039;right click&#039;&#039;&#039; on the &#039;&#039;&#039;clean&#039;&#039;&#039; theme and then &#039;&#039;&#039;&#039;&#039;copy&#039;&#039;&#039; and  &#039;&#039;&#039;paste&#039;&#039;&#039;&#039;&#039; back into your Moodle &#039;&#039;&#039;theme&#039;&#039;&#039; directory. You should now have a folder called &#039;&#039;&#039;Copy of clean&#039;&#039;&#039;. If you &#039;&#039;&#039;right click&#039;&#039;&#039; this folder you are given the option to &#039;&#039;&#039;Rename&#039;&#039;&#039; it. So rename this folder to your choosen theme name, using only lower case letters, and if needed, underscores. For the purpose of this tutorial we will call the theme &#039;cleantheme&#039;.&lt;br /&gt;
&lt;br /&gt;
On opening &#039;cleantheme&#039; you will find several files and sub-directories which have files within them.&lt;br /&gt;
&lt;br /&gt;
These are:&lt;br /&gt;
; config.php :  Where all the theme configurations are made. &#039;&#039;(contains some elements that require renaming)&#039;&#039;&lt;br /&gt;
; lib.php :  Where all the functions for the themes settings are found. &#039;&#039;(contains some elements that require renaming)&#039;&#039;&lt;br /&gt;
; settings.php :  Where all the setting for this theme are created. &#039;&#039;(contains some elements that require renaming)&#039;&#039;&lt;br /&gt;
; version.php :  Where the version number and plugin componant information is kept. &#039;&#039;(contains some elements that require renaming)&#039;&#039;&lt;br /&gt;
; /lang/ : This directory contains all language sub-directories for other languages if and when you want to add them.&lt;br /&gt;
; /lang/en/ : This sub-directory contains your language files, in this case &#039;&#039;English&#039;&#039;.&lt;br /&gt;
; /lang/en/theme_clean.php : This file contains all the language strings for your theme. &#039;&#039;(contains some elements that require renaming as well as the filename itself)&#039;&#039;  &lt;br /&gt;
; /layout/ : This directory contains all the layout files for this theme.&lt;br /&gt;
; /layout/general.php : Layout file for front page and general pages combined.&lt;br /&gt;
; /style/ : This directory contains all the CSS files for this theme.&lt;br /&gt;
; /style/custom.css : This is where all the settings CSS is generated.&lt;br /&gt;
; /pix/ : This directory contains a screen shot of this theme as well as a favicon and any images used in the theme.&lt;br /&gt;
&lt;br /&gt;
==Renaming Elements==&lt;br /&gt;
&lt;br /&gt;
The problem when &#039;&#039;&#039;cloning&#039;&#039;&#039; a theme is that you need to rename all those instances where the old theme name occurs, in this case &#039;&#039;&#039;simple&#039;&#039;&#039;. So using the above list as a guide, search through and change all the instances of the theme name &#039;simple&#039; to &#039;simple2&#039;. This includes the filename of the lang/en/theme_simple.php. You need to change this to &#039;theme_cleantheme.php&#039;.&lt;br /&gt;
&lt;br /&gt;
==Installing your theme==&lt;br /&gt;
&lt;br /&gt;
Once all the changes to the name have been made, you can safely install the theme. If you are already logged in just refreshing the browser should trigger your Moodle site to begin the install &#039;Plugins Check&#039;. If not then navigate to Administration &amp;gt; Notifications.&lt;br /&gt;
&lt;br /&gt;
Once your theme is successfully installed you can select it and begin to modify it using the custom settings page found by navigating to Administration &amp;gt; Site Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt;&amp;gt; and then click on (Cleantheme) or whatever you renamed your theme to, from the list of theme names that appear at this point in the side block.&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Themes&amp;diff=39516</id>
		<title>Themes</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Themes&amp;diff=39516"/>
		<updated>2013-05-05T12:36:30Z</updated>

		<summary type="html">&lt;p&gt;Tqr: Added a link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is a starting point for Moodle theme developers.&lt;br /&gt;
&lt;br /&gt;
For documentation on installing and using themes, please see the [[:en:Themes|Themes user documentation]] and [[:en:Themes FAQ|Themes FAQ]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Moodle has a powerful themes system that allows for a variety of effects through the use of XHTML and CSS.&lt;br /&gt;
&lt;br /&gt;
* [[Themes overview]]&lt;br /&gt;
* [[Creating a theme]] - A quick step by step guide to creating your first theme.&lt;br /&gt;
* [[Cloning a theme]]&lt;br /&gt;
* [[Using images in a theme]] - How to use and override images within your theme.&lt;br /&gt;
* [[Creating a theme settings page]] - Looks at how to add a setting page making your theme easily customisable.&lt;br /&gt;
* [[Extending the theme custom menu]] - Customising the custom menu.&lt;br /&gt;
* [[Overriding a renderer]] - A tutorial on creating a custom renderer and changing the HTML Moodle produces. &lt;br /&gt;
* [[Clean theme]] (new in 2.5) - How to copy and customise the Clean theme to create your own theme.&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=224651 How to add a &#039;Watermark&#039; as a background image to your theme.]&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[:Category:Themes|List of all themes-related developer documentation]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Themes]]&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=LESS&amp;diff=39400</id>
		<title>LESS</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=LESS&amp;diff=39400"/>
		<updated>2013-04-28T17:42:22Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* The bootstrap theme */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
LESS ([http://lesscss.org lesscss.org]) extends CSS with dynamic behavior such as variables, mixins, operations and functions.  It&#039;s an advanced way of writing CSS that we use in some themes within Moodle.&lt;br /&gt;
&lt;br /&gt;
Browsers don&#039;t interpret it themselves, however, so LESS files need to be converted into normal CSS before use.&lt;br /&gt;
&lt;br /&gt;
Recess is one tool used to compile and compress LESS into CSS under *nix based systems.  There are [https://github.com/cloudhead/less.js/wiki/GUI-compilers-that-use-LESS.js many others tools for LESS].&lt;br /&gt;
&lt;br /&gt;
== The bootstrap theme ==&lt;br /&gt;
&lt;br /&gt;
Moodle&#039;s [[Bootstrap]] base theme has rules written using LESS.&lt;br /&gt;
&lt;br /&gt;
The main LESS file is &#039;&#039;&#039;theme/bootstrap/less/moodle.less&#039;&#039;&#039;, with additional files  in &#039;&#039;&#039;theme/bootstrap/less/moodle/&#039;&#039;&#039; imported by the main file. &lt;br /&gt;
&lt;br /&gt;
After compiling the LESS files, CSS ends up in &#039;&#039;&#039;theme/bootstrapbase/style/moodle.css&#039;&#039;&#039;.  This file should not be edited manually.&lt;br /&gt;
&lt;br /&gt;
== Compilers ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Recess ===&lt;br /&gt;
==== Installing Recess under Ubuntu ====&lt;br /&gt;
The following commands should be run to install Recess&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. sudo apt-get install npm node&lt;br /&gt;
   (if the above fails due to the error &amp;quot;The following packages have unmet dependencies&amp;quot;, run the commands separately, ie. sudo apt-get install npm and then sudo apt-get install node)&lt;br /&gt;
2. npm install recess -g&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt; stands for Node Package Manager, and is the equivalent of apt-get for node.js packages.&lt;br /&gt;
&lt;br /&gt;
==== Installing Recess on Mac OS X ====&lt;br /&gt;
1. Install the basic node packages from the web site: [http://nodejs.org http://nodejs.org]   (or use your favourite package manager to install &amp;lt;code&amp;gt;node&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
2. On the command line, install recess like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    npm install recess -g&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installing Recess under Windows7 ====&lt;br /&gt;
&lt;br /&gt;
In order to install Recess you need to have Node.js installed first, which is relatively simple to do.&lt;br /&gt;
&lt;br /&gt;
====Install Node.js====  &lt;br /&gt;
&lt;br /&gt;
These instructions are for Windows 7 64 bit.&lt;br /&gt;
&lt;br /&gt;
Go to nodejs.org click install. &lt;br /&gt;
&lt;br /&gt;
When installed go to -&amp;gt; Start -&amp;gt; All Programs -&amp;gt; type Node.js into the Search box, then select Node.js Command prompt (black icon) from the list. Now you are ready to install Recess. So at the command line prompt type the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 npm install recess -g&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt; stands for Node Package Manager, and is the equivalent of apt-get for node.js packages.&lt;br /&gt;
&lt;br /&gt;
==== Using Recess ====&lt;br /&gt;
&lt;br /&gt;
After editing the LESS files, compile your CSS as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd theme/boostrap/less/&lt;br /&gt;
recess --compile --compress moodle.less &amp;gt; ../style/moodle.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will compile and compress the moodle.less file (and all the LESS and CSS files it imports) into a single file, moodle.css, and store it in the style folder of the bootstrap theme.&lt;br /&gt;
&lt;br /&gt;
NOTE: if you are getting empty moodle.css files, this is being caused by a parsing error in your LESS code. A bug in &amp;lt;code&amp;gt;recess&amp;lt;/code&amp;gt; currently prevents it giving you helpful error messages in many cases. You will need to examine what you have altered or written to make sure it is complete and the syntax is correct. The &amp;lt;code&amp;gt;lessc&amp;lt;/code&amp;gt; compiler is what is used by &amp;lt;code&amp;gt;recess&amp;lt;/code&amp;gt; to do the actual compiling and will have been installed automatically along with it. If you call it directly as &amp;lt;code&amp;gt;lessc moodle.less&amp;lt;/code&amp;gt; it should give you a helpful error message that points you to where the problem is.&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Clean_theme&amp;diff=39349</id>
		<title>Clean theme</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Clean_theme&amp;diff=39349"/>
		<updated>2013-04-25T09:47:25Z</updated>

		<summary type="html">&lt;p&gt;Tqr: Updating contents ready for name change. :)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}{{Moodle 2.5}}This document describes how to copy and customise the Clean (bootstrapbase) theme so that you can build on this to create a theme of your own. It assumes you have some understanding of how themes work within Moodle 2.5, as well as a basic understanding of HTML and CSS. Also, because of the rapid development within Moodle, resulting in a number of versions available namely 2.3.x and 2.4.x, and 2.5.x it is important to understand that this tutorial is only valid for the Moodle 2.5+ Clean theme.&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
From your Moodle &#039;&#039;&#039;theme&#039;&#039;&#039; directory &#039;&#039;&#039;right click&#039;&#039;&#039; on the &#039;&#039;&#039;clean&#039;&#039;&#039; theme and then &#039;&#039;&#039;&#039;&#039;copy&#039;&#039;&#039; and  &#039;&#039;&#039;paste&#039;&#039;&#039;&#039;&#039; back into your Moodle &#039;&#039;&#039;theme&#039;&#039;&#039; directory. You should now have a folder called &#039;&#039;&#039;Copy of clean&#039;&#039;&#039;. If you &#039;&#039;&#039;right click&#039;&#039;&#039; this folder you are given the option to &#039;&#039;&#039;Rename&#039;&#039;&#039; it. So rename this folder to your choosen theme name, using only lower case letters, and if needed, underscores. For the purpose of this tutorial we will call the theme &#039;cleantheme&#039;.&lt;br /&gt;
&lt;br /&gt;
On opening &#039;cleantheme&#039; you will find several files and sub-directories which have files within them.&lt;br /&gt;
&lt;br /&gt;
These are:&lt;br /&gt;
; config.php :  Where all the theme configurations are made. &#039;&#039;(contains some elements that require renaming)&#039;&#039;&lt;br /&gt;
; lib.php :  Where all the functions for the themes settings are found. &#039;&#039;(contains some elements that require renaming)&#039;&#039;&lt;br /&gt;
; settings.php :  Where all the setting for this theme are created. &#039;&#039;(contains some elements that require renaming)&#039;&#039;&lt;br /&gt;
; version.php :  Where the version number and plugin componant information is kept. &#039;&#039;(contains some elements that require renaming)&#039;&#039;&lt;br /&gt;
; /lang/ : This directory contains all language sub-directories for other languages if and when you want to add them.&lt;br /&gt;
; /lang/en/ : This sub-directory contains your language files, in this case &#039;&#039;English&#039;&#039;.&lt;br /&gt;
; /lang/en/theme_simple.php : This file contains all the language strings for your theme. &#039;&#039;(contains some elements that require renaming as well as the filename itself)&#039;&#039;  &lt;br /&gt;
; /layout/ : This directory contains all the layout files for this theme.&lt;br /&gt;
; /layout/general.php : Layout file for front page and general pages combined.&lt;br /&gt;
; /style/ : This directory contains all the CSS files for this theme.&lt;br /&gt;
; /style/custom.css : This is where all the settings CSS is generated.&lt;br /&gt;
; /pix/ : This directory contains a screen shot of this theme as well as a favicon and any images used in the theme.&lt;br /&gt;
&lt;br /&gt;
==Renaming Elements==&lt;br /&gt;
&lt;br /&gt;
The problem when &#039;&#039;&#039;cloning&#039;&#039;&#039; a theme is that you need to rename all those instances where the old theme name occurs, in this case &#039;&#039;&#039;simple&#039;&#039;&#039;. So using the above list as a guide, search through and change all the instances of the theme name &#039;simple&#039; to &#039;simple2&#039;. This includes the filename of the lang/en/theme_simple.php. You need to change this to &#039;theme_cleantheme.php&#039;.&lt;br /&gt;
&lt;br /&gt;
==Installing your theme==&lt;br /&gt;
&lt;br /&gt;
Once all the changes to the name have been made, you can safely install the theme. If you are already logged in just refreshing the browser should trigger your Moodle site to begin the install &#039;Plugins Check&#039;. If not then navigate to Administration &amp;gt; Notifications.&lt;br /&gt;
&lt;br /&gt;
Once your theme is successfully installed you can select it and begin to modify it using the custom settings page found by navigating to Administration &amp;gt; Site Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt;&amp;gt; and then click on (Cleantheme) or whatever you renamed your theme to, from the list of theme names that appear at this point in the side block.&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Cloning_a_theme&amp;diff=39325</id>
		<title>Cloning a theme</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Cloning_a_theme&amp;diff=39325"/>
		<updated>2013-04-23T21:32:31Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Renaming Elements */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}This document describes how to clone a theme from an existing Moodle 2 theme. It assumes you have some understanding of how themes work within Moodle, as well as a basic understanding of XHTML and CSS. Also, because of the rapid development within Moodle, resulting in a number of versions available namely 2.0.x, 2.1.x 2.2.x 2.3.x 2.4.x and soon to be announced Moodle 2.5.x it is important to know that this tutorial is valid for ONLY Moodle Boxxie theme, and as such does not take into account the various other elements you will find in other Moodle versions of themes like Afterburner, Formal White, Sky High, to name but a few. If you are looking to clone one of these themes then checkout my new tutorials. [https://docs.moodle.org/dev/Themes_2.2_how_to_clone_a_Moodle_2.2_theme How to clone a Moodle 2.2 theme].  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
Since this is a very easy introduction to creating a custom theme, the first thing to create is a copy of the version of the theme you want to clone. For the purpose of this tutorial, we will be cloning &#039;&#039;&#039;Boxxie&#039;&#039;&#039;, which is one of several Moodle &#039;&#039;&#039;core&#039;&#039;&#039; themes. There are other themes you can &#039;clone&#039; which are a little harder to do, but once you are familiar with this easy one, you can tackle the harder ones later.&lt;br /&gt;
&lt;br /&gt;
OK...let&#039;s get started. From your Moodle &#039;&#039;&#039;theme&#039;&#039;&#039; directory &#039;&#039;&#039;right click&#039;&#039;&#039; on &#039;&#039;&#039;boxxie&#039;&#039;&#039; and then &#039;&#039;&#039;&#039;&#039;copy&#039;&#039;&#039; and  &#039;&#039;&#039;paste&#039;&#039;&#039;&#039;&#039; back into your Moodle &#039;&#039;&#039;theme&#039;&#039;&#039; directory. You should now have a folder called &#039;&#039;&#039;Copy of boxxie&#039;&#039;&#039;. If you &#039;&#039;&#039;right click&#039;&#039;&#039; this folder you are given the option to &#039;&#039;&#039;Rename&#039;&#039;&#039; it. So let&#039;s rename this folder to &#039;&#039;&#039;foxxie&#039;&#039;&#039; (or to whatever name you want to call your &#039;&#039;&#039;cloned&#039;&#039;&#039; theme).  It is important to use only lower case letters and underscores.&lt;br /&gt;
&lt;br /&gt;
If you open the &#039;&#039;&#039;foxxie&#039;&#039;&#039; directory you will find several directories, sub-directories and files within it. One of these sub-directories &#039;&#039;&#039;&#039;&#039;lang/en/&#039;&#039;&#039;&#039;&#039; contain a file called &#039;&#039;&#039;theme_boxxie.php&#039;&#039;&#039; which will need to be re-named to &#039;&#039;&#039;theme_foxxie.php&#039;&#039;&#039;. But we shall address this later. For now just familiarise yourself with what you find in the &#039;&#039;&#039;foxxie&#039;&#039;&#039; directory.&lt;br /&gt;
&lt;br /&gt;
These are:&lt;br /&gt;
; config.php :  Where all the theme configurations are made.&lt;br /&gt;
; /lang/ : This directory contains all language sub-directories for other languages if and when you want to add them.&lt;br /&gt;
; /lang/en/ : This sub-directory contains your language files, in this case &#039;&#039;English&#039;&#039;.&lt;br /&gt;
; /lang/en/theme_boxxie.php : This file contains all the language strings for your theme.   &lt;br /&gt;
; /layout/ : This directory contains all the layout files for this theme.&lt;br /&gt;
; /layout/frontpage.php : Layout file for front page.&lt;br /&gt;
; /layout/general.php : Layout file for all pages other than the front page.&lt;br /&gt;
; /layout/embedded.php : Layout file for embedded pages.&lt;br /&gt;
; /style/ : This directory contains all the CSS files for this theme.&lt;br /&gt;
; /style/core.css : Contains all the CSS rules for this theme.&lt;br /&gt;
; /style/boilerplate.css : Contains all the &#039;&#039;reset&#039;&#039; CSS rules for this theme.&lt;br /&gt;
; /pix/ : This directory contains a screen shot of this theme as well as a favicon and any images used in the theme.&lt;br /&gt;
; /pix/tabs : This contains all the tab images for this theme.&lt;br /&gt;
&lt;br /&gt;
==Renaming Elements==&lt;br /&gt;
&lt;br /&gt;
The problem when &#039;&#039;&#039;cloning&#039;&#039;&#039; a theme is that you need to rename all those instances where the theme name, in this case &#039;&#039;&#039;boxxie&#039;&#039;&#039;, occurs. The first place to look is &#039;&#039;&#039;config.php&#039;&#039;&#039;, where you need to change the theme name.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;name = &#039;boxxie&#039;;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////////////&lt;br /&gt;
// Name of the theme. Most likely the name of&lt;br /&gt;
// the directory in which this file resides.&lt;br /&gt;
////////////////////////////////////////////////////&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The next place to look, as mentioned above, is &#039;&#039;&#039;lang/en/theme_boxxie.php&#039;&#039;&#039;. This file, as well as needing to be renamed, also needs some of its content renaming too. So before we forget, let&#039;s &#039;&#039;&#039;right click&#039;&#039;&#039; on this file and &#039;&#039;&#039;rename&#039;&#039;&#039; it &#039;&#039;&#039;theme_foxxie.php&#039;&#039;&#039; before we open it.&lt;br /&gt;
&lt;br /&gt;
=== Language Strings ===&lt;br /&gt;
&lt;br /&gt;
When you open &#039;&#039;&#039;theme_foxxie.php&#039;&#039;&#039; the first thing you will see are the &#039;&#039;&#039;credits&#039;&#039;&#039; for the theme. &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Strings for component &#039;theme_boxxie&#039;, language &#039;en&#039;, branch &#039;MOODLE_20_STABLE&#039;&lt;br /&gt;
 *&lt;br /&gt;
 * @package   moodlecore&lt;br /&gt;
 * @copyright 2010 Patrick Malley&lt;br /&gt;
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here you will need to change the reference from &#039;&#039;&#039;boxxie&#039;&#039;&#039; to &#039;&#039;&#039;foxxie&#039;&#039;&#039;, you can leave the rest of this as it is.&lt;br /&gt;
&lt;br /&gt;
The next things you will find in this file are what are known as the &#039;&#039;&#039;language strings&#039;&#039;&#039;. These are used for any customised &#039;&#039;&#039;&#039;&#039;words&#039;&#039; or &#039;&#039;phrases&#039;&#039;&#039;&#039;&#039; used in a theme. And because this is in the &#039;&#039;&#039;foxxie/lang/en/&#039;&#039;&#039; directory all the $strings are in English. But if you wanted to add some foreign words and phrases for whenever a user switched languages, you just need to create a new sub-directory in the &#039;&#039;&#039;foxxie/lang/&#039;&#039;&#039; directory for the language files you need to add there, and then copy and paste this file to that new sub-directory. For example: &#039;&#039;&#039;foxxie/lang/it/theme_foxxie.php&#039;&#039;&#039; (where &#039;&#039;&#039;it&#039;&#039;&#039; is the code which represents the Italian language). We will explore the Language aspect of themes in another Moodle Doc. So let&#039;s just concentrate on the changes we need to make to rest of the contents of &#039;&#039;&#039;theme_foxxie.php&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;Boxxie&#039;;&lt;br /&gt;
$string[&#039;region-side-post&#039;] = &#039;Right&#039;;&lt;br /&gt;
$string[&#039;region-side-pre&#039;] = &#039;Left&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the $string section above, the only thing you need to change here is the &#039;&#039;&#039;pluginname&#039;&#039;&#039; from &#039;&#039;&#039;boxxie&#039;&#039;&#039; to &#039;&#039;&#039;foxxie&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In this next section, the &#039;&#039;&#039;choosereadme&#039;&#039;&#039;, which is written in XHTML and is the contents of the page that you will see when selecting &#039;&#039;&#039;Foxxie&#039;&#039;&#039; in the Theme Selector. However, you are advised to read what is actually written there and change it accordingly, renaming &#039;Boxxie&#039; to &#039;Foxxie&#039;, and changing the contents of this part to suit yourself. You might not want to keep all that is written here. You could actually condense it, but that&#039;s up to you. Just as long as you give credit, where credit is due, to the original theme designer by stating something on similar lines to what I have written below.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;choosereadme&#039;] = &#039;Foxxie is a customised Moodle theme&lt;br /&gt;
by Mary Evans based on the original Boxxie theme by Patrick Malley&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Recipe for the Impatient==&lt;br /&gt;
For those who want a minimal set of instructions to semi-blindly blast through this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1.&#039;&#039;&#039; Copy &#039;&#039;[moodleroot]/theme/boxxie&#039;&#039; to &#039;&#039;[moodleroot]/theme/foxxie&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2.&#039;&#039;&#039; Rename &#039;&#039;[moodleroot]/theme/foxxie/lang/en/theme_boxxie.php&#039;&#039; to &#039;&#039;[moodleroot]/theme/foxxie/lang/en/theme_foxxie.php&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3.&#039;&#039;&#039; In &#039;&#039;[moodleroot]/theme/foxxie/lang/en/theme_foxxie.php&#039;&#039;, replace any instances of &amp;quot;boxxie&amp;quot; with &amp;quot;foxxie&amp;quot;, likewise for &amp;quot;Boxxie&amp;quot; and &amp;quot;Foxxie&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4.&#039;&#039;&#039; Edit &#039;&#039;[moodleroot]/theme/foxxie/config.php&#039;&#039; to replace instance(s) of &amp;quot;boxxie&amp;quot; with &amp;quot;foxxie&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Appendix==&lt;br /&gt;
Please Note: All theme names, directory names, and file names MUST be in lowercase.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Making a horizontal dock]] - Modifying the dock to make it horizontal.&lt;br /&gt;
* [[Styling and customising the dock]] - How to style and customise the dock.&lt;br /&gt;
* [[Adding theme upgrade code]]&lt;br /&gt;
* [[Theme changes in 2.0]]&lt;br /&gt;
* [[Using jQuery with Moodle]]&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Cloning_a_theme&amp;diff=39311</id>
		<title>Cloning a theme</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Cloning_a_theme&amp;diff=39311"/>
		<updated>2013-04-23T07:40:56Z</updated>

		<summary type="html">&lt;p&gt;Tqr: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}This document describes how to clone a theme from an existing Moodle 2 theme. It assumes you have some understanding of how themes work within Moodle, as well as a basic understanding of XHTML and CSS. Also, because of the rapid development within Moodle, resulting in a number of versions available namely 2.0.x, 2.1.x 2.2.x 2.3.x 2.4.x and soon to be announced Moodle 2.5.x it is important to know that this tutorial is valid for ONLY Moodle Boxxie theme, and as such does not take into account the various other elements you will find in other Moodle versions of themes like Afterburner, Formal White, Sky High, to name but a few. If you are looking to clone one of these themes then checkout my new tutorials. [https://docs.moodle.org/dev/Themes_2.2_how_to_clone_a_Moodle_2.2_theme How to clone a Moodle 2.2 theme].  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
Since this is a very easy introduction to creating a custom theme, the first thing to create is a copy of the version of the theme you want to clone. For the purpose of this tutorial, we will be cloning &#039;&#039;&#039;Boxxie&#039;&#039;&#039;, which is one of several Moodle &#039;&#039;&#039;core&#039;&#039;&#039; themes. There are other themes you can &#039;clone&#039; which are a little harder to do, but once you are familiar with this easy one, you can tackle the harder ones later.&lt;br /&gt;
&lt;br /&gt;
OK...let&#039;s get started. From your Moodle &#039;&#039;&#039;theme&#039;&#039;&#039; directory &#039;&#039;&#039;right click&#039;&#039;&#039; on &#039;&#039;&#039;boxxie&#039;&#039;&#039; and then &#039;&#039;&#039;&#039;&#039;copy&#039;&#039;&#039; and  &#039;&#039;&#039;paste&#039;&#039;&#039;&#039;&#039; back into your Moodle &#039;&#039;&#039;theme&#039;&#039;&#039; directory. You should now have a folder called &#039;&#039;&#039;Copy of boxxie&#039;&#039;&#039;. If you &#039;&#039;&#039;right click&#039;&#039;&#039; this folder you are given the option to &#039;&#039;&#039;Rename&#039;&#039;&#039; it. So let&#039;s rename this folder to &#039;&#039;&#039;foxxie&#039;&#039;&#039; (or to whatever name you want to call your &#039;&#039;&#039;cloned&#039;&#039;&#039; theme).  It is important to use only lower case letters and underscores.&lt;br /&gt;
&lt;br /&gt;
If you open the &#039;&#039;&#039;foxxie&#039;&#039;&#039; directory you will find several directories, sub-directories and files within it. One of these sub-directories &#039;&#039;&#039;&#039;&#039;lang/en/&#039;&#039;&#039;&#039;&#039; contain a file called &#039;&#039;&#039;theme_boxxie.php&#039;&#039;&#039; which will need to be re-named to &#039;&#039;&#039;theme_foxxie.php&#039;&#039;&#039;. But we shall address this later. For now just familiarise yourself with what you find in the &#039;&#039;&#039;foxxie&#039;&#039;&#039; directory.&lt;br /&gt;
&lt;br /&gt;
These are:&lt;br /&gt;
; config.php :  Where all the theme configurations are made.&lt;br /&gt;
; /lang/ : This directory contains all language sub-directories for other languages if and when you want to add them.&lt;br /&gt;
; /lang/en/ : This sub-directory contains your language files, in this case &#039;&#039;English&#039;&#039;.&lt;br /&gt;
; /lang/en/theme_boxxie.php : This file contains all the language strings for your theme.   &lt;br /&gt;
; /layout/ : This directory contains all the layout files for this theme.&lt;br /&gt;
; /layout/frontpage.php : Layout file for front page.&lt;br /&gt;
; /layout/general.php : Layout file for all pages other than the front page.&lt;br /&gt;
; /layout/embedded.php : Layout file for embedded pages.&lt;br /&gt;
; /style/ : This directory contains all the CSS files for this theme.&lt;br /&gt;
; /style/core.css : Contains all the CSS rules for this theme.&lt;br /&gt;
; /style/boilerplate.css : Contains all the &#039;&#039;reset&#039;&#039; CSS rules for this theme.&lt;br /&gt;
; /pix/ : This directory contains a screen shot of this theme as well as a favicon and any images used in the theme.&lt;br /&gt;
; /pix/tabs : This contains all the tab images for this theme.&lt;br /&gt;
&lt;br /&gt;
==Renaming Elements==&lt;br /&gt;
&lt;br /&gt;
The problem when &#039;&#039;&#039;cloning&#039;&#039;&#039; a theme is that you need to rename all those instances where the theme name, in this case &#039;&#039;&#039;boxxie&#039;&#039;&#039;, occurs. The first place to look is &#039;&#039;&#039;config.php&#039;&#039;&#039;, where you need to change the theme name.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;name = &#039;boxxie&#039;;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////////////&lt;br /&gt;
// Name of the theme. Most likely the name of&lt;br /&gt;
// the directory in which this file resides.&lt;br /&gt;
////////////////////////////////////////////////////&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The next place to look, as mentioned above, is &#039;&#039;&#039;lang/en/theme_boxxie.php&#039;&#039;&#039;. This file, as well as needing to be renamed, also needs some of its content renaming too. So before we forget, let&#039;s &#039;&#039;&#039;right click&#039;&#039;&#039; on this file and &#039;&#039;&#039;rename&#039;&#039;&#039; it &#039;&#039;&#039;theme_foxxie.php&#039;&#039;&#039; before we open it.&lt;br /&gt;
&lt;br /&gt;
=== Language Strings ===&lt;br /&gt;
&lt;br /&gt;
When you open &#039;&#039;&#039;theme_foxxie.php&#039;&#039;&#039; the first thing you will see are the &#039;&#039;&#039;credits&#039;&#039;&#039; for the theme. &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Strings for component &#039;theme_boxxie&#039;, language &#039;en&#039;, branch &#039;MOODLE_20_STABLE&#039;&lt;br /&gt;
 *&lt;br /&gt;
 * @package   moodlecore&lt;br /&gt;
 * @copyright 2010 Patrick Malley&lt;br /&gt;
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here you will need to change the reference from &#039;&#039;&#039;boxxie&#039;&#039;&#039; to &#039;&#039;&#039;foxxie&#039;&#039;&#039;, you can leave the rest of this as it is.&lt;br /&gt;
&lt;br /&gt;
The next things you will find in this file are what are known as the &#039;&#039;&#039;language strings&#039;&#039;&#039;. These are used for any customised &#039;&#039;&#039;&#039;&#039;words&#039;&#039; or &#039;&#039;phrases&#039;&#039;&#039;&#039;&#039; used in a theme. And because this is in the &#039;&#039;&#039;foxxie/lang/en/&#039;&#039;&#039; directory all the $strings are in English. But if you wanted to add some foreign words and phrases for whenever a user switched languages, you just need to create a new sub-directory in the &#039;&#039;&#039;foxxie/lang/&#039;&#039;&#039; directory for the language files you need to add there, and then copy and paste this file to that new sub-directory. For example: &#039;&#039;&#039;foxxie/lang/it/theme_foxxie.php&#039;&#039;&#039; (where &#039;&#039;&#039;it&#039;&#039;&#039; is the code which represents the Italian language). We will explore the Language aspect of themes in another Moodle Doc. So let&#039;s just concentrate on the changes we need to make to rest of the contents of &#039;&#039;&#039;theme_foxxie.php&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;Boxxie&#039;;&lt;br /&gt;
$string[&#039;region-side-post&#039;] = &#039;Right&#039;;&lt;br /&gt;
$string[&#039;region-side-pre&#039;] = &#039;Left&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the $string section above, the only thing you need to change here is the &#039;&#039;&#039;pluginname&#039;&#039;&#039; from &#039;&#039;&#039;boxxie&#039;&#039;&#039; to &#039;&#039;&#039;foxxie&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In this next section, the &#039;&#039;&#039;choosereadme&#039;&#039;&#039;, which is written in XHTML and is the contents of the page that you will see when selecting &#039;&#039;&#039;Foxxie&#039;&#039;&#039; in the Theme Selector. However, you are advised to read what is actually written there and change it accordingly, renaming &#039;Boxxie&#039; to &#039;Foxxie&#039;, and changing the contents of this part to suit yourself. You might not want to keep all that is written here. You could actually condense it, but that&#039;s up to you. Just as long as you give credit, where credit is due, to the original theme designer by stating something on similar lines to what I have written below.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;choosereadme&#039;] = &#039;Foxxie is a customised Moodle theme&lt;br /&gt;
by Mary Evans based on the original Boxxie theme by Patrick Malley&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And that is all there is to this Moodle 2.0 theme.&lt;br /&gt;
&lt;br /&gt;
==Recipe for the Impatient==&lt;br /&gt;
For those who want a minimal set of instructions to semi-blindly blast through this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1.&#039;&#039;&#039; Copy &#039;&#039;[moodleroot]/theme/boxxie&#039;&#039; to &#039;&#039;[moodleroot]/theme/foxxie&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2.&#039;&#039;&#039; Rename &#039;&#039;[moodleroot]/theme/foxxie/lang/en/theme_boxxie.php&#039;&#039; to &#039;&#039;[moodleroot]/theme/foxxie/lang/en/theme_foxxie.php&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3.&#039;&#039;&#039; In &#039;&#039;[moodleroot]/theme/foxxie/lang/en/theme_foxxie.php&#039;&#039;, replace any instances of &amp;quot;boxxie&amp;quot; with &amp;quot;foxxie&amp;quot;, likewise for &amp;quot;Boxxie&amp;quot; and &amp;quot;Foxxie&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4.&#039;&#039;&#039; Edit &#039;&#039;[moodleroot]/theme/foxxie/config.php&#039;&#039; to replace instance(s) of &amp;quot;boxxie&amp;quot; with &amp;quot;foxxie&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Appendix==&lt;br /&gt;
Please Note: All theme names, directory names, and file names MUST be in lowercase.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Making a horizontal dock]] - Modifying the dock to make it horizontal.&lt;br /&gt;
* [[Styling and customising the dock]] - How to style and customise the dock.&lt;br /&gt;
* [[Adding theme upgrade code]]&lt;br /&gt;
* [[Theme changes in 2.0]]&lt;br /&gt;
* [[Using jQuery with Moodle]]&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Cloning_a_theme&amp;diff=39310</id>
		<title>Cloning a theme</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Cloning_a_theme&amp;diff=39310"/>
		<updated>2013-04-23T07:38:16Z</updated>

		<summary type="html">&lt;p&gt;Tqr: Simplifying&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}This document describes how to clone a theme from an existing Moodle 2 theme. It assumes you have some understanding of how themes work within Moodle, as well as a basic understanding of XHTML and CSS. Also, because of the rapid development within Moodle, resulting in a number of versions available namely 2.0.x, 2.1.x 2.2.x 2.3.x 2.4.x and soon to be announced Moodle 2.5.x it is important to know that this tutorial is valid for ONLY Moodle Boxxie theme, and as such does not take into account the various other elements you will find in other Moodle versions of themes like Afterburner, Formal White, Sky High, to name but a few. If you are looking to clone one of these themes then checkout my new tutorials. [https://docs.moodle.org/dev/how_to_clone_a_Moodle_2.2_theme How to clone a Moodle 2.2 theme].  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
Since this is a very easy introduction to creating a custom theme, the first thing to create is a copy of the version of the theme you want to clone. For the purpose of this tutorial, we will be cloning &#039;&#039;&#039;Boxxie&#039;&#039;&#039;, which is one of several Moodle &#039;&#039;&#039;core&#039;&#039;&#039; themes. There are other themes you can &#039;clone&#039; which are a little harder to do, but once you are familiar with this easy one, you can tackle the harder ones later.&lt;br /&gt;
&lt;br /&gt;
OK...let&#039;s get started. From your Moodle &#039;&#039;&#039;theme&#039;&#039;&#039; directory &#039;&#039;&#039;right click&#039;&#039;&#039; on &#039;&#039;&#039;boxxie&#039;&#039;&#039; and then &#039;&#039;&#039;&#039;&#039;copy&#039;&#039;&#039; and  &#039;&#039;&#039;paste&#039;&#039;&#039;&#039;&#039; back into your Moodle &#039;&#039;&#039;theme&#039;&#039;&#039; directory. You should now have a folder called &#039;&#039;&#039;Copy of boxxie&#039;&#039;&#039;. If you &#039;&#039;&#039;right click&#039;&#039;&#039; this folder you are given the option to &#039;&#039;&#039;Rename&#039;&#039;&#039; it. So let&#039;s rename this folder to &#039;&#039;&#039;foxxie&#039;&#039;&#039; (or to whatever name you want to call your &#039;&#039;&#039;cloned&#039;&#039;&#039; theme).  It is important to use only lower case letters and underscores.&lt;br /&gt;
&lt;br /&gt;
If you open the &#039;&#039;&#039;foxxie&#039;&#039;&#039; directory you will find several directories, sub-directories and files within it. One of these sub-directories &#039;&#039;&#039;&#039;&#039;lang/en/&#039;&#039;&#039;&#039;&#039; contain a file called &#039;&#039;&#039;theme_boxxie.php&#039;&#039;&#039; which will need to be re-named to &#039;&#039;&#039;theme_foxxie.php&#039;&#039;&#039;. But we shall address this later. For now just familiarise yourself with what you find in the &#039;&#039;&#039;foxxie&#039;&#039;&#039; directory.&lt;br /&gt;
&lt;br /&gt;
These are:&lt;br /&gt;
; config.php :  Where all the theme configurations are made.&lt;br /&gt;
; /lang/ : This directory contains all language sub-directories for other languages if and when you want to add them.&lt;br /&gt;
; /lang/en/ : This sub-directory contains your language files, in this case &#039;&#039;English&#039;&#039;.&lt;br /&gt;
; /lang/en/theme_boxxie.php : This file contains all the language strings for your theme.   &lt;br /&gt;
; /layout/ : This directory contains all the layout files for this theme.&lt;br /&gt;
; /layout/frontpage.php : Layout file for front page.&lt;br /&gt;
; /layout/general.php : Layout file for all pages other than the front page.&lt;br /&gt;
; /layout/embedded.php : Layout file for embedded pages.&lt;br /&gt;
; /style/ : This directory contains all the CSS files for this theme.&lt;br /&gt;
; /style/core.css : Contains all the CSS rules for this theme.&lt;br /&gt;
; /style/boilerplate.css : Contains all the &#039;&#039;reset&#039;&#039; CSS rules for this theme.&lt;br /&gt;
; /pix/ : This directory contains a screen shot of this theme as well as a favicon and any images used in the theme.&lt;br /&gt;
; /pix/tabs : This contains all the tab images for this theme.&lt;br /&gt;
&lt;br /&gt;
==Renaming Elements==&lt;br /&gt;
&lt;br /&gt;
The problem when &#039;&#039;&#039;cloning&#039;&#039;&#039; a theme is that you need to rename all those instances where the theme name, in this case &#039;&#039;&#039;boxxie&#039;&#039;&#039;, occurs. The first place to look is &#039;&#039;&#039;config.php&#039;&#039;&#039;, where you need to change the theme name.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;name = &#039;boxxie&#039;;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////////////&lt;br /&gt;
// Name of the theme. Most likely the name of&lt;br /&gt;
// the directory in which this file resides.&lt;br /&gt;
////////////////////////////////////////////////////&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The next place to look, as mentioned above, is &#039;&#039;&#039;lang/en/theme_boxxie.php&#039;&#039;&#039;. This file, as well as needing to be renamed, also needs some of its content renaming too. So before we forget, let&#039;s &#039;&#039;&#039;right click&#039;&#039;&#039; on this file and &#039;&#039;&#039;rename&#039;&#039;&#039; it &#039;&#039;&#039;theme_foxxie.php&#039;&#039;&#039; before we open it.&lt;br /&gt;
&lt;br /&gt;
=== Language Strings ===&lt;br /&gt;
&lt;br /&gt;
When you open &#039;&#039;&#039;theme_foxxie.php&#039;&#039;&#039; the first thing you will see are the &#039;&#039;&#039;credits&#039;&#039;&#039; for the theme. &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Strings for component &#039;theme_boxxie&#039;, language &#039;en&#039;, branch &#039;MOODLE_20_STABLE&#039;&lt;br /&gt;
 *&lt;br /&gt;
 * @package   moodlecore&lt;br /&gt;
 * @copyright 2010 Patrick Malley&lt;br /&gt;
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here you will need to change the reference from &#039;&#039;&#039;boxxie&#039;&#039;&#039; to &#039;&#039;&#039;foxxie&#039;&#039;&#039;, you can leave the rest of this as it is.&lt;br /&gt;
&lt;br /&gt;
The next things you will find in this file are what are known as the &#039;&#039;&#039;language strings&#039;&#039;&#039;. These are used for any customised &#039;&#039;&#039;&#039;&#039;words&#039;&#039; or &#039;&#039;phrases&#039;&#039;&#039;&#039;&#039; used in a theme. And because this is in the &#039;&#039;&#039;foxxie/lang/en/&#039;&#039;&#039; directory all the $strings are in English. But if you wanted to add some foreign words and phrases for whenever a user switched languages, you just need to create a new sub-directory in the &#039;&#039;&#039;foxxie/lang/&#039;&#039;&#039; directory for the language files you need to add there, and then copy and paste this file to that new sub-directory. For example: &#039;&#039;&#039;foxxie/lang/it/theme_foxxie.php&#039;&#039;&#039; (where &#039;&#039;&#039;it&#039;&#039;&#039; is the code which represents the Italian language). We will explore the Language aspect of themes in another Moodle Doc. So let&#039;s just concentrate on the changes we need to make to rest of the contents of &#039;&#039;&#039;theme_foxxie.php&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;Boxxie&#039;;&lt;br /&gt;
$string[&#039;region-side-post&#039;] = &#039;Right&#039;;&lt;br /&gt;
$string[&#039;region-side-pre&#039;] = &#039;Left&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the $string section above, the only thing you need to change here is the &#039;&#039;&#039;pluginname&#039;&#039;&#039; from &#039;&#039;&#039;boxxie&#039;&#039;&#039; to &#039;&#039;&#039;foxxie&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In this next section, the &#039;&#039;&#039;choosereadme&#039;&#039;&#039;, which is written in XHTML and is the contents of the page that you will see when selecting &#039;&#039;&#039;Foxxie&#039;&#039;&#039; in the Theme Selector. However, you are advised to read what is actually written there and change it accordingly, renaming &#039;Boxxie&#039; to &#039;Foxxie&#039;, and changing the contents of this part to suit yourself. You might not want to keep all that is written here. You could actually condense it, but that&#039;s up to you. Just as long as you give credit, where credit is due, to the original theme designer by stating something on similar lines to what I have written below.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;choosereadme&#039;] = &#039;Foxxie is a customised Moodle theme&lt;br /&gt;
by Mary Evans based on the original Boxxie theme by Patrick Malley&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And that is all there is to this Moodle 2.0 theme.&lt;br /&gt;
&lt;br /&gt;
==Recipe for the Impatient==&lt;br /&gt;
For those who want a minimal set of instructions to semi-blindly blast through this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1.&#039;&#039;&#039; Copy &#039;&#039;[moodleroot]/theme/boxxie&#039;&#039; to &#039;&#039;[moodleroot]/theme/foxxie&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2.&#039;&#039;&#039; Rename &#039;&#039;[moodleroot]/theme/foxxie/lang/en/theme_boxxie.php&#039;&#039; to &#039;&#039;[moodleroot]/theme/foxxie/lang/en/theme_foxxie.php&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3.&#039;&#039;&#039; In &#039;&#039;[moodleroot]/theme/foxxie/lang/en/theme_foxxie.php&#039;&#039;, replace any instances of &amp;quot;boxxie&amp;quot; with &amp;quot;foxxie&amp;quot;, likewise for &amp;quot;Boxxie&amp;quot; and &amp;quot;Foxxie&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4.&#039;&#039;&#039; Edit &#039;&#039;[moodleroot]/theme/foxxie/config.php&#039;&#039; to replace instance(s) of &amp;quot;boxxie&amp;quot; with &amp;quot;foxxie&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Appendix==&lt;br /&gt;
Please Note: All theme names, directory names, and file names MUST be in lowercase.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Making a horizontal dock]] - Modifying the dock to make it horizontal.&lt;br /&gt;
* [[Styling and customising the dock]] - How to style and customise the dock.&lt;br /&gt;
* [[Adding theme upgrade code]]&lt;br /&gt;
* [[Theme changes in 2.0]]&lt;br /&gt;
* [[Using jQuery with Moodle]]&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=LESS&amp;diff=39304</id>
		<title>LESS</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=LESS&amp;diff=39304"/>
		<updated>2013-04-23T01:25:42Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Install Node.js */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
LESS ([http://lesscss.org lesscss.org]) extends CSS with dynamic behavior such as variables, mixins, operations and functions.  It&#039;s an advanced way of writing CSS that we use in some themes within Moodle.&lt;br /&gt;
&lt;br /&gt;
Browsers don&#039;t interpret it themselves, however, so LESS files need to be converted into normal CSS before use.&lt;br /&gt;
&lt;br /&gt;
Recess is one tool used to compile and compress LESS into CSS under *nix based systems.  There are [https://github.com/cloudhead/less.js/wiki/GUI-compilers-that-use-LESS.js many others tools for LESS].&lt;br /&gt;
&lt;br /&gt;
== The bootstrap theme ==&lt;br /&gt;
&lt;br /&gt;
Moodle&#039;s [[Bootstrap]] base theme has rules written using LESS.&lt;br /&gt;
&lt;br /&gt;
The main LESS file is &#039;&#039;&#039;theme/bootstrap/less/moodle.less&#039;&#039;&#039;, with additional files  in &#039;&#039;&#039;theme/bootstrap/less/moodle/&#039;&#039;&#039; imported by the main file. &lt;br /&gt;
&lt;br /&gt;
After compiling the LESS files, CSS ends up in &#039;&#039;&#039;theme/bootstrap/style/generated.css&#039;&#039;&#039;.  This file should not be edited manually.&lt;br /&gt;
&lt;br /&gt;
== Compilers ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Recess ===&lt;br /&gt;
==== Installing Recess under Ubuntu ====&lt;br /&gt;
The following commands should be run to install Recess&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. sudo apt-get install npm node&lt;br /&gt;
   (if the above fails due to the error &amp;quot;The following packages have unmet dependencies&amp;quot;, run the commands separately, ie. sudo apt-get install npm and then sudo apt-get install node)&lt;br /&gt;
2. npm install recess -g&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt; stands for Node Package Manager, and is the equivalent of apt-get for node.js packages.&lt;br /&gt;
&lt;br /&gt;
==== Installing Recess on Mac OS X ====&lt;br /&gt;
1. Install the basic node packages from the web site: [http://nodejs.org http://nodejs.org]   (or use your favourite package manager to install &amp;lt;code&amp;gt;node&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
2. On the command line, install recess like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    npm install recess -g&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installing Recess under Windows7 ====&lt;br /&gt;
&lt;br /&gt;
In order to install Recess you need to have Node.js installed first, which is relatively simple to do.&lt;br /&gt;
&lt;br /&gt;
====Install Node.js====  &lt;br /&gt;
&lt;br /&gt;
These instructions are for Windows 7 64 bit.&lt;br /&gt;
&lt;br /&gt;
Go to nodejs.org click install. &lt;br /&gt;
&lt;br /&gt;
When installed go to -&amp;gt; Start -&amp;gt; All Programs -&amp;gt; type Node.js into the Search box, then select Node.js Command prompt (black icon) from the list. Now you are ready to install Recess. So at the command line prompt type the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 npm install recess -g&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt; stands for Node Package Manager, and is the equivalent of apt-get for node.js packages.&lt;br /&gt;
&lt;br /&gt;
==== Using Recess ====&lt;br /&gt;
&lt;br /&gt;
After editing the LESS files, compile your CSS as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd theme/boostrap/less/&lt;br /&gt;
recess --compile --compress moodle.less &amp;gt; ../style/generated.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will compile and compress the moodle.less file (and all the LESS and CSS files it imports) into a single file, generated.css, and store it in the style folder of the bootstrap theme.&lt;br /&gt;
&lt;br /&gt;
NOTE: if you are getting empty generated.css files, this is being caused by a parsing error in your LESS code. A bug in &amp;lt;code&amp;gt;recess&amp;lt;/code&amp;gt; currently prevents it giving you helpful error messages in many cases. You will need to examine what you have altered or written to make sure it is complete and the syntax is correct. The &amp;lt;code&amp;gt;lessc&amp;lt;/code&amp;gt; compiler is what is used by &amp;lt;code&amp;gt;recess&amp;lt;/code&amp;gt; to do the actual compiling and will have been installed automatically along with it. If you call it directly as &amp;lt;code&amp;gt;lessc moodle.less&amp;lt;/code&amp;gt; it should give you a helpful error message that points you to where the problem is.&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=LESS&amp;diff=39303</id>
		<title>LESS</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=LESS&amp;diff=39303"/>
		<updated>2013-04-23T01:23:41Z</updated>

		<summary type="html">&lt;p&gt;Tqr: /* Install Node.js */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
LESS ([http://lesscss.org lesscss.org]) extends CSS with dynamic behavior such as variables, mixins, operations and functions.  It&#039;s an advanced way of writing CSS that we use in some themes within Moodle.&lt;br /&gt;
&lt;br /&gt;
Browsers don&#039;t interpret it themselves, however, so LESS files need to be converted into normal CSS before use.&lt;br /&gt;
&lt;br /&gt;
Recess is one tool used to compile and compress LESS into CSS under *nix based systems.  There are [https://github.com/cloudhead/less.js/wiki/GUI-compilers-that-use-LESS.js many others tools for LESS].&lt;br /&gt;
&lt;br /&gt;
== The bootstrap theme ==&lt;br /&gt;
&lt;br /&gt;
Moodle&#039;s [[Bootstrap]] base theme has rules written using LESS.&lt;br /&gt;
&lt;br /&gt;
The main LESS file is &#039;&#039;&#039;theme/bootstrap/less/moodle.less&#039;&#039;&#039;, with additional files  in &#039;&#039;&#039;theme/bootstrap/less/moodle/&#039;&#039;&#039; imported by the main file. &lt;br /&gt;
&lt;br /&gt;
After compiling the LESS files, CSS ends up in &#039;&#039;&#039;theme/bootstrap/style/generated.css&#039;&#039;&#039;.  This file should not be edited manually.&lt;br /&gt;
&lt;br /&gt;
== Compilers ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Recess ===&lt;br /&gt;
==== Installing Recess under Ubuntu ====&lt;br /&gt;
The following commands should be run to install Recess&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. sudo apt-get install npm node&lt;br /&gt;
   (if the above fails due to the error &amp;quot;The following packages have unmet dependencies&amp;quot;, run the commands separately, ie. sudo apt-get install npm and then sudo apt-get install node)&lt;br /&gt;
2. npm install recess -g&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt; stands for Node Package Manager, and is the equivalent of apt-get for node.js packages.&lt;br /&gt;
&lt;br /&gt;
==== Installing Recess on Mac OS X ====&lt;br /&gt;
1. Install the basic node packages from the web site: [http://nodejs.org http://nodejs.org]   (or use your favourite package manager to install &amp;lt;code&amp;gt;node&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
2. On the command line, install recess like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    npm install recess -g&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Installing Recess under Windows7 ====&lt;br /&gt;
&lt;br /&gt;
In order to install Recess you need to have Node.js installed first, which is relatively simple to do.&lt;br /&gt;
&lt;br /&gt;
====Install Node.js====  &lt;br /&gt;
&lt;br /&gt;
These instructions are for Windows 7 64 bit.&lt;br /&gt;
&lt;br /&gt;
Go to nodejs.org click install. &lt;br /&gt;
&lt;br /&gt;
When installed go to -&amp;gt; Start -&amp;gt; All Programs -&amp;gt; type Node.js into the Search box, then select Node.js Command prompt (black icon) from the list. Now you are ready to install Recess. So at the command lin promt tyle the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. npm install recess -g&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt; stands for Node Package Manager, and is the equivalent of apt-get for node.js packages.&lt;br /&gt;
&lt;br /&gt;
==== Using Recess ====&lt;br /&gt;
&lt;br /&gt;
After editing the LESS files, compile your CSS as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd theme/boostrap/less/&lt;br /&gt;
recess --compile --compress moodle.less &amp;gt; ../style/generated.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will compile and compress the moodle.less file (and all the LESS and CSS files it imports) into a single file, generated.css, and store it in the style folder of the bootstrap theme.&lt;br /&gt;
&lt;br /&gt;
NOTE: if you are getting empty generated.css files, this is being caused by a parsing error in your LESS code. A bug in &amp;lt;code&amp;gt;recess&amp;lt;/code&amp;gt; currently prevents it giving you helpful error messages in many cases. You will need to examine what you have altered or written to make sure it is complete and the syntax is correct. The &amp;lt;code&amp;gt;lessc&amp;lt;/code&amp;gt; compiler is what is used by &amp;lt;code&amp;gt;recess&amp;lt;/code&amp;gt; to do the actual compiling and will have been installed automatically along with it. If you call it directly as &amp;lt;code&amp;gt;lessc moodle.less&amp;lt;/code&amp;gt; it should give you a helpful error message that points you to where the problem is.&lt;/div&gt;</summary>
		<author><name>Tqr</name></author>
	</entry>
</feed>