<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.moodle.org/19/en/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Howardsmiller</id>
	<title>MoodleDocs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.moodle.org/19/en/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Howardsmiller"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/Special:Contributions/Howardsmiller"/>
	<updated>2026-05-12T16:25:52Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Development:Themes_2.0_creating_your_first_theme&amp;diff=83902</id>
		<title>Development:Themes 2.0 creating your first theme</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Development:Themes_2.0_creating_your_first_theme&amp;diff=83902"/>
		<updated>2011-05-27T09:04:59Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* Configuring the language file */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}{{Moodle 2.0}}This document describes how to create a theme for Moodle 2.0. 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;
    &#039;base&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;standard&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.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;course&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.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;coursecategory&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.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;incourse&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.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;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.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;admin&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.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;
    &#039;mydashboard&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.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;mypublic&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.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;standard.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;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.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;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.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;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.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),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;print&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.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;false),&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.&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 [[Development:Themes 2.0|Themes 2.0]] for the full list.&lt;br /&gt;
&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;
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 shown on the page.&lt;br /&gt;
&lt;br /&gt;
In both cases we can choose to wrap them in a div to make our life as a themer easier.&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;
&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 [[Development:Themes 2.0|Themes 2.0]] 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 {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;}&lt;br /&gt;
#page-header .headermenu  {color: #FFF;}&lt;br /&gt;
#page-header .headermenu a {color: #FDFF2A;}&lt;br /&gt;
&lt;br /&gt;
.navbar {padding-left: 1em;}&lt;br /&gt;
.breadcrumb li {color: #FFF;}&lt;br /&gt;
.breadcrumb li a {color: #FFF;}&lt;br /&gt;
&lt;br /&gt;
.block {background-color: #013D6A;}&lt;br /&gt;
.block .header .title {color: #FFF;}&lt;br /&gt;
.block .header .title .block_action input {background-color: #FFF;}&lt;br /&gt;
.block .content {border: 1px solid #000;padding: 5px;background-color: #FFF;}&lt;br /&gt;
.block .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;
&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 {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]]);background-repeat:repeat-x;background-color: #0273C8;}&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;
==See also==&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 overriding a renderer]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Themes]]&lt;br /&gt;
[[es:Desarollo:Temas 2.0 creando tu primer tema]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Development:Themes_2.0_creating_your_first_theme&amp;diff=83901</id>
		<title>Development:Themes 2.0 creating your first theme</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Development:Themes_2.0_creating_your_first_theme&amp;diff=83901"/>
		<updated>2011-05-27T09:03:16Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* Getting started */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}{{Moodle 2.0}}This document describes how to create a theme for Moodle 2.0. 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;
    &#039;base&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;standard&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.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;course&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.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;coursecategory&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.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;incourse&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.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;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.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;admin&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.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;
    &#039;mydashboard&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.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;mypublic&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.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;standard.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;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.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;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.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;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.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),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;print&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;standard.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;false),&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.&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 [[Development:Themes 2.0|Themes 2.0]] for the full list.&lt;br /&gt;
&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;
==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;
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 shown on the page.&lt;br /&gt;
&lt;br /&gt;
In both cases we can choose to wrap them in a div to make our life as a themer easier.&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;
&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 [[Development:Themes 2.0|Themes 2.0]] 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 {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;}&lt;br /&gt;
#page-header .headermenu  {color: #FFF;}&lt;br /&gt;
#page-header .headermenu a {color: #FDFF2A;}&lt;br /&gt;
&lt;br /&gt;
.navbar {padding-left: 1em;}&lt;br /&gt;
.breadcrumb li {color: #FFF;}&lt;br /&gt;
.breadcrumb li a {color: #FFF;}&lt;br /&gt;
&lt;br /&gt;
.block {background-color: #013D6A;}&lt;br /&gt;
.block .header .title {color: #FFF;}&lt;br /&gt;
.block .header .title .block_action input {background-color: #FFF;}&lt;br /&gt;
.block .content {border: 1px solid #000;padding: 5px;background-color: #FFF;}&lt;br /&gt;
.block .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;
&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 {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]]);background-repeat:repeat-x;background-color: #0273C8;}&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;
==See also==&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 overriding a renderer]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Themes]]&lt;br /&gt;
[[es:Desarollo:Temas 2.0 creando tu primer tema]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Development:Themes_2.0&amp;diff=83900</id>
		<title>Development:Themes 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Development:Themes_2.0&amp;diff=83900"/>
		<updated>2011-05-27T09:01:52Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* Layout files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}{{Moodle 2.0}}Welcome to the new world of themes within Moodle 2.0!&lt;br /&gt;
&lt;br /&gt;
This document explains how themes work in Moodle and is intended to help you create or modify most themes for Moodle 2.0.&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Moodle themes are responsible for much of the &amp;quot;look&amp;quot; of a Moodle site.  They provide the CSS for colours, layouts, fonts and so on, and can also change the structural XHTML code below that.  &lt;br /&gt;
&lt;br /&gt;
A theme can either contain all the definitions (completely stand alone) or it can extend an existing theme with one or more customizations. &lt;br /&gt;
&lt;br /&gt;
Most theme developers use the second method and simply add a few new CSS or layout definitions to their new theme. If a definition or element is not found in the new theme, it looks to the &amp;quot;parent&amp;quot; (or up the hierarchy of themes) to find one.  It an easy way to achieve just about any look you want for a theme.&lt;br /&gt;
&lt;br /&gt;
==What&#039;s new in 2.0==&lt;br /&gt;
&lt;br /&gt;
The theme system was completely redesigned in Moodle 2.0.  Known issues have been addressed and new features have been added to meet community requests.&lt;br /&gt;
&lt;br /&gt;
Unfortunately it was not possible to maintain backward compatibility, so all Moodle 1.x themes need to be recreated for Moodle 2.0.&lt;br /&gt;
&lt;br /&gt;
Major changes include:&lt;br /&gt;
* Clearer and more consistent CSS classes and IDs throughout all pages in Moodle&lt;br /&gt;
* Introduction of layout files (templates) describing overall layout HTML for many different types of pages in Moodle.&lt;br /&gt;
* Introduction of renderers, which produce the smaller &amp;quot;parts&amp;quot; of a HTML page.  Advanced themes can choose to override these too if they choose.&lt;br /&gt;
* Introduction of standard methods for adding Javascript to themes.&lt;br /&gt;
* Easier control over icons and images in Moodle.&lt;br /&gt;
* The old &amp;quot;standard&amp;quot; theme has been split into two themes:&lt;br /&gt;
**&#039;&#039;&#039;base&#039;&#039;&#039; - contains absolutely basic layout, and&lt;br /&gt;
**&#039;&#039;&#039;standard&#039;&#039;&#039; - which adds CSS to the base theme to make it look like the old standard theme.&lt;br /&gt;
* Performance tuning: In normal production mode CSS files are combined into a single optimised file, and both CSS and JavaScript files are minimised to ensure there are no wasted connections or traffic.  Files are heavily cached, but also versioned, so that users never need to clear their caches.&lt;br /&gt;
&lt;br /&gt;
==The structure of a theme==&lt;br /&gt;
&lt;br /&gt;
Some important things to know when building good themes:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;config.php&#039;&#039;&#039; - this file is required in every theme.  It defines configuration settings and definitions required to make the theme work in Moodle. These include theme, file, region, default region and options. &lt;br /&gt;
# &#039;&#039;&#039;Layouts and layout files&#039;&#039;&#039; -  in config.php there is one definition for each page type (see [[#theme_layouts_table|Appendix A: Theme layouts]] for a list of over 12 types).  Each page type definition tells Moodle which layout file will be used, what block regions this page type should display and so on.  The layout file contains the HTML and the minimum PHP required to display basic structure of pages. (If you know Moodle 1.9, it&#039;s like a combination of header.html and footer.html).&lt;br /&gt;
# &#039;&#039;&#039;The base theme&#039;&#039;&#039; - is not intended to be used for production sites.  It sets up the simplest possible generic layout and includes only CSS essential to that layout &#039;&#039;or&#039;&#039; to Moodle as a whole.  It tries not to make any unnecessary rules and makes as few assumptions as possible.  It&#039;s the perfect base on which to start designing a theme, as there are very few colours, borders, margins, and alignments to override.  You can just start adding what you need.&lt;br /&gt;
&lt;br /&gt;
===Files and folders===&lt;br /&gt;
A theme&#039;s files are placed in a folder with under moodle/theme folder and have subfolders. They are laid out like this:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Directory&lt;br /&gt;
! File&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| /config.php&lt;br /&gt;
| Contains all of the configuration and definitions for each theme&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| /lib.php &lt;br /&gt;
| Contains speciality classes and functions that are used by theme&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| /renderers.php &lt;br /&gt;
| Contains any custom renderers for the theme.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| /settings.php &lt;br /&gt;
| Contains custom theme settings. These local settings are defined by the theme allowing the theme user to easily alter something about the way it looks or operates. (eg a background colour, or a header image)&lt;br /&gt;
|-&lt;br /&gt;
| /javascript/ &lt;br /&gt;
| &lt;br /&gt;
| All specialty JavaScript files the theme requires should be located in here.&lt;br /&gt;
|-&lt;br /&gt;
| /lang/ &lt;br /&gt;
| &lt;br /&gt;
| Any special language files the theme requires should be located in here.&lt;br /&gt;
|-&lt;br /&gt;
| /layout/ &lt;br /&gt;
| &lt;br /&gt;
| Contains the layout files for the theme.&lt;br /&gt;
|-&lt;br /&gt;
| /pix/ &lt;br /&gt;
| &lt;br /&gt;
| Contains any images the theme makes use of either in CSS or in the layout files.&lt;br /&gt;
|-&lt;br /&gt;
|  /pix&lt;br /&gt;
| /favicon.ico &lt;br /&gt;
| The favicon to display for this theme.&lt;br /&gt;
|-&lt;br /&gt;
| /pix&lt;br /&gt;
| /screenshot.jpg &lt;br /&gt;
| A screenshot of the theme to be displayed in on the theme selection screen.&lt;br /&gt;
|-&lt;br /&gt;
| /style &lt;br /&gt;
| &lt;br /&gt;
| Default location for CSS files.&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|/*.css&lt;br /&gt;
|CSS files the theme requires&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
There are also several other places that stylesheets can be included from (see the CSS how and why section below).&lt;br /&gt;
&lt;br /&gt;
==Theme options==&lt;br /&gt;
All theme options are set within the config.php file for the theme.  The settings that are most used are: parents, sheets, layouts, and javascripts. Have a look at the &#039;&#039;&#039;[[#theme_options_table|theme options table]]&#039;&#039;&#039; for a complete list of theme options which include lesser used specialised or advanced settings.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Basic theme config example===&lt;br /&gt;
Lets have a look at a basic theme configuration file and the different bits that make it up:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;name = &#039;newtheme&#039;;&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;parents = array(&lt;br /&gt;
    &#039;base&#039;&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&lt;br /&gt;
    &#039;admin&#039;,&lt;br /&gt;
    &#039;blocks&#039;,&lt;br /&gt;
    &#039;calendar&#039;,&lt;br /&gt;
    &#039;course&#039;,&lt;br /&gt;
    &#039;grade&#039;,&lt;br /&gt;
    &#039;message&#039;,&lt;br /&gt;
    &#039;question&#039;,&lt;br /&gt;
    &#039;user&#039;&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;theme&#039; =&amp;gt; &#039;newtheme&#039;,&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;standard&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;theme&#039; =&amp;gt; &#039;newtheme&#039;,&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    )&lt;br /&gt;
    //.......&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;javascripts_footer = array(&lt;br /&gt;
    &#039;navigation&#039;&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Basic theme example settings explained===&lt;br /&gt;
First up you will notice everything is added to $THEME. This is the theme&#039;s configuration object, it is created by Moodle using default settings and is then updated by whatever settings you add to it.&lt;br /&gt;
&lt;br /&gt;
The first setting, $THEME-&amp;gt;name is the theme&#039;s name. This should simply be whatever your theme&#039;s name is, most likely whatever you named your theme directory.&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;parents defines the themes that the theme will extend. In this case it is extending only the base theme.&lt;br /&gt;
&lt;br /&gt;
After this is the $THEME-&amp;gt;sheets array containing the names of the CSS stylesheets to include for this theme. Note that it is just the name of the stylesheet and does not contain the directory or the file extension. Moodle assumes that the theme&#039;s stylesheets will be located in the styles directory of the theme and have .css as an extension.&lt;br /&gt;
&lt;br /&gt;
Next we see the $THEME-&amp;gt;layouts definition. In this example, two layouts have been defined to override the layouts from the base theme. For more information see the [[#Layouts|layouts]] section below.&lt;br /&gt;
&lt;br /&gt;
The final setting is to include a JavaScript file, as $THEME-&amp;gt;javascripts_footer. Much like stylesheets, you only need to provide the files name. Moodle will assume it is in your themes JavaScript directory and be a .js file.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note&#039;&#039;&#039;&#039;&#039;: When you first begin writing themes, make sure you take a look at the configuration files of the other themes that get shipped with Moodle. You will get a good picture of how everything works, and what is going on in a theme, simply by reading it and taking notice of what it is including or excluding.&lt;br /&gt;
&lt;br /&gt;
==CSS==&lt;br /&gt;
===Locations of CSS files===&lt;br /&gt;
First lets look at where CSS can be included from within Moodle:&lt;br /&gt;
; \theme\themename\styles\*.css : This is the default location for all of the stylesheets that are used by a theme and the place which should be used by a theme designer.&lt;br /&gt;
&lt;br /&gt;
New theme developers should note that the order in which CSS files are found and included creates a hierarchy.  This order ensures that the rules, within a theme&#039;s style sheets, take precedence over identical rules in other files that may have been introduced before.  This can both extend another files definitions (see parent array in the config file) and also ensures that the current theme&#039;s CSS rules/definitions have the last say.&lt;br /&gt;
&lt;br /&gt;
There are other locations that can be used (although very rarely) to include CSS in a page. A developer of a php file can manually specify a stylesheet from anywhere within Moodle, like the database. Usually, if code is doing this, it is because there is a non-theme config or plugin setting that contains information requires special CSS information.  As a theme designer you should be aware of, but not have to worry about, these locations of CSS files.  Here are some examples:&lt;br /&gt;
&lt;br /&gt;
; {pluginpath}\styles.css e.g. \block\blockname\styles.css or \mod\modname\styles.css : Every plugin can have its own styles.css file. This file should only contain the required CSS rules for the module and should not add anything to the look of the plugin such as colours, font sizes, or margins other than those that are truly required.&amp;lt;br /&amp;gt;Theme specific styles for a plugin should be located within the themes styles directory.&lt;br /&gt;
; {pluginpath}\styles_themename.css : This should only ever be used by plugin developers. It allows them to write CSS that is designed for a specific theme without having to make changes to that theme. You will notice that this is never used within Moodle and is designed to be used only by contributed code.&lt;br /&gt;
&lt;br /&gt;
As theme designers, we will only use the first method of introducing CSS: adding rules to a stylesheet file located in the themes styles directory.&lt;br /&gt;
&lt;br /&gt;
===Moodle&#039;s core CSS organisation===&lt;br /&gt;
The next thing to look at is the organisation of CSS and rules within a theme. Although as a theme designer it is entirely up to you as to how you create and organise your CSS. Please note that within the themes provided in the standard install by Moodle there is a very clear organisation of CSS.&lt;br /&gt;
&lt;br /&gt;
First is the  pagelayout.css file. This contains the CSS required to give the layouts their look and feel.  It doesn&#039;t contain any rules that affect the content generated by Moodle.&lt;br /&gt;
&lt;br /&gt;
Next is the core.css file. If you open up core you will notice that it contains all manner of general (usually simple) rules that don&#039;t relate to a specific section of Moodle but to Moodle as a whole.&lt;br /&gt;
&lt;br /&gt;
There can also be rules that relate to specific sections.  However, this is done only when there are only a handful of rules for that section. These small clusters of rules are grouped together and separated by comments identifying for which section each relates.&lt;br /&gt;
&lt;br /&gt;
Finally there are all the other CSS files, you will notice that there is a file for each section of Moodle that has a significant collection of rules.&lt;br /&gt;
&lt;br /&gt;
:For those who are familiar with Moodle 1.9 theme&#039;s, this organisation will be a big change. In 1.9, CSS was organised by its nature (for example: colours, layout, other).&lt;br /&gt;
&lt;br /&gt;
===How to write effective CSS rules within Moodle===&lt;br /&gt;
In Moodle 2.0, writing good CSS rules is an incredibly important.&lt;br /&gt;
&lt;br /&gt;
Due to performance requirements and browser limitations, all of the CSS files are combined into a single CSS file that gets included every time. This means that rules need to be written in such a way as to minimise the chances of a collision leading to unwanted styles being applied. Whilst writing good CSS is something most designers strive for we have implemented several new body classes and put more emphasis on developers for using classes more appropriately.&lt;br /&gt;
&lt;br /&gt;
====The body tag====&lt;br /&gt;
As of Moodle 2.0 the ID tag that gets applied to the body will always be a representation of the URI. For example if you are looking at a forum posting and the URI is &#039;/mod/forum/view.php&#039; then the body tags ID will be &#039;#page-mod-forum-view&#039;.&lt;br /&gt;
&lt;br /&gt;
As well as the body&#039;s ID attribute the URI is also exploded to form several CSS classes that get added to the body tag, so in the above example &#039;/mod/forum/view&#039; you would end up with the following classes being added to the body tag &#039;.path-mod&#039;, &#039;.path-mod-forum&#039;. Note that &#039;.path-mod-forum-view&#039; is not added as a class, this is intentionally left out to lessen confusion and duplication as rules can relate directly to the page by using the ID and do not require the final class.&lt;br /&gt;
&lt;br /&gt;
The body ID and body classes described above will form the bread and butter for many of the CSS rules you will need to write for your theme, however there are also several other very handy classes that get added to the body tag that will be beneficial to you once you start your journey down the rabbit hole that is themeing. Some of the more interesting classes are listed below.&lt;br /&gt;
&lt;br /&gt;
* If JavaScript is enabled then &#039;jsenabled&#039; will be added as a class to the body tag allowing you to style based on JavaScript being enabled or not.&lt;br /&gt;
* Either &#039;dir-rtl&#039; or &#039;dir-ltr&#039; will be added to the body as a class depending on the direction of the language pack: rtl = right to left, ltr = left to right. This allows you to determine your text-alignment based on language if required.&lt;br /&gt;
* A class will be added to represent the language pack currently in use, by default en_utf8 is used by Moodle and will result in the class &#039;lang-en_utf8&#039; being added to the body tag.&lt;br /&gt;
* The wwwroot for Moodle will also be converted to a class and added to the body tag allowing you to stylise your theme based on the URL through which it was reached. e.g. http://sam.moodle.local/moodle/ will become &#039;.sam-moodle-local—moodle&#039;&lt;br /&gt;
* If the current user is not logged then &#039;.notloggedin&#039; will be added to the body tag.&lt;br /&gt;
&lt;br /&gt;
What does all of this look like in practise? Well using the above example /mod/forum/view.php you would get at least the following body tag:&lt;br /&gt;
&amp;lt;code html4strict&amp;gt;&amp;lt;body id=”page-mod-forum-view” class=”path-mod path-mod-forum” /&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Writing your rules====&lt;br /&gt;
The best use of body ids and classes and writing selectors will reduce problems.&lt;br /&gt;
&lt;br /&gt;
There are many specific classes used within Moodle. We try to put them everywhere where anyone may want to apply their own styles. It is important to recognise that no one developer can be aware of the all of the class names that have been used all throughout Moodle, let alone within all of the different contributed bits and pieces available for Moodle.  It is up to the theme developer to write good rules and minimise the chances of a collision between rules because in this case good CSS is FAR more effective.&lt;br /&gt;
&lt;br /&gt;
When starting to write rules make sure that you have a good understanding of where you want those rules to be applied, it is a good idea to make the most of the body classes mentioned above.&lt;br /&gt;
If you want to write a rule for a specific page make use of the body tag&#039;s ID, e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;#page-mod-forum-view .forumpost {border:1px solid orange;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to write a rule that will be applied all throughout the forum.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.path-mod-forum .forumpost {border:1px solid orange;}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The other very important thing to take into consideration is the structure leading up to the tag you want to style. Browsers apply conflicting styles with priority on the more specific selectors. It can be very beneficial to keep this in mind and write full selectors that rely on the structure of the tags leading to the tag you wish to style.&lt;br /&gt;
&lt;br /&gt;
By making use of body id&#039;s and classes and writing selectors to take into account the leading structure you can greatly minimise the chance of a collision both with Moodle now and in the future.&lt;br /&gt;
&lt;br /&gt;
==Layouts==&lt;br /&gt;
All themes are required to define the layouts they wish to be responsible for as well as create; however, many layout files are required by those layouts. If the theme is overriding another theme then it is a case of deciding which layouts this new theme should override. If the theme is a completely fresh start then you will need to define a layout for each of the different possibilities. For both situations these layouts should be defined within config.php.&lt;br /&gt;
&lt;br /&gt;
It is also important to note that a new theme that will base itself on another theme (overriding it) does not need to define any layouts or use any layout files if there are no changes that it wishes to make to the layouts of the existing theme. The standard theme in Moodle is a good example of this as it extends the base theme simply adding CSS to achieve its look and feel.&lt;br /&gt;
&lt;br /&gt;
So layouts... as mentioned earlier layouts are defined in config.php within $THEME-&amp;gt;layouts. The following is an example of one such layout definition:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Standard layout with blocks, this is recommended for most pages with general information&lt;br /&gt;
    &#039;standard&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;theme&#039; =&amp;gt; &#039;base&#039;,&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The first thing Moodle looks at is the name of the layout, in this case it is `standard` (the array key in PHP), it then looks at the settings for the layout, this is the theme, file, regions, and default region. There are also a couple of other options that can be set by a layout.&lt;br /&gt;
&lt;br /&gt;
; theme : is the theme the layout file exists in. That&#039;s right you can make use of layouts from other installed themes. &#039;&#039;Optional&#039;&#039;&lt;br /&gt;
; file : is the name of the layout file this layout wants to use. &#039;&#039;Required&#039;&#039;&lt;br /&gt;
; regions : is the different block regions (places you can put blocks) within the theme. &#039;&#039;Required&#039;&#039;&lt;br /&gt;
; defaultregion : is the default location when adding new blocks. &#039;&#039;&#039;Required if regions is non-empty, otherwise optional&#039;&#039;&#039;&lt;br /&gt;
; options : an array of layout specific options described in detail below. &#039;&#039;&#039;Optional&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;theme&#039;&#039;&#039; is optional. Normally the the layout file is looked for in the current theme, or, if it is not there, in the parent theme. However, you can use a layout file from any other theme by giving the theme name here.&lt;br /&gt;
&lt;br /&gt;
You can define whatever regions you like. You just need to pick an name for each one. Most themes just use one or both of &#039;&#039;&#039;side_pre&#039;&#039;&#039; and &#039;&#039;&#039;side_post&#039;&#039;&#039;, which is like &#039;left side&#039; and &#039;right side&#039;, except in right to left languages, when they are reversed. If you say in config.php that your the layout provides regions called &#039;fred&#039; and &#039;barney&#039;, then you must call $OUTPUT-&amp;gt;blocks_for_region(&#039;fred&#039;) and $OUTPUT-&amp;gt;blocks_for_region(&#039;barney&#039;) somewhere in the layout file.&lt;br /&gt;
&lt;br /&gt;
The final setting &#039;&#039;&#039;options&#039;&#039;&#039; is a special case that only needs to be set if you want to make use of it. This setting allows the theme designer to specify special options that they would like to create that can be later accessed within the layout file. This allows the theme to make design decisions during the definition and react upon those decisions in what ever layout file is being used.&lt;br /&gt;
&lt;br /&gt;
One such place this has been used is infact within the base theme. If you take a look first at theme/base/config.php you will notice that several layouts specify options &#039;&#039;&#039;nonavbar&#039;&#039;&#039; and &#039;&#039;&#039;nofooter&#039;&#039;&#039; which can both be set to either true or false. Then if we take a look at theme/base/layout/general.php you will spot lines like the following:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$hasnavbar = (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar());&lt;br /&gt;
$hasfooter = (empty($PAGE-&amp;gt;layout_options[&#039;nofooter&#039;]));&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
............&lt;br /&gt;
&amp;lt;?php if ($hasnavbar) { ?&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;navbar clearfix&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;breadcrumb&amp;quot;&amp;gt;&amp;lt;?php echo $OUTPUT-&amp;gt;navbar(); ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;navbutton&amp;quot;&amp;gt; &amp;lt;?php echo $PAGE-&amp;gt;button; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
What you are seeing here is the use of those settings from the layout within the layout file. In this case it is being used to toggle the display of the navigation bar and page footer.&lt;br /&gt;
&lt;br /&gt;
==Layout files==&lt;br /&gt;
A layout file is a file that contains the core HTML structure for a layout including the header, footer, content and block regions.&lt;br /&gt;
For those of you who are familiar with themes in Moodle 1.9 this is simply header.html and footer.html combined.&lt;br /&gt;
Of course it is not all HTML, there are bits of HTML and content that Moodle needs to put into the page, within each layout file this will be done by a couple of VERY simple PHP calls to get bits and pieces including content.&lt;br /&gt;
&lt;br /&gt;
The following is a very simple layout file to illustrate the different bits that make it up:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;doctype() ?&amp;gt;&lt;br /&gt;
&amp;lt;html &amp;lt;?php echo $OUTPUT-&amp;gt;htmlattributes() ?&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;title ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;?php echo $OUTPUT-&amp;gt;standard_head_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php 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;table id=&amp;quot;page&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
        &amp;lt;td colspan=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;h1 class=&amp;quot;headermain&amp;quot;&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;heading ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;headermenu&amp;quot;&amp;gt;&amp;lt;?php echo $OUTPUT-&amp;gt;login_info(); echo $PAGE-&amp;gt;headingmenu; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-pre&#039;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-post&#039;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
        &amp;lt;td colspan=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;p class=&amp;quot;helplink&amp;quot;&amp;gt;&amp;lt;?php echo page_doc_link(get_string(&#039;moodledocslink&#039;)) ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
            &amp;lt;?php&lt;br /&gt;
            echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
            echo $OUTPUT-&amp;gt;home_link();&lt;br /&gt;
            echo $OUTPUT-&amp;gt;standard_footer_html();&lt;br /&gt;
            ?&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_end_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lets assume you know a enough HTML to understand the basic structure above, what you probably don&#039;t understand are the PHP calls so lets look at them.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;doctype() ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This occurs at the VERY top of the page, it must be the first bit of output and is responsible for adding the (X)HTML document type definition to the page. This of course is determined by the settings of the site and is one of the things that the theme designer has no control over.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;html &amp;lt;?php echo $OUTPUT-&amp;gt;htmlattributes() ?&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we have started writing the opening html tag and have asked Moodle to give us the HTML attributes that should be applied to it. This again is determined by several settings within the actual HTML install.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $PAGE-&amp;gt;title ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This gets us the title for the page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_head_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This very important call gets us the standard head HTML that needs to be within the HEAD tag of the page. This is where CSS and JavaScript requirements for the top of the page will be output as well as any special script or style tags.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php 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;
Much like the html tag above we have started writing the body tag and have asked for Moodle to get us the desired ID and classes that should be applied to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;h1 class=&amp;quot;headermain&amp;quot;&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;heading; ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;headermenu&amp;quot;&amp;gt;&amp;lt;?php echo $OUTPUT-&amp;gt;login_info(); echo $PAGE-&amp;gt;headingmenu; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are creating the header for the page. In this case we want the heading for the page, we want to display the login information which will be the current users username or a link to log in if they are not logged in, and we want the heading menu if there is one.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-pre&#039;) ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we get the HTML to display the blocks that have been added to the page. In this case we have asked for all blocks that have been added to the area labelled &#039;&#039;side-pre&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is one of the most important calls within the file, it determines where the actual content for the page gets inserted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-post&#039;) ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we get the HTML to display the blocks that have been added to the page. In this case we have asked for all blocks that have been added to the area labelled &#039;&#039;side-post&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
echo $OUTPUT-&amp;gt;home_link();&lt;br /&gt;
echo $OUTPUT-&amp;gt;standard_footer_html();&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This final bit of code gets the content for the footer of the page. It gets the login information which is the same as in the header, a home link, and the standard footer HTML which like the standard head HTML contains all of the script and style tags required by the page and requested to go in the footer.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note&#039;&#039;&#039;&#039;&#039;: Within Moodle 2.0 most of the JavaScript for the page will be included in the footer. This greatly helps reduce the loading time of the page.&lt;br /&gt;
&lt;br /&gt;
When writing layout files think about the different layouts and how the HTML that each makes use of will differ. You will most likely find you do not need a different layout file for each layout, most likely you will be able to reuse the layout files you create across several layouts. You can of course make use of layout options as well to further reduce the number of layout files you need to produce.&lt;br /&gt;
&lt;br /&gt;
Of course as mentioned above if you are customising an existing theme then you may not need to create any layouts or layout files at all.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;$OUTPUT&#039;&#039;&#039; is an instance of the &#039;&#039;&#039;core_renderer&#039;&#039;&#039; 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 &#039;&#039;&#039;moodle_page&#039;&#039;&#039; 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, some magic is going on, and the value you get is produced by calling a function. Also, you cannot change these values, they are read-only. However, you don&#039;t need to understand all that if you are just using these properties in your theme.)&lt;br /&gt;
&lt;br /&gt;
==Language File==&lt;br /&gt;
&lt;br /&gt;
You need to create a language file for your theme with a few standard strings in it. At a minimum create a file called lang/en.theme_themename.php in your theme folder. For example, the &#039;standard&#039; theme has a language file called lang/en/theme_standard.php. &lt;br /&gt;
&lt;br /&gt;
You &#039;&#039;&#039;must&#039;&#039;&#039; define the following lines in your file (example is from standard theme, adapt as required):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;Standard&#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;
$string[&#039;choosereadme&#039;] = &#039;This theme is a very basic white theme, with a minimum amount of &lt;br /&gt;
 CSS added to the base theme to make it actually usable.&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Without the above you will get notices for the missing strings.&lt;br /&gt;
&lt;br /&gt;
==Making use of images==&lt;br /&gt;
Right at the start when listing the features of the new themes system one of the features mentioned was the ability to override any of the standard images within Moodle from within your theme. At this point we will look at both how to make use of your own images within your theme, and secondly how to override the images being used by Moodle.&lt;br /&gt;
So first up a bit about images within Moodle,&lt;br /&gt;
&lt;br /&gt;
# Images you want to use within your theme &#039;&#039;&#039;need&#039;&#039;&#039; to be located within your theme&#039;s pix directory.&lt;br /&gt;
# You can use sub directories within the pix directory of your theme.&lt;br /&gt;
# Images used by Moodle&#039;s core are located within the pix directory of Moodle.&lt;br /&gt;
# Modules, blocks and other plugins should also store there images within a pix directory.&lt;br /&gt;
&lt;br /&gt;
So making use of your own images first up. Lets assume you have added two image files to the pix directory of your theme.&lt;br /&gt;
&lt;br /&gt;
* /theme/yourthemename/pix/imageone.jpg&lt;br /&gt;
* /theme/yourthemename/pix/subdir/imagetwo.png&lt;br /&gt;
&lt;br /&gt;
Notice that one image is a JPEG image, and the second is a PNG. Also the second image is in a subdirectory.&lt;br /&gt;
&lt;br /&gt;
The following code snippet illustrates how to make use of your images within HTML, such as if you wanted to use them within a layout file.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;&amp;lt;?php echo $OUTPUT-&amp;gt;pix_url(&#039;imageone&#039;, &#039;theme&#039;);?&amp;gt;&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt; &lt;br /&gt;
&amp;lt;img src=&amp;quot;&amp;lt;?php echo $OUTPUT-&amp;gt;pix_url(&#039;subdir/imagetwo&#039;, &#039;theme&#039;);?&amp;gt;&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt; &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;DO NOT&#039;&#039;&#039; include the image file extension. Moodle will work it out automatically and it will not work if you do include it.&lt;br /&gt;
&lt;br /&gt;
In this case rather than writing out the URL to the image we use a method of Moodle&#039;s output library. Its not too important how that functions works but it is important that we use it as it is what allows images within Moodle to be over-rideable.&lt;br /&gt;
&lt;br /&gt;
The following is how you would use the images from within CSS as background images.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
.divone {background-image:url([[pix:theme|imageone]]);}&lt;br /&gt;
.divtwo {background-image:url([[pix:theme|subdir/imagetwo]]);}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
If this case we have to use some special notations that Moodle looks for. Whenever Moodle hands out a CSS file it first searches for all &#039;&#039;[[something]]&#039;&#039; tags and replaces them with what is required.&lt;br /&gt;
&lt;br /&gt;
The final thing to notice with both of the cases above is that at no point do we include the images file extension. &lt;br /&gt;
The reason for this leads us into the next topic, how to override images.&lt;br /&gt;
&lt;br /&gt;
From within a theme you can VERY easily override any standard image within Moodle by simply adding the replacement image to the theme&#039;s pix directory in the same sub directory structure as it is in Moodle.&lt;br /&gt;
So for instance we wanted to override the following two images:&lt;br /&gt;
# /pix/moodlelogo.gif&lt;br /&gt;
# /pix/i/user.gif&lt;br /&gt;
We would simply need to add our replacement images to the theme in the following locations&lt;br /&gt;
# /theme/themename/pix/moodlelogo.gif&lt;br /&gt;
# /theme/themename/pix/i/user.gif&lt;br /&gt;
How easy is that!&lt;br /&gt;
&lt;br /&gt;
Now the other very cool thing to mention is that Moodle looks for not just replacements of the same image type (jpg, gif, etc...) but also replacements in any image format. This is why above when working with our images we never specified the images file extension.&lt;br /&gt;
This means that the following would also work:&lt;br /&gt;
# /theme/themename/pix/moodlelogo.png&lt;br /&gt;
# /theme/themename/pix/i/user.bmp&lt;br /&gt;
&lt;br /&gt;
For a more detailed description of how this all works see the page on [[Development:Themes_2.0_How_to_use_images_within_your_theme|using images within your theme]]&lt;br /&gt;
&lt;br /&gt;
==Unobvious Things==&lt;br /&gt;
===Getting Your Theme to Appear Correctly in Theme Selector===&lt;br /&gt;
If you follow the examples on this page to the letter, when you go to the Theme Selector page you may be discouraged to find that your theme does not appear like the other themes do. In fact, instead of your theme&#039;s name, you will see something along the lines of &amp;lt;nowiki&amp;gt;[[pluginname]]&amp;lt;/nowiki&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
To correct this, you must add the /lang/en/theme_THEMENAME.php file, where THEMENAME is the name of the theme folder. Inside that file, add the string &amp;quot;$string[&#039;pluginname&#039;] = &#039;THEMENAME&#039;; &amp;quot;. Make THEMENAME the name of your theme, however you want it displayed in the Theme selector.&lt;br /&gt;
&lt;br /&gt;
The screenshot for the theme should be about 500x400 px.&lt;br /&gt;
&lt;br /&gt;
===Required theme divs===&lt;br /&gt;
&lt;br /&gt;
Some parts of Moodle may rely on particular divs, for example the div with id &#039;page-header&#039;.&lt;br /&gt;
&lt;br /&gt;
Consequently all themes must include at least the divs (with the same ids) that are present in the &#039;base&#039; theme. &lt;br /&gt;
&lt;br /&gt;
Missing out these elements may result in unexpected behaviour within specific modules or other plugins.&lt;br /&gt;
&lt;br /&gt;
==Appendix A==&lt;br /&gt;
===Theme options as of April 28th, 2010===&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot; id=&amp;quot;theme_options_table&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting&lt;br /&gt;
! Effect&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;csspostprocess&#039;&#039;&#039;&lt;br /&gt;
|  Allows the user to provide the name of a function that all CSS should be passed to before being delivered.&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;editor_sheets&#039;&#039;&#039;&lt;br /&gt;
|  An array of stylesheets to include within the body of the editor.&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;enable_dock&#039;&#039;&#039;&lt;br /&gt;
|  If set to true the side dock is enabled for blocks&lt;br /&gt;
|-&lt;br /&gt;
| $THEME-&amp;gt;&#039;&#039;&#039;hidefromselector&#039;&#039;&#039;&lt;br /&gt;
| Used to hide a theme from the theme selector (unless theme designer mode is on). Accepts true or false.&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;filter_mediaplugin_colors&#039;&#039;&#039;&lt;br /&gt;
|  Used to control the colours used in the small media player for the filters&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;javascripts&#039;&#039;&#039;&lt;br /&gt;
|  An array containing the names of JavaScript files located in /javascript/ to include in the theme. (gets included in the head)&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;javascripts_footer&#039;&#039;&#039;&lt;br /&gt;
|  As above but will be included in the page footer.&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;larrow&#039;&#039;&#039;&lt;br /&gt;
|  Overrides the left arrow image used throughout Moodle&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;layouts&#039;&#039;&#039;&lt;br /&gt;
|  An array setting the layouts for the theme&lt;br /&gt;
|-&lt;br /&gt;
| $THEME-&amp;gt;&#039;&#039;&#039;name&#039;&#039;&#039;&lt;br /&gt;
| Name of the theme. Most likely the name of the directory in which this file resides.&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;parents&#039;&#039;&#039;&lt;br /&gt;
|  An array of themes to inherit from&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;parents_exclude_javascripts&#039;&#039;&#039;&lt;br /&gt;
|  An array of JavaScript files NOT to inherit from the themes parents&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;parents_exclude_sheets&#039;&#039;&#039;&lt;br /&gt;
|  An array of stylesheets not to inherit from the themes parents&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;plugins_exclude_sheets&#039;&#039;&#039;&lt;br /&gt;
|  An array of plugin sheets to ignore and not include.&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;rarrow&#039;&#039;&#039;&lt;br /&gt;
|  Overrides the right arrow image used throughout Moodle&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;renderfactory&#039;&#039;&#039;&lt;br /&gt;
|  Sets a custom render factory to use with the theme, used when working with custom renderers.&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;resource_mp3player_colors&#039;&#039;&#039;&lt;br /&gt;
|  Controls the colours for the MP3 player&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;sheets&#039;&#039;&#039;&lt;br /&gt;
|  An array of stylesheets to include for this theme. Should be located in the theme&#039;s style directory.&lt;br /&gt;
|}&lt;br /&gt;
===The different layouts as of August 17th, 2010===&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot; id=&amp;quot;theme_layouts_table&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Layout&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| base&lt;br /&gt;
| Most backwards compatible layout without the blocks - this is the layout used by default.&lt;br /&gt;
|- &lt;br /&gt;
| standard&lt;br /&gt;
| Standard layout with blocks, this is recommended for most pages with general information.&lt;br /&gt;
|- &lt;br /&gt;
| course&lt;br /&gt;
| Main course page.&lt;br /&gt;
|- &lt;br /&gt;
| coursecategory&lt;br /&gt;
| Use for browsing through course categories.&lt;br /&gt;
|- &lt;br /&gt;
| incourse&lt;br /&gt;
| Default layout while browsing a course, typical for modules.&lt;br /&gt;
|- &lt;br /&gt;
| frontpage&lt;br /&gt;
| The site home page.&lt;br /&gt;
|- &lt;br /&gt;
| admin&lt;br /&gt;
| Administration pages and scripts.&lt;br /&gt;
|- &lt;br /&gt;
| mydashboard&lt;br /&gt;
| My dashboard page.&lt;br /&gt;
|- &lt;br /&gt;
| mypublic&lt;br /&gt;
| My public page.&lt;br /&gt;
|- &lt;br /&gt;
| login&lt;br /&gt;
| The login page.&lt;br /&gt;
|-&lt;br /&gt;
| popup&lt;br /&gt;
| Pages that appear in pop-up windows - no navigation, no blocks, no header.&lt;br /&gt;
|-&lt;br /&gt;
| frametop&lt;br /&gt;
| Used for legacy frame layouts only. No blocks and minimal footer.&lt;br /&gt;
|-&lt;br /&gt;
| embedded&lt;br /&gt;
| Embeded pages, like iframe/object embedded in moodleform - it needs as much space as possible&lt;br /&gt;
|-&lt;br /&gt;
| maintenance&lt;br /&gt;
| Used during upgrade and install. This must not have any blocks, and it is good idea if it does not have links to other places - for example there should not be a home link in the footer.&lt;br /&gt;
|-&lt;br /&gt;
| print&lt;br /&gt;
| Used when the page is being displayed specifically for printing.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]] - A quick step by step guide to creating your first theme.&lt;br /&gt;
* [[Development:Themes 2.0 overriding a renderer]] - A tutorial on creating a custom renderer and changing the HTML Moodle produces.&lt;br /&gt;
* [[Development:Themes 2.0 How to use images within your theme]] - Explains how to use and override images within your theme.&lt;br /&gt;
* [[Development:Themes 2.0 adding a settings page]] - Looks at how to add a setting page making your theme easily customisable.&lt;br /&gt;
* [[Development:Themes 2.0 extending the custom menu]] - Customising the custom menu.&lt;br /&gt;
* [[Development:Themes 2.0 adding courses and categories to the custom menu]] - Extending the custom menu further adding all categories + courses&lt;br /&gt;
* [[Development:Themes 2.0 how to make the dock horizontal]] - Modifying the dock to make it horizontal.&lt;br /&gt;
* [[Development:Themes 2.0 adding upgrade code]]&lt;br /&gt;
* [[Development:Styling and customising the dock]] - How to style and customise the dock.&lt;br /&gt;
* [[Development:Theme changes in 2.0]]&lt;br /&gt;
* [[Development:Using jQuery with Moodle 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 how to clone a Moodle 2.0 theme]] &lt;br /&gt;
* [http://www.youtube.com/watch?v=OvaU54uh-qA New themes in Moodle 2.0 video]&lt;br /&gt;
&lt;br /&gt;
[[de:Designs 2.0]]&lt;br /&gt;
[[es:Temas 2.0]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Administrator_documentation&amp;diff=83865</id>
		<title>Administrator documentation</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Administrator_documentation&amp;diff=83865"/>
		<updated>2011-05-26T09:06:17Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: Undo revision 83864 by Howardsmiller (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this page is to list useful links by general topics for administrators of a Moodle site.&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Installation &amp;amp; Upgrading ==&lt;br /&gt;
&lt;br /&gt;
*[[Installation Quickstart]] for an overview of the installation steps&lt;br /&gt;
*[[Installing Moodle]] for detailed installation instructions&lt;br /&gt;
*[[Installation FAQ]]&lt;br /&gt;
*[[Installing AMP|Options for installing Apache, MySQL and PHP]]&lt;br /&gt;
*[[Upgrading|Upgrading Moodle]]&lt;br /&gt;
*[[Installing contributed modules or plugins]]&lt;br /&gt;
&lt;br /&gt;
== System-specific Instructions &amp;amp; Packages ==&lt;br /&gt;
&lt;br /&gt;
===Unix/Linux-based===&lt;br /&gt;
* [[SUSE Linux Server 10|Automated Installation Guide for SUSE Linux Enterprise Server 10]] operating system&lt;br /&gt;
* [[RedHat Linux installation|Step-by-step Installation Guide for RedHat]] operating system&lt;br /&gt;
* [[Debian GNU/Linux installation|Step-by-step Installation Guide for Debian GNU/Linux]] operating system&lt;br /&gt;
* [[Step-by-step Installation Guide for Ubuntu]]&lt;br /&gt;
* [[Manual installation of Moodle 2.0 on Mythbuntu using Git|Manual installation of Moodle 2.0 on Mythbuntu (and Ubuntu 10.10, 11.04) using Git]]&lt;br /&gt;
* [[Manual_installation_on_Ubuntu|Manual Installation on Ubuntu]]&lt;br /&gt;
* [[Step-by-step Install Guide for Zenwalk-5.0|Step-by-step Installation Guide for Zenwalk-5.0]]&lt;br /&gt;
* [[OLPC XS installation|Step-by-step Installation Guide for the One Laptop per Child XS Server (Beta)]]&lt;br /&gt;
* [[Step-by-step Install Guide for Solaris 10 with Oracle 10|Step-by-step Installation Guide for Solaris 10 with Oracle 10]]&lt;br /&gt;
* [[Installation Guide for Installing on Amazon EC2]]&lt;br /&gt;
&lt;br /&gt;
===Windows===&lt;br /&gt;
* [[Windows installation|Windows installations with instructions for Windows NT/2000/2003 servers]]&lt;br /&gt;
* [[Windows installation using XAMPP|Windows installation using XAMPP: Apache, MySQL and PHP]]&lt;br /&gt;
* [[Development:Windows_Installer_anywhere|MoodleAnywhere]] another Windows installation package&lt;br /&gt;
* [[Installing Moodle on Windows Vista]] - how to&lt;br /&gt;
* [http://www.bfcnetworks.com/whitepapers/installing-moodle-on-windows-server-iis-sql/ Installing Moodle on Windows Server 2008 x86]&lt;br /&gt;
* [http://www.bfcnetworks.com/whitepapers/installing-moodle-on-windows-server-2008-r2-x64-sql-iis/ Installing Moodle on Windows Server 2008 R2]&lt;br /&gt;
* [http://www.bfcnetworks.com/whitepapers/implementing-moodle-on-a-windows-high-availability-environment// Implementing Moodle on a Windows High Availability Environment] Implementing Moodle 1.9 on 2 Microsoft Load Balanced Web Front End Server and a Microsoft SQL Server 2008 R2 Cluster environment&lt;br /&gt;
&lt;br /&gt;
Moodle 2&lt;br /&gt;
* [http://www.bfcnetworks.com/whitepapers/installing-moodle-2-on-windows-server-mysql-php-and-iis7/ Installing Moodle 2 on Windows Server, MySQL, PHP and IIS7]&lt;br /&gt;
* [http://www.bfcnetworks.com/whitepapers/installing-moodle-2-on-windows-server-2008-r2-x64-sql-iis/ Installing Moodle 2 on Windows Server, Microsoft SQL Server, PHP and IIS7]&lt;br /&gt;
&lt;br /&gt;
===Mac===&lt;br /&gt;
* [[Step by Step Installation on a Mac OS X Server|Step by step Installation on a Mac OS X Server 10.5/10.6]]&lt;br /&gt;
* [[Complete Install Packages for Mac OS X | Complete Install Packages for Mac OS X Clients 10.4/10.5/10.6]]&lt;br /&gt;
* [[Step-by-step Guide for Installing Moodle on Mac OS X 10.4 Client|Step by Step Installation on a Mac OS X 10.4 Client using the internal web server]]&lt;br /&gt;
&lt;br /&gt;
===Web Hosts===&lt;br /&gt;
* [[1and1_MySQL_installation | Installation on &#039;&#039;&#039;1and1&#039;&#039;&#039; web hosting]]&lt;br /&gt;
* [[powweb_MySQL_installation | Step-by-step Installation on &#039;&#039;&#039;Powweb&#039;&#039;&#039; web hosting]]&lt;br /&gt;
* [[Step-by-step Installation using the old version of CPanel]]&lt;br /&gt;
* [[Step-by-step Installation using the new version of CPanel]]&lt;br /&gt;
&lt;br /&gt;
===Appliances===&lt;br /&gt;
Some users may prefer to skip manual installation by using a pre-integrated [[Moodle appliance]].&lt;br /&gt;
&lt;br /&gt;
===Database===&lt;br /&gt;
* [[Installing Oracle for PHP]]&lt;br /&gt;
* [[Installing MSSQL for PHP]]&lt;br /&gt;
* [[Installing Postgres for PHP]]&lt;br /&gt;
&lt;br /&gt;
===Plugins===&lt;br /&gt;
* [[Installing contributed modules or plugins]]&lt;br /&gt;
&lt;br /&gt;
==Security, Performance and Roles==&lt;br /&gt;
&lt;br /&gt;
*[[Security]] contains important security procedures for a production site&lt;br /&gt;
*[[Performance]] for ideas on improving the speed of your installation&lt;br /&gt;
*[[Manage roles]] For Moodle 1.7 and later.&lt;br /&gt;
*[[Reducing spam in Moodle]]&lt;br /&gt;
*[[suhosin]] is an advanced protection system for PHP installation. It was designed to protect servers and users from known and unknown flaws in PHP applications and the PHP core.&lt;br /&gt;
*[[nagios]] Open source software to monitor servers&lt;br /&gt;
&lt;br /&gt;
== FAQs ==&lt;br /&gt;
&lt;br /&gt;
*[[Installation FAQ]]&lt;br /&gt;
*[[Beginning Administration FAQ]]&lt;br /&gt;
*[[Administration FAQ]]&lt;br /&gt;
*[[Performance FAQ]]&lt;br /&gt;
*[[Backup and restore FAQ]]&lt;br /&gt;
*[[Errors FAQ]]&lt;br /&gt;
*[[:Category:FAQ|List of FAQs]]&lt;br /&gt;
&lt;br /&gt;
== Configuration Settings ==&lt;br /&gt;
=== Site administration setting===&lt;br /&gt;
[[Site administration block]] contains most site configuration settings including:&lt;br /&gt;
*[[Front Page settings]]- initial or home page of a Moodle site&lt;br /&gt;
*[[Themes]] - user interface packages of XHTML and CSS controls&lt;br /&gt;
*[[Language]] - default and additional language packs&lt;br /&gt;
*[[Activity modules administration]]&lt;br /&gt;
*[[Blocks administration]]&lt;br /&gt;
*[[Filters]] - Text and Multimedea plugins &lt;br /&gt;
*[[Backup settings]]&lt;br /&gt;
*[[HTML editor settings]]&lt;br /&gt;
*[[Calendar settings]]&lt;br /&gt;
*[[Maintenance mode]]&lt;br /&gt;
*[[Notification page]] used to update versions&lt;br /&gt;
*[[Settings block]] Moodle 2.0 site settings location&lt;br /&gt;
&lt;br /&gt;
===Other settings===&lt;br /&gt;
*[[Course settings]] for course home page configuration&lt;br /&gt;
**Each type of [[Activities|activity]], [[resource]] and [[:Category:Block|block]] has their own settings&lt;br /&gt;
*Older versions settings&lt;br /&gt;
**[[Site settings]] pre 1.7&lt;br /&gt;
**[[Variables]] pre 1.6 &lt;br /&gt;
**[[Location of admin settings in 1.7|Comparison between configuration settings in Moodle 1.6 &amp;amp; 1.7]]&lt;br /&gt;
&lt;br /&gt;
==User Management==&lt;br /&gt;
&lt;br /&gt;
*[[Authentication]] of user on a site&lt;br /&gt;
*[[Add new user|Add a new user]] - on a site&lt;br /&gt;
*[[Upload users]] - from a file to a site, and into existing course and group, some existing user global updates&lt;br /&gt;
*[[User_profile_fields]]&lt;br /&gt;
*[[Enrolment plugins]]&lt;br /&gt;
**[[Flat file]] - enrol existing users in a course&lt;br /&gt;
*[[Roles and capabilities|Assigning user a role]] - typical assignments include:&lt;br /&gt;
**[[Students|Enrol students in a course]]&lt;br /&gt;
**[[Unenrolment]] Student&lt;br /&gt;
**[[Courses (administrator)|Assign teachers]] - to a course&lt;br /&gt;
**[[Assign creators|Assign course creators]] - in a site&lt;br /&gt;
**[[Assign administrators]] - in a site&lt;br /&gt;
&lt;br /&gt;
==Other==&lt;br /&gt;
&lt;br /&gt;
*[[Courses (administrator)|Courses]] and [[Course formats|course formats]]&lt;br /&gt;
*[[Reports (administrator)]] and [[Logs]]&lt;br /&gt;
*[[Site files]]&lt;br /&gt;
*[[Moodle database|Moodle site database]] &lt;br /&gt;
*[[Environment]]&lt;br /&gt;
*[[MNet|Moodle Network]] and Moodle [[Community hub]]&lt;br /&gt;
*[[Streaming Media]]&lt;br /&gt;
*[[Case studies (administrator)]]&lt;br /&gt;
*[[Anti-virus]]&lt;br /&gt;
*[[System Monitoring and Server Statistic Software]]&lt;br /&gt;
*[[Integrate Moodle, LDAP and SIMS.net]]&lt;br /&gt;
*[[How to rebuild context paths]]&lt;br /&gt;
*[[Hacking the Moodle 2.0 database transfer script to convert a Moodle 1.9 site]]&lt;br /&gt;
*[[Category:ProxyProblems]]&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
*[[:Category:Administrator | Index of all Administrator-related pages]]&lt;br /&gt;
*[[Integrations]]&lt;br /&gt;
*[[CVS for Administrators]]&lt;br /&gt;
*[[Email processing]]&lt;br /&gt;
*[[Search engine optimization]]&lt;br /&gt;
*[[Messaging]]&lt;br /&gt;
*[[Migration]]&lt;br /&gt;
*[[Metacourses]]&lt;br /&gt;
*[[Block layout]]&lt;br /&gt;
*[[Customizing Moodle]]&lt;br /&gt;
*[[Administrator do&#039;s and don&#039;ts]]&lt;br /&gt;
*[[Using Moodle book]] Chapter 16: Moodle Administration&lt;br /&gt;
*[[Administration hacks]]&lt;br /&gt;
*[[Git]] Version control, upgrading &lt;br /&gt;
&lt;br /&gt;
[[Category: Administrator]]&lt;br /&gt;
[[cs:Rukověť správce]]&lt;br /&gt;
[[es:Documentación para Administradores]]&lt;br /&gt;
[[eu:Kudeatzaileentzako dokumentazioa]]&lt;br /&gt;
[[fr:Documentation administrateur]]&lt;br /&gt;
[[ja:管理者ドキュメント]]&lt;br /&gt;
[[ko:관리자 문서]]&lt;br /&gt;
[[nl:Documentatie voor beheerders]]&lt;br /&gt;
[[pt:Documentação para administradores]]&lt;br /&gt;
[[ru:Администраторам]]&lt;br /&gt;
[[sk:Dokumentácia pre správcov]]&lt;br /&gt;
[[zh:管理员文档]]&lt;br /&gt;
[[pl:Administrator documentation]]&lt;br /&gt;
[[fi:Ylläpitäjän opas]]&lt;br /&gt;
[[de:Dokumentation für Administratoren]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Administrator_documentation&amp;diff=83864</id>
		<title>Administrator documentation</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Administrator_documentation&amp;diff=83864"/>
		<updated>2011-05-26T09:04:27Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* Unix/Linux-based */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this page is to list useful links by general topics for administrators of a Moodle site.&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Installation &amp;amp; Upgrading ==&lt;br /&gt;
&lt;br /&gt;
*[[Installation Quickstart]] for an overview of the installation steps&lt;br /&gt;
*[[Installing Moodle]] for detailed installation instructions&lt;br /&gt;
*[[Installation FAQ]]&lt;br /&gt;
*[[Installing AMP|Options for installing Apache, MySQL and PHP]]&lt;br /&gt;
*[[Upgrading|Upgrading Moodle]]&lt;br /&gt;
*[[Installing contributed modules or plugins]]&lt;br /&gt;
&lt;br /&gt;
== System-specific Instructions &amp;amp; Packages ==&lt;br /&gt;
&lt;br /&gt;
===Unix/Linux-based===&lt;br /&gt;
* [[SUSE Linux Server 10|Automated Installation Guide for SUSE Linux Enterprise Server 10]] operating system&lt;br /&gt;
* [[RedHat Linux installation|Step-by-step Installation Guide for RedHat]] operating system&lt;br /&gt;
* [[Debian GNU/Linux installation|Step-by-step Installation Guide for Debian GNU/Linux]] operating system&lt;br /&gt;
* [[Step-by-step Installation Guide for Ubuntu]]&lt;br /&gt;
* [[Manual installation of Moodle 2.0 on Mythbuntu (and Ubuntu 10.10, 11.04) using Git]]&lt;br /&gt;
* [[Manual_installation_on_Ubuntu|Manual Installation on Ubuntu]]&lt;br /&gt;
* [[Step-by-step Install Guide for Zenwalk-5.0|Step-by-step Installation Guide for Zenwalk-5.0]]&lt;br /&gt;
* [[OLPC XS installation|Step-by-step Installation Guide for the One Laptop per Child XS Server (Beta)]]&lt;br /&gt;
* [[Step-by-step Install Guide for Solaris 10 with Oracle 10|Step-by-step Installation Guide for Solaris 10 with Oracle 10]]&lt;br /&gt;
* [[Installation Guide for Installing on Amazon EC2]]&lt;br /&gt;
&lt;br /&gt;
===Windows===&lt;br /&gt;
* [[Windows installation|Windows installations with instructions for Windows NT/2000/2003 servers]]&lt;br /&gt;
* [[Windows installation using XAMPP|Windows installation using XAMPP: Apache, MySQL and PHP]]&lt;br /&gt;
* [[Development:Windows_Installer_anywhere|MoodleAnywhere]] another Windows installation package&lt;br /&gt;
* [[Installing Moodle on Windows Vista]] - how to&lt;br /&gt;
* [http://www.bfcnetworks.com/whitepapers/installing-moodle-on-windows-server-iis-sql/ Installing Moodle on Windows Server 2008 x86]&lt;br /&gt;
* [http://www.bfcnetworks.com/whitepapers/installing-moodle-on-windows-server-2008-r2-x64-sql-iis/ Installing Moodle on Windows Server 2008 R2]&lt;br /&gt;
* [http://www.bfcnetworks.com/whitepapers/implementing-moodle-on-a-windows-high-availability-environment// Implementing Moodle on a Windows High Availability Environment] Implementing Moodle 1.9 on 2 Microsoft Load Balanced Web Front End Server and a Microsoft SQL Server 2008 R2 Cluster environment&lt;br /&gt;
&lt;br /&gt;
Moodle 2&lt;br /&gt;
* [http://www.bfcnetworks.com/whitepapers/installing-moodle-2-on-windows-server-mysql-php-and-iis7/ Installing Moodle 2 on Windows Server, MySQL, PHP and IIS7]&lt;br /&gt;
* [http://www.bfcnetworks.com/whitepapers/installing-moodle-2-on-windows-server-2008-r2-x64-sql-iis/ Installing Moodle 2 on Windows Server, Microsoft SQL Server, PHP and IIS7]&lt;br /&gt;
&lt;br /&gt;
===Mac===&lt;br /&gt;
* [[Step by Step Installation on a Mac OS X Server|Step by step Installation on a Mac OS X Server 10.5/10.6]]&lt;br /&gt;
* [[Complete Install Packages for Mac OS X | Complete Install Packages for Mac OS X Clients 10.4/10.5/10.6]]&lt;br /&gt;
* [[Step-by-step Guide for Installing Moodle on Mac OS X 10.4 Client|Step by Step Installation on a Mac OS X 10.4 Client using the internal web server]]&lt;br /&gt;
&lt;br /&gt;
===Web Hosts===&lt;br /&gt;
* [[1and1_MySQL_installation | Installation on &#039;&#039;&#039;1and1&#039;&#039;&#039; web hosting]]&lt;br /&gt;
* [[powweb_MySQL_installation | Step-by-step Installation on &#039;&#039;&#039;Powweb&#039;&#039;&#039; web hosting]]&lt;br /&gt;
* [[Step-by-step Installation using the old version of CPanel]]&lt;br /&gt;
* [[Step-by-step Installation using the new version of CPanel]]&lt;br /&gt;
&lt;br /&gt;
===Appliances===&lt;br /&gt;
Some users may prefer to skip manual installation by using a pre-integrated [[Moodle appliance]].&lt;br /&gt;
&lt;br /&gt;
===Database===&lt;br /&gt;
* [[Installing Oracle for PHP]]&lt;br /&gt;
* [[Installing MSSQL for PHP]]&lt;br /&gt;
* [[Installing Postgres for PHP]]&lt;br /&gt;
&lt;br /&gt;
===Plugins===&lt;br /&gt;
* [[Installing contributed modules or plugins]]&lt;br /&gt;
&lt;br /&gt;
==Security, Performance and Roles==&lt;br /&gt;
&lt;br /&gt;
*[[Security]] contains important security procedures for a production site&lt;br /&gt;
*[[Performance]] for ideas on improving the speed of your installation&lt;br /&gt;
*[[Manage roles]] For Moodle 1.7 and later.&lt;br /&gt;
*[[Reducing spam in Moodle]]&lt;br /&gt;
*[[suhosin]] is an advanced protection system for PHP installation. It was designed to protect servers and users from known and unknown flaws in PHP applications and the PHP core.&lt;br /&gt;
*[[nagios]] Open source software to monitor servers&lt;br /&gt;
&lt;br /&gt;
== FAQs ==&lt;br /&gt;
&lt;br /&gt;
*[[Installation FAQ]]&lt;br /&gt;
*[[Beginning Administration FAQ]]&lt;br /&gt;
*[[Administration FAQ]]&lt;br /&gt;
*[[Performance FAQ]]&lt;br /&gt;
*[[Backup and restore FAQ]]&lt;br /&gt;
*[[Errors FAQ]]&lt;br /&gt;
*[[:Category:FAQ|List of FAQs]]&lt;br /&gt;
&lt;br /&gt;
== Configuration Settings ==&lt;br /&gt;
=== Site administration setting===&lt;br /&gt;
[[Site administration block]] contains most site configuration settings including:&lt;br /&gt;
*[[Front Page settings]]- initial or home page of a Moodle site&lt;br /&gt;
*[[Themes]] - user interface packages of XHTML and CSS controls&lt;br /&gt;
*[[Language]] - default and additional language packs&lt;br /&gt;
*[[Activity modules administration]]&lt;br /&gt;
*[[Blocks administration]]&lt;br /&gt;
*[[Filters]] - Text and Multimedea plugins &lt;br /&gt;
*[[Backup settings]]&lt;br /&gt;
*[[HTML editor settings]]&lt;br /&gt;
*[[Calendar settings]]&lt;br /&gt;
*[[Maintenance mode]]&lt;br /&gt;
*[[Notification page]] used to update versions&lt;br /&gt;
*[[Settings block]] Moodle 2.0 site settings location&lt;br /&gt;
&lt;br /&gt;
===Other settings===&lt;br /&gt;
*[[Course settings]] for course home page configuration&lt;br /&gt;
**Each type of [[Activities|activity]], [[resource]] and [[:Category:Block|block]] has their own settings&lt;br /&gt;
*Older versions settings&lt;br /&gt;
**[[Site settings]] pre 1.7&lt;br /&gt;
**[[Variables]] pre 1.6 &lt;br /&gt;
**[[Location of admin settings in 1.7|Comparison between configuration settings in Moodle 1.6 &amp;amp; 1.7]]&lt;br /&gt;
&lt;br /&gt;
==User Management==&lt;br /&gt;
&lt;br /&gt;
*[[Authentication]] of user on a site&lt;br /&gt;
*[[Add new user|Add a new user]] - on a site&lt;br /&gt;
*[[Upload users]] - from a file to a site, and into existing course and group, some existing user global updates&lt;br /&gt;
*[[User_profile_fields]]&lt;br /&gt;
*[[Enrolment plugins]]&lt;br /&gt;
**[[Flat file]] - enrol existing users in a course&lt;br /&gt;
*[[Roles and capabilities|Assigning user a role]] - typical assignments include:&lt;br /&gt;
**[[Students|Enrol students in a course]]&lt;br /&gt;
**[[Unenrolment]] Student&lt;br /&gt;
**[[Courses (administrator)|Assign teachers]] - to a course&lt;br /&gt;
**[[Assign creators|Assign course creators]] - in a site&lt;br /&gt;
**[[Assign administrators]] - in a site&lt;br /&gt;
&lt;br /&gt;
==Other==&lt;br /&gt;
&lt;br /&gt;
*[[Courses (administrator)|Courses]] and [[Course formats|course formats]]&lt;br /&gt;
*[[Reports (administrator)]] and [[Logs]]&lt;br /&gt;
*[[Site files]]&lt;br /&gt;
*[[Moodle database|Moodle site database]] &lt;br /&gt;
*[[Environment]]&lt;br /&gt;
*[[MNet|Moodle Network]] and Moodle [[Community hub]]&lt;br /&gt;
*[[Streaming Media]]&lt;br /&gt;
*[[Case studies (administrator)]]&lt;br /&gt;
*[[Anti-virus]]&lt;br /&gt;
*[[System Monitoring and Server Statistic Software]]&lt;br /&gt;
*[[Integrate Moodle, LDAP and SIMS.net]]&lt;br /&gt;
*[[How to rebuild context paths]]&lt;br /&gt;
*[[Hacking the Moodle 2.0 database transfer script to convert a Moodle 1.9 site]]&lt;br /&gt;
*[[Category:ProxyProblems]]&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
*[[:Category:Administrator | Index of all Administrator-related pages]]&lt;br /&gt;
*[[Integrations]]&lt;br /&gt;
*[[CVS for Administrators]]&lt;br /&gt;
*[[Email processing]]&lt;br /&gt;
*[[Search engine optimization]]&lt;br /&gt;
*[[Messaging]]&lt;br /&gt;
*[[Migration]]&lt;br /&gt;
*[[Metacourses]]&lt;br /&gt;
*[[Block layout]]&lt;br /&gt;
*[[Customizing Moodle]]&lt;br /&gt;
*[[Administrator do&#039;s and don&#039;ts]]&lt;br /&gt;
*[[Using Moodle book]] Chapter 16: Moodle Administration&lt;br /&gt;
*[[Administration hacks]]&lt;br /&gt;
*[[Git]] Version control, upgrading &lt;br /&gt;
&lt;br /&gt;
[[Category: Administrator]]&lt;br /&gt;
[[cs:Rukověť správce]]&lt;br /&gt;
[[es:Documentación para Administradores]]&lt;br /&gt;
[[eu:Kudeatzaileentzako dokumentazioa]]&lt;br /&gt;
[[fr:Documentation administrateur]]&lt;br /&gt;
[[ja:管理者ドキュメント]]&lt;br /&gt;
[[ko:관리자 문서]]&lt;br /&gt;
[[nl:Documentatie voor beheerders]]&lt;br /&gt;
[[pt:Documentação para administradores]]&lt;br /&gt;
[[ru:Администраторам]]&lt;br /&gt;
[[sk:Dokumentácia pre správcov]]&lt;br /&gt;
[[zh:管理员文档]]&lt;br /&gt;
[[pl:Administrator documentation]]&lt;br /&gt;
[[fi:Ylläpitäjän opas]]&lt;br /&gt;
[[de:Dokumentation für Administratoren]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=HTML_editor_FAQ&amp;diff=83452</id>
		<title>HTML editor FAQ</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=HTML_editor_FAQ&amp;diff=83452"/>
		<updated>2011-05-12T18:32:09Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* The HTML Editor does not appear */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Be sure to see the [[HTML editor]] page for more information.&lt;br /&gt;
&lt;br /&gt;
==I can&#039;t find the option to do......==&lt;br /&gt;
&lt;br /&gt;
Click the icon at the far right of the bottom row (two boxes with an arrow). It will say &amp;quot;Enlarge Editor&amp;quot; when you hover over it. The editor will now appear in a pop-up with the full range of options available (e.g. tables). &lt;br /&gt;
&lt;br /&gt;
==The HTML Editor does not appear==&lt;br /&gt;
&lt;br /&gt;
Check the following points and/or discussions (in no particular order);&lt;br /&gt;
&lt;br /&gt;
* Prior to 1.9.11 HTMLArea only supported Firefox and Internet Explorer. Thereafter Chrome and Safari (but not in mobile devices) are also supported. &lt;br /&gt;
* GoDaddy http://moodle.org/mod/forum/discuss.php?d=117556&lt;br /&gt;
* Analytics code or advertisement scripts http://moodle.org/mod/forum/discuss.php?d=117034&lt;br /&gt;
* Hacked site / injected code http://moodle.org/mod/forum/discuss.php?d=116374&lt;br /&gt;
* Editor can be disabled from Administration &amp;gt; Appearance &amp;gt; HTML editor &amp;gt; Use HTML editor or &lt;br /&gt;
* Editor can be disabled from user profile (When editing text &amp;gt; Use standard web forms)&lt;br /&gt;
* Settings of browser (javascript may be disabled)&lt;br /&gt;
* Some custom plugin may break source code&lt;br /&gt;
* Check the config.php file - remove the closing &#039;?&amp;gt;&#039; at the end (it doesn&#039;t need it). Make sure you haven&#039;t used a broken editor (anything Microsoft wrote, typically) that may have corrupted the file.&lt;br /&gt;
&lt;br /&gt;
==How can I enable a spell-check?==&lt;br /&gt;
&lt;br /&gt;
If you want the HTML editor to have a spell-check button, you need to install aspell 0.50 or later on your server, and enter the correct path to access the aspell binary in &#039;&#039;Administration &amp;gt; Server &amp;gt; [[System paths]]&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==How we can disable the spell check button for specific instances in a quiz?==&lt;br /&gt;
The spell check is very handy for most circumstances but a quiz where you are looking at spelling and punctuation in student responses kind of defeats the purpose of the question. You can use the theme CSS files to disable the button on a specific question type. Try: &lt;br /&gt;
&lt;br /&gt;
  .essay div[title=&#039;Spell-check&#039;] {&lt;br /&gt;
  display:none;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
The spell check button should be displayed everywhere &#039;&#039;&#039;except&#039;&#039;&#039; on the essay question type response box. &lt;br /&gt;
&lt;br /&gt;
Suggested by Joshua Westerway.&lt;br /&gt;
&lt;br /&gt;
==What is new with the HTML editor in Moodle 2.0?==&lt;br /&gt;
&lt;br /&gt;
See [[HTML editor 2.0]].&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
*Using Moodle [http://moodle.org/mod/forum/view.php?f=224 HTML editor forum]&lt;br /&gt;
*Using Moodle [http://moodle.org/mod/forum/discuss.php?d=103418 Students can&#039;t upload files using HTML editor] forum discussion&lt;br /&gt;
&lt;br /&gt;
[[Category:HTML editor]]&lt;br /&gt;
[[Category:FAQ]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=HTML_editor_FAQ&amp;diff=83443</id>
		<title>HTML editor FAQ</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=HTML_editor_FAQ&amp;diff=83443"/>
		<updated>2011-05-12T14:32:20Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* The HTML Editor does not appear */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Be sure to see the [[HTML editor]] page for more information.&lt;br /&gt;
&lt;br /&gt;
==I can&#039;t find the option to do......==&lt;br /&gt;
&lt;br /&gt;
Click the icon at the far right of the bottom row (two boxes with an arrow). It will say &amp;quot;Enlarge Editor&amp;quot; when you hover over it. The editor will now appear in a pop-up with the full range of options available (e.g. tables). &lt;br /&gt;
&lt;br /&gt;
==The HTML Editor does not appear==&lt;br /&gt;
&lt;br /&gt;
Check the following points and/or discussions (in no particular order);&lt;br /&gt;
&lt;br /&gt;
* Prior to 1.9.11 HTMLArea only supported Firefox and Internet Explorer. Thereafter Chrome and Safari (but not in mobile devices) are also supported. &lt;br /&gt;
* GoDaddy http://moodle.org/mod/forum/discuss.php?d=117556&lt;br /&gt;
* Analytics code or advertisement scripts http://moodle.org/mod/forum/discuss.php?d=117034&lt;br /&gt;
* Hacked site / injected code http://moodle.org/mod/forum/discuss.php?d=116374&lt;br /&gt;
* Editor can be disabled from Administration &amp;gt; Appearance &amp;gt; HTML editor &amp;gt; Use HTML editor or &lt;br /&gt;
* Editor can be disabled from user profile (When editing text &amp;gt; Use standard web forms)&lt;br /&gt;
* Settings of browser (javascript may be disabled)&lt;br /&gt;
* Some custom plugin may break source code&lt;br /&gt;
&lt;br /&gt;
==How can I enable a spell-check?==&lt;br /&gt;
&lt;br /&gt;
If you want the HTML editor to have a spell-check button, you need to install aspell 0.50 or later on your server, and enter the correct path to access the aspell binary in &#039;&#039;Administration &amp;gt; Server &amp;gt; [[System paths]]&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==How we can disable the spell check button for specific instances in a quiz?==&lt;br /&gt;
The spell check is very handy for most circumstances but a quiz where you are looking at spelling and punctuation in student responses kind of defeats the purpose of the question. You can use the theme CSS files to disable the button on a specific question type. Try: &lt;br /&gt;
&lt;br /&gt;
  .essay div[title=&#039;Spell-check&#039;] {&lt;br /&gt;
  display:none;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
The spell check button should be displayed everywhere &#039;&#039;&#039;except&#039;&#039;&#039; on the essay question type response box. &lt;br /&gt;
&lt;br /&gt;
Suggested by Joshua Westerway.&lt;br /&gt;
&lt;br /&gt;
==What is new with the HTML editor in Moodle 2.0?==&lt;br /&gt;
&lt;br /&gt;
See [[HTML editor 2.0]].&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
*Using Moodle [http://moodle.org/mod/forum/view.php?f=224 HTML editor forum]&lt;br /&gt;
*Using Moodle [http://moodle.org/mod/forum/discuss.php?d=103418 Students can&#039;t upload files using HTML editor] forum discussion&lt;br /&gt;
&lt;br /&gt;
[[Category:HTML editor]]&lt;br /&gt;
[[Category:FAQ]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Cookie_Sessions&amp;diff=83197</id>
		<title>Cookie Sessions</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Cookie_Sessions&amp;diff=83197"/>
		<updated>2011-05-04T06:43:55Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: spelling&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Troubleshooting&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Some users get the following error when trying to login to their moodle: &amp;lt;code&amp;gt;A server error that affects your login session was detected. Please login again or restart your browser&amp;lt;/code&amp;gt;&lt;br /&gt;
or even: &amp;lt;code&amp;gt;Your session has timed out. Please login again&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* check and fix your permissions in moodledata/session -- set it to 0777&lt;br /&gt;
* check config.php, it should NOT has any spaces/new lines at the end of code. Repeat this on all moodle php files you lately changed, such as course/lib.php&lt;br /&gt;
* In admin &amp;gt; server &amp;gt; session handling &amp;gt; &amp;quot;Cookie Prefix&amp;quot; put something in the Cookie prefix field that is different for each of your moodle sites, and it should improve the issue with multiple sites on the same url.&lt;br /&gt;
* test your server&#039;s sessions by running session test on http://yourserver/moodle/lib/session-test.php&lt;br /&gt;
* check your phpinfo(); if it session handeling is configured correctly or not.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Administrator]]&lt;br /&gt;
[[Category:Cookies]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Development:Using_the_File_API_in_Moodle_forms&amp;diff=82923</id>
		<title>Development:Using the File API in Moodle forms</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Development:Using_the_File_API_in_Moodle_forms&amp;diff=82923"/>
		<updated>2011-04-22T08:14:15Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* Add file manager element */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
This document shows you exactly how to use Moodle forms to get files from users in a standard and secure way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
In Moodle 2.0 all files are stored in a central database accessible via the [[Development:File API|File API]], and every file is associated with a component and a &amp;quot;file area&amp;quot; in Moodle, such as a particular module.&lt;br /&gt;
&lt;br /&gt;
A common use case is to provide a form (using Moodle&#039;s [[Development:lib/formslib.php|Forms API]]) which allows users to upload or import files as attachments or media embedded into HTML.&lt;br /&gt;
&lt;br /&gt;
Normally this works like this:&lt;br /&gt;
# User starts creation or re-edits an existing item in Moodle (eg forum post, resource, glossary entry etc)&lt;br /&gt;
# User presses some sort of button to browse for new files to attach or embed&lt;br /&gt;
# User sees our &amp;quot;Choose file...&amp;quot; dialog, which contains one or more repository instances. &lt;br /&gt;
# User chooses a file, the [[Development:Repository API|Repository API]] takes care of copying the file into a &amp;quot;draft file area&amp;quot; within Moodle&lt;br /&gt;
# File appears in the text or as an attachment in the form.&lt;br /&gt;
# When the user hits save, the [[Development:File API|File API]] is invoked to move the file from the draft file area into a permanent file area associated with that data &lt;br /&gt;
&lt;br /&gt;
This document shows you exactly how to use Moodle forms to interact with users in a standard and secure way.&lt;br /&gt;
&lt;br /&gt;
If you just want to write code to manipulate Moodle files internally (without user input) then see [[Development:Using_the_File_API]].&lt;br /&gt;
&lt;br /&gt;
==Form elements== &lt;br /&gt;
&lt;br /&gt;
In Moodle 2.0 there are three file-related form elements for interacting with users:&lt;br /&gt;
&lt;br /&gt;
# filemanager - the way to attach one or more files as a set&lt;br /&gt;
# editor - the way to specify a textarea with a HTML editor, and all the handling of images and movies within that HTML&lt;br /&gt;
# filepicker - a way to specify one file for the case when you want to process the file and throw it away &lt;br /&gt;
&lt;br /&gt;
In Moodle 1.9 there were two other types which are now &#039;&#039;&#039;deprecated&#039;&#039;&#039; (they work, but please do not use these anymore)&lt;br /&gt;
# file - used to just allow a normal file upload from the desktop only.&lt;br /&gt;
# htmleditor - this old method of embedding a HTML editor in a textarea is not able to support repositories etc.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===filepicker===&lt;br /&gt;
&lt;br /&gt;
File picker (&#039;&#039;filepicker&#039;&#039;) is a direct replacement of the older &#039;&#039;file&#039;&#039; formslib element. &lt;br /&gt;
&lt;br /&gt;
It is intended for situations when you want the user to upload &#039;&#039;&#039;one&#039;&#039;&#039; file so you can process it and delete it, such as when you are importing data from a CSV file.&lt;br /&gt;
&lt;br /&gt;
==== Using the filepicker element ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;filepicker&#039;, &#039;userfile&#039;, get_string(&#039;file&#039;), null, array(&#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;accepted_types&#039; =&amp;gt; &#039;*&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Obtain the chosen file ====&lt;br /&gt;
&lt;br /&gt;
The API for getting file contents is exactly the same as for &#039;&#039;file&#039;&#039; element.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$content = $mform-&amp;gt;get_file_content(&#039;userfile&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== filemanager ===&lt;br /&gt;
&lt;br /&gt;
The File Manager element improves on file picker by allowing you to manage more than one file.  It is expected that the files will be stored permanently for future use (such as forum and glossary attachments).&lt;br /&gt;
&lt;br /&gt;
==== Add file manager element ====&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;filemanager&#039;, &#039;attachments&#039;, get_string(&#039;attachment&#039;, &#039;moodle&#039;), null,&lt;br /&gt;
                    array(&#039;subdirs&#039; =&amp;gt; 0, &#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;maxfiles&#039; =&amp;gt; 50, &#039;accepted_types&#039; =&amp;gt; array(&#039;document&#039;) ));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here are the fields for filemanager:&lt;br /&gt;
&lt;br /&gt;
;&#039;filemanager&#039;:This is a filemanager element :)&lt;br /&gt;
;elementname:The unique name of the element in the form&lt;br /&gt;
;elementlabel:The label string that users see &lt;br /&gt;
;attributes:(leave it as null)&lt;br /&gt;
;options: an array of further options for the filepicker (see below)&lt;br /&gt;
&lt;br /&gt;
The options array can contain:&lt;br /&gt;
&lt;br /&gt;
;subdirs:(Default 0) Are subdirectories allowed?  (true or false)&lt;br /&gt;
;maxbytes:(Default 0) Restricts the total size of all the files.&lt;br /&gt;
;maxfiles:(Default -1) Restricts the total number of files.&lt;br /&gt;
;accepted_types:(Default *) You can specify what file types are accepted by filemanager.  All current file types are listed in this file: [http://cvs.moodle.org/moodle/lib/filestorage/file_types.mm moodle/lib/filestorage/file_types.mm].  This is a [http://freemind.sourceforge.net/wiki/index.php/Main_Page freemind] file: if it is edited the changes will be immediately reflected in Moodle.  Example usage:  &#039;&#039;&#039;array(&#039;audio&#039;, &#039;video&#039;, &#039;documents&#039;)&#039;&#039;&#039;, you can include file extensions as well, for example: &#039;&#039;&#039;array(&#039;*.txt&#039;, &#039;*.jpg&#039;, &#039;audio&#039;)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Load existing files into draft area ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (empty($entry-&amp;gt;id)) {&lt;br /&gt;
    $entry = new object();&lt;br /&gt;
    $entry-&amp;gt;id = null;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$draftitemid = file_get_submitted_draft_itemid(&#039;attachments&#039;);&lt;br /&gt;
file_prepare_draft_area($draftitemid, $context-&amp;gt;id, &#039;mod_glossary&#039;, &#039;attachment&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039; =&amp;gt; 0, &#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;maxfiles&#039; =&amp;gt; 50));&lt;br /&gt;
$entry-&amp;gt;attachments = $draftitemid;&lt;br /&gt;
&lt;br /&gt;
$mform-&amp;gt;set_data($entry);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Store updated set of files ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($data = $mform-&amp;gt;get_data()) {&lt;br /&gt;
    // ... store or update $entry&lt;br /&gt;
    file_save_draft_area_files($data-&amp;gt;attachments, $context-&amp;gt;id, &#039;mod_glossary&#039;, &#039;attachment&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039; =&amp;gt; 0, &#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;maxfiles&#039; =&amp;gt; 50));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===editor===&lt;br /&gt;
There are two way for using of editor element in code, the first one is easier but expects some standardized fields. The second method is more low level.&lt;br /&gt;
&lt;br /&gt;
====Simple use====&lt;br /&gt;
# name database fields: &#039;&#039;textfield&#039;&#039;, &#039;&#039;textfieldformat&#039;&#039; (and &#039;&#039;textfieldtrust&#039;&#039; if required)&lt;br /&gt;
# create options array &amp;lt;code php&amp;gt;$textfieldoptions = array(&#039;trusttext&#039;=&amp;gt;true, &#039;subdirs&#039;=&amp;gt;true, &#039;maxfiles&#039;=&amp;gt;$maxfiles, &#039;maxbytes&#039;=&amp;gt;$maxbytes);&amp;lt;/code&amp;gt;&lt;br /&gt;
# add editor &#039;&#039;textfield_editor&#039;&#039; to moodle form, pass options through custom data in form constructor, set $data-&amp;gt;id to null if data not exist yet &amp;lt;code php&amp;gt;$mform-&amp;gt;addElement(&#039;editor&#039;, &#039;textfield_editor&#039;, get_string(&#039;fieldname&#039;, &#039;somemodule&#039;), null, $textfieldoptions);&amp;lt;/code&amp;gt;&lt;br /&gt;
# prepare data &amp;lt;code php&amp;gt;$data = file_prepare_standard_editor($data, &#039;textfield&#039;, $textfieldoptions, $context, &#039;mod_somemodule&#039;, &#039;somearea&#039;, $data-&amp;gt;id);&amp;lt;/code&amp;gt;&lt;br /&gt;
# get submitted data and after inserting/updating of data &amp;lt;code php&amp;gt;$data = file_postupdate_standard_editor($data, &#039;textfield&#039;, $textfieldoptions, $context, &#039;mod_somemodule&#039;, &#039;somearea&#039;, $data-&amp;gt;id);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Real world examples are in mod/glossary/edit.php and mod/glossary/comment.php&lt;br /&gt;
&lt;br /&gt;
====Low level use====&lt;br /&gt;
&lt;br /&gt;
When using editor element you  need to preprocess and postprocess the data:&lt;br /&gt;
# detect if form was already submitted (usually means draft is area already exists) - &#039;&#039;file_get_submitted_draft_itemid()&#039;&#039;&lt;br /&gt;
# prepare draft file area, temporary storage of all files attached to the text - &#039;&#039;file_prepare_draft_area()&#039;&#039;&lt;br /&gt;
# convert encoded relative links to absolute links - &#039;&#039;file_prepare_draft_area()&#039;&#039;&lt;br /&gt;
# create form and set current data&lt;br /&gt;
# after submission the changed files must be merged back into original area - &#039;&#039;file_save_draft_area_files()&#039;&#039;&lt;br /&gt;
# absolute links have to be replaced by relative links - &#039;&#039;file_save_draft_area_files()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=====Replace old htmleditor with editor=====&lt;br /&gt;
&lt;br /&gt;
The file picker has been integrated with with TinyMCE to make the editor element. This new element should support all types on editors and should be able to switch them on-the-fly. Instances of the old htmleditor element in your forms should be replaced by the new editor element, this may need adding of new format and trusttext columns. For example:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;editor&#039;, &#039;entry&#039;, get_string(&#039;definition&#039;, &#039;glossary&#039;), null,&lt;br /&gt;
        array(&#039;maxfiles&#039; =&amp;gt; EDITOR_UNLIMITED_FILES));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The editor element can take following options: maxfiles, maxbytes, subdirs and changeformat. Please note that the embedded files is optional feature and is not expected be used everywhere.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: the editor element now includes text format option. You should no longer use the separate format element type.&lt;br /&gt;
&lt;br /&gt;
=====Prepare current data - text and files=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (empty($entry-&amp;gt;id)) {&lt;br /&gt;
  $entry = new object();&lt;br /&gt;
  $entry-&amp;gt;id = null;&lt;br /&gt;
  $entry-&amp;gt;definition = &#039;&#039;;&lt;br /&gt;
  $entry-&amp;gt;format = FORMAT_HTML;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$draftid_editor = file_get_submitted_draft_itemid(&#039;entry&#039;);&lt;br /&gt;
$currenttext = file_prepare_draft_area($draftid_editor, $context-&amp;gt;id, &#039;mod_glossary&#039;, &#039;entry&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039;=&amp;gt;true), $entry-&amp;gt;definition);&lt;br /&gt;
$entry-&amp;gt;entry = array(&#039;text&#039;=&amp;gt;$currenttext, &#039;format&#039;=&amp;gt;$entry-&amp;gt;format, &#039;itemid&#039;=&amp;gt;$draftid_editor);&lt;br /&gt;
&lt;br /&gt;
$mform-&amp;gt;set_data($entry);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If there are multiple files, they will share the same itemid.&lt;br /&gt;
&lt;br /&gt;
=====Obtain text, format and save draft files=====&lt;br /&gt;
&lt;br /&gt;
To retrieve editor content, you need to use following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($fromform = $mform-&amp;gt;get_data()) {&lt;br /&gt;
    // content of editor&lt;br /&gt;
    $messagetext = $fromform-&amp;gt;entry[&#039;text&#039;];&lt;br /&gt;
    // format of content&lt;br /&gt;
    $messageformat  = $fromform-&amp;gt;entry[&#039;format&#039;];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When a user selects a file using the file picker, the file is initially stored in a draft file area, and a URL is inserted into the HTML in the editor that lets the person editing the content (but no one else) see the file.&lt;br /&gt;
&lt;br /&gt;
When the user submits the form, we then need to save the draft files to the correct place in permanent storage. (Just like you have to call $DB-&amp;gt;update_record(&#039;tablename&#039;, $data); to have the other parts of the form submission stored correctly.)&lt;br /&gt;
&lt;br /&gt;
The save_files_from_draft_area function and replace absolute links with internal relative links do:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$messagetext = file_save_draft_area_files($draftid_editor, $context-&amp;gt;id, &#039;mod_glossary&#039;, &#039;entry&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039;=&amp;gt;true), $messagetext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
; $context-&amp;gt;id, &#039;component&#039;, &#039;proper_file_area&#039; and $entry-&amp;gt;id : correspond to the contextid, filearea and itemid columns in the [[Development:File_API#Table:_files|files table]].&lt;br /&gt;
; $messagetext : this is the message text. As the files are saved to the real file area, the URLs in this content are rewritten.&lt;br /&gt;
&lt;br /&gt;
All URLs in content that point to files managed to the File API are converted to a form that starts &#039;@@PLUGINFILE@@/&#039; before the content is stored in the database. That is what we mean by rewriting.&lt;br /&gt;
&lt;br /&gt;
== File serving==&lt;br /&gt;
&lt;br /&gt;
=== Convert internal relative links to absolute links ===&lt;br /&gt;
&lt;br /&gt;
Before text content is displayed to the user, any URLs in the &#039;@@PLUGINFILE@@/&#039; form in the content need to be rewritten to the real URL where the user can access the files. &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$messagetext = file_rewrite_pluginfile_urls($messagetext, &#039;pluginfile.php&#039;,&lt;br /&gt;
        $context-&amp;gt;id, &#039;mod_mymodule&#039;, &#039;proper_file_area&#039;, $itemid);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
; $messagetext : is the content containing the @@PLUGINFILE@@ URLs from the database.&lt;br /&gt;
; &#039;pluginfile.php&#039; : there are a number of different scripts that can serve files with different permissions checks. You need to specify which one to use.&lt;br /&gt;
; $context-&amp;gt;id, &#039;mod_mymodule&#039;, &#039;proper_file_area&#039;, $itemid : uniquely identifies the file area, as before.&lt;br /&gt;
&lt;br /&gt;
=== Implement file serving access control ===&lt;br /&gt;
&lt;br /&gt;
Attachments and embedded images should have the same access control like the text itself, in majority of cases these files are served using pluginfile.php. Access control is defined in &#039;&#039;module/lib.php&#039;&#039; file in function &#039;&#039;module_pluginfile()&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== File browsing support ==&lt;br /&gt;
Only owner of each file area is allowed to use low level File API function to access files, other parts of Moodle should use file browsing API.&lt;br /&gt;
&lt;br /&gt;
Activities may specify browsing support in own module/lib.php file by implementing functions module_get_file_areas() and module_get_file_info().&lt;br /&gt;
&lt;br /&gt;
== Upgrading your code ==&lt;br /&gt;
Here I will attempt to describe some simple steps you can take to upgrade your file-handling form elements from pre-2.0 code to 2.0. We will use the example of glossary, since it has been used above.&lt;br /&gt;
&lt;br /&gt;
=== Preparing your options ===&lt;br /&gt;
Unless you are happy with the defaults, you will need to define an array of options for each file-handling form element. You could define it at different places, but it&#039;s best to put it in one place and make the array(s) available to other files if they need it. In the majority of cases, this will be in a file like edit.php&lt;br /&gt;
&lt;br /&gt;
Previous code in mod/glossary/edit.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform =&amp;amp; new mod_glossary_entry_form(null, compact(&#039;cm&#039;, &#039;glossary&#039;, &#039;hook&#039;, &#039;mode&#039;, &#039;e&#039;, &#039;context&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$maxbytes = $course-&amp;gt;maxbytes; // Could also use $CFG-&amp;gt;maxbytes if you are not coding within a course context&lt;br /&gt;
$definitionoptions = array(&#039;subdirs&#039;=&amp;gt;false, &#039;maxfiles&#039;=&amp;gt;99, &#039;maxbytes&#039;=&amp;gt;$maxbytes, &#039;trusttext&#039;=&amp;gt;true, &#039;context&#039;=&amp;gt;$context);&lt;br /&gt;
$attachmentoptions = array(&#039;subdirs&#039;=&amp;gt;false, &#039;maxfiles&#039;=&amp;gt;99, &#039;maxbytes&#039;=&amp;gt;$maxbytes);&lt;br /&gt;
$mform = new mod_glossary_entry_form(null, array(&lt;br /&gt;
        &#039;current&#039;=&amp;gt;$entry, &lt;br /&gt;
        &#039;cm&#039;=&amp;gt;$cm, &lt;br /&gt;
        &#039;glossary&#039;=&amp;gt;$glossary,&lt;br /&gt;
        &#039;definitionoptions&#039;=&amp;gt;$definitionoptions, &lt;br /&gt;
        &#039;attachmentoptions&#039;=&amp;gt;$attachmentoptions));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note that the data being passed to the form constructor have changed also, but this is not part of the file API changes, I just include them to avoid confusion.&lt;br /&gt;
&lt;br /&gt;
These options are for the htmleditor (definition field) and the filemanager (attachment field). They are used by a file called edit_form.php.&lt;br /&gt;
&lt;br /&gt;
=== Element preparation ===&lt;br /&gt;
Before we look at this, however, we need to &amp;quot;prepare&amp;quot; the elements so that they can correctly display existing embedded images and attached files when you are editing a record instead of just creating one. So, let&#039;s take the code we&#039;ve got so far in edit.php and add to it:&lt;br /&gt;
&lt;br /&gt;
Currently upgraded code in edit.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform = new mod_glossary_entry_form(null, array(&lt;br /&gt;
        &#039;current&#039;=&amp;gt;$entry, &lt;br /&gt;
        &#039;cm&#039;=&amp;gt;$cm, &lt;br /&gt;
        &#039;glossary&#039;=&amp;gt;$glossary,&lt;br /&gt;
        &#039;definitionoptions&#039;=&amp;gt;$definitionoptions, &lt;br /&gt;
        &#039;attachmentoptions&#039;=&amp;gt;$attachmentoptions));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code with element preparation:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$entry = file_prepare_standard_editor($entry, &#039;definition&#039;, $definitionoptions, $context, &#039;mod_glossary&#039;, &#039;entry&#039;, $entry-&amp;gt;id);&lt;br /&gt;
$entry = file_prepare_standard_filemanager($entry, &#039;attachment&#039;, $attachmentoptions, $context, &#039;mod_glossary&#039;, &#039;attachment&#039;, $entry-&amp;gt;id);&lt;br /&gt;
$mform = new mod_glossary_entry_form(null, array(&lt;br /&gt;
        &#039;current&#039;=&amp;gt;$entry, &lt;br /&gt;
        &#039;cm&#039;=&amp;gt;$cm, &lt;br /&gt;
        &#039;glossary&#039;=&amp;gt;$glossary,&lt;br /&gt;
        &#039;definitionoptions&#039;=&amp;gt;$definitionoptions, &lt;br /&gt;
        &#039;attachmentoptions&#039;=&amp;gt;$attachmentoptions));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Things to note:&lt;br /&gt;
* $entry in this case is simply a stdClass object which may either represent a new glossary entry or an existing one.&lt;br /&gt;
* $entry-&amp;gt;id must be the unique identifier for the current object. If we are creating a new entry, it will be null, but in all cases it must be defined.&lt;br /&gt;
* These two functions (file_prepare_standard_editor and file_prepare_standard_filemanager) are shortcuts functions that take care of some of the tedious setting up for you, but they make a couple of assumptions:&lt;br /&gt;
*# You &#039;&#039;&#039;must&#039;&#039;&#039; name the form element as {element}_editor or {element}_filemanager (see next section)&lt;br /&gt;
*# You &#039;&#039;&#039;must&#039;&#039;&#039; have at least the following fields in the database: {element} and {element}summary, as described earlier in this documentation&lt;br /&gt;
&lt;br /&gt;
We can now look at the upgrades needed in the form definition file.&lt;br /&gt;
&lt;br /&gt;
=== Form definition ===&lt;br /&gt;
Previous code in mod/glossary/edit_form.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;htmleditor&#039;, &#039;definition&#039;, get_string(&#039;definition&#039;, &#039;glossary&#039;), array(&#039;rows&#039;=&amp;gt;20));&lt;br /&gt;
$mform-&amp;gt;setType(&#039;definition&#039;, PARAM_RAW);&lt;br /&gt;
$mform-&amp;gt;addRule(&#039;definition&#039;, null, &#039;required&#039;, null, &#039;client&#039;);&lt;br /&gt;
$mform-&amp;gt;setHelpButton(&#039;definition&#039;, array(&#039;writing&#039;, &#039;richtext&#039;), false, &#039;editorhelpbutton&#039;);&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;format&#039;);&lt;br /&gt;
// a bit further...&lt;br /&gt;
$this-&amp;gt;set_upload_manager(new upload_manager(&#039;attachment&#039;, true, false, $COURSE, false, 0, true, true, false));&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;file&#039;, &#039;attachment&#039;, get_string(&#039;attachment&#039;, &#039;forum&#039;));&lt;br /&gt;
$mform-&amp;gt;setHelpButton(&#039;attachment&#039;, array(&#039;attachment&#039;, get_string(&#039;attachment&#039;, &#039;glossary&#039;), &#039;glossary&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$definitionoptions = $this-&amp;gt;_customdata[&#039;definitionoptions&#039;];&lt;br /&gt;
$attachmentoptions = $this-&amp;gt;_customdata[&#039;attachmentoptions&#039;];&lt;br /&gt;
// a bit further...&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;editor&#039;, &#039;definition_editor&#039;, get_string(&#039;definition&#039;, &#039;glossary&#039;), null, $definitionoptions);&lt;br /&gt;
$mform-&amp;gt;setType(&#039;definition_editor&#039;, PARAM_RAW);&lt;br /&gt;
$mform-&amp;gt;addRule(&#039;definition_editor&#039;, get_string(&#039;required&#039;), &#039;required&#039;, null, &#039;client&#039;);&lt;br /&gt;
// a bit further...&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;filemanager&#039;, &#039;attachment_filemanager&#039;, get_string(&#039;attachment&#039;, &#039;glossary&#039;), null, $attachmentoptions);&lt;br /&gt;
$mform-&amp;gt;setHelpButton(&#039;attachment_filemanager&#039;, array(&#039;attachment2&#039;, get_string(&#039;attachment&#039;, &#039;glossary&#039;), &#039;glossary&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the following:&lt;br /&gt;
* The format element and the help button are no longer required for the HTML editor element&lt;br /&gt;
* The name of the form element needs to be changed by adding &#039;_editor&#039; or &#039;_manager&#039; to the original name. This is a naming convention that is used by a couple of functions we will look at shortly&lt;br /&gt;
&lt;br /&gt;
=== Handling submitted data ===&lt;br /&gt;
The final step is to handle the submitted data properly, i.e. retrieve the files and save them to disk, associating them with the record we have just created (a glossary entry in our example). This happens in edit.php:&lt;br /&gt;
&lt;br /&gt;
Previous code in edit.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Section that updates an entry:&lt;br /&gt;
$todb-&amp;gt;id = $e;&lt;br /&gt;
$dir = glossary_file_area_name($todb);&lt;br /&gt;
if ($mform-&amp;gt;save_files($dir) and $newfilename = $mform-&amp;gt;get_new_filename()) {&lt;br /&gt;
    $todb-&amp;gt;attachment = $newfilename;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Section that adds an entry:&lt;br /&gt;
if ($todb-&amp;gt;id = insert_record(&amp;quot;glossary_entries&amp;quot;, $todb)) {&lt;br /&gt;
    $e = $todb-&amp;gt;id;&lt;br /&gt;
    $dir = glossary_file_area_name($todb);&lt;br /&gt;
    if ($mform-&amp;gt;save_files($dir) and $newfilename = $mform-&amp;gt;get_new_filename()) {&lt;br /&gt;
        set_field(&amp;quot;glossary_entries&amp;quot;, &amp;quot;attachment&amp;quot;, $newfilename, &amp;quot;id&amp;quot;, $todb-&amp;gt;id);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// $todb was renamed to $entry, and the code was refactored &lt;br /&gt;
// so that the file-handling code is only used once for either an add or an update action.&lt;br /&gt;
// If an entry is being added, $DB-&amp;gt;insert() has already been called, so we have a valid $entry-&amp;gt;id&lt;br /&gt;
$entry = file_postupdate_standard_editor($entry, &#039;definition&#039;, $definitionoptions, $context, &#039;mod_glossary&#039;, &#039;entry&#039;, $entry-&amp;gt;id);&lt;br /&gt;
$entry = file_postupdate_standard_filemanager($entry, &#039;attachment&#039;, $attachmentoptions, $context, &#039;mod_glossary&#039;, &#039;attachment&#039;, $entry-&amp;gt;id);&lt;br /&gt;
// store the updated value values&lt;br /&gt;
$DB-&amp;gt;update_record(&#039;glossary_entries&#039;, $entry);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Things to note:&lt;br /&gt;
* If you are adding a new record, you will still need to call update_record after calling the file_postupdate* functions&lt;br /&gt;
&lt;br /&gt;
=== Gotchas ===&lt;br /&gt;
A few things to keep in mind:&lt;br /&gt;
* Make sure that you instantiate the moodle form before any call to $OUTPUT-&amp;gt;header()&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Development:File API]]&lt;br /&gt;
* [[Development:Using the file API]]&lt;br /&gt;
* [[Development:Repository API]]&lt;br /&gt;
* [[Development:Portfolio API]]&lt;br /&gt;
* MDL-14589 - File API Meta issue&lt;br /&gt;
&lt;br /&gt;
{{CategoryDeveloper}}&lt;br /&gt;
[[Category:Files]]&lt;br /&gt;
[[Category:Repositories]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Development:Using_the_File_API_in_Moodle_forms&amp;diff=82922</id>
		<title>Development:Using the File API in Moodle forms</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Development:Using_the_File_API_in_Moodle_forms&amp;diff=82922"/>
		<updated>2011-04-22T08:13:24Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: Correcting file location&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
This document shows you exactly how to use Moodle forms to get files from users in a standard and secure way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
In Moodle 2.0 all files are stored in a central database accessible via the [[Development:File API|File API]], and every file is associated with a component and a &amp;quot;file area&amp;quot; in Moodle, such as a particular module.&lt;br /&gt;
&lt;br /&gt;
A common use case is to provide a form (using Moodle&#039;s [[Development:lib/formslib.php|Forms API]]) which allows users to upload or import files as attachments or media embedded into HTML.&lt;br /&gt;
&lt;br /&gt;
Normally this works like this:&lt;br /&gt;
# User starts creation or re-edits an existing item in Moodle (eg forum post, resource, glossary entry etc)&lt;br /&gt;
# User presses some sort of button to browse for new files to attach or embed&lt;br /&gt;
# User sees our &amp;quot;Choose file...&amp;quot; dialog, which contains one or more repository instances. &lt;br /&gt;
# User chooses a file, the [[Development:Repository API|Repository API]] takes care of copying the file into a &amp;quot;draft file area&amp;quot; within Moodle&lt;br /&gt;
# File appears in the text or as an attachment in the form.&lt;br /&gt;
# When the user hits save, the [[Development:File API|File API]] is invoked to move the file from the draft file area into a permanent file area associated with that data &lt;br /&gt;
&lt;br /&gt;
This document shows you exactly how to use Moodle forms to interact with users in a standard and secure way.&lt;br /&gt;
&lt;br /&gt;
If you just want to write code to manipulate Moodle files internally (without user input) then see [[Development:Using_the_File_API]].&lt;br /&gt;
&lt;br /&gt;
==Form elements== &lt;br /&gt;
&lt;br /&gt;
In Moodle 2.0 there are three file-related form elements for interacting with users:&lt;br /&gt;
&lt;br /&gt;
# filemanager - the way to attach one or more files as a set&lt;br /&gt;
# editor - the way to specify a textarea with a HTML editor, and all the handling of images and movies within that HTML&lt;br /&gt;
# filepicker - a way to specify one file for the case when you want to process the file and throw it away &lt;br /&gt;
&lt;br /&gt;
In Moodle 1.9 there were two other types which are now &#039;&#039;&#039;deprecated&#039;&#039;&#039; (they work, but please do not use these anymore)&lt;br /&gt;
# file - used to just allow a normal file upload from the desktop only.&lt;br /&gt;
# htmleditor - this old method of embedding a HTML editor in a textarea is not able to support repositories etc.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===filepicker===&lt;br /&gt;
&lt;br /&gt;
File picker (&#039;&#039;filepicker&#039;&#039;) is a direct replacement of the older &#039;&#039;file&#039;&#039; formslib element. &lt;br /&gt;
&lt;br /&gt;
It is intended for situations when you want the user to upload &#039;&#039;&#039;one&#039;&#039;&#039; file so you can process it and delete it, such as when you are importing data from a CSV file.&lt;br /&gt;
&lt;br /&gt;
==== Using the filepicker element ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;filepicker&#039;, &#039;userfile&#039;, get_string(&#039;file&#039;), null, array(&#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;accepted_types&#039; =&amp;gt; &#039;*&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Obtain the chosen file ====&lt;br /&gt;
&lt;br /&gt;
The API for getting file contents is exactly the same as for &#039;&#039;file&#039;&#039; element.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$content = $mform-&amp;gt;get_file_content(&#039;userfile&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== filemanager ===&lt;br /&gt;
&lt;br /&gt;
The File Manager element improves on file picker by allowing you to manage more than one file.  It is expected that the files will be stored permanently for future use (such as forum and glossary attachments).&lt;br /&gt;
&lt;br /&gt;
==== Add file manager element ====&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;filemanager&#039;, &#039;attachments&#039;, get_string(&#039;attachment&#039;, &#039;moodle&#039;), null,&lt;br /&gt;
                    array(&#039;subdirs&#039; =&amp;gt; 0, &#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;maxfiles&#039; =&amp;gt; 50, &#039;accepted_types&#039; =&amp;gt; array(&#039;document&#039;) ));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here are the fields for filemanager:&lt;br /&gt;
&lt;br /&gt;
;&#039;filemanager&#039;:This is a filemanager element :)&lt;br /&gt;
;elementname:The unique name of the element in the form&lt;br /&gt;
;elementlabel:The label string that users see &lt;br /&gt;
;attributes:(leave it as null)&lt;br /&gt;
;options: an array of further options for the filepicker (see below)&lt;br /&gt;
&lt;br /&gt;
The options array can contain:&lt;br /&gt;
&lt;br /&gt;
;subdirs:(Default 0) Are subdirectories allowed?  (true or false)&lt;br /&gt;
;maxbytes:(Default 0) Restricts the total size of all the files.&lt;br /&gt;
;maxfiles:(Default -1) Restricts the total number of files.&lt;br /&gt;
;accepted_types:(Default *) You can specify what file types are accepted by filemanager.  All current file types are listed in this file: [http://cvs.moodle.org/moodle/lib/filestorage/file_types.mm moodle/lib/file/file_types.mm].  This is a [http://freemind.sourceforge.net/wiki/index.php/Main_Page freemind] file: if it is edited the changes will be immediately reflected in Moodle.  Example usage:  &#039;&#039;&#039;array(&#039;audio&#039;, &#039;video&#039;, &#039;documents&#039;)&#039;&#039;&#039;, you can include file extensions as well, for example: &#039;&#039;&#039;array(&#039;*.txt&#039;, &#039;*.jpg&#039;, &#039;audio&#039;)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Load existing files into draft area ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (empty($entry-&amp;gt;id)) {&lt;br /&gt;
    $entry = new object();&lt;br /&gt;
    $entry-&amp;gt;id = null;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$draftitemid = file_get_submitted_draft_itemid(&#039;attachments&#039;);&lt;br /&gt;
file_prepare_draft_area($draftitemid, $context-&amp;gt;id, &#039;mod_glossary&#039;, &#039;attachment&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039; =&amp;gt; 0, &#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;maxfiles&#039; =&amp;gt; 50));&lt;br /&gt;
$entry-&amp;gt;attachments = $draftitemid;&lt;br /&gt;
&lt;br /&gt;
$mform-&amp;gt;set_data($entry);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Store updated set of files ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($data = $mform-&amp;gt;get_data()) {&lt;br /&gt;
    // ... store or update $entry&lt;br /&gt;
    file_save_draft_area_files($data-&amp;gt;attachments, $context-&amp;gt;id, &#039;mod_glossary&#039;, &#039;attachment&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039; =&amp;gt; 0, &#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;maxfiles&#039; =&amp;gt; 50));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===editor===&lt;br /&gt;
There are two way for using of editor element in code, the first one is easier but expects some standardized fields. The second method is more low level.&lt;br /&gt;
&lt;br /&gt;
====Simple use====&lt;br /&gt;
# name database fields: &#039;&#039;textfield&#039;&#039;, &#039;&#039;textfieldformat&#039;&#039; (and &#039;&#039;textfieldtrust&#039;&#039; if required)&lt;br /&gt;
# create options array &amp;lt;code php&amp;gt;$textfieldoptions = array(&#039;trusttext&#039;=&amp;gt;true, &#039;subdirs&#039;=&amp;gt;true, &#039;maxfiles&#039;=&amp;gt;$maxfiles, &#039;maxbytes&#039;=&amp;gt;$maxbytes);&amp;lt;/code&amp;gt;&lt;br /&gt;
# add editor &#039;&#039;textfield_editor&#039;&#039; to moodle form, pass options through custom data in form constructor, set $data-&amp;gt;id to null if data not exist yet &amp;lt;code php&amp;gt;$mform-&amp;gt;addElement(&#039;editor&#039;, &#039;textfield_editor&#039;, get_string(&#039;fieldname&#039;, &#039;somemodule&#039;), null, $textfieldoptions);&amp;lt;/code&amp;gt;&lt;br /&gt;
# prepare data &amp;lt;code php&amp;gt;$data = file_prepare_standard_editor($data, &#039;textfield&#039;, $textfieldoptions, $context, &#039;mod_somemodule&#039;, &#039;somearea&#039;, $data-&amp;gt;id);&amp;lt;/code&amp;gt;&lt;br /&gt;
# get submitted data and after inserting/updating of data &amp;lt;code php&amp;gt;$data = file_postupdate_standard_editor($data, &#039;textfield&#039;, $textfieldoptions, $context, &#039;mod_somemodule&#039;, &#039;somearea&#039;, $data-&amp;gt;id);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Real world examples are in mod/glossary/edit.php and mod/glossary/comment.php&lt;br /&gt;
&lt;br /&gt;
====Low level use====&lt;br /&gt;
&lt;br /&gt;
When using editor element you  need to preprocess and postprocess the data:&lt;br /&gt;
# detect if form was already submitted (usually means draft is area already exists) - &#039;&#039;file_get_submitted_draft_itemid()&#039;&#039;&lt;br /&gt;
# prepare draft file area, temporary storage of all files attached to the text - &#039;&#039;file_prepare_draft_area()&#039;&#039;&lt;br /&gt;
# convert encoded relative links to absolute links - &#039;&#039;file_prepare_draft_area()&#039;&#039;&lt;br /&gt;
# create form and set current data&lt;br /&gt;
# after submission the changed files must be merged back into original area - &#039;&#039;file_save_draft_area_files()&#039;&#039;&lt;br /&gt;
# absolute links have to be replaced by relative links - &#039;&#039;file_save_draft_area_files()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=====Replace old htmleditor with editor=====&lt;br /&gt;
&lt;br /&gt;
The file picker has been integrated with with TinyMCE to make the editor element. This new element should support all types on editors and should be able to switch them on-the-fly. Instances of the old htmleditor element in your forms should be replaced by the new editor element, this may need adding of new format and trusttext columns. For example:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;editor&#039;, &#039;entry&#039;, get_string(&#039;definition&#039;, &#039;glossary&#039;), null,&lt;br /&gt;
        array(&#039;maxfiles&#039; =&amp;gt; EDITOR_UNLIMITED_FILES));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The editor element can take following options: maxfiles, maxbytes, subdirs and changeformat. Please note that the embedded files is optional feature and is not expected be used everywhere.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: the editor element now includes text format option. You should no longer use the separate format element type.&lt;br /&gt;
&lt;br /&gt;
=====Prepare current data - text and files=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (empty($entry-&amp;gt;id)) {&lt;br /&gt;
  $entry = new object();&lt;br /&gt;
  $entry-&amp;gt;id = null;&lt;br /&gt;
  $entry-&amp;gt;definition = &#039;&#039;;&lt;br /&gt;
  $entry-&amp;gt;format = FORMAT_HTML;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$draftid_editor = file_get_submitted_draft_itemid(&#039;entry&#039;);&lt;br /&gt;
$currenttext = file_prepare_draft_area($draftid_editor, $context-&amp;gt;id, &#039;mod_glossary&#039;, &#039;entry&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039;=&amp;gt;true), $entry-&amp;gt;definition);&lt;br /&gt;
$entry-&amp;gt;entry = array(&#039;text&#039;=&amp;gt;$currenttext, &#039;format&#039;=&amp;gt;$entry-&amp;gt;format, &#039;itemid&#039;=&amp;gt;$draftid_editor);&lt;br /&gt;
&lt;br /&gt;
$mform-&amp;gt;set_data($entry);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If there are multiple files, they will share the same itemid.&lt;br /&gt;
&lt;br /&gt;
=====Obtain text, format and save draft files=====&lt;br /&gt;
&lt;br /&gt;
To retrieve editor content, you need to use following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($fromform = $mform-&amp;gt;get_data()) {&lt;br /&gt;
    // content of editor&lt;br /&gt;
    $messagetext = $fromform-&amp;gt;entry[&#039;text&#039;];&lt;br /&gt;
    // format of content&lt;br /&gt;
    $messageformat  = $fromform-&amp;gt;entry[&#039;format&#039;];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When a user selects a file using the file picker, the file is initially stored in a draft file area, and a URL is inserted into the HTML in the editor that lets the person editing the content (but no one else) see the file.&lt;br /&gt;
&lt;br /&gt;
When the user submits the form, we then need to save the draft files to the correct place in permanent storage. (Just like you have to call $DB-&amp;gt;update_record(&#039;tablename&#039;, $data); to have the other parts of the form submission stored correctly.)&lt;br /&gt;
&lt;br /&gt;
The save_files_from_draft_area function and replace absolute links with internal relative links do:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$messagetext = file_save_draft_area_files($draftid_editor, $context-&amp;gt;id, &#039;mod_glossary&#039;, &#039;entry&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039;=&amp;gt;true), $messagetext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
; $context-&amp;gt;id, &#039;component&#039;, &#039;proper_file_area&#039; and $entry-&amp;gt;id : correspond to the contextid, filearea and itemid columns in the [[Development:File_API#Table:_files|files table]].&lt;br /&gt;
; $messagetext : this is the message text. As the files are saved to the real file area, the URLs in this content are rewritten.&lt;br /&gt;
&lt;br /&gt;
All URLs in content that point to files managed to the File API are converted to a form that starts &#039;@@PLUGINFILE@@/&#039; before the content is stored in the database. That is what we mean by rewriting.&lt;br /&gt;
&lt;br /&gt;
== File serving==&lt;br /&gt;
&lt;br /&gt;
=== Convert internal relative links to absolute links ===&lt;br /&gt;
&lt;br /&gt;
Before text content is displayed to the user, any URLs in the &#039;@@PLUGINFILE@@/&#039; form in the content need to be rewritten to the real URL where the user can access the files. &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$messagetext = file_rewrite_pluginfile_urls($messagetext, &#039;pluginfile.php&#039;,&lt;br /&gt;
        $context-&amp;gt;id, &#039;mod_mymodule&#039;, &#039;proper_file_area&#039;, $itemid);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
; $messagetext : is the content containing the @@PLUGINFILE@@ URLs from the database.&lt;br /&gt;
; &#039;pluginfile.php&#039; : there are a number of different scripts that can serve files with different permissions checks. You need to specify which one to use.&lt;br /&gt;
; $context-&amp;gt;id, &#039;mod_mymodule&#039;, &#039;proper_file_area&#039;, $itemid : uniquely identifies the file area, as before.&lt;br /&gt;
&lt;br /&gt;
=== Implement file serving access control ===&lt;br /&gt;
&lt;br /&gt;
Attachments and embedded images should have the same access control like the text itself, in majority of cases these files are served using pluginfile.php. Access control is defined in &#039;&#039;module/lib.php&#039;&#039; file in function &#039;&#039;module_pluginfile()&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== File browsing support ==&lt;br /&gt;
Only owner of each file area is allowed to use low level File API function to access files, other parts of Moodle should use file browsing API.&lt;br /&gt;
&lt;br /&gt;
Activities may specify browsing support in own module/lib.php file by implementing functions module_get_file_areas() and module_get_file_info().&lt;br /&gt;
&lt;br /&gt;
== Upgrading your code ==&lt;br /&gt;
Here I will attempt to describe some simple steps you can take to upgrade your file-handling form elements from pre-2.0 code to 2.0. We will use the example of glossary, since it has been used above.&lt;br /&gt;
&lt;br /&gt;
=== Preparing your options ===&lt;br /&gt;
Unless you are happy with the defaults, you will need to define an array of options for each file-handling form element. You could define it at different places, but it&#039;s best to put it in one place and make the array(s) available to other files if they need it. In the majority of cases, this will be in a file like edit.php&lt;br /&gt;
&lt;br /&gt;
Previous code in mod/glossary/edit.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform =&amp;amp; new mod_glossary_entry_form(null, compact(&#039;cm&#039;, &#039;glossary&#039;, &#039;hook&#039;, &#039;mode&#039;, &#039;e&#039;, &#039;context&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$maxbytes = $course-&amp;gt;maxbytes; // Could also use $CFG-&amp;gt;maxbytes if you are not coding within a course context&lt;br /&gt;
$definitionoptions = array(&#039;subdirs&#039;=&amp;gt;false, &#039;maxfiles&#039;=&amp;gt;99, &#039;maxbytes&#039;=&amp;gt;$maxbytes, &#039;trusttext&#039;=&amp;gt;true, &#039;context&#039;=&amp;gt;$context);&lt;br /&gt;
$attachmentoptions = array(&#039;subdirs&#039;=&amp;gt;false, &#039;maxfiles&#039;=&amp;gt;99, &#039;maxbytes&#039;=&amp;gt;$maxbytes);&lt;br /&gt;
$mform = new mod_glossary_entry_form(null, array(&lt;br /&gt;
        &#039;current&#039;=&amp;gt;$entry, &lt;br /&gt;
        &#039;cm&#039;=&amp;gt;$cm, &lt;br /&gt;
        &#039;glossary&#039;=&amp;gt;$glossary,&lt;br /&gt;
        &#039;definitionoptions&#039;=&amp;gt;$definitionoptions, &lt;br /&gt;
        &#039;attachmentoptions&#039;=&amp;gt;$attachmentoptions));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note that the data being passed to the form constructor have changed also, but this is not part of the file API changes, I just include them to avoid confusion.&lt;br /&gt;
&lt;br /&gt;
These options are for the htmleditor (definition field) and the filemanager (attachment field). They are used by a file called edit_form.php.&lt;br /&gt;
&lt;br /&gt;
=== Element preparation ===&lt;br /&gt;
Before we look at this, however, we need to &amp;quot;prepare&amp;quot; the elements so that they can correctly display existing embedded images and attached files when you are editing a record instead of just creating one. So, let&#039;s take the code we&#039;ve got so far in edit.php and add to it:&lt;br /&gt;
&lt;br /&gt;
Currently upgraded code in edit.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform = new mod_glossary_entry_form(null, array(&lt;br /&gt;
        &#039;current&#039;=&amp;gt;$entry, &lt;br /&gt;
        &#039;cm&#039;=&amp;gt;$cm, &lt;br /&gt;
        &#039;glossary&#039;=&amp;gt;$glossary,&lt;br /&gt;
        &#039;definitionoptions&#039;=&amp;gt;$definitionoptions, &lt;br /&gt;
        &#039;attachmentoptions&#039;=&amp;gt;$attachmentoptions));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code with element preparation:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$entry = file_prepare_standard_editor($entry, &#039;definition&#039;, $definitionoptions, $context, &#039;mod_glossary&#039;, &#039;entry&#039;, $entry-&amp;gt;id);&lt;br /&gt;
$entry = file_prepare_standard_filemanager($entry, &#039;attachment&#039;, $attachmentoptions, $context, &#039;mod_glossary&#039;, &#039;attachment&#039;, $entry-&amp;gt;id);&lt;br /&gt;
$mform = new mod_glossary_entry_form(null, array(&lt;br /&gt;
        &#039;current&#039;=&amp;gt;$entry, &lt;br /&gt;
        &#039;cm&#039;=&amp;gt;$cm, &lt;br /&gt;
        &#039;glossary&#039;=&amp;gt;$glossary,&lt;br /&gt;
        &#039;definitionoptions&#039;=&amp;gt;$definitionoptions, &lt;br /&gt;
        &#039;attachmentoptions&#039;=&amp;gt;$attachmentoptions));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Things to note:&lt;br /&gt;
* $entry in this case is simply a stdClass object which may either represent a new glossary entry or an existing one.&lt;br /&gt;
* $entry-&amp;gt;id must be the unique identifier for the current object. If we are creating a new entry, it will be null, but in all cases it must be defined.&lt;br /&gt;
* These two functions (file_prepare_standard_editor and file_prepare_standard_filemanager) are shortcuts functions that take care of some of the tedious setting up for you, but they make a couple of assumptions:&lt;br /&gt;
*# You &#039;&#039;&#039;must&#039;&#039;&#039; name the form element as {element}_editor or {element}_filemanager (see next section)&lt;br /&gt;
*# You &#039;&#039;&#039;must&#039;&#039;&#039; have at least the following fields in the database: {element} and {element}summary, as described earlier in this documentation&lt;br /&gt;
&lt;br /&gt;
We can now look at the upgrades needed in the form definition file.&lt;br /&gt;
&lt;br /&gt;
=== Form definition ===&lt;br /&gt;
Previous code in mod/glossary/edit_form.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;htmleditor&#039;, &#039;definition&#039;, get_string(&#039;definition&#039;, &#039;glossary&#039;), array(&#039;rows&#039;=&amp;gt;20));&lt;br /&gt;
$mform-&amp;gt;setType(&#039;definition&#039;, PARAM_RAW);&lt;br /&gt;
$mform-&amp;gt;addRule(&#039;definition&#039;, null, &#039;required&#039;, null, &#039;client&#039;);&lt;br /&gt;
$mform-&amp;gt;setHelpButton(&#039;definition&#039;, array(&#039;writing&#039;, &#039;richtext&#039;), false, &#039;editorhelpbutton&#039;);&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;format&#039;);&lt;br /&gt;
// a bit further...&lt;br /&gt;
$this-&amp;gt;set_upload_manager(new upload_manager(&#039;attachment&#039;, true, false, $COURSE, false, 0, true, true, false));&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;file&#039;, &#039;attachment&#039;, get_string(&#039;attachment&#039;, &#039;forum&#039;));&lt;br /&gt;
$mform-&amp;gt;setHelpButton(&#039;attachment&#039;, array(&#039;attachment&#039;, get_string(&#039;attachment&#039;, &#039;glossary&#039;), &#039;glossary&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$definitionoptions = $this-&amp;gt;_customdata[&#039;definitionoptions&#039;];&lt;br /&gt;
$attachmentoptions = $this-&amp;gt;_customdata[&#039;attachmentoptions&#039;];&lt;br /&gt;
// a bit further...&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;editor&#039;, &#039;definition_editor&#039;, get_string(&#039;definition&#039;, &#039;glossary&#039;), null, $definitionoptions);&lt;br /&gt;
$mform-&amp;gt;setType(&#039;definition_editor&#039;, PARAM_RAW);&lt;br /&gt;
$mform-&amp;gt;addRule(&#039;definition_editor&#039;, get_string(&#039;required&#039;), &#039;required&#039;, null, &#039;client&#039;);&lt;br /&gt;
// a bit further...&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;filemanager&#039;, &#039;attachment_filemanager&#039;, get_string(&#039;attachment&#039;, &#039;glossary&#039;), null, $attachmentoptions);&lt;br /&gt;
$mform-&amp;gt;setHelpButton(&#039;attachment_filemanager&#039;, array(&#039;attachment2&#039;, get_string(&#039;attachment&#039;, &#039;glossary&#039;), &#039;glossary&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the following:&lt;br /&gt;
* The format element and the help button are no longer required for the HTML editor element&lt;br /&gt;
* The name of the form element needs to be changed by adding &#039;_editor&#039; or &#039;_manager&#039; to the original name. This is a naming convention that is used by a couple of functions we will look at shortly&lt;br /&gt;
&lt;br /&gt;
=== Handling submitted data ===&lt;br /&gt;
The final step is to handle the submitted data properly, i.e. retrieve the files and save them to disk, associating them with the record we have just created (a glossary entry in our example). This happens in edit.php:&lt;br /&gt;
&lt;br /&gt;
Previous code in edit.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Section that updates an entry:&lt;br /&gt;
$todb-&amp;gt;id = $e;&lt;br /&gt;
$dir = glossary_file_area_name($todb);&lt;br /&gt;
if ($mform-&amp;gt;save_files($dir) and $newfilename = $mform-&amp;gt;get_new_filename()) {&lt;br /&gt;
    $todb-&amp;gt;attachment = $newfilename;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Section that adds an entry:&lt;br /&gt;
if ($todb-&amp;gt;id = insert_record(&amp;quot;glossary_entries&amp;quot;, $todb)) {&lt;br /&gt;
    $e = $todb-&amp;gt;id;&lt;br /&gt;
    $dir = glossary_file_area_name($todb);&lt;br /&gt;
    if ($mform-&amp;gt;save_files($dir) and $newfilename = $mform-&amp;gt;get_new_filename()) {&lt;br /&gt;
        set_field(&amp;quot;glossary_entries&amp;quot;, &amp;quot;attachment&amp;quot;, $newfilename, &amp;quot;id&amp;quot;, $todb-&amp;gt;id);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// $todb was renamed to $entry, and the code was refactored &lt;br /&gt;
// so that the file-handling code is only used once for either an add or an update action.&lt;br /&gt;
// If an entry is being added, $DB-&amp;gt;insert() has already been called, so we have a valid $entry-&amp;gt;id&lt;br /&gt;
$entry = file_postupdate_standard_editor($entry, &#039;definition&#039;, $definitionoptions, $context, &#039;mod_glossary&#039;, &#039;entry&#039;, $entry-&amp;gt;id);&lt;br /&gt;
$entry = file_postupdate_standard_filemanager($entry, &#039;attachment&#039;, $attachmentoptions, $context, &#039;mod_glossary&#039;, &#039;attachment&#039;, $entry-&amp;gt;id);&lt;br /&gt;
// store the updated value values&lt;br /&gt;
$DB-&amp;gt;update_record(&#039;glossary_entries&#039;, $entry);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Things to note:&lt;br /&gt;
* If you are adding a new record, you will still need to call update_record after calling the file_postupdate* functions&lt;br /&gt;
&lt;br /&gt;
=== Gotchas ===&lt;br /&gt;
A few things to keep in mind:&lt;br /&gt;
* Make sure that you instantiate the moodle form before any call to $OUTPUT-&amp;gt;header()&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Development:File API]]&lt;br /&gt;
* [[Development:Using the file API]]&lt;br /&gt;
* [[Development:Repository API]]&lt;br /&gt;
* [[Development:Portfolio API]]&lt;br /&gt;
* MDL-14589 - File API Meta issue&lt;br /&gt;
&lt;br /&gt;
{{CategoryDeveloper}}&lt;br /&gt;
[[Category:Files]]&lt;br /&gt;
[[Category:Repositories]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Errors_FAQ&amp;diff=82726</id>
		<title>Errors FAQ</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Errors_FAQ&amp;diff=82726"/>
		<updated>2011-04-12T08:25:46Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* Fatal error allowed memory size exhausted. How do I increase my php memory limit? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Error: database connection failed==&lt;br /&gt;
&lt;br /&gt;
If you get errors like &amp;quot;database connection failed&amp;quot; or &amp;quot;could not connect to the database you specified&amp;quot;, here are some possible reasons and some possible solutions.&lt;br /&gt;
&lt;br /&gt;
* Your &#039;&#039;&#039;database server&#039;&#039;&#039; isn&#039;t installed or running. To check this for MySQL try typing the following command line&lt;br /&gt;
 $telnet database_host_name 3306&lt;br /&gt;
:You should get a cryptic response which includes the version number of the MySQL server. &lt;br /&gt;
* If you are attempting to run &#039;&#039;&#039;two instances of Moodle on different ports&#039;&#039;&#039;, use the ip address of the host (not localhost) in the $CFG-&amp;gt;dbhost setting, e.g. $CFG-&amp;gt;dbhost = 127.0.0.1:3308.&lt;br /&gt;
* You don&#039;t have the &#039;&#039;&#039;PHP mysql or postgresql extensions&#039;&#039;&#039; installed (please refer to FAQ re. whether PHP is installed).&lt;br /&gt;
* You haven&#039;t created a &#039;&#039;&#039;Moodle database and assigned a user&#039;&#039;&#039; with the correct privileges to access it. &lt;br /&gt;
* The &#039;&#039;&#039;Moodle database settings&#039;&#039;&#039; are incorrect. The database name, database user or database user password in your Moodle configuration file &#039;&#039;config.php&#039;&#039; are incorrect. Use phpMyAdmin to set up and check your MySQL installation.&lt;br /&gt;
* Check that there are &#039;&#039;&#039;no apostrophes or non-alphabetic letters&#039;&#039;&#039; in your MySQL username or password.&lt;br /&gt;
* You are using MySQL version 4.1 or higher but the PHP MySQL extension is pre-4.1 (check in your phpinfo output). In this case the &#039;&#039;&#039;default password hashing algorithm&#039;&#039;&#039; is incompatible with that available in the PHP mysql extension versions 4.x.x. Use these MySQL commands to change the passwords to the old format:&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt;SET PASSWORD FOR &#039;root&#039;@&#039;localhost&#039; = OLD_PASSWORD(&#039;password&#039;);&lt;br /&gt;
 mysql&amp;gt;SET PASSWORD FOR &#039;moodleuser&#039;@&#039;localhost&#039; = OLD_PASSWORD(&#039;password&#039;);&lt;br /&gt;
&lt;br /&gt;
:Also, consider upgrading your PHP MySQL extension. See [http://dev.mysql.com/doc/mysql/en/old-client.html this MySQL document] for further information on how to deal with this problem.&lt;br /&gt;
* You are using Fedora core 3 or some other Linux system with &#039;&#039;&#039;SELinux installed&#039;&#039;&#039; and enabled. See the following URL for information on how to disable SELinux: http://fedora.redhat.com/projects/selinux/ If you don&#039;t want to disable SELinux, you have to allow httpd process to create network connections:&lt;br /&gt;
&lt;br /&gt;
 setsebool httpd_can_network_connect true&lt;br /&gt;
 &lt;br /&gt;
* Mac OSX users -- if you are running MySQL on a Mac OSX, try changing &#039;&#039;&#039;$CFG-&amp;gt;dbhost&#039;&#039;&#039; from &#039;localhost&#039; to &#039;127.0.0.1&#039;&lt;br /&gt;
&#039;&#039;&#039;See also&#039;&#039;&#039;: MySQL page on [http://dev.mysql.com/doc/refman/5.0/en/common-errors.html common errors] which lists several possible scenarios for connection failure, with advice on how to fix the problems.&lt;br /&gt;
&lt;br /&gt;
==I can&#039;t log in with message &amp;quot;Please verify that the current setting of session.save_path is correct&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
This error occurs when PHP is having problems saving its session files. You may also see these other error messages displayed on the screen or in your log files:&lt;br /&gt;
&lt;br /&gt;
 Warning: Unknown: open(some-path/sessions/sess_acbf942a7399db3489ffa910e35d5242, O_RDWR)&lt;br /&gt;
 failed: Permission denied (13) in Unknown on line 0&lt;br /&gt;
&lt;br /&gt;
 Warning: Unknown(): open(some-path/sessions/sess_acbf942a7399db3489ffa910e35d5242, O_RDWR) &lt;br /&gt;
 failed: No space left on device (28) in Unknown on line 0&lt;br /&gt;
&lt;br /&gt;
 Warning: Unknown: Failed to write session data (files). Please verify that the current &lt;br /&gt;
 setting of session.save_path is correct (some-path/sessions) in Unknown on line 0 &lt;br /&gt;
&lt;br /&gt;
To temporarily bypass these errors, &#039;&#039;&#039;use database sessions&#039;&#039;&#039; by editing your [[Configuration_file | moodle configuration file]] and adding this line:&lt;br /&gt;
&lt;br /&gt;
 $CFG-&amp;gt;dbsessions = true;&lt;br /&gt;
&lt;br /&gt;
Database sessions may overload your mysql database and are not ideal in a shared hosting environment, so if this solves the problem, you can start fixing the problem as follows:&lt;br /&gt;
* Check &#039;&#039;&#039;access rights&#039;&#039;&#039;. The session.save_path should be accessible by the apache user. Try this command:&lt;br /&gt;
&lt;br /&gt;
 chown -R apache:apache some-path/sessions&lt;br /&gt;
&lt;br /&gt;
:This assumes that &#039;apache&#039; is the name of the user your webserver runs under - it could also be &#039;nobody&#039;.&lt;br /&gt;
* Check the &#039;&#039;&#039;permissions&#039;&#039;&#039; to the directory that PHP is trying to save to (session.save_path = some-path/sessions). Set the permissions initially to 0777 (everyone read, write, execute) with this command:&lt;br /&gt;
&lt;br /&gt;
 chmod -R 0777 some-path/sessions&lt;br /&gt;
&lt;br /&gt;
:If this fixes the problem, reduce the permissions (700 is recommended).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;See also&#039;&#039;&#039;: Session problems can be specific to your server environment. As an example, see [http://moodle.org/mod/forum/discuss.php?d=55925#254596 this forum discussion] about session problems with Lycos hosting.&lt;br /&gt;
&lt;br /&gt;
==Error: A server error that affects your login session was detected==&lt;br /&gt;
If restarting your browser and logging in again to your Moodle site does not work, see the Using Moodle [http://moodle.org/mod/forum/discuss.php?d=73716 forum discussion about this error message].&lt;br /&gt;
&lt;br /&gt;
If this was received at a Moodle.org site, the site could be in the process of updating.  Please try the suggestion and/or wait and try it again. Or report it in [[Tracker]].&lt;br /&gt;
&lt;br /&gt;
==Error: Failed opening required &#039;/web/moodle/lib/setup.php&#039;==&lt;br /&gt;
&lt;br /&gt;
In your &#039;&#039;config.php&#039;&#039;, the setting that you use for the dirroot variable must be the complete path from the root of your server&#039;s hard drive.&lt;br /&gt;
&lt;br /&gt;
Sometimes people only use the path from their home directory, or relative to the root of the web server directory.&lt;br /&gt;
&lt;br /&gt;
==Any text I add with an apostrophe (&#039;) or a quote (&amp;quot;) causes errors or comes up with a slash added==&lt;br /&gt;
&lt;br /&gt;
Problems caused by apostrophes are caused by incorrect &amp;quot;magic quotes&amp;quot; settings. Moodle requires the following settings in the php.ini file (which are usually the default):&lt;br /&gt;
&lt;br /&gt;
 magic_quotes_runtime = Off&lt;br /&gt;
&lt;br /&gt;
Starting in 2.0 it is strongly recommended to disable magic quotes completely&lt;br /&gt;
&lt;br /&gt;
  magic_quotes_gpc = Off&lt;br /&gt;
&lt;br /&gt;
Please see [[Installing Moodle]] for more details.&lt;br /&gt;
&lt;br /&gt;
If you are using [[Debian_GNU/Linux_installation|Debian]] then the problem might be in the version of PHP that you have installed. Have a look at this [http://tracker.moodle.org/browse/MDL-9691 bug report ]  to see if it matches your situation.&lt;br /&gt;
&lt;br /&gt;
==My pages show fatal errors such as : Parse error, call to undefined function: get_string()==&lt;br /&gt;
&lt;br /&gt;
If you see errors like:&lt;br /&gt;
&lt;br /&gt;
 Parse error: parse error, unexpected T_VARIABLE in /path/to/moodle/config.php on line 94 &lt;br /&gt;
 Fatal error: Call to undefined function: get_string() in /path/to/moodle/mod/resource/lib.php&lt;br /&gt;
 on line 11&lt;br /&gt;
&lt;br /&gt;
then you have probably left out a semi-colon or closing quote from a line in &#039;&#039;config.php&#039;&#039; (previous to line 94).&lt;br /&gt;
&lt;br /&gt;
Another possibility is that you edited &#039;&#039;config.php&#039;&#039; in a program like Word and saved it as a HTML web page, instead of using a plain text editor like Notepad.&lt;br /&gt;
&lt;br /&gt;
Another thing to check, particularly if you are using 3rd party modules or plugins, is whether any of the php scripts use short open tags (&amp;lt;? ?&amp;gt;) instead of proper ones (&amp;lt;?php ?&amp;gt;). Short tags are bad for various reasons, so first contact the author of that extension to tell them about the problem. Then either replace short tags with conventional ones, or set this line in php.ini:&lt;br /&gt;
&lt;br /&gt;
 short_open_tag = On&lt;br /&gt;
&lt;br /&gt;
You should never find short tags in core moodle code. If you do, please file a bug in the bug tracker.&lt;br /&gt;
&lt;br /&gt;
==Serious Error! Could not set up the site!==&lt;br /&gt;
&lt;br /&gt;
Please refer to the Using Moodle forum discussion [http://moodle.org/mod/forum/discuss.php?d=32071 Serious Error! Could not set up the site!].&lt;br /&gt;
&lt;br /&gt;
==When I go to the admin page, I get told to make dirroot blank!==&lt;br /&gt;
&lt;br /&gt;
If you see errors like this:&lt;br /&gt;
&lt;br /&gt;
 Please fix your settings in config.php: &lt;br /&gt;
 You have: $CFG-&amp;gt;dirroot = &amp;quot;/home/users/fred/public_html/moodle&amp;quot;; &lt;br /&gt;
 but it should be: $CFG-&amp;gt;dirroot = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
then you have encountered a small bug that occurs on some servers. The problem is with the error-checking mechanism, not with your actual path. To fix it, find this line (line 66) in the file &#039;&#039;admin/index.php&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
 if ($dirroot != $CFG-&amp;gt;dirroot) {&lt;br /&gt;
&lt;br /&gt;
and change it to this:&lt;br /&gt;
&lt;br /&gt;
 if (!empty($dirroot) and $dirroot != $CFG-&amp;gt;dirroot) {&lt;br /&gt;
&lt;br /&gt;
==When trying to add a resource I receive error messages==&lt;br /&gt;
&lt;br /&gt;
Assuming you are using Apache, then it&#039;s quite likely that your setting in &#039;&#039;config.php&#039;&#039; for &amp;lt;code&amp;gt;$CFG-&amp;gt;wwwroot&amp;lt;/code&amp;gt; is different from the actual URL you are using to access the site. Also try turning off the &#039;&#039;secureforms&#039;&#039; variable in the security section of Administration &amp;gt;&amp;gt; Configuration &amp;gt;&amp;gt; [[admin/config|Variables]].&lt;br /&gt;
&lt;br /&gt;
==Why do I keep getting error messages about &amp;quot;headers already sent&amp;quot;?==&lt;br /&gt;
&lt;br /&gt;
If you see errors like this:&lt;br /&gt;
&lt;br /&gt;
 Warning: Cannot add header information - headers already sent by &lt;br /&gt;
 (output started at /webs/moodle/config.php:87) in /webs/moodle/lib/moodlelib.php &lt;br /&gt;
 on line 1322 &lt;br /&gt;
&lt;br /&gt;
 Warning: Cannot add header information - headers already sent by &lt;br /&gt;
 (output started at /webs/moodle/config.php:87) in /webs/moodle/lib/moodlelib.php &lt;br /&gt;
 on line 1323 &lt;br /&gt;
&lt;br /&gt;
 Warning: Cannot add header information - headers already sent by &lt;br /&gt;
 (output started at /webs/moodle/config.php:87) in /webs/moodle/login/index.php &lt;br /&gt;
 on line 54&lt;br /&gt;
&lt;br /&gt;
you have blank lines or spaces after the final &amp;lt;code&amp;gt;?&amp;gt;&amp;lt;/code&amp;gt; in your &#039;&#039;config.php&#039;&#039; file. Sometimes text editors add these - for example Notepad on Windows - so you may have to try a different text editor to remove these spaces or blank lines completely.&lt;br /&gt;
&lt;br /&gt;
==Error: &amp;quot;500:Internal Server Error&amp;quot;==&lt;br /&gt;
There are several possible causes for this error:&lt;br /&gt;
&lt;br /&gt;
1. &#039;&#039;&#039;Syntax error&#039;&#039;&#039;: There is a syntax error in your .htaccess or httpd.conf files. The way in which directives are written [http://httpd.apache.org/docs/1.3/howto/htaccess.html#when differs] depending on which file you are using. You can test for configuration errors in your Apache files using the command:&lt;br /&gt;
 #apachectl configtest&lt;br /&gt;
&lt;br /&gt;
2. &#039;&#039;&#039;PHPsuexec&#039;&#039;&#039;: Your server does not support .htaccess files, especially if it is running PHPsuexec, which is an Apache module used for increasing the security of a site on a hosted system. In this situation:&lt;br /&gt;
&lt;br /&gt;
- you may also see a 403: Forbidden error.&lt;br /&gt;
&lt;br /&gt;
- the webserver executes under your own username and all files have a maximum permissions level of 755. Check that this is set for your Moodle directory in your control panel or (if you have access to the shell) use this command:&lt;br /&gt;
 #chmod -R 755 moodle&lt;br /&gt;
&lt;br /&gt;
- use a PHP.INI file instead of a .htaccess in the directory where the Moodle PHP script is being executed. For example: if you are receiving a memory exhausted error when your server is executing the file moodle/admin/cron.php, use a PHP.INI file to change your memory_limit and copy it to the moodle/admin directory. Remember that for PHP4, PHP.INI files are per-directory, so you&#039;ll need to copy it to each sub-directory. If you are using PHP5 or higher on a shared host, check with your host on whether they support custom PHP.INI files, and how to create them. The syntax used in a PHP.INI file is different from a .htaccess file and you need to take out php_value/php_flag at the beginning of the line and use an equals sign to assign a value, e.g.&lt;br /&gt;
 php_value memory_limit 128M &amp;lt;-- .htaccess&lt;br /&gt;
 memory_limit = 128M         &amp;lt;-- php.ini equivalent &lt;br /&gt;
&lt;br /&gt;
3. &#039;&#039;&#039;Incompatible directive&#039;&#039;&#039;: You may have a directive in your .htaccess or httpd.conf files which are not compatible with your web server version. Check your webserver documentation.&lt;br /&gt;
&lt;br /&gt;
==Error &amp;quot;403: Forbidden&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
Check your webserver configuration. See also the section above &amp;quot;500:Internal Server Error&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Fatal error allowed memory size exhausted. How do I increase my php memory limit?==&lt;br /&gt;
You will sometimes see an error message something like this:&lt;br /&gt;
 Fatal error: Allowed memory size of 67108864 bytes exhausted &lt;br /&gt;
 (tried to allocate xx bytes) in /var/www/moodle/yyyy.php&lt;br /&gt;
This error means that the php memory_limit value is not enough for the php script. The memory_limit value is the &amp;quot;allowed memory size&amp;quot; - 64M in the example above (67108864 bytes / 1024 = 65536 KB. 65536 KB / 1024 = 64 MB). You will need to increase the php memory_limit value until this message is not shown anymore. There are two methods of doing this.&lt;br /&gt;
*On a hosted installation, add the following line to your .htaccess file (or create one in the moodle directory if it does not already exist):&lt;br /&gt;
 php_value memory_limit &amp;lt;value&amp;gt;M&lt;br /&gt;
 Example: php_value memory_limit 40M&lt;br /&gt;
*If you have your own server with shell access, edit your php.ini file (make sure it&#039;s the correct one by checking in your phpinfo output) as follows:&lt;br /&gt;
 memory_limit &amp;lt;value&amp;gt;M&lt;br /&gt;
 Example: memory_limit 40M&lt;br /&gt;
* For later versions of Moodle you could be looking at figures in the region of 512M for all functions to work properly (backup and restore are particularly memory hungry). It is sensible to monitor the memory usage on your server if using these large settings.&lt;br /&gt;
Remember that you need to restart your web server to make changes to php.ini effective. An alternative is to disable the memory_limit by using the command &#039;&#039;memory_limit 0&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Error: &amp;quot;Could not create guest user record!&amp;quot;==&lt;br /&gt;
&lt;br /&gt;
Most likely the database table mdl_user needs repairing. This may be done as follows using phpMyAdmin:&lt;br /&gt;
&lt;br /&gt;
# Click the SQL tab.&lt;br /&gt;
# In the &amp;quot;Run SQL query/queries on database moodle&amp;quot; field type &amp;lt;code&amp;gt;REPAIR TABLE mdl_user&amp;lt;/code&amp;gt;&lt;br /&gt;
# Click the Go button.&lt;br /&gt;
&lt;br /&gt;
==Error: &amp;quot;Your session has timed out. Please login again.&amp;quot;==&lt;br /&gt;
&lt;br /&gt;
Please do one/all of the following:&lt;br /&gt;
* Try deleting cookies manually from your browser and close it down, then access your site again. Sometimes this clears up the problem.&lt;br /&gt;
* Check that your &#039;&#039;moodledata/sessions&#039;&#039; directory has write permissions. When you access Moodle a new file should be created there.&lt;br /&gt;
* If you are running two versions of Moodle on the same computer, set a cookie prefix in &#039;&#039;Administration &amp;gt; Server &amp;gt; [[Session handling]]&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The discussion [http://moodle.org/mod/forum/discuss.php?d=46580 Your session has timed out. Please login again] has further suggested solutions.&lt;br /&gt;
&lt;br /&gt;
==How can I fix just one bug, without upgrading my whole site?==&lt;br /&gt;
&lt;br /&gt;
Suppose:&lt;br /&gt;
* You are running an older Moodle version.&lt;br /&gt;
* You are experiencing a particular bug.&lt;br /&gt;
* You have searched in the [http://tracker.moodle.org/ tracker], and found that your problem is MDL-abc, and that it has been fixed in the latest version.&lt;br /&gt;
* For some reason, you cannot upgrade your whole site, even though the latest version probably has security fixes.&lt;br /&gt;
&lt;br /&gt;
Then, how can you get the fix for just this one bug, without upgrading your whole site? Well, if you are prepared to manually patch the code, you can probably get this information from the tracker. Please see [[How to fix just one bug without upgrading|this guide]].&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[:Category:Error]] for a list of Moodle error pages. &lt;br /&gt;
&lt;br /&gt;
[[Category:FAQ]]&lt;br /&gt;
[[Category:Error]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Development:Themes_2.0&amp;diff=82576</id>
		<title>Development:Themes 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Development:Themes_2.0&amp;diff=82576"/>
		<updated>2011-04-05T15:05:41Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: using image file extensions break pix_url()&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}{{Moodle 2.0}}Welcome to the new world of themes within Moodle 2.0!&lt;br /&gt;
&lt;br /&gt;
This document explains how themes work in Moodle and is intended to help you create or modify most themes for Moodle 2.0.&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Moodle themes are responsible for much of the &amp;quot;look&amp;quot; of a Moodle site.  They provide the CSS for colours, layouts, fonts and so on, and can also change the structural XHTML code below that.  &lt;br /&gt;
&lt;br /&gt;
A theme can either contain all the definitions (completely stand alone) or it can extend an existing theme with one or more customizations. &lt;br /&gt;
&lt;br /&gt;
Most theme developers use the second method and simply add a few new CSS or layout definitions to their new theme. If a definition or element is not found in the new theme, it looks to the &amp;quot;parent&amp;quot; (or up the hierarchy of themes) to find one.  It an easy way to achieve just about any look you want for a theme.&lt;br /&gt;
&lt;br /&gt;
==What&#039;s new in 2.0==&lt;br /&gt;
&lt;br /&gt;
The theme system was completely redesigned in Moodle 2.0.  Known issues have been addressed and new features have been added to meet community requests.&lt;br /&gt;
&lt;br /&gt;
Unfortunately it was not possible to maintain backward compatibility, so all Moodle 1.x themes need to be recreated for Moodle 2.0.&lt;br /&gt;
&lt;br /&gt;
Major changes include:&lt;br /&gt;
* Clearer and more consistent CSS classes and IDs throughout all pages in Moodle&lt;br /&gt;
* Introduction of layout files (templates) describing overall layout HTML for many different types of pages in Moodle.&lt;br /&gt;
* Introduction of renderers, which produce the smaller &amp;quot;parts&amp;quot; of a HTML page.  Advanced themes can choose to override these too if they choose.&lt;br /&gt;
* Introduction of standard methods for adding Javascript to themes.&lt;br /&gt;
* Easier control over icons and images in Moodle.&lt;br /&gt;
* The old &amp;quot;standard&amp;quot; theme has been split into two themes:&lt;br /&gt;
**&#039;&#039;&#039;base&#039;&#039;&#039; - contains absolutely basic layout, and&lt;br /&gt;
**&#039;&#039;&#039;standard&#039;&#039;&#039; - which adds CSS to the base theme to make it look like the old standard theme.&lt;br /&gt;
* Performance tuning: In normal production mode CSS files are combined into a single optimised file, and both CSS and JavaScript files are minimised to ensure there are no wasted connections or traffic.  Files are heavily cached, but also versioned, so that users never need to clear their caches.&lt;br /&gt;
&lt;br /&gt;
==The structure of a theme==&lt;br /&gt;
&lt;br /&gt;
Some important things to know when building good themes:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;config.php&#039;&#039;&#039; - this file is required in every theme.  It defines configuration settings and definitions required to make the theme work in Moodle. These include theme, file, region, default region and options. &lt;br /&gt;
# &#039;&#039;&#039;Layouts and layout files&#039;&#039;&#039; -  in config.php there is one definition for each page type (see [[#theme_layouts_table|Appendix A: Theme layouts]] for a list of over 12 types).  Each page type definition tells Moodle which layout file will be used, what block regions this page type should display and so on.  The layout file contains the HTML and the minimum PHP required to display basic structure of pages. (If you know Moodle 1.9, it&#039;s like a combination of header.html and footer.html).&lt;br /&gt;
# &#039;&#039;&#039;The base theme&#039;&#039;&#039; - is not intended to be used for production sites.  It sets up the simplest possible generic layout and includes only CSS essential to that layout &#039;&#039;or&#039;&#039; to Moodle as a whole.  It tries not to make any unnecessary rules and makes as few assumptions as possible.  It&#039;s the perfect base on which to start designing a theme, as there are very few colours, borders, margins, and alignments to override.  You can just start adding what you need.&lt;br /&gt;
&lt;br /&gt;
===Files and folders===&lt;br /&gt;
A theme&#039;s files are placed in a folder with under moodle/theme folder and have subfolders. They are laid out like this:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Directory&lt;br /&gt;
! File&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| /config.php&lt;br /&gt;
| Contains all of the configuration and definitions for each theme&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| /lib.php &lt;br /&gt;
| Contains speciality classes and functions that are used by theme&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| /renderers.php &lt;br /&gt;
| Contains any custom renderers for the theme.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| /settings.php &lt;br /&gt;
| Contains custom theme settings. These local settings are defined by the theme allowing the theme user to easily alter something about the way it looks or operates. (eg a background colour, or a header image)&lt;br /&gt;
|-&lt;br /&gt;
| /javascript/ &lt;br /&gt;
| &lt;br /&gt;
| All specialty JavaScript files the theme requires should be located in here.&lt;br /&gt;
|-&lt;br /&gt;
| /lang/ &lt;br /&gt;
| &lt;br /&gt;
| Any special language files the theme requires should be located in here.&lt;br /&gt;
|-&lt;br /&gt;
| /layout/ &lt;br /&gt;
| &lt;br /&gt;
| Contains the layout files for the theme.&lt;br /&gt;
|-&lt;br /&gt;
| /pix/ &lt;br /&gt;
| &lt;br /&gt;
| Contains any images the theme makes use of either in CSS or in the layout files.&lt;br /&gt;
|-&lt;br /&gt;
|  /pix&lt;br /&gt;
| /favicon.ico &lt;br /&gt;
| The favicon to display for this theme.&lt;br /&gt;
|-&lt;br /&gt;
| /pix&lt;br /&gt;
| /screenshot.jpg &lt;br /&gt;
| A screenshot of the theme to be displayed in on the theme selection screen.&lt;br /&gt;
|-&lt;br /&gt;
| /style &lt;br /&gt;
| &lt;br /&gt;
| Default location for CSS files.&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|/*.css&lt;br /&gt;
|CSS files the theme requires&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
There are also several other places that stylesheets can be included from (see the CSS how and why section below).&lt;br /&gt;
&lt;br /&gt;
==Theme options==&lt;br /&gt;
All theme options are set within the config.php file for the theme.  The settings that are most used are: parents, sheets, layouts, and javascripts. Have a look at the &#039;&#039;&#039;[[#theme_options_table|theme options table]]&#039;&#039;&#039; for a complete list of theme options which include lesser used specialised or advanced settings.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Basic theme config example===&lt;br /&gt;
Lets have a look at a basic theme configuration file and the different bits that make it up:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;name = &#039;newtheme&#039;;&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;parents = array(&lt;br /&gt;
    &#039;base&#039;&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&lt;br /&gt;
    &#039;admin&#039;,&lt;br /&gt;
    &#039;blocks&#039;,&lt;br /&gt;
    &#039;calendar&#039;,&lt;br /&gt;
    &#039;course&#039;,&lt;br /&gt;
    &#039;grade&#039;,&lt;br /&gt;
    &#039;message&#039;,&lt;br /&gt;
    &#039;question&#039;,&lt;br /&gt;
    &#039;user&#039;&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;theme&#039; =&amp;gt; &#039;newtheme&#039;,&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;standard&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;theme&#039; =&amp;gt; &#039;newtheme&#039;,&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    )&lt;br /&gt;
    //.......&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;javascripts_footer = array(&lt;br /&gt;
    &#039;navigation&#039;&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Basic theme example settings explained===&lt;br /&gt;
First up you will notice everything is added to $THEME. This is the theme&#039;s configuration object, it is created by Moodle using default settings and is then updated by whatever settings you add to it.&lt;br /&gt;
&lt;br /&gt;
The first setting, $THEME-&amp;gt;name is the theme&#039;s name. This should simply be whatever your theme&#039;s name is, most likely whatever you named your theme directory.&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;parents defines the themes that the theme will extend. In this case it is extending only the base theme.&lt;br /&gt;
&lt;br /&gt;
After this is the $THEME-&amp;gt;sheets array containing the names of the CSS stylesheets to include for this theme. Note that it is just the name of the stylesheet and does not contain the directory or the file extension. Moodle assumes that the theme&#039;s stylesheets will be located in the styles directory of the theme and have .css as an extension.&lt;br /&gt;
&lt;br /&gt;
Next we see the $THEME-&amp;gt;layouts definition. In this example, two layouts have been defined to override the layouts from the base theme. For more information see the [[#Layouts|layouts]] section below.&lt;br /&gt;
&lt;br /&gt;
The final setting is to include a JavaScript file, as $THEME-&amp;gt;javascripts_footer. Much like stylesheets, you only need to provide the files name. Moodle will assume it is in your themes JavaScript directory and be a .js file.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note&#039;&#039;&#039;&#039;&#039;: When you first begin writing themes, make sure you take a look at the configuration files of the other themes that get shipped with Moodle. You will get a good picture of how everything works, and what is going on in a theme, simply by reading it and taking notice of what it is including or excluding.&lt;br /&gt;
&lt;br /&gt;
==CSS==&lt;br /&gt;
===Locations of CSS files===&lt;br /&gt;
First lets look at where CSS can be included from within Moodle:&lt;br /&gt;
; \theme\themename\styles\*.css : This is the default location for all of the stylesheets that are used by a theme and the place which should be used by a theme designer.&lt;br /&gt;
&lt;br /&gt;
New theme developers should note that the order in which CSS files are found and included creates a hierarchy.  This order ensures that the rules, within a theme&#039;s style sheets, take precedence over identical rules in other files that may have been introduced before.  This can both extend another files definitions (see parent array in the config file) and also ensures that the current theme&#039;s CSS rules/definitions have the last say.&lt;br /&gt;
&lt;br /&gt;
There are other locations that can be used (although very rarely) to include CSS in a page. A developer of a php file can manually specify a stylesheet from anywhere within Moodle, like the database. Usually, if code is doing this, it is because there is a non-theme config or plugin setting that contains information requires special CSS information.  As a theme designer you should be aware of, but not have to worry about, these locations of CSS files.  Here are some examples:&lt;br /&gt;
&lt;br /&gt;
; {pluginpath}\styles.css e.g. \block\blockname\styles.css or \mod\modname\styles.css : Every plugin can have its own styles.css file. This file should only contain the required CSS rules for the module and should not add anything to the look of the plugin such as colours, font sizes, or margins other than those that are truly required.&amp;lt;br /&amp;gt;Theme specific styles for a plugin should be located within the themes styles directory.&lt;br /&gt;
; {pluginpath}\styles_themename.css : This should only ever be used by plugin developers. It allows them to write CSS that is designed for a specific theme without having to make changes to that theme. You will notice that this is never used within Moodle and is designed to be used only by contributed code.&lt;br /&gt;
&lt;br /&gt;
As theme designers, we will only use the first method of introducing CSS: adding rules to a stylesheet file located in the themes styles directory.&lt;br /&gt;
&lt;br /&gt;
===Moodle&#039;s core CSS organisation===&lt;br /&gt;
The next thing to look at is the organisation of CSS and rules within a theme. Although as a theme designer it is entirely up to you as to how you create and organise your CSS. Please note that within the themes provided in the standard install by Moodle there is a very clear organisation of CSS.&lt;br /&gt;
&lt;br /&gt;
First is the  pagelayout.css file. This contains the CSS required to give the layouts their look and feel.  It doesn&#039;t contain any rules that affect the content generated by Moodle.&lt;br /&gt;
&lt;br /&gt;
Next is the core.css file. If you open up core you will notice that it contains all manner of general (usually simple) rules that don&#039;t relate to a specific section of Moodle but to Moodle as a whole.&lt;br /&gt;
&lt;br /&gt;
There can also be rules that relate to specific sections.  However, this is done only when there are only a handful of rules for that section. These small clusters of rules are grouped together and separated by comments identifying for which section each relates.&lt;br /&gt;
&lt;br /&gt;
Finally there are all the other CSS files, you will notice that there is a file for each section of Moodle that has a significant collection of rules.&lt;br /&gt;
&lt;br /&gt;
:For those who are familiar with Moodle 1.9 theme&#039;s, this organisation will be a big change. In 1.9, CSS was organised by its nature (for example: colours, layout, other).&lt;br /&gt;
&lt;br /&gt;
===How to write effective CSS rules within Moodle===&lt;br /&gt;
In Moodle 2.0, writing good CSS rules is an incredibly important.&lt;br /&gt;
&lt;br /&gt;
Due to performance requirements and browser limitations, all of the CSS files are combined into a single CSS file that gets included every time. This means that rules need to be written in such a way as to minimise the chances of a collision leading to unwanted styles being applied. Whilst writing good CSS is something most designers strive for we have implemented several new body classes and put more emphasis on developers for using classes more appropriately.&lt;br /&gt;
&lt;br /&gt;
====The body tag====&lt;br /&gt;
As of Moodle 2.0 the ID tag that gets applied to the body will always be a representation of the URI. For example if you are looking at a forum posting and the URI is &#039;/mod/forum/view.php&#039; then the body tags ID will be &#039;#page-mod-forum-view&#039;.&lt;br /&gt;
&lt;br /&gt;
As well as the body&#039;s ID attribute the URI is also exploded to form several CSS classes that get added to the body tag, so in the above example &#039;/mod/forum/view&#039; you would end up with the following classes being added to the body tag &#039;.path-mod&#039;, &#039;.path-mod-forum&#039;. Note that &#039;.path-mod-forum-view&#039; is not added as a class, this is intentionally left out to lessen confusion and duplication as rules can relate directly to the page by using the ID and do not require the final class.&lt;br /&gt;
&lt;br /&gt;
The body ID and body classes described above will form the bread and butter for many of the CSS rules you will need to write for your theme, however there are also several other very handy classes that get added to the body tag that will be beneficial to you once you start your journey down the rabbit hole that is themeing. Some of the more interesting classes are listed below.&lt;br /&gt;
&lt;br /&gt;
* If JavaScript is enabled then &#039;jsenabled&#039; will be added as a class to the body tag allowing you to style based on JavaScript being enabled or not.&lt;br /&gt;
* Either &#039;dir-rtl&#039; or &#039;dir-ltr&#039; will be added to the body as a class depending on the direction of the language pack: rtl = right to left, ltr = left to right. This allows you to determine your text-alignment based on language if required.&lt;br /&gt;
* A class will be added to represent the language pack currently in use, by default en_utf8 is used by Moodle and will result in the class &#039;lang-en_utf8&#039; being added to the body tag.&lt;br /&gt;
* The wwwroot for Moodle will also be converted to a class and added to the body tag allowing you to stylise your theme based on the URL through which it was reached. e.g. http://sam.moodle.local/moodle/ will become &#039;.sam-moodle-local—moodle&#039;&lt;br /&gt;
* If the current user is not logged then &#039;.notloggedin&#039; will be added to the body tag.&lt;br /&gt;
&lt;br /&gt;
What does all of this look like in practise? Well using the above example /mod/forum/view.php you would get at least the following body tag:&lt;br /&gt;
&amp;lt;code html4strict&amp;gt;&amp;lt;body id=”page-mod-forum-view” class=”path-mod path-mod-forum” /&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Writing your rules====&lt;br /&gt;
The best use of body ids and classes and writing selectors will reduce problems.&lt;br /&gt;
&lt;br /&gt;
There are many specific classes used within Moodle. We try to put them everywhere where anyone may want to apply their own styles. It is important to recognise that no one developer can be aware of the all of the class names that have been used all throughout Moodle, let alone within all of the different contributed bits and pieces available for Moodle.  It is up to the theme developer to write good rules and minimise the chances of a collision between rules because in this case good CSS is FAR more effective.&lt;br /&gt;
&lt;br /&gt;
When starting to write rules make sure that you have a good understanding of where you want those rules to be applied, it is a good idea to make the most of the body classes mentioned above.&lt;br /&gt;
If you want to write a rule for a specific page make use of the body tag&#039;s ID, e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;#page-mod-forum-view .forumpost {border:1px solid orange;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to write a rule that will be applied all throughout the forum.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;.path-mod-forum .forumpost {border:1px solid orange;}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The other very important thing to take into consideration is the structure leading up to the tag you want to style. Browsers apply conflicting styles with priority on the more specific selectors. It can be very beneficial to keep this in mind and write full selectors that rely on the structure of the tags leading to the tag you wish to style.&lt;br /&gt;
&lt;br /&gt;
By making use of body id&#039;s and classes and writing selectors to take into account the leading structure you can greatly minimise the chance of a collision both with Moodle now and in the future.&lt;br /&gt;
&lt;br /&gt;
==Layouts==&lt;br /&gt;
All themes are required to define the layouts they wish to be responsible for as well as create; however, many layout files are required by those layouts. If the theme is overriding another theme then it is a case of deciding which layouts this new theme should override. If the theme is a completely fresh start then you will need to define a layout for each of the different possibilities. For both situations these layouts should be defined within config.php.&lt;br /&gt;
&lt;br /&gt;
It is also important to note that a new theme that will base itself on another theme (overriding it) does not need to define any layouts or use any layout files if there are no changes that it wishes to make to the layouts of the existing theme. The standard theme in Moodle is a good example of this as it extends the base theme simply adding CSS to achieve its look and feel.&lt;br /&gt;
&lt;br /&gt;
So layouts... as mentioned earlier layouts are defined in config.php within $THEME-&amp;gt;layouts. The following is an example of one such layout definition:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Standard layout with blocks, this is recommended for most pages with general information&lt;br /&gt;
    &#039;standard&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;theme&#039; =&amp;gt; &#039;base&#039;,&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The first thing Moodle looks at is the name of the layout, in this case it is `standard` (the array key in PHP), it then looks at the settings for the layout, this is the theme, file, regions, and default region. There are also a couple of other options that can be set by a layout.&lt;br /&gt;
&lt;br /&gt;
; theme : is the theme the layout file exists in. That&#039;s right you can make use of layouts from other installed themes. &#039;&#039;Optional&#039;&#039;&lt;br /&gt;
; file : is the name of the layout file this layout wants to use. &#039;&#039;Required&#039;&#039;&lt;br /&gt;
; regions : is the different block regions (places you can put blocks) within the theme. &#039;&#039;Required&#039;&#039;&lt;br /&gt;
; defaultregion : is the default location when adding new blocks. &#039;&#039;&#039;Required if regions is non-empty, otherwise optional&#039;&#039;&#039;&lt;br /&gt;
; options : an array of layout specific options described in detail below. &#039;&#039;&#039;Optional&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;theme&#039;&#039;&#039; is optional. Normally the the layout file is looked for in the current theme, or, if it is not there, in the parent theme. However, you can use a layout file from any other theme by giving the theme name here.&lt;br /&gt;
&lt;br /&gt;
You can define whatever regions you like. You just need to pick an name for each one. Most themes just use one or both of &#039;&#039;&#039;side_pre&#039;&#039;&#039; and &#039;&#039;&#039;side_post&#039;&#039;&#039;, which is like &#039;left side&#039; and &#039;right side&#039;, except in right to left languages, when they are reversed. If you say in config.php that your the layout provides regions called &#039;fred&#039; and &#039;barney&#039;, then you must call $OUTPUT-&amp;gt;blocks_for_region(&#039;fred&#039;) and $OUTPUT-&amp;gt;blocks_for_region(&#039;barney&#039;) somewhere in the layout file.&lt;br /&gt;
&lt;br /&gt;
The final setting &#039;&#039;&#039;options&#039;&#039;&#039; is a special case that only needs to be set if you want to make use of it. This setting allows the theme designer to specify special options that they would like to create that can be later accessed within the layout file. This allows the theme to make design decisions during the definition and react upon those decisions in what ever layout file is being used.&lt;br /&gt;
&lt;br /&gt;
One such place this has been used is infact within the base theme. If you take a look first at theme/base/config.php you will notice that several layouts specify options &#039;&#039;&#039;nonavbar&#039;&#039;&#039; and &#039;&#039;&#039;nofooter&#039;&#039;&#039; which can both be set to either true or false. Then if we take a look at theme/base/layout/general.php you will spot lines like the following:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$hasnavbar = (empty($PAGE-&amp;gt;layout_options[&#039;nonavbar&#039;]) &amp;amp;&amp;amp; $PAGE-&amp;gt;has_navbar());&lt;br /&gt;
$hasfooter = (empty($PAGE-&amp;gt;layout_options[&#039;nofooter&#039;]));&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
............&lt;br /&gt;
&amp;lt;?php if ($hasnavbar) { ?&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;navbar clearfix&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;breadcrumb&amp;quot;&amp;gt;&amp;lt;?php echo $OUTPUT-&amp;gt;navbar(); ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;navbutton&amp;quot;&amp;gt; &amp;lt;?php echo $PAGE-&amp;gt;button; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
What you are seeing here is the use of those settings from the layout within the layout file. In this case it is being used to toggle the display of the navigation bar and page footer.&lt;br /&gt;
&lt;br /&gt;
==Layout files==&lt;br /&gt;
A layout file is a file that contains the core HTML structure for a layout including the header, footer, content and block regions.&lt;br /&gt;
For those of you who are familiar with themes in Moodle 1.9 this is simply header.html and footer.html combined.&lt;br /&gt;
Of course it is not all HTML, there are bits of HTML and content that Moodle needs to put into the page, within each layout file this will be done by a couple of VERY simple PHP calls to get bits and pieces including content.&lt;br /&gt;
&lt;br /&gt;
The following is a very simple layout file to illustrate the different bits that make it up:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;doctype() ?&amp;gt;&lt;br /&gt;
&amp;lt;html &amp;lt;?php echo $OUTPUT-&amp;gt;htmlattributes() ?&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
    &amp;lt;title&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;title ?&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;
    &amp;lt;?php echo $OUTPUT-&amp;gt;standard_head_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php 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;table id=&amp;quot;page&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
        &amp;lt;td colspan=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;h1 class=&amp;quot;headermain&amp;quot;&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;heading ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;headermenu&amp;quot;&amp;gt;&amp;lt;?php echo $OUTPUT-&amp;gt;login_info(); echo $PAGE-&amp;gt;headingmenu; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-pre&#039;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-post&#039;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
        &amp;lt;td colspan=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;p class=&amp;quot;helplink&amp;quot;&amp;gt;&amp;lt;?php echo page_doc_link(get_string(&#039;moodledocslink&#039;)) ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
            &amp;lt;?php&lt;br /&gt;
            echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
            echo $OUTPUT-&amp;gt;home_link();&lt;br /&gt;
            echo $OUTPUT-&amp;gt;standard_footer_html();&lt;br /&gt;
            ?&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_end_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lets assume you know a enough HTML to understand the basic structure above, what you probably don&#039;t understand are the PHP calls so lets look at them.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;doctype() ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This occurs at the VERY top of the page, it must be the first bit of output and is responsible for adding the (X)HTML document type definition to the page. This of course is determined by the settings of the site and is one of the things that the theme designer has no control over.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;html &amp;lt;?php echo $OUTPUT-&amp;gt;htmlattributes() ?&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we have started writing the opening html tag and have asked Moodle to give us the HTML attributes that should be applied to it. This again is determined by several settings within the actual HTML install.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $PAGE-&amp;gt;title ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This gets us the title for the page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_head_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This very important call gets us the standard head HTML that needs to be within the HEAD tag of the page. This is where CSS and JavaScript requirements for the top of the page will be output as well as any special script or style tags.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php 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;
Much like the html tag above we have started writing the body tag and have asked for Moodle to get us the desired ID and classes that should be applied to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;h1 class=&amp;quot;headermain&amp;quot;&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;heading; ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;headermenu&amp;quot;&amp;gt;&amp;lt;?php echo $OUTPUT-&amp;gt;login_info(); echo $PAGE-&amp;gt;headingmenu; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are creating the header for the page. In this case we want the heading for the page, we want to display the login information which will be the current users username or a link to log in if they are not logged in, and we want the heading menu if there is one.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-pre&#039;) ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we get the HTML to display the blocks that have been added to the page. In this case we have asked for all blocks that have been added to the area labelled &#039;&#039;side-pre&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is one of the most important calls within the file, it determines where the actual content for the page gets inserted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-post&#039;) ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we get the HTML to display the blocks that have been added to the page. In this case we have asked for all blocks that have been added to the area labelled &#039;&#039;side-post&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
echo $OUTPUT-&amp;gt;home_link();&lt;br /&gt;
echo $OUTPUT-&amp;gt;standard_footer_html();&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This final bit of code gets the content for the footer of the page. It gets the login information which is the same as in the header, a home link, and the standard footer HTML which like the standard head HTML contains all of the script and style tags required by the page and requested to go in the footer.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note&#039;&#039;&#039;&#039;&#039;: Within Moodle 2.0 most of the JavaScript for the page will be included in the footer. This greatly helps reduce the loading time of the page.&lt;br /&gt;
&lt;br /&gt;
When writing layout files think about the different layouts and how the HTML that each makes use of will differ. You will most likely find you do not need a different layout file for each layout, most likely you will be able to reuse the layout files you create across several layouts. You can of course make use of layout options as well to further reduce the number of layout files you need to produce.&lt;br /&gt;
&lt;br /&gt;
Of course as mentioned above if you are customising an existing theme then you may not need to create any layouts or layout files at all.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;$OUTPUT&#039;&#039;&#039; is an instance of the &#039;&#039;&#039;core_renderer&#039;&#039;&#039; 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 &#039;&#039;&#039;moodle_page&#039;&#039;&#039; 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, some magic is going on, and the value you get is produced by calling a function. Also, you cannot change these values, they are read-only. However, you don&#039;t need to understand all that if you are just using these properties in your theme.)&lt;br /&gt;
&lt;br /&gt;
==Making use of images==&lt;br /&gt;
Right at the start when listing the features of the new themes system one of the features mentioned was the ability to override any of the standard images within Moodle from within your theme. At this point we will look at both how to make use of your own images within your theme, and secondly how to override the images being used by Moodle.&lt;br /&gt;
So first up a bit about images within Moodle,&lt;br /&gt;
&lt;br /&gt;
# Images you want to use within your theme &#039;&#039;&#039;need&#039;&#039;&#039; to be located within your theme&#039;s pix directory.&lt;br /&gt;
# You can use sub directories within the pix directory of your theme.&lt;br /&gt;
# Images used by Moodle&#039;s core are located within the pix directory of Moodle.&lt;br /&gt;
# Modules, blocks and other plugins should also store there images within a pix directory.&lt;br /&gt;
&lt;br /&gt;
So making use of your own images first up. Lets assume you have added two image files to the pix directory of your theme.&lt;br /&gt;
&lt;br /&gt;
* /theme/yourthemename/pix/imageone.jpg&lt;br /&gt;
* /theme/yourthemename/pix/subdir/imagetwo.png&lt;br /&gt;
&lt;br /&gt;
Notice that one image is a JPEG image, and the second is a PNG. Also the second image is in a subdirectory.&lt;br /&gt;
&lt;br /&gt;
The following code snippet illustrates how to make use of your images within HTML, such as if you wanted to use them within a layout file.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;&amp;lt;?php echo $OUTPUT-&amp;gt;pix_url(&#039;imageone&#039;, &#039;theme&#039;);?&amp;gt;&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt; &lt;br /&gt;
&amp;lt;img src=&amp;quot;&amp;lt;?php echo $OUTPUT-&amp;gt;pix_url(&#039;subdir/imagetwo&#039;, &#039;theme&#039;);?&amp;gt;&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt; &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;DO NOT&#039;&#039;&#039; include the image file extension. Moodle will work it out automatically and it will not work if you do include it.&lt;br /&gt;
&lt;br /&gt;
In this case rather than writing out the URL to the image we use a method of Moodle&#039;s output library. Its not too important how that functions works but it is important that we use it as it is what allows images within Moodle to be over-rideable.&lt;br /&gt;
&lt;br /&gt;
The following is how you would use the images from within CSS as background images.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
.divone {background-image:url([[pix:theme|imageone]]);}&lt;br /&gt;
.divtwo {background-image:url([[pix:theme|subdir/imagetwo]]);}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
If this case we have to use some special notations that Moodle looks for. Whenever Moodle hands out a CSS file it first searches for all &#039;&#039;[[something]]&#039;&#039; tags and replaces them with what is required.&lt;br /&gt;
&lt;br /&gt;
The final thing to notice with both of the cases above is that at no point do we include the images file extension. &lt;br /&gt;
The reason for this leads us into the next topic, how to override images.&lt;br /&gt;
&lt;br /&gt;
From within a theme you can VERY easily override any standard image within Moodle by simply adding the replacement image to the theme&#039;s pix directory in the same sub directory structure as it is in Moodle.&lt;br /&gt;
So for instance we wanted to override the following two images:&lt;br /&gt;
# /pix/moodlelogo.gif&lt;br /&gt;
# /pix/i/user.gif&lt;br /&gt;
We would simply need to add our replacement images to the theme in the following locations&lt;br /&gt;
# /theme/themename/pix/moodlelogo.gif&lt;br /&gt;
# /theme/themename/pix/i/user.gif&lt;br /&gt;
How easy is that!&lt;br /&gt;
&lt;br /&gt;
Now the other very cool thing to mention is that Moodle looks for not just replacements of the same image type (jpg, gif, etc...) but also replacements in any image format. This is why above when working with our images we never specified the images file extension.&lt;br /&gt;
This means that the following would also work:&lt;br /&gt;
# /theme/themename/pix/moodlelogo.png&lt;br /&gt;
# /theme/themename/pix/i/user.bmp&lt;br /&gt;
&lt;br /&gt;
For a more detailed description of how this all works see the page on [[Development:Themes_2.0_How_to_use_images_within_your_theme|using images within your theme]]&lt;br /&gt;
&lt;br /&gt;
==Unobvious Things==&lt;br /&gt;
===Getting Your Theme to Appear Correctly in Theme Selector===&lt;br /&gt;
If you follow the examples on this page to the letter, when you go to the Theme Selector page you may be discouraged to find that your theme does not appear like the other themes do. In fact, instead of your theme&#039;s name, you will see something along the lines of &amp;lt;nowiki&amp;gt;[[pluginname]]&amp;lt;/nowiki&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
To correct this, you must add the /lang/en/theme_THEMENAME.php file, where THEMENAME is the name of the theme folder. Inside that file, add the string &amp;quot;$string[&#039;pluginname&#039;] = &#039;THEMENAME&#039;; &amp;quot;. Make THEMENAME the name of your theme, however you want it displayed in the Theme selector.&lt;br /&gt;
&lt;br /&gt;
The screenshot for the theme should be about 500x400 px.&lt;br /&gt;
&lt;br /&gt;
===Required theme divs===&lt;br /&gt;
&lt;br /&gt;
Some parts of Moodle may rely on particular divs, for example the div with id &#039;page-header&#039;.&lt;br /&gt;
&lt;br /&gt;
Consequently all themes must include at least the divs (with the same ids) that are present in the &#039;base&#039; theme. &lt;br /&gt;
&lt;br /&gt;
Missing out these elements may result in unexpected behaviour within specific modules or other plugins.&lt;br /&gt;
&lt;br /&gt;
==Appendix A==&lt;br /&gt;
===Theme options as of April 28th, 2010===&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot; id=&amp;quot;theme_options_table&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Setting&lt;br /&gt;
! Effect&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;csspostprocess&#039;&#039;&#039;&lt;br /&gt;
|  Allows the user to provide the name of a function that all CSS should be passed to before being delivered.&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;editor_sheets&#039;&#039;&#039;&lt;br /&gt;
|  An array of stylesheets to include within the body of the editor.&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;enable_dock&#039;&#039;&#039;&lt;br /&gt;
|  If set to true the side dock is enabled for blocks&lt;br /&gt;
|-&lt;br /&gt;
| $THEME-&amp;gt;&#039;&#039;&#039;hidefromselector&#039;&#039;&#039;&lt;br /&gt;
| Used to hide a theme from the theme selector (unless theme designer mode is on). Accepts true or false.&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;filter_mediaplugin_colors&#039;&#039;&#039;&lt;br /&gt;
|  Used to control the colours used in the small media player for the filters&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;javascripts&#039;&#039;&#039;&lt;br /&gt;
|  An array containing the names of JavaScript files located in /javascript/ to include in the theme. (gets included in the head)&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;javascripts_footer&#039;&#039;&#039;&lt;br /&gt;
|  As above but will be included in the page footer.&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;larrow&#039;&#039;&#039;&lt;br /&gt;
|  Overrides the left arrow image used throughout Moodle&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;layouts&#039;&#039;&#039;&lt;br /&gt;
|  An array setting the layouts for the theme&lt;br /&gt;
|-&lt;br /&gt;
| $THEME-&amp;gt;&#039;&#039;&#039;name&#039;&#039;&#039;&lt;br /&gt;
| Name of the theme. Most likely the name of the directory in which this file resides.&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;parents&#039;&#039;&#039;&lt;br /&gt;
|  An array of themes to inherit from&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;parents_exclude_javascripts&#039;&#039;&#039;&lt;br /&gt;
|  An array of JavaScript files NOT to inherit from the themes parents&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;parents_exclude_sheets&#039;&#039;&#039;&lt;br /&gt;
|  An array of stylesheets not to inherit from the themes parents&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;plugins_exclude_sheets&#039;&#039;&#039;&lt;br /&gt;
|  An array of plugin sheets to ignore and not include.&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;rarrow&#039;&#039;&#039;&lt;br /&gt;
|  Overrides the right arrow image used throughout Moodle&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;renderfactory&#039;&#039;&#039;&lt;br /&gt;
|  Sets a custom render factory to use with the theme, used when working with custom renderers.&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;resource_mp3player_colors&#039;&#039;&#039;&lt;br /&gt;
|  Controls the colours for the MP3 player&lt;br /&gt;
|-&lt;br /&gt;
|  $THEME-&amp;gt;&#039;&#039;&#039;sheets&#039;&#039;&#039;&lt;br /&gt;
|  An array of stylesheets to include for this theme. Should be located in the theme&#039;s style directory.&lt;br /&gt;
|}&lt;br /&gt;
===The different layouts as of August 17th, 2010===&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot; id=&amp;quot;theme_layouts_table&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Layout&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| base&lt;br /&gt;
| Most backwards compatible layout without the blocks - this is the layout used by default.&lt;br /&gt;
|- &lt;br /&gt;
| standard&lt;br /&gt;
| Standard layout with blocks, this is recommended for most pages with general information.&lt;br /&gt;
|- &lt;br /&gt;
| course&lt;br /&gt;
| Main course page.&lt;br /&gt;
|- &lt;br /&gt;
| coursecategory&lt;br /&gt;
| Use for browsing through course categories.&lt;br /&gt;
|- &lt;br /&gt;
| incourse&lt;br /&gt;
| Default layout while browsing a course, typical for modules.&lt;br /&gt;
|- &lt;br /&gt;
| frontpage&lt;br /&gt;
| The site home page.&lt;br /&gt;
|- &lt;br /&gt;
| admin&lt;br /&gt;
| Administration pages and scripts.&lt;br /&gt;
|- &lt;br /&gt;
| mydashboard&lt;br /&gt;
| My dashboard page.&lt;br /&gt;
|- &lt;br /&gt;
| mypublic&lt;br /&gt;
| My public page.&lt;br /&gt;
|- &lt;br /&gt;
| login&lt;br /&gt;
| The login page.&lt;br /&gt;
|-&lt;br /&gt;
| popup&lt;br /&gt;
| Pages that appear in pop-up windows - no navigation, no blocks, no header.&lt;br /&gt;
|-&lt;br /&gt;
| frametop&lt;br /&gt;
| Used for legacy frame layouts only. No blocks and minimal footer.&lt;br /&gt;
|-&lt;br /&gt;
| embedded&lt;br /&gt;
| Embeded pages, like iframe/object embedded in moodleform - it needs as much space as possible&lt;br /&gt;
|-&lt;br /&gt;
| maintenance&lt;br /&gt;
| Used during upgrade and install. This must not have any blocks, and it is good idea if it does not have links to other places - for example there should not be a home link in the footer.&lt;br /&gt;
|-&lt;br /&gt;
| print&lt;br /&gt;
| Used when the page is being displayed specifically for printing.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]] - A quick step by step guide to creating your first theme.&lt;br /&gt;
* [[Development:Themes 2.0 overriding a renderer]] - A tutorial on creating a custom renderer and changing the HTML Moodle produces.&lt;br /&gt;
* [[Development:Themes 2.0 How to use images within your theme]] - Explains how to use and override images within your theme.&lt;br /&gt;
* [[Development:Themes 2.0 adding a settings page]] - Looks at how to add a setting page making your theme easily customisable.&lt;br /&gt;
* [[Development:Themes 2.0 extending the custom menu]] - Customising the custom menu.&lt;br /&gt;
* [[Development:Themes 2.0 how to make the dock horizontal]] - Modifying the dock to make it horizontal.&lt;br /&gt;
* [[Development:Themes 2.0 adding_upgrade_code]]&lt;br /&gt;
* [[Development:Styling and customising the dock]] - How to style and customise the dock.&lt;br /&gt;
* [[Development:Theme changes in 2.0]]&lt;br /&gt;
* [[Development:Using jQuery with Moodle 2.0]]&lt;br /&gt;
* [http://www.youtube.com/watch?v=OvaU54uh-qA New themes in Moodle 2.0 video]&lt;br /&gt;
&lt;br /&gt;
[[de:Designs 2.0]]&lt;br /&gt;
[[es:Temas 2.0]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Administrator_documentation&amp;diff=82052</id>
		<title>Administrator documentation</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Administrator_documentation&amp;diff=82052"/>
		<updated>2011-03-18T10:49:03Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* Unix/Linux-based */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this page is to list useful links by general topics for administrators of a Moodle site.&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Installation &amp;amp; Upgrading ==&lt;br /&gt;
&lt;br /&gt;
*[[Installation Quickstart]] for an overview of the installation steps&lt;br /&gt;
*[[Installing Moodle]] for detailed installation instructions&lt;br /&gt;
*[[Installation FAQ]]&lt;br /&gt;
*[[Installing AMP|Options for installing Apache, MySQL and PHP]]&lt;br /&gt;
*[[Upgrading|Upgrading Moodle]]&lt;br /&gt;
*[[Installing contributed modules or plugins]]&lt;br /&gt;
&lt;br /&gt;
== System-specific Instructions &amp;amp; Packages ==&lt;br /&gt;
&lt;br /&gt;
===Unix/Linux-based===&lt;br /&gt;
* [[SUSE Linux Server 10|Automated Installation Guide for SUSE Linux Enterprise Server 10]] operating system&lt;br /&gt;
* [[RedHat Linux installation|Step-by-step Installation Guide for RedHat]] operating system&lt;br /&gt;
* [[Debian GNU/Linux installation|Step-by-step Installation Guide for Debian GNU/Linux]] operating system&lt;br /&gt;
* [[Step-by-step Installation Guide for Ubuntu]]&lt;br /&gt;
* [[Manual installation of Moodle 2.0 on Mythbuntu using Git]]&lt;br /&gt;
* [[Manual_installation_on_Ubuntu|Manual Installation on Ubuntu]]&lt;br /&gt;
* [[Step-by-step Install Guide for Zenwalk-5.0|Step-by-step Installation Guide for Zenwalk-5.0]]&lt;br /&gt;
* [[OLPC XS installation|Step-by-step Installation Guide for the One Laptop per Child XS Server (Beta)]]&lt;br /&gt;
* [[Step-by-step Install Guide for Solaris 10 with Oracle 10|Step-by-step Installation Guide for Solaris 10 with Oracle 10]]&lt;br /&gt;
* [[Installation Guide for Installing on Amazon EC2]]&lt;br /&gt;
&lt;br /&gt;
===Windows===&lt;br /&gt;
* [[Windows installation|Windows installations with instructions for Windows NT/2000/2003 servers]]&lt;br /&gt;
* [[Windows installation using XAMPP|Windows installation using XAMPP: Apache, MySQL and PHP]]&lt;br /&gt;
* [[Development:Windows_Installer_anywhere|MoodleAnywhere]] another Windows installation package&lt;br /&gt;
* [[Installing Moodle on Windows Vista]] - how to&lt;br /&gt;
* [http://www.bfcnetworks.com/whitepapers/installing-moodle-on-windows-server-iis-sql/ Installing Moodle on Windows Server 2008 x86]&lt;br /&gt;
* [http://www.bfcnetworks.com/whitepapers/installing-moodle-on-windows-server-2008-r2-x64-sql-iis/ Installing Moodle on Windows Server 2008 R2]&lt;br /&gt;
* [http://www.bfcnetworks.com/whitepapers/implementing-moodle-on-a-windows-high-availability-environment// Implementing Moodle on a Windows High Availability Environment] Implementing Moodle 1.9 on 2 Microsoft Load Balanced Web Front End Server and a Microsoft SQL Server 2008 R2 Cluster environment&lt;br /&gt;
&lt;br /&gt;
Moodle 2&lt;br /&gt;
* [http://www.bfcnetworks.com/whitepapers/installing-moodle-2-on-windows-server-mysql-php-and-iis7/ Installing Moodle 2 on Windows Server, MySQL, PHP and IIS7]&lt;br /&gt;
* [http://www.bfcnetworks.com/whitepapers/installing-moodle-2-on-windows-server-2008-r2-x64-sql-iis/ Installing Moodle 2 on Windows Server, Microsoft SQL Server, PHP and IIS7]&lt;br /&gt;
&lt;br /&gt;
===Mac===&lt;br /&gt;
* [[Step by Step Installation on a Mac OS X Server|Step by step Installation on a Mac OS X Server 10.5/10.6]]&lt;br /&gt;
* [[Complete Install Packages for Mac OS X | Complete Install Packages for Mac OS X Clients 10.4/10.5/10.6]]&lt;br /&gt;
* [[Step-by-step Guide for Installing Moodle on Mac OS X 10.4 Client|Step by Step Installation on a Mac OS X 10.4 Client using the internal web server]]&lt;br /&gt;
&lt;br /&gt;
===Web Hosts===&lt;br /&gt;
* [[1and1_MySQL_installation | Installation on &#039;&#039;&#039;1and1&#039;&#039;&#039; web hosting]]&lt;br /&gt;
* [[powweb_MySQL_installation | Step-by-step Installation on &#039;&#039;&#039;Powweb&#039;&#039;&#039; web hosting]]&lt;br /&gt;
* [[Step-by-step Installation using the old version of CPanel]]&lt;br /&gt;
* [[Step-by-step Installation using the new version of CPanel]]&lt;br /&gt;
&lt;br /&gt;
===Appliances===&lt;br /&gt;
Some users may prefer to skip manual installation by using a pre-integrated [[Moodle appliance]].&lt;br /&gt;
&lt;br /&gt;
===Database===&lt;br /&gt;
* [[Installing Oracle for PHP]]&lt;br /&gt;
* [[Installing MSSQL for PHP]]&lt;br /&gt;
* [[Installing Postgres for PHP]]&lt;br /&gt;
&lt;br /&gt;
===Plugins===&lt;br /&gt;
* [[Installing contributed modules or plugins]]&lt;br /&gt;
&lt;br /&gt;
==Security, Performance and Roles==&lt;br /&gt;
&lt;br /&gt;
*[[Security]] contains important security procedures for a production site&lt;br /&gt;
*[[Performance]] for ideas on improving the speed of your installation&lt;br /&gt;
*[[Manage roles]] For Moodle 1.7 and later.&lt;br /&gt;
*[[Reducing spam in Moodle]]&lt;br /&gt;
*[[suhosin]] is an advanced protection system for PHP installation. It was designed to protect servers and users from known and unknown flaws in PHP applications and the PHP core.&lt;br /&gt;
*[[nagios]] Open source software to monitor servers&lt;br /&gt;
&lt;br /&gt;
== FAQs ==&lt;br /&gt;
&lt;br /&gt;
*[[Installation FAQ]]&lt;br /&gt;
*[[Beginning Administration FAQ]]&lt;br /&gt;
*[[Administration FAQ]]&lt;br /&gt;
*[[Performance FAQ]]&lt;br /&gt;
*[[Backup and restore FAQ]]&lt;br /&gt;
*[[Errors FAQ]]&lt;br /&gt;
*[[:Category:FAQ|List of FAQs]]&lt;br /&gt;
&lt;br /&gt;
== Configuration Settings ==&lt;br /&gt;
=== Site administration setting===&lt;br /&gt;
[[Site administration block]] contains most site configuration settings including:&lt;br /&gt;
*[[Front Page settings]]- initial or home page of a Moodle site&lt;br /&gt;
*[[Themes]] - user interface packages of XHTML and CSS controls&lt;br /&gt;
*[[Language]] - default and additional language packs&lt;br /&gt;
*[[Activity modules administration]]&lt;br /&gt;
*[[Blocks administration]]&lt;br /&gt;
*[[Filters]] - Text and Multimedea plugins &lt;br /&gt;
*[[Backup settings]]&lt;br /&gt;
*[[HTML editor settings]]&lt;br /&gt;
*[[Calendar settings]]&lt;br /&gt;
*[[Maintenance mode]]&lt;br /&gt;
*[[Notification page]] used to update versions&lt;br /&gt;
*[[Settings block]] Moodle 2.0 site settings location&lt;br /&gt;
&lt;br /&gt;
===Other settings===&lt;br /&gt;
*[[Course settings]] for course home page configuration&lt;br /&gt;
**Each type of [[Activities|activity]], [[resource]] and [[:Category:Block|block]] has their own settings&lt;br /&gt;
*Older versions settings&lt;br /&gt;
**[[Site settings]] pre 1.7&lt;br /&gt;
**[[Variables]] pre 1.6 &lt;br /&gt;
**[[Location of admin settings in 1.7|Comparison between configuration settings in Moodle 1.6 &amp;amp; 1.7]]&lt;br /&gt;
&lt;br /&gt;
==User Management==&lt;br /&gt;
&lt;br /&gt;
*[[Authentication]] of user on a site&lt;br /&gt;
*[[Add new user|Add a new user]] - on a site&lt;br /&gt;
*[[Upload users]] - from a file to a site, and into existing course and group, some existing user global updates&lt;br /&gt;
*[[User_profile_fields]]&lt;br /&gt;
*[[Enrolment plugins]]&lt;br /&gt;
**[[Flat file]] - enrol existing users in a course&lt;br /&gt;
*[[Roles and capabilities|Assigning user a role]] - typical assignments include:&lt;br /&gt;
**[[Students|Enrol students in a course]]&lt;br /&gt;
**[[Unenrolment]] Student&lt;br /&gt;
**[[Courses (administrator)|Assign teachers]] - to a course&lt;br /&gt;
**[[Assign creators|Assign course creators]] - in a site&lt;br /&gt;
**[[Assign administrators]] - in a site&lt;br /&gt;
&lt;br /&gt;
==Other==&lt;br /&gt;
&lt;br /&gt;
*[[Courses (administrator)|Courses]] and [[Course formats|course formats]]&lt;br /&gt;
*[[Reports (administrator)]] and [[Logs]]&lt;br /&gt;
*[[Site files]]&lt;br /&gt;
*[[Moodle database|Moodle site database]] &lt;br /&gt;
*[[Environment]]&lt;br /&gt;
*[[MNet|Moodle Network]] and Moodle [[Community hub]]&lt;br /&gt;
*[[Streaming Media]]&lt;br /&gt;
*[[Case studies (administrator)]]&lt;br /&gt;
*[[Anti-virus]]&lt;br /&gt;
*[[System Monitoring and Server Statistic Software]]&lt;br /&gt;
*[[Integrate Moodle, LDAP and SIMS.net]]&lt;br /&gt;
*[[How to rebuild context paths]]&lt;br /&gt;
*[[Hacking the Moodle 2.0 database transfer script to convert a Moodle 1.9 site]]&lt;br /&gt;
*[[Category:ProxyProblems]]&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
*[[:Category:Administrator | Index of all Administrator-related pages]]&lt;br /&gt;
*[[Integrations]]&lt;br /&gt;
*[[CVS for Administrators]]&lt;br /&gt;
*[[Email processing]]&lt;br /&gt;
*[[Search engine optimization]]&lt;br /&gt;
*[[Messaging]]&lt;br /&gt;
*[[Migration]]&lt;br /&gt;
*[[Metacourses]]&lt;br /&gt;
*[[Block layout]]&lt;br /&gt;
*[[Customizing Moodle]]&lt;br /&gt;
*[[Administrator do&#039;s and don&#039;ts]]&lt;br /&gt;
*[[Using Moodle book]] Chapter 16: Moodle Administration&lt;br /&gt;
*[[Administration hacks]]&lt;br /&gt;
*[[Git]] Version control, upgrading &lt;br /&gt;
&lt;br /&gt;
[[Category: Administrator]]&lt;br /&gt;
[[cs:Rukověť správce]]&lt;br /&gt;
[[es:Documentación para Administradores]]&lt;br /&gt;
[[eu:Kudeatzaileentzako dokumentazioa]]&lt;br /&gt;
[[fr:Documentation administrateur]]&lt;br /&gt;
[[ja:管理者ドキュメント]]&lt;br /&gt;
[[ko:관리자 문서]]&lt;br /&gt;
[[nl:Documentatie voor beheerders]]&lt;br /&gt;
[[pt:Documentação para administradores]]&lt;br /&gt;
[[ru:Администраторам]]&lt;br /&gt;
[[sk:Dokumentácia pre správcov]]&lt;br /&gt;
[[zh:管理员文档]]&lt;br /&gt;
[[pl:Administrator documentation]]&lt;br /&gt;
[[fi:Ylläpitäjän opas]]&lt;br /&gt;
[[de:Dokumentation für Administratoren]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Development:JavaScript_guidelines&amp;diff=81401</id>
		<title>Development:JavaScript guidelines</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Development:JavaScript_guidelines&amp;diff=81401"/>
		<updated>2011-02-18T13:26:04Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* Getting Moodle to load your JavaScript files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
These guidelines can only be applied fully from Moodle 2.0 onwards, because they rely on our new API to facilitate use of JavaScript.&lt;br /&gt;
&lt;br /&gt;
When writing JavaScript for earlier versions of Moodle, please try to follow these guidelines in spirit and use the &#039;&#039;&#039;require_js&#039;&#039;&#039; function in place of $PAGE-&amp;gt;requires-&amp;gt;js_module/yui2_lib.&lt;br /&gt;
&lt;br /&gt;
==General principles==&lt;br /&gt;
&lt;br /&gt;
===Moodle should be usable without JavaScript===&lt;br /&gt;
&lt;br /&gt;
Everything in Moodle should work with JavaScript turned off. This is important for accessibility, and in line with the principles of [[Development:Unobtrusive_Javascript|unobtrusive JavaScript]] and [[Development:Progressive_enhancement|progressive enhancement]].&lt;br /&gt;
&lt;br /&gt;
===Minimise inline JavaScript===&lt;br /&gt;
&lt;br /&gt;
Almost all JavaScript code should be in separate .js files. There should be the smallest possible amount of JavaScript inline in the HTML code of pages.&lt;br /&gt;
&lt;br /&gt;
The only &amp;amp;lt;script&amp;gt; tags in the HTML should be&lt;br /&gt;
# &amp;amp;lt;script src=... tags to include the necessary .js files.&lt;br /&gt;
# Simple function calls to trigger initialisation and pass data from PHP to JavaScript. For example &amp;amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;initialise_my_widget(&#039;some&#039;, &#039;data&#039;, 123);&amp;amp;lt;/script&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Even these small amounts of JS you should not output directly. They will be generated automatically by calls to the $PAGE-&amp;gt;requries-&amp;gt;js_init_call() API. See below for details.&lt;br /&gt;
&lt;br /&gt;
You should not use old-fashioned onXXX=&amp;quot;event_handler&amp;quot; attributes in the HTML. Use Modern DOM events. The YUI events library makes this easy.&lt;br /&gt;
&lt;br /&gt;
=== JavaScript libraries ===&lt;br /&gt;
&lt;br /&gt;
* The official JavaScript library for Moodle is [[Development:YUI|YUI]]. That may not be your favourite, but it&#039;s the one that was chosen after careful research, so live with it.&lt;br /&gt;
&lt;br /&gt;
* Moodle also has its own JavaScript library code, packaged into in various JavaScript modules.&lt;br /&gt;
&lt;br /&gt;
* Moodle uses the &#039;&#039;&#039;TinyMCE&#039;&#039;&#039; HTML editor.&lt;br /&gt;
&lt;br /&gt;
===When to include the JavaScript===&lt;br /&gt;
&lt;br /&gt;
As per [http://developer.yahoo.com/performance/rules.html Yahoo&#039;s best practice guidelines], load and execute the JavaScript as late as possible, ideally the script tags should be the last thing before the &amp;amp;lt;/body&amp;gt; close tag. (This is the default behaviour with Moodle&#039;s JavaScript handling functions like $PAGE-&amp;gt;requries-&amp;gt;js_init_call().)&lt;br /&gt;
&lt;br /&gt;
Since everything should work without JavaScript, load and initialising your scripts only after everything else on the page has loaded should not be a problem and will increase the perceived page-load performance for users.&lt;br /&gt;
&lt;br /&gt;
===Minimise the number of .js files===&lt;br /&gt;
&lt;br /&gt;
Try not to use too many different .js files. Each separate file that the browser has to load incurs an overhead.&lt;br /&gt;
&lt;br /&gt;
On the other hand, organise the JavaScript logically to ease maintenance, and don&#039;t include large amounts of irrelevant JavaScript code. Code that is loaded but never used is a waste of time.&lt;br /&gt;
&lt;br /&gt;
So, if you are writing a new module that needs its own JavaScript, try starting with a single file mod/mymod/module.js. If you find that you are writing a lot of JavaScript that is only needed when the teacher edits your module, but is not needed by students, then consider splitting that code into a separate file like mod/mymod/edit.js, and only including it where needed.&lt;br /&gt;
&lt;br /&gt;
==How to achive these general principles in Moodle==&lt;br /&gt;
&lt;br /&gt;
The rest of this page explains how you can achieve the above goals. Note that this particularly applies to loading and using the YUI 3 library which is Moodle 2.0&#039;s default. You should check which version of YUI Moodle is using as it may lag behind the latest YUI release (and, hence, the documentation).&lt;br /&gt;
&lt;br /&gt;
===Getting Moodle to load your JavaScript files===&lt;br /&gt;
&lt;br /&gt;
Everything required by the current page is tracked by the $PAGE-&amp;gt;requires object, which is an instance of the [http://phpdocs.moodle.org/HEAD/moodlecore/page_requirements_manager.html page_requirements_manager] class defined in lib/outputrequirementslib.php.&lt;br /&gt;
&lt;br /&gt;
The most important method in this class is the -&amp;gt;js_init_call(...) method. You use it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.mod_mymod.init_something&#039;, array(&#039;some&#039;, &#039;data&#039;, &#039;from&#039;, &#039;PHP&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that this will implicitly load the JavaScript code in mod/mymod/module.js, and then call the M.mod_mymod.init_something function passing four string arguments &#039;some&#039;, &#039;data&#039;, &#039;from&#039;, &#039;PHP&#039;. You can pass any PHP type as an argument. The PHP values are encoded with json_encode before being passed to JavaScript, so numbers, strings, arrays and objects all work.&lt;br /&gt;
&lt;br /&gt;
Sometimes, the code in the JavaScript module mod/mymod/module.js may require some other JavaScript libraries to be loaded, or it may require some language strings. In that case you need to use the full form of js_init_call:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$jsmodule = array(&lt;br /&gt;
    &#039;name&#039;     =&amp;gt; &#039;mod_mymod&#039;,&lt;br /&gt;
    &#039;fullpath&#039; =&amp;gt; &#039;/mod/mymod/module.js&#039;,&lt;br /&gt;
    &#039;requires&#039; =&amp;gt; array(&#039;base&#039;, &#039;io&#039;, &#039;node&#039;, &#039;json&#039;),&lt;br /&gt;
    &#039;strings&#039; =&amp;gt; array(&lt;br /&gt;
        array(&#039;something&#039;, &#039;mymod&#039;),&lt;br /&gt;
        array(&#039;confirmdelete&#039;, &#039;mymod&#039;),&lt;br /&gt;
        array(&#039;yes&#039;, &#039;moodle&#039;),&lt;br /&gt;
        array(&#039;no&#039;, &#039;moodle&#039;)&lt;br /&gt;
    )&lt;br /&gt;
);&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.mod_mymod.init_something&#039;, array(&#039;some&#039;, &#039;data&#039;, &#039;from&#039;, &#039;PHP&#039;), false, $jsmodule);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
(Naturally, it would be a good idea to put the definition of the $jsmodule array somewhere central like in the locallib.php file.)&lt;br /&gt;
&lt;br /&gt;
The third (boolean) parameter is defined as &amp;quot;Wait for DOM Ready&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The libraries in the &#039;requires&#039; sub-array are YUI3 (or YUI2) libraries. Moodle contains YUIs &#039;phploader&#039; which understands what the library dependencies are, so this is all taken care of for you. &lt;br /&gt;
&lt;br /&gt;
The strings are Moodle language strings. In order for Moodle to have correctly determined the user&#039;s language, you should only call js_init_call after the call to require_login, which sets the current course, and ensures the user is logged in.&lt;br /&gt;
Strings that are passed to Javascript in this way are then available from Javascript using M.util.get_string(), which works just like the PHP function.&lt;br /&gt;
&lt;br /&gt;
$PAGE-&amp;gt;requires keeps track of which files have been included. For example if two other modules both require the YUI base module, then it is only included once.&lt;br /&gt;
&lt;br /&gt;
Your &#039;module.js&#039; file in your plugin&#039;s directory will look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
M.mod_mymod = {};&lt;br /&gt;
&lt;br /&gt;
M.mod_mymod.init = function(Y) {&lt;br /&gt;
&lt;br /&gt;
    // example to submit a form field on change&lt;br /&gt;
    Y.on(&#039;change&#039;, function(e) {&lt;br /&gt;
        Y.one(&#039;#mform1&#039;).submit();&lt;br /&gt;
    }, &#039;#id_fieldname&#039; );&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mod_mymod&#039;&#039; needs changed to reflect the plugin type (see [[Development:Frankenstyle]]) and the name of your plugin throughout.&lt;br /&gt;
&lt;br /&gt;
===JavaScript coding style===&lt;br /&gt;
&lt;br /&gt;
Moodle JavaScript code should should follow the same [[Development:Coding_style|coding style as Moodle PHP code]], allowing for the differences between PHP and JavaScript.&lt;br /&gt;
&lt;br /&gt;
For example, all the rules on &#039;&#039;function_names&#039;&#039;, &#039;&#039;class_names&#039;&#039; and &#039;&#039;variablenames&#039;&#039; apply. You should document your code with [http://jsdoc.sourceforge.net/ JSDoc] comments. Layout your JavaScript expressions and statements like the equivalent PHP ones.&lt;br /&gt;
&lt;br /&gt;
Normally, your .js files should simply define things like functions, classes and variables. When the file is loaded, no JavaScript code should actually be executed that has any effect unless it is the sort of code that can safely be executed once per HTML page. This is so that it plays nicely with the require_once-like behaviour of $PAGE-&amp;gt;requires-&amp;gt;js.&lt;br /&gt;
&lt;br /&gt;
Do not pollute the global JavaScript name-space. Try to package your JavaScript into objects, and put all objects inside the global M object, like the M.mod_mymod example above. &lt;br /&gt;
&lt;br /&gt;
===Different content when JavaScript is on or off===&lt;br /&gt;
&lt;br /&gt;
Remember the overriding principals that everything should work with JavaScript off, and we should adopt a [[Progressive enhancement]] approach. However, there are valid reasons why sometimes you need different content with JavaScript is on or off. We can break it down into three cases:&lt;br /&gt;
&lt;br /&gt;
====Content that should only be visible with JavaScript off====&lt;br /&gt;
&lt;br /&gt;
An example of this is the automatic search when you are looking for a user to assign a role to. With JavaScript on, the search automatically starts after a delay. With JavaScript off, we want an explicit Search button visible.&lt;br /&gt;
&lt;br /&gt;
To handle this case, Moodle automatically add a class &#039;jsenabled&#039; to the body tag using JavaScript. So you just need to add a rule like&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
body.jsenebled .mywidget .submitbutton {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
to the stylesheet, and the button will be invisible if JavaScript is enabled.&lt;br /&gt;
&lt;br /&gt;
An alternative strategy is to remove the particular bits of HTML from the page using DOM methods. However, if your JavaScript is only loaded at the end of the page, it may take some time for the extra content to disappear, which leads to a disconcerting flicker in the page.&lt;br /&gt;
&lt;br /&gt;
Yet another approach is the old-fashioned &amp;lt;noscript&amp;gt; tag.&lt;br /&gt;
&lt;br /&gt;
====Content that needs to be visible right away when JavaScript is on====&lt;br /&gt;
&lt;br /&gt;
An example is the &amp;lt;nowiki&amp;gt;[+] or [-]&amp;lt;/nowiki&amp;gt; icon that can be used to expand/collapse each block if JavaScript is on.&lt;br /&gt;
&lt;br /&gt;
We can divide this into two subcases:&lt;br /&gt;
&lt;br /&gt;
=====Content generated by PHP code=====&lt;br /&gt;
&lt;br /&gt;
Where the HTML for the JavaScript only widget is generated by PHP, we can make it invisible when JavaScript is off using just CSS:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
.mywidget {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
body.jsenabled .mywidget {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
However, it could be argued that this approach is not really progressive enhancement.&lt;br /&gt;
&lt;br /&gt;
=====Content generated by JavaScript code=====&lt;br /&gt;
&lt;br /&gt;
This is more in keeping with progressive enhancement, and this is the way that the expand/collapse block icon is handled.&lt;br /&gt;
&lt;br /&gt;
We build the icon using DOM methods. The only problem is that as the JavaScript is loaded in the footer, there is a small delay before the icons appear. Since when the icons appear, they do not cause other content on the page to move around, that is OK. Also, this delayed appearance is becoming more common on the web. For example, on http://twitter.com/, some things only appear a moment after the main part of the page has finished loading.&lt;br /&gt;
&lt;br /&gt;
However, it the delayed appearance is really a problem, then the only solution is to embed the JavaScript that generates the extra content in the middle of the HTML, using the js_writer class.&lt;br /&gt;
&lt;br /&gt;
====Content that only appears when the user does something, when JavaScript is on====&lt;br /&gt;
&lt;br /&gt;
An example of this is something like file picker dialog that appears when you add an image to some content in the HTML editor, or the one that pops up when you click &#039;Add new question&#039; in the quiz editing interface.&lt;br /&gt;
&lt;br /&gt;
We have the same two sub-cases:&lt;br /&gt;
&lt;br /&gt;
=====Content generated by PHP code=====&lt;br /&gt;
&lt;br /&gt;
In this case, you need to make sure the content is always covered by a &#039;&#039;display: none;&#039;&#039; rule in the CSS, but then when the user takes an action like clicking a button to reveal the extra content, you need to override that class name some how, perhaps by adding or removing a className using JavaScript.&lt;br /&gt;
&lt;br /&gt;
=====Content generated by JavaScript code=====&lt;br /&gt;
&lt;br /&gt;
In this case, there is no problem. When the use triggers the extra content to appear, it is constructed using DOM methods. There may be a tiny delay, but the chances are that it will hardly be noticeable to the human eye.&lt;br /&gt;
&lt;br /&gt;
If the content generation may be slow (perhaps because it is waiting for an Ajax request) then you should display a progress icon. See, for example, the loading of the tooltip for help icons.&lt;br /&gt;
&lt;br /&gt;
===Don&#039;t break XHTML strict!===&lt;br /&gt;
&lt;br /&gt;
Remember that all Moodle output must be [[Development:XHTML|XHTML strict]], and that means that the HTML output must be well-formed XML. Inline JavaScript is a great way to break that. (JavaScript uses the &amp;lt; and &amp;amp; symbols that must be escaped in XML.) Therefore any JavaScript inline in the HTML should be escaped in a CDATA section:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
//&amp;lt;![CDATA[&lt;br /&gt;
&lt;br /&gt;
   // Your JavaScript code goes here.&lt;br /&gt;
&lt;br /&gt;
//]]&amp;gt;&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Of course, if you are following the above guidelines and putting most of your JavaScript in separate .js files, and using $PAGE-&amp;gt;requires-&amp;gt;js_init_call, then this is taken care of for you automatically.&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
&lt;br /&gt;
JavaScript support varies a lot between browsers. JavaScript needs to be tested in IE, Firefox and Safari. Ideally, Moodle will support [http://developer.yahoo.com/yui/articles/gbs/ all the browsers that YUI does].&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Development:Coding|The rest of Moodle coding guidelines]]&lt;br /&gt;
* [http://developer.yahoo.com/yui/ YUI documentation]&lt;br /&gt;
* [[Javascript FAQ]]&lt;br /&gt;
* [[Javascript and YUI 3 FAQ]]&lt;br /&gt;
* [[Development:Unobtrusive Javascript]]&lt;br /&gt;
* [[Development:JavaScript functions]]&lt;br /&gt;
* [http://developer.yahoo.com/performance/rules.html Yahoo&#039;s Best Practices for Speeding Up Your Web Site]&lt;br /&gt;
&lt;br /&gt;
[[Category:Coding guidelines|JavaScript guidelines]]&lt;br /&gt;
[[Category:Javascript|JavaScript guidelines]]&lt;br /&gt;
[[Category:AJAX|JavaScript guidelines]]&lt;br /&gt;
&lt;br /&gt;
[[ja:開発:Javaスクリプトガイドライン]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Development:JavaScript_guidelines&amp;diff=81400</id>
		<title>Development:JavaScript guidelines</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Development:JavaScript_guidelines&amp;diff=81400"/>
		<updated>2011-02-18T13:22:54Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* How to achive these general principles in Moodle */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
These guidelines can only be applied fully from Moodle 2.0 onwards, because they rely on our new API to facilitate use of JavaScript.&lt;br /&gt;
&lt;br /&gt;
When writing JavaScript for earlier versions of Moodle, please try to follow these guidelines in spirit and use the &#039;&#039;&#039;require_js&#039;&#039;&#039; function in place of $PAGE-&amp;gt;requires-&amp;gt;js_module/yui2_lib.&lt;br /&gt;
&lt;br /&gt;
==General principles==&lt;br /&gt;
&lt;br /&gt;
===Moodle should be usable without JavaScript===&lt;br /&gt;
&lt;br /&gt;
Everything in Moodle should work with JavaScript turned off. This is important for accessibility, and in line with the principles of [[Development:Unobtrusive_Javascript|unobtrusive JavaScript]] and [[Development:Progressive_enhancement|progressive enhancement]].&lt;br /&gt;
&lt;br /&gt;
===Minimise inline JavaScript===&lt;br /&gt;
&lt;br /&gt;
Almost all JavaScript code should be in separate .js files. There should be the smallest possible amount of JavaScript inline in the HTML code of pages.&lt;br /&gt;
&lt;br /&gt;
The only &amp;amp;lt;script&amp;gt; tags in the HTML should be&lt;br /&gt;
# &amp;amp;lt;script src=... tags to include the necessary .js files.&lt;br /&gt;
# Simple function calls to trigger initialisation and pass data from PHP to JavaScript. For example &amp;amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;initialise_my_widget(&#039;some&#039;, &#039;data&#039;, 123);&amp;amp;lt;/script&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Even these small amounts of JS you should not output directly. They will be generated automatically by calls to the $PAGE-&amp;gt;requries-&amp;gt;js_init_call() API. See below for details.&lt;br /&gt;
&lt;br /&gt;
You should not use old-fashioned onXXX=&amp;quot;event_handler&amp;quot; attributes in the HTML. Use Modern DOM events. The YUI events library makes this easy.&lt;br /&gt;
&lt;br /&gt;
=== JavaScript libraries ===&lt;br /&gt;
&lt;br /&gt;
* The official JavaScript library for Moodle is [[Development:YUI|YUI]]. That may not be your favourite, but it&#039;s the one that was chosen after careful research, so live with it.&lt;br /&gt;
&lt;br /&gt;
* Moodle also has its own JavaScript library code, packaged into in various JavaScript modules.&lt;br /&gt;
&lt;br /&gt;
* Moodle uses the &#039;&#039;&#039;TinyMCE&#039;&#039;&#039; HTML editor.&lt;br /&gt;
&lt;br /&gt;
===When to include the JavaScript===&lt;br /&gt;
&lt;br /&gt;
As per [http://developer.yahoo.com/performance/rules.html Yahoo&#039;s best practice guidelines], load and execute the JavaScript as late as possible, ideally the script tags should be the last thing before the &amp;amp;lt;/body&amp;gt; close tag. (This is the default behaviour with Moodle&#039;s JavaScript handling functions like $PAGE-&amp;gt;requries-&amp;gt;js_init_call().)&lt;br /&gt;
&lt;br /&gt;
Since everything should work without JavaScript, load and initialising your scripts only after everything else on the page has loaded should not be a problem and will increase the perceived page-load performance for users.&lt;br /&gt;
&lt;br /&gt;
===Minimise the number of .js files===&lt;br /&gt;
&lt;br /&gt;
Try not to use too many different .js files. Each separate file that the browser has to load incurs an overhead.&lt;br /&gt;
&lt;br /&gt;
On the other hand, organise the JavaScript logically to ease maintenance, and don&#039;t include large amounts of irrelevant JavaScript code. Code that is loaded but never used is a waste of time.&lt;br /&gt;
&lt;br /&gt;
So, if you are writing a new module that needs its own JavaScript, try starting with a single file mod/mymod/module.js. If you find that you are writing a lot of JavaScript that is only needed when the teacher edits your module, but is not needed by students, then consider splitting that code into a separate file like mod/mymod/edit.js, and only including it where needed.&lt;br /&gt;
&lt;br /&gt;
==How to achive these general principles in Moodle==&lt;br /&gt;
&lt;br /&gt;
The rest of this page explains how you can achieve the above goals. Note that this particularly applies to loading and using the YUI 3 library which is Moodle 2.0&#039;s default. You should check which version of YUI Moodle is using as it may lag behind the latest YUI release (and, hence, the documentation).&lt;br /&gt;
&lt;br /&gt;
===Getting Moodle to load your JavaScript files===&lt;br /&gt;
&lt;br /&gt;
Everything required by the current page is tracked by the $PAGE-&amp;gt;requires object, which is an instance of the [http://phpdocs.moodle.org/HEAD/moodlecore/page_requirements_manager.html page_requirements_manager] class defined in lib/outputrequirementslib.php.&lt;br /&gt;
&lt;br /&gt;
The most important method in this class is the -&amp;gt;js_init_call(...) method. You use it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.mod_mymod.init_something&#039;, array(&#039;some&#039;, &#039;data&#039;, &#039;from&#039;, &#039;PHP&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that this will implicitly load the JavaScript code in mod/mymod/module.js, and then call the M.mod_mymod.init_something function passing four string arguments &#039;some&#039;, &#039;data&#039;, &#039;from&#039;, &#039;PHP&#039;. You can pass any PHP type as an argument. The PHP values are encoded with json_encode before being passed to JavaScript, so numbers, strings, arrays and objects all work.&lt;br /&gt;
&lt;br /&gt;
Sometimes, the code in the JavaScript module mod/mymod/module.js may require some other JavaScript libraries to be loaded, or it may require some language strings. In that case you need to use the full form of js_init_call:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$jsmodule = array(&lt;br /&gt;
    &#039;name&#039;     =&amp;gt; &#039;mod_mymod&#039;,&lt;br /&gt;
    &#039;fullpath&#039; =&amp;gt; &#039;/mod/mymod/module.js&#039;,&lt;br /&gt;
    &#039;requires&#039; =&amp;gt; array(&#039;base&#039;, &#039;io&#039;, &#039;node&#039;, &#039;json&#039;),&lt;br /&gt;
    &#039;strings&#039; =&amp;gt; array(&lt;br /&gt;
        array(&#039;something&#039;, &#039;mymod&#039;),&lt;br /&gt;
        array(&#039;confirmdelete&#039;, &#039;mymod&#039;),&lt;br /&gt;
        array(&#039;yes&#039;, &#039;moodle&#039;),&lt;br /&gt;
        array(&#039;no&#039;, &#039;moodle&#039;)&lt;br /&gt;
    )&lt;br /&gt;
);&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.mod_mymod.init_something&#039;, array(&#039;some&#039;, &#039;data&#039;, &#039;from&#039;, &#039;PHP&#039;), false, $jsmodule);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
(Naturally, it would be a good idea to put the definition of the $jsmodule array somewhere central like in the locallib.php file.)&lt;br /&gt;
&lt;br /&gt;
The third (boolean) parameter is defined as &amp;quot;Wait for DOM Ready&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The libraries in the &#039;requires&#039; sub-array are YUI3 (or YUI2) libraries. Moodle contains YUIs &#039;phploader&#039; which understands what the library dependencies are, so this is all taken care of for you. &lt;br /&gt;
&lt;br /&gt;
The strings are Moodle language strings. In order for Moodle to have correctly determined the user&#039;s language, you should only call js_init_call after the call to require_login, which sets the current course, and ensures the user is logged in.&lt;br /&gt;
Strings that are passed to Javascript in this way are then available from Javascript using M.util.get_string(), which works just like the PHP function.&lt;br /&gt;
&lt;br /&gt;
$PAGE-&amp;gt;requires keeps track of which files have been included. For example if two other modules both require the YUI base module, then it is only included once.&lt;br /&gt;
&lt;br /&gt;
Your &#039;module.js&#039; file in your plugin&#039;s directory will look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
M.mod_mymod = {};&lt;br /&gt;
&lt;br /&gt;
M.mod_mymod.init = function(Y) {&lt;br /&gt;
&lt;br /&gt;
    // example to submit a form field on change&lt;br /&gt;
    Y.on(&#039;change&#039;, function(e) {&lt;br /&gt;
        Y.one(&#039;#mform1&#039;).submit();&lt;br /&gt;
    }, &#039;#id_fieldname&#039; );&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mod_mymod&#039;&#039; needs changed to reflect the plugin type (e.g. mod,block,local,coursereport) and the name of your plugin throughout.&lt;br /&gt;
&lt;br /&gt;
===JavaScript coding style===&lt;br /&gt;
&lt;br /&gt;
Moodle JavaScript code should should follow the same [[Development:Coding_style|coding style as Moodle PHP code]], allowing for the differences between PHP and JavaScript.&lt;br /&gt;
&lt;br /&gt;
For example, all the rules on &#039;&#039;function_names&#039;&#039;, &#039;&#039;class_names&#039;&#039; and &#039;&#039;variablenames&#039;&#039; apply. You should document your code with [http://jsdoc.sourceforge.net/ JSDoc] comments. Layout your JavaScript expressions and statements like the equivalent PHP ones.&lt;br /&gt;
&lt;br /&gt;
Normally, your .js files should simply define things like functions, classes and variables. When the file is loaded, no JavaScript code should actually be executed that has any effect unless it is the sort of code that can safely be executed once per HTML page. This is so that it plays nicely with the require_once-like behaviour of $PAGE-&amp;gt;requires-&amp;gt;js.&lt;br /&gt;
&lt;br /&gt;
Do not pollute the global JavaScript name-space. Try to package your JavaScript into objects, and put all objects inside the global M object, like the M.mod_mymod example above. &lt;br /&gt;
&lt;br /&gt;
===Different content when JavaScript is on or off===&lt;br /&gt;
&lt;br /&gt;
Remember the overriding principals that everything should work with JavaScript off, and we should adopt a [[Progressive enhancement]] approach. However, there are valid reasons why sometimes you need different content with JavaScript is on or off. We can break it down into three cases:&lt;br /&gt;
&lt;br /&gt;
====Content that should only be visible with JavaScript off====&lt;br /&gt;
&lt;br /&gt;
An example of this is the automatic search when you are looking for a user to assign a role to. With JavaScript on, the search automatically starts after a delay. With JavaScript off, we want an explicit Search button visible.&lt;br /&gt;
&lt;br /&gt;
To handle this case, Moodle automatically add a class &#039;jsenabled&#039; to the body tag using JavaScript. So you just need to add a rule like&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
body.jsenebled .mywidget .submitbutton {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
to the stylesheet, and the button will be invisible if JavaScript is enabled.&lt;br /&gt;
&lt;br /&gt;
An alternative strategy is to remove the particular bits of HTML from the page using DOM methods. However, if your JavaScript is only loaded at the end of the page, it may take some time for the extra content to disappear, which leads to a disconcerting flicker in the page.&lt;br /&gt;
&lt;br /&gt;
Yet another approach is the old-fashioned &amp;lt;noscript&amp;gt; tag.&lt;br /&gt;
&lt;br /&gt;
====Content that needs to be visible right away when JavaScript is on====&lt;br /&gt;
&lt;br /&gt;
An example is the &amp;lt;nowiki&amp;gt;[+] or [-]&amp;lt;/nowiki&amp;gt; icon that can be used to expand/collapse each block if JavaScript is on.&lt;br /&gt;
&lt;br /&gt;
We can divide this into two subcases:&lt;br /&gt;
&lt;br /&gt;
=====Content generated by PHP code=====&lt;br /&gt;
&lt;br /&gt;
Where the HTML for the JavaScript only widget is generated by PHP, we can make it invisible when JavaScript is off using just CSS:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
.mywidget {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
body.jsenabled .mywidget {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
However, it could be argued that this approach is not really progressive enhancement.&lt;br /&gt;
&lt;br /&gt;
=====Content generated by JavaScript code=====&lt;br /&gt;
&lt;br /&gt;
This is more in keeping with progressive enhancement, and this is the way that the expand/collapse block icon is handled.&lt;br /&gt;
&lt;br /&gt;
We build the icon using DOM methods. The only problem is that as the JavaScript is loaded in the footer, there is a small delay before the icons appear. Since when the icons appear, they do not cause other content on the page to move around, that is OK. Also, this delayed appearance is becoming more common on the web. For example, on http://twitter.com/, some things only appear a moment after the main part of the page has finished loading.&lt;br /&gt;
&lt;br /&gt;
However, it the delayed appearance is really a problem, then the only solution is to embed the JavaScript that generates the extra content in the middle of the HTML, using the js_writer class.&lt;br /&gt;
&lt;br /&gt;
====Content that only appears when the user does something, when JavaScript is on====&lt;br /&gt;
&lt;br /&gt;
An example of this is something like file picker dialog that appears when you add an image to some content in the HTML editor, or the one that pops up when you click &#039;Add new question&#039; in the quiz editing interface.&lt;br /&gt;
&lt;br /&gt;
We have the same two sub-cases:&lt;br /&gt;
&lt;br /&gt;
=====Content generated by PHP code=====&lt;br /&gt;
&lt;br /&gt;
In this case, you need to make sure the content is always covered by a &#039;&#039;display: none;&#039;&#039; rule in the CSS, but then when the user takes an action like clicking a button to reveal the extra content, you need to override that class name some how, perhaps by adding or removing a className using JavaScript.&lt;br /&gt;
&lt;br /&gt;
=====Content generated by JavaScript code=====&lt;br /&gt;
&lt;br /&gt;
In this case, there is no problem. When the use triggers the extra content to appear, it is constructed using DOM methods. There may be a tiny delay, but the chances are that it will hardly be noticeable to the human eye.&lt;br /&gt;
&lt;br /&gt;
If the content generation may be slow (perhaps because it is waiting for an Ajax request) then you should display a progress icon. See, for example, the loading of the tooltip for help icons.&lt;br /&gt;
&lt;br /&gt;
===Don&#039;t break XHTML strict!===&lt;br /&gt;
&lt;br /&gt;
Remember that all Moodle output must be [[Development:XHTML|XHTML strict]], and that means that the HTML output must be well-formed XML. Inline JavaScript is a great way to break that. (JavaScript uses the &amp;lt; and &amp;amp; symbols that must be escaped in XML.) Therefore any JavaScript inline in the HTML should be escaped in a CDATA section:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
//&amp;lt;![CDATA[&lt;br /&gt;
&lt;br /&gt;
   // Your JavaScript code goes here.&lt;br /&gt;
&lt;br /&gt;
//]]&amp;gt;&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Of course, if you are following the above guidelines and putting most of your JavaScript in separate .js files, and using $PAGE-&amp;gt;requires-&amp;gt;js_init_call, then this is taken care of for you automatically.&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
&lt;br /&gt;
JavaScript support varies a lot between browsers. JavaScript needs to be tested in IE, Firefox and Safari. Ideally, Moodle will support [http://developer.yahoo.com/yui/articles/gbs/ all the browsers that YUI does].&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Development:Coding|The rest of Moodle coding guidelines]]&lt;br /&gt;
* [http://developer.yahoo.com/yui/ YUI documentation]&lt;br /&gt;
* [[Javascript FAQ]]&lt;br /&gt;
* [[Javascript and YUI 3 FAQ]]&lt;br /&gt;
* [[Development:Unobtrusive Javascript]]&lt;br /&gt;
* [[Development:JavaScript functions]]&lt;br /&gt;
* [http://developer.yahoo.com/performance/rules.html Yahoo&#039;s Best Practices for Speeding Up Your Web Site]&lt;br /&gt;
&lt;br /&gt;
[[Category:Coding guidelines|JavaScript guidelines]]&lt;br /&gt;
[[Category:Javascript|JavaScript guidelines]]&lt;br /&gt;
[[Category:AJAX|JavaScript guidelines]]&lt;br /&gt;
&lt;br /&gt;
[[ja:開発:Javaスクリプトガイドライン]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Development:JavaScript_guidelines&amp;diff=81399</id>
		<title>Development:JavaScript guidelines</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Development:JavaScript_guidelines&amp;diff=81399"/>
		<updated>2011-02-18T13:20:24Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* Getting Moodle to load your JavaScript files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
These guidelines can only be applied fully from Moodle 2.0 onwards, because they rely on our new API to facilitate use of JavaScript.&lt;br /&gt;
&lt;br /&gt;
When writing JavaScript for earlier versions of Moodle, please try to follow these guidelines in spirit and use the &#039;&#039;&#039;require_js&#039;&#039;&#039; function in place of $PAGE-&amp;gt;requires-&amp;gt;js_module/yui2_lib.&lt;br /&gt;
&lt;br /&gt;
==General principles==&lt;br /&gt;
&lt;br /&gt;
===Moodle should be usable without JavaScript===&lt;br /&gt;
&lt;br /&gt;
Everything in Moodle should work with JavaScript turned off. This is important for accessibility, and in line with the principles of [[Development:Unobtrusive_Javascript|unobtrusive JavaScript]] and [[Development:Progressive_enhancement|progressive enhancement]].&lt;br /&gt;
&lt;br /&gt;
===Minimise inline JavaScript===&lt;br /&gt;
&lt;br /&gt;
Almost all JavaScript code should be in separate .js files. There should be the smallest possible amount of JavaScript inline in the HTML code of pages.&lt;br /&gt;
&lt;br /&gt;
The only &amp;amp;lt;script&amp;gt; tags in the HTML should be&lt;br /&gt;
# &amp;amp;lt;script src=... tags to include the necessary .js files.&lt;br /&gt;
# Simple function calls to trigger initialisation and pass data from PHP to JavaScript. For example &amp;amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;initialise_my_widget(&#039;some&#039;, &#039;data&#039;, 123);&amp;amp;lt;/script&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Even these small amounts of JS you should not output directly. They will be generated automatically by calls to the $PAGE-&amp;gt;requries-&amp;gt;js_init_call() API. See below for details.&lt;br /&gt;
&lt;br /&gt;
You should not use old-fashioned onXXX=&amp;quot;event_handler&amp;quot; attributes in the HTML. Use Modern DOM events. The YUI events library makes this easy.&lt;br /&gt;
&lt;br /&gt;
=== JavaScript libraries ===&lt;br /&gt;
&lt;br /&gt;
* The official JavaScript library for Moodle is [[Development:YUI|YUI]]. That may not be your favourite, but it&#039;s the one that was chosen after careful research, so live with it.&lt;br /&gt;
&lt;br /&gt;
* Moodle also has its own JavaScript library code, packaged into in various JavaScript modules.&lt;br /&gt;
&lt;br /&gt;
* Moodle uses the &#039;&#039;&#039;TinyMCE&#039;&#039;&#039; HTML editor.&lt;br /&gt;
&lt;br /&gt;
===When to include the JavaScript===&lt;br /&gt;
&lt;br /&gt;
As per [http://developer.yahoo.com/performance/rules.html Yahoo&#039;s best practice guidelines], load and execute the JavaScript as late as possible, ideally the script tags should be the last thing before the &amp;amp;lt;/body&amp;gt; close tag. (This is the default behaviour with Moodle&#039;s JavaScript handling functions like $PAGE-&amp;gt;requries-&amp;gt;js_init_call().)&lt;br /&gt;
&lt;br /&gt;
Since everything should work without JavaScript, load and initialising your scripts only after everything else on the page has loaded should not be a problem and will increase the perceived page-load performance for users.&lt;br /&gt;
&lt;br /&gt;
===Minimise the number of .js files===&lt;br /&gt;
&lt;br /&gt;
Try not to use too many different .js files. Each separate file that the browser has to load incurs an overhead.&lt;br /&gt;
&lt;br /&gt;
On the other hand, organise the JavaScript logically to ease maintenance, and don&#039;t include large amounts of irrelevant JavaScript code. Code that is loaded but never used is a waste of time.&lt;br /&gt;
&lt;br /&gt;
So, if you are writing a new module that needs its own JavaScript, try starting with a single file mod/mymod/module.js. If you find that you are writing a lot of JavaScript that is only needed when the teacher edits your module, but is not needed by students, then consider splitting that code into a separate file like mod/mymod/edit.js, and only including it where needed.&lt;br /&gt;
&lt;br /&gt;
==How to achive these general principles in Moodle==&lt;br /&gt;
&lt;br /&gt;
The rest of this page explains how you can achieve the above goals.&lt;br /&gt;
&lt;br /&gt;
===Getting Moodle to load your JavaScript files===&lt;br /&gt;
&lt;br /&gt;
Everything required by the current page is tracked by the $PAGE-&amp;gt;requires object, which is an instance of the [http://phpdocs.moodle.org/HEAD/moodlecore/page_requirements_manager.html page_requirements_manager] class defined in lib/outputrequirementslib.php.&lt;br /&gt;
&lt;br /&gt;
The most important method in this class is the -&amp;gt;js_init_call(...) method. You use it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.mod_mymod.init_something&#039;, array(&#039;some&#039;, &#039;data&#039;, &#039;from&#039;, &#039;PHP&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that this will implicitly load the JavaScript code in mod/mymod/module.js, and then call the M.mod_mymod.init_something function passing four string arguments &#039;some&#039;, &#039;data&#039;, &#039;from&#039;, &#039;PHP&#039;. You can pass any PHP type as an argument. The PHP values are encoded with json_encode before being passed to JavaScript, so numbers, strings, arrays and objects all work.&lt;br /&gt;
&lt;br /&gt;
Sometimes, the code in the JavaScript module mod/mymod/module.js may require some other JavaScript libraries to be loaded, or it may require some language strings. In that case you need to use the full form of js_init_call:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$jsmodule = array(&lt;br /&gt;
    &#039;name&#039;     =&amp;gt; &#039;mod_mymod&#039;,&lt;br /&gt;
    &#039;fullpath&#039; =&amp;gt; &#039;/mod/mymod/module.js&#039;,&lt;br /&gt;
    &#039;requires&#039; =&amp;gt; array(&#039;base&#039;, &#039;io&#039;, &#039;node&#039;, &#039;json&#039;),&lt;br /&gt;
    &#039;strings&#039; =&amp;gt; array(&lt;br /&gt;
        array(&#039;something&#039;, &#039;mymod&#039;),&lt;br /&gt;
        array(&#039;confirmdelete&#039;, &#039;mymod&#039;),&lt;br /&gt;
        array(&#039;yes&#039;, &#039;moodle&#039;),&lt;br /&gt;
        array(&#039;no&#039;, &#039;moodle&#039;)&lt;br /&gt;
    )&lt;br /&gt;
);&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.mod_mymod.init_something&#039;, array(&#039;some&#039;, &#039;data&#039;, &#039;from&#039;, &#039;PHP&#039;), false, $jsmodule);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
(Naturally, it would be a good idea to put the definition of the $jsmodule array somewhere central like in the locallib.php file.)&lt;br /&gt;
&lt;br /&gt;
The third (boolean) parameter is defined as &amp;quot;Wait for DOM Ready&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The libraries in the &#039;requires&#039; sub-array are YUI3 (or YUI2) libraries. Moodle contains YUIs &#039;phploader&#039; which understands what the library dependencies are, so this is all taken care of for you. &lt;br /&gt;
&lt;br /&gt;
The strings are Moodle language strings. In order for Moodle to have correctly determined the user&#039;s language, you should only call js_init_call after the call to require_login, which sets the current course, and ensures the user is logged in.&lt;br /&gt;
Strings that are passed to Javascript in this way are then available from Javascript using M.util.get_string(), which works just like the PHP function.&lt;br /&gt;
&lt;br /&gt;
$PAGE-&amp;gt;requires keeps track of which files have been included. For example if two other modules both require the YUI base module, then it is only included once.&lt;br /&gt;
&lt;br /&gt;
Your &#039;module.js&#039; file in your plugin&#039;s directory will look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
M.mod_mymod = {};&lt;br /&gt;
&lt;br /&gt;
M.mod_mymod.init = function(Y) {&lt;br /&gt;
&lt;br /&gt;
    // example to submit a form field on change&lt;br /&gt;
    Y.on(&#039;change&#039;, function(e) {&lt;br /&gt;
        Y.one(&#039;#mform1&#039;).submit();&lt;br /&gt;
    }, &#039;#id_fieldname&#039; );&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mod_mymod&#039;&#039; needs changed to reflect the plugin type (e.g. mod,block,local,coursereport) and the name of your plugin throughout.&lt;br /&gt;
&lt;br /&gt;
===JavaScript coding style===&lt;br /&gt;
&lt;br /&gt;
Moodle JavaScript code should should follow the same [[Development:Coding_style|coding style as Moodle PHP code]], allowing for the differences between PHP and JavaScript.&lt;br /&gt;
&lt;br /&gt;
For example, all the rules on &#039;&#039;function_names&#039;&#039;, &#039;&#039;class_names&#039;&#039; and &#039;&#039;variablenames&#039;&#039; apply. You should document your code with [http://jsdoc.sourceforge.net/ JSDoc] comments. Layout your JavaScript expressions and statements like the equivalent PHP ones.&lt;br /&gt;
&lt;br /&gt;
Normally, your .js files should simply define things like functions, classes and variables. When the file is loaded, no JavaScript code should actually be executed that has any effect unless it is the sort of code that can safely be executed once per HTML page. This is so that it plays nicely with the require_once-like behaviour of $PAGE-&amp;gt;requires-&amp;gt;js.&lt;br /&gt;
&lt;br /&gt;
Do not pollute the global JavaScript name-space. Try to package your JavaScript into objects, and put all objects inside the global M object, like the M.mod_mymod example above. &lt;br /&gt;
&lt;br /&gt;
===Different content when JavaScript is on or off===&lt;br /&gt;
&lt;br /&gt;
Remember the overriding principals that everything should work with JavaScript off, and we should adopt a [[Progressive enhancement]] approach. However, there are valid reasons why sometimes you need different content with JavaScript is on or off. We can break it down into three cases:&lt;br /&gt;
&lt;br /&gt;
====Content that should only be visible with JavaScript off====&lt;br /&gt;
&lt;br /&gt;
An example of this is the automatic search when you are looking for a user to assign a role to. With JavaScript on, the search automatically starts after a delay. With JavaScript off, we want an explicit Search button visible.&lt;br /&gt;
&lt;br /&gt;
To handle this case, Moodle automatically add a class &#039;jsenabled&#039; to the body tag using JavaScript. So you just need to add a rule like&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
body.jsenebled .mywidget .submitbutton {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
to the stylesheet, and the button will be invisible if JavaScript is enabled.&lt;br /&gt;
&lt;br /&gt;
An alternative strategy is to remove the particular bits of HTML from the page using DOM methods. However, if your JavaScript is only loaded at the end of the page, it may take some time for the extra content to disappear, which leads to a disconcerting flicker in the page.&lt;br /&gt;
&lt;br /&gt;
Yet another approach is the old-fashioned &amp;lt;noscript&amp;gt; tag.&lt;br /&gt;
&lt;br /&gt;
====Content that needs to be visible right away when JavaScript is on====&lt;br /&gt;
&lt;br /&gt;
An example is the &amp;lt;nowiki&amp;gt;[+] or [-]&amp;lt;/nowiki&amp;gt; icon that can be used to expand/collapse each block if JavaScript is on.&lt;br /&gt;
&lt;br /&gt;
We can divide this into two subcases:&lt;br /&gt;
&lt;br /&gt;
=====Content generated by PHP code=====&lt;br /&gt;
&lt;br /&gt;
Where the HTML for the JavaScript only widget is generated by PHP, we can make it invisible when JavaScript is off using just CSS:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
.mywidget {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
body.jsenabled .mywidget {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
However, it could be argued that this approach is not really progressive enhancement.&lt;br /&gt;
&lt;br /&gt;
=====Content generated by JavaScript code=====&lt;br /&gt;
&lt;br /&gt;
This is more in keeping with progressive enhancement, and this is the way that the expand/collapse block icon is handled.&lt;br /&gt;
&lt;br /&gt;
We build the icon using DOM methods. The only problem is that as the JavaScript is loaded in the footer, there is a small delay before the icons appear. Since when the icons appear, they do not cause other content on the page to move around, that is OK. Also, this delayed appearance is becoming more common on the web. For example, on http://twitter.com/, some things only appear a moment after the main part of the page has finished loading.&lt;br /&gt;
&lt;br /&gt;
However, it the delayed appearance is really a problem, then the only solution is to embed the JavaScript that generates the extra content in the middle of the HTML, using the js_writer class.&lt;br /&gt;
&lt;br /&gt;
====Content that only appears when the user does something, when JavaScript is on====&lt;br /&gt;
&lt;br /&gt;
An example of this is something like file picker dialog that appears when you add an image to some content in the HTML editor, or the one that pops up when you click &#039;Add new question&#039; in the quiz editing interface.&lt;br /&gt;
&lt;br /&gt;
We have the same two sub-cases:&lt;br /&gt;
&lt;br /&gt;
=====Content generated by PHP code=====&lt;br /&gt;
&lt;br /&gt;
In this case, you need to make sure the content is always covered by a &#039;&#039;display: none;&#039;&#039; rule in the CSS, but then when the user takes an action like clicking a button to reveal the extra content, you need to override that class name some how, perhaps by adding or removing a className using JavaScript.&lt;br /&gt;
&lt;br /&gt;
=====Content generated by JavaScript code=====&lt;br /&gt;
&lt;br /&gt;
In this case, there is no problem. When the use triggers the extra content to appear, it is constructed using DOM methods. There may be a tiny delay, but the chances are that it will hardly be noticeable to the human eye.&lt;br /&gt;
&lt;br /&gt;
If the content generation may be slow (perhaps because it is waiting for an Ajax request) then you should display a progress icon. See, for example, the loading of the tooltip for help icons.&lt;br /&gt;
&lt;br /&gt;
===Don&#039;t break XHTML strict!===&lt;br /&gt;
&lt;br /&gt;
Remember that all Moodle output must be [[Development:XHTML|XHTML strict]], and that means that the HTML output must be well-formed XML. Inline JavaScript is a great way to break that. (JavaScript uses the &amp;lt; and &amp;amp; symbols that must be escaped in XML.) Therefore any JavaScript inline in the HTML should be escaped in a CDATA section:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
//&amp;lt;![CDATA[&lt;br /&gt;
&lt;br /&gt;
   // Your JavaScript code goes here.&lt;br /&gt;
&lt;br /&gt;
//]]&amp;gt;&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Of course, if you are following the above guidelines and putting most of your JavaScript in separate .js files, and using $PAGE-&amp;gt;requires-&amp;gt;js_init_call, then this is taken care of for you automatically.&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
&lt;br /&gt;
JavaScript support varies a lot between browsers. JavaScript needs to be tested in IE, Firefox and Safari. Ideally, Moodle will support [http://developer.yahoo.com/yui/articles/gbs/ all the browsers that YUI does].&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Development:Coding|The rest of Moodle coding guidelines]]&lt;br /&gt;
* [http://developer.yahoo.com/yui/ YUI documentation]&lt;br /&gt;
* [[Javascript FAQ]]&lt;br /&gt;
* [[Javascript and YUI 3 FAQ]]&lt;br /&gt;
* [[Development:Unobtrusive Javascript]]&lt;br /&gt;
* [[Development:JavaScript functions]]&lt;br /&gt;
* [http://developer.yahoo.com/performance/rules.html Yahoo&#039;s Best Practices for Speeding Up Your Web Site]&lt;br /&gt;
&lt;br /&gt;
[[Category:Coding guidelines|JavaScript guidelines]]&lt;br /&gt;
[[Category:Javascript|JavaScript guidelines]]&lt;br /&gt;
[[Category:AJAX|JavaScript guidelines]]&lt;br /&gt;
&lt;br /&gt;
[[ja:開発:Javaスクリプトガイドライン]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Development:JavaScript_guidelines&amp;diff=81398</id>
		<title>Development:JavaScript guidelines</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Development:JavaScript_guidelines&amp;diff=81398"/>
		<updated>2011-02-18T13:16:26Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* Getting Moodle to load your JavaScript files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
These guidelines can only be applied fully from Moodle 2.0 onwards, because they rely on our new API to facilitate use of JavaScript.&lt;br /&gt;
&lt;br /&gt;
When writing JavaScript for earlier versions of Moodle, please try to follow these guidelines in spirit and use the &#039;&#039;&#039;require_js&#039;&#039;&#039; function in place of $PAGE-&amp;gt;requires-&amp;gt;js_module/yui2_lib.&lt;br /&gt;
&lt;br /&gt;
==General principles==&lt;br /&gt;
&lt;br /&gt;
===Moodle should be usable without JavaScript===&lt;br /&gt;
&lt;br /&gt;
Everything in Moodle should work with JavaScript turned off. This is important for accessibility, and in line with the principles of [[Development:Unobtrusive_Javascript|unobtrusive JavaScript]] and [[Development:Progressive_enhancement|progressive enhancement]].&lt;br /&gt;
&lt;br /&gt;
===Minimise inline JavaScript===&lt;br /&gt;
&lt;br /&gt;
Almost all JavaScript code should be in separate .js files. There should be the smallest possible amount of JavaScript inline in the HTML code of pages.&lt;br /&gt;
&lt;br /&gt;
The only &amp;amp;lt;script&amp;gt; tags in the HTML should be&lt;br /&gt;
# &amp;amp;lt;script src=... tags to include the necessary .js files.&lt;br /&gt;
# Simple function calls to trigger initialisation and pass data from PHP to JavaScript. For example &amp;amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;initialise_my_widget(&#039;some&#039;, &#039;data&#039;, 123);&amp;amp;lt;/script&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Even these small amounts of JS you should not output directly. They will be generated automatically by calls to the $PAGE-&amp;gt;requries-&amp;gt;js_init_call() API. See below for details.&lt;br /&gt;
&lt;br /&gt;
You should not use old-fashioned onXXX=&amp;quot;event_handler&amp;quot; attributes in the HTML. Use Modern DOM events. The YUI events library makes this easy.&lt;br /&gt;
&lt;br /&gt;
=== JavaScript libraries ===&lt;br /&gt;
&lt;br /&gt;
* The official JavaScript library for Moodle is [[Development:YUI|YUI]]. That may not be your favourite, but it&#039;s the one that was chosen after careful research, so live with it.&lt;br /&gt;
&lt;br /&gt;
* Moodle also has its own JavaScript library code, packaged into in various JavaScript modules.&lt;br /&gt;
&lt;br /&gt;
* Moodle uses the &#039;&#039;&#039;TinyMCE&#039;&#039;&#039; HTML editor.&lt;br /&gt;
&lt;br /&gt;
===When to include the JavaScript===&lt;br /&gt;
&lt;br /&gt;
As per [http://developer.yahoo.com/performance/rules.html Yahoo&#039;s best practice guidelines], load and execute the JavaScript as late as possible, ideally the script tags should be the last thing before the &amp;amp;lt;/body&amp;gt; close tag. (This is the default behaviour with Moodle&#039;s JavaScript handling functions like $PAGE-&amp;gt;requries-&amp;gt;js_init_call().)&lt;br /&gt;
&lt;br /&gt;
Since everything should work without JavaScript, load and initialising your scripts only after everything else on the page has loaded should not be a problem and will increase the perceived page-load performance for users.&lt;br /&gt;
&lt;br /&gt;
===Minimise the number of .js files===&lt;br /&gt;
&lt;br /&gt;
Try not to use too many different .js files. Each separate file that the browser has to load incurs an overhead.&lt;br /&gt;
&lt;br /&gt;
On the other hand, organise the JavaScript logically to ease maintenance, and don&#039;t include large amounts of irrelevant JavaScript code. Code that is loaded but never used is a waste of time.&lt;br /&gt;
&lt;br /&gt;
So, if you are writing a new module that needs its own JavaScript, try starting with a single file mod/mymod/module.js. If you find that you are writing a lot of JavaScript that is only needed when the teacher edits your module, but is not needed by students, then consider splitting that code into a separate file like mod/mymod/edit.js, and only including it where needed.&lt;br /&gt;
&lt;br /&gt;
==How to achive these general principles in Moodle==&lt;br /&gt;
&lt;br /&gt;
The rest of this page explains how you can achieve the above goals.&lt;br /&gt;
&lt;br /&gt;
===Getting Moodle to load your JavaScript files===&lt;br /&gt;
&lt;br /&gt;
Everything required by the current page is tracked by the $PAGE-&amp;gt;requires object, which is an instance of the [http://phpdocs.moodle.org/HEAD/moodlecore/page_requirements_manager.html page_requirements_manager] class defined in lib/outputrequirementslib.php.&lt;br /&gt;
&lt;br /&gt;
The most important method in this class is the -&amp;gt;js_init_call(...) method. You use it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.mod_mymod.init_something&#039;, array(&#039;some&#039;, &#039;data&#039;, &#039;from&#039;, &#039;PHP&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that this will implicitly load the JavaScript code in mod/mymod/module.js, and then call the M.mod_mymod.init_something function passing four string arguments &#039;some&#039;, &#039;data&#039;, &#039;from&#039;, &#039;PHP&#039;. You can pass any PHP type as an argument. The PHP values are encoded with json_encode before being passed to JavaScript, so numbers, strings, arrays and objects all work.&lt;br /&gt;
&lt;br /&gt;
Sometimes, the code in the JavaScript module mod/mymod/module.js may require some other JavaScript libraries to be loaded, or it may require some language strings. In that case you need to use the full form of js_init_call:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$jsmodule = array(&lt;br /&gt;
    &#039;name&#039;     =&amp;gt; &#039;mod_mymod&#039;,&lt;br /&gt;
    &#039;fullpath&#039; =&amp;gt; &#039;/mod/mymod/module.js&#039;,&lt;br /&gt;
    &#039;requires&#039; =&amp;gt; array(&#039;base&#039;, &#039;io&#039;, &#039;node&#039;, &#039;json&#039;),&lt;br /&gt;
    &#039;strings&#039; =&amp;gt; array(&lt;br /&gt;
        array(&#039;something&#039;, &#039;mymod&#039;),&lt;br /&gt;
        array(&#039;confirmdelete&#039;, &#039;mymod&#039;),&lt;br /&gt;
        array(&#039;yes&#039;, &#039;moodle&#039;),&lt;br /&gt;
        array(&#039;no&#039;, &#039;moodle&#039;)&lt;br /&gt;
    )&lt;br /&gt;
);&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.mod_mymod.init_something&#039;, array(&#039;some&#039;, &#039;data&#039;, &#039;from&#039;, &#039;PHP&#039;), false, $jsmodule);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
(Naturally, it would be a good idea to put the definition of the $jsmodule array somewhere central like in the locallib.php file.)&lt;br /&gt;
&lt;br /&gt;
The third (boolean) parameter is defined as &amp;quot;Wait for DOM Ready&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The libraries in the &#039;requires&#039; sub-array are YUI3 (or YUI2) libraries. Moodle contains YUIs &#039;phploader&#039; which understands what the library dependencies are, so this is all taken care of for you. &lt;br /&gt;
&lt;br /&gt;
The strings are Moodle language strings. In order for Moodle to have correctly determined the user&#039;s language, you should only call js_init_call after the call to require_login, which sets the current course, and ensures the user is logged in.&lt;br /&gt;
Strings that are passed to Javascript in this way are then available from Javascript using M.util.get_string(), which works just like the PHP function.&lt;br /&gt;
&lt;br /&gt;
$PAGE-&amp;gt;requires keeps track of which files have been included. For example if two other modules both require the YUI base module, then it is only included once.&lt;br /&gt;
&lt;br /&gt;
===JavaScript coding style===&lt;br /&gt;
&lt;br /&gt;
Moodle JavaScript code should should follow the same [[Development:Coding_style|coding style as Moodle PHP code]], allowing for the differences between PHP and JavaScript.&lt;br /&gt;
&lt;br /&gt;
For example, all the rules on &#039;&#039;function_names&#039;&#039;, &#039;&#039;class_names&#039;&#039; and &#039;&#039;variablenames&#039;&#039; apply. You should document your code with [http://jsdoc.sourceforge.net/ JSDoc] comments. Layout your JavaScript expressions and statements like the equivalent PHP ones.&lt;br /&gt;
&lt;br /&gt;
Normally, your .js files should simply define things like functions, classes and variables. When the file is loaded, no JavaScript code should actually be executed that has any effect unless it is the sort of code that can safely be executed once per HTML page. This is so that it plays nicely with the require_once-like behaviour of $PAGE-&amp;gt;requires-&amp;gt;js.&lt;br /&gt;
&lt;br /&gt;
Do not pollute the global JavaScript name-space. Try to package your JavaScript into objects, and put all objects inside the global M object, like the M.mod_mymod example above. &lt;br /&gt;
&lt;br /&gt;
===Different content when JavaScript is on or off===&lt;br /&gt;
&lt;br /&gt;
Remember the overriding principals that everything should work with JavaScript off, and we should adopt a [[Progressive enhancement]] approach. However, there are valid reasons why sometimes you need different content with JavaScript is on or off. We can break it down into three cases:&lt;br /&gt;
&lt;br /&gt;
====Content that should only be visible with JavaScript off====&lt;br /&gt;
&lt;br /&gt;
An example of this is the automatic search when you are looking for a user to assign a role to. With JavaScript on, the search automatically starts after a delay. With JavaScript off, we want an explicit Search button visible.&lt;br /&gt;
&lt;br /&gt;
To handle this case, Moodle automatically add a class &#039;jsenabled&#039; to the body tag using JavaScript. So you just need to add a rule like&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
body.jsenebled .mywidget .submitbutton {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
to the stylesheet, and the button will be invisible if JavaScript is enabled.&lt;br /&gt;
&lt;br /&gt;
An alternative strategy is to remove the particular bits of HTML from the page using DOM methods. However, if your JavaScript is only loaded at the end of the page, it may take some time for the extra content to disappear, which leads to a disconcerting flicker in the page.&lt;br /&gt;
&lt;br /&gt;
Yet another approach is the old-fashioned &amp;lt;noscript&amp;gt; tag.&lt;br /&gt;
&lt;br /&gt;
====Content that needs to be visible right away when JavaScript is on====&lt;br /&gt;
&lt;br /&gt;
An example is the &amp;lt;nowiki&amp;gt;[+] or [-]&amp;lt;/nowiki&amp;gt; icon that can be used to expand/collapse each block if JavaScript is on.&lt;br /&gt;
&lt;br /&gt;
We can divide this into two subcases:&lt;br /&gt;
&lt;br /&gt;
=====Content generated by PHP code=====&lt;br /&gt;
&lt;br /&gt;
Where the HTML for the JavaScript only widget is generated by PHP, we can make it invisible when JavaScript is off using just CSS:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
.mywidget {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
body.jsenabled .mywidget {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
However, it could be argued that this approach is not really progressive enhancement.&lt;br /&gt;
&lt;br /&gt;
=====Content generated by JavaScript code=====&lt;br /&gt;
&lt;br /&gt;
This is more in keeping with progressive enhancement, and this is the way that the expand/collapse block icon is handled.&lt;br /&gt;
&lt;br /&gt;
We build the icon using DOM methods. The only problem is that as the JavaScript is loaded in the footer, there is a small delay before the icons appear. Since when the icons appear, they do not cause other content on the page to move around, that is OK. Also, this delayed appearance is becoming more common on the web. For example, on http://twitter.com/, some things only appear a moment after the main part of the page has finished loading.&lt;br /&gt;
&lt;br /&gt;
However, it the delayed appearance is really a problem, then the only solution is to embed the JavaScript that generates the extra content in the middle of the HTML, using the js_writer class.&lt;br /&gt;
&lt;br /&gt;
====Content that only appears when the user does something, when JavaScript is on====&lt;br /&gt;
&lt;br /&gt;
An example of this is something like file picker dialog that appears when you add an image to some content in the HTML editor, or the one that pops up when you click &#039;Add new question&#039; in the quiz editing interface.&lt;br /&gt;
&lt;br /&gt;
We have the same two sub-cases:&lt;br /&gt;
&lt;br /&gt;
=====Content generated by PHP code=====&lt;br /&gt;
&lt;br /&gt;
In this case, you need to make sure the content is always covered by a &#039;&#039;display: none;&#039;&#039; rule in the CSS, but then when the user takes an action like clicking a button to reveal the extra content, you need to override that class name some how, perhaps by adding or removing a className using JavaScript.&lt;br /&gt;
&lt;br /&gt;
=====Content generated by JavaScript code=====&lt;br /&gt;
&lt;br /&gt;
In this case, there is no problem. When the use triggers the extra content to appear, it is constructed using DOM methods. There may be a tiny delay, but the chances are that it will hardly be noticeable to the human eye.&lt;br /&gt;
&lt;br /&gt;
If the content generation may be slow (perhaps because it is waiting for an Ajax request) then you should display a progress icon. See, for example, the loading of the tooltip for help icons.&lt;br /&gt;
&lt;br /&gt;
===Don&#039;t break XHTML strict!===&lt;br /&gt;
&lt;br /&gt;
Remember that all Moodle output must be [[Development:XHTML|XHTML strict]], and that means that the HTML output must be well-formed XML. Inline JavaScript is a great way to break that. (JavaScript uses the &amp;lt; and &amp;amp; symbols that must be escaped in XML.) Therefore any JavaScript inline in the HTML should be escaped in a CDATA section:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
//&amp;lt;![CDATA[&lt;br /&gt;
&lt;br /&gt;
   // Your JavaScript code goes here.&lt;br /&gt;
&lt;br /&gt;
//]]&amp;gt;&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Of course, if you are following the above guidelines and putting most of your JavaScript in separate .js files, and using $PAGE-&amp;gt;requires-&amp;gt;js_init_call, then this is taken care of for you automatically.&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
&lt;br /&gt;
JavaScript support varies a lot between browsers. JavaScript needs to be tested in IE, Firefox and Safari. Ideally, Moodle will support [http://developer.yahoo.com/yui/articles/gbs/ all the browsers that YUI does].&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Development:Coding|The rest of Moodle coding guidelines]]&lt;br /&gt;
* [http://developer.yahoo.com/yui/ YUI documentation]&lt;br /&gt;
* [[Javascript FAQ]]&lt;br /&gt;
* [[Javascript and YUI 3 FAQ]]&lt;br /&gt;
* [[Development:Unobtrusive Javascript]]&lt;br /&gt;
* [[Development:JavaScript functions]]&lt;br /&gt;
* [http://developer.yahoo.com/performance/rules.html Yahoo&#039;s Best Practices for Speeding Up Your Web Site]&lt;br /&gt;
&lt;br /&gt;
[[Category:Coding guidelines|JavaScript guidelines]]&lt;br /&gt;
[[Category:Javascript|JavaScript guidelines]]&lt;br /&gt;
[[Category:AJAX|JavaScript guidelines]]&lt;br /&gt;
&lt;br /&gt;
[[ja:開発:Javaスクリプトガイドライン]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Javascript_and_YUI_3_FAQ&amp;diff=81205</id>
		<title>Javascript and YUI 3 FAQ</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Javascript_and_YUI_3_FAQ&amp;diff=81205"/>
		<updated>2011-02-09T14:07:03Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* How does Y relate to the yui docs? To step back, how do I work out what methods etc. Y has that I can use? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}A quick primer on the internals of Moodle&#039;s javascript, and how to use YUI within it. Based on [http://moodle.org/mod/forum/discuss.php?d=168157 formlibs plus ajax] discussion in the General Developer forum.&lt;br /&gt;
&lt;br /&gt;
== How do I add an event to make changing a value in a select control submit its parent form? ==&lt;br /&gt;
&lt;br /&gt;
When you put the field&#039;s name in addElement, it automatically gives it an ID. Say you called it &amp;quot;select1&amp;quot;, the id would be &amp;quot;id_select1&amp;quot;. There&#039;s an exception to this (I can&#039;t remember which element it is) in which case you&#039;ll need to define an id in the attributes.&lt;br /&gt;
&lt;br /&gt;
You&#039;ll then want to get the select and the form using YUI, and attach an event listener:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;Y.on(&#039;change&#039;, submit_form, &#039;#select1&#039;);&lt;br /&gt;
 function submit_form() {    &lt;br /&gt;
    var form = Y.one(&#039;#mform1&#039;); // The id for the moodle form is automatically set.&lt;br /&gt;
    var form.submit();&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code would normally live in a file called &#039;module.js&#039; within your plugin directory. See other FAQs for actually accessing this. &lt;br /&gt;
&lt;br /&gt;
Explanation:&lt;br /&gt;
* The first line sets up the event listener. The first parameter says watch for a &#039;change&#039; of value. The second is the name of the callback function to execute when the change happens. The third is the name of the DOM element that is being watched (in this case the select form element with id=&#039;select1&#039;. The second parameter matches the name of the callback function below.&lt;br /&gt;
* For a full explanation of event listeners see http://developer.yahoo.com/yui/3/event/&lt;br /&gt;
* The callback function &#039;submit_form&#039; uses YUI&#039;s methods to access the form in which the select box lives (in this case with id=&amp;quot;form1&amp;quot;) and then submits it. For a full explanation of the Y.one method see http://developer.yahoo.com/yui/3/node&lt;br /&gt;
* When the form node has been obtained, the node&#039;s submit method is used to submit the form. See the API documentation for YUI&#039;s node class for this and other node methods - http://developer.yahoo.com/yui/3/api/Node.html&lt;br /&gt;
&lt;br /&gt;
== How do I get that into the page. Is that a &#039;yui&#039; call or a &#039;requires_js&amp;quot; call or whatever? == &lt;br /&gt;
&lt;br /&gt;
The best documentation to read is here: [[Development:JavaScript_guidelines]]&lt;br /&gt;
&lt;br /&gt;
Essentially, you need to define M.your_plugin as an object in a javascript file. You then define the submit_form() function as a method of M.your_plugin, and put the Y.on() call in the init method of the object. You then include the javascript file with $PAGE-&amp;gt;requires_js() and call the init method with js_init_call (see docs).&lt;br /&gt;
&lt;br /&gt;
== Also, where does the &#039;Y&#039; get defined? Is this documented somewhere (I can&#039;t find anything)? ==&lt;br /&gt;
&lt;br /&gt;
Y is a bit complicated, it took me a while to really understand what happens, but here&#039;s a brief explanation:&lt;br /&gt;
&lt;br /&gt;
Y is a namespace generated when YUI is initialised containing the methods from all the loaded modules.  Internally, moodle initialises Y and passes it to the module&#039;s init function in js_init_call, as the first parameter. To access Y from your init function, you need to do this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;M.my_plugin.init = function(Y) { //Y is now accessible in the scope of init().&amp;lt;/code&amp;gt;&lt;br /&gt;
However, you probably want access Y in your object&#039;s other method&#039;s too, so you need to do something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;M.my_plugin.init = function(Y) { //Y is now accessible in the scope of init().&lt;br /&gt;
    this.Y = Y; // this.Y is now accessible from all methods of M.my_plugin&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
For tidiness, I always start any other method using Y with &amp;quot;var Y = this.Y&amp;quot; so I don&#039;t have to keep prefixing with this.&lt;br /&gt;
&lt;br /&gt;
You may also find this page useful (or more confusing ) [[Development:How_to_create_a_YUI_3_module]]&lt;br /&gt;
&lt;br /&gt;
== The M.your_plugin thing. What if it isn&#039;t a module? What if it&#039;s a report somewhere or a local plugin. What&#039;s the syntax for this thing? I guess the &#039;M&#039; is just an arbitrary &amp;quot;thing&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
First of all, disambiguation of terms:&lt;br /&gt;
&lt;br /&gt;
* A &#039;&#039;YUI Module&#039;&#039; is subset of YUI functionality, contained in it&#039;s own namespace, e.g Y.Node&lt;br /&gt;
* A &#039;&#039;Moodle Module&#039;&#039;, I&#039;m sure you understand.&lt;br /&gt;
* A &#039;&#039;Javascript Module&#039;&#039; in this context, is a subset of javascript functionality contained in it&#039;s own M. namespace.&lt;br /&gt;
Any Moodle plugin can define it&#039;s own Javascript Module, whether it&#039;s a Moodle Module or a different type of plugin. Usually this will be in the plugin&#039;s module.js file, and be called M.plugintype_pluginame (similar to the lang file naming convention), but the object passed as the 4th parameter of $PAGE-&amp;gt;requires-&amp;gt;js_init_call() allows you to customise this.&lt;br /&gt;
&lt;br /&gt;
A good example of Y&#039;s usage that I can point you to is my quickfindlist block.&lt;br /&gt;
&lt;br /&gt;
Take a look at the bottom of get_content() in [https://github.com/marxjohnson/moodle-block_quickfindlist/blob/dev/block_quickfindlist.php block_quickfindlist.php]. This defines $jsmodule (the Javascript module&#039;s parameters, including the name, the file it&#039;s stored in, and the YUI modules it needs), $jsdata (extra parameters to pass with the init call, in addition to Y), and then passes them, along with the name of the module&#039;s init function, to js_init_call(). Note that as it&#039;s a block, it uses $this-&amp;gt;page in place of $PAGE.&lt;br /&gt;
&lt;br /&gt;
Now look at [https://github.com/marxjohnson/moodle-block_quickfindlist/blob/dev/module.js module.js]. It defines M.block_quickfindlist (which is the module we specified with $jsmodule) and the init() method (which we referenced in js_init_call()).  init accepts 6 parameters: Y, and the 5 set in $jsdata.  It then stores a copy of Y in M.block_quickfindlist.Y so it can be used in other methods, and uses Y itself to call Y.on(), adding event listeners to the block.&lt;br /&gt;
M.block_quickfindlist.search() is defined futher down module.js - it needs acces to Y too, so we create a copy in the method&#039;s scope for easy referencing, before using it to make an AJAX request with Y.io().  You can also see use of M.cfg, another Javascript Module, to access the value of wwwroot.&lt;br /&gt;
&lt;br /&gt;
An important thing to note about Y being used all over the place is that as I understand it, Y is only initialised once with all the YUI Modules required by any Javascript Modules on the current page (hence the requirements manager). It&#039;s then passed to each module&#039;s init function, so they can use it in their own scope.&lt;br /&gt;
&lt;br /&gt;
The actual &amp;quot;core&amp;quot; javascript code to do this would look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
YUI.use(&#039;required&#039;, &#039;yui&#039;, &#039;modules&#039;, function(Y) { &lt;br /&gt;
    // YUI.use initialises Y with required modules, &lt;br /&gt;
    // and passes it to an anonymous function.&lt;br /&gt;
    // Y is then available to pass to our own init functions&lt;br /&gt;
    M.block_blockname.init_function(Y);&lt;br /&gt;
    M.report_reportname.init_function(Y, other, parameters);&lt;br /&gt;
 });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How does Y relate to the yui docs? To step back, how do I work out what methods etc. Y has that I can use? ==&lt;br /&gt;
&lt;br /&gt;
When you request a module for inclusion, it&#039;s classes will be attached to the Y namespace. You can see it&#039;s classes by going to the YUI documentation for that module, and looking at the API docs. Each module&#039;s classes then has a set of properties and methods.&lt;br /&gt;
&lt;br /&gt;
For example the IO module contains the io class. So telling Moodle that your javascript module requires io will give you access to Y.io and all of its methods.&lt;br /&gt;
In general, reading the YUI module&#039;s documentation and it&#039;s examples will give you a good general idea of how to use it&#039;s functionality.&lt;br /&gt;
&lt;br /&gt;
It&#039;s also worth noting that some modules will create a shortcut method attached directly to Y for convenience. For instance Y.io.io() can also be called using Y.io(), and Y.Node.one() can be called using Y.one().&lt;br /&gt;
&lt;br /&gt;
I&#039;m guessing that some YUI modules are loaded by default (&#039;base&#039; and &#039;node&#039; probably are), but the requirements manager should make sure that each one&#039;s only loaded once. I always define all the YUI Modules my Javascript Module needs, just to make sure.&lt;br /&gt;
&lt;br /&gt;
== It doesn&#039;t work. Now what? ==&lt;br /&gt;
&lt;br /&gt;
Firstly, make sure you have debugging on your site set to Developer (and messages displayed). Without this level of debugging any detected errors will fail silently.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [http://developer.yahoo.com/yui/3/ YUI documentation]&lt;br /&gt;
* [[Javascript FAQ]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Javascript]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Javascript_and_YUI_3_FAQ&amp;diff=81188</id>
		<title>Javascript and YUI 3 FAQ</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Javascript_and_YUI_3_FAQ&amp;diff=81188"/>
		<updated>2011-02-09T11:08:33Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* How do I add an event to make changing a value in a select control submit its parent form? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}A quick primer on the internals of Moodle&#039;s javascript, and how to use YUI within it. Based on [http://moodle.org/mod/forum/discuss.php?d=168157 formlibs plus ajax] discussion in the General Developer forum.&lt;br /&gt;
&lt;br /&gt;
== How do I add an event to make changing a value in a select control submit its parent form? ==&lt;br /&gt;
&lt;br /&gt;
When you put the field&#039;s name in addElement, it automatically gives it an ID. Say you called it &amp;quot;select1&amp;quot;, the id would be &amp;quot;id_select1&amp;quot;. There&#039;s an exception to this (I can&#039;t remember which element it is) in which case you&#039;ll need to define an id in the attributes.&lt;br /&gt;
&lt;br /&gt;
You&#039;ll then want to get the select and the form using YUI, and attach an event listener:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;Y.on(&#039;change&#039;, submit_form, &#039;#select1&#039;);&lt;br /&gt;
 function submit_form() {    &lt;br /&gt;
    var form = Y.one(&#039;#mform1&#039;); // The id for the moodle form is automatically set.&lt;br /&gt;
    var form.submit();&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code would normally live in a file called &#039;module.js&#039; within your plugin directory. See other FAQs for actually accessing this. &lt;br /&gt;
&lt;br /&gt;
Explanation:&lt;br /&gt;
* The first line sets up the event listener. The first parameter says watch for a &#039;change&#039; of value. The second is the name of the callback function to execute when the change happens. The third is the name of the DOM element that is being watched (in this case the select form element with id=&#039;select1&#039;. The second parameter matches the name of the callback function below.&lt;br /&gt;
* For a full explanation of event listeners see http://developer.yahoo.com/yui/3/event/&lt;br /&gt;
* The callback function &#039;submit_form&#039; uses YUI&#039;s methods to access the form in which the select box lives (in this case with id=&amp;quot;form1&amp;quot;) and then submits it. For a full explanation of the Y.one method see http://developer.yahoo.com/yui/3/node&lt;br /&gt;
* When the form node has been obtained, the node&#039;s submit method is used to submit the form. See the API documentation for YUI&#039;s node class for this and other node methods - http://developer.yahoo.com/yui/3/api/Node.html&lt;br /&gt;
&lt;br /&gt;
== How do I get that into the page. Is that a &#039;yui&#039; call or a &#039;requires_js&amp;quot; call or whatever? == &lt;br /&gt;
&lt;br /&gt;
The best documentation to read is here: [[Development:JavaScript_guidelines]]&lt;br /&gt;
&lt;br /&gt;
Essentially, you need to define M.your_plugin as an object in a javascript file. You then define the submit_form() function as a method of M.your_plugin, and put the Y.on() call in the init method of the object. You then include the javascript file with $PAGE-&amp;gt;requires_js() and call the init method with js_init_call (see docs).&lt;br /&gt;
&lt;br /&gt;
== Also, where does the &#039;Y&#039; get defined? Is this documented somewhere (I can&#039;t find anything)? ==&lt;br /&gt;
&lt;br /&gt;
Y is a bit complicated, it took me a while to really understand what happens, but here&#039;s a brief explanation:&lt;br /&gt;
&lt;br /&gt;
Y is a namespace generated when YUI is initialised containing the methods from all the loaded modules.  Internally, moodle initialises Y and passes it to the module&#039;s init function in js_init_call, as the first parameter. To access Y from your init function, you need to do this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;M.my_plugin.init = function(Y) { //Y is now accessible in the scope of init().&amp;lt;/code&amp;gt;&lt;br /&gt;
However, you probably want access Y in your object&#039;s other method&#039;s too, so you need to do something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;M.my_plugin.init = function(Y) { //Y is now accessible in the scope of init().&lt;br /&gt;
    this.Y = Y; // this.Y is now accessible from all methods of M.my_plugin&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
For tidiness, I always start any other method using Y with &amp;quot;var Y = this.Y&amp;quot; so I don&#039;t have to keep prefixing with this.&lt;br /&gt;
&lt;br /&gt;
You may also find this page useful (or more confusing ) [[Development:How_to_create_a_YUI_3_module]]&lt;br /&gt;
&lt;br /&gt;
== The M.your_plugin thing. What if it isn&#039;t a module? What if it&#039;s a report somewhere or a local plugin. What&#039;s the syntax for this thing? I guess the &#039;M&#039; is just an arbitrary &amp;quot;thing&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
First of all, disambiguation of terms:&lt;br /&gt;
&lt;br /&gt;
* A &#039;&#039;YUI Module&#039;&#039; is subset of YUI functionality, contained in it&#039;s own namespace, e.g Y.Node&lt;br /&gt;
* A &#039;&#039;Moodle Module&#039;&#039;, I&#039;m sure you understand.&lt;br /&gt;
* A &#039;&#039;Javascript Module&#039;&#039; in this context, is a subset of javascript functionality contained in it&#039;s own M. namespace.&lt;br /&gt;
Any Moodle plugin can define it&#039;s own Javascript Module, whether it&#039;s a Moodle Module or a different type of plugin. Usually this will be in the plugin&#039;s module.js file, and be called M.plugintype_pluginame (similar to the lang file naming convention), but the object passed as the 4th parameter of $PAGE-&amp;gt;requires-&amp;gt;js_init_call() allows you to customise this.&lt;br /&gt;
&lt;br /&gt;
A good example of Y&#039;s usage that I can point you to is my quickfindlist block.&lt;br /&gt;
&lt;br /&gt;
Take a look at the bottom of get_content() in [https://github.com/marxjohnson/moodle-block_quickfindlist/blob/dev/block_quickfindlist.php block_quickfindlist.php]. This defines $jsmodule (the Javascript module&#039;s parameters, including the name, the file it&#039;s stored in, and the YUI modules it needs), $jsdata (extra parameters to pass with the init call, in addition to Y), and then passes them, along with the name of the module&#039;s init function, to js_init_call(). Note that as it&#039;s a block, it uses $this-&amp;gt;page in place of $PAGE.&lt;br /&gt;
&lt;br /&gt;
Now look at [https://github.com/marxjohnson/moodle-block_quickfindlist/blob/dev/module.js module.js]. It defines M.block_quickfindlist (which is the module we specified with $jsmodule) and the init() method (which we referenced in js_init_call()).  init accepts 6 parameters: Y, and the 5 set in $jsdata.  It then stores a copy of Y in M.block_quickfindlist.Y so it can be used in other methods, and uses Y itself to call Y.on(), adding event listeners to the block.&lt;br /&gt;
M.block_quickfindlist.search() is defined futher down module.js - it needs acces to Y too, so we create a copy in the method&#039;s scope for easy referencing, before using it to make an AJAX request with Y.io().  You can also see use of M.cfg, another Javascript Module, to access the value of wwwroot.&lt;br /&gt;
&lt;br /&gt;
An important thing to note about Y being used all over the place is that as I understand it, Y is only initialised once with all the YUI Modules required by any Javascript Modules on the current page (hence the requirements manager). It&#039;s then passed to each module&#039;s init function, so they can use it in their own scope.&lt;br /&gt;
&lt;br /&gt;
The actual &amp;quot;core&amp;quot; javascript code to do this would look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
YUI.use(&#039;required&#039;, &#039;yui&#039;, &#039;modules&#039;, function(Y) { &lt;br /&gt;
    // YUI.use initialises Y with required modules, &lt;br /&gt;
    // and passes it to an anonymous function.&lt;br /&gt;
    // Y is then available to pass to our own init functions&lt;br /&gt;
    M.block_blockname.init_function(Y);&lt;br /&gt;
    M.report_reportname.init_function(Y, other, parameters);&lt;br /&gt;
 });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How does Y relate to the yui docs? To step back, how do I work out what methods etc. Y has that I can use? ==&lt;br /&gt;
&lt;br /&gt;
When you request a module for inclusion, it&#039;s classes will be attached to the Y namespace. You can see it&#039;s classes by going to the YUI documentation for that module, and looking at the API docs. Each module&#039;s classes then has a set of properties and methods.&lt;br /&gt;
&lt;br /&gt;
For example the IO module contains the io class. So telling Moodle that your javascript module requires io will give you access to Y.io and all of its methods.&lt;br /&gt;
In general, reading the YUI module&#039;s documentation and it&#039;s examples will give you a good general idea of how to use it&#039;s functionality.&lt;br /&gt;
&lt;br /&gt;
It&#039;s also worth noting that some modules will create a shortcut method attached directly to Y for convenience. For instance Y.io.io() can also be called using Y.io(), and Y.Node.one() can be called using Y.one().&lt;br /&gt;
&lt;br /&gt;
I&#039;m guessing that some YUI modules are loaded by default (&#039;base&#039; and &#039;node&#039; probably are), but the requirements manager should make sure that each one&#039;s only loaded once. I always define all the YUI Modules my Javascript Module needs, just to make sure.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [http://developer.yahoo.com/yui/3/ YUI documentation]&lt;br /&gt;
* [[Javascript FAQ]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Javascript]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Javascript_and_YUI_3_FAQ&amp;diff=81187</id>
		<title>Javascript and YUI 3 FAQ</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Javascript_and_YUI_3_FAQ&amp;diff=81187"/>
		<updated>2011-02-09T11:07:22Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* How do I add an event to make changing a value in a select control submit its parent form? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}A quick primer on the internals of Moodle&#039;s javascript, and how to use YUI within it. Based on [http://moodle.org/mod/forum/discuss.php?d=168157 formlibs plus ajax] discussion in the General Developer forum.&lt;br /&gt;
&lt;br /&gt;
== How do I add an event to make changing a value in a select control submit its parent form? ==&lt;br /&gt;
&lt;br /&gt;
When you put the field&#039;s name in addElement, it automatically gives it an ID. Say you called it &amp;quot;select1&amp;quot;, the id would be &amp;quot;id_select1&amp;quot;. There&#039;s an exception to this (I can&#039;t remember which element it is) in which case you&#039;ll need to define an id in the attributes.&lt;br /&gt;
&lt;br /&gt;
You&#039;ll then want to get the select and the form using YUI, and attach an event listener:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;Y.on(&#039;change&#039;, submit_form, &#039;#select1&#039;);&lt;br /&gt;
 function submit_form() {    &lt;br /&gt;
    var form = Y.one(&#039;#mform1&#039;); // The id for the moodle form is automatically set.&lt;br /&gt;
    var form.submit();&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explanation:&lt;br /&gt;
* The first line sets up the event listener. The first parameter says watch for a &#039;change&#039; of value. The second is the name of the callback function to execute when the change happens. The third is the name of the DOM element that is being watched (in this case the select form element with id=&#039;select1&#039;. The second parameter matches the name of the callback function below.&lt;br /&gt;
* For a full explanation of event listeners see http://developer.yahoo.com/yui/3/event/&lt;br /&gt;
* The callback function &#039;submit_form&#039; uses YUI&#039;s methods to access the form in which the select box lives (in this case with id=&amp;quot;form1&amp;quot;) and then submits it. For a full explanation of the Y.one method see http://developer.yahoo.com/yui/3/node&lt;br /&gt;
* When the form node has been obtained, the node&#039;s submit method is used to submit the form. See the API documentation for YUI&#039;s node class for this and other node methods - http://developer.yahoo.com/yui/3/api/Node.html&lt;br /&gt;
&lt;br /&gt;
== How do I get that into the page. Is that a &#039;yui&#039; call or a &#039;requires_js&amp;quot; call or whatever? == &lt;br /&gt;
&lt;br /&gt;
The best documentation to read is here: [[Development:JavaScript_guidelines]]&lt;br /&gt;
&lt;br /&gt;
Essentially, you need to define M.your_plugin as an object in a javascript file. You then define the submit_form() function as a method of M.your_plugin, and put the Y.on() call in the init method of the object. You then include the javascript file with $PAGE-&amp;gt;requires_js() and call the init method with js_init_call (see docs).&lt;br /&gt;
&lt;br /&gt;
== Also, where does the &#039;Y&#039; get defined? Is this documented somewhere (I can&#039;t find anything)? ==&lt;br /&gt;
&lt;br /&gt;
Y is a bit complicated, it took me a while to really understand what happens, but here&#039;s a brief explanation:&lt;br /&gt;
&lt;br /&gt;
Y is a namespace generated when YUI is initialised containing the methods from all the loaded modules.  Internally, moodle initialises Y and passes it to the module&#039;s init function in js_init_call, as the first parameter. To access Y from your init function, you need to do this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;M.my_plugin.init = function(Y) { //Y is now accessible in the scope of init().&amp;lt;/code&amp;gt;&lt;br /&gt;
However, you probably want access Y in your object&#039;s other method&#039;s too, so you need to do something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;M.my_plugin.init = function(Y) { //Y is now accessible in the scope of init().&lt;br /&gt;
    this.Y = Y; // this.Y is now accessible from all methods of M.my_plugin&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
For tidiness, I always start any other method using Y with &amp;quot;var Y = this.Y&amp;quot; so I don&#039;t have to keep prefixing with this.&lt;br /&gt;
&lt;br /&gt;
You may also find this page useful (or more confusing ) [[Development:How_to_create_a_YUI_3_module]]&lt;br /&gt;
&lt;br /&gt;
== The M.your_plugin thing. What if it isn&#039;t a module? What if it&#039;s a report somewhere or a local plugin. What&#039;s the syntax for this thing? I guess the &#039;M&#039; is just an arbitrary &amp;quot;thing&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
First of all, disambiguation of terms:&lt;br /&gt;
&lt;br /&gt;
* A &#039;&#039;YUI Module&#039;&#039; is subset of YUI functionality, contained in it&#039;s own namespace, e.g Y.Node&lt;br /&gt;
* A &#039;&#039;Moodle Module&#039;&#039;, I&#039;m sure you understand.&lt;br /&gt;
* A &#039;&#039;Javascript Module&#039;&#039; in this context, is a subset of javascript functionality contained in it&#039;s own M. namespace.&lt;br /&gt;
Any Moodle plugin can define it&#039;s own Javascript Module, whether it&#039;s a Moodle Module or a different type of plugin. Usually this will be in the plugin&#039;s module.js file, and be called M.plugintype_pluginame (similar to the lang file naming convention), but the object passed as the 4th parameter of $PAGE-&amp;gt;requires-&amp;gt;js_init_call() allows you to customise this.&lt;br /&gt;
&lt;br /&gt;
A good example of Y&#039;s usage that I can point you to is my quickfindlist block.&lt;br /&gt;
&lt;br /&gt;
Take a look at the bottom of get_content() in [https://github.com/marxjohnson/moodle-block_quickfindlist/blob/dev/block_quickfindlist.php block_quickfindlist.php]. This defines $jsmodule (the Javascript module&#039;s parameters, including the name, the file it&#039;s stored in, and the YUI modules it needs), $jsdata (extra parameters to pass with the init call, in addition to Y), and then passes them, along with the name of the module&#039;s init function, to js_init_call(). Note that as it&#039;s a block, it uses $this-&amp;gt;page in place of $PAGE.&lt;br /&gt;
&lt;br /&gt;
Now look at [https://github.com/marxjohnson/moodle-block_quickfindlist/blob/dev/module.js module.js]. It defines M.block_quickfindlist (which is the module we specified with $jsmodule) and the init() method (which we referenced in js_init_call()).  init accepts 6 parameters: Y, and the 5 set in $jsdata.  It then stores a copy of Y in M.block_quickfindlist.Y so it can be used in other methods, and uses Y itself to call Y.on(), adding event listeners to the block.&lt;br /&gt;
M.block_quickfindlist.search() is defined futher down module.js - it needs acces to Y too, so we create a copy in the method&#039;s scope for easy referencing, before using it to make an AJAX request with Y.io().  You can also see use of M.cfg, another Javascript Module, to access the value of wwwroot.&lt;br /&gt;
&lt;br /&gt;
An important thing to note about Y being used all over the place is that as I understand it, Y is only initialised once with all the YUI Modules required by any Javascript Modules on the current page (hence the requirements manager). It&#039;s then passed to each module&#039;s init function, so they can use it in their own scope.&lt;br /&gt;
&lt;br /&gt;
The actual &amp;quot;core&amp;quot; javascript code to do this would look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
YUI.use(&#039;required&#039;, &#039;yui&#039;, &#039;modules&#039;, function(Y) { &lt;br /&gt;
    // YUI.use initialises Y with required modules, &lt;br /&gt;
    // and passes it to an anonymous function.&lt;br /&gt;
    // Y is then available to pass to our own init functions&lt;br /&gt;
    M.block_blockname.init_function(Y);&lt;br /&gt;
    M.report_reportname.init_function(Y, other, parameters);&lt;br /&gt;
 });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How does Y relate to the yui docs? To step back, how do I work out what methods etc. Y has that I can use? ==&lt;br /&gt;
&lt;br /&gt;
When you request a module for inclusion, it&#039;s classes will be attached to the Y namespace. You can see it&#039;s classes by going to the YUI documentation for that module, and looking at the API docs. Each module&#039;s classes then has a set of properties and methods.&lt;br /&gt;
&lt;br /&gt;
For example the IO module contains the io class. So telling Moodle that your javascript module requires io will give you access to Y.io and all of its methods.&lt;br /&gt;
In general, reading the YUI module&#039;s documentation and it&#039;s examples will give you a good general idea of how to use it&#039;s functionality.&lt;br /&gt;
&lt;br /&gt;
It&#039;s also worth noting that some modules will create a shortcut method attached directly to Y for convenience. For instance Y.io.io() can also be called using Y.io(), and Y.Node.one() can be called using Y.one().&lt;br /&gt;
&lt;br /&gt;
I&#039;m guessing that some YUI modules are loaded by default (&#039;base&#039; and &#039;node&#039; probably are), but the requirements manager should make sure that each one&#039;s only loaded once. I always define all the YUI Modules my Javascript Module needs, just to make sure.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [http://developer.yahoo.com/yui/3/ YUI documentation]&lt;br /&gt;
* [[Javascript FAQ]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Javascript]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Javascript_and_YUI_3_FAQ&amp;diff=81186</id>
		<title>Javascript and YUI 3 FAQ</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Javascript_and_YUI_3_FAQ&amp;diff=81186"/>
		<updated>2011-02-09T11:03:49Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* How do I add an event to make changing a value in a select control submit its parent form? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}A quick primer on the internals of Moodle&#039;s javascript, and how to use YUI within it. Based on [http://moodle.org/mod/forum/discuss.php?d=168157 formlibs plus ajax] discussion in the General Developer forum.&lt;br /&gt;
&lt;br /&gt;
== How do I add an event to make changing a value in a select control submit its parent form? ==&lt;br /&gt;
&lt;br /&gt;
When you put the field&#039;s name in addElement, it automatically gives it an ID. Say you called it &amp;quot;select1&amp;quot;, the id would be &amp;quot;id_select1&amp;quot;. There&#039;s an exception to this (I can&#039;t remember which element it is) in which case you&#039;ll need to define an id in the attributes.&lt;br /&gt;
&lt;br /&gt;
You&#039;ll then want to get the select and the form using YUI, and attach an event listener:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;Y.on(&#039;change&#039;, submit_form, &#039;#select1&#039;);&lt;br /&gt;
 function submit_form() {    &lt;br /&gt;
    var form = Y.one(&#039;#mform1&#039;); // The id for the moodle form is automatically set.&lt;br /&gt;
    var form.submit();&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explanation:&lt;br /&gt;
* The first line sets up the event listener. The first parameter says watch for a &#039;change&#039; of value. The second is the name of the callback function to execute when the change happens. The third is the name of the DOM element that is being watched (in this case the select form element with id=&#039;select1&#039;. The second parameter matches the name of the callback function below.&lt;br /&gt;
* For a full explanation of event listeners see http://developer.yahoo.com/yui/3/event/&lt;br /&gt;
* The callback function &#039;submit_form&#039; uses YUI&#039;s methods to access the form in which the select box lives (in this case with id=&amp;quot;form1&amp;quot;) and then submits it. For a full explanation of the Y.one method see http://developer.yahoo.com/yui/3/node&lt;br /&gt;
&lt;br /&gt;
== How do I get that into the page. Is that a &#039;yui&#039; call or a &#039;requires_js&amp;quot; call or whatever? == &lt;br /&gt;
&lt;br /&gt;
The best documentation to read is here: [[Development:JavaScript_guidelines]]&lt;br /&gt;
&lt;br /&gt;
Essentially, you need to define M.your_plugin as an object in a javascript file. You then define the submit_form() function as a method of M.your_plugin, and put the Y.on() call in the init method of the object. You then include the javascript file with $PAGE-&amp;gt;requires_js() and call the init method with js_init_call (see docs).&lt;br /&gt;
&lt;br /&gt;
== Also, where does the &#039;Y&#039; get defined? Is this documented somewhere (I can&#039;t find anything)? ==&lt;br /&gt;
&lt;br /&gt;
Y is a bit complicated, it took me a while to really understand what happens, but here&#039;s a brief explanation:&lt;br /&gt;
&lt;br /&gt;
Y is a namespace generated when YUI is initialised containing the methods from all the loaded modules.  Internally, moodle initialises Y and passes it to the module&#039;s init function in js_init_call, as the first parameter. To access Y from your init function, you need to do this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;M.my_plugin.init = function(Y) { //Y is now accessible in the scope of init().&amp;lt;/code&amp;gt;&lt;br /&gt;
However, you probably want access Y in your object&#039;s other method&#039;s too, so you need to do something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;M.my_plugin.init = function(Y) { //Y is now accessible in the scope of init().&lt;br /&gt;
    this.Y = Y; // this.Y is now accessible from all methods of M.my_plugin&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
For tidiness, I always start any other method using Y with &amp;quot;var Y = this.Y&amp;quot; so I don&#039;t have to keep prefixing with this.&lt;br /&gt;
&lt;br /&gt;
You may also find this page useful (or more confusing ) [[Development:How_to_create_a_YUI_3_module]]&lt;br /&gt;
&lt;br /&gt;
== The M.your_plugin thing. What if it isn&#039;t a module? What if it&#039;s a report somewhere or a local plugin. What&#039;s the syntax for this thing? I guess the &#039;M&#039; is just an arbitrary &amp;quot;thing&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
First of all, disambiguation of terms:&lt;br /&gt;
&lt;br /&gt;
* A &#039;&#039;YUI Module&#039;&#039; is subset of YUI functionality, contained in it&#039;s own namespace, e.g Y.Node&lt;br /&gt;
* A &#039;&#039;Moodle Module&#039;&#039;, I&#039;m sure you understand.&lt;br /&gt;
* A &#039;&#039;Javascript Module&#039;&#039; in this context, is a subset of javascript functionality contained in it&#039;s own M. namespace.&lt;br /&gt;
Any Moodle plugin can define it&#039;s own Javascript Module, whether it&#039;s a Moodle Module or a different type of plugin. Usually this will be in the plugin&#039;s module.js file, and be called M.plugintype_pluginame (similar to the lang file naming convention), but the object passed as the 4th parameter of $PAGE-&amp;gt;requires-&amp;gt;js_init_call() allows you to customise this.&lt;br /&gt;
&lt;br /&gt;
A good example of Y&#039;s usage that I can point you to is my quickfindlist block.&lt;br /&gt;
&lt;br /&gt;
Take a look at the bottom of get_content() in [https://github.com/marxjohnson/moodle-block_quickfindlist/blob/dev/block_quickfindlist.php block_quickfindlist.php]. This defines $jsmodule (the Javascript module&#039;s parameters, including the name, the file it&#039;s stored in, and the YUI modules it needs), $jsdata (extra parameters to pass with the init call, in addition to Y), and then passes them, along with the name of the module&#039;s init function, to js_init_call(). Note that as it&#039;s a block, it uses $this-&amp;gt;page in place of $PAGE.&lt;br /&gt;
&lt;br /&gt;
Now look at [https://github.com/marxjohnson/moodle-block_quickfindlist/blob/dev/module.js module.js]. It defines M.block_quickfindlist (which is the module we specified with $jsmodule) and the init() method (which we referenced in js_init_call()).  init accepts 6 parameters: Y, and the 5 set in $jsdata.  It then stores a copy of Y in M.block_quickfindlist.Y so it can be used in other methods, and uses Y itself to call Y.on(), adding event listeners to the block.&lt;br /&gt;
M.block_quickfindlist.search() is defined futher down module.js - it needs acces to Y too, so we create a copy in the method&#039;s scope for easy referencing, before using it to make an AJAX request with Y.io().  You can also see use of M.cfg, another Javascript Module, to access the value of wwwroot.&lt;br /&gt;
&lt;br /&gt;
An important thing to note about Y being used all over the place is that as I understand it, Y is only initialised once with all the YUI Modules required by any Javascript Modules on the current page (hence the requirements manager). It&#039;s then passed to each module&#039;s init function, so they can use it in their own scope.&lt;br /&gt;
&lt;br /&gt;
The actual &amp;quot;core&amp;quot; javascript code to do this would look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
YUI.use(&#039;required&#039;, &#039;yui&#039;, &#039;modules&#039;, function(Y) { &lt;br /&gt;
    // YUI.use initialises Y with required modules, &lt;br /&gt;
    // and passes it to an anonymous function.&lt;br /&gt;
    // Y is then available to pass to our own init functions&lt;br /&gt;
    M.block_blockname.init_function(Y);&lt;br /&gt;
    M.report_reportname.init_function(Y, other, parameters);&lt;br /&gt;
 });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How does Y relate to the yui docs? To step back, how do I work out what methods etc. Y has that I can use? ==&lt;br /&gt;
&lt;br /&gt;
When you request a module for inclusion, it&#039;s classes will be attached to the Y namespace. You can see it&#039;s classes by going to the YUI documentation for that module, and looking at the API docs. Each module&#039;s classes then has a set of properties and methods.&lt;br /&gt;
&lt;br /&gt;
For example the IO module contains the io class. So telling Moodle that your javascript module requires io will give you access to Y.io and all of its methods.&lt;br /&gt;
In general, reading the YUI module&#039;s documentation and it&#039;s examples will give you a good general idea of how to use it&#039;s functionality.&lt;br /&gt;
&lt;br /&gt;
It&#039;s also worth noting that some modules will create a shortcut method attached directly to Y for convenience. For instance Y.io.io() can also be called using Y.io(), and Y.Node.one() can be called using Y.one().&lt;br /&gt;
&lt;br /&gt;
I&#039;m guessing that some YUI modules are loaded by default (&#039;base&#039; and &#039;node&#039; probably are), but the requirements manager should make sure that each one&#039;s only loaded once. I always define all the YUI Modules my Javascript Module needs, just to make sure.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [http://developer.yahoo.com/yui/3/ YUI documentation]&lt;br /&gt;
* [[Javascript FAQ]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Javascript]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Javascript_and_YUI_3_FAQ&amp;diff=81185</id>
		<title>Javascript and YUI 3 FAQ</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Javascript_and_YUI_3_FAQ&amp;diff=81185"/>
		<updated>2011-02-09T10:31:47Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* How do I add an event to make changing a value in a select control submit its parent form? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}A quick primer on the internals of Moodle&#039;s javascript, and how to use YUI within it. Based on [http://moodle.org/mod/forum/discuss.php?d=168157 formlibs plus ajax] discussion in the General Developer forum.&lt;br /&gt;
&lt;br /&gt;
== How do I add an event to make changing a value in a select control submit its parent form? ==&lt;br /&gt;
&lt;br /&gt;
When you put the field&#039;s name in addElement, it automatically gives it an ID. Say you called it &amp;quot;select1&amp;quot;, the id would be &amp;quot;id_select1&amp;quot;. There&#039;s an exception to this (I can&#039;t remember which element it is) in which case you&#039;ll need to define an id in the attributes.&lt;br /&gt;
&lt;br /&gt;
You&#039;ll then want to get the select and the form using YUI, and attach an event listener:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;Y.on(&#039;change&#039;, submit_form, &#039;#select1&#039;);&lt;br /&gt;
 function submit_form() {    &lt;br /&gt;
    var form = Y.one(&#039;#mform1&#039;); // The id for the moodle form is automatically set.&lt;br /&gt;
    var form.submit();&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explanation:&lt;br /&gt;
* The first line sets up the event listener. The first parameter says watch for a &#039;change&#039; of value. The second is the name of the callback function to execute when the change happens. The third is the name of the DOM element that is being watched (in this case the select form element with id=&#039;select1&#039;. The second parameter matches the name of the callback function below.&lt;br /&gt;
* For a full explanation of event listeners see http://developer.yahoo.com/yui/3/event/&lt;br /&gt;
&lt;br /&gt;
== How do I get that into the page. Is that a &#039;yui&#039; call or a &#039;requires_js&amp;quot; call or whatever? == &lt;br /&gt;
&lt;br /&gt;
The best documentation to read is here: [[Development:JavaScript_guidelines]]&lt;br /&gt;
&lt;br /&gt;
Essentially, you need to define M.your_plugin as an object in a javascript file. You then define the submit_form() function as a method of M.your_plugin, and put the Y.on() call in the init method of the object. You then include the javascript file with $PAGE-&amp;gt;requires_js() and call the init method with js_init_call (see docs).&lt;br /&gt;
&lt;br /&gt;
== Also, where does the &#039;Y&#039; get defined? Is this documented somewhere (I can&#039;t find anything)? ==&lt;br /&gt;
&lt;br /&gt;
Y is a bit complicated, it took me a while to really understand what happens, but here&#039;s a brief explanation:&lt;br /&gt;
&lt;br /&gt;
Y is a namespace generated when YUI is initialised containing the methods from all the loaded modules.  Internally, moodle initialises Y and passes it to the module&#039;s init function in js_init_call, as the first parameter. To access Y from your init function, you need to do this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;M.my_plugin.init = function(Y) { //Y is now accessible in the scope of init().&amp;lt;/code&amp;gt;&lt;br /&gt;
However, you probably want access Y in your object&#039;s other method&#039;s too, so you need to do something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;M.my_plugin.init = function(Y) { //Y is now accessible in the scope of init().&lt;br /&gt;
    this.Y = Y; // this.Y is now accessible from all methods of M.my_plugin&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
For tidiness, I always start any other method using Y with &amp;quot;var Y = this.Y&amp;quot; so I don&#039;t have to keep prefixing with this.&lt;br /&gt;
&lt;br /&gt;
You may also find this page useful (or more confusing ) [[Development:How_to_create_a_YUI_3_module]]&lt;br /&gt;
&lt;br /&gt;
== The M.your_plugin thing. What if it isn&#039;t a module? What if it&#039;s a report somewhere or a local plugin. What&#039;s the syntax for this thing? I guess the &#039;M&#039; is just an arbitrary &amp;quot;thing&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
First of all, disambiguation of terms:&lt;br /&gt;
&lt;br /&gt;
* A &#039;&#039;YUI Module&#039;&#039; is subset of YUI functionality, contained in it&#039;s own namespace, e.g Y.Node&lt;br /&gt;
* A &#039;&#039;Moodle Module&#039;&#039;, I&#039;m sure you understand.&lt;br /&gt;
* A &#039;&#039;Javascript Module&#039;&#039; in this context, is a subset of javascript functionality contained in it&#039;s own M. namespace.&lt;br /&gt;
Any Moodle plugin can define it&#039;s own Javascript Module, whether it&#039;s a Moodle Module or a different type of plugin. Usually this will be in the plugin&#039;s module.js file, and be called M.plugintype_pluginame (similar to the lang file naming convention), but the object passed as the 4th parameter of $PAGE-&amp;gt;requires-&amp;gt;js_init_call() allows you to customise this.&lt;br /&gt;
&lt;br /&gt;
A good example of Y&#039;s usage that I can point you to is my quickfindlist block.&lt;br /&gt;
&lt;br /&gt;
Take a look at the bottom of get_content() in [https://github.com/marxjohnson/moodle-block_quickfindlist/blob/dev/block_quickfindlist.php block_quickfindlist.php]. This defines $jsmodule (the Javascript module&#039;s parameters, including the name, the file it&#039;s stored in, and the YUI modules it needs), $jsdata (extra parameters to pass with the init call, in addition to Y), and then passes them, along with the name of the module&#039;s init function, to js_init_call(). Note that as it&#039;s a block, it uses $this-&amp;gt;page in place of $PAGE.&lt;br /&gt;
&lt;br /&gt;
Now look at [https://github.com/marxjohnson/moodle-block_quickfindlist/blob/dev/module.js module.js]. It defines M.block_quickfindlist (which is the module we specified with $jsmodule) and the init() method (which we referenced in js_init_call()).  init accepts 6 parameters: Y, and the 5 set in $jsdata.  It then stores a copy of Y in M.block_quickfindlist.Y so it can be used in other methods, and uses Y itself to call Y.on(), adding event listeners to the block.&lt;br /&gt;
M.block_quickfindlist.search() is defined futher down module.js - it needs acces to Y too, so we create a copy in the method&#039;s scope for easy referencing, before using it to make an AJAX request with Y.io().  You can also see use of M.cfg, another Javascript Module, to access the value of wwwroot.&lt;br /&gt;
&lt;br /&gt;
An important thing to note about Y being used all over the place is that as I understand it, Y is only initialised once with all the YUI Modules required by any Javascript Modules on the current page (hence the requirements manager). It&#039;s then passed to each module&#039;s init function, so they can use it in their own scope.&lt;br /&gt;
&lt;br /&gt;
The actual &amp;quot;core&amp;quot; javascript code to do this would look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
YUI.use(&#039;required&#039;, &#039;yui&#039;, &#039;modules&#039;, function(Y) { &lt;br /&gt;
    // YUI.use initialises Y with required modules, &lt;br /&gt;
    // and passes it to an anonymous function.&lt;br /&gt;
    // Y is then available to pass to our own init functions&lt;br /&gt;
    M.block_blockname.init_function(Y);&lt;br /&gt;
    M.report_reportname.init_function(Y, other, parameters);&lt;br /&gt;
 });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How does Y relate to the yui docs? To step back, how do I work out what methods etc. Y has that I can use? ==&lt;br /&gt;
&lt;br /&gt;
When you request a module for inclusion, it&#039;s classes will be attached to the Y namespace. You can see it&#039;s classes by going to the YUI documentation for that module, and looking at the API docs. Each module&#039;s classes then has a set of properties and methods.&lt;br /&gt;
&lt;br /&gt;
For example the IO module contains the io class. So telling Moodle that your javascript module requires io will give you access to Y.io and all of its methods.&lt;br /&gt;
In general, reading the YUI module&#039;s documentation and it&#039;s examples will give you a good general idea of how to use it&#039;s functionality.&lt;br /&gt;
&lt;br /&gt;
It&#039;s also worth noting that some modules will create a shortcut method attached directly to Y for convenience. For instance Y.io.io() can also be called using Y.io(), and Y.Node.one() can be called using Y.one().&lt;br /&gt;
&lt;br /&gt;
I&#039;m guessing that some YUI modules are loaded by default (&#039;base&#039; and &#039;node&#039; probably are), but the requirements manager should make sure that each one&#039;s only loaded once. I always define all the YUI Modules my Javascript Module needs, just to make sure.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [http://developer.yahoo.com/yui/3/ YUI documentation]&lt;br /&gt;
* [[Javascript FAQ]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Javascript]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Development:JavaScript_guidelines&amp;diff=81138</id>
		<title>Development:JavaScript guidelines</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Development:JavaScript_guidelines&amp;diff=81138"/>
		<updated>2011-02-08T13:20:53Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* Getting Moodle to load your JavaScript files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
These guidelines can only be applied fully from Moodle 2.0 onwards, because they rely on our new API to facilitate use of JavaScript.&lt;br /&gt;
&lt;br /&gt;
When writing JavaScript for earlier versions of Moodle, please try to follow these guidelines in spirit and use the &#039;&#039;&#039;require_js&#039;&#039;&#039; function in place of $PAGE-&amp;gt;requires-&amp;gt;js_module/yui2_lib.&lt;br /&gt;
&lt;br /&gt;
==General principles==&lt;br /&gt;
&lt;br /&gt;
===Moodle should be usable without JavaScript===&lt;br /&gt;
&lt;br /&gt;
Everything in Moodle should work with JavaScript turned off. This is important for accessibility, and in line with the principles of [[Development:Unobtrusive_Javascript|unobtrusive JavaScript]] and [[Development:Progressive_enhancement|progressive enhancement]].&lt;br /&gt;
&lt;br /&gt;
===Minimise inline JavaScript===&lt;br /&gt;
&lt;br /&gt;
Almost all JavaScript code should be in separate .js files. There should be the smallest possible amount of JavaScript inline in the HTML code of pages.&lt;br /&gt;
&lt;br /&gt;
The only &amp;amp;lt;script&amp;gt; tags in the HTML should be&lt;br /&gt;
# &amp;amp;lt;script src=... tags to include the necessary .js files.&lt;br /&gt;
# Simple function calls to trigger initialisation and pass data from PHP to JavaScript. For example &amp;amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;initialise_my_widget(&#039;some&#039;, &#039;data&#039;, 123);&amp;amp;lt;/script&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Even these small amounts of JS you should not output directly. They will be generated automatically by calls to the $PAGE-&amp;gt;requries-&amp;gt;js_init_call() API. See below for details.&lt;br /&gt;
&lt;br /&gt;
You should not use old-fashioned onXXX=&amp;quot;event_handler&amp;quot; attributes in the HTML. Use Modern DOM events. The YUI events library makes this easy.&lt;br /&gt;
&lt;br /&gt;
=== JavaScript libraries ===&lt;br /&gt;
&lt;br /&gt;
* The official JavaScript library for Moodle is [[Development:YUI|YUI]]. That may not be your favourite, but it&#039;s the one that was chosen after careful research, so live with it.&lt;br /&gt;
&lt;br /&gt;
* Moodle also has its own JavaScript library code, packaged into in various JavaScript modules.&lt;br /&gt;
&lt;br /&gt;
* Moodle uses the &#039;&#039;&#039;TinyMCE&#039;&#039;&#039; HTML editor.&lt;br /&gt;
&lt;br /&gt;
===When to include the JavaScript===&lt;br /&gt;
&lt;br /&gt;
As per [http://developer.yahoo.com/performance/rules.html Yahoo&#039;s best practice guidelines], load and execute the JavaScript as late as possible, ideally the script tags should be the last thing before the &amp;amp;lt;/body&amp;gt; close tag. (This is the default behaviour with Moodle&#039;s JavaScript handling functions like $PAGE-&amp;gt;requries-&amp;gt;js_init_call().)&lt;br /&gt;
&lt;br /&gt;
Since everything should work without JavaScript, load and initialising your scripts only after everything else on the page has loaded should not be a problem and will increase the perceived page-load performance for users.&lt;br /&gt;
&lt;br /&gt;
===Minimise the number of .js files===&lt;br /&gt;
&lt;br /&gt;
Try not to use too many different .js files. Each separate file that the browser has to load incurs an overhead.&lt;br /&gt;
&lt;br /&gt;
On the other hand, organise the JavaScript logically to ease maintenance, and don&#039;t include large amounts of irrelevant JavaScript code. Code that is loaded but never used is a waste of time.&lt;br /&gt;
&lt;br /&gt;
So, if you are writing a new module that needs its own JavaScript, try starting with a single file mod/mymod/module.js. If you find that you are writing a lot of JavaScript that is only needed when the teacher edits your module, but is not needed by students, then consider splitting that code into a separate file like mod/mymod/edit.js, and only including it where needed.&lt;br /&gt;
&lt;br /&gt;
==How to achive these general principles in Moodle==&lt;br /&gt;
&lt;br /&gt;
The rest of this page explains how you can achieve the above goals.&lt;br /&gt;
&lt;br /&gt;
===Getting Moodle to load your JavaScript files===&lt;br /&gt;
&lt;br /&gt;
Everything required by the current page is tracked by the $PAGE-&amp;gt;requires object, which is an instance of the [http://phpdocs.moodle.org/HEAD/moodlecore/page_requirements_manager.html page_requirements_manager] class defined in lib/outputrequirementslib.php.&lt;br /&gt;
&lt;br /&gt;
The most important method in this class is the -&amp;gt;js_init_call(...) method. You use it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.mod_mymod.init_something&#039;, array(&#039;some&#039;, &#039;data&#039;, &#039;from&#039;, &#039;PHP&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that this will implicitly load the JavaScript code in mod/mymod/module.js, and then call the M.mod_mymod.init_something function passing four string arguments &#039;some&#039;, &#039;data&#039;, &#039;from&#039;, &#039;PHP&#039;. You can pass any PHP type as an argument. The PHP values are encoded with json_encode before being passed to JavaScript, so numbers, strings, arrays and objects all work.&lt;br /&gt;
&lt;br /&gt;
Sometimes, the code in the JavaScript module mod/mymod/module.js may require some other JavaScript libraries to be loaded, or it may require some language strings. In that case you need to use the full form of js_init_call:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$jsmodule = array(&lt;br /&gt;
    &#039;name&#039;     =&amp;gt; &#039;mod_mymod&#039;,&lt;br /&gt;
    &#039;fullpath&#039; =&amp;gt; &#039;/mod/mymod/module.js&#039;,&lt;br /&gt;
    &#039;requires&#039; =&amp;gt; array(&#039;base&#039;, &#039;io&#039;, &#039;node&#039;, &#039;json&#039;),&lt;br /&gt;
    &#039;strings&#039; =&amp;gt; array(&lt;br /&gt;
        array(&#039;something&#039;, &#039;mymod&#039;),&lt;br /&gt;
        array(&#039;confirmdelete&#039;, &#039;mymod&#039;),&lt;br /&gt;
        array(&#039;yes&#039;, &#039;moodle&#039;),&lt;br /&gt;
        array(&#039;no&#039;, &#039;moodle&#039;)&lt;br /&gt;
    )&lt;br /&gt;
);&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.mod_mymod.init_something&#039;, array(&#039;some&#039;, &#039;data&#039;, &#039;from&#039;, &#039;PHP&#039;), false, $jsmodule);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
(Naturally, it would be a good idea to put the definition of the $jsmodule array somewhere central like in the locallib.php file.)&lt;br /&gt;
&lt;br /&gt;
The third (boolean) parameter is defined as &amp;quot;Wait for DOM Ready&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The libraries in the &#039;requires&#039; sub-array are YUI3 (or YUI2) libraries.&lt;br /&gt;
&lt;br /&gt;
The strings are Moodle language strings. In order for Moodle to have correctly determined the user&#039;s language, you should only call js_init_call after the call to require_login, which sets the current course, and ensures the user is logged in.&lt;br /&gt;
&lt;br /&gt;
$PAGE-&amp;gt;requires keeps track of which files have been included. For example if two other modules both require the YUI base module, then it is only included once.&lt;br /&gt;
&lt;br /&gt;
===JavaScript coding style===&lt;br /&gt;
&lt;br /&gt;
Moodle JavaScript code should should follow the same [[Development:Coding_style|coding style as Moodle PHP code]], allowing for the differences between PHP and JavaScript.&lt;br /&gt;
&lt;br /&gt;
For example, all the rules on &#039;&#039;function_names&#039;&#039;, &#039;&#039;class_names&#039;&#039; and &#039;&#039;variablenames&#039;&#039; apply. You should document your code with [http://jsdoc.sourceforge.net/ JSDoc] comments. Layout your JavaScript expressions and statements like the equivalent PHP ones.&lt;br /&gt;
&lt;br /&gt;
Normally, your .js files should simply define things like functions, classes and variables. When the file is loaded, no JavaScript code should actually be executed that has any effect unless it is the sort of code that can safely be executed once per HTML page. This is so that it plays nicely with the require_once-like behaviour of $PAGE-&amp;gt;requires-&amp;gt;js.&lt;br /&gt;
&lt;br /&gt;
Do not pollute the global JavaScript name-space. Try to package your JavaScript into objects, and put all objects inside the global M object, like the M.mod_mymod example above. &lt;br /&gt;
&lt;br /&gt;
===Different content when JavaScript is on or off===&lt;br /&gt;
&lt;br /&gt;
Remember the overriding principals that everything should work with JavaScript off, and we should adopt a [[Progressive enhancement]] approach. However, there are valid reasons why sometimes you need different content with JavaScript is on or off. We can break it down into three cases:&lt;br /&gt;
&lt;br /&gt;
====Content that should only be visible with JavaScript off====&lt;br /&gt;
&lt;br /&gt;
An example of this is the automatic search when you are looking for a user to assign a role to. With JavaScript on, the search automatically starts after a delay. With JavaScript off, we want an explicit Search button visible.&lt;br /&gt;
&lt;br /&gt;
To handle this case, Moodle automatically add a class &#039;jsenabled&#039; to the body tag using JavaScript. So you just need to add a rule like&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
body.jsenebled .mywidget .submitbutton {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
to the stylesheet, and the button will be invisible if JavaScript is enabled.&lt;br /&gt;
&lt;br /&gt;
An alternative strategy is to remove the particular bits of HTML from the page using DOM methods. However, if your JavaScript is only loaded at the end of the page, it may take some time for the extra content to disappear, which leads to a disconcerting flicker in the page.&lt;br /&gt;
&lt;br /&gt;
Yet another approach is the old-fashioned &amp;lt;noscript&amp;gt; tag.&lt;br /&gt;
&lt;br /&gt;
====Content that needs to be visible right away when JavaScript is on====&lt;br /&gt;
&lt;br /&gt;
An example is the &amp;lt;nowiki&amp;gt;[+] or [-]&amp;lt;/nowiki&amp;gt; icon that can be used to expand/collapse each block if JavaScript is on.&lt;br /&gt;
&lt;br /&gt;
We can divide this into two subcases:&lt;br /&gt;
&lt;br /&gt;
=====Content generated by PHP code=====&lt;br /&gt;
&lt;br /&gt;
Where the HTML for the JavaScript only widget is generated by PHP, we can make it invisible when JavaScript is off using just CSS:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
.mywidget {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
body.jsenabled .mywidget {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
However, it could be argued that this approach is not really progressive enhancement.&lt;br /&gt;
&lt;br /&gt;
=====Content generated by JavaScript code=====&lt;br /&gt;
&lt;br /&gt;
This is more in keeping with progressive enhancement, and this is the way that the expand/collapse block icon is handled.&lt;br /&gt;
&lt;br /&gt;
We build the icon using DOM methods. The only problem is that as the JavaScript is loaded in the footer, there is a small delay before the icons appear. Since when the icons appear, they do not cause other content on the page to move around, that is OK. Also, this delayed appearance is becoming more common on the web. For example, on http://twitter.com/, some things only appear a moment after the main part of the page has finished loading.&lt;br /&gt;
&lt;br /&gt;
However, it the delayed appearance is really a problem, then the only solution is to embed the JavaScript that generates the extra content in the middle of the HTML, using the js_writer class.&lt;br /&gt;
&lt;br /&gt;
====Content that only appears when the user does something, when JavaScript is on====&lt;br /&gt;
&lt;br /&gt;
An example of this is something like file picker dialog that appears when you add an image to some content in the HTML editor, or the one that pops up when you click &#039;Add new question&#039; in the quiz editing interface.&lt;br /&gt;
&lt;br /&gt;
We have the same two sub-cases:&lt;br /&gt;
&lt;br /&gt;
=====Content generated by PHP code=====&lt;br /&gt;
&lt;br /&gt;
In this case, you need to make sure the content is always covered by a &#039;&#039;display: none;&#039;&#039; rule in the CSS, but then when the user takes an action like clicking a button to reveal the extra content, you need to override that class name some how, perhaps by adding or removing a className using JavaScript.&lt;br /&gt;
&lt;br /&gt;
=====Content generated by JavaScript code=====&lt;br /&gt;
&lt;br /&gt;
In this case, there is no problem. When the use triggers the extra content to appear, it is constructed using DOM methods. There may be a tiny delay, but the chances are that it will hardly be noticeable to the human eye.&lt;br /&gt;
&lt;br /&gt;
If the content generation may be slow (perhaps because it is waiting for an Ajax request) then you should display a progress icon. See, for example, the loading of the tooltip for help icons.&lt;br /&gt;
&lt;br /&gt;
===Don&#039;t break XHTML strict!===&lt;br /&gt;
&lt;br /&gt;
Remember that all Moodle output must be [[Development:XHTML|XHTML strict]], and that means that the HTML output must be well-formed XML. Inline JavaScript is a great way to break that. (JavaScript uses the &amp;lt; and &amp;amp; symbols that must be escaped in XML.) Therefore any JavaScript inline in the HTML should be escaped in a CDATA section:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
//&amp;lt;![CDATA[&lt;br /&gt;
&lt;br /&gt;
   // Your JavaScript code goes here.&lt;br /&gt;
&lt;br /&gt;
//]]&amp;gt;&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Of course, if you are following the above guidelines and putting most of your JavaScript in separate .js files, and using $PAGE-&amp;gt;requires-&amp;gt;js_init_call, then this is taken care of for you automatically.&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
&lt;br /&gt;
JavaScript support varies a lot between browsers. JavaScript needs to be tested in IE, Firefox and Safari. Ideally, Moodle will support [http://developer.yahoo.com/yui/articles/gbs/ all the browsers that YUI does].&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Development:Coding|The rest of Moodle coding guidelines]]&lt;br /&gt;
* [http://developer.yahoo.com/yui/ YUI documentation]&lt;br /&gt;
* [[Javascript FAQ]]&lt;br /&gt;
* [[Development:Unobtrusive Javascript]]&lt;br /&gt;
* [[Development:JavaScript functions]]&lt;br /&gt;
* [http://developer.yahoo.com/performance/rules.html Yahoo&#039;s Best Practices for Speeding Up Your Web Site]&lt;br /&gt;
&lt;br /&gt;
[[Category:Coding guidelines|JavaScript guidelines]]&lt;br /&gt;
[[Category:Javascript|JavaScript guidelines]]&lt;br /&gt;
[[Category:AJAX|JavaScript guidelines]]&lt;br /&gt;
&lt;br /&gt;
[[ja:開発:Javaスクリプトガイドライン]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Development_talk:JavaScript_guidelines&amp;diff=81135</id>
		<title>Development talk:JavaScript guidelines</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Development_talk:JavaScript_guidelines&amp;diff=81135"/>
		<updated>2011-02-08T11:20:16Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* Some information on using YUI calls? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== event handlers ==&lt;br /&gt;
Should there be a recommendation to use YUI event handlers instead of JavaScript&#039;s inline event handlers? This might be better for cross-browser compatibility. --[[User:Frank Ralf|Frank Ralf]] 09:24, 15 June 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
:Good idea--[[User:Tim Hunt|Tim Hunt]] 03:16, 16 June 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Getting Moodle to load your JavaScript files ==&lt;br /&gt;
are in_head and asap now obsolete?&lt;br /&gt;
It seems in_head is replaced by the second parameter to the js class constructor, is there an alternative for asap? --[[User:Alastair Hole|Alastair Hole]] 17:46, 13 June 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
: Yes. They are obsolete. If you want to output JS in the middle of the page, you should not just do that using the js_writer class. However, the only javascript like that should be simple function calls to initialise things. It is much better to have your javascript in the footer, and if you plan for that in advance, it is normally easy to do. (I will now update this page, to remove mention of obsolete stuff.)--[[User:Tim Hunt|Tim Hunt]] 19:27, 13 June 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Some information on using YUI calls? ==&lt;br /&gt;
Unless I&#039;ve missed something, I can&#039;t see any information on how to use the YUI library in Moodle 2. It&#039;s not intuitively obvious either. --[[User:Howard Miller|Howard Miller]] 10:44, 8 February 2011 (UTC)&lt;br /&gt;
&lt;br /&gt;
== What does M.mod_mymod.init_something in general ==&lt;br /&gt;
What if my &#039;module&#039; is a block or a report or some-such? What is the general syntax of this string? --[[User:Howard Miller|Howard Miller]] 11:20, 8 February 2011 (UTC)&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Development_talk:JavaScript_guidelines&amp;diff=81134</id>
		<title>Development talk:JavaScript guidelines</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Development_talk:JavaScript_guidelines&amp;diff=81134"/>
		<updated>2011-02-08T10:44:14Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* Getting Moodle to load your JavaScript files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== event handlers ==&lt;br /&gt;
Should there be a recommendation to use YUI event handlers instead of JavaScript&#039;s inline event handlers? This might be better for cross-browser compatibility. --[[User:Frank Ralf|Frank Ralf]] 09:24, 15 June 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
:Good idea--[[User:Tim Hunt|Tim Hunt]] 03:16, 16 June 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Getting Moodle to load your JavaScript files ==&lt;br /&gt;
are in_head and asap now obsolete?&lt;br /&gt;
It seems in_head is replaced by the second parameter to the js class constructor, is there an alternative for asap? --[[User:Alastair Hole|Alastair Hole]] 17:46, 13 June 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
: Yes. They are obsolete. If you want to output JS in the middle of the page, you should not just do that using the js_writer class. However, the only javascript like that should be simple function calls to initialise things. It is much better to have your javascript in the footer, and if you plan for that in advance, it is normally easy to do. (I will now update this page, to remove mention of obsolete stuff.)--[[User:Tim Hunt|Tim Hunt]] 19:27, 13 June 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Some information on using YUI calls? ==&lt;br /&gt;
Unless I&#039;ve missed something, I can&#039;t see any information on how to use the YUI library in Moodle 2. It&#039;s not intuitively obvious either. --[[User:Howard Miller|Howard Miller]] 10:44, 8 February 2011 (UTC)&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Development:YUI&amp;diff=81133</id>
		<title>Development:YUI</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Development:YUI&amp;diff=81133"/>
		<updated>2011-02-08T10:36:29Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: Wrong url&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &#039;&#039;&#039;Yahoo! User Interface&#039;&#039;&#039; (YUI) Library is a set of utilities and controls, written in JavaScript, for building richly interactive web applications using techniques such as DOM scripting, DHTML and AJAX. &lt;br /&gt;
&lt;br /&gt;
All components in the YUI Library have been released as open source under a BSD license and are free for all uses.&lt;br /&gt;
&lt;br /&gt;
Details of the YUI can be found at the [http://developer.yahoo.com/yui/index.html Yahoo Developer Website].&lt;br /&gt;
&lt;br /&gt;
==Note==&lt;br /&gt;
&lt;br /&gt;
Some of the following information will be out of date when Moodle 2.0 is released. Please see [[Development:JavaScript guidelines]] for the latest information.&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
One approach is to find an example that is close to what you want, either in the Moodle code, or on the [http://developer.yahoo.com/yui/ Yahoo Developer Website]. Then adapt it to your needs.&lt;br /&gt;
&lt;br /&gt;
The entire YUI libraries are all part of a single YAHOO object, so they will not clash with other code. You then use them like this:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
YAHOO.util.Event.onDOMReady(...);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dependencies ===&lt;br /&gt;
&lt;br /&gt;
In order to make the &#039;&#039;onDOMReady&#039;&#039; method available to you, you first include a .js file that sets up the global object, then the events library .js file that adds all of the events methods to it. Moodle&#039;s way of doing this is with the &#039;&#039;require_js()&#039;&#039; function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
require_js(array(&#039;yui_yahoo&#039;, &#039;yui_event&#039;)); &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, you need only refer to the libraries by name. You don&#039;t need to know the full path. The [http://xref.moodle.org/lib/ajax/ajaxlib.php.source.html#l6 ajax_get_lib()] function in &#039;&#039;/lib/ajax/ajaxlib.php&#039;&#039; has the complete list of libraries. &lt;br /&gt;
&lt;br /&gt;
Once you have included the various .js dependency files with &#039;&#039;require_js()&#039;&#039; as outlined above, then write your own source .js file and add that to the require_js array &#039;&#039;&#039;after&#039;&#039;&#039; the other YUI ones. Many of the YUI files have other dependencies, so you&#039;ll often need to include more than one and the order matters for them too. Just follow the examples.&lt;br /&gt;
&lt;br /&gt;
=== Skinning ===&lt;br /&gt;
&lt;br /&gt;
For CSS, you include the css dependency files in either your theme styles.php or module/block styles.php using the standard PHP include() function. You will often need to apply the yui-skin-sam style to the body tag to get the skins to work right, so add something near the top of your script like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
document.body.className += &#039; yui-skin-sam&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a caveat, the paths in the CSS files assume that yui is placed in the site&#039;s web root and have no reference to $CFG-&amp;gt;wwwroot, so none of the images work. The solution is to go through the CSS files, pulling out any that have&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
background: url(../../whatever.png);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and paste them into your styles.php below the css include you&#039;ve added, but looking like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
background: url(&amp;lt;?php echo $CFG-&amp;gt;wwwroot ?&amp;gt;/lib/yui/whatever.png);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Performance ==&lt;br /&gt;
&lt;br /&gt;
Remember to use [http://developer.yahoo.com/yui/examples/event/event-delegation.html event bubbling] wherever possible so that instead of adding a drag-drop listener to every page element, you just add one to the content div which catches all of the events lower down the DOM tree and does what&#039;s needed.&lt;br /&gt;
&lt;br /&gt;
== Debugging ==&lt;br /&gt;
&lt;br /&gt;
* Ideally, you should use &#039;&#039;&#039;Firefox&#039;&#039;&#039;, with the [https://addons.mozilla.org/en-US/firefox/addon/60 Web Developer Toolbar], [https://addons.mozilla.org/en-US/firefox/addon/1843 Firebug] and [https://addons.mozilla.org/en-US/firefox/addon/5369 YSlow] extensions loaded (see also [[Development:Firebug]] and [[Web developer extension]]). &lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;YUI logger&#039;&#039;&#039; will need to be included as a dependency if you want to use the xxx-debug.js versions of the files, so you need to add it to require_js() before them.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [http://developer.yahoo.com/yui/ The official YUI documentation]&lt;br /&gt;
* [[JavaScript FAQ]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Javascript|YUI]]&lt;br /&gt;
[[Category:AJAX|YUI]]&lt;br /&gt;
{{CategoryDeveloper}}&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Development:lib/formslib.php_Usage&amp;diff=81099</id>
		<title>Development:lib/formslib.php Usage</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Development:lib/formslib.php_Usage&amp;diff=81099"/>
		<updated>2011-02-06T20:49:01Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* Basic Usage in A Normal Page */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Formslib}}&lt;br /&gt;
==Usage of Formslib==&lt;br /&gt;
&lt;br /&gt;
There are many phpdoc style comments in lib/formslib.php&lt;br /&gt;
&lt;br /&gt;
course/edit.php and the included course/edit_form.php provide a good example of usage of this library.&lt;br /&gt;
&lt;br /&gt;
Also see the PEAR docs for [http://pear.php.net/package/HTML_QuickForm/ HTML_QuickForm docs] I found this [http://pear.php.net/manual/en/package.html.html-quickform.tutorial.php quick tutorial] and this [http://www.midnighthax.com/quickform.php slightly longer one] particularly useful.&lt;br /&gt;
&lt;br /&gt;
We created some special wrapper functions for moodle. Function $mform-&amp;gt;get_data() returns an object with the contents of the submitted data or returns null if no data has been submitted or validation fails.&lt;br /&gt;
&lt;br /&gt;
===Basic Usage in A Normal Page===&lt;br /&gt;
&lt;br /&gt;
Generally the structure of a page with a form on it looks like this :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
require_once(&#039;pathtoformdescription&#039;);&lt;br /&gt;
//you&#039;ll process some page parameters at the top here and get the info about&lt;br /&gt;
//what instance of your module and what course you&#039;re in etc. Make sure you&lt;br /&gt;
//include hidden variable in your forms which have their defaults set in set_data&lt;br /&gt;
//which pass these variables from page to page&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$mform = new yourmod_formfunction_form();//name of the form you defined in file above.&lt;br /&gt;
//default &#039;action&#039; for form is strip_querystring(qualified_me())&lt;br /&gt;
if ($mform-&amp;gt;is_cancelled()){&lt;br /&gt;
    //you need this section if you have a cancel button on your form&lt;br /&gt;
    //here you tell php what to do if your user presses cancel&lt;br /&gt;
    //probably a redirect is called for!&lt;br /&gt;
} else if ($fromform=$mform-&amp;gt;get_data()){&lt;br /&gt;
//this branch is where you process validated data.&lt;br /&gt;
&lt;br /&gt;
} else {&lt;br /&gt;
// this branch is executed if the form is submitted but the data doesn&#039;t validate and the form should be redisplayed&lt;br /&gt;
// or on the first display of the form.&lt;br /&gt;
    //setup strings for heading&lt;br /&gt;
    print_header_simple($streditinga, &#039;&#039;,&lt;br /&gt;
     &amp;quot;&amp;lt;a href=\&amp;quot;$CFG-&amp;gt;wwwroot/mod/$module-&amp;gt;name/index.php?id=$course-&amp;gt;id\&amp;quot;&amp;gt;$strmodulenameplural&amp;lt;/a&amp;gt; -&amp;gt;&lt;br /&gt;
     $strnav $streditinga&amp;quot;, $mform-&amp;gt;focus(), &amp;quot;&amp;quot;, false);&lt;br /&gt;
    //notice use of $mform-&amp;gt;focus() above which puts the cursor &lt;br /&gt;
    //in the first form field or the first field with an error.&lt;br /&gt;
&lt;br /&gt;
    //call to print_heading_with_help or print_heading? then :&lt;br /&gt;
    &lt;br /&gt;
    //put data you want to fill out in the form into array $toform here then :&lt;br /&gt;
&lt;br /&gt;
    $mform-&amp;gt;set_data($toform);&lt;br /&gt;
    $mform-&amp;gt;display();&lt;br /&gt;
    print_footer($course);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You are encouraged to look at &#039;&#039;&#039;lib/formslib.php&#039;&#039;&#039; to see what additional functions and parameters are available. Available functions are well commented.&lt;br /&gt;
&lt;br /&gt;
===Defining Your Form Class===&lt;br /&gt;
&lt;br /&gt;
The form class tells us about the structure of the form. You are encouraged to put this in a file called {function}_form.php probably in the same folder in which the page that uses it is located. The name of your class should be {modname}_{function}_form eg. forum_post_form or course_edit_form. These classes will extend class moodleform.&lt;br /&gt;
&lt;br /&gt;
Note the name you give the class is used as the id attribute of your form in html (any trailing &#039;_form&#039; is chopped off&#039;). Your form class name should be unique in order for it to be selectable in CSS by theme designers who may want to tweak the css just for that form.&lt;br /&gt;
&lt;br /&gt;
====definition()====&lt;br /&gt;
&lt;br /&gt;
[[Development:lib/formslib.php_Form_Definition|Help is here for defining your form]] by defining a function definition() in your form class that sets up your form structure.&lt;br /&gt;
&lt;br /&gt;
===Use in Activity Modules Add / Update Forms===&lt;br /&gt;
&lt;br /&gt;
Syntax is the same in activity modules to create your update / add page. We are still supporting mod.html but if you want to use the new formslib then you can in Moodle 1.8 just include in your module directory the file mod_form.php instead of mod.html and it will be automatically detected. Inside this file you define a class with class name &#039;{modname}__mod_form&#039; which extends the class &#039;moodleform_mod&#039;. See many examples of the core modules which have been converted to use formslib already.&lt;br /&gt;
&lt;br /&gt;
====defaults_preprocessing====&lt;br /&gt;
&lt;br /&gt;
For activity modules you use the same syntax to define your form. You may also want to override method defaults_preprocessing this can be used to take the data from the data base and tell the form how to fill out defaults in the form with this data. For example in the forum module in forum/mod_form.php we needed to tick an enable check box if a date had been selected in the date select. Normally data is loaded from the database and directly loaded into form fields with the same name as the database record you only need to use defaults_preprocessing if there isn&#039;t this one to one relationship. Another example is the lesson/mod_form.php which takes the data from the database and unserializes it. choice/mod_form.php shows an exampe of loading data from another db table referred to by a foreign key, to include in the form.&lt;br /&gt;
&lt;br /&gt;
====Post Processing Still Done in lib.php Functions====&lt;br /&gt;
&lt;br /&gt;
Post processing of data is done in lib.php functions modname_add_instance and modname_update_instance after the data has been validated. When migrating a form often little changes need to be made in the post processing. An exception is that date and date_time_selector fields automatically have their submitted data turned into timestamps so you don&#039;t need to do this in your add and update functions anymore.&lt;br /&gt;
&lt;br /&gt;
====Automatically Including Standard Activity Module Form Elements====&lt;br /&gt;
&lt;br /&gt;
Standard activity module form elements are automatically included using the moodleform_mod method standard_coursemodule_elements(). The default is to include a visibility and groupsmode select box and to include all necessary hidden fields. You can pass a parameter false to tell the method that your module doesn&#039;t support groups and so you don&#039;t want the groupsmode select button.&lt;br /&gt;
&lt;br /&gt;
[[Category:Formslib]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Development:lib/formslib.php_Form_Definition&amp;diff=81098</id>
		<title>Development:lib/formslib.php Form Definition</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Development:lib/formslib.php_Form_Definition&amp;diff=81098"/>
		<updated>2011-02-06T20:41:32Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* definition() */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Formslib}}&lt;br /&gt;
== &#039;&#039;definition()&#039;&#039; ==&lt;br /&gt;
&lt;br /&gt;
The definition of the elements to be included in the form, their &#039;types&#039; (PARAM_*), helpbuttons included, etc. is all included in a function you must define in your class.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;definition()&#039;&#039; is used to define the elements in the form and &#039;&#039;&#039;this definition will be used for validating data submitted as well as for printing the form.&#039;&#039;&#039; For select and checkbox type elements only data that could have been selected will be allowed. And only data that corresponds to a form element in the definition will be accepted as submitted data.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;definition()&#039;&#039; should include all elements that are going to be used on form, some elements may be removed or tweaked later in &#039;&#039;definition_after_data()&#039;&#039;. Please do not create conditional elements in &#039;&#039;definition()&#039;&#039;, the definition() should not directly depend on the submitted data.&lt;br /&gt;
&lt;br /&gt;
Note that the definition function is called when the form class is instantiated. There is no option to (say) manipulate data in the class (that may affect the rendering of the form) between instantiating the form and calling any other methods. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
require_once(&amp;quot;$CFG-&amp;gt;libdir/formslib.php&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
class simplehtml_form extends moodleform {&lt;br /&gt;
&lt;br /&gt;
    function definition() {&lt;br /&gt;
        global $CFG;&lt;br /&gt;
       &lt;br /&gt;
        $mform =&amp;amp; $this-&amp;gt;_form; // Don&#039;t forget the underscore! &lt;br /&gt;
&lt;br /&gt;
        $mform-&amp;gt;addElement()... // Add elements to your form&lt;br /&gt;
            ...&lt;br /&gt;
    }                           // Close the function&lt;br /&gt;
}                               // Close the class&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Use Fieldsets to group Form Elements==&lt;br /&gt;
&lt;br /&gt;
You use code like this to open a fieldset with a &#039;&#039;legend&#039;&#039;. &amp;lt;br /&amp;gt;&lt;br /&gt;
(&#039;&#039;&#039;Note&#039;&#039;&#039;: Some themes turn off legends on admin setting pages by using CSS: &amp;lt;nowiki&amp;gt;#adminsettings legend {display:none;}&amp;lt;/nowiki&amp;gt;.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;header&#039;, &#039;nameforyourheaderelement&#039;, get_string(&#039;titleforlegened&#039;, &#039;modulename&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can&#039;t yet nest these visible fieldsets unfortunately. But in fact groups of elements are wrapped in invisible fieldsets.&lt;br /&gt;
&lt;br /&gt;
You close a fieldset with moodle_form&#039;s closeHeaderBefore method. You tell closeHeaderBefore the element before you wish to end the fieldset. A fieldset is automatically closed if you open a new one. You need to use this code only if you want to close a fieldset and the subsequent form elements are not to be enclosed by a visible fieldset (they are still enclosed with an invisibe one with no legend) :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;closeHeaderBefore(&#039;buttonar&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==addElement==&lt;br /&gt;
&lt;br /&gt;
Use the addElement method to add an element to a form. The first few arguments are always the same. The first param is the type of the element to add. The second is the elementname to use which is normally the html name of the element in the form. The third is often the text for the label for the element.&lt;br /&gt;
&lt;br /&gt;
Some examples are below :&lt;br /&gt;
=== button ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;button&#039;, &#039;intro&#039;, get_string(&amp;quot;buttonlabel&amp;quot;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A button element. If you want a submit or cancel button see &#039;submit&#039; element.&lt;br /&gt;
&lt;br /&gt;
=== checkbox ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;checkbox&#039;, &#039;ratingtime&#039;, get_string(&#039;ratingtime&#039;, &#039;forum&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a simple checkbox. The third parameter for this element is the label to display on the left side of the form. You can also supply a string as a fourth parameter to specify a label that will appear on the right of the element. Checkboxes and radio buttons can be grouped and have individual labels on their right.&lt;br /&gt;
&lt;br /&gt;
You can have a 5th parameter $attributes, as on other elements.&lt;br /&gt;
&lt;br /&gt;
==== advcheckbox ====&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;advcheckbox&#039;, &#039;ratingtime&#039;, get_string(&#039;ratingtime&#039;, &#039;forum&#039;), &#039;Label displayed after checkbox&#039;, array(&#039;group&#039; =&amp;gt; 1), array(0, 1));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similar to the checkbox above, but with a couple of important improvements:&lt;br /&gt;
&lt;br /&gt;
# The 5th parameter is a normal $attributes array, normally used to set HTML attributes for the &amp;lt;input&amp;gt; element. However, a special value of &#039;group&#039; can be given, which will add a class name to the element, and enable its grouping for a [[Development:lib/formslib.php_add_checkbox_controller|checkbox controller]]&lt;br /&gt;
#The 6th parameter is an array of values that will be associated with the checked/unchecked state of the checkbox. With a normal checkbox you cannot choose that value, and in fact an unchecked checkbox will not even be sent with the form data.&lt;br /&gt;
&lt;br /&gt;
=== choosecoursefile ===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;choosecoursefile&#039;, &#039;mediafile&#039;, get_string(&#039;mediafile&#039;, &#039;lesson&#039;), array(&#039;courseid&#039;=&amp;gt;$COURSE-&amp;gt;id));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choose a file from the course files area. The fourth option is a list of options for the element. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
array(&#039;courseid&#039; =&amp;gt;null,  //if it is null (default then use global $COURSE&lt;br /&gt;
      &#039;height&#039;   =&amp;gt;500,   // height of the popup window&lt;br /&gt;
      &#039;width&#039;    =&amp;gt;750,   // width of the popup window&lt;br /&gt;
      &#039;options&#039;  =&amp;gt;&#039;none&#039;); //options string for the pop up window &lt;br /&gt;
                          //eg. &#039;menubar=0,location=0,scrollbars,resizable&#039;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also pass an optional 5th parameter of attributes, as for other elements. The most useful way of using that is something like &lt;br /&gt;
&amp;lt;code php&amp;gt;array(&#039;maxlength&#039; =&amp;gt; 255, &#039;size&#039; =&amp;gt; 48)&amp;lt;/code&amp;gt;&lt;br /&gt;
to control the maxlength / size of the text box (note size will default to 48 if not specified)&lt;br /&gt;
&lt;br /&gt;
Finally, as this element is a group containing two elements (button + value), you can add validation rules by using the &#039;&#039;&#039;addGroupRule()&#039;&#039;&#039; method in this (complex) way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;$mform-&amp;gt;addGroupRule(&#039;elementname&#039;, array(&#039;value&#039; =&amp;gt; array(array(list, of, rule, params, but, fieldname))));&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where: &#039;&#039;&#039;&amp;quot;elementname&amp;quot;&#039;&#039;&#039; is the name of the choosecoursefile group element, &#039;&#039;&#039;&amp;quot;value&amp;quot;&#039;&#039;&#039; is the name of the text field within the group and the &#039;&#039;&#039;&amp;quot;list, of, addrule, params, but, fieldname&amp;quot;&#039;&#039;&#039; is exactly that, the list of fields in the normal addRule() function but ommiting the first one, the fieldname.&lt;br /&gt;
&lt;br /&gt;
For example, the [http://cvs.moodle.org/moodle/mod/resource/type/file/resource.class.php?view=markup file/url resource type], uses one &amp;quot;choosecoursefile&amp;quot; element, and it controls the maximum length of the field (255) with this use of addGroupRule():&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;$mform-&amp;gt;addGroupRule(&#039;reference&#039;, array(&#039;value&#039; =&amp;gt; array(array(get_string(&#039;maximumchars&#039;, &#039;&#039;, 255), &#039;maxlength&#039;, 255, &#039;client&#039;))));&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== date_selector ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;date_selector&#039;, &#039;assesstimefinish&#039;, get_string(&#039;to&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a date selector. You can select a Day, Month and Year using a group of select boxes. The fourth param here is an array of options. The defaults for the options are :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
array(&lt;br /&gt;
    &#039;startyear&#039; =&amp;gt; 1970, &lt;br /&gt;
    &#039;stopyear&#039;  =&amp;gt; 2020,&lt;br /&gt;
    &#039;timezone&#039;  =&amp;gt; 99, &lt;br /&gt;
    &#039;applydst&#039;  =&amp;gt; true, &lt;br /&gt;
    &#039;optional&#039;  =&amp;gt; false&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can override these defaults by supplying an array as fourth param with one or more keys with a value to override the default. You can supply a fifth param of attributes here as well.&lt;br /&gt;
&lt;br /&gt;
=== date_time_selector ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;date_time_selector&#039;, &#039;assesstimestart&#039;, get_string(&#039;from&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a group of select boxes to select a date (Day Month and Year) and time (Hour and Minute). When submitted, submitted data is processed and a timestamp is passed to $form-&amp;gt;get_data(); the fourth param here is an array of options. The defaults for the options are:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
array(&lt;br /&gt;
    &#039;startyear&#039; =&amp;gt; 1970, &lt;br /&gt;
    &#039;stopyear&#039;  =&amp;gt; 2020,&lt;br /&gt;
    &#039;timezone&#039;  =&amp;gt; 99, &lt;br /&gt;
    &#039;applydst&#039;  =&amp;gt; true, &lt;br /&gt;
    &#039;step&#039;      =&amp;gt; 5&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can override these defaults by supplying an array as fourth param with one or more keys with a value to override the default. You can supply a fifth param of attributes here as well.&lt;br /&gt;
&lt;br /&gt;
===duration===&lt;br /&gt;
{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
        $mform-&amp;gt;addElement(&#039;duration&#039;, &#039;timelimit&#039;, get_string(&#039;timelimit&#039;, &#039;quiz&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This field type lets the user input an interval of time. It comprises a text field, where you can type a number, and a dropdown for selecting a unit (days, hours, minutes or seconds). When submitted the value is converted to a number of seconds.&lt;br /&gt;
&lt;br /&gt;
You can add a fourth parameter to give options. At the moment the only option supported is here is an array of options. The defaults for the options is:&lt;br /&gt;
&amp;lt;code php&amp;gt;array(&#039;optional&#039; =&amp;gt; true)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also pass an optional 5th parameter of attributes, as for other elements. The most useful way of using that is something like &lt;br /&gt;
&amp;lt;code php&amp;gt;array(&#039;size&#039; =&amp;gt; 5)&amp;lt;/code&amp;gt;&lt;br /&gt;
to control the size of the text box.&lt;br /&gt;
&lt;br /&gt;
=== file ===&lt;br /&gt;
&lt;br /&gt;
File upload input box with browse button. In the form definition type&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;file&#039;, &#039;attachment&#039;, get_string(&#039;attachment&#039;, &#039;forum&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
after form submission and validation use&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($data = $mform-&amp;gt;get_data()) {&lt;br /&gt;
      ...&lt;br /&gt;
    $mform-&amp;gt;save_files($destination_directory);&lt;br /&gt;
      ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you need advanced settings such as required file, different max upload size or name of uploaded file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$this-&amp;gt;set_upload_manager(new upload_manager(&#039;attachment&#039;, true, false, $COURSE, false, 0, true, true, false));&lt;br /&gt;
            $mform-&amp;gt;addElement(&#039;file&#039;, &#039;attachment&#039;, get_string(&#039;attachment&#039;, &#039;forum&#039;));&lt;br /&gt;
            $mform-&amp;gt;addRule(&#039;attachment&#039;, null, &#039;required&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($data = $mform-&amp;gt;get_data()) {&lt;br /&gt;
      ...&lt;br /&gt;
    $mform-&amp;gt;save_files($destination_directory);&lt;br /&gt;
    $newfilename = $mform-&amp;gt;get_new_filename();&lt;br /&gt;
      ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When porting old code it is also possible to use the upload manager directly for processing of uploaded files.&lt;br /&gt;
&lt;br /&gt;
Please note that if using set_upload_manager() it must be before addElement(&#039;file&#039;,..).&lt;br /&gt;
&lt;br /&gt;
{{Moodle 2.0}}&lt;br /&gt;
File uploading was rewritten in 2.0. Please see inline docs for now. This page will be updated when the new API stabilises.&lt;br /&gt;
&lt;br /&gt;
===filepicker===&lt;br /&gt;
{{Moodle 2.0}}&lt;br /&gt;
General replacement of &#039;&#039;file&#039;&#039; element.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;filepicker&#039;, &#039;userfile&#039;, get_string(&#039;file&#039;), null, array(&#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;accepted_types&#039; =&amp;gt; &#039;*&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
See also [[Development:Using the File API in Moodle forms]]&lt;br /&gt;
&lt;br /&gt;
=== hidden ===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;hidden&#039;, &#039;reply&#039;, &#039;yes&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A hidden element. Set the element name (in this case &#039;&#039;&#039;reply&#039;&#039;&#039;) to the stated value (in this case &#039;&#039;&#039;yes&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
=== html ===&lt;br /&gt;
You can add arbitrary HTML to your Moodle form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;html&#039;, &#039;&amp;lt;div class=&amp;quot;qheader&amp;quot;&amp;gt;&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See [http://moodle.org/mod/forum/discuss.php?d=126935 &amp;quot;Question: Can I put a moodleform inside a table td?&amp;quot;] for a concrete example.&lt;br /&gt;
&lt;br /&gt;
=== htmleditor &amp;amp; format ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;htmleditor&#039;, &#039;text&#039;, get_string(&#039;choicetext&#039;, &#039;choice&#039;));&lt;br /&gt;
$mform-&amp;gt;setType(&#039;text&#039;, PARAM_RAW);&lt;br /&gt;
$mform-&amp;gt;addRule(&#039;text&#039;, null, &#039;required&#039;, null, &#039;client&#039;);&lt;br /&gt;
&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;format&#039;, &#039;format&#039;, get_string(&#039;format&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can supply a fourth param to htmleditor of an array of options :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
array(&lt;br /&gt;
    &#039;canUseHtmlEditor&#039;=&amp;gt;&#039;detect&#039;,&lt;br /&gt;
    &#039;rows&#039;  =&amp;gt; 10, &lt;br /&gt;
    &#039;cols&#039;  =&amp;gt; 65, &lt;br /&gt;
    &#039;width&#039; =&amp;gt; 0,&lt;br /&gt;
    &#039;height&#039;=&amp;gt; 0, &lt;br /&gt;
    &#039;course&#039;=&amp;gt; 0,&lt;br /&gt;
);&lt;br /&gt;
//options same as print_textarea params&lt;br /&gt;
//use rows and cols options to control htmleditor size.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===modgrade===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $mform-&amp;gt;addElement(&#039;modgrade&#039;, &#039;scale&#039;, get_string(&#039;grade&#039;), false);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is a custom element for selecting a grade for any activity module. The fourth argument is whether to include an option for no grade which has a value 0. This select box does include scales. The default is true, include no grade option.&lt;br /&gt;
&lt;br /&gt;
A helpbutton is automatically added.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===password===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         $mform-&amp;gt;addElement(&#039;password&#039;, &#039;password&#039;, get_string(&#039;label&#039;), $attributes);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A password element. Fourth param is an array or string of attributes.&lt;br /&gt;
&lt;br /&gt;
===passwordunmask===&lt;br /&gt;
{{Moodle 1.9}}&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         $mform-&amp;gt;addElement(&#039;passwordunmask&#039;, &#039;password&#039;, get_string(&#039;label&#039;), $attributes);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A password element with option to show the password in plaintext. Fourth param is an array or string of attributes.&lt;br /&gt;
&lt;br /&gt;
=== radio ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$radioarray=array();&lt;br /&gt;
$radioarray[] = &amp;amp;MoodleQuickForm::createElement(&#039;radio&#039;, &#039;yesno&#039;, &#039;&#039;, get_string(&#039;yes&#039;), 1, $attributes);&lt;br /&gt;
$radioarray[] = &amp;amp;MoodleQuickForm::createElement(&#039;radio&#039;, &#039;yesno&#039;, &#039;&#039;, get_string(&#039;no&#039;), 0, $attributes);&lt;br /&gt;
$mform-&amp;gt;addGroup($radioarray, &#039;radioar&#039;, &#039;&#039;, array(&#039; &#039;), false);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Second param names the radio button and should be the same for each button in the group in order to toggle correctly. Third param would be the label for the form element but is generally ignored as this element will always be in a group which has it&#039;s own label. Fourth param is a string, a label to be displayed on the right of the element. The fifth is the value for this radio button. $attributes can be a string or an array of attributes.&lt;br /&gt;
&lt;br /&gt;
It is possible to add help to individual radio buttons but this requires a custom template to be defined for the group elements. See MDL-15571.&lt;br /&gt;
&lt;br /&gt;
==== setDefault ====&lt;br /&gt;
&lt;br /&gt;
To set the default for a radio button group as above use the following :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;setDefault(&#039;yesno&#039;, 0);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would make the default &#039;no&#039;.&lt;br /&gt;
&lt;br /&gt;
===select===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $mform-&amp;gt;addElement(&#039;select&#039;, &#039;type&#039;, get_string(&#039;forumtype&#039;, &#039;forum&#039;), $FORUM_TYPES, $attributes);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The fourth param for this element is an array of options for the select box. The keys are the values for the option and the value of the array is the text for the option. The fifth param $attributes is optional, see text element for description of attributes param.&lt;br /&gt;
&lt;br /&gt;
It is also possible to create a select with certain options disabled, using [http://stackoverflow.com/questions/2138089/how-can-i-use-quickform-to-add-disabled-select-options/2150275#2150275 this technique].&lt;br /&gt;
&lt;br /&gt;
====multi-select====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $select = &amp;amp;$mform-&amp;gt;addElement(&#039;select&#039;, &#039;colors&#039;, get_string(&#039;colors&#039;), array(&#039;red&#039;, &#039;blue&#039;, &#039;green&#039;), $attributes);&lt;br /&gt;
        $select-&amp;gt;setMultiple(true);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===selectyesno===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $mform-&amp;gt;addElement(&#039;selectyesno&#039;, &#039;maxbytes&#039;, get_string(&#039;maxattachmentsize&#039;, &#039;forum&#039;));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want a yes / no select box this one automatically translates itself and has value 1 for yes and 0 for no.&lt;br /&gt;
&lt;br /&gt;
===static===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         $mform-&amp;gt;addElement(&#039;static&#039;, &#039;description&#039;, get_string(&#039;description&#039;, &#039;exercise&#039;),&lt;br /&gt;
                  get_string(&#039;descriptionofexercise&#039;, &#039;exercise&#039;, $COURSE-&amp;gt;students));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a static element. It should be used with care it is used to display a static piece of text with a label. The third param is the label and the fourth is the static text itself.&lt;br /&gt;
&lt;br /&gt;
===submit, reset and cancel===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        //normally you use add_action_buttons instead of this code&lt;br /&gt;
        $buttonarray=array();&lt;br /&gt;
        $buttonarray[] = &amp;amp;$mform-&amp;gt;createElement(&#039;submit&#039;, &#039;submitbutton&#039;, get_string(&#039;savechanges&#039;));&lt;br /&gt;
        $buttonarray[] = &amp;amp;$mform-&amp;gt;createElement(&#039;reset&#039;, &#039;resetbutton&#039;, get_string(&#039;revert&#039;));&lt;br /&gt;
        $buttonarray[] = &amp;amp;$mform-&amp;gt;createElement(&#039;cancel&#039;);&lt;br /&gt;
        $mform-&amp;gt;addGroup($buttonarray, &#039;buttonar&#039;, &#039;&#039;, array(&#039; &#039;), false);&lt;br /&gt;
        $mform-&amp;gt;closeHeaderBefore(&#039;buttonar&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A &#039;Submit&#039; type element is a submit type form element which will submit the form. A &#039;Reset&#039; will not submit the form but will reset any changes the user has made to form contents. A &#039;Cancel&#039; element cancels form submission. You need to have a branch in your code before you check for get_data() to check if submission has been cancelled with is_cancelled(); See the example on the usage page.&lt;br /&gt;
&lt;br /&gt;
You should name your submit and reset buttons &#039;submitbutton&#039; and &#039;resetbutton&#039; or something similar (not &#039;submit&#039; and &#039;reset&#039;). This avoids problems in JavaScript of collisions between form element names and names of JavaScript methods of the form object.&lt;br /&gt;
&lt;br /&gt;
====add_action_buttons($cancel = true, $submitlabel=null);====&lt;br /&gt;
&lt;br /&gt;
You will normally use this helper function which is a method of moodleform to add all the &#039;action&#039; buttons to the end of your form. A boolean parameter allow you to specify whether to include a cancel button and specify the label for your submit button (pass the result of get_string). Default for the submit button label is get_string(&#039;savechanges&#039;).&lt;br /&gt;
&lt;br /&gt;
===text===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $mform-&amp;gt;addElement(&#039;text&#039;, &#039;name&#039;, get_string(&#039;forumname&#039;, &#039;forum&#039;), $attributes);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For a simple text element. Your fourth parameter here can be a string or array of attributes for the text element. The following are equivalent :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $attributes=&#039;size=&amp;quot;20&amp;quot;&#039;;&lt;br /&gt;
        $attributes=array(&#039;size&#039;=&amp;gt;&#039;20&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Generally you are encouraged to use CSS instead of using attributes for styling.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A format element can be used as a format select box. It will be non-selectable if you&#039;re using an html editor.&lt;br /&gt;
&lt;br /&gt;
The third param for this element is $useHtmlEditor and it defaults to null in which case an html editor is used if the browser and user profile support it.&lt;br /&gt;
&lt;br /&gt;
===textarea===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            $mform-&amp;gt;addElement(&#039;textarea&#039;, &#039;introduction&#039;, get_string(&amp;quot;introtext&amp;quot;, &amp;quot;survey&amp;quot;), &#039;wrap=&amp;quot;virtual&amp;quot; rows=&amp;quot;20&amp;quot; cols=&amp;quot;50&amp;quot;&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A textarea element. If you want an htmleditor use htmleditor element. Fourth element here is a string or array of attributes.&lt;br /&gt;
&lt;br /&gt;
===recaptcha===&lt;br /&gt;
{{Moodle 1.9}}&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            $mform-&amp;gt;addElement(&#039;recaptcha&#039;, &#039;recaptcha_field_name&#039;, $attributes);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use this recaptcha element to reduce the spam risk in your forms. Third element here is a string or array of attributes. Take care to get an API key from http://recaptcha.net/api/getkey before using this element.&lt;br /&gt;
&lt;br /&gt;
To check whether recaptcha is enabled at site level use:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if (!empty($CFG-&amp;gt;recaptchapublickey) &amp;amp;&amp;amp; !empty($CFG-&amp;gt;recaptchaprivatekey)) {&lt;br /&gt;
    //recaptcha is enabled&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===tags===&lt;br /&gt;
{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            $mform-&amp;gt;addElement(&#039;tags&#039;, &#039;field_name&#039;, $lable, $options, $attributes);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Used for editing a list of tags, for example on a blog post.&lt;br /&gt;
&lt;br /&gt;
There is only one option available, &#039;display&#039;, which should be set to one of the contstants MoodleQuickForm_tags::ONLYOFFICIAL, NOOFFICIAL or DEFAULTUI. This controls whether the official tags are listed for easy selection, or a text area where arbitrary tags may be typed, or both. The default is both.&lt;br /&gt;
&lt;br /&gt;
The value should be set/returned as an array of tags.&lt;br /&gt;
&lt;br /&gt;
==addGroup==&lt;br /&gt;
&lt;br /&gt;
A &#039;group&#039; in formslib is just a group of elements that will have a label and will be included on one line. &lt;br /&gt;
&lt;br /&gt;
For example typical code to include a submit and cancel button on the same line : &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $buttonarray=array();&lt;br /&gt;
        $buttonarray[] =&amp;amp; $mform-&amp;gt;createElement(&#039;submit&#039;, &#039;submitbutton&#039;, get_string(&#039;savechanges&#039;));&lt;br /&gt;
        $buttonarray[] =&amp;amp; $mform-&amp;gt;createElement(&#039;submit&#039;, &#039;cancel&#039;, get_string(&#039;cancel&#039;));&lt;br /&gt;
        $mform-&amp;gt;addGroup($buttonarray, &#039;buttonar&#039;, &#039;&#039;, array(&#039; &#039;), false);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You use the same arguments for createElement as you do for addElement. Any label for the element in the third argument is normally ignored (but not in the case of the submit buttons above where the third argument is not for a label but is the text for the button).&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a bad example (don&#039;t do this for real, use the &#039;optional&#039; =&amp;gt; true option of the date element): putting a date_selector (which is itself a group of elements) and a checkbox on the same line, note that you can disable every element in the group using the group name &#039;availablefromgroup&#039; but it doesn&#039;t disable the controlling element the &#039;availablefromenabled&#039; checkbox:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $availablefromgroup=array();&lt;br /&gt;
	$availablefromgroup[] =&amp;amp; $mform-&amp;gt;createElement(&#039;date_selector&#039;, &#039;availablefrom&#039;, &#039;&#039;);&lt;br /&gt;
	$availablefromgroup[] =&amp;amp; $mform-&amp;gt;createElement(&#039;checkbox&#039;, &#039;availablefromenabled&#039;, &#039;&#039;, get_string(&#039;enable&#039;));&lt;br /&gt;
        $mform-&amp;gt;addGroup($availablefromgroup, &#039;availablefromgroup&#039;, get_string(&#039;availablefromdate&#039;, &#039;data&#039;), &#039;&amp;amp;nbsp;&#039;, false);&lt;br /&gt;
        $mform-&amp;gt;disabledIf(&#039;availablefromgroup&#039;, &#039;availablefromenabled&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==addRule==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $mform-&amp;gt;addRule(&#039;elementname&#039;, get_string(&#039;error&#039;), &#039;rule type&#039;, &#039;extraruledata&#039;, &#039;server&#039;(default), false, false);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first param(element) is an element name and second(message) is the error message that will be displayed to the user.&lt;br /&gt;
The third parameter(type) is the type of rule. The fourth param(format) is used for extra data needed with some rules such as minlength and regex. The fifth parameter(validation) validates input data on server or client side, if validation is done on client side then it will be checked on the server side as well.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 * @param    string     $element       Form element name&lt;br /&gt;
 * @param    string     $message       Message to display for invalid data&lt;br /&gt;
 * @param    string     $type          Rule type, use getRegisteredRules() to get types&lt;br /&gt;
 * @param    string     $format        (optional)Required for extra rule data&lt;br /&gt;
 * @param    string     $validation    (optional)Where to perform validation: &amp;quot;server&amp;quot;, &amp;quot;client&amp;quot;&lt;br /&gt;
 * @param    boolean    $reset         Client-side validation: reset the form element to its original value if there is an error?&lt;br /&gt;
 * @param    boolean    $force         Force the rule to be applied, even if the target form element does not exist&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Common Rule Types&#039;&#039;&#039;&lt;br /&gt;
* required &lt;br /&gt;
* maxlength&lt;br /&gt;
* minlength&lt;br /&gt;
* rangelength&lt;br /&gt;
* email&lt;br /&gt;
* regex&lt;br /&gt;
* lettersonly&lt;br /&gt;
* alphanumeric&lt;br /&gt;
* numeric&lt;br /&gt;
* nopunctuation&lt;br /&gt;
* nonzero&lt;br /&gt;
* callback&lt;br /&gt;
* compare&lt;br /&gt;
&lt;br /&gt;
==setHelpButton==&lt;br /&gt;
{{Moodle 1.9}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            $mform-&amp;gt;setHelpButton(&#039;lessondefault&#039;, array(&#039;lessondefault&#039;, get_string(&#039;lessondefault&#039;, &#039;lesson&#039;), &#039;lesson&#039;));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
First param is an elementname and the second param is an array of params that are passed to helpbutton in weblib.php. Params are :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 * @param string $page  The keyword that defines a help page&lt;br /&gt;
 * @param string $title The title of links, rollover tips, alt tags etc&lt;br /&gt;
 *           &#039;Help with&#039; (or the language equivalent) will be prefixed and &#039;...&#039; will be stripped.&lt;br /&gt;
 * @param string $module Which module is the page defined in&lt;br /&gt;
 * @param mixed $image Use a help image for the link?  (true/false/&amp;quot;both&amp;quot;)&lt;br /&gt;
 * @param boolean $linktext If true, display the title next to the help icon.&lt;br /&gt;
 * @param string $text If defined then this text is used in the page, and&lt;br /&gt;
 *           the $page variable is ignored.&lt;br /&gt;
 * @param boolean $return If true then the output is returned as a string, if false it is printed to the current page.&lt;br /&gt;
 * @param string $imagetext The full text for the helpbutton icon. If empty use default help.gif&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Make sure you don&#039;t set boolean $return to false. &lt;br /&gt;
&lt;br /&gt;
You need to do use this method after addElement();&lt;br /&gt;
&lt;br /&gt;
==addHelpButton==&lt;br /&gt;
{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            $mform-&amp;gt;addHelpButton(&#039;api_key_field&#039;, &#039;api_key&#039;, &#039;block_extsearch&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Moodle 2.0 the &amp;quot;setHelpButton&amp;quot; method has been deprecated in favor of the &amp;quot;addHelpButton&amp;quot; method, which has a simplified interface and uses $OUTPUT-&amp;gt;help_icon() on the back end. The following parameters are expected:&lt;br /&gt;
&lt;br /&gt;
 * @param $elementname The name of the form element to add the help button for&lt;br /&gt;
 * @param $identifier The identifier for the help string and its title (see below)&lt;br /&gt;
 * @param $component The component name to look for the help string in&lt;br /&gt;
&lt;br /&gt;
Unlike in Moodle 1.9, it is no longer necessary to put your help pages in separate HTML files. Instead, the function looks for two strings:&lt;br /&gt;
&lt;br /&gt;
 1. get_string($identifier, $component): The title of the help page&lt;br /&gt;
 2. get_string(&amp;quot;{$identifier}_help&amp;quot;, $component): The content of the help page&lt;br /&gt;
&lt;br /&gt;
So you will need to have &#039;&#039;&#039;$identifier&#039;&#039;&#039; and &#039;&#039;&#039;{$identifier}_help&#039;&#039;&#039; defined in order for the help button to be created properly.&lt;br /&gt;
&lt;br /&gt;
==setDefault==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $mform-&amp;gt;addElement(&#039;select&#039;, &#039;grade&#039;, get_string(&#039;gradeforsubmission&#039;, &#039;exercise&#039;), $grades);&lt;br /&gt;
        $mform-&amp;gt;setHelpButton(&#039;grade&#039;, array(&#039;grade&#039;, get_string(&#039;gradeforsubmission&#039;, &#039;exercise&#039;), &#039;exercise&#039;));&lt;br /&gt;
        $mform-&amp;gt;setDefault(&#039;grade&#039;, 100);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set the default of the form value with setDefault($elementname, $value); where elementname is the elementname whose default you want to set and $value is the default to set. We set the defaults for the form in definition(). This default is what is used if no data is loaded into the form with set_data(); eg. on display of the form for an &#039;add&#039; rather than &#039;update&#039; function.&lt;br /&gt;
&lt;br /&gt;
==disabledIf==&lt;br /&gt;
&lt;br /&gt;
For any element or groups of element in a form you can conditionally disable the group or individual element depending on conditions.&lt;br /&gt;
&lt;br /&gt;
You can use $mform-&amp;gt;disabledIf($elementName, $dependentOn, $condition = &#039;notchecked&#039;, $value=null)&lt;br /&gt;
&lt;br /&gt;
* elementname can be a group. If you specify a group all elements in the group will be disabled (if dependentOn is in elementname group that is ignored and not disabled). These are the element names you&#039;ve used as the second argument in addElement or addGroup.&lt;br /&gt;
* dependentOn is the actual name of the element as it will appear in html. This can be different to the name used in addGroup particularly but also addElement where you&#039;re adding a complex element like a date_selector. Check the html of your page. You typically make the depedentOn a checkbox or select box.&lt;br /&gt;
* $condition will be &#039;notchecked&#039;, &#039;checked&#039;, &#039;noitemselected&#039;, &#039;eq&#039; or, if it is anything else, we test for &#039;neq&#039;.&lt;br /&gt;
** If $condition is &#039;eq&#039; or &#039;neq&#039; then we check the value of the dependentOn field and check for equality (==) or nonequality (!=) in js&lt;br /&gt;
** If $condition is &#039;checked&#039; or &#039;notchecked&#039; then we check to see if a checkbox is checked or not.&lt;br /&gt;
** If $condition is &#039;noitemselected&#039; then we check to see whether nothing is selected in a dropdown list.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
 // Disable my control unless a checkbox is checked.&lt;br /&gt;
 $mform-&amp;gt;disabledIf(&#039;mycontrol&#039;, &#039;somecheckbox&#039;);&lt;br /&gt;
 &lt;br /&gt;
 // Disable my control if a checkbox &#039;&#039;&#039;is&#039;&#039;&#039; checked.&lt;br /&gt;
 $mform-&amp;gt;disabledIf(&#039;mycontrol&#039;, &#039;somecheckbox&#039;, &#039;checked&#039;);&lt;br /&gt;
 &lt;br /&gt;
 // Disable my control unless a dropdown has value 42.&lt;br /&gt;
 $mform-&amp;gt;disabledIf(&#039;mycontrol&#039;, &#039;someselect&#039;, &#039;eq&#039;, 42);&lt;br /&gt;
&lt;br /&gt;
The possible choices here are in the function lockoptionsall in lib/javascript-static.js.&lt;br /&gt;
&lt;br /&gt;
==setType==&lt;br /&gt;
&lt;br /&gt;
PARAM_* types are used to specify how a submitted variable should be cleaned. These should be used for get parameters such as id, course etc. which are used to load a page and also with setType(); method. Every form element should have a type specified except select, radio box and checkbox elements, these elements do a good job of cleaning themselves (only specified options are allowed as user input).&lt;br /&gt;
&lt;br /&gt;
===Most Commonly Used PARAM_* Types===&lt;br /&gt;
&lt;br /&gt;
These are the most commonly used PARAM_* types and their proper uses. More types can be seen in moodlelib.php starting around line 100.&lt;br /&gt;
&lt;br /&gt;
* PARAM_CLEAN is deprecated and you should try to use a more specific type.&lt;br /&gt;
* PARAM_TEXT should be used for cleaning data that is expected to be plain text. It will strip all html tags. But will still let tags for multilang support through.&lt;br /&gt;
* PARAM_NOTAGS should be used for cleaning data that is expected to be plain text. It will strip *all* html type tags. It will still *not* let tags for multilang support through. This should be used for instance for email addresses where no multilang support is appropriate.&lt;br /&gt;
* PARAM_RAW means no cleaning whatsoever, it is used mostly for data from the html editor. Data from the editor is later cleaned before display using format_text() function. PARAM_RAW can also be used for data that is validated by some other way or printed by p() or s().&lt;br /&gt;
* PARAM_INT should be used for integers.&lt;br /&gt;
* PARAM_ACTION is an alias of PARAM_ALPHA and is used for hidden fields specifying form actions.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
* [http://www.midnighthax.com/quickform.php PEAR HTML QuickForm Getting Started Guide] by Keith Edmunds of Midnighthax.com&lt;br /&gt;
* [http://pear.php.net/manual/en/package.html.html-quickform.php PEAR::HTML_QuickForm manual]&lt;br /&gt;
&lt;br /&gt;
[[Category:Formslib]]&lt;br /&gt;
&lt;br /&gt;
If you have problems creating php forms you may get them with form builder http://phpforms.net/tutorial/html-basics/form-builder.html&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Development_talk:lib/formslib.php_Form_Definition&amp;diff=81094</id>
		<title>Development talk:lib/formslib.php Form Definition</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Development_talk:lib/formslib.php_Form_Definition&amp;diff=81094"/>
		<updated>2011-02-06T13:06:47Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There&#039;s items on here (e.g. &#039;duration&#039;) that are 2.0 only. Please can people adding them mark them as such to avoid confusion. Ta --[[User:Howard Miller|Howard Miller]] 11:42, 23 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
: Hi Howard, You can just add &amp;lt;nowiki&amp;gt;{{Moodle 2.0}}&amp;lt;/nowiki&amp;gt; to those items. I did that for &#039;duration&#039;. --[[User:Frank Ralf|Frank Ralf]] 11:54, 23 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Use Static elements with care? ==&lt;br /&gt;
&lt;br /&gt;
Why are static elements listed as being used with care?&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;Please do not create conditional elements in definition(), the definition() should not directly depend on the submitted data.&#039;&#039; ==&lt;br /&gt;
&lt;br /&gt;
I&#039;m really not sure what this means. Does it actually mean &amp;quot;do not create elements that are conditional upon the values of other submitted elements&amp;quot; as opposed to not creating conditional elements at all? Lots of forms have conditional elements --[[User:Howard Miller|Howard Miller]] 13:06, 6 February 2011 (UTC)&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Development:Development_hints_and_tips&amp;diff=81072</id>
		<title>Development:Development hints and tips</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Development:Development_hints_and_tips&amp;diff=81072"/>
		<updated>2011-02-04T10:36:20Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* Use a Version Control system */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
&lt;br /&gt;
There is a great deal of development experience amongst the Moodle developers. This page is some general hints and tips that may help people starting out in PHP and Moodle development. These apply as much to people writing their own plugins as core developers.&lt;br /&gt;
&lt;br /&gt;
== Avoid writing code in the first place ==&lt;br /&gt;
&lt;br /&gt;
Always take the trouble to find if there is another (existing) way to do what you need. Failing that, does a plugin or option already exist. Failing that, does something exist that you can modify. Failing that, is there a library (or libraries) that exist to reduce your effort. Lastly write the code yourself. Existing, tested code is always to be preferred - more so if it has an extensive user base. &lt;br /&gt;
&lt;br /&gt;
== Follow the Coding Guidelines ==&lt;br /&gt;
&lt;br /&gt;
Moodle has a well developed set of [[Development:Coding|Coding Guidelines]]. Read them and follow them. It&#039;s surprising how many custom plugins for Moodle do not. It instantly prevents your code from being incorporated in core Moodle.&lt;br /&gt;
&lt;br /&gt;
Pay particular attention to the security information. A basic understanding of security in a web development environment is no longer optional. If you don&#039;t know what an XSS attack or an SQL injection are then you need to find out.&lt;br /&gt;
&lt;br /&gt;
== When in Rome, do like the Romans ==&lt;br /&gt;
&lt;br /&gt;
The Coding Guidelines do not describe every possible situation. When you find yourself in that situation, try to follow the example of how things are done in other parts of Moodle. Just because Moodle is not written the way you would do it if you were starting from scratch does not matter. In a large project like Moodle, it is more important to keep the code consistent than it is to satisfy your personal prejudices about how code should be. That makes it easier to maintain the code, and if you start writing Moodle-style code, you will find it easier to understand the other bits of Moodle code you look at.&lt;br /&gt;
&lt;br /&gt;
Of course, some parts of Moodle are just badly written. You should not copy what is done in those places. ;-) When looking for examples to follow, try to find code that has been written recently by one of the reliable core developers.&lt;br /&gt;
&lt;br /&gt;
Getting involved in a large Open Source project can be a bit of a culture shock if you are not used to it. Lots of advice (and, sometimes, constructive criticism) is readily available. Don&#039;t be afraid to ask - that&#039;s what the General Developer Forum is for.&lt;br /&gt;
&lt;br /&gt;
== Use a Version Control system ==&lt;br /&gt;
&lt;br /&gt;
If you are developing without a version control system then you are doing it wrong. The benefits run well beyond just being able to keep past versions of your code. Moodle uses [[Development:Git tips|Git]] for developing so it makes sense to learn it. This is a powerful distributed system and does take a bit of getting your head around but the effort is worth it.&lt;br /&gt;
&lt;br /&gt;
== Find an editor or IDE that works for you and learn it properly ==&lt;br /&gt;
&lt;br /&gt;
There are many different development platforms from complex Integrated Development Environments (IDEs) to simple editors and command line tools. Choose something that works for you and then take the trouble to learn how to use it properly.&lt;br /&gt;
&lt;br /&gt;
Find the editor&#039;s customisation options and make it fit in with Moodle&#039;s coding guidelines - example, most editors can be persuaded to use the correct number of spaces (4 in Moodle&#039;s case) rather than the tab character.&lt;br /&gt;
&lt;br /&gt;
== Comment effectively ==&lt;br /&gt;
&lt;br /&gt;
Don&#039;t be shy about putting comments in code. If the code deserves a blank line it probably deserves a comment. It&#039;s obvious what the code does now but it won&#039;t be in six months.&lt;br /&gt;
&lt;br /&gt;
== KISS (Keep It Simple Stupid) ==&lt;br /&gt;
&lt;br /&gt;
Albert Einstein didn&#039;t &#039;&#039;actually&#039;&#039; say &amp;quot;Everything should be made as simple as possible, but no simpler&amp;quot; but it would still have been good advice if he had. Take the trouble to come up with the simplest solution to the problem at hand. Resist the temptation to add code for things that you &#039;&#039;might&#039;&#039; need in the future or &#039;&#039;might&#039;&#039; be required one day. They usually never happen and you can always change the code later if requirements change. For example, don&#039;t use some insanely complex object factory when old-fashioned procedural programming will do. Don&#039;t use old-fashioned procedural programming when a class-hierarchy models the real-world problem more intuitively. Avoid complex abstractions where they are not actually needed to get the job done. Any additional code increases the risk of bugs, security problems and maintenance issues in the future.&lt;br /&gt;
&lt;br /&gt;
== Use good variable and function names ==&lt;br /&gt;
&lt;br /&gt;
It should be easy and obvious to pick a name for a variable or a function. If it isn&#039;t you are either trying to make that function too complicated (simplify and break it up) or you haven&#039;t fully understood what you are trying to do (another cup of coffee?). Names should always say what they are for or what they do - plainly.&lt;br /&gt;
&lt;br /&gt;
== Pretty code is good code ==&lt;br /&gt;
&lt;br /&gt;
Seriously! Code that is well laid out and easy to read is easy to debug and to modify. Make the effort to lay out code so it looks good and is easy to read through. Don&#039;t be afraid to break something nasty into several lines so that it reads well. It&#039;s tempting to make one line of code do something incredibly complex but you won&#039;t feel so clever when you can&#039;t remember how it works.&lt;br /&gt;
&lt;br /&gt;
== Write Plugins. Use APIs ==&lt;br /&gt;
&lt;br /&gt;
Always, when developing custom features, write a standard plugin in preference to modifying core code. Even if you have to compromise the functionality a bit. Most Moodle plugin structures are able to easily create database structures, handle role capabilities, define language files and ease future updates. Furthermore, the end result can all be delivered in one simple zip file. It doesn&#039;t rely on one particular build of Moodle either. These are real and big advantages. A core code patch is only guaranteed to work with the exact build it was written with, it probably won&#039;t survive upgrades and patches are notoriously difficult to apply properly - even for experienced developers. If in doubt look at blocks - you can do an awful lot with a block (even if it&#039;s never actually added as a visible block). Blocks are reasonably easy to understand and to develop, too. &lt;br /&gt;
&lt;br /&gt;
Similarly, take the trouble to investigate existing Moodle APIs and library calls. Your code will last longer and be more reliable.&lt;br /&gt;
&lt;br /&gt;
== Separate out functionality ==&lt;br /&gt;
&lt;br /&gt;
Or... don&#039;t muddle up the user interface with the database access and other logic. For example, alarm bells should ring if you are writing functions like &#039;&#039;&#039;get_data_and_display()&#039;&#039;&#039;. It is a much better idea to write &#039;&#039;&#039;get_data()&#039;&#039;&#039; and then &#039;&#039;&#039;display_data()&#039;&#039;&#039;. The effort is little or no different, however, the end result is often easier to follow and (say) if someone asks you to dump the data to Excel rather than display it the latter method saves you a costly refactor. Even if you are not writing functions and your logic is all on one page try to split things into logical blocks - read the input, THEN do the calculations and database access, THEN display the output. It will be easier to refactor or to modify.&lt;br /&gt;
&lt;br /&gt;
== Don&#039;t Make Me Think ==&lt;br /&gt;
&lt;br /&gt;
It&#039;s actually a title of a book by Steve Krug (and it should be obligatory reading for all web designers), however, the point is really about Usability. Usability is hard but you still have to try. Don&#039;t make your users have to think. Good documentation is important but it&#039;s hard to keep it up to date and it&#039;s a partial failure if someone has to resort to reading it. In particular, be quite clear that ordinary Moodle users don&#039;t care about clever implementation or super flexibility. Anything that complicates the job of getting effective learning materials to students is &amp;quot;a bad thing&amp;quot;. Anything that in the name of adding flexibility or functionality makes an ordinary user&#039;s job more complex is a regression. If something must be done then the code must do it - do not burden the user. &lt;br /&gt;
&lt;br /&gt;
Force yourself to think like a user and not a programmer. A clever, elegant solution to a programming problem is not guaranteed to result in a feature that is simple and intuitive to use. Look at the forums. If lots of people are having trouble using a feature then you need to consider if the feature is doing the job well enough. &lt;br /&gt;
&lt;br /&gt;
It should be hard (or even better impossible) for users to break things. The greatest invention ever was the undo button - it doesn&#039;t only protect the user against mistakes it allows them to safely experiment. Users don&#039;t learn to use software by reading the manual - they experiment and guess. Make it easy for them.&lt;br /&gt;
&lt;br /&gt;
There&#039;s some guidelines (currently under development) in [[Development:Moodle User Interface Guidelines|User Interface Guidelines]]&lt;br /&gt;
&lt;br /&gt;
== Let the database do the grunt work ==&lt;br /&gt;
&lt;br /&gt;
If there&#039;s a choice let the database do the work of searches. Especially if multiple tables are involved. It&#039;s what it was designed to do. It can be tempting, especially if your SQL knowledge isn&#039;t too good, to tie together multiple database queries with PHP loops and the like. Always consider using a single database call instead. Always try to use the basic Moodle database API functions before writing custom SQL (portability!).&lt;br /&gt;
&lt;br /&gt;
Having said all that, optimising databases (especially when datasets get large) is a subject in itself. Nearly all web development involves database interactions so even basic db admin skills are very valuable and worthwhile acquiring.&lt;br /&gt;
&lt;br /&gt;
== Generate helpful error messages ==&lt;br /&gt;
&lt;br /&gt;
If you generate an error message, consider if it &#039;really&#039; helps the user fix the problem. Be as specific as possible. If you can give information that will help resolve the problem rather than just say it happened then do so. BUT... you also have to consider security. Don&#039;t give away information that might help a hacker. You might want to consider debugging level (is it on?) and/or who the user is (you might give an administrator more information).&lt;br /&gt;
&lt;br /&gt;
You should also try to trap as many possible errors as possible. If a function returns a fail condition then you would need to have a very good reason not to check it. This helps avoid the highly unpopular &amp;quot;white screen of death&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Add extra debugging code (call &#039;&#039;debugging()&#039;&#039; )if you think it might help. This is especially true for functions that have complex configuration or external dependencies (i.e. lots that can go wrong).&lt;br /&gt;
&lt;br /&gt;
Never write an error message that looks something like &amp;quot;An unknown error occurred&amp;quot;. You might as well not bother as this doesn&#039;t help anybody fix the problem.&lt;br /&gt;
&lt;br /&gt;
== Don&#039;t make empty pages and blocks ==&lt;br /&gt;
&lt;br /&gt;
If you write code that returns (typically) a block (but you can do it lots of places) think very carefully before returning nothing. An empty return for a block causes the block not to be displayed at all. Unless you have a very compelling reason to do this avoid it. It will confuse the user - they add a block and then nothing happens. If some capability or configuration is required consider displaying a message to help them. In a report or other pages that return variable data, be careful how you deal with empty data sets. Always display something like &amp;quot;no data found&amp;quot; rather than a blank page. Blank pages make users think something is broken.&lt;br /&gt;
&lt;br /&gt;
== Turn on Debugging and fix those notices and warnings ==&lt;br /&gt;
&lt;br /&gt;
If you get PHP warnings or notices when [[Debugging]] is switched on the problem is &#039;&#039;&#039;not&#039;&#039;&#039; that debugging has been left on, the problem is that there are bugs in your code. There is no excuse for not checking for and then fixing notices and warnings. To not do so is shoddy at best.&lt;br /&gt;
&lt;br /&gt;
== Expand Moodle Docs ==&lt;br /&gt;
&lt;br /&gt;
If something you want to do isn&#039;t documented (or isn&#039;t documented well or fully) and you figure it out - document it. Don&#039;t write it in your notebook or your company&#039;s closed Wiki, put it in the docs here. It&#039;s there for you next time and for everyone else as well.&lt;br /&gt;
&lt;br /&gt;
== More tips please ==&lt;br /&gt;
(add your own!)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Talk:Grade_import&amp;diff=81041</id>
		<title>Talk:Grade import</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Talk:Grade_import&amp;diff=81041"/>
		<updated>2011-02-03T10:41:55Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The instructions on this page are very unclear. They vaguely instruct you to just &amp;quot;export some grades using the corresponding export format&amp;quot;, &amp;quot;edit the export file as appropriate and save it&amp;quot; and then &amp;quot;upload your previously saved file&amp;quot;.&lt;br /&gt;
It doesn&#039;t have any details. For instance, what fields CAN you include in the export file (what fields are optional), what fields MUST you include (are compulsory) and what fields CAN&#039;T you include (e.g. course totals)?&lt;br /&gt;
&lt;br /&gt;
In http://moodle.org/mod/forum/discuss.php?d=85944#p381209 Tim Hunt says: &amp;quot;... please be aware that you cannot import the course total. The gradebook handles the aggregation of grades, and you can edit this aggregation, or even override the course total manually, but you cannot import it using a CSV file.&amp;quot; This is valuable information but it seems to have been completely omitted from the import/export documentation.&lt;br /&gt;
&lt;br /&gt;
What makes it more confusing is that the https://docs.moodle.org/en/Grade_export documentation (which is also very vague)&lt;br /&gt;
says that you can include the Course Total in the export file but the implications thereof aren&#039;t explained. If users are exporting data just for the purpose of getting the format of the IMPORT file (as the instructions on the https://docs.moodle.org/en/Grade_import page tell you to do) they should NOT select the Course Total in the export. This should be clarified in the documentation.&lt;br /&gt;
&lt;br /&gt;
Also, the instructions for importing grades are quite vague, e.g.:&lt;br /&gt;
&lt;br /&gt;
Point 2 says: &amp;quot;Edit the export file as appropriate and save it.&amp;quot; What is &amp;quot;appropriate&amp;quot; and when is it appropriate?&lt;br /&gt;
&lt;br /&gt;
Point 5 says: &amp;quot;Set options as required.&amp;quot; What options are these?&lt;br /&gt;
&lt;br /&gt;
And the Grade_import page also says: &amp;quot;You need two permissions to import grades: (1) general permission to import grades and (2) permission to import grades in a particular format. For example, to import CSV grades you need:&lt;br /&gt;
&lt;br /&gt;
   moodle/grade:import (&amp;quot;Import grades&amp;quot;) = Allow&lt;br /&gt;
   gradeimport/csv:view (&amp;quot;Import grades from CSV&amp;quot;) = Allow&amp;quot;&lt;br /&gt;
&lt;br /&gt;
How and where do you set these permissions? Are they code changes that you have to make?&lt;br /&gt;
&lt;br /&gt;
Finally, no mention is made of what format the grades must be in when you import them into Moodle. Can you import grades as percentages, or MUST they be the actual numerical values? Do users have the option of importing grades as percentages or is it assumed that grades will always be in their numerical form?&lt;br /&gt;
&lt;br /&gt;
I don&#039;t know the answers so I can&#039;t update the documentation...&lt;br /&gt;
&lt;br /&gt;
[[User:Luis de Vasconcelos|Luis de Vasconcelos]] 02:13, 27 October 2008 (CDT)&lt;br /&gt;
&lt;br /&gt;
I&#039;ll be a little more forthright than the above. Without an explanation of the file format this is all a bit useless. --[[User:Howard Miller|Howard Miller]] 10:41, 3 February 2011 (UTC)&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Development:Development_hints_and_tips&amp;diff=80952</id>
		<title>Development:Development hints and tips</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Development:Development_hints_and_tips&amp;diff=80952"/>
		<updated>2011-01-30T20:51:50Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* Generate helpful error messages */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
&lt;br /&gt;
There is a great deal of development experience amongst the Moodle developers. This page is some general hints and tips that may help people starting out in PHP and Moodle development. These apply as much to people writing their own plugins as core developers.&lt;br /&gt;
&lt;br /&gt;
== Avoid writing code in the first place ==&lt;br /&gt;
&lt;br /&gt;
Always take the trouble to find if there is another (existing) way to do what you need. Failing that, does a plugin or option already exist. Failing that, does something exist that you can modify. Failing that, is there a library (or libraries) that exist to reduce your effort. Lastly write the code yourself. Existing, tested code is always to be preferred - more so if it has an extensive user base. &lt;br /&gt;
&lt;br /&gt;
== Follow the Coding Guidelines ==&lt;br /&gt;
&lt;br /&gt;
Moodle has a well developed set of [[Development:Coding|Coding Guidelines]]. Read them and follow them. It&#039;s surprising how many custom plugins for Moodle do not. It instantly prevents your code from being incorporated in core Moodle.&lt;br /&gt;
&lt;br /&gt;
Pay particular attention to the security information. A basic understanding of security in a web development environment is no longer optional. If you don&#039;t know what an XSS attack or an SQL injection are then you need to find out.&lt;br /&gt;
&lt;br /&gt;
== When in Rome, do like the Romans ==&lt;br /&gt;
&lt;br /&gt;
The Coding Guidelines do not describe every possible situation. When you find yourself in that situation, try to follow the example of how things are done in other parts of Moodle. Just because Moodle is not written the way you would do it if you were starting from scratch does not matter. In a large project like Moodle, it is more important to keep the code consistent than it is to satisfy your personal prejudices about how code should be. That makes it easier to maintain the code, and if you start writing Moodle-style code, you will find it easier to understand the other bits of Moodle code you look at.&lt;br /&gt;
&lt;br /&gt;
Of course, some parts of Moodle are just badly written. You should not copy what is done in those places. ;-) When looking for examples to follow, try to find code that has been written recently by one of the reliable core developers.&lt;br /&gt;
&lt;br /&gt;
Getting involved in a large Open Source project can be a bit of a culture shock if you are not used to it. Lots of advice (and, sometimes, constructive criticism) is readily available. Don&#039;t be afraid to ask - that&#039;s what the General Developer Forum is for.&lt;br /&gt;
&lt;br /&gt;
== Use a Version Control system ==&lt;br /&gt;
&lt;br /&gt;
If you are developing without a version control system then you are doing it wrong. The benefits run well beyond just being able to keep past versions of your code. Moodle currently uses CVS for core development but this is probably a poor (out of date) choice for a new project. Moodle uses [[Development:Git tips|Git]] for developing so it makes sense to learn it. This is a powerful distributed system and does take a bit of getting your head around but the effort is worth it.&lt;br /&gt;
&lt;br /&gt;
== Find an editor or IDE that works for you and learn it properly ==&lt;br /&gt;
&lt;br /&gt;
There are many different development platforms from complex Integrated Development Environments (IDEs) to simple editors and command line tools. Choose something that works for you and then take the trouble to learn how to use it properly.&lt;br /&gt;
&lt;br /&gt;
Find the editor&#039;s customisation options and make it fit in with Moodle&#039;s coding guidelines - example, most editors can be persuaded to use the correct number of spaces (4 in Moodle&#039;s case) rather than the tab character.&lt;br /&gt;
&lt;br /&gt;
== Comment effectively ==&lt;br /&gt;
&lt;br /&gt;
Don&#039;t be shy about putting comments in code. If the code deserves a blank line it probably deserves a comment. It&#039;s obvious what the code does now but it won&#039;t be in six months.&lt;br /&gt;
&lt;br /&gt;
== KISS (Keep It Simple Stupid) ==&lt;br /&gt;
&lt;br /&gt;
Albert Einstein didn&#039;t &#039;&#039;actually&#039;&#039; say &amp;quot;Everything should be made as simple as possible, but no simpler&amp;quot; but it would still have been good advice if he had. Take the trouble to come up with the simplest solution to the problem at hand. Resist the temptation to add code for things that you &#039;&#039;might&#039;&#039; need in the future or &#039;&#039;might&#039;&#039; be required one day. They usually never happen and you can always change the code later if requirements change. For example, don&#039;t use some insanely complex object factory when old-fashioned procedural programming will do. Don&#039;t use old-fashioned procedural programming when a class-hierarchy models the real-world problem more intuitively. Avoid complex abstractions where they are not actually needed to get the job done. Any additional code increases the risk of bugs, security problems and maintenance issues in the future.&lt;br /&gt;
&lt;br /&gt;
== Use good variable and function names ==&lt;br /&gt;
&lt;br /&gt;
It should be easy and obvious to pick a name for a variable or a function. If it isn&#039;t you are either trying to make that function too complicated (simplify and break it up) or you haven&#039;t fully understood what you are trying to do (another cup of coffee?). Names should always say what they are for or what they do - plainly.&lt;br /&gt;
&lt;br /&gt;
== Pretty code is good code ==&lt;br /&gt;
&lt;br /&gt;
Seriously! Code that is well laid out and easy to read is easy to debug and to modify. Make the effort to lay out code so it looks good and is easy to read through. Don&#039;t be afraid to break something nasty into several lines so that it reads well. It&#039;s tempting to make one line of code do something incredibly complex but you won&#039;t feel so clever when you can&#039;t remember how it works.&lt;br /&gt;
&lt;br /&gt;
== Write Plugins. Use APIs ==&lt;br /&gt;
&lt;br /&gt;
Always, when developing custom features, write a standard plugin in preference to modifying core code. Even if you have to compromise the functionality a bit. Most Moodle plugin structures are able to easily create database structures, handle role capabilities, define language files and ease future updates. Furthermore, the end result can all be delivered in one simple zip file. It doesn&#039;t rely on one particular build of Moodle either. These are real and big advantages. A core code patch is only guaranteed to work with the exact build it was written with, it probably won&#039;t survive upgrades and patches are notoriously difficult to apply properly - even for experienced developers. If in doubt look at blocks - you can do an awful lot with a block (even if it&#039;s never actually added as a visible block). Blocks are reasonably easy to understand and to develop, too. &lt;br /&gt;
&lt;br /&gt;
Similarly, take the trouble to investigate existing Moodle APIs and library calls. Your code will last longer and be more reliable.&lt;br /&gt;
&lt;br /&gt;
== Separate out functionality ==&lt;br /&gt;
&lt;br /&gt;
Or... don&#039;t muddle up the user interface with the database access and other logic. For example, alarm bells should ring if you are writing functions like &#039;&#039;&#039;get_data_and_display()&#039;&#039;&#039;. It is a much better idea to write &#039;&#039;&#039;get_data()&#039;&#039;&#039; and then &#039;&#039;&#039;display_data()&#039;&#039;&#039;. The effort is little or no different, however, the end result is often easier to follow and (say) if someone asks you to dump the data to Excel rather than display it the latter method saves you a costly refactor. Even if you are not writing functions and your logic is all on one page try to split things into logical blocks - read the input, THEN do the calculations and database access, THEN display the output. It will be easier to refactor or to modify.&lt;br /&gt;
&lt;br /&gt;
== Don&#039;t Make Me Think ==&lt;br /&gt;
&lt;br /&gt;
It&#039;s actually a title of a book by Steve Krug (and it should be obligatory reading for all web designers), however, the point is really about Usability. Usability is hard but you still have to try. Don&#039;t make your users have to think. Good documentation is important but it&#039;s hard to keep it up to date and it&#039;s a partial failure if someone has to resort to reading it. In particular, be quite clear that ordinary Moodle users don&#039;t care about clever implementation or super flexibility. Anything that complicates the job of getting effective learning materials to students is &amp;quot;a bad thing&amp;quot;. Anything that in the name of adding flexibility or functionality makes an ordinary user&#039;s job more complex is a regression. If something must be done then the code must do it - do not burden the user. &lt;br /&gt;
&lt;br /&gt;
Force yourself to think like a user and not a programmer. A clever, elegant solution to a programming problem is not guaranteed to result in a feature that is simple and intuitive to use. Look at the forums. If lots of people are having trouble using a feature then you need to consider if the feature is doing the job well enough. &lt;br /&gt;
&lt;br /&gt;
It should be hard (or even better impossible) for users to break things. The greatest invention ever was the undo button - it doesn&#039;t only protect the user against mistakes it allows them to safely experiment. Users don&#039;t learn to use software by reading the manual - they experiment and guess. Make it easy for them.&lt;br /&gt;
&lt;br /&gt;
There&#039;s some guidelines (currently under development) in [[Development:Moodle User Interface Guidelines|User Interface Guidelines]]&lt;br /&gt;
&lt;br /&gt;
== Let the database do the grunt work ==&lt;br /&gt;
&lt;br /&gt;
If there&#039;s a choice let the database do the work of searches. Especially if multiple tables are involved. It&#039;s what it was designed to do. It can be tempting, especially if your SQL knowledge isn&#039;t too good, to tie together multiple database queries with PHP loops and the like. Always consider using a single database call instead. Always try to use the basic Moodle database API functions before writing custom SQL (portability!).&lt;br /&gt;
&lt;br /&gt;
Having said all that, optimising databases (especially when datasets get large) is a subject in itself. Nearly all web development involves database interactions so even basic db admin skills are very valuable and worthwhile acquiring.&lt;br /&gt;
&lt;br /&gt;
== Generate helpful error messages ==&lt;br /&gt;
&lt;br /&gt;
If you generate an error message, consider if it &#039;really&#039; helps the user fix the problem. Be as specific as possible. If you can give information that will help resolve the problem rather than just say it happened then do so. BUT... you also have to consider security. Don&#039;t give away information that might help a hacker. You might want to consider debugging level (is it on?) and/or who the user is (you might give an administrator more information).&lt;br /&gt;
&lt;br /&gt;
You should also try to trap as many possible errors as possible. If a function returns a fail condition then you would need to have a very good reason not to check it. This helps avoid the highly unpopular &amp;quot;white screen of death&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Add extra debugging code (call &#039;&#039;debugging()&#039;&#039; )if you think it might help. This is especially true for functions that have complex configuration or external dependencies (i.e. lots that can go wrong).&lt;br /&gt;
&lt;br /&gt;
Never write an error message that looks something like &amp;quot;An unknown error occurred&amp;quot;. You might as well not bother as this doesn&#039;t help anybody fix the problem.&lt;br /&gt;
&lt;br /&gt;
== Don&#039;t make empty pages and blocks ==&lt;br /&gt;
&lt;br /&gt;
If you write code that returns (typically) a block (but you can do it lots of places) think very carefully before returning nothing. An empty return for a block causes the block not to be displayed at all. Unless you have a very compelling reason to do this avoid it. It will confuse the user - they add a block and then nothing happens. If some capability or configuration is required consider displaying a message to help them. In a report or other pages that return variable data, be careful how you deal with empty data sets. Always display something like &amp;quot;no data found&amp;quot; rather than a blank page. Blank pages make users think something is broken.&lt;br /&gt;
&lt;br /&gt;
== Turn on Debugging and fix those notices and warnings ==&lt;br /&gt;
&lt;br /&gt;
If you get PHP warnings or notices when [[Debugging]] is switched on the problem is &#039;&#039;&#039;not&#039;&#039;&#039; that debugging has been left on, the problem is that there are bugs in your code. There is no excuse for not checking for and then fixing notices and warnings. To not do so is shoddy at best.&lt;br /&gt;
&lt;br /&gt;
== Expand Moodle Docs ==&lt;br /&gt;
&lt;br /&gt;
If something you want to do isn&#039;t documented (or isn&#039;t documented well or fully) and you figure it out - document it. Don&#039;t write it in your notebook or your company&#039;s closed Wiki, put it in the docs here. It&#039;s there for you next time and for everyone else as well.&lt;br /&gt;
&lt;br /&gt;
== More tips please ==&lt;br /&gt;
(add your own!)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Development:Places_to_search_for_lang_strings&amp;diff=80801</id>
		<title>Development:Places to search for lang strings</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Development:Places_to_search_for_lang_strings&amp;diff=80801"/>
		<updated>2011-01-25T13:51:35Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* Defining the search path(s) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Moodle has a mechanism that allows a number of places to be searched (in order) to find language strings or help files. This enables language strings and help to be packaged with optional plugins and avoids the step of having to copy the language files over to the language directory when a plugin is installed. This page provides some information about this mechanism which might be useful to plugin developers or those wishing to add a completely new pluggable feature to moodle.&lt;br /&gt;
&lt;br /&gt;
This page covers both how to set up (core) Moodle to support a new plugabble resource and how to incorporate language elements in a plugin. Plugin writers really only need to read the last bit.&lt;br /&gt;
&lt;br /&gt;
== Basic concepts ==&lt;br /&gt;
&lt;br /&gt;
When it is required to lookup a string or point to a help file, two basic items of information are required. The first is the name of the string (or the help filename) and the name of the module in which it can be found. For example, &#039;&#039;&#039;get_string(&#039;editingquiz&#039;,&#039;quiz&#039;)&#039;&#039;&#039; returns &amp;quot;Editing Quiz&amp;quot; in the current language; a call to &#039;&#039;&#039;help.php?module=label&amp;amp;file=mods.html&#039;&#039;&#039; displays the help for a label, again in the current language. &lt;br /&gt;
&lt;br /&gt;
Plugin support extends this by defining a new format for the module name so that certain resources can both exist in core, the core distribution (and language packs) and be installed as options. The module name becomes &#039;&#039;type&#039;&#039;_&#039;&#039;plugin&#039;&#039;, where &#039;&#039;type&#039;&#039; is a generic name common to the plugin type and &#039;&#039;plugin&#039;&#039; is the name of the individual item. To illustrate this, here is an example. Blocks are a pluggable resource - the &#039;&#039;type&#039;&#039; name is &#039;&#039;&#039;block_&#039;&#039;&#039; and the &#039;&#039;plugin&#039;&#039; name is the name of the individual block. Some examples of block module names are &#039;&#039;&#039;block_search&#039;&#039;&#039; (&#039;&#039;type&#039;&#039; is &#039;&#039;&#039;block_&#039;&#039;&#039; and &#039;&#039;plugin&#039;&#039; is &#039;&#039;&#039;search&#039;&#039;&#039;) and &#039;&#039;&#039;block_online_users&#039;&#039;&#039; (&#039;&#039;type&#039;&#039; is &#039;&#039;&#039;block_&#039;&#039;&#039; and &#039;&#039;plugin&#039;&#039; is &#039;&#039;&#039;online_users&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
It is important to grasp that every block is now a discrete module type. This applies to all pluggable resources, so every, e.g., questiontype, authentication plugin, grade report is a separate module and will have its own language file and it&#039;s own directory for its help files. Not all plugin types define both language strings and help files but here is an example of what you might find for a pluggable resource that is included in core:&lt;br /&gt;
&lt;br /&gt;
    Description: questiontype plugin for multichoice&lt;br /&gt;
    Module name: qtype_multichoice&lt;br /&gt;
    Language strings (English): question/type/multichoice/lang/en_utf8/qtype_multichoice.php&lt;br /&gt;
    Help files directory (English): question/type/multichoice/lang/en_utf8/help/qtype_multichoice/&lt;br /&gt;
&lt;br /&gt;
All of the above must be in place for pluggable language and help strings to be a possibility for optional plugins.&lt;br /&gt;
&lt;br /&gt;
NOTE: Module names cannot have numbers in them (only A-Z, a-z and underscore). This might be an issue to consider if you are moving from an existing architecture.&lt;br /&gt;
&lt;br /&gt;
== Defining the search path(s) ==&lt;br /&gt;
&lt;br /&gt;
The next step is to define the search locations for the plugin. This is only needed to define where the optional plugins will be installed, the standard help locations will be searched automatically. This is done by adding an entry to the array defined in the function &#039;&#039;&#039;places_to_search_for_lang_strings&#039;&#039;&#039; located in &#039;&#039;&#039;lib/moodlelib.php&#039;&#039;&#039;. This should be obvious from viewing the code but don&#039;t forget to include the underscore!&lt;br /&gt;
&lt;br /&gt;
Some plugins define multiple locations for the same plugin type. For example, admin reports, course reports and quiz reports all have the plugin type &#039;&#039;&#039;report_&#039;&#039;&#039;. The code permits an array of different locations to be specified which are checked in turn. &lt;br /&gt;
&lt;br /&gt;
Viewing this function will also show you what Moodle elements currently support language string searching. This varies somewhat from version to version of Moodle as new locations are added.&lt;br /&gt;
&lt;br /&gt;
== Adding language support to a plugin ==&lt;br /&gt;
&lt;br /&gt;
If you are a plugin writer and you didn&#039;t read the first part of this you just need to be aware that your plugin name needs to start with the generic type for the plugin. For example all questiontype plugins &#039;&#039;&#039;must&#039;&#039;&#039; be prefixed &#039;&#039;&#039;qtype_&#039;&#039;&#039;, all authentication plugins &#039;&#039;&#039;auth_&#039;&#039;&#039;. Moodle uses this prefix to identify the language search path. &lt;br /&gt;
&lt;br /&gt;
All that remains is now to add the language support to the optional plugin(s). This is done by creating a &#039;&#039;&#039;lang&#039;&#039;&#039; subdirectory in the plugin directory. The structure of the &#039;&#039;&#039;lang&#039;&#039;&#039; directory is then the same as the &amp;quot;main&amp;quot; language directory with one exception - the help directory name should &#039;&#039;&#039;not&#039;&#039;&#039; have the &#039;&#039;type_&#039;&#039; part of the module name (this might be a bug really!). Example...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    Description: Drag &amp;amp; Drop optional question type&lt;br /&gt;
    Module type: qtype_&lt;br /&gt;
    Module name: qtype_dragdrop&lt;br /&gt;
    Language file location (English): contrib/plugins/question/type/dragdrop/lang/en_utf8/qtype_dragdrop.php&lt;br /&gt;
    Help file directory (English): contrib/plugins/question/type/dragdrop/lang/en_utf8/help/dragdrop/&lt;br /&gt;
&lt;br /&gt;
(Note: the help file directory is called &#039;&#039;&#039;dragdrop&#039;&#039;&#039; in the plugin. Compare this with the multichoice question type in core where the help folder is &#039;&#039;&#039;qtype_multichoice&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [http://phpdocs.moodle.org/HEAD/default/string_manager.html PHPdocs for the string_manager class]&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Language]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Development:CVS_for_developers&amp;diff=80370</id>
		<title>Development:CVS for developers</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Development:CVS_for_developers&amp;diff=80370"/>
		<updated>2011-01-15T19:45:45Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;NOTE: Moodle has now adopted Git for core development along with a new and evolving workflow. This document may no longer apply&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CVS&#039;&#039;&#039; is the Concurrent Versioning System, a commonly-used way of managing source code for large software projects. CVS keeps all versions of all files so that nothing is ever lost, and usage by different people is tracked. It also provides ways to merge code if two or more people are working on the same file. All code and all versions are stored on a central server (in the case of Moodle, at cvs.moodle.org). The [http://cvsbook.red-bean.com/cvsbook.html CVS book] holds more information about CVS than you need.&lt;br /&gt;
&lt;br /&gt;
If you just want to download Moodle using CVS to run a site, then you probably don&#039;t need this page - please see [[CVS for Administrators]] instead.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Joining the project as a developer==&lt;br /&gt;
&lt;br /&gt;
So, you&#039;ve been offered CVS write access to help us develop and maintain Moodle!  Welcome aboard!&lt;br /&gt;
&lt;br /&gt;
To be able to write changes into [http://cvs.moodle.org/ Moodle&#039;s CVS archive], you first need to have an account on the server.  Only trusted developers get these accounts.  To request access, go to the &amp;quot;Apply for CVS Access&amp;quot; tab on the CVS page on Moodle.org (http://moodle.org/cvs).  Tell us what modules you&#039;d like to access (e.g. a language module), and why.  You&#039;ll receive notification as soon as one of the core admins can authorise it.  (Please be patient, but if you feel your application is languishing, message Martin D on moodle.org :) )&lt;br /&gt;
&lt;br /&gt;
With that done, you should have all the permissions you need, so you just need to set up your machine and download the current source code so you can start working on it. &lt;br /&gt;
&lt;br /&gt;
For the examples on this page, let&#039;s assume your username is &#039;&#039;&#039;myusername&#039;&#039;&#039; and your password is &#039;&#039;&#039;mypassword&#039;&#039;&#039;. Things are a lot easier if you use an SSH key to access the server, as you won&#039;t have to keep typing these in. Check [[Development:SSH_key | here]] for instructions on how to make one.&lt;br /&gt;
&lt;br /&gt;
==CVS modules==&lt;br /&gt;
&lt;br /&gt;
Within CVS, the word &amp;quot;modules&amp;quot; refers to separate collections of code. In Moodle we have the following modules within our repository:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;moodle&#039;&#039;&#039; - the main Moodle source code&lt;br /&gt;
* &#039;&#039;&#039;lang&#039;&#039;&#039; - all the language packs&lt;br /&gt;
* &#039;&#039;&#039;[[Development:contrib|contrib]]&#039;&#039;&#039; - user contributions and other assorted code in development&lt;br /&gt;
* &#039;&#039;&#039;mysql&#039;&#039;&#039; - a customised phpMyAdmin to plug into Moodle for database admin&lt;br /&gt;
* &#039;&#039;&#039;windows-cron&#039;&#039;&#039; - a small package that makes cron possible on Windows systems&lt;br /&gt;
* &#039;&#039;&#039;docs&#039;&#039;&#039; - various extra user-contributed documentation&lt;br /&gt;
&lt;br /&gt;
Most people are working on the existing features in the moodle module, but many are also contributing new ideas in the contrib modules. Once code reaches a certain level of maturity in the contrib area, it can be migrated over into the main moodle tree.&lt;br /&gt;
&lt;br /&gt;
==Basic CVS commands==&lt;br /&gt;
&lt;br /&gt;
===CVS on Unix===&lt;br /&gt;
&lt;br /&gt;
Moodle CVS uses ssh as a transport layer for security, so you will have to set a CVS_RSH environment variable in your Unix shell. It&#039;s best to put these commands in your .bashrc or .cshrc so you don&#039;t have to type it all the time:&lt;br /&gt;
        setenv CVS_RSH ssh (for csh, tcsh etc)&lt;br /&gt;
        export CVS_RSH=ssh (for sh, bash etc)&lt;br /&gt;
&lt;br /&gt;
Next, you can check out the latest development version of Moodle using this (all one line). NOTE: Don&#039;t try to do run this first CVS command over an existing moodle installation: start fresh with a new directory!:&lt;br /&gt;
        cvs -z3 -d:ext:myusername@cvs.moodle.org:/cvsroot/moodle co -P moodle&lt;br /&gt;
&lt;br /&gt;
The command is similar for other CVS modules:&lt;br /&gt;
        cvs -z3 -d:ext:myusername@cvs.moodle.org:/cvsroot/moodle co -P contrib&lt;br /&gt;
&lt;br /&gt;
If you want to checkout a single plugin (attendance block as an example here) from contrib into the current directory, you can use:&lt;br /&gt;
        cvs -z3 -d:ext:myusername@cvs.moodle.org:/cvsroot/moodle co -d attendance contrib/plugins/blocks/attendance&lt;br /&gt;
&lt;br /&gt;
Note that you will be prompted for mypassword for each command unless you set up authorized keys.  Read [[Development:SSH_key|SSH Keys]] for more details on how to set those up.&lt;br /&gt;
&lt;br /&gt;
Now, you should have a new &#039;moodle&#039; directory. You can rename it and move it around if you like. Go into it:&lt;br /&gt;
        cd moodle&lt;br /&gt;
&lt;br /&gt;
All the latest Moodle files should be in there. You can now change files in your copy. To compare your files and directories against the main CVS copy on the server use cvs diff, e.g.:&lt;br /&gt;
        cvs diff -c config-dist.php&lt;br /&gt;
        cvs diff -c lang&lt;br /&gt;
&lt;br /&gt;
To fetch the latest updates from the server use:&lt;br /&gt;
        cvs update -dP&lt;br /&gt;
&lt;br /&gt;
To copy your new files back to the server you would do something like:&lt;br /&gt;
        cd lang/ca&lt;br /&gt;
        cvs commit&lt;br /&gt;
&lt;br /&gt;
You will be prompted to add some comments (depends on your default text editor).   Please write a meaningful, descriptive comment and &#039;&#039;&#039;always include the name of any tracker issues that talk about the issue you are fixing&#039;&#039;&#039; (eg &#039;&#039;&#039;MDL-XXXX&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
After that your changes will be sent to the CVS server and stored in the repository. Done!&lt;br /&gt;
&lt;br /&gt;
To save more time you can put default arguments into a file called .cvsrc in your home directory. For example, mine contains:&lt;br /&gt;
        diff -c&lt;br /&gt;
        update -dP&lt;br /&gt;
&lt;br /&gt;
Try &#039;cvs help&#039; for more details ...&lt;br /&gt;
&lt;br /&gt;
=== CVS on Mac OSX ===&lt;br /&gt;
&lt;br /&gt;
You can follow the same instructions as for Unix (above) in a terminal window. However, the cvs command is not installed by default in an OSX. You first need to install the &#039;&#039;&#039;Xcode Tools&#039;&#039;&#039;. You should find this on your original installation disk. Failing that it can be downloaded (a fairly hefty download) from the [http://developer.apple.com/technology/tools.html Apple developer web site].&lt;br /&gt;
&lt;br /&gt;
=== CVS on Windows ===&lt;br /&gt;
&lt;br /&gt;
First, you need to download a completely fresh copy of Moodle using your developer account. (If you only want a private copy for local development, anonymous login will work too.)&lt;br /&gt;
&lt;br /&gt;
1. Get [http://www.tortoisecvs.org TortoiseCVS] and install it, then reboot. TortoiseCVS works under Windows 95, 98, ME, NT, 2000, XP, and 2003. Vista is also supported, although some people report problems with UAC. (In the latter case you might resort to [http://www.syntevo.com/smartcvs/index.html SmartCVS].)&lt;br /&gt;
&lt;br /&gt;
2. Find or create a new folder somewhere where you want Moodle to be downloaded to.&lt;br /&gt;
&lt;br /&gt;
3. Right-mouse-click that folder and choose &amp;quot;CVS Checkout&amp;quot; from the menu. You should see a dialog box.&lt;br /&gt;
&lt;br /&gt;
4. Copy this text into the CVSROOT field (using your own username!):&lt;br /&gt;
&lt;br /&gt;
 :ext:myusername@cvs.moodle.org:/cvsroot/moodle&lt;br /&gt;
&lt;br /&gt;
5. Under the &amp;quot;Module&amp;quot; field, type &amp;quot;moodle&amp;quot; to get the latest development version of Moodle, &amp;quot;contrib&amp;quot; to get the contributions directory, or &amp;quot;mysql&amp;quot; to get the MySQL Admin module.&lt;br /&gt;
&lt;br /&gt;
6. Press the button: &amp;quot;OK&amp;quot; and everything should be downloaded.&lt;br /&gt;
&lt;br /&gt;
A dialog box should show all the files being downloaded, and after a while you should have a complete copy of Moodle. After this first checkout, you can fetch the latest updated files from the CVS server:&lt;br /&gt;
&lt;br /&gt;
# Right-mouse-click on your Moodle folder (or any file) and select &amp;quot;CVS Update&amp;quot;.&lt;br /&gt;
# Sit back and watch the logs scroll by. Take note of conflicts that may occur if your local code has changes that conflict with the incoming versions - you will need to edit these files and resolve the conflicts manually.&lt;br /&gt;
&lt;br /&gt;
After modifying files (you will notice their icons change from green to red!), you can commit them back to the CVS server like this:&lt;br /&gt;
&lt;br /&gt;
# Right-mouse-click on your Moodle folder (or any file) and select &amp;quot;CVS Commit...&amp;quot;.&lt;br /&gt;
# In the dialog box, type a clear description of the changes you are committing.  &#039;&#039;&#039;Always include the name of any tracker issues related to what you are fixing&#039;&#039;&#039; (eg &#039;&#039;&#039;MDL-XXXX&#039;&#039;&#039;).&lt;br /&gt;
# Click &amp;quot;OK&amp;quot;. Your changes will be sent to the server.&lt;br /&gt;
# If you create a folder, BE CAREFUL about using the &amp;quot;CVS Add&amp;quot; option as it will add the folder to CVS without requiring a commit. Once added, the folder cannot be removed from CVS even though it will be pruned so long as it is empty.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
N.B. I had enormous headaches with the above settings until I changed from ext to ssh. This was using an ssh certificate on windows 2003 to both check out and commit code. Your mileage may vary, of course. [[User:Matt Gibson|Matt Gibson]] 12:52, 18 August 2008 (CDT)&lt;br /&gt;
&lt;br /&gt;
=== CVS through your IDE ===&lt;br /&gt;
&lt;br /&gt;
Will naturally depend on the IDE you choose to use so we do not give specific instructions here. For some IDEs, there are instructions elsewhere here. (E.g. [[Development:Setting_up_Eclipse|for Eclipse]].)&lt;br /&gt;
&lt;br /&gt;
However, &#039;&#039;&#039;be warned&#039;&#039;&#039;, we have noticed that when adding a new file to CVS using some IDEs (for example Eclipse), then by default they forcibly set the [http://ximbiot.com/cvs/manual/cvs-1.11.23/cvs_12.html#SEC101 CVS substitution mode] to -kk for ASCII files. In Moodle we like all ASCII files to be stored with the CVS default of -kkv, so if you use an IDE like this, please adjust its default.&lt;br /&gt;
&lt;br /&gt;
If you are never likely to add a new file to CVS, you don&#039;t need to worry too much about the preceding paragraph. If you know something version control, you might think that -kk is better than -kkv, and in many ways you would be right. (For example it makes merging easier.) However, for the Moodle project, we use -kkv because it makes it easier to generate the [[Development:Unmerged_files|Unmerged files]] page, and because expanded $Id$ tags in the download packages makes it easier for people to make more specific bug reports.&lt;br /&gt;
&lt;br /&gt;
==CVS commit messages==&lt;br /&gt;
&lt;br /&gt;
Every commit you make to CVS should have a commit message. These can be invaluable. They are included in the automatic emails sent out whenever a change is made to Moodle, so they help other developers follow and review what is being changed; and they are very helpful when tyring to understand a piece of code. CVS will tell you who last changed each line of code, and when they did it. The commit comment (hopefully) tells you why.&lt;br /&gt;
&lt;br /&gt;
A commit message should contain, in order:&lt;br /&gt;
* A couple of words indicating which part of moodle this change affects. For example &#039;forum backup&#039;, &#039;quiz attempting&#039; or &#039;weblib&#039;.&lt;br /&gt;
* A tracker issue id like MDL-12345. (If necessary, create an issue before committing, the only exception is for very minor typos.)&lt;br /&gt;
* A brief description of the problem you are fixing. (If you are feeling lazy, you may be able to get away with copying and pasting the issue summary from the tracker.)&lt;br /&gt;
* If it is not immediately obvious, a brief summary of why this change fixes the problem. If a longer description is necessary,  you may also want to add more information to the tracker issue, or Moodle Docs, but the code changes + commit message should provide enough clues to how the fix works on their own.&lt;br /&gt;
&lt;br /&gt;
Here is an example of a commit message from a simple change:&lt;br /&gt;
&lt;br /&gt;
 user selection: MDL-17072 Polishing the role assign page: Do processing&lt;br /&gt;
 before print_header in line with best practice.&lt;br /&gt;
&lt;br /&gt;
Actually, the ideal commit message would be a bit shorter than that. It is good if the first three items (area of Moodle, tracker id and brief description) will fit in the subject line of an email message.&lt;br /&gt;
&lt;br /&gt;
Here is an example from a bigger commit (would it have been better if this could have been done as several smaller commits?):&lt;br /&gt;
 &lt;br /&gt;
 role overrides: MDL-17070 Improve override roles page to match the recent&lt;br /&gt;
 usability improvements on the assign page.&lt;br /&gt;
 &lt;br /&gt;
 Including:&lt;br /&gt;
 MDL-11529 When assigning/overriding roles, the dropdown for switching to&lt;br /&gt;
 another role should have a number in brackets&lt;br /&gt;
 &lt;br /&gt;
 MDL-16549 Should not be able to edit the permission associated with&lt;br /&gt;
 moodle/site:doanything on any role.&lt;br /&gt;
&lt;br /&gt;
Here is an example of a commit (from a while ago, which is why the issue number is in the wrong place) with some explanation of the change:&lt;br /&gt;
&lt;br /&gt;
 accesslib: get_user_by_capability() - Handle complex rolecap resolution&lt;br /&gt;
 &lt;br /&gt;
 With this patch, get_user_by_capability() can handle the cases where&lt;br /&gt;
 users have multiple role assignments to the same course, and PREVENTs&lt;br /&gt;
 and PROHIBITs affect the rolecaps of this course.&lt;br /&gt;
 &lt;br /&gt;
 Without stored procedures we cannot resolve this entirely on the&lt;br /&gt;
 server side - so in the complex cases we do as much as we can on SQL,&lt;br /&gt;
 and post-process the data on the PHP side, including SQL-style&lt;br /&gt;
 pagination.&lt;br /&gt;
 &lt;br /&gt;
 MDL-12452&lt;br /&gt;
&lt;br /&gt;
===The CVS commits email list===&lt;br /&gt;
&lt;br /&gt;
You can subscribe at http://lists.moodle.org/info/commits to this email list. You will then get an email every time someone commits a change to Moodle. This is a good way to keep track of what is going on, and also a good way to learn best-practice for CVS commit messages.&lt;br /&gt;
&lt;br /&gt;
You probably want to set your mail client to automatically move messages from this list into a separate mail folder. You may not want to remain subscribed all the time, but when you are new to the project, it is a great way to do a bit of social-constructionist peer learning about our use of CVS.&lt;br /&gt;
&lt;br /&gt;
==Working with branches==&lt;br /&gt;
&lt;br /&gt;
This diagram shows how the main moodle module branches into different versions over time.&lt;br /&gt;
&lt;br /&gt;
[[Image:Cvstree.png|CVS tree]]&lt;br /&gt;
&lt;br /&gt;
To see all the current tags and branches that are available, use this command on any old file (such as index.php in the top moodle directory):&lt;br /&gt;
    cvs status -v index.php&lt;br /&gt;
&lt;br /&gt;
Some tagging guidelines:&lt;br /&gt;
* Tag and branch names should always be all upper-case.&lt;br /&gt;
* Tags and branches should ALWAYS be applied to the entire module (all of Moodle). Don&#039;t tag individual files or directories.&lt;br /&gt;
* We don&#039;t allow renaming of tags because people may be relying on them, so get them right the first time!&lt;br /&gt;
&lt;br /&gt;
===Trunk development===&lt;br /&gt;
&lt;br /&gt;
The Trunk of CVS is the main development version of Moodle. In CVS it is also known as the HEAD, or default branch.&lt;br /&gt;
&lt;br /&gt;
Moodle developers try to keep this stable as possible, but as it usually contains new code it probably has bugs and small instabilities.&lt;br /&gt;
&lt;br /&gt;
Every now and then we decide the product has enough features to make a release. At this time, the trunk is tagged with a MOODLE_XX_BETA tag (in case we ever want to roll back to that point) and a new branch is formed for the release, called MOODLE_XX_STABLE.&lt;br /&gt;
&lt;br /&gt;
A Beta package is also released at this point - it&#039;s for testers who don&#039;t use CVS but want to test the latest features and report bugs.&lt;br /&gt;
&lt;br /&gt;
===Stable branches for each release===&lt;br /&gt;
&lt;br /&gt;
As soon as the stable branch MOODLE_XX_STABLE is created, development efforts will fork into two streams for a while. Some people may continue working on new features in the trunk for the next release, but most developers should be concentrating on using the current STABLE branch and fixing bugs that are found in it.&lt;br /&gt;
&lt;br /&gt;
You can switch your local copy of Moodle to the STABLE version using the following command in Unix from the root directory:&lt;br /&gt;
    cvs update -dP -r MOODLE_XX_STABLE&lt;br /&gt;
&lt;br /&gt;
After that, all the commands described above will apply to that stable version. To return to the trunk version just issue:&lt;br /&gt;
    cvs update -dPA&lt;br /&gt;
&lt;br /&gt;
On Windows clients you should have a menu from which you can choose the branch.&lt;br /&gt;
&lt;br /&gt;
Once the new STABLE branch really stabilises, a release can be declared. Packages are created for distribution and the branch will be tagged (by Martin Dougiamas) with a tag named: MOODLE_XXX&lt;br /&gt;
&lt;br /&gt;
===Merging fixes===&lt;br /&gt;
&lt;br /&gt;
All bug fixes in any STABLE branch should be merged back into the trunk so that they become available in future versions of Moodle. A floating tag called MOODLE_XX_MERGED needs to be maintained to keep track of the last merge. The procedure for such a merge is as follows (I&#039;m using CVS on the Unix command line but the steps are the same for any CVS client):&lt;br /&gt;
&lt;br /&gt;
[[Image:Merging.png|thumb|right|300px|This diagram summarises the process]]&lt;br /&gt;
1. I highly recommend keeping one checked out copy of each stable branch and the trunk/head version locally to make it easier to jump between them.  Set them all up as virtual web sites on your development machine.  I use directories like /moodle/18, /moodle/19 /moodle/dev etc.&lt;br /&gt;
&lt;br /&gt;
2. Update to the latest stable version (I&#039;ll use XX in the example but it could be 18, 19 etc) for the relevant files, and do a cvs diff just to double-check exactly what you are checking in.  Note you only need to update the files/directories you are working in, but sometimes it help to update everything anyway just to do a final check on the functionality using the web.&lt;br /&gt;
&lt;br /&gt;
          cd /moodle/XX/user&lt;br /&gt;
          cvs update -dPA&lt;br /&gt;
          cvs diff -c file1.php file2.php&lt;br /&gt;
&lt;br /&gt;
3. If all looks OK, check in the fix to the stable branch.  Make sure that the commit message contains the bug tracker ID (eg MDL-1111) and a decent description of your thoughts on the fix.  If you don&#039;t specify a message in the command line, you&#039;ll be put into an editor to type one.&lt;br /&gt;
&lt;br /&gt;
          cvs commit -m &amp;quot;MDL-1234 Corrected a small typo in the user name field&amp;quot; file1.php file2.php&lt;br /&gt;
&lt;br /&gt;
4. Go to the very latest trunk version and make sure it&#039;s up-to-date.&lt;br /&gt;
          &lt;br /&gt;
          cd /moodle/dev/user&lt;br /&gt;
          cvs update -dPA&lt;br /&gt;
&lt;br /&gt;
5. Merge everything into your local copy of the trunk from your stable branch since the last merge.  You can use the same sequence of (4) and (5) to merge the changes into other stable branches too (to backport the fix to the previous stable versions).&lt;br /&gt;
&lt;br /&gt;
          cvs update -kk -j MOODLE_XX_MERGED -j MOODLE_XX_STABLE file1.php file2.php&lt;br /&gt;
&lt;br /&gt;
6. Carefully watch the update logs for conflicts, and fix every file that you see with a conflict.  Afterwards, it may help to just run a diff to make sure the result is what you expected:&lt;br /&gt;
&lt;br /&gt;
          cvs diff -c file1.php file2.php&lt;br /&gt;
&lt;br /&gt;
7. Check your merged local copy back into CVS trunk version&lt;br /&gt;
&lt;br /&gt;
          cvs commit -m &amp;quot;MDL-1234 Corrected a small typo in the user name field, merged from XX&amp;quot; file1.php file2.php&lt;br /&gt;
&lt;br /&gt;
8. Go back to your branch version&lt;br /&gt;
&lt;br /&gt;
          cd /moodle/XX/user&lt;br /&gt;
&lt;br /&gt;
9. Update the floating merge tag for the affected files (so that it matches MOODLE_XX_STABLE) so that this process can be repeated next time&lt;br /&gt;
&lt;br /&gt;
          cvs tag -F MOODLE_XX_MERGED file1.php file2.php&lt;br /&gt;
&lt;br /&gt;
Finally, the values for $version in all the Moodle version.php files within the stable branch should not be updated at all if possible (except the last digit if absolutely necessary). The reason is that someone updating from a very stable version to the next very stable version could miss database upgrades that happened on the trunk.&lt;br /&gt;
&lt;br /&gt;
In other words, if you have changes to the database schema to commit to a stable branch, please check with Martin Dougiamas, or one of the other core Moodle developers.&lt;br /&gt;
&lt;br /&gt;
===Backporting===&lt;br /&gt;
Sometimes you fix something in a branch that needs to be &amp;quot;backported&amp;quot; to an earlier branch. This is often the case with security fixes. The procedure is exactly the same as described above, except you apply your changes backward instead of forward (to previous versions instead of HEAD). Here is a summary, using the steps described above. The scenario is that you have a fix in MOODLE_19_STABLE that needs backporting to MOODLE_18_STABLE, but NOT to HEAD (the problem you are fixing doesn&#039;t exist in HEAD):&lt;br /&gt;
&lt;br /&gt;
          cd /moodle/19/lib&lt;br /&gt;
          cvs update -dPA&lt;br /&gt;
          cvs diff -c file1.php file2.php&lt;br /&gt;
&lt;br /&gt;
          cvs commit -m &amp;quot;MDL-1234 Fixed major security hole&amp;quot; file1.php file2.php&lt;br /&gt;
&lt;br /&gt;
          cd /moodle/18/lib&lt;br /&gt;
          cvs update -dPA&lt;br /&gt;
&lt;br /&gt;
          cvs update -kk -j MOODLE_19_MERGED -j MOODLE_19_STABLE file1.php file2.php&lt;br /&gt;
          cvs diff -c file1.php file2.php&lt;br /&gt;
&lt;br /&gt;
          cvs commit -m &amp;quot;MDL-1234 Fixed major security hole, backported from 19&amp;quot; file1.php file2.php&lt;br /&gt;
&lt;br /&gt;
When it comes to tagging, things change a little bit. You&#039;ve now got changes in 18 and 19, both of which are stable releases, so need to be tagged as MERGED. You start with 18 (assuming you are still in that directory)&lt;br /&gt;
&lt;br /&gt;
          cvs tag -F MOODLE_18_MERGED file1.php file2.php&lt;br /&gt;
&lt;br /&gt;
Then, you go and do the same for 19, &#039;&#039;regardless of whether or not the changes were merged into HEAD&#039;&#039;. Of course, if the changes need to be merged into HEAD, you do that first. But if they don&#039;t, you still need to tag the modified files of each stable branch once your fixes are complete and tested:&lt;br /&gt;
          &lt;br /&gt;
          cd /moodle/18/lib&lt;br /&gt;
          cvs tag -F MOODLE_19_MERGED file1.php file2.php&lt;br /&gt;
&lt;br /&gt;
===Merging fixes with TortoiseCVS===&lt;br /&gt;
Situation: we did a fix on MOODLE_19_STABLE. We modified one file for this fix. This fix needs to be done on Moodle 1.8 and trunk(HEAD). All following CVS instructions will be applied on the file that we changed.&lt;br /&gt;
 &lt;br /&gt;
1. Update to the latest stable versions (HEAD included)&lt;br /&gt;
&lt;br /&gt;
          Right click on the moodle folder&lt;br /&gt;
          CVS update&lt;br /&gt;
          OK&lt;br /&gt;
&lt;br /&gt;
2. On your MOODLE19 branch: commit your fix &lt;br /&gt;
&lt;br /&gt;
          Right Click on the file&lt;br /&gt;
          CVS commit&lt;br /&gt;
          Enter a description: &amp;quot;MDL-XXXX bug fix description&amp;quot;&lt;br /&gt;
          OK&lt;br /&gt;
&lt;br /&gt;
3. On your HEAD repository: merge the changes&lt;br /&gt;
&lt;br /&gt;
          Right Click on the file&lt;br /&gt;
          CVS&amp;gt;&lt;br /&gt;
          Merge...&lt;br /&gt;
          Start: MOODLE_19_MERGED&lt;br /&gt;
          End  : MOODLE_19_STABLE&lt;br /&gt;
          OK&lt;br /&gt;
&lt;br /&gt;
4. If the resulting file have some conflicts, TortoiseCVS displays a red square on the file icon. Edit the file with your text editor and resolve the conflicts.&lt;br /&gt;
&lt;br /&gt;
5. Run a diff to make sure the result is what you expected&lt;br /&gt;
&lt;br /&gt;
          Right Click on the file&lt;br /&gt;
          CVS Diff&lt;br /&gt;
          OK&lt;br /&gt;
&lt;br /&gt;
6. Commit the fix&lt;br /&gt;
&lt;br /&gt;
          Right Click on the file&lt;br /&gt;
          CVS commit&lt;br /&gt;
          Enter a description: &amp;quot;MDL-XXXX bug fix description, merged from 19&amp;quot;&lt;br /&gt;
          OK&lt;br /&gt;
&lt;br /&gt;
We&#039;ve commit MOODLE_19_STABLE and trunk. It&#039;s now time to backport the change on MOODLE_18_STABLE.&lt;br /&gt;
On your MOODLE18 branch: reproduce step 3 to 6.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
7. On your MOODLE19 branch: update the floating merge tag for the affected file&lt;br /&gt;
&lt;br /&gt;
          Right Click on the file&lt;br /&gt;
          CVS&amp;gt;&lt;br /&gt;
          Tag...&lt;br /&gt;
          Tag: MOODLE_19_MERGED&lt;br /&gt;
          Select &#039;Move existing tag&#039;&lt;br /&gt;
          OK&lt;br /&gt;
&lt;br /&gt;
On your MOODLE18 branch: reproduce step 7 (with Tag: MOODLE_18_MERGED).&lt;br /&gt;
&lt;br /&gt;
===Feature branches for large changes===&lt;br /&gt;
&lt;br /&gt;
Occasionally, there may be a very large feature that needs to be checked in so several people can work on it, but it is too unstable to be included in the main development trunk.&lt;br /&gt;
&lt;br /&gt;
In these cases a short-term branch can be created to work on the feature, and then merged back into the main trunk as soon as possible. An example called MOODLE_19_WIDGET branch can be seen in the above diagram.&lt;br /&gt;
&lt;br /&gt;
If you need to do this for your new WIDGET feature, follow these steps:&lt;br /&gt;
&lt;br /&gt;
1. Discuss with other developers to make sure it&#039;s necessary!&lt;br /&gt;
&lt;br /&gt;
2. Make a new tag on the trunk (for all of moodle) called MOODLE_XX_WIDGET_PRE&lt;br /&gt;
&lt;br /&gt;
          cvs tag -R MOODLE_XX_WIDGET_PRE&lt;br /&gt;
&lt;br /&gt;
3. Create your branch called MOODLE_XX_WIDGET&lt;br /&gt;
&lt;br /&gt;
          cvs tag -Rb MOODLE_XX_WIDGET&lt;br /&gt;
&lt;br /&gt;
4. Work in that branch until the feature is reasonably stable. Commit as necessary.&lt;br /&gt;
&lt;br /&gt;
          cvs commit&lt;br /&gt;
&lt;br /&gt;
5. When ready, merge the whole branch into the trunk, fix conflicts, commit it to the trunk and then abandon the branch.&lt;br /&gt;
&lt;br /&gt;
          cvs update -dPA&lt;br /&gt;
          cvs update -kk -j MOODLE_XX_WIDGET&lt;br /&gt;
          cvs commit&lt;br /&gt;
&lt;br /&gt;
Good luck, be careful and have fun!&lt;br /&gt;
&lt;br /&gt;
==Who on earth is ...==&lt;br /&gt;
&lt;br /&gt;
Some of the people committing to the Moodle codebase have non-boring account names on the CVS server. If you are ever looking at a CVS commit, and wondering &amp;quot;who on earth is this purpleblob person?&amp;quot; This information is now available at: [http://moodle.org/mod/cvsadmin/view.php?cid=1 Moodle developers with write access].&lt;br /&gt;
&lt;br /&gt;
==Tips and Hints==&lt;br /&gt;
* [http://moodle.org/mod/cvsadmin/ Change your password or SSH key] (click on &amp;quot;Update my developer information&amp;quot;)&lt;br /&gt;
* [[Tracking Moodle CVS with git]]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=34472 Merging Custom Moodle Code With Stable Releases]&lt;br /&gt;
* [[Unmerged files]]: To see if you&#039;ve forgotten to merge any file.&lt;br /&gt;
* [http://ximbiot.com/cvs/manual/ CVS Manual]&lt;br /&gt;
* [[Development:contrib|Introduction to the &#039;&#039;&#039;contrib&#039;&#039;&#039; area of CVS]]&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [http://tracker.moodle.org/browse/MDLSITE-193 &amp;quot;All developers should switch to using the cvs.moodle.org alias&amp;quot;]&lt;br /&gt;
* [[CVS for Administrators]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer| CVS for developers]]&lt;br /&gt;
[[Category:Developer tools| CVS for developers]]&lt;br /&gt;
&lt;br /&gt;
[[es:CVS para desarrolladores]]&lt;br /&gt;
[[fr:CVS pour développeurs]]&lt;br /&gt;
[[pt:CVS_para_programadores]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Upgrading&amp;diff=80354</id>
		<title>Upgrading</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Upgrading&amp;diff=80354"/>
		<updated>2011-01-14T15:58:15Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* Linux */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Moodle is designed to upgrade itself from one version to the next. The procedure is&lt;br /&gt;
# [[Site backup|Back up everything]].&lt;br /&gt;
# Replace the old version of the code with the new one.&lt;br /&gt;
# Visit the [[Site_administration_block#Notifications|administrator notifications]] link, which triggers Moodle to self-update.&lt;br /&gt;
These steps are explained in more detail below.&lt;br /&gt;
&lt;br /&gt;
Sometimes there are specific considerations when upgrading to a particular version. Please refer to [[Upgrading to Moodle 1.6]], [[Upgrading to Moodle 1.8]], [[Upgrading to Moodle 1.9]] or [[Upgrading to Moodle 2.0]] if applicable. You also have to be more careful if you have installed additional plug-ins or customised the code.&lt;br /&gt;
&lt;br /&gt;
See this tutorial if you are [http://ic.eflclasses.org/tutorials/howtoupgrademoodlewithcpanel.swf upgrading Moodle on cpanel]. It is a bit rough around the edges and is a little dated, but you should get the idea.&lt;br /&gt;
&lt;br /&gt;
There is also a separate page about [[Ubuntu_Debian_Upgrades|upgrading Moodle if you installed it using the Ubuntu/Kubuntu/Debian package manager]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
When upgrading a Moodle installation you should follow these steps:&lt;br /&gt;
&lt;br /&gt;
==Before you upgrade your site for real==&lt;br /&gt;
&lt;br /&gt;
You are strongly advised to make a copy of your entire Moodle site onto another computer (see [[Moodle migration]]) and run the upgrade there to verify it will work.&lt;br /&gt;
&lt;br /&gt;
==Check the requirements==&lt;br /&gt;
Spend some time re-reading the [[Installing Moodle | installation documentation]] and documentation for the new version. Check the system requirements for the target version you want to upgrade-to in &#039;&#039;Administration &amp;gt; Server &amp;gt; [[Environment]]&#039;&#039;.&lt;br /&gt;
==Put your Site into Maintenance Mode==&lt;br /&gt;
Before you begin upgrading your site, you should put it into [[Maintenance_mode | Maintenance Mode]] to stop any non-admin users from logging in.&lt;br /&gt;
&lt;br /&gt;
== Backup important data ==&lt;br /&gt;
See [[Site backup]] for more specific information.&lt;br /&gt;
&lt;br /&gt;
There are three areas that should be backed up before any upgrade:&lt;br /&gt;
#Moodle software (For example, everything in server/htdocs/moodle)&lt;br /&gt;
#Moodle uploaded files (For example, server/moodledata)&lt;br /&gt;
#Moodle database (For example, the SQL or Progres database)&lt;br /&gt;
&lt;br /&gt;
Experienced site administrators know that it is a best practice (a very good idea) to make a backup of any production system before a major upgrade. In fact, it is a good idea to automate your server to backup your Moodle installation daily.  Most upgrades on sites that have used the standard Moodle packages (no contributed code and no little tweaks to the php files), will not have any major issues with the upgrade process.  &lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;TIP:&#039;&#039; One more time, &amp;quot;do not risk what you can not afford to lose&amp;quot;: do regular backups, make sure it is really backed up and know how to restore a backup!&lt;br /&gt;
&lt;br /&gt;
== Install the new Moodle software ==&lt;br /&gt;
Upgrading can be a simple process or a more complicated process.  Sites that have not used contributed code and are migrating from say Moodle 1.x.1 to 1.x.3 &#039;&#039;&#039;should&#039;&#039;&#039; not have a problem.  However, we still recommend that with any production server that you have made a successful backup of the MySQL database, the moodledata directory and the moodle program folders and files.  &lt;br /&gt;
&lt;br /&gt;
*Do not overwrite an old installation unless you know what you are doing ... sometimes old files can cause problems in new installations. Review the backup section above.&lt;br /&gt;
&lt;br /&gt;
=== Standard install package ===&lt;br /&gt;
Having read the cautions about backups, download a copy of the standard install package. Here is a set of simple instructions for an average site.&lt;br /&gt;
*It is probably a good idea to use the [[Site administration block]]&amp;gt;Server&amp;gt;Maintenance mode to prevent user activity as the site upgrades. &lt;br /&gt;
*Having moved your old Moodle software program files to another location, unzip or unpack the upgrade file so that all new the Moodle software program files are in the location the old files used to be in on the server.  Moodle will adjust SQL and [[Moodledata directory|moodledata]] if it needs to in the upgrade.&lt;br /&gt;
*Copy your old [[Configuration file|config.php file]] back to the new Moodle directory.&lt;br /&gt;
*If you had added any custom plugins or themes into your Moodle you can add them to the new code. It is important to check that you get the correct version for your new version of Moodle. You should check in the optional plugins database. Be particularly careful that you do not overwrite any code in the new version of Moodle. If you are upgrading to Moodle 2.0 or newer, note that all optional plugins and themes required a significant rewrite and most do not have 2.0 versions (yet). &lt;br /&gt;
*Use the notification link in the site administration to start the upgrade process. You will see a series of lines or screens indicating progress.  &lt;br /&gt;
*After a successful upgrade, turn off the maintenance mode, so your users can get into the site.&lt;br /&gt;
&lt;br /&gt;
=== Using a downloaded archive ===&lt;br /&gt;
In some installs, the site administrator may overwrite the Moodle code with a backup copy.  Or create a new clean install copy of Moodle, then restore an archive (via a compressed file or parts of a saved set of Moodle code files and folders). &lt;br /&gt;
&lt;br /&gt;
*Do not overwrite an old installation unless you know what you are doing ... sometimes old files can cause problems in new or &amp;quot;cleaned&amp;quot; installations. The best way is to rename the current Moodle code directory (for example rename &amp;quot;moodle&amp;quot; to &amp;quot;moodleold&amp;quot;), then unpack the new Moodle archive into the old location (for example, a new directory called &amp;quot;moodle&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
====Linux====&lt;br /&gt;
 mv moodle moodle.backup&lt;br /&gt;
 tar xvzf moodle-1.1.tgz&lt;br /&gt;
&lt;br /&gt;
Next, copy across your config.php, any other plugins such as custom themes, and your .htaccess file if you created one (&#039;&#039;&#039;check that optional/custom plugins are the correct version for your new Moodle first&#039;&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
 cp moodle.backup/config.php moodle&lt;br /&gt;
 cp -pr moodle.backup/theme/mytheme moodle/theme/mytheme&lt;br /&gt;
 cp -pr moodle.backup/mod/mymod moodle/mod/mymod&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to &lt;br /&gt;
&lt;br /&gt;
 sudo chown www-data moodle/config.php&lt;br /&gt;
&lt;br /&gt;
if necessary.&lt;br /&gt;
&lt;br /&gt;
where www-data is whatever user the Apache user is on your system. This is often &#039;apache&#039; or &#039;www&#039;.&lt;br /&gt;
You can find out by doing &#039;ls -l&#039; in your /var/www/moodle folder (or wherever your moodle site is)&lt;br /&gt;
and then looking at the owner and group.&lt;br /&gt;
&lt;br /&gt;
so you may see something like&lt;br /&gt;
&lt;br /&gt;
 ls -l&lt;br /&gt;
 ...lots of lines...&lt;br /&gt;
 -rw-r--r--   1 apache system     784 Jun 28  2007 config.php &lt;br /&gt;
 ...lots more lines...&lt;br /&gt;
&lt;br /&gt;
so the owner is apache and the group is system. &lt;br /&gt;
&lt;br /&gt;
To replicate this on your new system you can do  &#039;chown apache:system config.php&#039; &lt;br /&gt;
&lt;br /&gt;
or to do a whole group do&lt;br /&gt;
&lt;br /&gt;
 chown apache:system ./*&lt;br /&gt;
&lt;br /&gt;
and recursively&lt;br /&gt;
&lt;br /&gt;
 chown -R apache:system ./*&lt;br /&gt;
&lt;br /&gt;
=== Using CVS ===&lt;br /&gt;
&lt;br /&gt;
You can use CVS for updating or upgrading your Moodle.&lt;br /&gt;
First you need to do a CVS checkout in your (empty) Moodle root directory.&lt;br /&gt;
&lt;br /&gt;
You can use any of our [[CVS_for_Administrators#CVS_Servers|CVS Mirror servers]]. Just replace &#039;&#039;&#039;SERVER.cvs.moodle.org&#039;&#039;&#039; in the instructions below with the name of the mirror server you chose!.&lt;br /&gt;
&lt;br /&gt;
====For Linux servers====&lt;br /&gt;
&lt;br /&gt;
To do a CVS checkout of Moodle, you first have to logon to the Moodle CVS server.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;cvs -d:pserver:anonymous@SERVER.cvs.moodle.org:/cvsroot/moodle login&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  No password for anonymous, so just hit the Enter button.&lt;br /&gt;
&lt;br /&gt;
Go to the directory where you want the Moodle root to come and type&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;cvs -z3 -d:pserver:anonymous@SERVER.cvs.moodle.org:/cvsroot/moodle co -r MOODLE_18_STABLE moodle&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  (where MOODLE_18_STABLE is the desired version)&lt;br /&gt;
&lt;br /&gt;
To update, just go into the Moodle root directory and update to the new files:&lt;br /&gt;
&lt;br /&gt;
  cvs update -dP&lt;br /&gt;
To update to a new version type in the following and change 18 to whatever newest version upgrade number is&lt;br /&gt;
  cvs -Q update -dP -r MOODLE_18_STABLE&lt;br /&gt;
&lt;br /&gt;
Make sure you use the &amp;quot;d&amp;quot; parameter to create new directories if necessary, and the &amp;quot;P&amp;quot; parameter to prune empty directories.&lt;br /&gt;
&lt;br /&gt;
====For Windows servers====&lt;br /&gt;
&lt;br /&gt;
You can use Tortoise CVS to do the initial checkout and the updates.&lt;br /&gt;
&lt;br /&gt;
If you have been editing Moodle files, watch the messages very closely for possible conflicts. All your customised themes and non-standard plugins will be untouched.&lt;br /&gt;
&lt;br /&gt;
Do not forget to trigger the install process in the site administration block (see below).&lt;br /&gt;
&lt;br /&gt;
== Finishing the upgrade ==&lt;br /&gt;
&lt;br /&gt;
The last step is to trigger the upgrade processes within Moodle. &lt;br /&gt;
&lt;br /&gt;
To do this just visit the [[Site administration block]] admin page (or &#039;&#039;&amp;lt;nowiki&amp;gt;http://example.com/moodle/admin&amp;lt;/nowiki&amp;gt;&#039;&#039;) and the &amp;quot;Notifications&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
Moodle will automatically detect the new version and perform all the SQL database or file system upgrades that are necessary. If there is anything it can&#039;t do itself (very rare) then you will see messages telling you what you need to do.&lt;br /&gt;
&lt;br /&gt;
Assuming all goes well (no error messages) then you can start using your new version of Moodle and enjoy the new features!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;TIP:&#039;&#039; Use the site administration block&amp;gt;Server&amp;gt;Maintenance mode to prevent users from changing data during the upgrade.&lt;br /&gt;
:&#039;&#039;TIP:&#039;&#039; If you are running a large scale Moodle site (e.g. have more tha 10,000+ courses and 40,000+ users), make sure that you do your own performance profiling testing.  Post a thread or check the [http://moodle.org/mod/forum/view.php?id=28 Installation problems forum] and check [[Tracker]] for potential issues.&lt;br /&gt;
&lt;br /&gt;
== Verify the upgrade (optional) ==&lt;br /&gt;
&lt;br /&gt;
If you wish to confirm that the database definitions in the upgraded database match the definitions of a new, clean install (which they should) you might like to look at [[Verify Database Schema]].&lt;br /&gt;
&lt;br /&gt;
==Upgrading more than one version==&lt;br /&gt;
&lt;br /&gt;
In general, it is recommended to upgrade via the newest of each major version of Moodle, for example 1.7 -&amp;gt; 1.9. An exception to this is when upgrading from 1.5 or 1.6, when it is recommended that 1.7 and 1.8 are skipped, in other words upgrade 1.5 -&amp;gt; 1.6 -&amp;gt; 1.9. (The main reason for this recommendation is that the default roles settings obtained when upgrading to 1.7 are not ideal for 1.8 onwards, 1.8 has problems with groups, etc.)&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
*[[Installing Moodle]]&lt;br /&gt;
*[[Installation FAQ]]&lt;br /&gt;
*[[Upgrading to Moodle 1.6]]&lt;br /&gt;
*[[Upgrading to Moodle 1.8]]&lt;br /&gt;
*[[Upgrading to Moodle 1.9]]&lt;br /&gt;
*[[Upgrading to Moodle 2.0]]&lt;br /&gt;
*[[Environment]]&lt;br /&gt;
*[[Git]] Version control and upgrading&lt;br /&gt;
*Moodle.org [http://moodle.org/mod/forum/view.php?id=28 Installation problems forum] &lt;br /&gt;
*[http://ic.eflclasses.org/tutorials/howtoupgrademoodlewithcpanel.swf How to upgrade Moodle with cpanel tutorial] - screencasts of older Moodle/Cpanel install but useful (also, a very large file that will take some time to load).&lt;br /&gt;
&lt;br /&gt;
Using Moodle.org forum discussions:&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=26731&amp;amp;parent=125858 Using cvs]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=56915 Upgrading from 1.5.2 to 1.7]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=56991 Upgrade nightmares.... any help appreciated]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=62463 After upgrading i get &amp;quot;Your site may not be secure.&amp;quot; msg]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=104887 Best practices for QA]&lt;br /&gt;
&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[es:Actualización de moodle]]&lt;br /&gt;
[[fr:Mise à jour]]&lt;br /&gt;
[[ja:アップグレード]]&lt;br /&gt;
[[nl:Upgraden]]&lt;br /&gt;
[[zh:升级]]&lt;br /&gt;
[[pl:Aktualizacja]]&lt;br /&gt;
[[de:Aktualisierung von Moodle]]&lt;br /&gt;
[[ru:Обновление]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Upgrading&amp;diff=80353</id>
		<title>Upgrading</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Upgrading&amp;diff=80353"/>
		<updated>2011-01-14T15:55:20Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* Standard install package */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Moodle is designed to upgrade itself from one version to the next. The procedure is&lt;br /&gt;
# [[Site backup|Back up everything]].&lt;br /&gt;
# Replace the old version of the code with the new one.&lt;br /&gt;
# Visit the [[Site_administration_block#Notifications|administrator notifications]] link, which triggers Moodle to self-update.&lt;br /&gt;
These steps are explained in more detail below.&lt;br /&gt;
&lt;br /&gt;
Sometimes there are specific considerations when upgrading to a particular version. Please refer to [[Upgrading to Moodle 1.6]], [[Upgrading to Moodle 1.8]], [[Upgrading to Moodle 1.9]] or [[Upgrading to Moodle 2.0]] if applicable. You also have to be more careful if you have installed additional plug-ins or customised the code.&lt;br /&gt;
&lt;br /&gt;
See this tutorial if you are [http://ic.eflclasses.org/tutorials/howtoupgrademoodlewithcpanel.swf upgrading Moodle on cpanel]. It is a bit rough around the edges and is a little dated, but you should get the idea.&lt;br /&gt;
&lt;br /&gt;
There is also a separate page about [[Ubuntu_Debian_Upgrades|upgrading Moodle if you installed it using the Ubuntu/Kubuntu/Debian package manager]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
When upgrading a Moodle installation you should follow these steps:&lt;br /&gt;
&lt;br /&gt;
==Before you upgrade your site for real==&lt;br /&gt;
&lt;br /&gt;
You are strongly advised to make a copy of your entire Moodle site onto another computer (see [[Moodle migration]]) and run the upgrade there to verify it will work.&lt;br /&gt;
&lt;br /&gt;
==Check the requirements==&lt;br /&gt;
Spend some time re-reading the [[Installing Moodle | installation documentation]] and documentation for the new version. Check the system requirements for the target version you want to upgrade-to in &#039;&#039;Administration &amp;gt; Server &amp;gt; [[Environment]]&#039;&#039;.&lt;br /&gt;
==Put your Site into Maintenance Mode==&lt;br /&gt;
Before you begin upgrading your site, you should put it into [[Maintenance_mode | Maintenance Mode]] to stop any non-admin users from logging in.&lt;br /&gt;
&lt;br /&gt;
== Backup important data ==&lt;br /&gt;
See [[Site backup]] for more specific information.&lt;br /&gt;
&lt;br /&gt;
There are three areas that should be backed up before any upgrade:&lt;br /&gt;
#Moodle software (For example, everything in server/htdocs/moodle)&lt;br /&gt;
#Moodle uploaded files (For example, server/moodledata)&lt;br /&gt;
#Moodle database (For example, the SQL or Progres database)&lt;br /&gt;
&lt;br /&gt;
Experienced site administrators know that it is a best practice (a very good idea) to make a backup of any production system before a major upgrade. In fact, it is a good idea to automate your server to backup your Moodle installation daily.  Most upgrades on sites that have used the standard Moodle packages (no contributed code and no little tweaks to the php files), will not have any major issues with the upgrade process.  &lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;TIP:&#039;&#039; One more time, &amp;quot;do not risk what you can not afford to lose&amp;quot;: do regular backups, make sure it is really backed up and know how to restore a backup!&lt;br /&gt;
&lt;br /&gt;
== Install the new Moodle software ==&lt;br /&gt;
Upgrading can be a simple process or a more complicated process.  Sites that have not used contributed code and are migrating from say Moodle 1.x.1 to 1.x.3 &#039;&#039;&#039;should&#039;&#039;&#039; not have a problem.  However, we still recommend that with any production server that you have made a successful backup of the MySQL database, the moodledata directory and the moodle program folders and files.  &lt;br /&gt;
&lt;br /&gt;
*Do not overwrite an old installation unless you know what you are doing ... sometimes old files can cause problems in new installations. Review the backup section above.&lt;br /&gt;
&lt;br /&gt;
=== Standard install package ===&lt;br /&gt;
Having read the cautions about backups, download a copy of the standard install package. Here is a set of simple instructions for an average site.&lt;br /&gt;
*It is probably a good idea to use the [[Site administration block]]&amp;gt;Server&amp;gt;Maintenance mode to prevent user activity as the site upgrades. &lt;br /&gt;
*Having moved your old Moodle software program files to another location, unzip or unpack the upgrade file so that all new the Moodle software program files are in the location the old files used to be in on the server.  Moodle will adjust SQL and [[Moodledata directory|moodledata]] if it needs to in the upgrade.&lt;br /&gt;
*Copy your old [[Configuration file|config.php file]] back to the new Moodle directory.&lt;br /&gt;
*If you had added any custom plugins or themes into your Moodle you can add them to the new code. It is important to check that you get the correct version for your new version of Moodle. You should check in the optional plugins database. Be particularly careful that you do not overwrite any code in the new version of Moodle. If you are upgrading to Moodle 2.0 or newer, note that all optional plugins and themes required a significant rewrite and most do not have 2.0 versions (yet). &lt;br /&gt;
*Use the notification link in the site administration to start the upgrade process. You will see a series of lines or screens indicating progress.  &lt;br /&gt;
*After a successful upgrade, turn off the maintenance mode, so your users can get into the site.&lt;br /&gt;
&lt;br /&gt;
=== Using a downloaded archive ===&lt;br /&gt;
In some installs, the site administrator may overwrite the Moodle code with a backup copy.  Or create a new clean install copy of Moodle, then restore an archive (via a compressed file or parts of a saved set of Moodle code files and folders). &lt;br /&gt;
&lt;br /&gt;
*Do not overwrite an old installation unless you know what you are doing ... sometimes old files can cause problems in new or &amp;quot;cleaned&amp;quot; installations. The best way is to rename the current Moodle code directory (for example rename &amp;quot;moodle&amp;quot; to &amp;quot;moodleold&amp;quot;), then unpack the new Moodle archive into the old location (for example, a new directory called &amp;quot;moodle&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
====Linux====&lt;br /&gt;
 mv moodle moodle.backup&lt;br /&gt;
 tar xvzf moodle-1.1.tgz&lt;br /&gt;
&lt;br /&gt;
Next, copy across your config.php, any other plugins such as custom themes, and your .htaccess file if you created one:&lt;br /&gt;
&lt;br /&gt;
 cp moodle.backup/config.php moodle&lt;br /&gt;
 cp -pr moodle.backup/theme/mytheme moodle/theme/mytheme&lt;br /&gt;
 cp -pr moodle.backup/mod/mymod moodle/mod/mymod&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to &lt;br /&gt;
&lt;br /&gt;
 sudo chown www-data moodle/config.php&lt;br /&gt;
&lt;br /&gt;
if necessary.&lt;br /&gt;
&lt;br /&gt;
where www-data is whatever user the Apache user is on your system. This is often &#039;apache&#039; or &#039;www&#039;.&lt;br /&gt;
You can find out by doing &#039;ls -l&#039; in your /var/www/moodle folder (or wherever your moodle site is)&lt;br /&gt;
and then looking at the owner and group.&lt;br /&gt;
&lt;br /&gt;
so you may see something like&lt;br /&gt;
&lt;br /&gt;
 ls -l&lt;br /&gt;
 ...lots of lines...&lt;br /&gt;
 -rw-r--r--   1 apache system     784 Jun 28  2007 config.php &lt;br /&gt;
 ...lots more lines...&lt;br /&gt;
&lt;br /&gt;
so the owner is apache and the group is system. &lt;br /&gt;
&lt;br /&gt;
To replicate this on your new system you can do  &#039;chown apache:system config.php&#039; &lt;br /&gt;
&lt;br /&gt;
or to do a whole group do&lt;br /&gt;
&lt;br /&gt;
 chown apache:system ./*&lt;br /&gt;
&lt;br /&gt;
and recursively&lt;br /&gt;
&lt;br /&gt;
 chown -R apache:system ./*&lt;br /&gt;
&lt;br /&gt;
=== Using CVS ===&lt;br /&gt;
&lt;br /&gt;
You can use CVS for updating or upgrading your Moodle.&lt;br /&gt;
First you need to do a CVS checkout in your (empty) Moodle root directory.&lt;br /&gt;
&lt;br /&gt;
You can use any of our [[CVS_for_Administrators#CVS_Servers|CVS Mirror servers]]. Just replace &#039;&#039;&#039;SERVER.cvs.moodle.org&#039;&#039;&#039; in the instructions below with the name of the mirror server you chose!.&lt;br /&gt;
&lt;br /&gt;
====For Linux servers====&lt;br /&gt;
&lt;br /&gt;
To do a CVS checkout of Moodle, you first have to logon to the Moodle CVS server.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;cvs -d:pserver:anonymous@SERVER.cvs.moodle.org:/cvsroot/moodle login&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  No password for anonymous, so just hit the Enter button.&lt;br /&gt;
&lt;br /&gt;
Go to the directory where you want the Moodle root to come and type&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;cvs -z3 -d:pserver:anonymous@SERVER.cvs.moodle.org:/cvsroot/moodle co -r MOODLE_18_STABLE moodle&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  (where MOODLE_18_STABLE is the desired version)&lt;br /&gt;
&lt;br /&gt;
To update, just go into the Moodle root directory and update to the new files:&lt;br /&gt;
&lt;br /&gt;
  cvs update -dP&lt;br /&gt;
To update to a new version type in the following and change 18 to whatever newest version upgrade number is&lt;br /&gt;
  cvs -Q update -dP -r MOODLE_18_STABLE&lt;br /&gt;
&lt;br /&gt;
Make sure you use the &amp;quot;d&amp;quot; parameter to create new directories if necessary, and the &amp;quot;P&amp;quot; parameter to prune empty directories.&lt;br /&gt;
&lt;br /&gt;
====For Windows servers====&lt;br /&gt;
&lt;br /&gt;
You can use Tortoise CVS to do the initial checkout and the updates.&lt;br /&gt;
&lt;br /&gt;
If you have been editing Moodle files, watch the messages very closely for possible conflicts. All your customised themes and non-standard plugins will be untouched.&lt;br /&gt;
&lt;br /&gt;
Do not forget to trigger the install process in the site administration block (see below).&lt;br /&gt;
&lt;br /&gt;
== Finishing the upgrade ==&lt;br /&gt;
&lt;br /&gt;
The last step is to trigger the upgrade processes within Moodle. &lt;br /&gt;
&lt;br /&gt;
To do this just visit the [[Site administration block]] admin page (or &#039;&#039;&amp;lt;nowiki&amp;gt;http://example.com/moodle/admin&amp;lt;/nowiki&amp;gt;&#039;&#039;) and the &amp;quot;Notifications&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
Moodle will automatically detect the new version and perform all the SQL database or file system upgrades that are necessary. If there is anything it can&#039;t do itself (very rare) then you will see messages telling you what you need to do.&lt;br /&gt;
&lt;br /&gt;
Assuming all goes well (no error messages) then you can start using your new version of Moodle and enjoy the new features!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;TIP:&#039;&#039; Use the site administration block&amp;gt;Server&amp;gt;Maintenance mode to prevent users from changing data during the upgrade.&lt;br /&gt;
:&#039;&#039;TIP:&#039;&#039; If you are running a large scale Moodle site (e.g. have more tha 10,000+ courses and 40,000+ users), make sure that you do your own performance profiling testing.  Post a thread or check the [http://moodle.org/mod/forum/view.php?id=28 Installation problems forum] and check [[Tracker]] for potential issues.&lt;br /&gt;
&lt;br /&gt;
== Verify the upgrade (optional) ==&lt;br /&gt;
&lt;br /&gt;
If you wish to confirm that the database definitions in the upgraded database match the definitions of a new, clean install (which they should) you might like to look at [[Verify Database Schema]].&lt;br /&gt;
&lt;br /&gt;
==Upgrading more than one version==&lt;br /&gt;
&lt;br /&gt;
In general, it is recommended to upgrade via the newest of each major version of Moodle, for example 1.7 -&amp;gt; 1.9. An exception to this is when upgrading from 1.5 or 1.6, when it is recommended that 1.7 and 1.8 are skipped, in other words upgrade 1.5 -&amp;gt; 1.6 -&amp;gt; 1.9. (The main reason for this recommendation is that the default roles settings obtained when upgrading to 1.7 are not ideal for 1.8 onwards, 1.8 has problems with groups, etc.)&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
*[[Installing Moodle]]&lt;br /&gt;
*[[Installation FAQ]]&lt;br /&gt;
*[[Upgrading to Moodle 1.6]]&lt;br /&gt;
*[[Upgrading to Moodle 1.8]]&lt;br /&gt;
*[[Upgrading to Moodle 1.9]]&lt;br /&gt;
*[[Upgrading to Moodle 2.0]]&lt;br /&gt;
*[[Environment]]&lt;br /&gt;
*[[Git]] Version control and upgrading&lt;br /&gt;
*Moodle.org [http://moodle.org/mod/forum/view.php?id=28 Installation problems forum] &lt;br /&gt;
*[http://ic.eflclasses.org/tutorials/howtoupgrademoodlewithcpanel.swf How to upgrade Moodle with cpanel tutorial] - screencasts of older Moodle/Cpanel install but useful (also, a very large file that will take some time to load).&lt;br /&gt;
&lt;br /&gt;
Using Moodle.org forum discussions:&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=26731&amp;amp;parent=125858 Using cvs]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=56915 Upgrading from 1.5.2 to 1.7]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=56991 Upgrade nightmares.... any help appreciated]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=62463 After upgrading i get &amp;quot;Your site may not be secure.&amp;quot; msg]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=104887 Best practices for QA]&lt;br /&gt;
&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[es:Actualización de moodle]]&lt;br /&gt;
[[fr:Mise à jour]]&lt;br /&gt;
[[ja:アップグレード]]&lt;br /&gt;
[[nl:Upgraden]]&lt;br /&gt;
[[zh:升级]]&lt;br /&gt;
[[pl:Aktualizacja]]&lt;br /&gt;
[[de:Aktualisierung von Moodle]]&lt;br /&gt;
[[ru:Обновление]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Verify_Database_Schema&amp;diff=80352</id>
		<title>Verify Database Schema</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Verify_Database_Schema&amp;diff=80352"/>
		<updated>2011-01-14T14:19:10Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you have been upgrading your Moodle site over several versions, it is possible (likely even) that some differences may have crept in between the database table definitions (the &amp;quot;schema&amp;quot;) in your database and the version you would get creating a new empty site. This happens because of small errors or oversights in the upgrade scripts. Most of these differences are not harmful, but some may cause strange or unexpected errors. For example, if a default value has been added to a field and this was not reflected in an upgrade script code that assumes the presence of the default may fail to work as expected. &lt;br /&gt;
&lt;br /&gt;
The solution is after doing an upgrade (or, if your problem is that the upgrade fails, before) to compare the database schema of the &amp;quot;production&amp;quot; site to that of a newly created site (where no upgrades have been performed) using &#039;&#039;&#039;exactly&#039;&#039;&#039; the same code base. There are a number of ways of doing this, but this article outlines a simple way using the Unix command line.&lt;br /&gt;
&lt;br /&gt;
* Complete the upgrade&lt;br /&gt;
* Generate the database schema from your recently upgraded site using the following command:&lt;br /&gt;
    mysqldump -d -u root -p &#039;&#039;myproductiondb&#039;&#039; &amp;gt;production.schema&lt;br /&gt;
* Copy the code  of your production database to a new (web accessible) location (this is important, it *must* be the same version)&lt;br /&gt;
* Create a new, empty database and moodledata area for the new site as per the [[Installation]] instructions&lt;br /&gt;
* Edit the config.php file to point at the new database and locations, or delete it and use the install script&lt;br /&gt;
* Run the install script to generate the (if applicable) config.php file and the database (admin and site values are not important)&lt;br /&gt;
* Generate the database schema from your new site using the following command:&lt;br /&gt;
    mysqldump -d -u root -p &#039;&#039;mycleandb&#039;&#039; &amp;gt;clean.schema&lt;br /&gt;
* Run the following command to detect the differences&lt;br /&gt;
    diff -u production.schema clean.schema &amp;gt;db.diff&lt;br /&gt;
&lt;br /&gt;
You can now look at &#039;&#039;db.diff&#039;&#039; with your favorite editor to see the differences.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039; The above obviously applies to MySQL databases. Other databases are likely to have a similar function to dump only the schema. For example PostgreSQL has the &#039;&#039;&#039;pg_dump&#039;&#039;&#039; command. The remainder of the discussion still applies. &lt;br /&gt;
&lt;br /&gt;
==Interpreting the diff file==&lt;br /&gt;
&lt;br /&gt;
Firstly here&#039;s a (real) example:&lt;br /&gt;
&lt;br /&gt;
     --&lt;br /&gt;
     -- Table structure for table `mdl_backup_config`&lt;br /&gt;
        @@ -129,11 +93,11 @@&lt;br /&gt;
         DROP TABLE IF EXISTS `mdl_backup_config`;&lt;br /&gt;
         CREATE TABLE `mdl_backup_config` (&lt;br /&gt;
    -  `id` int(10) unsigned NOT NULL auto_increment,&lt;br /&gt;
    +  `id` bigint(10) unsigned NOT NULL auto_increment,&lt;br /&gt;
       `name` varchar(255) NOT NULL default &#039;&#039;,&lt;br /&gt;
       `value` varchar(255) NOT NULL default &#039;&#039;,&lt;br /&gt;
        PRIMARY KEY  (`id`),&lt;br /&gt;
    -  UNIQUE KEY `name` (`name`)&lt;br /&gt;
    +  UNIQUE KEY `mdl_backconf_nam_uix` (`name`)&lt;br /&gt;
         ) ENGINE=MyISAM AUTO_INCREMENT=15 DEFAULT CHARSET=utf8 COMMENT=&#039;To store backup configuration variables&#039;;&lt;br /&gt;
&lt;br /&gt;
The file may have lots of blocks of changes. The - lines show lines to be taken out and the + lines the ones to replace them (from the production to the clean). So here, the int has been replaced with a bigint and the key name changed. Both of these, technically, should have been changed at some point by upgrade scripts but have been missed. In this case they are unlikely to affect the operation of Moodle. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Should I worry?==&lt;br /&gt;
&lt;br /&gt;
Changes in field types (as long as they are compatible) and key name changes seem to be the common issues but &#039;&#039;&#039;should&#039;&#039;&#039; not cause problems. Things to look out for would be along the lines of missing fields and changes to default values.&lt;br /&gt;
&lt;br /&gt;
If you are about to upgrade to Moodle 2.0 you should be more concerned. In order for the upgrade to proceed smoothly it is a very good idea to correct these problems.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* The missing indexes report in SiteAdmin-&amp;gt;Misc-&amp;gt;XMLDB editor-&amp;gt;Check Indexes&lt;br /&gt;
* [http://moodle.org/mod/forum/view.php?id=45 Moodle Databases Forum]&lt;br /&gt;
&lt;br /&gt;
[[Category:Administrator]]&lt;br /&gt;
&lt;br /&gt;
[[de:Datenbank-Schema prüfen]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Verify_Database_Schema&amp;diff=80351</id>
		<title>Verify Database Schema</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Verify_Database_Schema&amp;diff=80351"/>
		<updated>2011-01-14T14:18:28Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you have been upgrading your Moodle site over several versions, it is possible (likely even) that some differences may have crept in between the database table definitions (the &amp;quot;schema&amp;quot;) in your database and the version you would get creating a new empty site. This happens because of small errors or oversights in the upgrade scripts. Most of these differences are not harmful, but some may cause strange or unexpected errors. For example, if a default value has been added to a field and this was not reflected in an upgrade script code that assumes the presence of the default may fail to work as expected. &lt;br /&gt;
&lt;br /&gt;
The solution is after doing an upgrade (or, if your problem is that the upgrade fails, before) to compare the database schema of the &amp;quot;production&amp;quot; site to that of a newly created site (where no upgrades have been performed) using &#039;&#039;&#039;exactly&#039;&#039;&#039; the same code base. There are a number of ways of doing this, but this article outlines a simple way using the Unix command line.&lt;br /&gt;
&lt;br /&gt;
* Complete the upgrade&lt;br /&gt;
* Generate the database schema from your recently upgraded site using the following command:&lt;br /&gt;
    mysqldump -d -u root -p &#039;&#039;myproductiondb&#039;&#039; &amp;gt;production.schema&lt;br /&gt;
* Copy the code  of your production database to a new (web accessible) location (this is important, it *must* be the same version)&lt;br /&gt;
* Create a new, empty database and moodledata area for the new site as per the [[Installation]] instructions&lt;br /&gt;
* Edit the config.php file to point at the new database and locations, or delete it and use the install script&lt;br /&gt;
* Run the install script to generate the (if applicable) config.php file and the database (admin and site values are not important)&lt;br /&gt;
* Generate the database schema from your new site using the following command:&lt;br /&gt;
    mysqldump -d -u root -p &#039;&#039;mycleandb&#039;&#039; &amp;gt;clean.schema&lt;br /&gt;
* Run the following command to detect the differences&lt;br /&gt;
    diff -u production.schema clean.schema &amp;gt;db.diff&lt;br /&gt;
&lt;br /&gt;
You can now look at &#039;&#039;db.diff&#039;&#039; with your favorite editor to see the differences.&lt;br /&gt;
&lt;br /&gt;
==Interpreting the diff file==&lt;br /&gt;
&lt;br /&gt;
Firstly here&#039;s a (real) example:&lt;br /&gt;
&lt;br /&gt;
     --&lt;br /&gt;
     -- Table structure for table `mdl_backup_config`&lt;br /&gt;
        @@ -129,11 +93,11 @@&lt;br /&gt;
         DROP TABLE IF EXISTS `mdl_backup_config`;&lt;br /&gt;
         CREATE TABLE `mdl_backup_config` (&lt;br /&gt;
    -  `id` int(10) unsigned NOT NULL auto_increment,&lt;br /&gt;
    +  `id` bigint(10) unsigned NOT NULL auto_increment,&lt;br /&gt;
       `name` varchar(255) NOT NULL default &#039;&#039;,&lt;br /&gt;
       `value` varchar(255) NOT NULL default &#039;&#039;,&lt;br /&gt;
        PRIMARY KEY  (`id`),&lt;br /&gt;
    -  UNIQUE KEY `name` (`name`)&lt;br /&gt;
    +  UNIQUE KEY `mdl_backconf_nam_uix` (`name`)&lt;br /&gt;
         ) ENGINE=MyISAM AUTO_INCREMENT=15 DEFAULT CHARSET=utf8 COMMENT=&#039;To store backup configuration variables&#039;;&lt;br /&gt;
&lt;br /&gt;
The file may have lots of blocks of changes. The - lines show lines to be taken out and the + lines the ones to replace them (from the production to the clean). So here, the int has been replaced with a bigint and the key name changed. Both of these, technically, should have been changed at some point by upgrade scripts but have been missed. In this case they are unlikely to affect the operation of Moodle. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039; The above obviously applies to MySQL databases. Other databases are likely to have a similar function to dump only the schema. For example PostgreSQL has the &#039;&#039;&#039;pg_dump&#039;&#039;&#039; command. The remainder of the discussion still applies. &lt;br /&gt;
&lt;br /&gt;
==Should I worry?==&lt;br /&gt;
&lt;br /&gt;
Changes in field types (as long as they are compatible) and key name changes seem to be the common issues but &#039;&#039;&#039;should&#039;&#039;&#039; not cause problems. Things to look out for would be along the lines of missing fields and changes to default values.&lt;br /&gt;
&lt;br /&gt;
If you are about to upgrade to Moodle 2.0 you should be more concerned. In order for the upgrade to proceed smoothly it is a very good idea to correct these problems.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* The missing indexes report in SiteAdmin-&amp;gt;Misc-&amp;gt;XMLDB editor-&amp;gt;Check Indexes&lt;br /&gt;
* [http://moodle.org/mod/forum/view.php?id=45 Moodle Databases Forum]&lt;br /&gt;
&lt;br /&gt;
[[Category:Administrator]]&lt;br /&gt;
&lt;br /&gt;
[[de:Datenbank-Schema prüfen]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Talk:Verify_Database_Schema&amp;diff=80350</id>
		<title>Talk:Verify Database Schema</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Talk:Verify_Database_Schema&amp;diff=80350"/>
		<updated>2011-01-14T14:14:57Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page seems to apply to MySQL databases only. What about other platforms such as Postgres and MSSQL?&lt;br /&gt;
Is it necessary to verify the database schemas on other database platforms?&lt;br /&gt;
&lt;br /&gt;
--[[User:Luis de Vasconcelos|Luis de Vasconcelos]] 13:45, 14 January 2011 (UTC)&lt;br /&gt;
&lt;br /&gt;
I&#039;m going to say yes. The problem is caused by minor bugs in the upgrade scripts that don&#039;t exactly match the table creation xml. That will be just as likely for any database. --[[User:Howard Miller|Howard Miller]] 14:14, 14 January 2011 (UTC)&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Verify_Database_Schema&amp;diff=80329</id>
		<title>Verify Database Schema</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Verify_Database_Schema&amp;diff=80329"/>
		<updated>2011-01-14T10:56:42Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* Should I worry? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you have been upgrading your Moodle site over several versions, it is possible (likely even) that some differences may have crept in between the database table definitions (the &amp;quot;schema&amp;quot;) in your database and the version you would get creating a new empty site. This happens because of small errors or oversights in the upgrade scripts. Most of these differences are not harmful, but some may cause strange or unexpected errors. For example, if a default value has been added to a field and this was not reflected in an upgrade script code that assumes the presence of the default may fail to work as expected. &lt;br /&gt;
&lt;br /&gt;
The solution is after doing an upgrade (or, if your problem is that the upgrade fails, before) to compare the database schema of the &amp;quot;production&amp;quot; site to that of a newly created site (where no upgrades have been performed) using &#039;&#039;&#039;exactly&#039;&#039;&#039; the same code base. There are a number of ways of doing this, but this article outlines a simple way using the Unix command line.&lt;br /&gt;
&lt;br /&gt;
* Complete the upgrade&lt;br /&gt;
* Generate the database schema from your recently upgraded site using the following command:&lt;br /&gt;
    mysqldump -d -u root -p &#039;&#039;myproductiondb&#039;&#039; &amp;gt;production.schema&lt;br /&gt;
* Copy the code  of your production database to a new (web accessible) location (this is important, it *must* be the same version)&lt;br /&gt;
* Create a new, empty database and moodledata area for the new site as per the [[Installation]] instructions&lt;br /&gt;
* Edit the config.php file to point at the new database and locations, or delete it and use the install script&lt;br /&gt;
* Run the install script to generate the (if applicable) config.php file and the database (admin and site values are not important)&lt;br /&gt;
* Generate the database schema from your new site using the following command:&lt;br /&gt;
    mysqldump -d -u root -p &#039;&#039;mycleandb&#039;&#039; &amp;gt;clean.schema&lt;br /&gt;
* Run the following command to detect the differences&lt;br /&gt;
    diff -u production.schema clean.schema &amp;gt;db.diff&lt;br /&gt;
&lt;br /&gt;
You can now look at &#039;&#039;db.diff&#039;&#039; with your favorite editor to see the differences.&lt;br /&gt;
&lt;br /&gt;
==Interpreting the diff file==&lt;br /&gt;
&lt;br /&gt;
Firstly here&#039;s a (real) example:&lt;br /&gt;
&lt;br /&gt;
     --&lt;br /&gt;
     -- Table structure for table `mdl_backup_config`&lt;br /&gt;
        @@ -129,11 +93,11 @@&lt;br /&gt;
         DROP TABLE IF EXISTS `mdl_backup_config`;&lt;br /&gt;
         CREATE TABLE `mdl_backup_config` (&lt;br /&gt;
    -  `id` int(10) unsigned NOT NULL auto_increment,&lt;br /&gt;
    +  `id` bigint(10) unsigned NOT NULL auto_increment,&lt;br /&gt;
       `name` varchar(255) NOT NULL default &#039;&#039;,&lt;br /&gt;
       `value` varchar(255) NOT NULL default &#039;&#039;,&lt;br /&gt;
        PRIMARY KEY  (`id`),&lt;br /&gt;
    -  UNIQUE KEY `name` (`name`)&lt;br /&gt;
    +  UNIQUE KEY `mdl_backconf_nam_uix` (`name`)&lt;br /&gt;
         ) ENGINE=MyISAM AUTO_INCREMENT=15 DEFAULT CHARSET=utf8 COMMENT=&#039;To store backup configuration variables&#039;;&lt;br /&gt;
&lt;br /&gt;
The file may have lots of blocks of changes. The - lines show lines to be taken out and the + lines the ones to replace them (from the production to the clean). So here, the int has been replaced with a bigint and the key name changed. Both of these, technically, should have been changed at some point by upgrade scripts but have been missed. In this case they are unlikely to affect the operation of Moodle. &lt;br /&gt;
&lt;br /&gt;
==Should I worry?==&lt;br /&gt;
&lt;br /&gt;
Changes in field types (as long as they are compatible) and key name changes seem to be the common issues but &#039;&#039;&#039;should&#039;&#039;&#039; not cause problems. Things to look out for would be along the lines of missing fields and changes to default values.&lt;br /&gt;
&lt;br /&gt;
If you are about to upgrade to Moodle 2.0 you should be more concerned. In order for the upgrade to proceed smoothly it is a very good idea to correct these problems.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* The missing indexes report in SiteAdmin-&amp;gt;Misc-&amp;gt;XMLDB editor-&amp;gt;Check Indexes&lt;br /&gt;
* [http://moodle.org/mod/forum/view.php?id=45 Moodle Databases Forum]&lt;br /&gt;
&lt;br /&gt;
[[Category:Administrator]]&lt;br /&gt;
&lt;br /&gt;
[[de:Datenbank-Schema prüfen]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Talk:Branch_structures&amp;diff=80168</id>
		<title>Talk:Branch structures</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Talk:Branch_structures&amp;diff=80168"/>
		<updated>2011-01-11T15:56:27Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: New page: This needs some work to make any sense. It randomly uses notation like B1, V1 etc. without any explanation of what those codes mean --~~~~&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This needs some work to make any sense. It randomly uses notation like B1, V1 etc. without any explanation of what those codes mean --[[User:Howard Miller|Howard Miller]] 15:56, 11 January 2011 (UTC)&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Export_questions&amp;diff=80060</id>
		<title>Export questions</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Export_questions&amp;diff=80060"/>
		<updated>2011-01-04T11:23:19Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* Process */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questions may be exported from the [[Quiz module]] and the [[Question bank]] in any one of 4 formats: &lt;br /&gt;
&lt;br /&gt;
* [[GIFT format]]&lt;br /&gt;
* [[Moodle XML format]]&lt;br /&gt;
* [[IMS QTI 2.0 format]]&lt;br /&gt;
* [[XHTML format]] &lt;br /&gt;
&lt;br /&gt;
==Process==&lt;br /&gt;
*Select the export tab.  &lt;br /&gt;
[[Image:Question bank export.png|thumb|center|Export tab in Question bank]]&lt;br /&gt;
*Select the output type required for the exported file.&lt;br /&gt;
*Use the pulldown menu to select the question category you want to export &lt;br /&gt;
*Check if you want the category name to exported and/or the context to be included. This only applies to some formats and is used to restore this information on import.  &lt;br /&gt;
*Click on the export questions to file button&lt;br /&gt;
*The exported questions will be listed to the screen for confirmation.&lt;br /&gt;
[[Image:Question bank Exported questions.png|thumb|center|Exported questions screen]]&lt;br /&gt;
*You are invited to download the file to your computer.&lt;br /&gt;
&lt;br /&gt;
*The file has been saved in your course files (course admin block), backup&amp;gt;quiz.&lt;br /&gt;
&lt;br /&gt;
==Example uses of exported files==&lt;br /&gt;
*GIFT and Moodle XML formats can be imported into the [[Lesson module]] And [[Question bank]] via [[Import questions|an import question process]].&lt;br /&gt;
*Exported question files on one server, can be imported into another Moodle site/server&lt;br /&gt;
*GIFT and Moodle XML formats can be tweaked to create word processing or spreadsheet documents suitable for paper tests or vetting.&lt;br /&gt;
*In case you want to convert your Moodle XML file into text format  upload XML to [http://moodle.heroku.com http://moodle.heroku.com]. It automatically generates *.txt with your questions&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[http://moodle.heroku.com Moodle XML Converter] to generate in and from XML.&lt;br /&gt;
*[http://www.moodle2word.net Website for converting Moodle Questions into tables in a Microsoft Word file, and vice versa].&lt;br /&gt;
&lt;br /&gt;
[[Category:Questions]]&lt;br /&gt;
&lt;br /&gt;
[[de:Fragen exportieren]]&lt;br /&gt;
[[eu:Galderak_esportatu]]&lt;br /&gt;
[[fr:Exporter des questions]]&lt;br /&gt;
[[ja:問題のエクスポート]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Development:Development_hints_and_tips&amp;diff=79727</id>
		<title>Development:Development hints and tips</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Development:Development_hints_and_tips&amp;diff=79727"/>
		<updated>2010-12-23T09:56:14Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* Use a Version Control system */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
&lt;br /&gt;
There is a great deal of development experience amongst the Moodle developers. This page is some general hints and tips that may help people starting out in PHP and Moodle development. These apply as much to people writing their own plugins as core developers.&lt;br /&gt;
&lt;br /&gt;
== Avoid writing code in the first place ==&lt;br /&gt;
&lt;br /&gt;
Always take the trouble to find if there is another (existing) way to do what you need. Failing that, does a plugin or option already exist. Failing that, does something exist that you can modify. Failing that, is there a library (or libraries) that exist to reduce your effort. Lastly write the code yourself. Existing, tested code is always to be preferred - more so if it has an extensive user base. &lt;br /&gt;
&lt;br /&gt;
== Follow the Coding Guidelines ==&lt;br /&gt;
&lt;br /&gt;
Moodle has a well developed set of [[Development:Coding|Coding Guidelines]]. Read them and follow them. It&#039;s surprising how many custom plugins for Moodle do not. It instantly prevents your code from being incorporated in core Moodle.&lt;br /&gt;
&lt;br /&gt;
Pay particular attention to the security information. A basic understanding of security in a web development environment is no longer optional. If you don&#039;t know what an XSS attack or an SQL injection are then you need to find out.&lt;br /&gt;
&lt;br /&gt;
== When in Rome, do like the Romans ==&lt;br /&gt;
&lt;br /&gt;
The Coding Guidelines do not describe every possible situation. When you find yourself in that situation, try to follow the example of how things are done in other parts of Moodle. Just because Moodle is not written the way you would do it if you were starting from scratch does not matter. In a large project like Moodle, it is more important to keep the code consistent than it is to satisfy your personal prejudices about how code should be. That makes it easier to maintain the code, and if you start writing Moodle-style code, you will find it easier to understand the other bits of Moodle code you look at.&lt;br /&gt;
&lt;br /&gt;
Of course, some parts of Moodle are just badly written. You should not copy what is done in those places. ;-) When looking for examples to follow, try to find code that has been written recently by one of the reliable core developers.&lt;br /&gt;
&lt;br /&gt;
Getting involved in a large Open Source project can be a bit of a culture shock if you are not used to it. Lots of advice (and, sometimes, constructive criticism) is readily available. Don&#039;t be afraid to ask - that&#039;s what the General Developer Forum is for.&lt;br /&gt;
&lt;br /&gt;
== Use a Version Control system ==&lt;br /&gt;
&lt;br /&gt;
If you are developing without a version control system then you are doing it wrong. The benefits run well beyond just being able to keep past versions of your code. Moodle currently uses CVS for core development but this is probably a poor (out of date) choice for a new project. Moodle uses [[Development:Git tips|Git]] for developing so it makes sense to learn it. This is a powerful distributed system and does take a bit of getting your head around but the effort is worth it.&lt;br /&gt;
&lt;br /&gt;
== Find an editor or IDE that works for you and learn it properly ==&lt;br /&gt;
&lt;br /&gt;
There are many different development platforms from complex Integrated Development Environments (IDEs) to simple editors and command line tools. Choose something that works for you and then take the trouble to learn how to use it properly.&lt;br /&gt;
&lt;br /&gt;
Find the editor&#039;s customisation options and make it fit in with Moodle&#039;s coding guidelines - example, most editors can be persuaded to use the correct number of spaces (4 in Moodle&#039;s case) rather than the tab character.&lt;br /&gt;
&lt;br /&gt;
== Comment effectively ==&lt;br /&gt;
&lt;br /&gt;
Don&#039;t be shy about putting comments in code. If the code deserves a blank line it probably deserves a comment. It&#039;s obvious what the code does now but it won&#039;t be in six months.&lt;br /&gt;
&lt;br /&gt;
== KISS (Keep It Simple Stupid) ==&lt;br /&gt;
&lt;br /&gt;
Albert Einstein didn&#039;t &#039;&#039;actually&#039;&#039; say &amp;quot;Everything should be made as simple as possible, but no simpler&amp;quot; but it would still have been good advice if he had. Take the trouble to come up with the simplest solution to the problem at hand. Resist the temptation to add code for things that you &#039;&#039;might&#039;&#039; need in the future or &#039;&#039;might&#039;&#039; be required one day. They usually never happen and you can always change the code later if requirements change. For example, don&#039;t use some insanely complex object factory when old-fashioned procedural programming will do. Don&#039;t use old-fashioned procedural programming when a class-hierarchy models the real-world problem more intuitively. Avoid complex abstractions where they are not actually needed to get the job done. Any additional code increases the risk of bugs, security problems and maintenance issues in the future.&lt;br /&gt;
&lt;br /&gt;
== Use good variable and function names ==&lt;br /&gt;
&lt;br /&gt;
It should be easy and obvious to pick a name for a variable or a function. If it isn&#039;t you are either trying to make that function too complicated (simplify and break it up) or you haven&#039;t fully understood what you are trying to do (another cup of coffee?). Names should always say what they are for or what they do - plainly.&lt;br /&gt;
&lt;br /&gt;
== Pretty code is good code ==&lt;br /&gt;
&lt;br /&gt;
Seriously! Code that is well laid out and easy to read is easy to debug and to modify. Make the effort to lay out code so it looks good and is easy to read through. Don&#039;t be afraid to break something nasty into several lines so that it reads well. It&#039;s tempting to make one line of code do something incredibly complex but you won&#039;t feel so clever when you can&#039;t remember how it works.&lt;br /&gt;
&lt;br /&gt;
== Write Plugins. Use APIs ==&lt;br /&gt;
&lt;br /&gt;
Always, when developing custom features, write a standard plugin in preference to modifying core code. Even if you have to compromise the functionality a bit. Most Moodle plugin structures are able to easily create database structures, handle role capabilities, define language files and ease future updates. Furthermore, the end result can all be delivered in one simple zip file. It doesn&#039;t rely on one particular build of Moodle either. These are real and big advantages. A core code patch is only guaranteed to work with the exact build it was written with, it probably won&#039;t survive upgrades and patches are notoriously difficult to apply properly - even for experienced developers. If in doubt look at blocks - you can do an awful lot with a block (even if it&#039;s never actually added as a visible block). Blocks are reasonably easy to understand and to develop, too. &lt;br /&gt;
&lt;br /&gt;
Similarly, take the trouble to investigate existing Moodle APIs and library calls. Your code will last longer and be more reliable.&lt;br /&gt;
&lt;br /&gt;
== Separate out functionality ==&lt;br /&gt;
&lt;br /&gt;
Or... don&#039;t muddle up the user interface with the database access and other logic. For example, alarm bells should ring if you are writing functions like &#039;&#039;&#039;get_data_and_display()&#039;&#039;&#039;. It is a much better idea to write &#039;&#039;&#039;get_data()&#039;&#039;&#039; and then &#039;&#039;&#039;display_data()&#039;&#039;&#039;. The effort is little or no different, however, the end result is often easier to follow and (say) if someone asks you to dump the data to Excel rather than display it the latter method saves you a costly refactor. Even if you are not writing functions and your logic is all on one page try to split things into logical blocks - read the input, THEN do the calculations and database access, THEN display the output. It will be easier to refactor or to modify.&lt;br /&gt;
&lt;br /&gt;
== Don&#039;t Make Me Think ==&lt;br /&gt;
&lt;br /&gt;
It&#039;s actually a title of a book by Steve Krug (and it should be obligatory reading for all web designers), however, the point is really about Usability. Usability is hard but you still have to try. Don&#039;t make your users have to think. Good documentation is important but it&#039;s hard to keep it up to date and it&#039;s a partial failure if someone has to resort to reading it. In particular, be quite clear that ordinary Moodle users don&#039;t care about clever implementation or super flexibility. Anything that complicates the job of getting effective learning materials to students is &amp;quot;a bad thing&amp;quot;. Anything that in the name of adding flexibility or functionality makes an ordinary user&#039;s job more complex is a regression. If something must be done then the code must do it - do not burden the user. &lt;br /&gt;
&lt;br /&gt;
Force yourself to think like a user and not a programmer. A clever, elegant solution to a programming problem is not guaranteed to result in a feature that is simple and intuitive to use. Look at the forums. If lots of people are having trouble using a feature then you need to consider if the feature is doing the job well enough. &lt;br /&gt;
&lt;br /&gt;
It should be hard (or even better impossible) for users to break things. The greatest invention ever was the undo button - it doesn&#039;t only protect the user against mistakes it allows them to safely experiment. Users don&#039;t learn to use software by reading the manual - they experiment and guess. Make it easy for them.&lt;br /&gt;
&lt;br /&gt;
There&#039;s some guidelines (currently under development) in [[Development:Moodle User Interface Guidelines|User Interface Guidelines]]&lt;br /&gt;
&lt;br /&gt;
== Let the database do the grunt work ==&lt;br /&gt;
&lt;br /&gt;
If there&#039;s a choice let the database do the work of searches. Especially if multiple tables are involved. It&#039;s what it was designed to do. It can be tempting, especially if your SQL knowledge isn&#039;t too good, to tie together multiple database queries with PHP loops and the like. Always consider using a single database call instead. Always try to use the basic Moodle database API functions before writing custom SQL (portability!).&lt;br /&gt;
&lt;br /&gt;
Having said all that, optimising databases (especially when datasets get large) is a subject in itself. Nearly all web development involves database interactions so even basic db admin skills are very valuable and worthwhile acquiring.&lt;br /&gt;
&lt;br /&gt;
== Generate helpful error messages ==&lt;br /&gt;
&lt;br /&gt;
If you generate an error message, consider if it &#039;really&#039; helps the user fix the problem. Be as specific as possible. If you can give information that will help resolve the problem rather than just say it happened then do so. BUT... you also have to consider security. Don&#039;t give away information that might help a hacker. You might want to consider debugging level (is it on?) and/or who the user is (you might give an administrator more information).&lt;br /&gt;
&lt;br /&gt;
You should also try to trap as many possible errors as possible. If a function returns a fail condition then you would need to have a very good reason not to check it. This helps avoid the highly unpopular &amp;quot;white screen of death&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Add extra debugging code (call &#039;&#039;debugging()&#039;&#039; )if you think it might help. This is especially true for functions that have complex configuration or external dependencies (i.e. lots that can go wrong).&lt;br /&gt;
&lt;br /&gt;
Never write an error message that looks something like &amp;quot;An unknown error occurred&amp;quot;. You might as well not bother as this doesn&#039;t help anybody fix the problem.&lt;br /&gt;
&lt;br /&gt;
== Turn on Debugging and fix those notices and warnings ==&lt;br /&gt;
&lt;br /&gt;
If you get PHP warnings or notices when [[Debugging]] is switched on the problem is &#039;&#039;&#039;not&#039;&#039;&#039; that debugging has been left on, the problem is that there are bugs in your code. There is no excuse for not checking for and then fixing notices and warnings. To not do so is shoddy at best.&lt;br /&gt;
&lt;br /&gt;
== Expand Moodle Docs ==&lt;br /&gt;
&lt;br /&gt;
If something you want to do isn&#039;t documented (or isn&#039;t documented well or fully) and you figure it out - document it. Don&#039;t write it in your notebook or your company&#039;s closed Wiki, put it in the docs here. It&#039;s there for you next time and for everyone else as well.&lt;br /&gt;
&lt;br /&gt;
== More tips please ==&lt;br /&gt;
(add your own!)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Development:Development_hints_and_tips&amp;diff=79726</id>
		<title>Development:Development hints and tips</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Development:Development_hints_and_tips&amp;diff=79726"/>
		<updated>2010-12-23T09:52:14Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* Generate helpful error messages */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
&lt;br /&gt;
There is a great deal of development experience amongst the Moodle developers. This page is some general hints and tips that may help people starting out in PHP and Moodle development. These apply as much to people writing their own plugins as core developers.&lt;br /&gt;
&lt;br /&gt;
== Avoid writing code in the first place ==&lt;br /&gt;
&lt;br /&gt;
Always take the trouble to find if there is another (existing) way to do what you need. Failing that, does a plugin or option already exist. Failing that, does something exist that you can modify. Failing that, is there a library (or libraries) that exist to reduce your effort. Lastly write the code yourself. Existing, tested code is always to be preferred - more so if it has an extensive user base. &lt;br /&gt;
&lt;br /&gt;
== Follow the Coding Guidelines ==&lt;br /&gt;
&lt;br /&gt;
Moodle has a well developed set of [[Development:Coding|Coding Guidelines]]. Read them and follow them. It&#039;s surprising how many custom plugins for Moodle do not. It instantly prevents your code from being incorporated in core Moodle.&lt;br /&gt;
&lt;br /&gt;
Pay particular attention to the security information. A basic understanding of security in a web development environment is no longer optional. If you don&#039;t know what an XSS attack or an SQL injection are then you need to find out.&lt;br /&gt;
&lt;br /&gt;
== When in Rome, do like the Romans ==&lt;br /&gt;
&lt;br /&gt;
The Coding Guidelines do not describe every possible situation. When you find yourself in that situation, try to follow the example of how things are done in other parts of Moodle. Just because Moodle is not written the way you would do it if you were starting from scratch does not matter. In a large project like Moodle, it is more important to keep the code consistent than it is to satisfy your personal prejudices about how code should be. That makes it easier to maintain the code, and if you start writing Moodle-style code, you will find it easier to understand the other bits of Moodle code you look at.&lt;br /&gt;
&lt;br /&gt;
Of course, some parts of Moodle are just badly written. You should not copy what is done in those places. ;-) When looking for examples to follow, try to find code that has been written recently by one of the reliable core developers.&lt;br /&gt;
&lt;br /&gt;
Getting involved in a large Open Source project can be a bit of a culture shock if you are not used to it. Lots of advice (and, sometimes, constructive criticism) is readily available. Don&#039;t be afraid to ask - that&#039;s what the General Developer Forum is for.&lt;br /&gt;
&lt;br /&gt;
== Use a Version Control system ==&lt;br /&gt;
&lt;br /&gt;
If you are developing without a version control system then you are doing it wrong. The benefits run well beyond just being able to keep past versions of your code. Moodle currently uses CVS for core development but this is probably a poor (out of date) choice for a new project. Moodle will soon be using [[Development:Git tips|Git]]. This is a powerful distributed system and does take a bit of getting your head around but the effort is worth it.&lt;br /&gt;
&lt;br /&gt;
== Find an editor or IDE that works for you and learn it properly ==&lt;br /&gt;
&lt;br /&gt;
There are many different development platforms from complex Integrated Development Environments (IDEs) to simple editors and command line tools. Choose something that works for you and then take the trouble to learn how to use it properly.&lt;br /&gt;
&lt;br /&gt;
Find the editor&#039;s customisation options and make it fit in with Moodle&#039;s coding guidelines - example, most editors can be persuaded to use the correct number of spaces (4 in Moodle&#039;s case) rather than the tab character.&lt;br /&gt;
&lt;br /&gt;
== Comment effectively ==&lt;br /&gt;
&lt;br /&gt;
Don&#039;t be shy about putting comments in code. If the code deserves a blank line it probably deserves a comment. It&#039;s obvious what the code does now but it won&#039;t be in six months.&lt;br /&gt;
&lt;br /&gt;
== KISS (Keep It Simple Stupid) ==&lt;br /&gt;
&lt;br /&gt;
Albert Einstein didn&#039;t &#039;&#039;actually&#039;&#039; say &amp;quot;Everything should be made as simple as possible, but no simpler&amp;quot; but it would still have been good advice if he had. Take the trouble to come up with the simplest solution to the problem at hand. Resist the temptation to add code for things that you &#039;&#039;might&#039;&#039; need in the future or &#039;&#039;might&#039;&#039; be required one day. They usually never happen and you can always change the code later if requirements change. For example, don&#039;t use some insanely complex object factory when old-fashioned procedural programming will do. Don&#039;t use old-fashioned procedural programming when a class-hierarchy models the real-world problem more intuitively. Avoid complex abstractions where they are not actually needed to get the job done. Any additional code increases the risk of bugs, security problems and maintenance issues in the future.&lt;br /&gt;
&lt;br /&gt;
== Use good variable and function names ==&lt;br /&gt;
&lt;br /&gt;
It should be easy and obvious to pick a name for a variable or a function. If it isn&#039;t you are either trying to make that function too complicated (simplify and break it up) or you haven&#039;t fully understood what you are trying to do (another cup of coffee?). Names should always say what they are for or what they do - plainly.&lt;br /&gt;
&lt;br /&gt;
== Pretty code is good code ==&lt;br /&gt;
&lt;br /&gt;
Seriously! Code that is well laid out and easy to read is easy to debug and to modify. Make the effort to lay out code so it looks good and is easy to read through. Don&#039;t be afraid to break something nasty into several lines so that it reads well. It&#039;s tempting to make one line of code do something incredibly complex but you won&#039;t feel so clever when you can&#039;t remember how it works.&lt;br /&gt;
&lt;br /&gt;
== Write Plugins. Use APIs ==&lt;br /&gt;
&lt;br /&gt;
Always, when developing custom features, write a standard plugin in preference to modifying core code. Even if you have to compromise the functionality a bit. Most Moodle plugin structures are able to easily create database structures, handle role capabilities, define language files and ease future updates. Furthermore, the end result can all be delivered in one simple zip file. It doesn&#039;t rely on one particular build of Moodle either. These are real and big advantages. A core code patch is only guaranteed to work with the exact build it was written with, it probably won&#039;t survive upgrades and patches are notoriously difficult to apply properly - even for experienced developers. If in doubt look at blocks - you can do an awful lot with a block (even if it&#039;s never actually added as a visible block). Blocks are reasonably easy to understand and to develop, too. &lt;br /&gt;
&lt;br /&gt;
Similarly, take the trouble to investigate existing Moodle APIs and library calls. Your code will last longer and be more reliable.&lt;br /&gt;
&lt;br /&gt;
== Separate out functionality ==&lt;br /&gt;
&lt;br /&gt;
Or... don&#039;t muddle up the user interface with the database access and other logic. For example, alarm bells should ring if you are writing functions like &#039;&#039;&#039;get_data_and_display()&#039;&#039;&#039;. It is a much better idea to write &#039;&#039;&#039;get_data()&#039;&#039;&#039; and then &#039;&#039;&#039;display_data()&#039;&#039;&#039;. The effort is little or no different, however, the end result is often easier to follow and (say) if someone asks you to dump the data to Excel rather than display it the latter method saves you a costly refactor. Even if you are not writing functions and your logic is all on one page try to split things into logical blocks - read the input, THEN do the calculations and database access, THEN display the output. It will be easier to refactor or to modify.&lt;br /&gt;
&lt;br /&gt;
== Don&#039;t Make Me Think ==&lt;br /&gt;
&lt;br /&gt;
It&#039;s actually a title of a book by Steve Krug (and it should be obligatory reading for all web designers), however, the point is really about Usability. Usability is hard but you still have to try. Don&#039;t make your users have to think. Good documentation is important but it&#039;s hard to keep it up to date and it&#039;s a partial failure if someone has to resort to reading it. In particular, be quite clear that ordinary Moodle users don&#039;t care about clever implementation or super flexibility. Anything that complicates the job of getting effective learning materials to students is &amp;quot;a bad thing&amp;quot;. Anything that in the name of adding flexibility or functionality makes an ordinary user&#039;s job more complex is a regression. If something must be done then the code must do it - do not burden the user. &lt;br /&gt;
&lt;br /&gt;
Force yourself to think like a user and not a programmer. A clever, elegant solution to a programming problem is not guaranteed to result in a feature that is simple and intuitive to use. Look at the forums. If lots of people are having trouble using a feature then you need to consider if the feature is doing the job well enough. &lt;br /&gt;
&lt;br /&gt;
It should be hard (or even better impossible) for users to break things. The greatest invention ever was the undo button - it doesn&#039;t only protect the user against mistakes it allows them to safely experiment. Users don&#039;t learn to use software by reading the manual - they experiment and guess. Make it easy for them.&lt;br /&gt;
&lt;br /&gt;
There&#039;s some guidelines (currently under development) in [[Development:Moodle User Interface Guidelines|User Interface Guidelines]]&lt;br /&gt;
&lt;br /&gt;
== Let the database do the grunt work ==&lt;br /&gt;
&lt;br /&gt;
If there&#039;s a choice let the database do the work of searches. Especially if multiple tables are involved. It&#039;s what it was designed to do. It can be tempting, especially if your SQL knowledge isn&#039;t too good, to tie together multiple database queries with PHP loops and the like. Always consider using a single database call instead. Always try to use the basic Moodle database API functions before writing custom SQL (portability!).&lt;br /&gt;
&lt;br /&gt;
Having said all that, optimising databases (especially when datasets get large) is a subject in itself. Nearly all web development involves database interactions so even basic db admin skills are very valuable and worthwhile acquiring.&lt;br /&gt;
&lt;br /&gt;
== Generate helpful error messages ==&lt;br /&gt;
&lt;br /&gt;
If you generate an error message, consider if it &#039;really&#039; helps the user fix the problem. Be as specific as possible. If you can give information that will help resolve the problem rather than just say it happened then do so. BUT... you also have to consider security. Don&#039;t give away information that might help a hacker. You might want to consider debugging level (is it on?) and/or who the user is (you might give an administrator more information).&lt;br /&gt;
&lt;br /&gt;
You should also try to trap as many possible errors as possible. If a function returns a fail condition then you would need to have a very good reason not to check it. This helps avoid the highly unpopular &amp;quot;white screen of death&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Add extra debugging code (call &#039;&#039;debugging()&#039;&#039; )if you think it might help. This is especially true for functions that have complex configuration or external dependencies (i.e. lots that can go wrong).&lt;br /&gt;
&lt;br /&gt;
Never write an error message that looks something like &amp;quot;An unknown error occurred&amp;quot;. You might as well not bother as this doesn&#039;t help anybody fix the problem.&lt;br /&gt;
&lt;br /&gt;
== Turn on Debugging and fix those notices and warnings ==&lt;br /&gt;
&lt;br /&gt;
If you get PHP warnings or notices when [[Debugging]] is switched on the problem is &#039;&#039;&#039;not&#039;&#039;&#039; that debugging has been left on, the problem is that there are bugs in your code. There is no excuse for not checking for and then fixing notices and warnings. To not do so is shoddy at best.&lt;br /&gt;
&lt;br /&gt;
== Expand Moodle Docs ==&lt;br /&gt;
&lt;br /&gt;
If something you want to do isn&#039;t documented (or isn&#039;t documented well or fully) and you figure it out - document it. Don&#039;t write it in your notebook or your company&#039;s closed Wiki, put it in the docs here. It&#039;s there for you next time and for everyone else as well.&lt;br /&gt;
&lt;br /&gt;
== More tips please ==&lt;br /&gt;
(add your own!)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Development:Development_hints_and_tips&amp;diff=79725</id>
		<title>Development:Development hints and tips</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Development:Development_hints_and_tips&amp;diff=79725"/>
		<updated>2010-12-23T09:50:41Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* Generate helpful error messages */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
&lt;br /&gt;
There is a great deal of development experience amongst the Moodle developers. This page is some general hints and tips that may help people starting out in PHP and Moodle development. These apply as much to people writing their own plugins as core developers.&lt;br /&gt;
&lt;br /&gt;
== Avoid writing code in the first place ==&lt;br /&gt;
&lt;br /&gt;
Always take the trouble to find if there is another (existing) way to do what you need. Failing that, does a plugin or option already exist. Failing that, does something exist that you can modify. Failing that, is there a library (or libraries) that exist to reduce your effort. Lastly write the code yourself. Existing, tested code is always to be preferred - more so if it has an extensive user base. &lt;br /&gt;
&lt;br /&gt;
== Follow the Coding Guidelines ==&lt;br /&gt;
&lt;br /&gt;
Moodle has a well developed set of [[Development:Coding|Coding Guidelines]]. Read them and follow them. It&#039;s surprising how many custom plugins for Moodle do not. It instantly prevents your code from being incorporated in core Moodle.&lt;br /&gt;
&lt;br /&gt;
Pay particular attention to the security information. A basic understanding of security in a web development environment is no longer optional. If you don&#039;t know what an XSS attack or an SQL injection are then you need to find out.&lt;br /&gt;
&lt;br /&gt;
== When in Rome, do like the Romans ==&lt;br /&gt;
&lt;br /&gt;
The Coding Guidelines do not describe every possible situation. When you find yourself in that situation, try to follow the example of how things are done in other parts of Moodle. Just because Moodle is not written the way you would do it if you were starting from scratch does not matter. In a large project like Moodle, it is more important to keep the code consistent than it is to satisfy your personal prejudices about how code should be. That makes it easier to maintain the code, and if you start writing Moodle-style code, you will find it easier to understand the other bits of Moodle code you look at.&lt;br /&gt;
&lt;br /&gt;
Of course, some parts of Moodle are just badly written. You should not copy what is done in those places. ;-) When looking for examples to follow, try to find code that has been written recently by one of the reliable core developers.&lt;br /&gt;
&lt;br /&gt;
Getting involved in a large Open Source project can be a bit of a culture shock if you are not used to it. Lots of advice (and, sometimes, constructive criticism) is readily available. Don&#039;t be afraid to ask - that&#039;s what the General Developer Forum is for.&lt;br /&gt;
&lt;br /&gt;
== Use a Version Control system ==&lt;br /&gt;
&lt;br /&gt;
If you are developing without a version control system then you are doing it wrong. The benefits run well beyond just being able to keep past versions of your code. Moodle currently uses CVS for core development but this is probably a poor (out of date) choice for a new project. Moodle will soon be using [[Development:Git tips|Git]]. This is a powerful distributed system and does take a bit of getting your head around but the effort is worth it.&lt;br /&gt;
&lt;br /&gt;
== Find an editor or IDE that works for you and learn it properly ==&lt;br /&gt;
&lt;br /&gt;
There are many different development platforms from complex Integrated Development Environments (IDEs) to simple editors and command line tools. Choose something that works for you and then take the trouble to learn how to use it properly.&lt;br /&gt;
&lt;br /&gt;
Find the editor&#039;s customisation options and make it fit in with Moodle&#039;s coding guidelines - example, most editors can be persuaded to use the correct number of spaces (4 in Moodle&#039;s case) rather than the tab character.&lt;br /&gt;
&lt;br /&gt;
== Comment effectively ==&lt;br /&gt;
&lt;br /&gt;
Don&#039;t be shy about putting comments in code. If the code deserves a blank line it probably deserves a comment. It&#039;s obvious what the code does now but it won&#039;t be in six months.&lt;br /&gt;
&lt;br /&gt;
== KISS (Keep It Simple Stupid) ==&lt;br /&gt;
&lt;br /&gt;
Albert Einstein didn&#039;t &#039;&#039;actually&#039;&#039; say &amp;quot;Everything should be made as simple as possible, but no simpler&amp;quot; but it would still have been good advice if he had. Take the trouble to come up with the simplest solution to the problem at hand. Resist the temptation to add code for things that you &#039;&#039;might&#039;&#039; need in the future or &#039;&#039;might&#039;&#039; be required one day. They usually never happen and you can always change the code later if requirements change. For example, don&#039;t use some insanely complex object factory when old-fashioned procedural programming will do. Don&#039;t use old-fashioned procedural programming when a class-hierarchy models the real-world problem more intuitively. Avoid complex abstractions where they are not actually needed to get the job done. Any additional code increases the risk of bugs, security problems and maintenance issues in the future.&lt;br /&gt;
&lt;br /&gt;
== Use good variable and function names ==&lt;br /&gt;
&lt;br /&gt;
It should be easy and obvious to pick a name for a variable or a function. If it isn&#039;t you are either trying to make that function too complicated (simplify and break it up) or you haven&#039;t fully understood what you are trying to do (another cup of coffee?). Names should always say what they are for or what they do - plainly.&lt;br /&gt;
&lt;br /&gt;
== Pretty code is good code ==&lt;br /&gt;
&lt;br /&gt;
Seriously! Code that is well laid out and easy to read is easy to debug and to modify. Make the effort to lay out code so it looks good and is easy to read through. Don&#039;t be afraid to break something nasty into several lines so that it reads well. It&#039;s tempting to make one line of code do something incredibly complex but you won&#039;t feel so clever when you can&#039;t remember how it works.&lt;br /&gt;
&lt;br /&gt;
== Write Plugins. Use APIs ==&lt;br /&gt;
&lt;br /&gt;
Always, when developing custom features, write a standard plugin in preference to modifying core code. Even if you have to compromise the functionality a bit. Most Moodle plugin structures are able to easily create database structures, handle role capabilities, define language files and ease future updates. Furthermore, the end result can all be delivered in one simple zip file. It doesn&#039;t rely on one particular build of Moodle either. These are real and big advantages. A core code patch is only guaranteed to work with the exact build it was written with, it probably won&#039;t survive upgrades and patches are notoriously difficult to apply properly - even for experienced developers. If in doubt look at blocks - you can do an awful lot with a block (even if it&#039;s never actually added as a visible block). Blocks are reasonably easy to understand and to develop, too. &lt;br /&gt;
&lt;br /&gt;
Similarly, take the trouble to investigate existing Moodle APIs and library calls. Your code will last longer and be more reliable.&lt;br /&gt;
&lt;br /&gt;
== Separate out functionality ==&lt;br /&gt;
&lt;br /&gt;
Or... don&#039;t muddle up the user interface with the database access and other logic. For example, alarm bells should ring if you are writing functions like &#039;&#039;&#039;get_data_and_display()&#039;&#039;&#039;. It is a much better idea to write &#039;&#039;&#039;get_data()&#039;&#039;&#039; and then &#039;&#039;&#039;display_data()&#039;&#039;&#039;. The effort is little or no different, however, the end result is often easier to follow and (say) if someone asks you to dump the data to Excel rather than display it the latter method saves you a costly refactor. Even if you are not writing functions and your logic is all on one page try to split things into logical blocks - read the input, THEN do the calculations and database access, THEN display the output. It will be easier to refactor or to modify.&lt;br /&gt;
&lt;br /&gt;
== Don&#039;t Make Me Think ==&lt;br /&gt;
&lt;br /&gt;
It&#039;s actually a title of a book by Steve Krug (and it should be obligatory reading for all web designers), however, the point is really about Usability. Usability is hard but you still have to try. Don&#039;t make your users have to think. Good documentation is important but it&#039;s hard to keep it up to date and it&#039;s a partial failure if someone has to resort to reading it. In particular, be quite clear that ordinary Moodle users don&#039;t care about clever implementation or super flexibility. Anything that complicates the job of getting effective learning materials to students is &amp;quot;a bad thing&amp;quot;. Anything that in the name of adding flexibility or functionality makes an ordinary user&#039;s job more complex is a regression. If something must be done then the code must do it - do not burden the user. &lt;br /&gt;
&lt;br /&gt;
Force yourself to think like a user and not a programmer. A clever, elegant solution to a programming problem is not guaranteed to result in a feature that is simple and intuitive to use. Look at the forums. If lots of people are having trouble using a feature then you need to consider if the feature is doing the job well enough. &lt;br /&gt;
&lt;br /&gt;
It should be hard (or even better impossible) for users to break things. The greatest invention ever was the undo button - it doesn&#039;t only protect the user against mistakes it allows them to safely experiment. Users don&#039;t learn to use software by reading the manual - they experiment and guess. Make it easy for them.&lt;br /&gt;
&lt;br /&gt;
There&#039;s some guidelines (currently under development) in [[Development:Moodle User Interface Guidelines|User Interface Guidelines]]&lt;br /&gt;
&lt;br /&gt;
== Let the database do the grunt work ==&lt;br /&gt;
&lt;br /&gt;
If there&#039;s a choice let the database do the work of searches. Especially if multiple tables are involved. It&#039;s what it was designed to do. It can be tempting, especially if your SQL knowledge isn&#039;t too good, to tie together multiple database queries with PHP loops and the like. Always consider using a single database call instead. Always try to use the basic Moodle database API functions before writing custom SQL (portability!).&lt;br /&gt;
&lt;br /&gt;
Having said all that, optimising databases (especially when datasets get large) is a subject in itself. Nearly all web development involves database interactions so even basic db admin skills are very valuable and worthwhile acquiring.&lt;br /&gt;
&lt;br /&gt;
== Generate helpful error messages ==&lt;br /&gt;
&lt;br /&gt;
If you generate an error message, consider if it &#039;really&#039; helps the user fix the problem. Be as specific as possible. If you can give information that will help resolve the problem rather than just say it happened then do so. BUT... you also have to consider security. Don&#039;t give away information that might help a hacker. You might want to consider debugging level (is it on?) and/or who the user is (you might give an administrator more information).&lt;br /&gt;
&lt;br /&gt;
You should also try to trap as many possible errors as possible. If a function returns a fail condition then you would need to have a very good reason not to check it. This helps avoid the highly unpopular &amp;quot;white screen of death&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Add extra debugging code (call &#039;&#039;debugging()&#039;&#039; )if you think it might help. This is especially true for functions that have complex configuration or external dependencies (i.e. lots that can go wrong).&lt;br /&gt;
&lt;br /&gt;
== Turn on Debugging and fix those notices and warnings ==&lt;br /&gt;
&lt;br /&gt;
If you get PHP warnings or notices when [[Debugging]] is switched on the problem is &#039;&#039;&#039;not&#039;&#039;&#039; that debugging has been left on, the problem is that there are bugs in your code. There is no excuse for not checking for and then fixing notices and warnings. To not do so is shoddy at best.&lt;br /&gt;
&lt;br /&gt;
== Expand Moodle Docs ==&lt;br /&gt;
&lt;br /&gt;
If something you want to do isn&#039;t documented (or isn&#039;t documented well or fully) and you figure it out - document it. Don&#039;t write it in your notebook or your company&#039;s closed Wiki, put it in the docs here. It&#039;s there for you next time and for everyone else as well.&lt;br /&gt;
&lt;br /&gt;
== More tips please ==&lt;br /&gt;
(add your own!)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Talk:Moodle_2.0_release_notes&amp;diff=79724</id>
		<title>Talk:Moodle 2.0 release notes</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Talk:Moodle_2.0_release_notes&amp;diff=79724"/>
		<updated>2010-12-23T09:47:29Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Random comments about 2.0 release documentation==&lt;br /&gt;
*[[Course completion]] aka [[Course completion tracking]] - a MAJOR new feature not listed or at least does not jump out --[[User:chris collman|chris collman]] 12:15, 26 November 2010 (UTC)&lt;br /&gt;
::Realized it was there.  I know &amp;quot;completion&amp;quot; is also a feature common with conditional activities.  Someone looking for course conditions of entry is not going to think completion has anything to do with it.  I put the activity stuff with conditional activities and change the subheading to &amp;quot;Course completion and prerequsites&amp;quot;.  Sorry if I overstepped my bounds here.--[[User:chris collman|chris collman]] 13:14, 26 November 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
*[[Activity completion]] - here it is called [[Conditional activities]]. --[[User:chris collman|chris collman]] 12:15, 26 November 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
==The Lesson activity==&lt;br /&gt;
Note 1: when type or paste text formatting does not happen in the page preview.&lt;br /&gt;
Note 2: In true / false question, the variable &#039;Your answer&#039; is equal to feedback message.&lt;br /&gt;
Quiz Activity:&lt;br /&gt;
Note 1: In question multiple-choice answers entered do not appear in the view of the question. {{Unsigned|José Albuquerque}}&lt;br /&gt;
&lt;br /&gt;
:Hi José, rather than adding comments here, please could you check that any problems/bugs have been reported in the [http://tracker.moodle.org Moodle tracker]. If you&#039;re not sure whether something is a bug or not, you can ask about it in the [http://moodle.org/mod/forum/view.php?id=56 Testing and QA forum] in Using Moodle. Thanks in advance for your help! --[[User:Helen Foster|Helen Foster]] 14:50, 17 November 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
==Rendering Layer Changes==&lt;br /&gt;
This points to a page that is marked as obsolete :( --[[User:Howard Miller|Howard Miller]] 09:47, 23 December 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Obsolete:Migrating_your_code_to_the_2.0_rendering_API&amp;diff=79723</id>
		<title>Obsolete:Migrating your code to the 2.0 rendering API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Obsolete:Migrating_your_code_to_the_2.0_rendering_API&amp;diff=79723"/>
		<updated>2010-12-23T09:44:51Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* print_header */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;strong&amp;gt; THIS PAGE IS OUTDATED, DO NOT USE! &amp;lt;/strong&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This page explains how to update your code to take advantage of the new navigation/block/themes/rendering APIs in Moodle 2.0. These changes are explained on [[Development:Navigation 2.0]], [[Development:Navigation 2.0 implementation plan]] and linked pages. You should read that background to understand the changes. This page just explains how you should update your code, not why.&lt;br /&gt;
&lt;br /&gt;
Note that most of the code here has extensive php documentor documentation. Please use that [http://phpdocs.moodle.org/HEAD/index.html API documentation] if you want more details of how to use this new code. If you really want to know how it works see [[Developement:How_Moodle_outputs_HTML]], and I hope the code is readable and well commented.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==General note==&lt;br /&gt;
&lt;br /&gt;
First of all, go to Administration -&amp;gt; Server -&amp;gt; Debugging, and turn debugging up to DEVELOPER level.&lt;br /&gt;
&lt;br /&gt;
Most of the things that have been deprecated or that need to be changed cause debugging output that explains how to update your code.&lt;br /&gt;
&lt;br /&gt;
I went to a lot of effort to implement all that helpful output, please use it!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Outputting HTML==&lt;br /&gt;
See [[Development:Outputting HTML in 2.0]] for a detailed list of functions to migrate.&lt;br /&gt;
&lt;br /&gt;
HTML used to be output through a mixture of direct echo/print statements, and calls to functions like print_header, print_box, ... in lib/weblib.php.&lt;br /&gt;
&lt;br /&gt;
The functions in weblib have been replaced by a new global $OUTPUT. This generates HTML that you need to echo, so&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_box(...);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
becomes&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
global $OUTPUT; // If necessary.&lt;br /&gt;
$OUTPUT-&amp;gt;box(...);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Why do we do this, well by default $OUTPUT is a moodle_core_renderer. However, the theme can choose a different class, and so use different output for, say, a box. As an example look in theme/custom_corners/renderers.php.)&lt;br /&gt;
&lt;br /&gt;
===Outputting complex objects===&lt;br /&gt;
&lt;br /&gt;
Some of the old weblib.php functions had a lot of arguments, for example:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu($options, &#039;outcome_&#039;.$n.&#039;[&#039;.$userid.&#039;]&#039;,&lt;br /&gt;
        $outcome-&amp;gt;grades[$submission-&amp;gt;userid]-&amp;gt;grade, get_string(&#039;nooutcome&#039;, &#039;grades&#039;),&lt;br /&gt;
        &#039;&#039;, 0, false, false, 0, &#039;menuoutcome_&#039;.$n);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
That was quite difficult to work with. (What do those two false parameters mean?). The equivalent new code looks like&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$menu = new moodle_select_menu;&lt;br /&gt;
$menu-&amp;gt;options = $options;&lt;br /&gt;
$menu-&amp;gt;name = &#039;outcome_&#039;.$n.&#039;[&#039;.$userid.&#039;]&#039;;&lt;br /&gt;
$menu-&amp;gt;selectedoption = $outcome-&amp;gt;grades[$submission-&amp;gt;userid]-&amp;gt;grade;&lt;br /&gt;
$menu-&amp;gt;nothinglabel = get_string(&#039;nooutcome&#039;, &#039;grades&#039;);&lt;br /&gt;
$menu-&amp;gt;id = &#039;menuoutcome_&#039;.$n;&lt;br /&gt;
echo $OUTPUT-&amp;gt;select_menu($menu);&lt;br /&gt;
&amp;lt;/code&amp;gt;  &lt;br /&gt;
The new code is more verbose, but much easier to understand  ([http://moodle.org/mod/forum/discuss.php?d=126220 discussion]).&lt;br /&gt;
&lt;br /&gt;
If fact if you remember the old print_table method, this approach will be quite familiar. However, note that we now use a real class, rather than stdClass. The main reason for that is that it lets us document the structure ([http://phpdocs.moodle.org/HEAD/moodlecore/moodle_select_menu.html see here for an example). It also makes it easy to set defaults and lets IDEs offer autocompletion.&lt;br /&gt;
&lt;br /&gt;
===print_header===&lt;br /&gt;
&lt;br /&gt;
The old print_header function becomes $OUTPUT-&amp;gt;header(). Instead of passing millions of arguments to that function, instead you set propeties on $PAGE. For exampe:&lt;br /&gt;
&lt;br /&gt;
The Moodle 1.9 code&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$navlinks = array(array(&#039;name&#039;=&amp;gt;$strparticipants, &#039;link&#039;=&amp;gt;$CFG-&amp;gt;wwwroot.&#039;/user/index.php?id=&#039;.$courseid, &#039;type&#039;=&amp;gt;&#039;misc&#039;),&lt;br /&gt;
                  array(&#039;name&#039;=&amp;gt;$strgroups, &#039;link&#039;=&amp;gt;&#039;&#039;, &#039;type&#039;=&amp;gt;&#039;misc&#039;));&lt;br /&gt;
$navigation = build_navigation($navlinks);&lt;br /&gt;
print_header(get_string(&#039;publishcourse&#039;), $course-&amp;gt;fullname, $navigation,&#039;&#039;,$meta, true, &#039;&amp;amp;nbsp;&#039;, user_login_string($course, $USER));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Becomes the following Moodle 2.0 code &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
require_login( $course );&lt;br /&gt;
$PAGE-&amp;gt;set_title(get_string(&#039;publishcourse&#039;));&lt;br /&gt;
$PAGE-&amp;gt;set_heading($course-&amp;gt;fullname);&lt;br /&gt;
$PAGE-&amp;gt;set_focuscontrol(&#039;&#039;);&lt;br /&gt;
$PAGE-&amp;gt;set_cacheable(true);&lt;br /&gt;
$PAGE-&amp;gt;set_button(&#039;$nbsp;&#039;);&lt;br /&gt;
$PAGE-&amp;gt;set_headingmenu(user_login_string($course, $USER));&lt;br /&gt;
$PAGE-&amp;gt;navbar-&amp;gt;add($strparticipants, null, null, navigation_node::TYPE_CUSTOM, new moodle_url($CFG-&amp;gt;wwwroot.&#039;/user/index.php?id=&#039;.$courseid));&lt;br /&gt;
$PAGE-&amp;gt;navbar-&amp;gt;add($strgroups);&lt;br /&gt;
echo $OUTPUT-&amp;gt;header();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NOTE: The &#039;&#039;&#039;require_login()&#039;&#039;&#039; does some magic in the background to set up $PAGE. If you don&#039;t have it you may have to do some more work.&lt;br /&gt;
&lt;br /&gt;
The following arguments are no longer supported at all. They were not being used anywhere in core code in a way that could not be handled by a better mechanism.&lt;br /&gt;
* meta&lt;br /&gt;
* usexml&lt;br /&gt;
* bodytags&lt;br /&gt;
&lt;br /&gt;
===Outputting HTML specific to your module===&lt;br /&gt;
&lt;br /&gt;
$OUTPUT lets themes customise the HTML used for standard things like boxes, but what about places where code echoes HTML directly? Well, in addition to moodle_core_renderer, every plugin should also define its own renderer, like moodle_mod_workshop_renderer, and all  module-specific HTML output should done in methods of that class. That class should be defined in a files called renderers.php inside your plugin. &lt;br /&gt;
&lt;br /&gt;
When you actually want to do some output, you need to get an instance of your class (or whatever subclass the theme wants to substitute). You do that like this:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
global $PAGE; // If necessary.&lt;br /&gt;
$wsoutput = $PAGE-&amp;gt;theme-&amp;gt;get_renderer(&#039;mod_workshop&#039;, $PAGE);&lt;br /&gt;
echo $wsoutput-&amp;gt;manual_allocation_interface($workshop, $allocationdata);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The moodle_mod_workshop_renderer object will have access to a moodle_core_renderer available as $this-&amp;gt;output. You should use this instead of global $OUTPUT, and you should use it. That is, boxes in the workshop should look like boxes elsewhere, so boxes in the workshop should be output with $this-&amp;gt;output-&amp;gt;box().&lt;br /&gt;
&lt;br /&gt;
===Don&#039;t panic!===&lt;br /&gt;
&lt;br /&gt;
Completely updating your code to use the new output methods everywhere, and writing a renderer class is a big job. The good news is that you don&#039;t have to. All the old weblib methods have been moved to deprecatedlib, and now call $OUTPUT, so all your old code will go on working. You can update it at your leisure. (Of course, eventually, the old methods will be removed, so you should update some time.)&lt;br /&gt;
&lt;br /&gt;
==Blocks==&lt;br /&gt;
&lt;br /&gt;
=== Settings forms ===&lt;br /&gt;
&lt;br /&gt;
==== Global ====&lt;br /&gt;
&lt;br /&gt;
config_global.html files must be replaced by a [[Development:Admin_settings|settings.php]] file, just like other plugin types. (There is rudimentary support for config_global.html files still in the code, but you should not rely on it.)&lt;br /&gt;
&lt;br /&gt;
==== Instance ====&lt;br /&gt;
&lt;br /&gt;
config_instance.html files must be replaced by a proper settings form. The form must be a subclass of block_settings_form called block_&#039;&#039;myblock&#039;&#039;_edit_form defined in the file blocks/&#039;&#039;myblock&#039;&#039;/edit_form.php.&lt;br /&gt;
&lt;br /&gt;
In addition, the old instance_config_print is no longer used, so any code there needs to be moved into the form class you create.&lt;br /&gt;
&lt;br /&gt;
blocks/html/edit_form.php is a nice simple example to look at. Other blocks mentioned in MDL-19889 provide more complex examples. The [http://tracker.moodle.org/browse/MDL-19889?page=com.atlassian.jira.plugin.system.issuetabpanels%3Acvs-tabpanel changes associated with that bug] show you exactly how to covert a block.&lt;br /&gt;
&lt;br /&gt;
There is currently no backwards-compatible support for old config_instance.html files. It would be hard to do that. It might be possible if people really need it, but no-one has had time to try yet.&lt;br /&gt;
&lt;br /&gt;
=== Other API changes ===&lt;br /&gt;
&lt;br /&gt;
* The method block_base::preferred_width is no longer used the width of blocks is entirely controlled by the theme. If your block is too wide, it will probably get cropped with overflow: hidden. See http://moodle.org/mod/forum/discuss.php?d=122525 for discussion.&lt;br /&gt;
&lt;br /&gt;
* Code in the block that relied on $this-&amp;gt;instance-&amp;gt;... will probably break. Information about the page the block is appearing on is available from $this-&amp;gt;page-&amp;gt;.... Specifically:&lt;br /&gt;
** $this-&amp;gt;instance-&amp;gt;pagetype should be changed to $this-&amp;gt;page-&amp;gt;pagetype&lt;br /&gt;
** $this-&amp;gt;instance-&amp;gt;pageid - there is no longer a concept of page id. Instead, you are probably looking for $this-&amp;gt;page-&amp;gt;course, $this-&amp;gt;page-&amp;gt;cm or $this-&amp;gt;page-&amp;gt;activityrecord. See below for more on $PAGE.&lt;br /&gt;
&lt;br /&gt;
=== Useful new stuff ===&lt;br /&gt;
&lt;br /&gt;
* Every block now has access to the page it appears on, via $this-&amp;gt;page. (Therefore, you do not have to use the global $PAGE object in blocks!)&lt;br /&gt;
&lt;br /&gt;
* Every block now has its own context, and you can always access it via $this-&amp;gt;context. However when checking permissions you need to decide which of two contexts is more appropriate:&lt;br /&gt;
*# The block context ($this-&amp;gt;context)&lt;br /&gt;
*# The page context the block is appearing on ($this-&amp;gt;page-&amp;gt;context). For sticky blocks, this may be a more appropriate choice.&lt;br /&gt;
For example, when deciding whether the user can edit the block settings, or see the block, you should use the block context. When deciding whether the user can do something relating to the context where the block appears (can the user see participants here) you should probably use the page context.&lt;br /&gt;
&lt;br /&gt;
=== Other things to be aware of ===&lt;br /&gt;
&lt;br /&gt;
Note that the way the blocks are output to HTML has changed. However, there has been no change to the blocks API, so you should not have to make any changes, unless you had overridden formerly &#039;private&#039; methods.&lt;br /&gt;
&lt;br /&gt;
==Activity modules==&lt;br /&gt;
&lt;br /&gt;
See also the section on [[#Outputting blocks]] below.&lt;br /&gt;
&lt;br /&gt;
===Blocks upgrade===&lt;br /&gt;
&lt;br /&gt;
If you have a custom module that has a pagelib.php file, then you need to ensure it is included in the blocks upgrade. Just look for the bit in lib/db/upgrade.php that says&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$moduleswithblocks = array(&#039;chat&#039;, &#039;data&#039;, &#039;lesson&#039;, &#039;quiz&#039;, &#039;dimdim&#039;, &#039;game&#039;, &#039;wiki&#039;, &#039;oublog&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
and add the name of your module. You must do this before trying to upgrade your site.&lt;br /&gt;
&lt;br /&gt;
If you have done something more complicated than what is in the NEWMODULE template, then you will have to write more custom code.&lt;br /&gt;
&lt;br /&gt;
===in mod/.../view.php===&lt;br /&gt;
&lt;br /&gt;
You need to change how $PAGE is initialised.&lt;br /&gt;
* Don&#039;t call page_create_instance any more. It is deprecated, and if you do, you should see a debug warning. (You do you development with debugging set to DEBUG_DEVELOPER, right?)&lt;br /&gt;
* In fact, you probably only need to replace the line &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE = page_create_instance($chat-&amp;gt;id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
with&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_url(&#039;mod/MYMOD/view.php&#039;, array(&#039;id&#039; =&amp;gt; $cm-&amp;gt;id));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
* Take the code that is left in page_generic_activity::print_header in inline it in your view.php file at the point where you used to call $PAGE::print_header. You will need to fix it up to make it work, but normally that involves deleting about half of it and editing the rest a bit. Some helpful notes:&lt;br /&gt;
** $this-&amp;gt;modulerecord -&amp;gt; $cm&lt;br /&gt;
** $this-&amp;gt;$course -&amp;gt; $course&lt;br /&gt;
** $this-&amp;gt;activityname -&amp;gt; &#039;&#039;&amp;lt;nowiki&amp;gt;&#039;MYMOD&#039;&amp;lt;/nowiki&amp;gt;&#039;&#039;&lt;br /&gt;
** Change the complicated mess that computes $title into a simple line of code.&lt;br /&gt;
** Other instances of $this -&amp;gt; $PAGE&lt;br /&gt;
** See if $meta, $bodytags and so on are acutally used, and if not remove them.&lt;br /&gt;
* Delete your &#039;mod/MYMOD/pagelib.php&#039; file, and any places where it is included.&lt;br /&gt;
&lt;br /&gt;
To help with this conversion, the regex &#039;&#039;&#039;page_|\$PAGE|pagelib&#039;&#039;&#039; is a good thing to search for.&lt;br /&gt;
&lt;br /&gt;
===in ..._delete_instance in lib.php===&lt;br /&gt;
&lt;br /&gt;
You used to have to worry about deleting blocks when an instance of your module was deleted. You can forget about that now, since all blocks data are deleted automatically when a context is deleted.&lt;br /&gt;
&lt;br /&gt;
That is, code like&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$pagetypes = page_import_types(&#039;mod/chat/&#039;);&lt;br /&gt;
foreach($pagetypes as $pagetype) {&lt;br /&gt;
    if(!blocks_delete_all_on_page($pagetype, $chat-&amp;gt;id)) {&lt;br /&gt;
        $result = false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
in lib.php can just be deleted.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$PAGE==&lt;br /&gt;
&lt;br /&gt;
It is no longer necessary to write subclasses of page_base, and in fact, such subclasses are no longer used. Instead there is a single moodle_page class, and an instance of that is automatically created as $PAGE.&lt;br /&gt;
&lt;br /&gt;
Do not set $CFG-&amp;gt;pagepath. Instead, call $PAGE-&amp;gt;set_pagetype(); For example&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;pagepath = &#039;question/type/&#039; . $question-&amp;gt;qtype;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
becomes&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_pagetype(&#039;question-type-&#039; . $question-&amp;gt;qtype);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===blocks_... methods===&lt;br /&gt;
&lt;br /&gt;
If your page subclass used to try to control blocks you need to change it to get equivalent functionality&lt;br /&gt;
&lt;br /&gt;
; blocks_get_positions&lt;br /&gt;
; blocks_default_position&lt;br /&gt;
: You no longer control this. These settings now belong to the theme. However, if you want special extra block areas on certain pages, then you can call $PAGE-&amp;gt;blocks-&amp;gt;add_region(&#039;myregion&#039;);&lt;br /&gt;
; blocks_get_default&lt;br /&gt;
: No longer supported. Instead, in your .../db/install.php you should probably do blocks_create_block(&#039;blockname&#039;, get_context_instance(CONTEXT_SYSTEM), BLOCKS_SHOWINSUBCONTEXTS, &#039;my-page-type&#039;);&lt;br /&gt;
; blocks_move_position&lt;br /&gt;
: No longer required at all. The way blocks editing now works means that it is unnecessary.&lt;br /&gt;
&lt;br /&gt;
===url_... methods===&lt;br /&gt;
&lt;br /&gt;
Instead of implementing the url_get_parameters and url_get_path() methods, you should instead be setting the $PAGE-&amp;gt;set_url(...) method from within your script.&lt;br /&gt;
&lt;br /&gt;
===user_... methods===&lt;br /&gt;
&lt;br /&gt;
; user_is_editing&lt;br /&gt;
: is now implemented by the base class and should not be changed.&lt;br /&gt;
; user_allowed_editing is also implemented by the base class, you must call $PAGE-&amp;gt;set_block_editing_capability and/or $PAGE-&amp;gt;set_other_editing_capability to set the right logic. By default, editing can be turned on on a page if if the user has the &#039;moodle/site:manageblocks&#039; capability in the page context.&lt;br /&gt;
&lt;br /&gt;
===print_header===&lt;br /&gt;
&lt;br /&gt;
the page object no longer has any responsibility for printing the header. Your script should do it directly. This means that if you page class has a print_header method, you should move that code elsewhere.&lt;br /&gt;
&lt;br /&gt;
===Other changes===&lt;br /&gt;
&lt;br /&gt;
* Code that used to rely on the -&amp;gt;courserecord field of pages should be changed to refer to -&amp;gt;course.&lt;br /&gt;
* Calls to $PAGE-&amp;gt;get_type() should be changed to $page-&amp;gt;pagetype.&lt;br /&gt;
* page_id_and_class, which was used to initialise and return the pagetype (as $getid) is no longer necessary. Just use $PAGE-&amp;gt;pagetype.&lt;br /&gt;
* $PAGE-&amp;gt;get_format_name is deprecated. use $PAGE-&amp;gt;pagetype instead.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Libraries to include==&lt;br /&gt;
&lt;br /&gt;
lib/blocklib.php and lib/pagelib.php are now always included by config.php. Therefore you should clean up any places in your code where you explicitly require_once them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$CFG-&amp;gt;pixpath and $CFG-&amp;gt;modpixpath==&lt;br /&gt;
&lt;br /&gt;
$CFG-&amp;gt;pixpath and $CFG-&amp;gt;modpixpath are now deprecated. Old code like &amp;quot;$CFG-&amp;gt;pixpath/i/course.gif&amp;quot; should be changed to $OUTPUT-&amp;gt;pix_url(&#039;i/course&#039;) and code like &amp;quot;$CFG-&amp;gt;modpixpath/$mod/icon.gif&amp;quot; should be changed to $OUTPUT-&amp;gt;pix_url(&#039;icon&#039;, $mod-&amp;gt;modname).&lt;br /&gt;
&lt;br /&gt;
When I started converting Moodle core code, there were 467 matches for the regular expression &#039;&#039;&#039;/\$CFG-&amp;gt;(mod)?pixpath/&#039;&#039;&#039; - that will find all the places in the code you have to update.&lt;br /&gt;
&lt;br /&gt;
I used the following regular expressions (Eclipse regular expression search and replace) to fix a lot of them semi-automatically.&lt;br /&gt;
&lt;br /&gt;
 \$CFG-&amp;gt;pixpath ?\. ?&#039;/((\w/)?[a-zA-Z0-9_-]+)\.(gif|png)&lt;br /&gt;
   -&amp;gt;&lt;br /&gt;
 \$OUTPUT-&amp;gt;pix_url(&#039;$1&#039;) . &#039;&lt;br /&gt;
 (225 matches in HEAD)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 \{?\$CFG-&amp;gt;pixpath\}?/(\w/[a-zA-Z0-9_-]+)\.(gif|png)&lt;br /&gt;
   -&amp;gt;&lt;br /&gt;
 &amp;quot; . \$OUTPUT-&amp;gt;pix_url(&#039;$1&#039;) . &amp;quot;&lt;br /&gt;
 (68 matches in HEAD)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 \$CFG-&amp;gt;pixpath ?\. ?&#039;/([a-zA-Z0-9_-]+)\.(gif|png)&lt;br /&gt;
   -&amp;gt;&lt;br /&gt;
 \$OUTPUT-&amp;gt;pix_url(&#039;$1&#039;) . &#039;&lt;br /&gt;
 (29 matches in HEAD)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 \$CFG-&amp;gt;modpixpath ?\. ?&#039;/&#039; ?\. ?([^\.]+) ?\. ?&#039;/icon\.gif&lt;br /&gt;
   -&amp;gt;&lt;br /&gt;
 \$OUTPUT-&amp;gt;mod_icon_url(&#039;icon&#039;, $1) . &#039;&lt;br /&gt;
 (12 matches in HEAD)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 \$CFG-&amp;gt;modpixpath/([^/]+)/icon.gif&lt;br /&gt;
   -&amp;gt;&lt;br /&gt;
 &amp;quot; . \$OUTPUT-&amp;gt;mod_icon_url(&#039;icon&#039;, $1) . &amp;quot;&lt;br /&gt;
 (13 matches in HEAD)&lt;br /&gt;
&lt;br /&gt;
After you have done the automatic replaces, you need to review the changes (e.g. using cvs diff) because sometimes you end up with code like . &amp;quot;&amp;quot; . that should be cleaned up, and the search and replace cannot add global $OUTPUT; where necessary, nor remove no longer necessary global $CFG; statements.&lt;br /&gt;
&lt;br /&gt;
== Outputting blocks ==&lt;br /&gt;
&lt;br /&gt;
Blocks are now output by the theme, in its layout.php file. Any code you have in your scripts that calls blocks_setup, blocks_preferred_width, blocks_have_content or blocks_print_group should just be deleted. http://git.moodle.org/gw?p=moodle.git;a=commitdiff;h=d4a03c00ea3885ac2b264b7d7a8c6c635d5714d2#patch31 is typical of how to update a script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Themes ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Please don&#039;t forget to take the advice [[#General note|above]] and turn [[Debugging|debugging]] up to DEVELOPER level. That will give you lots of helpful debug output that tells you what you need to update.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== header.html and footer.html replaces by layout.php ===&lt;br /&gt;
&lt;br /&gt;
Instead of separate header.html and footer.html files for the top and bottom of the page, there is now a single layout.php template. You need to create a layout.php file for your theme.&lt;br /&gt;
&lt;br /&gt;
To create layout.php, you basically need to merge your header.html and footer.html files with &amp;quot;[MAIN CONTENT GOES HERE]&amp;quot; in the middle. Then update the resulting code to match the kind of things done in &#039;&#039;theme/standard/layout.php&#039;&#039;. This is explain in more detail in the next few sections.&lt;br /&gt;
&lt;br /&gt;
=== layout.php should get data from $PAGE ===&lt;br /&gt;
&lt;br /&gt;
In the past, header.html and footer.html had to rely on certain variables that were set up in the print_header and print_footer functions. Instead, you should now get the information you want from properties of $PAGE, or call $OUTPUT methods to output various standard things. &lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;replacements&#039;&#039;&#039; for the various old variables are:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Old code in header/footer.html -&amp;gt;   // New code in layout.php&lt;br /&gt;
[hard-coded doctype]              -&amp;gt;   &amp;lt;?php echo $OUTPUT-&amp;gt;doctype() ?&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $direction ?&amp;gt;          -&amp;gt;   &amp;lt;?php echo $OUTPUT-&amp;gt;htmlattributes(); ?&amp;gt;&lt;br /&gt;
$title                            -&amp;gt;   $PAGE-&amp;gt;title;&lt;br /&gt;
$heading                          -&amp;gt;   $PAGE-&amp;gt;heading;&lt;br /&gt;
$focus                            -&amp;gt;   $PAGE-&amp;gt;focuscontrol;&lt;br /&gt;
$button                           -&amp;gt;   $PAGE-&amp;gt;button;&lt;br /&gt;
$pageid                           -&amp;gt;   $PAGE-&amp;gt;pagetype;&lt;br /&gt;
$pageclass                        -&amp;gt;   $PAGE-&amp;gt;bodyclasses;&lt;br /&gt;
&amp;lt;?php echo &amp;quot; $bodytags&amp;quot;; ?&amp;gt;       -&amp;gt;   id=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;pagetype ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyclasses ?&amp;gt;&amp;quot;&lt;br /&gt;
if ($home) {...                   -&amp;gt;   if ($PAGE-&amp;gt;generaltype == &#039;home&#039;) {...&lt;br /&gt;
$homelink                         -&amp;gt;   $OUTPUT-&amp;gt;home_link();&lt;br /&gt;
$loggedinas                       -&amp;gt;   $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
$course                           -&amp;gt;   $PAGE-&amp;gt;course;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some standard bits that used to be present need to be &#039;&#039;&#039;deleted&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Delete these bits that used to be in header/footer.html&lt;br /&gt;
&amp;lt;?php echo $meta ?&amp;gt;&lt;br /&gt;
&amp;lt;meta name=&amp;quot;keywords&amp;quot; content=&amp;quot;moodle, &amp;lt;?php echo $title ?&amp;gt; &amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;?php include(&amp;quot;$CFG-&amp;gt;javascript&amp;quot;); ?&amp;gt;&lt;br /&gt;
  if (!empty($performanceinfo)) {&lt;br /&gt;
    echo $performanceinfo;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And certain new bits need to be &#039;&#039;&#039;added&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Add these bits in the appropriate places in layout.php&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_head_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_top_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_footer_html() ?&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;
&lt;br /&gt;
=== Themes must print the blocks ===&lt;br /&gt;
&lt;br /&gt;
You must also add code to your layout.php to output any blocks. &lt;br /&gt;
&lt;br /&gt;
Typically the code will look something like:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Add code like this in the appropriate places in layout.php&lt;br /&gt;
&amp;lt;?php if ($PAGE-&amp;gt;blocks-&amp;gt;region_has_content(&#039;side-pre&#039;)) { ?&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;region-side-pre&amp;quot; class=&amp;quot;block-region&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;?php } ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As I said above, the quickest way to get the hang of all the things you need to do in layout.php is by example. Look at [http://cvs.moodle.org/moodle/theme/standard/layout.php?view=markup theme/standard/layout.php], or other examples in the standard Moodle themes.&lt;br /&gt;
&lt;br /&gt;
=== You can have different layout.php files for different page. ===&lt;br /&gt;
&lt;br /&gt;
Pages in Moodle are now classified into one of a few general types, like &#039;normal&#039;, &#039;home&#039;, &#039;form&#039;, &#039;popup&#039;, ...&lt;br /&gt;
&lt;br /&gt;
If you wish, you can specify a different template for each one. Also, each type of template can have any number of regions for blocks. This is controlled by the $THEME-&amp;gt;layouts setting in your theme&#039;s config.php. Here is an example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Code in theme config.php&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Most pages. Put this first, so if we encounter an unknown page type, this is used.&lt;br /&gt;
    &#039;normal&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;layout&#039; =&amp;gt; &#039;standard:layout.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;home&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;layout&#039; =&amp;gt; &#039;layout-home.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;
    // Settings form pages, like course of module settings.&lt;br /&gt;
    &#039;form&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;layout&#039; =&amp;gt; &#039;standard:layout.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
    ),&lt;br /&gt;
    // Pages that appear in pop-up windows.&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;layout&#039; =&amp;gt; &#039;standard:layout-popup.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&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;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;layout&#039; =&amp;gt; &#039;standard:layout-popup.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What you see there is that for each type of page, which layout file to use, and where blocks may appear.&lt;br /&gt;
&lt;br /&gt;
There are three ways you can specify a layout file. It may be in this theme (for example layout-home.php) or it may come from the parent theme (for example you could say parent:layout.php) or from the standard theme (for example standard:layout-popup.php).&lt;br /&gt;
&lt;br /&gt;
Some templates have &#039;regions&#039; for blocks and others don&#039;t. You can even use a template that has block regions (like standard:layout.php) but then say you don&#039;t want any blocks there, as for &#039;form&#039; pages in the example above. Note that the default names for regions are now side-pre and side-post. That makes more sends than left and right in right-to-left languages.&lt;br /&gt;
&lt;br /&gt;
If there are block regions, then you must specify one of them as the default. That is where the &#039;Add new blocks&#039; pretend block appears, and where new blocks are added.&lt;br /&gt;
&lt;br /&gt;
Also, suppose someone adds some blocks while using another theme that uses one set of names for its block regions, and then switches to your theme that uses different names. We don&#039;t want some of the blocks to just disappear, so any blocks from unrecognised regions are shown at the end of the default region.&lt;br /&gt;
&lt;br /&gt;
=== styles.php ===&lt;br /&gt;
&lt;br /&gt;
The standard form for the styles.php file has changed (become simpler). Please copy the latest theme/standard/styles.php into your theme.&lt;br /&gt;
&lt;br /&gt;
=== No longer supported options in config.php ===&lt;br /&gt;
&lt;br /&gt;
Note that there is now documentation about all the things you can set in config.php at http://phpdocs.moodle.org/HEAD/moodlecore/theme_config.html.&lt;br /&gt;
&lt;br /&gt;
All the separate $THEME-&amp;gt;modsheets = true; $THEME-&amp;gt;blocksheets = true; ... settings have been replaced by a single&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;pluginsheets = array(&#039;mod&#039;, &#039;block&#039;, &#039;format&#039;, &#039;gradereport&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
setting, and all plugin types are now supported.&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;customcorners = true; should be changed to $this-&amp;gt;rendererfactory = &#039;custom_corners_renderer_factory&#039;;&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;cssconstants = true; is no longer supported in config.php files. Use $THEME-&amp;gt;customcssoutputfunction = &#039;output_css_replacing_constants&#039;;&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;CSSEdit = true; is no longer supported in config.php files. Use $THEME-&amp;gt;customcssoutputfunction = &#039;output_css_for_css_edit&#039;;&lt;br /&gt;
&lt;br /&gt;
== JavaScript ==&lt;br /&gt;
&lt;br /&gt;
The way in which JavaScript is included for a page has now changed and methods have been provided for $PAGE to require JavaScript within a page.&lt;br /&gt;
As part of this change several JavaScript libraries that were been included on every page are not any more, and if you have code that was using them you need to modify it to manually include these JavaScript files.&lt;br /&gt;
&lt;br /&gt;
=== Replacement for require_js() ===&lt;br /&gt;
&lt;br /&gt;
In the past we have had a function called require_js(), which made it very easy to make sure that you JavaScript files you wanted got linked to somewhere, and that each file was linked to no more than once.&lt;br /&gt;
&lt;br /&gt;
That was very nice, but only went so far. For example, there was no equivalent require_css(), and some of the [[Development:YUI|YUI]] libraries need their own CSS files to work properly. Also, you could not control when the JS was linked to and [http://moodle.org/mod/forum/discuss.php?d=106312 as discussed here], it is best to link to most of the JavaScript from the end of the HTML, not from &amp;lt;head&amp;gt; because that gives better page-load performance. &lt;br /&gt;
&lt;br /&gt;
Of course some things cannot wait that long and  do need to be included in HEAD or in some cases within the body of the page, in other cases if your script is at the end of the page and you need to call an init function then that initialise function had also better be at the end of the page.&lt;br /&gt;
&lt;br /&gt;
As such the requirements have become more complicated and in order to handle them a new &#039;&#039;&#039;[http://phpdocs.moodle.org/HEAD/moodlecore/page_requirements_manager.html page_requirements_manager]&#039;&#039;&#039; was created to replace require_js().&lt;br /&gt;
&lt;br /&gt;
The following are examples of how to use the new page requirements manager.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;css(&#039;mod/mymod/styles.css&#039;);&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;yui_lib(&#039;autocomplete&#039;); // YUI requirements are known about  &lt;br /&gt;
// and automatically included, without you needing to call yui_lib for each one&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js(&#039;mod/mymod/script.js&#039;);&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js(&#039;mod/mymod/small_but_urgent.js&#039;)-&amp;gt;in_head();&lt;br /&gt;
echo $PAGE-&amp;gt;requires-&amp;gt;js(&#039;mod/mymod/small_but_urgent.js&#039;)-&amp;gt;asap();&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js_function_call(&#039;init_mymod&#039;, array($data))-&amp;gt;on_dom_ready();&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;data_for_js(&#039;mydata&#039;, Array(&#039;name1&#039;=&amp;gt;$value1, &#039;name2&#039;=&amp;gt;$value2));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Unobtrusive Flash Objects - ufo.js ===&lt;br /&gt;
&lt;br /&gt;
The UFO JS object used to display inline media is no longer included on every page. If you have any code that is relying on the UFO library you will need to update it in order for it to work.&lt;br /&gt;
&lt;br /&gt;
In order to use the UFO you will need to include the following line of code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
global $PAGE; // You will only need this if you are within a function&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js(&#039;lib/ufo.js&#039;); // Only use -&amp;gt;asap() or -&amp;gt;in_head() if you really need to&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A good idea at the same time might be to convert your code to use the new $PAGE methods to the full extent which can be done in the following fashion.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;From&#039;&#039;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo &#039;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
echo &#039;//&amp;lt;![CDATA[&#039;;&lt;br /&gt;
echo &#039;  var FO = { movie:&amp;quot;&#039;.$CFG-&amp;gt;wwwroot.&#039;/filter/mediaplugin/mp3player.swf?src=&#039;.$url.&#039;&amp;quot;,&#039;;&lt;br /&gt;
echo &#039;    width:&amp;quot;90&amp;quot;, height:&amp;quot;15&amp;quot;, majorversion:&amp;quot;6&amp;quot;, build:&amp;quot;40&amp;quot;, flashvars:&amp;quot;&#039;.$c.&#039;&amp;quot;, quality: &amp;quot;high&amp;quot; };&#039;;&lt;br /&gt;
echo &#039;  UFO.create(FO, &amp;quot;&#039;.$id.&#039;&amp;quot;);&#039;;&lt;br /&gt;
echo &#039;//]]&amp;gt;&#039;;&lt;br /&gt;
echo &#039;&amp;lt;/script&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&#039;&#039;To&#039;&#039;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$ufoargs = Array();&lt;br /&gt;
$ufoargs[&#039;movie&#039;] = $CFG-&amp;gt;wwwroot.&#039;/filter/mediaplugin/mp3player.swf?src=&#039;.$url;&lt;br /&gt;
$ufoargs[&#039;width&#039;] = 90;&lt;br /&gt;
$ufoargs[&#039;height&#039;] = 15;&lt;br /&gt;
$ufoargs[&#039;majorversion&#039;] = 6;&lt;br /&gt;
$ufoargs[&#039;build&#039;] = 40;&lt;br /&gt;
$ufoargs[&#039;quality&#039;] = &#039;high&#039;;&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js(&#039;lib/ufo.js&#039;);&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;data_for_js(&#039;FO&#039;, $ufoargs);&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js_function_call(&#039;create_UFO_object&#039;, Array(&#039;myelementid&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== DOM events ===&lt;br /&gt;
In the past we have used DOM events inline within HTML elements. Now that we are avoiding inline JavaScript, these methods are no longer suitable. The new rendering API in lib/outputlib.php abstracts all event handlers into a simple approach. &lt;br /&gt;
# JS functions you want to call when an event is triggered must be written in a JS-only text file (no PHP)&lt;br /&gt;
# These functions MUST have 2 params only: event and args. Args is a JS object with named variables which you can use in your function. The event object is used to determine the target of the event (the element to which the event handler is attached), and the type of event that was triggered.&lt;br /&gt;
# To output a HTML element that has an event handler, you must use a subclass of moodle_html_component. These objects have an add_action() method which takes a component_action object or 2-3 params as described in the phpdocs.&lt;br /&gt;
# In the rendering methods of the $OUTPUT object, the render::prepare_event_handlers($component) is called and the appropriate YUI Javascript is added to the page, creating an event listener on the given object.&lt;br /&gt;
An example follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$image = new html_image();&lt;br /&gt;
$image-&amp;gt;src = $src;&lt;br /&gt;
$image-&amp;gt;add_action(&#039;click&#039;, &#039;show_large_version&#039;, array(&#039;title&#039; =&amp;gt; &#039;Large version&#039;, &#039;description&#039; =&amp;gt; &#039;a lovely image&#039;));&lt;br /&gt;
echo $OUTPUT-&amp;gt;image($image);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This examples will output an image which, when clicked, will trigger the call to the show_large_version() JS function, passing the event object and a JS object with two named variables: title and description. That function may look like this:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
function show_large_version(e, args) {&lt;br /&gt;
    var title = args.title;&lt;br /&gt;
    var description = args.description;&lt;br /&gt;
    popup(this.src, title, description); // An imaginary function&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note, in the JS function above, the use of &amp;quot;this&amp;quot;, which is the element that triggered the event. It can be obtained through the event object too.&lt;br /&gt;
&lt;br /&gt;
==Information for admins==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;This probably needs to be moved into the release notes when it is done.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Some hidden blocks my become un-hidden during the upgrade===&lt;br /&gt;
&lt;br /&gt;
In Moodle 1.9, it was, in theory, possible to add a sticky block to a type of page, and then make that stickyblock hidden. The way blocks are hidden in Moodle 2.0 is slightly different, so if in your Moodle 1.9 site you had hidden sticky blocks, they will become visible during the upgrade to Moodle 2.0.&lt;br /&gt;
&lt;br /&gt;
Also, in a few situations, other non-sticky blocks that were hidden may becomes visible. (This will only happen if the block appeared on more than one page. For example, if you have a hidden block on a course page, and also have enabled showing course blocks on resource pages, then the block will be visible on the resource page until you hide it again.) If there are specific identifiable instances of this problem, it may be possible to improve the upgrade code while Moodle is in beta testing.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Developement:How_Moodle_outputs_HTML]]&lt;br /&gt;
* [[Development:Navigation 2.0]]&lt;br /&gt;
* [[Development:Navigation 2.0 implementation plan]]&lt;br /&gt;
* [[Development:Outputting HTML in 2.0]]&lt;br /&gt;
&lt;br /&gt;
{{CategoryDeveloper}}&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Debugging&amp;diff=79595</id>
		<title>Debugging</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Debugging&amp;diff=79595"/>
		<updated>2010-12-22T09:25:58Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* In config.php */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Location: &#039;&#039;Administration &amp;gt; Server &amp;gt; Debugging&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Debugging messages are intended to help diagnose problems and/or help Moodle developers. If you have a problem with your Moodle site and ask for help in a Moodle.org forum, a developer may ask you to turn debug messages on, in order to locate the cause of the problem. By default Moodle does not show any error messages at all. If you are having problems (e.g. blank screens or incomplete screens) turning on debugging is usually the first thing to try. &lt;br /&gt;
&lt;br /&gt;
==How to turn on debugging==&lt;br /&gt;
&lt;br /&gt;
Go into the admin screens, and look under Administration &amp;gt; Server &amp;gt; Debugging (In Moodle 2.0 it is Site administration ▶ Development ▶ Debugging). Set the...&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Debug messages&#039;&#039;&#039; to &#039;&#039;&#039;ALL&#039;&#039;&#039;, and &lt;br /&gt;
* &#039;&#039;&#039;Display debug messages&#039;&#039;&#039; to &#039;&#039;&#039;Yes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
(You &#039;&#039;&#039;must&#039;&#039;&#039; do both). There is rarely any advantage in going to Developer level, unless you are a developer, in which case it is strongly recommended.&lt;br /&gt;
&lt;br /&gt;
Once you have got the error message, and copied and pasted it somewhere, you are recommended to turn debugging back off again.&lt;br /&gt;
&lt;br /&gt;
==Debug messages==&lt;br /&gt;
&lt;br /&gt;
{{Moodle 1.7}}From Moodle 1.7 onwards, further options are provided for controlling how to handle PHP error messages. The administrator can select the types of error messages to be displayed or logged. &lt;br /&gt;
&lt;br /&gt;
The options for debugging include:&lt;br /&gt;
* NONE: Do not show any errors or warnings&lt;br /&gt;
* MINIMAL: Show only fatal errors&lt;br /&gt;
* NORMAL: Show errors, warnings and notices&lt;br /&gt;
* ALL: Show all reasonable PHP debug messages. When you want to find the cause of a problem with your site, this is probably best the setting to use.&lt;br /&gt;
* DEVELOPER: extra Moodle debug messages for developers - If you turn this on, then PHP&#039;s error_reporting will be increased so that more warnings are printed.  This is almost essential for developers, but not very helpful for anyone else.&lt;br /&gt;
&lt;br /&gt;
==Display debug messages==&lt;br /&gt;
&lt;br /&gt;
There is an option to choose whether to display error messages or simply record them in the server logs.&lt;br /&gt;
&lt;br /&gt;
==Debug email sending==&lt;br /&gt;
&lt;br /&gt;
Determines whether or not to enable verbose debug information during sending of email messages to SMTP server.&lt;br /&gt;
&lt;br /&gt;
==Performance info==&lt;br /&gt;
&lt;br /&gt;
The Performance info option determines whether performance info will be included in the footer of the standard theme (and some other themes). Performance info includes the time for the page to load, the amount of memory used to generate the page, cpu usage, load, and the record cache hit/miss ration.&lt;br /&gt;
&lt;br /&gt;
If you add&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
define(&#039;MDL_PERF&#039;, true);&lt;br /&gt;
define(&#039;MDL_PERFDB&#039;, true);&lt;br /&gt;
define(&#039;MDL_PERFTOLOG&#039;, true);&lt;br /&gt;
define(&#039;MDL_PERFTOFOOT&#039;, true);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
to your config.php file, then it will also count database queries. (This has to be in config.php, because Moodle starts doing DB queries before it loads the config information in the database!&lt;br /&gt;
&lt;br /&gt;
==What to do if you cannot get to the admin screens==&lt;br /&gt;
&lt;br /&gt;
If the error is stopping you even getting to the admin screens to turn on debugging, then you can set the debugging setting manually.&lt;br /&gt;
&lt;br /&gt;
===Try typing the URL directly===&lt;br /&gt;
&lt;br /&gt;
The debug settings are at the URL &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://.../admin/settings.php?section=debugging&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; on your server. Sometimes that URL will work, even though the pages you need to go to to get there (for example the site front page) do not. So it is worth trying to enter that URL directly.&lt;br /&gt;
&lt;br /&gt;
===In config.php===&lt;br /&gt;
&lt;br /&gt;
In moodle/config.php you can add the lines:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;debug = 2047; &lt;br /&gt;
$CFG-&amp;gt;debugdisplay = 1;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or even more debugging messages:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;debug = 6143; &lt;br /&gt;
$CFG-&amp;gt;debugdisplay = 1;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Moodle 2.0}}For Moodle 2.0 the possible settings are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Force a debugging mode regardless the settings in the site administration&lt;br /&gt;
// @error_reporting(1023);  // NOT FOR PRODUCTION SERVERS!&lt;br /&gt;
@ini_set(&#039;display_errors&#039;, &#039;1&#039;); // NOT FOR PRODUCTION SERVERS!&lt;br /&gt;
$CFG-&amp;gt;debug = 38911;  // DEBUG_DEVELOPER // NOT FOR PRODUCTION SERVERS!&lt;br /&gt;
$CFG-&amp;gt;debugdisplay = true;   // NOT FOR PRODUCTION SERVERS!&lt;br /&gt;
&lt;br /&gt;
// You can specify a comma separated list of user ids that that always see&lt;br /&gt;
// debug messages, this overrides the debug flag in $CFG-&amp;gt;debug and $CFG-&amp;gt;debugdisplay&lt;br /&gt;
// for these users only.&lt;br /&gt;
$CFG-&amp;gt;debugusers = &#039;2&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remember to remove those lines again when you have finished diagnosing your problem.&lt;br /&gt;
&lt;br /&gt;
===In the database===&lt;br /&gt;
&lt;br /&gt;
Using a tool like phpMyAdmin, execute the following SQL commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code sql&amp;gt;&lt;br /&gt;
UPDATE mdl_config SET value = 2047 WHERE name = &#039;debug&#039;;&lt;br /&gt;
UPDATE mdl_config SET value = 1 WHERE name = &#039;debugdisplay&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To turn it back off, use the admin screens, or the commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code sql&amp;gt;&lt;br /&gt;
UPDATE mdl_config SET value = 0 WHERE name = &#039;debug&#039;;&lt;br /&gt;
UPDATE mdl_config SET value = 0 WHERE name = &#039;debugdisplay&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(If you use a different database prefix, you will need to adjust those commands accordingly.)&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/discuss.php?d=91031 Debugging Turned on to Developer Mode on 1.8.2] forum discussion including instructions on how to turn debugging off&lt;br /&gt;
&lt;br /&gt;
[[Category:Administrator]]&lt;br /&gt;
&lt;br /&gt;
[[fr:Débogage]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Debugging&amp;diff=79594</id>
		<title>Debugging</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Debugging&amp;diff=79594"/>
		<updated>2010-12-22T09:24:49Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* In config.php */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Location: &#039;&#039;Administration &amp;gt; Server &amp;gt; Debugging&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Debugging messages are intended to help diagnose problems and/or help Moodle developers. If you have a problem with your Moodle site and ask for help in a Moodle.org forum, a developer may ask you to turn debug messages on, in order to locate the cause of the problem. By default Moodle does not show any error messages at all. If you are having problems (e.g. blank screens or incomplete screens) turning on debugging is usually the first thing to try. &lt;br /&gt;
&lt;br /&gt;
==How to turn on debugging==&lt;br /&gt;
&lt;br /&gt;
Go into the admin screens, and look under Administration &amp;gt; Server &amp;gt; Debugging (In Moodle 2.0 it is Site administration ▶ Development ▶ Debugging). Set the...&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Debug messages&#039;&#039;&#039; to &#039;&#039;&#039;ALL&#039;&#039;&#039;, and &lt;br /&gt;
* &#039;&#039;&#039;Display debug messages&#039;&#039;&#039; to &#039;&#039;&#039;Yes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
(You &#039;&#039;&#039;must&#039;&#039;&#039; do both). There is rarely any advantage in going to Developer level, unless you are a developer, in which case it is strongly recommended.&lt;br /&gt;
&lt;br /&gt;
Once you have got the error message, and copied and pasted it somewhere, you are recommended to turn debugging back off again.&lt;br /&gt;
&lt;br /&gt;
==Debug messages==&lt;br /&gt;
&lt;br /&gt;
{{Moodle 1.7}}From Moodle 1.7 onwards, further options are provided for controlling how to handle PHP error messages. The administrator can select the types of error messages to be displayed or logged. &lt;br /&gt;
&lt;br /&gt;
The options for debugging include:&lt;br /&gt;
* NONE: Do not show any errors or warnings&lt;br /&gt;
* MINIMAL: Show only fatal errors&lt;br /&gt;
* NORMAL: Show errors, warnings and notices&lt;br /&gt;
* ALL: Show all reasonable PHP debug messages. When you want to find the cause of a problem with your site, this is probably best the setting to use.&lt;br /&gt;
* DEVELOPER: extra Moodle debug messages for developers - If you turn this on, then PHP&#039;s error_reporting will be increased so that more warnings are printed.  This is almost essential for developers, but not very helpful for anyone else.&lt;br /&gt;
&lt;br /&gt;
==Display debug messages==&lt;br /&gt;
&lt;br /&gt;
There is an option to choose whether to display error messages or simply record them in the server logs.&lt;br /&gt;
&lt;br /&gt;
==Debug email sending==&lt;br /&gt;
&lt;br /&gt;
Determines whether or not to enable verbose debug information during sending of email messages to SMTP server.&lt;br /&gt;
&lt;br /&gt;
==Performance info==&lt;br /&gt;
&lt;br /&gt;
The Performance info option determines whether performance info will be included in the footer of the standard theme (and some other themes). Performance info includes the time for the page to load, the amount of memory used to generate the page, cpu usage, load, and the record cache hit/miss ration.&lt;br /&gt;
&lt;br /&gt;
If you add&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
define(&#039;MDL_PERF&#039;, true);&lt;br /&gt;
define(&#039;MDL_PERFDB&#039;, true);&lt;br /&gt;
define(&#039;MDL_PERFTOLOG&#039;, true);&lt;br /&gt;
define(&#039;MDL_PERFTOFOOT&#039;, true);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
to your config.php file, then it will also count database queries. (This has to be in config.php, because Moodle starts doing DB queries before it loads the config information in the database!&lt;br /&gt;
&lt;br /&gt;
==What to do if you cannot get to the admin screens==&lt;br /&gt;
&lt;br /&gt;
If the error is stopping you even getting to the admin screens to turn on debugging, then you can set the debugging setting manually.&lt;br /&gt;
&lt;br /&gt;
===Try typing the URL directly===&lt;br /&gt;
&lt;br /&gt;
The debug settings are at the URL &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://.../admin/settings.php?section=debugging&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; on your server. Sometimes that URL will work, even though the pages you need to go to to get there (for example the site front page) do not. So it is worth trying to enter that URL directly.&lt;br /&gt;
&lt;br /&gt;
===In config.php===&lt;br /&gt;
&lt;br /&gt;
In moodle/config.php you can add the lines:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;debug = 2047; &lt;br /&gt;
$CFG-&amp;gt;debugdisplay = 1;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or even more debugging messages:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;debug = 6143; &lt;br /&gt;
$CFG-&amp;gt;debugdisplay = 1;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For Moodle 2.0 the possible settings are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Force a debugging mode regardless the settings in the site administration&lt;br /&gt;
// @error_reporting(1023);  // NOT FOR PRODUCTION SERVERS!&lt;br /&gt;
@ini_set(&#039;display_errors&#039;, &#039;1&#039;); // NOT FOR PRODUCTION SERVERS!&lt;br /&gt;
$CFG-&amp;gt;debug = 38911;  // DEBUG_DEVELOPER // NOT FOR PRODUCTION SERVERS!&lt;br /&gt;
$CFG-&amp;gt;debugdisplay = true;   // NOT FOR PRODUCTION SERVERS!&lt;br /&gt;
&lt;br /&gt;
// You can specify a comma separated list of user ids that that always see&lt;br /&gt;
// debug messages, this overrides the debug flag in $CFG-&amp;gt;debug and $CFG-&amp;gt;debugdisplay&lt;br /&gt;
// for these users only.&lt;br /&gt;
$CFG-&amp;gt;debugusers = &#039;2&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remember to remove those lines again when you have finished diagnosing your problem.&lt;br /&gt;
&lt;br /&gt;
===In the database===&lt;br /&gt;
&lt;br /&gt;
Using a tool like phpMyAdmin, execute the following SQL commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code sql&amp;gt;&lt;br /&gt;
UPDATE mdl_config SET value = 2047 WHERE name = &#039;debug&#039;;&lt;br /&gt;
UPDATE mdl_config SET value = 1 WHERE name = &#039;debugdisplay&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To turn it back off, use the admin screens, or the commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code sql&amp;gt;&lt;br /&gt;
UPDATE mdl_config SET value = 0 WHERE name = &#039;debug&#039;;&lt;br /&gt;
UPDATE mdl_config SET value = 0 WHERE name = &#039;debugdisplay&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(If you use a different database prefix, you will need to adjust those commands accordingly.)&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/discuss.php?d=91031 Debugging Turned on to Developer Mode on 1.8.2] forum discussion including instructions on how to turn debugging off&lt;br /&gt;
&lt;br /&gt;
[[Category:Administrator]]&lt;br /&gt;
&lt;br /&gt;
[[fr:Débogage]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/19/en/index.php?title=Debugging&amp;diff=79593</id>
		<title>Debugging</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/19/en/index.php?title=Debugging&amp;diff=79593"/>
		<updated>2010-12-22T09:24:23Z</updated>

		<summary type="html">&lt;p&gt;Howardsmiller: /* In config.php */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Location: &#039;&#039;Administration &amp;gt; Server &amp;gt; Debugging&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Debugging messages are intended to help diagnose problems and/or help Moodle developers. If you have a problem with your Moodle site and ask for help in a Moodle.org forum, a developer may ask you to turn debug messages on, in order to locate the cause of the problem. By default Moodle does not show any error messages at all. If you are having problems (e.g. blank screens or incomplete screens) turning on debugging is usually the first thing to try. &lt;br /&gt;
&lt;br /&gt;
==How to turn on debugging==&lt;br /&gt;
&lt;br /&gt;
Go into the admin screens, and look under Administration &amp;gt; Server &amp;gt; Debugging (In Moodle 2.0 it is Site administration ▶ Development ▶ Debugging). Set the...&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Debug messages&#039;&#039;&#039; to &#039;&#039;&#039;ALL&#039;&#039;&#039;, and &lt;br /&gt;
* &#039;&#039;&#039;Display debug messages&#039;&#039;&#039; to &#039;&#039;&#039;Yes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
(You &#039;&#039;&#039;must&#039;&#039;&#039; do both). There is rarely any advantage in going to Developer level, unless you are a developer, in which case it is strongly recommended.&lt;br /&gt;
&lt;br /&gt;
Once you have got the error message, and copied and pasted it somewhere, you are recommended to turn debugging back off again.&lt;br /&gt;
&lt;br /&gt;
==Debug messages==&lt;br /&gt;
&lt;br /&gt;
{{Moodle 1.7}}From Moodle 1.7 onwards, further options are provided for controlling how to handle PHP error messages. The administrator can select the types of error messages to be displayed or logged. &lt;br /&gt;
&lt;br /&gt;
The options for debugging include:&lt;br /&gt;
* NONE: Do not show any errors or warnings&lt;br /&gt;
* MINIMAL: Show only fatal errors&lt;br /&gt;
* NORMAL: Show errors, warnings and notices&lt;br /&gt;
* ALL: Show all reasonable PHP debug messages. When you want to find the cause of a problem with your site, this is probably best the setting to use.&lt;br /&gt;
* DEVELOPER: extra Moodle debug messages for developers - If you turn this on, then PHP&#039;s error_reporting will be increased so that more warnings are printed.  This is almost essential for developers, but not very helpful for anyone else.&lt;br /&gt;
&lt;br /&gt;
==Display debug messages==&lt;br /&gt;
&lt;br /&gt;
There is an option to choose whether to display error messages or simply record them in the server logs.&lt;br /&gt;
&lt;br /&gt;
==Debug email sending==&lt;br /&gt;
&lt;br /&gt;
Determines whether or not to enable verbose debug information during sending of email messages to SMTP server.&lt;br /&gt;
&lt;br /&gt;
==Performance info==&lt;br /&gt;
&lt;br /&gt;
The Performance info option determines whether performance info will be included in the footer of the standard theme (and some other themes). Performance info includes the time for the page to load, the amount of memory used to generate the page, cpu usage, load, and the record cache hit/miss ration.&lt;br /&gt;
&lt;br /&gt;
If you add&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
define(&#039;MDL_PERF&#039;, true);&lt;br /&gt;
define(&#039;MDL_PERFDB&#039;, true);&lt;br /&gt;
define(&#039;MDL_PERFTOLOG&#039;, true);&lt;br /&gt;
define(&#039;MDL_PERFTOFOOT&#039;, true);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
to your config.php file, then it will also count database queries. (This has to be in config.php, because Moodle starts doing DB queries before it loads the config information in the database!&lt;br /&gt;
&lt;br /&gt;
==What to do if you cannot get to the admin screens==&lt;br /&gt;
&lt;br /&gt;
If the error is stopping you even getting to the admin screens to turn on debugging, then you can set the debugging setting manually.&lt;br /&gt;
&lt;br /&gt;
===Try typing the URL directly===&lt;br /&gt;
&lt;br /&gt;
The debug settings are at the URL &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://.../admin/settings.php?section=debugging&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; on your server. Sometimes that URL will work, even though the pages you need to go to to get there (for example the site front page) do not. So it is worth trying to enter that URL directly.&lt;br /&gt;
&lt;br /&gt;
===In config.php===&lt;br /&gt;
&lt;br /&gt;
In moodle/config.php you can add the lines:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;debug = 2047; &lt;br /&gt;
$CFG-&amp;gt;debugdisplay = 1;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or even more debugging messages:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;debug = 6143; &lt;br /&gt;
$CFG-&amp;gt;debugdisplay = 1;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For Moodle 2.0 the possible settings are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php?&lt;br /&gt;
// Force a debugging mode regardless the settings in the site administration&lt;br /&gt;
// @error_reporting(1023);  // NOT FOR PRODUCTION SERVERS!&lt;br /&gt;
@ini_set(&#039;display_errors&#039;, &#039;1&#039;); // NOT FOR PRODUCTION SERVERS!&lt;br /&gt;
$CFG-&amp;gt;debug = 38911;  // DEBUG_DEVELOPER // NOT FOR PRODUCTION SERVERS!&lt;br /&gt;
$CFG-&amp;gt;debugdisplay = true;   // NOT FOR PRODUCTION SERVERS!&lt;br /&gt;
&lt;br /&gt;
// You can specify a comma separated list of user ids that that always see&lt;br /&gt;
// debug messages, this overrides the debug flag in $CFG-&amp;gt;debug and $CFG-&amp;gt;debugdisplay&lt;br /&gt;
// for these users only.&lt;br /&gt;
$CFG-&amp;gt;debugusers = &#039;2&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remember to remove those lines again when you have finished diagnosing your problem.&lt;br /&gt;
&lt;br /&gt;
===In the database===&lt;br /&gt;
&lt;br /&gt;
Using a tool like phpMyAdmin, execute the following SQL commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code sql&amp;gt;&lt;br /&gt;
UPDATE mdl_config SET value = 2047 WHERE name = &#039;debug&#039;;&lt;br /&gt;
UPDATE mdl_config SET value = 1 WHERE name = &#039;debugdisplay&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To turn it back off, use the admin screens, or the commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code sql&amp;gt;&lt;br /&gt;
UPDATE mdl_config SET value = 0 WHERE name = &#039;debug&#039;;&lt;br /&gt;
UPDATE mdl_config SET value = 0 WHERE name = &#039;debugdisplay&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(If you use a different database prefix, you will need to adjust those commands accordingly.)&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/discuss.php?d=91031 Debugging Turned on to Developer Mode on 1.8.2] forum discussion including instructions on how to turn debugging off&lt;br /&gt;
&lt;br /&gt;
[[Category:Administrator]]&lt;br /&gt;
&lt;br /&gt;
[[fr:Débogage]]&lt;/div&gt;</summary>
		<author><name>Howardsmiller</name></author>
	</entry>
</feed>