<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.moodle.org/24/en/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Samhemelryk</id>
	<title>MoodleDocs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.moodle.org/24/en/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Samhemelryk"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/Special:Contributions/Samhemelryk"/>
	<updated>2026-05-09T01:55:43Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk&amp;diff=90078</id>
		<title>User:Sam Hemelryk</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk&amp;diff=90078"/>
		<updated>2011-09-23T02:47:09Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: Replaced content with &amp;quot;Hi, I maintain my profile on the dev wiki.
You can find it here:

https://docs.moodle.org/dev/User:Sam_Hemelryk&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi, I maintain my profile on the dev wiki.&lt;br /&gt;
You can find it here:&lt;br /&gt;
&lt;br /&gt;
https://docs.moodle.org/dev/User:Sam_Hemelryk&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=90077</id>
		<title>User:Sam Hemelryk/My Moodle Git workflow</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=90077"/>
		<updated>2011-09-23T02:30:50Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: Replaced content with &amp;quot;Hi, this doc has previously existed in a couple of locations and has now been consolidated to just one location.
You can now find it here:

https://docs.moodle.org/dev/User:Sa...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi, this doc has previously existed in a couple of locations and has now been consolidated to just one location.&lt;br /&gt;
You can now find it here:&lt;br /&gt;
&lt;br /&gt;
https://docs.moodle.org/dev/User:Sam_Hemelryk/My_Moodle_Git_workflow&lt;br /&gt;
&lt;br /&gt;
PLEASE DO NOT EDIT THIS PAGE, feel free to edit the linked page above.&lt;br /&gt;
&lt;br /&gt;
Cheers&lt;br /&gt;
Sam&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_adding_courses_and_categories_to_the_custom_menu&amp;diff=83288</id>
		<title>Development:Themes 2.0 adding courses and categories to the custom menu</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_adding_courses_and_categories_to_the_custom_menu&amp;diff=83288"/>
		<updated>2011-05-06T03:17:56Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* A word of warning */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello this is going to be a very brief tutorial on how to add a courses and categories tree to the custom menu.&amp;lt;br /&amp;gt;&lt;br /&gt;
The reason for writing this tutorial is simply that this seems to be a request that is being made over and over again.&lt;br /&gt;
&lt;br /&gt;
==Before we get started==&lt;br /&gt;
Please please please make sure you are familiar with the other Themes 2.0 tutorials before attempting this tutorial.&lt;br /&gt;
&lt;br /&gt;
In particular I would recommend being familiar with the following documents and tutorials as I&#039;m going to move through this tutorial at a fast pace.&lt;br /&gt;
&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]]&lt;br /&gt;
* [[Development:Themes 2.0 overriding a renderer]]&lt;br /&gt;
* [[Development:Themes 2.0 extending the custom menu]]&lt;br /&gt;
&lt;br /&gt;
Providing you are familiar with the above you should manage just fine with this tutorial and if you ever get stuck don&#039;t forget to ask in the theme&#039;s forums, there is always someone around who can help.&lt;br /&gt;
&lt;br /&gt;
===Two words of warning===&lt;br /&gt;
&#039;&#039;&#039;First&#039;&#039;&#039; Just a quick warning here, this tutorial adds all categories and courses to the navigation, on a site with a large number of categories and/or courses this will be a performance hit. I would strongly suggest that if you are looking to implement something such as this on a large site that you talk to your system admin and/or resident developer about setting up a shared cache and caching the result of the get_course_category_tree method... it is a technical task but doing so will improve the performance of this extension on a large site.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Second&#039;&#039;&#039; If you have categories nested 2 or more deep then there is a chance that you will run into display problems with the custom menu on some themes... not too much you can do about it but if you encounter it with a core theme and you fix it perhaps you would be kind enough to create an issue in our bug tracker and share the fix. That&#039;d being said this is only a hunch I have all of the theme&#039;s may be fine :)&lt;br /&gt;
&lt;br /&gt;
==Laying the ground work==&lt;br /&gt;
Alright I don&#039;t want this tutorial to drag out so get ready. For this tutorial I am just going to extend the standard theme, I&#039;m going to make absolutely no changes to the design and layout of the theme or the custom menu I am ONLY going to add a list of courses and categories to it.&lt;br /&gt;
&lt;br /&gt;
So to begin with within your Moodle themes directory create a new directory coursecategorymenu in which I want you to create three files, the first config.php which is obviously required, the second renderers.php as we are going to achieve this by overriding a renderer, and the third the English language file for this theme.&lt;br /&gt;
&lt;br /&gt;
You should end up with:&lt;br /&gt;
&lt;br /&gt;
* moodle/theme/coursecategorymenu&lt;br /&gt;
* moodle/theme/coursecategorymenu/config.php&lt;br /&gt;
* moodle/theme/coursecategorymenu/renderers.php&lt;br /&gt;
* moodle/theme/coursecategorymenu/lang/en/theme_coursecategorymenu.php&lt;br /&gt;
&lt;br /&gt;
==config.php==&lt;br /&gt;
Obviously because all I want to base this theme off the standard theme and only override a renderer the config.php file is going to be VERY basic, so much so that I&#039;m not going to go into details about it, as you&#039;ve read the recommended tutorials you will already be completely familiar with everything it is doing.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;name = &#039;coursecategorymenu&#039;;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;, &#039;base&#039;);&lt;br /&gt;
$THEME-&amp;gt;rendererfactory = &#039;theme_overridden_renderer_factory&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==renderers.php==&lt;br /&gt;
This is of course where the magic is going to happen.&lt;br /&gt;
&lt;br /&gt;
In my case I want to add a branch to the end of the custom menu titled &#039;&#039;Courses&#039;&#039; and then I want to add the category and course structure to that branch.&lt;br /&gt;
&lt;br /&gt;
So like the [[Development:Themes 2.0 extending the custom menu|extending the custom menu]] tutorial I will be overriding the core renderer and I will also be overriding the render_custom_menu_method.&lt;br /&gt;
&lt;br /&gt;
So the code for this:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
class theme_coursecategorymenu_core_renderer extends core_renderer {&lt;br /&gt;
 &lt;br /&gt;
    protected function render_custom_menu(custom_menu $menu) {&lt;br /&gt;
        // Our code will go here shortly&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice that is identical to the starting code for the extending custom menu tutorial.&lt;br /&gt;
&lt;br /&gt;
The difference comes in the code that we are going to populate it with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
require_once($CFG-&amp;gt;dirroot.&#039;/course/lib.php&#039;);&lt;br /&gt;
        &lt;br /&gt;
$branch = $menu-&amp;gt;add(get_string(&#039;courses&#039;, &#039;theme_coursecategorymenu&#039;), null, null, 10000);&lt;br /&gt;
&lt;br /&gt;
$categorytree = get_course_category_tree();&lt;br /&gt;
foreach ($categorytree as $category) {&lt;br /&gt;
    $this-&amp;gt;add_category_to_custommenu($branch, $category);&lt;br /&gt;
}&lt;br /&gt;
        &lt;br /&gt;
return parent::render_custom_menu($menu);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So lets work through this code line by line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
require_once($CFG-&amp;gt;dirroot.&#039;/course/lib.php&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This we need to do because we are going to use part of the course API, in particular a function called &#039;&#039;get_course_category_tree()&#039;&#039; that we&#039;ll look at shortly.&lt;br /&gt;
The function we want to use exists within the course lib file and in order to be sure its always available we need to include this file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$branch = $menu-&amp;gt;add(get_string(&#039;courses&#039;, &#039;theme_coursecategorymenu&#039;), null, null, 10000);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This line adds the &#039;&#039;Courses&#039;&#039; branch to the custom menu into which we will add the category and course structure.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$categorytree = get_course_category_tree();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This line is the main one to note, here we are calling a Moodle function that will return us a category and course tree, because all courses need to be within a category the initial return is an array of categories, each category in the array will have the properties of the category as well as two additional properties, the first property &#039;&#039;&#039;categories&#039;&#039;&#039; is an array containing all of this categories sub categories, and the second property &#039;&#039;&#039;courses&#039;&#039;&#039; is also an array containing all of the courses within this category.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$categorytree = get_course_category_tree();&lt;br /&gt;
foreach ($categorytree as $category) {&lt;br /&gt;
    $this-&amp;gt;add_category_to_custommenu($branch, $category);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now these lines of code deal with the initial array of categories returned by the &#039;&#039;get_course_category_tree&#039;&#039; function.&lt;br /&gt;
&lt;br /&gt;
In this case we iterate of the initial categories and for each one we call a method of the renderer &#039;&#039;&#039;add_category_to_custommenu&#039;&#039;&#039; now those of you who are clued in will realise that this method doesn&#039;t exist yet... and you are correct - we need to write this method which is what we will look at next.&amp;lt;br /&amp;gt;&lt;br /&gt;
As a heads up the reason that we need to write another method is because we need a method that we can call recursivily as there are potentially infinite category branches all contains sub categories and courses.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
return parent::render_custom_menu($menu);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final line of code simply calls the original render_custom_menu method now that we have extended the custom menu as we want.&lt;br /&gt;
&lt;br /&gt;
Now that we have looked at the render_custom_menu lets write the function we just talked about &#039;&#039;&#039;add_category_to_custommenu&#039;&#039;&#039;.&amp;lt;br /&amp;gt;&lt;br /&gt;
This function as discussed above is special in that we intend to call it recursively, that means we want to call it once for EVERY category that exists in the tree. We will need to give it the categories parent menu item as well as the category object we want added.&lt;br /&gt;
&lt;br /&gt;
Lets look at the code for this method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
protected function add_category_to_custommenu(custom_menu_item $parent, stdClass $category) {&lt;br /&gt;
    $branch = $parent-&amp;gt;add($category-&amp;gt;name, new moodle_url(&#039;/course/category.php&#039;, array(&#039;id&#039; =&amp;gt;  $category-&amp;gt;id)));&lt;br /&gt;
    if (!empty($category-&amp;gt;categories)) {&lt;br /&gt;
        foreach ($category-&amp;gt;categories as $subcategory) {&lt;br /&gt;
            $this-&amp;gt;add_category_to_custommenu($branch, $subcategory);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    if (!empty($category-&amp;gt;courses)) {&lt;br /&gt;
        foreach ($category-&amp;gt;courses as $course) {&lt;br /&gt;
            $branch-&amp;gt;add($course-&amp;gt;shortname, new moodle_url(&#039;/course/view.php&#039;, array(&#039;id&#039; =&amp;gt; $course-&amp;gt;id)), $course-&amp;gt;fullname);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ok so that doesn&#039;t look too bad, as you&#039;ve already read the extending custom menu tutorial you will be able to spot some of the things it is doing, none the less lets walk through the code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
protected function add_category_to_custommenu(custom_menu_item $parent, stdClass $category) {&lt;br /&gt;
    .....&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First up the function definition, this function is going to be private because only we need it and it is going to take two arguments, the first $parent has to be a custom_menu_item, the second $category has to be the category object.&lt;br /&gt;
&lt;br /&gt;
The objective of this method is to add a category node to the custom menu, in regards to our arguments we want to add $category as a child of $parent.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$branch = $parent-&amp;gt;add($category-&amp;gt;name, new moodle_url(&#039;/course/category.php&#039;, array(&#039;id&#039; =&amp;gt;  $category-&amp;gt;id)));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This line looks very familiar, here we are adding a node for the category to the $parent, we are also collecting the newly added node as $branch.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($category-&amp;gt;categories)) {&lt;br /&gt;
    foreach ($category-&amp;gt;categories as $subcategory) {&lt;br /&gt;
        $this-&amp;gt;add_category_to_custommenu($branch, $subcategory);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now this code is responsible for add the sub categories of this category to the menu as well, first we need to check that the categories property isn&#039;t empty (if it is there is nothing to add).&lt;br /&gt;
Assuming there are sub categories we need go through each of them and call this method on them so that they get added to the custom menu as well.&amp;lt;br /&amp;gt;&lt;br /&gt;
This is called recursion.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($category-&amp;gt;courses)) {&lt;br /&gt;
    foreach ($category-&amp;gt;courses as $course) {&lt;br /&gt;
        $branch-&amp;gt;add($course-&amp;gt;shortname, new moodle_url(&#039;/course/view.php&#039;, array(&#039;id&#039; =&amp;gt; $course-&amp;gt;id)), $course-&amp;gt;fullname);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This code is very similar to the above code except that we are looking at the courses within this category.&amp;lt;br /&amp;gt;&lt;br /&gt;
Also note that this bit of code doesn&#039;t call add_category_to_custommenu recursivily, it doesn&#039;t need to as courses are the last bit we want to display on the menu within the category.&lt;br /&gt;
&lt;br /&gt;
And that is it, time to tidy up and we&#039;re done.&lt;br /&gt;
&lt;br /&gt;
==Finishing up==&lt;br /&gt;
All of the code is written now there is only last thing to do in order to tidy up however and that is to add the &#039;&#039;courses&#039;&#039; string that we used earlier... did you spot it?&lt;br /&gt;
&lt;br /&gt;
This is of course very easy, open up &#039;&#039;&#039;moodle/theme/coursecategorymenu/lang/en/theme_coursecategorymenu.php&#039;&#039;&#039; and add the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
$string[&#039;courses&#039;] = &#039;Courses&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And we&#039;re done. If you now browse to your site and change to the new theme you should see the Courses branch at the end of your custom menu that contains all of the categories, sub categories and courses for your site.&lt;br /&gt;
&lt;br /&gt;
==Full source==&lt;br /&gt;
===config.php===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;name = &#039;coursecategorymenu&#039;;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;, &#039;base&#039;);&lt;br /&gt;
$THEME-&amp;gt;rendererfactory = &#039;theme_overridden_renderer_factory&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
===renderers.php===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
class theme_coursecategorymenu_core_renderer extends core_renderer {&lt;br /&gt;
 &lt;br /&gt;
    protected function render_custom_menu(custom_menu $menu) {&lt;br /&gt;
        global $CFG;&lt;br /&gt;
        &lt;br /&gt;
        require_once($CFG-&amp;gt;dirroot.&#039;/course/lib.php&#039;);&lt;br /&gt;
        &lt;br /&gt;
        $branch = $menu-&amp;gt;add(get_string(&#039;courses&#039;, &#039;theme_coursecategorymenu&#039;), null, null, 10000);&lt;br /&gt;
        &lt;br /&gt;
        $categorytree = get_course_category_tree();&lt;br /&gt;
        foreach ($categorytree as $category) {&lt;br /&gt;
            $this-&amp;gt;add_category_to_custommenu($branch, $category);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return parent::render_custom_menu($menu);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    protected function add_category_to_custommenu(custom_menu_item $parent, stdClass $category) {&lt;br /&gt;
        $branch = $parent-&amp;gt;add($category-&amp;gt;name, new moodle_url(&#039;/course/category.php&#039;, array(&#039;id&#039; =&amp;gt;  $category-&amp;gt;id)));&lt;br /&gt;
        if (!empty($category-&amp;gt;categories)) {&lt;br /&gt;
            foreach ($category-&amp;gt;categories as $subcategory) {&lt;br /&gt;
                $this-&amp;gt;add_category_to_custommenu($branch, $subcategory);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if (!empty($category-&amp;gt;courses)) {&lt;br /&gt;
            foreach ($category-&amp;gt;courses as $course) {&lt;br /&gt;
                $branch-&amp;gt;add($course-&amp;gt;shortname, new moodle_url(&#039;/course/view.php&#039;, array(&#039;id&#039; =&amp;gt; $course-&amp;gt;id)), $course-&amp;gt;fullname);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
===lang/en/theme_coursecategorymenu.php===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
$string[&#039;courses&#039;] = &#039;Courses&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]]&lt;br /&gt;
* [[Development:Themes 2.0 overriding a renderer]]&lt;br /&gt;
* [[Development:Themes 2.0 extending the custom menu]]&lt;br /&gt;
* [http://developer.yahoo.com/yui/3/node-menunav/ YUI 3 Menunav component the custom menu uses]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_adding_courses_and_categories_to_the_custom_menu&amp;diff=83287</id>
		<title>Development:Themes 2.0 adding courses and categories to the custom menu</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_adding_courses_and_categories_to_the_custom_menu&amp;diff=83287"/>
		<updated>2011-05-06T03:11:50Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* Before we get started */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello this is going to be a very brief tutorial on how to add a courses and categories tree to the custom menu.&amp;lt;br /&amp;gt;&lt;br /&gt;
The reason for writing this tutorial is simply that this seems to be a request that is being made over and over again.&lt;br /&gt;
&lt;br /&gt;
==Before we get started==&lt;br /&gt;
Please please please make sure you are familiar with the other Themes 2.0 tutorials before attempting this tutorial.&lt;br /&gt;
&lt;br /&gt;
In particular I would recommend being familiar with the following documents and tutorials as I&#039;m going to move through this tutorial at a fast pace.&lt;br /&gt;
&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]]&lt;br /&gt;
* [[Development:Themes 2.0 overriding a renderer]]&lt;br /&gt;
* [[Development:Themes 2.0 extending the custom menu]]&lt;br /&gt;
&lt;br /&gt;
Providing you are familiar with the above you should manage just fine with this tutorial and if you ever get stuck don&#039;t forget to ask in the theme&#039;s forums, there is always someone around who can help.&lt;br /&gt;
&lt;br /&gt;
===A word of warning===&lt;br /&gt;
Just a quick warning here, this tutorial adds all categories and courses to the navigation, on a site with a large number of categories and/or courses this will be a performance hit. I would strongly suggest that if you are looking to implement something such as this on a large site that you talk to your system admin and/or resident developer about setting up a shared cache and caching the result of the get_course_category_tree method... it is a technical task but doing so will improve the performance of this extension on a large site.&lt;br /&gt;
&lt;br /&gt;
==Laying the ground work==&lt;br /&gt;
Alright I don&#039;t want this tutorial to drag out so get ready. For this tutorial I am just going to extend the standard theme, I&#039;m going to make absolutely no changes to the design and layout of the theme or the custom menu I am ONLY going to add a list of courses and categories to it.&lt;br /&gt;
&lt;br /&gt;
So to begin with within your Moodle themes directory create a new directory coursecategorymenu in which I want you to create three files, the first config.php which is obviously required, the second renderers.php as we are going to achieve this by overriding a renderer, and the third the English language file for this theme.&lt;br /&gt;
&lt;br /&gt;
You should end up with:&lt;br /&gt;
&lt;br /&gt;
* moodle/theme/coursecategorymenu&lt;br /&gt;
* moodle/theme/coursecategorymenu/config.php&lt;br /&gt;
* moodle/theme/coursecategorymenu/renderers.php&lt;br /&gt;
* moodle/theme/coursecategorymenu/lang/en/theme_coursecategorymenu.php&lt;br /&gt;
&lt;br /&gt;
==config.php==&lt;br /&gt;
Obviously because all I want to base this theme off the standard theme and only override a renderer the config.php file is going to be VERY basic, so much so that I&#039;m not going to go into details about it, as you&#039;ve read the recommended tutorials you will already be completely familiar with everything it is doing.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;name = &#039;coursecategorymenu&#039;;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;, &#039;base&#039;);&lt;br /&gt;
$THEME-&amp;gt;rendererfactory = &#039;theme_overridden_renderer_factory&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==renderers.php==&lt;br /&gt;
This is of course where the magic is going to happen.&lt;br /&gt;
&lt;br /&gt;
In my case I want to add a branch to the end of the custom menu titled &#039;&#039;Courses&#039;&#039; and then I want to add the category and course structure to that branch.&lt;br /&gt;
&lt;br /&gt;
So like the [[Development:Themes 2.0 extending the custom menu|extending the custom menu]] tutorial I will be overriding the core renderer and I will also be overriding the render_custom_menu_method.&lt;br /&gt;
&lt;br /&gt;
So the code for this:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
class theme_coursecategorymenu_core_renderer extends core_renderer {&lt;br /&gt;
 &lt;br /&gt;
    protected function render_custom_menu(custom_menu $menu) {&lt;br /&gt;
        // Our code will go here shortly&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice that is identical to the starting code for the extending custom menu tutorial.&lt;br /&gt;
&lt;br /&gt;
The difference comes in the code that we are going to populate it with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
require_once($CFG-&amp;gt;dirroot.&#039;/course/lib.php&#039;);&lt;br /&gt;
        &lt;br /&gt;
$branch = $menu-&amp;gt;add(get_string(&#039;courses&#039;, &#039;theme_coursecategorymenu&#039;), null, null, 10000);&lt;br /&gt;
&lt;br /&gt;
$categorytree = get_course_category_tree();&lt;br /&gt;
foreach ($categorytree as $category) {&lt;br /&gt;
    $this-&amp;gt;add_category_to_custommenu($branch, $category);&lt;br /&gt;
}&lt;br /&gt;
        &lt;br /&gt;
return parent::render_custom_menu($menu);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So lets work through this code line by line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
require_once($CFG-&amp;gt;dirroot.&#039;/course/lib.php&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This we need to do because we are going to use part of the course API, in particular a function called &#039;&#039;get_course_category_tree()&#039;&#039; that we&#039;ll look at shortly.&lt;br /&gt;
The function we want to use exists within the course lib file and in order to be sure its always available we need to include this file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$branch = $menu-&amp;gt;add(get_string(&#039;courses&#039;, &#039;theme_coursecategorymenu&#039;), null, null, 10000);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This line adds the &#039;&#039;Courses&#039;&#039; branch to the custom menu into which we will add the category and course structure.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$categorytree = get_course_category_tree();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This line is the main one to note, here we are calling a Moodle function that will return us a category and course tree, because all courses need to be within a category the initial return is an array of categories, each category in the array will have the properties of the category as well as two additional properties, the first property &#039;&#039;&#039;categories&#039;&#039;&#039; is an array containing all of this categories sub categories, and the second property &#039;&#039;&#039;courses&#039;&#039;&#039; is also an array containing all of the courses within this category.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$categorytree = get_course_category_tree();&lt;br /&gt;
foreach ($categorytree as $category) {&lt;br /&gt;
    $this-&amp;gt;add_category_to_custommenu($branch, $category);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now these lines of code deal with the initial array of categories returned by the &#039;&#039;get_course_category_tree&#039;&#039; function.&lt;br /&gt;
&lt;br /&gt;
In this case we iterate of the initial categories and for each one we call a method of the renderer &#039;&#039;&#039;add_category_to_custommenu&#039;&#039;&#039; now those of you who are clued in will realise that this method doesn&#039;t exist yet... and you are correct - we need to write this method which is what we will look at next.&amp;lt;br /&amp;gt;&lt;br /&gt;
As a heads up the reason that we need to write another method is because we need a method that we can call recursivily as there are potentially infinite category branches all contains sub categories and courses.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
return parent::render_custom_menu($menu);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final line of code simply calls the original render_custom_menu method now that we have extended the custom menu as we want.&lt;br /&gt;
&lt;br /&gt;
Now that we have looked at the render_custom_menu lets write the function we just talked about &#039;&#039;&#039;add_category_to_custommenu&#039;&#039;&#039;.&amp;lt;br /&amp;gt;&lt;br /&gt;
This function as discussed above is special in that we intend to call it recursively, that means we want to call it once for EVERY category that exists in the tree. We will need to give it the categories parent menu item as well as the category object we want added.&lt;br /&gt;
&lt;br /&gt;
Lets look at the code for this method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
protected function add_category_to_custommenu(custom_menu_item $parent, stdClass $category) {&lt;br /&gt;
    $branch = $parent-&amp;gt;add($category-&amp;gt;name, new moodle_url(&#039;/course/category.php&#039;, array(&#039;id&#039; =&amp;gt;  $category-&amp;gt;id)));&lt;br /&gt;
    if (!empty($category-&amp;gt;categories)) {&lt;br /&gt;
        foreach ($category-&amp;gt;categories as $subcategory) {&lt;br /&gt;
            $this-&amp;gt;add_category_to_custommenu($branch, $subcategory);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    if (!empty($category-&amp;gt;courses)) {&lt;br /&gt;
        foreach ($category-&amp;gt;courses as $course) {&lt;br /&gt;
            $branch-&amp;gt;add($course-&amp;gt;shortname, new moodle_url(&#039;/course/view.php&#039;, array(&#039;id&#039; =&amp;gt; $course-&amp;gt;id)), $course-&amp;gt;fullname);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ok so that doesn&#039;t look too bad, as you&#039;ve already read the extending custom menu tutorial you will be able to spot some of the things it is doing, none the less lets walk through the code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
protected function add_category_to_custommenu(custom_menu_item $parent, stdClass $category) {&lt;br /&gt;
    .....&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First up the function definition, this function is going to be private because only we need it and it is going to take two arguments, the first $parent has to be a custom_menu_item, the second $category has to be the category object.&lt;br /&gt;
&lt;br /&gt;
The objective of this method is to add a category node to the custom menu, in regards to our arguments we want to add $category as a child of $parent.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$branch = $parent-&amp;gt;add($category-&amp;gt;name, new moodle_url(&#039;/course/category.php&#039;, array(&#039;id&#039; =&amp;gt;  $category-&amp;gt;id)));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This line looks very familiar, here we are adding a node for the category to the $parent, we are also collecting the newly added node as $branch.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($category-&amp;gt;categories)) {&lt;br /&gt;
    foreach ($category-&amp;gt;categories as $subcategory) {&lt;br /&gt;
        $this-&amp;gt;add_category_to_custommenu($branch, $subcategory);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now this code is responsible for add the sub categories of this category to the menu as well, first we need to check that the categories property isn&#039;t empty (if it is there is nothing to add).&lt;br /&gt;
Assuming there are sub categories we need go through each of them and call this method on them so that they get added to the custom menu as well.&amp;lt;br /&amp;gt;&lt;br /&gt;
This is called recursion.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($category-&amp;gt;courses)) {&lt;br /&gt;
    foreach ($category-&amp;gt;courses as $course) {&lt;br /&gt;
        $branch-&amp;gt;add($course-&amp;gt;shortname, new moodle_url(&#039;/course/view.php&#039;, array(&#039;id&#039; =&amp;gt; $course-&amp;gt;id)), $course-&amp;gt;fullname);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This code is very similar to the above code except that we are looking at the courses within this category.&amp;lt;br /&amp;gt;&lt;br /&gt;
Also note that this bit of code doesn&#039;t call add_category_to_custommenu recursivily, it doesn&#039;t need to as courses are the last bit we want to display on the menu within the category.&lt;br /&gt;
&lt;br /&gt;
And that is it, time to tidy up and we&#039;re done.&lt;br /&gt;
&lt;br /&gt;
==Finishing up==&lt;br /&gt;
All of the code is written now there is only last thing to do in order to tidy up however and that is to add the &#039;&#039;courses&#039;&#039; string that we used earlier... did you spot it?&lt;br /&gt;
&lt;br /&gt;
This is of course very easy, open up &#039;&#039;&#039;moodle/theme/coursecategorymenu/lang/en/theme_coursecategorymenu.php&#039;&#039;&#039; and add the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
$string[&#039;courses&#039;] = &#039;Courses&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And we&#039;re done. If you now browse to your site and change to the new theme you should see the Courses branch at the end of your custom menu that contains all of the categories, sub categories and courses for your site.&lt;br /&gt;
&lt;br /&gt;
==Full source==&lt;br /&gt;
===config.php===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;name = &#039;coursecategorymenu&#039;;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;, &#039;base&#039;);&lt;br /&gt;
$THEME-&amp;gt;rendererfactory = &#039;theme_overridden_renderer_factory&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
===renderers.php===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
class theme_coursecategorymenu_core_renderer extends core_renderer {&lt;br /&gt;
 &lt;br /&gt;
    protected function render_custom_menu(custom_menu $menu) {&lt;br /&gt;
        global $CFG;&lt;br /&gt;
        &lt;br /&gt;
        require_once($CFG-&amp;gt;dirroot.&#039;/course/lib.php&#039;);&lt;br /&gt;
        &lt;br /&gt;
        $branch = $menu-&amp;gt;add(get_string(&#039;courses&#039;, &#039;theme_coursecategorymenu&#039;), null, null, 10000);&lt;br /&gt;
        &lt;br /&gt;
        $categorytree = get_course_category_tree();&lt;br /&gt;
        foreach ($categorytree as $category) {&lt;br /&gt;
            $this-&amp;gt;add_category_to_custommenu($branch, $category);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return parent::render_custom_menu($menu);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    protected function add_category_to_custommenu(custom_menu_item $parent, stdClass $category) {&lt;br /&gt;
        $branch = $parent-&amp;gt;add($category-&amp;gt;name, new moodle_url(&#039;/course/category.php&#039;, array(&#039;id&#039; =&amp;gt;  $category-&amp;gt;id)));&lt;br /&gt;
        if (!empty($category-&amp;gt;categories)) {&lt;br /&gt;
            foreach ($category-&amp;gt;categories as $subcategory) {&lt;br /&gt;
                $this-&amp;gt;add_category_to_custommenu($branch, $subcategory);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if (!empty($category-&amp;gt;courses)) {&lt;br /&gt;
            foreach ($category-&amp;gt;courses as $course) {&lt;br /&gt;
                $branch-&amp;gt;add($course-&amp;gt;shortname, new moodle_url(&#039;/course/view.php&#039;, array(&#039;id&#039; =&amp;gt; $course-&amp;gt;id)), $course-&amp;gt;fullname);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
===lang/en/theme_coursecategorymenu.php===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
$string[&#039;courses&#039;] = &#039;Courses&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]]&lt;br /&gt;
* [[Development:Themes 2.0 overriding a renderer]]&lt;br /&gt;
* [[Development:Themes 2.0 extending the custom menu]]&lt;br /&gt;
* [http://developer.yahoo.com/yui/3/node-menunav/ YUI 3 Menunav component the custom menu uses]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk&amp;diff=83286</id>
		<title>User:Sam Hemelryk</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk&amp;diff=83286"/>
		<updated>2011-05-06T03:03:21Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello, I am a senior developer at Moodle and have been with the project since the June 2009.&lt;br /&gt;
&lt;br /&gt;
For those interested I have written a tutorial on my Moodle development process with Git: [[User:Sam_Hemelryk/My_Moodle_Git_workflow]]&lt;br /&gt;
&lt;br /&gt;
A short list of helpful documents I have created:&lt;br /&gt;
&lt;br /&gt;
* [[Development:Themes 2.0]]&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:Using jQuery with Moodle 2.0]]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_adding_courses_and_categories_to_the_custom_menu&amp;diff=83285</id>
		<title>Development:Themes 2.0 adding courses and categories to the custom menu</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_adding_courses_and_categories_to_the_custom_menu&amp;diff=83285"/>
		<updated>2011-05-06T03:02:43Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* See also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello this is going to be a very brief tutorial on how to add a courses and categories tree to the custom menu.&amp;lt;br /&amp;gt;&lt;br /&gt;
The reason for writing this tutorial is simply that this seems to be a request that is being made over and over again.&lt;br /&gt;
&lt;br /&gt;
==Before we get started==&lt;br /&gt;
Please please please make sure you are familiar with the other Themes 2.0 tutorials before attempting this tutorial.&lt;br /&gt;
&lt;br /&gt;
In particular I would recommend being familiar with the following documents and tutorials as I&#039;m going to move through this tutorial at a fast pace.&lt;br /&gt;
&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]]&lt;br /&gt;
* [[Development:Themes 2.0 overriding a renderer]]&lt;br /&gt;
* [[Development:Themes 2.0 extending the custom menu]]&lt;br /&gt;
&lt;br /&gt;
Providing you are familiar with the above you should manage just fine with this tutorial and if you ever get stuck don&#039;t forget to ask in the theme&#039;s forums, there is always someone around who can help.&lt;br /&gt;
&lt;br /&gt;
==Laying the ground work==&lt;br /&gt;
Alright I don&#039;t want this tutorial to drag out so get ready. For this tutorial I am just going to extend the standard theme, I&#039;m going to make absolutely no changes to the design and layout of the theme or the custom menu I am ONLY going to add a list of courses and categories to it.&lt;br /&gt;
&lt;br /&gt;
So to begin with within your Moodle themes directory create a new directory coursecategorymenu in which I want you to create three files, the first config.php which is obviously required, the second renderers.php as we are going to achieve this by overriding a renderer, and the third the English language file for this theme.&lt;br /&gt;
&lt;br /&gt;
You should end up with:&lt;br /&gt;
&lt;br /&gt;
* moodle/theme/coursecategorymenu&lt;br /&gt;
* moodle/theme/coursecategorymenu/config.php&lt;br /&gt;
* moodle/theme/coursecategorymenu/renderers.php&lt;br /&gt;
* moodle/theme/coursecategorymenu/lang/en/theme_coursecategorymenu.php&lt;br /&gt;
&lt;br /&gt;
==config.php==&lt;br /&gt;
Obviously because all I want to base this theme off the standard theme and only override a renderer the config.php file is going to be VERY basic, so much so that I&#039;m not going to go into details about it, as you&#039;ve read the recommended tutorials you will already be completely familiar with everything it is doing.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;name = &#039;coursecategorymenu&#039;;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;, &#039;base&#039;);&lt;br /&gt;
$THEME-&amp;gt;rendererfactory = &#039;theme_overridden_renderer_factory&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==renderers.php==&lt;br /&gt;
This is of course where the magic is going to happen.&lt;br /&gt;
&lt;br /&gt;
In my case I want to add a branch to the end of the custom menu titled &#039;&#039;Courses&#039;&#039; and then I want to add the category and course structure to that branch.&lt;br /&gt;
&lt;br /&gt;
So like the [[Development:Themes 2.0 extending the custom menu|extending the custom menu]] tutorial I will be overriding the core renderer and I will also be overriding the render_custom_menu_method.&lt;br /&gt;
&lt;br /&gt;
So the code for this:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
class theme_coursecategorymenu_core_renderer extends core_renderer {&lt;br /&gt;
 &lt;br /&gt;
    protected function render_custom_menu(custom_menu $menu) {&lt;br /&gt;
        // Our code will go here shortly&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice that is identical to the starting code for the extending custom menu tutorial.&lt;br /&gt;
&lt;br /&gt;
The difference comes in the code that we are going to populate it with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
require_once($CFG-&amp;gt;dirroot.&#039;/course/lib.php&#039;);&lt;br /&gt;
        &lt;br /&gt;
$branch = $menu-&amp;gt;add(get_string(&#039;courses&#039;, &#039;theme_coursecategorymenu&#039;), null, null, 10000);&lt;br /&gt;
&lt;br /&gt;
$categorytree = get_course_category_tree();&lt;br /&gt;
foreach ($categorytree as $category) {&lt;br /&gt;
    $this-&amp;gt;add_category_to_custommenu($branch, $category);&lt;br /&gt;
}&lt;br /&gt;
        &lt;br /&gt;
return parent::render_custom_menu($menu);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So lets work through this code line by line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
require_once($CFG-&amp;gt;dirroot.&#039;/course/lib.php&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This we need to do because we are going to use part of the course API, in particular a function called &#039;&#039;get_course_category_tree()&#039;&#039; that we&#039;ll look at shortly.&lt;br /&gt;
The function we want to use exists within the course lib file and in order to be sure its always available we need to include this file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$branch = $menu-&amp;gt;add(get_string(&#039;courses&#039;, &#039;theme_coursecategorymenu&#039;), null, null, 10000);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This line adds the &#039;&#039;Courses&#039;&#039; branch to the custom menu into which we will add the category and course structure.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$categorytree = get_course_category_tree();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This line is the main one to note, here we are calling a Moodle function that will return us a category and course tree, because all courses need to be within a category the initial return is an array of categories, each category in the array will have the properties of the category as well as two additional properties, the first property &#039;&#039;&#039;categories&#039;&#039;&#039; is an array containing all of this categories sub categories, and the second property &#039;&#039;&#039;courses&#039;&#039;&#039; is also an array containing all of the courses within this category.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$categorytree = get_course_category_tree();&lt;br /&gt;
foreach ($categorytree as $category) {&lt;br /&gt;
    $this-&amp;gt;add_category_to_custommenu($branch, $category);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now these lines of code deal with the initial array of categories returned by the &#039;&#039;get_course_category_tree&#039;&#039; function.&lt;br /&gt;
&lt;br /&gt;
In this case we iterate of the initial categories and for each one we call a method of the renderer &#039;&#039;&#039;add_category_to_custommenu&#039;&#039;&#039; now those of you who are clued in will realise that this method doesn&#039;t exist yet... and you are correct - we need to write this method which is what we will look at next.&amp;lt;br /&amp;gt;&lt;br /&gt;
As a heads up the reason that we need to write another method is because we need a method that we can call recursivily as there are potentially infinite category branches all contains sub categories and courses.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
return parent::render_custom_menu($menu);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final line of code simply calls the original render_custom_menu method now that we have extended the custom menu as we want.&lt;br /&gt;
&lt;br /&gt;
Now that we have looked at the render_custom_menu lets write the function we just talked about &#039;&#039;&#039;add_category_to_custommenu&#039;&#039;&#039;.&amp;lt;br /&amp;gt;&lt;br /&gt;
This function as discussed above is special in that we intend to call it recursively, that means we want to call it once for EVERY category that exists in the tree. We will need to give it the categories parent menu item as well as the category object we want added.&lt;br /&gt;
&lt;br /&gt;
Lets look at the code for this method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
protected function add_category_to_custommenu(custom_menu_item $parent, stdClass $category) {&lt;br /&gt;
    $branch = $parent-&amp;gt;add($category-&amp;gt;name, new moodle_url(&#039;/course/category.php&#039;, array(&#039;id&#039; =&amp;gt;  $category-&amp;gt;id)));&lt;br /&gt;
    if (!empty($category-&amp;gt;categories)) {&lt;br /&gt;
        foreach ($category-&amp;gt;categories as $subcategory) {&lt;br /&gt;
            $this-&amp;gt;add_category_to_custommenu($branch, $subcategory);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    if (!empty($category-&amp;gt;courses)) {&lt;br /&gt;
        foreach ($category-&amp;gt;courses as $course) {&lt;br /&gt;
            $branch-&amp;gt;add($course-&amp;gt;shortname, new moodle_url(&#039;/course/view.php&#039;, array(&#039;id&#039; =&amp;gt; $course-&amp;gt;id)), $course-&amp;gt;fullname);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ok so that doesn&#039;t look too bad, as you&#039;ve already read the extending custom menu tutorial you will be able to spot some of the things it is doing, none the less lets walk through the code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
protected function add_category_to_custommenu(custom_menu_item $parent, stdClass $category) {&lt;br /&gt;
    .....&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First up the function definition, this function is going to be private because only we need it and it is going to take two arguments, the first $parent has to be a custom_menu_item, the second $category has to be the category object.&lt;br /&gt;
&lt;br /&gt;
The objective of this method is to add a category node to the custom menu, in regards to our arguments we want to add $category as a child of $parent.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$branch = $parent-&amp;gt;add($category-&amp;gt;name, new moodle_url(&#039;/course/category.php&#039;, array(&#039;id&#039; =&amp;gt;  $category-&amp;gt;id)));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This line looks very familiar, here we are adding a node for the category to the $parent, we are also collecting the newly added node as $branch.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($category-&amp;gt;categories)) {&lt;br /&gt;
    foreach ($category-&amp;gt;categories as $subcategory) {&lt;br /&gt;
        $this-&amp;gt;add_category_to_custommenu($branch, $subcategory);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now this code is responsible for add the sub categories of this category to the menu as well, first we need to check that the categories property isn&#039;t empty (if it is there is nothing to add).&lt;br /&gt;
Assuming there are sub categories we need go through each of them and call this method on them so that they get added to the custom menu as well.&amp;lt;br /&amp;gt;&lt;br /&gt;
This is called recursion.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($category-&amp;gt;courses)) {&lt;br /&gt;
    foreach ($category-&amp;gt;courses as $course) {&lt;br /&gt;
        $branch-&amp;gt;add($course-&amp;gt;shortname, new moodle_url(&#039;/course/view.php&#039;, array(&#039;id&#039; =&amp;gt; $course-&amp;gt;id)), $course-&amp;gt;fullname);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This code is very similar to the above code except that we are looking at the courses within this category.&amp;lt;br /&amp;gt;&lt;br /&gt;
Also note that this bit of code doesn&#039;t call add_category_to_custommenu recursivily, it doesn&#039;t need to as courses are the last bit we want to display on the menu within the category.&lt;br /&gt;
&lt;br /&gt;
And that is it, time to tidy up and we&#039;re done.&lt;br /&gt;
&lt;br /&gt;
==Finishing up==&lt;br /&gt;
All of the code is written now there is only last thing to do in order to tidy up however and that is to add the &#039;&#039;courses&#039;&#039; string that we used earlier... did you spot it?&lt;br /&gt;
&lt;br /&gt;
This is of course very easy, open up &#039;&#039;&#039;moodle/theme/coursecategorymenu/lang/en/theme_coursecategorymenu.php&#039;&#039;&#039; and add the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
$string[&#039;courses&#039;] = &#039;Courses&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And we&#039;re done. If you now browse to your site and change to the new theme you should see the Courses branch at the end of your custom menu that contains all of the categories, sub categories and courses for your site.&lt;br /&gt;
&lt;br /&gt;
==Full source==&lt;br /&gt;
===config.php===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;name = &#039;coursecategorymenu&#039;;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;, &#039;base&#039;);&lt;br /&gt;
$THEME-&amp;gt;rendererfactory = &#039;theme_overridden_renderer_factory&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
===renderers.php===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
class theme_coursecategorymenu_core_renderer extends core_renderer {&lt;br /&gt;
 &lt;br /&gt;
    protected function render_custom_menu(custom_menu $menu) {&lt;br /&gt;
        global $CFG;&lt;br /&gt;
        &lt;br /&gt;
        require_once($CFG-&amp;gt;dirroot.&#039;/course/lib.php&#039;);&lt;br /&gt;
        &lt;br /&gt;
        $branch = $menu-&amp;gt;add(get_string(&#039;courses&#039;, &#039;theme_coursecategorymenu&#039;), null, null, 10000);&lt;br /&gt;
        &lt;br /&gt;
        $categorytree = get_course_category_tree();&lt;br /&gt;
        foreach ($categorytree as $category) {&lt;br /&gt;
            $this-&amp;gt;add_category_to_custommenu($branch, $category);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return parent::render_custom_menu($menu);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    protected function add_category_to_custommenu(custom_menu_item $parent, stdClass $category) {&lt;br /&gt;
        $branch = $parent-&amp;gt;add($category-&amp;gt;name, new moodle_url(&#039;/course/category.php&#039;, array(&#039;id&#039; =&amp;gt;  $category-&amp;gt;id)));&lt;br /&gt;
        if (!empty($category-&amp;gt;categories)) {&lt;br /&gt;
            foreach ($category-&amp;gt;categories as $subcategory) {&lt;br /&gt;
                $this-&amp;gt;add_category_to_custommenu($branch, $subcategory);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if (!empty($category-&amp;gt;courses)) {&lt;br /&gt;
            foreach ($category-&amp;gt;courses as $course) {&lt;br /&gt;
                $branch-&amp;gt;add($course-&amp;gt;shortname, new moodle_url(&#039;/course/view.php&#039;, array(&#039;id&#039; =&amp;gt; $course-&amp;gt;id)), $course-&amp;gt;fullname);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
===lang/en/theme_coursecategorymenu.php===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
$string[&#039;courses&#039;] = &#039;Courses&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]]&lt;br /&gt;
* [[Development:Themes 2.0 overriding a renderer]]&lt;br /&gt;
* [[Development:Themes 2.0 extending the custom menu]]&lt;br /&gt;
* [http://developer.yahoo.com/yui/3/node-menunav/ YUI 3 Menunav component the custom menu uses]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_extending_the_custom_menu&amp;diff=83284</id>
		<title>Development:Themes 2.0 extending the custom menu</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_extending_the_custom_menu&amp;diff=83284"/>
		<updated>2011-05-06T03:02:19Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* See also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}{{Moodle 2.0}}This is a quick tutorial that will quickly run you through extending the custom menu by overriding your theme&#039;s renderer.&lt;br /&gt;
&lt;br /&gt;
This tutorial is primarily PHP coding, and ranges from is a moderate to advanced difficulty.&lt;br /&gt;
&lt;br /&gt;
==Before we begin==&lt;br /&gt;
First things first you need to know a little something about the custom menu. As you are undoubtedly aware the custom menu is populated from a specially crafted lines that you enter within the custommenu admin setting on the theme settings page under appearance in the settings block. Once the admin has entered the custom menu items into the setting and saved them the following steps are what they go through in order to be displayed:&lt;br /&gt;
# The theme calls &#039;&#039;&#039;&#039;&#039;$OUTPUT-&amp;gt;custom_menu()&#039;&#039;&#039;&#039;&#039; which is the core_renderers method responsible for producing the custom menu.&lt;br /&gt;
# core_renderer::custom_menu() does the following:&lt;br /&gt;
## Checks to make sure the admin has added custom menu items.&lt;br /&gt;
## Creates a new &#039;&#039;&#039;&#039;&#039;custom_menu&#039;&#039;&#039;&#039;&#039; object. When the custom menu object is created it turns what ever the admin entered into a structured array of information.&lt;br /&gt;
## Calls core_renderer::render_custom_menu and gives it the custom_menu object.&lt;br /&gt;
# core_renderer::render_custom_menu is where the magic happens, it does the following.&lt;br /&gt;
## First it checks to make sure custom menu contains items.&lt;br /&gt;
## Initialises the JavaScript for the custom menu, this is the YUI3 menunode component.&lt;br /&gt;
## Creates the HTML base of the custom menu&lt;br /&gt;
## Then iterates through all of the items and calls the custom menu and passes them to another function that will turn them into HTML correctly.&lt;br /&gt;
&lt;br /&gt;
I&#039;m going to stop there, as there is no need at this point to go into any more detail. Don&#039;t worry if you are a little lost, it will get clearer as we start working through code.&lt;br /&gt;
&lt;br /&gt;
In this tutorial will we look at how to extend the theme&#039;s renderer in two different way.&lt;br /&gt;
# Add a dynamic My Courses branch to the custom menu that will display all of the courses a user is enrolled in.&lt;br /&gt;
# Get the custom menu to fetch strings from the language files rather than just static strings you type, allowing for a translatable custom menu.&lt;br /&gt;
&lt;br /&gt;
Before you start into this tutorial you should have read the following tutorials I have written, or at least have a good knowledge of the the Moodle 2.0 theme engine and Moodle development.&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]]&lt;br /&gt;
* [[Development:Themes 2.0 overriding a renderer]]&lt;br /&gt;
&lt;br /&gt;
As this is a quick tutorial I am going to assume you have created a theme, tested it and got it all working, and are already well on your way to becoming a theme guru.&lt;br /&gt;
&lt;br /&gt;
Because the pressure is on to get Moodle 2.0 out the door this will be a quick tutorial, please if you have any questions or need a hand ask in the theme&#039;s forum.&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
Alright, as you have already have your theme ready to go preparation is pretty simple, we are going to go through and create (if you haven&#039;t already) the following files:&lt;br /&gt;
* theme/themename/lib.php&lt;br /&gt;
* theme/themename/renderers.php&lt;br /&gt;
* theme/themename/lang/en/themename.php&lt;br /&gt;
&lt;br /&gt;
Next step open up your themes config.php file and add the following configuration option to it (at the bottom):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;rendererfactory = &#039;theme_overridden_renderer_factory&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you&#039;ve already got a custom renderer you will already have this line.&lt;br /&gt;
&lt;br /&gt;
And thats it! now we move on to extending the custom menu.&lt;br /&gt;
&lt;br /&gt;
==Adding the My Courses branch==&lt;br /&gt;
So the point of this extension is to add a &#039;&#039;&#039;My Courses&#039;&#039;&#039; branch to the end of the custom menu.&lt;br /&gt;
&lt;br /&gt;
The plan is to have the my courses branch and then within that branch have an entry for every course the user is enrolled in, much the same as the my courses branch of the navigation. &lt;br /&gt;
&lt;br /&gt;
In order to achieve this we need to add some items to the custom menu, the my courses branch and all of the courses within it. We can do this overriding the core_renderers &#039;&#039;&#039;render_custom_menu&#039;&#039;&#039; method, of more accuratly create our own render_custom_menu method that adds our items and then calls the original. Remember we only need to add items, we don&#039;t need to change what is being produced.&lt;br /&gt;
&lt;br /&gt;
So within our renderers.php file add the following code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
class theme_themename_core_renderer extends core_renderer {&lt;br /&gt;
&lt;br /&gt;
    protected function render_custom_menu(custom_menu $menu) {&lt;br /&gt;
        // Our code will go here shortly&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So that is pretty simple right?!&lt;br /&gt;
&lt;br /&gt;
Here we are defining our core_renderer which will contain our overridden method &#039;&#039;render_custom_menu&#039;&#039; which we have also defined there.&lt;br /&gt;
Note the definition of the render_custom_menu must be the same as the original, this means it must be &#039;&#039;&#039;protected&#039;&#039;&#039; and it must take one argument &#039;&#039;&#039;custom_menu $menu&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Next step is to write the code for our render_custom_menu method. As stated above we want to add a branch and courses to the end of it which we can do with the following bit of code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mycourses = $this-&amp;gt;page-&amp;gt;navigation-&amp;gt;get(&#039;mycourses&#039;);&lt;br /&gt;
&lt;br /&gt;
if (isloggedin() &amp;amp;&amp;amp; $mycourses &amp;amp;&amp;amp; $mycourses-&amp;gt;has_children()) {&lt;br /&gt;
    $branchlabel = get_string(&#039;mycourses&#039;);&lt;br /&gt;
    $branchurl   = new moodle_url(&#039;/course/index.php&#039;);&lt;br /&gt;
    $branchtitle = $branchlabel;&lt;br /&gt;
    $branchsort  = 10000;&lt;br /&gt;
&lt;br /&gt;
    $branch = $menu-&amp;gt;add($branchlabel, $branchurl, $branchtitle, $branchsort);&lt;br /&gt;
&lt;br /&gt;
    foreach ($mycourses-&amp;gt;children as $coursenode) {&lt;br /&gt;
        $branch-&amp;gt;add($coursenode-&amp;gt;get_content(), $coursenode-&amp;gt;action, $coursenode-&amp;gt;get_title());&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return parent::render_custom_menu($menu);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So how this all works....&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mycourses = $this-&amp;gt;page-&amp;gt;navigation-&amp;gt;get(&#039;mycourses&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This line is a little bit of smarts, what we are doing is getting the mycourses branch from the navigation. We could make all of the database calls and work it all out ourselves but this will be much better for performance and is easier!&lt;br /&gt;
&lt;br /&gt;
The next line of code is an &#039;&#039;if&#039;&#039; statement that checks three things&lt;br /&gt;
# The user is logged in, you must be logged in to see your courses.&lt;br /&gt;
# That we have a mycourses object, if the user isn&#039;t enrolled in anything they won&#039;t have a mycourses object.&lt;br /&gt;
# The the mycourses object has children, if it exists it should but it is better to be safe than get errors.&lt;br /&gt;
&lt;br /&gt;
Within the if statement we are doing two main things happening, the first is to add the branch to the menu:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$branchlabel = get_string(&#039;mycourses&#039;);&lt;br /&gt;
$branchurl   = new moodle_url(&#039;/course/index.php&#039;);&lt;br /&gt;
$branchtitle = $branchlabel;&lt;br /&gt;
$branchsort  = 10000;&lt;br /&gt;
&lt;br /&gt;
$branch = $menu-&amp;gt;add($branchlabel, $branchurl, $branchtitle, $branchsort);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
When adding a new branch we need to give it three things:&lt;br /&gt;
# A label &#039;&#039;&#039;$branchlabel&#039;&#039;&#039;.&lt;br /&gt;
# A URL &#039;&#039;&#039;$branchurl&#039;&#039;&#039;.&lt;br /&gt;
# A title &#039;&#039;&#039;$branchtitle&#039;&#039;&#039; in this case I have just set it to the same as $branchlabel because I am lazy, you can make it anything you want.&lt;br /&gt;
# A sort order &#039;&#039;&#039;$branchsort&#039;&#039;&#039; this just needs to be high enough that it ends up on last place where we want it. Make it small to put it at the front.&lt;br /&gt;
&lt;br /&gt;
The final line of code from above simply adds it to the menu and collects a reference to it so that we can add courses to it.&lt;br /&gt;
&lt;br /&gt;
The second thing being done in the if statement is iterate through all of the courses in the mycourses object and add them to the branch. That is done with the following bit of code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
foreach ($mycourses-&amp;gt;children as $coursenode) {&lt;br /&gt;
    $branch-&amp;gt;add($coursenode-&amp;gt;get_content(), $coursenode-&amp;gt;action, $coursenode-&amp;gt;get_title());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
So here we go through all of the mycourses objects children (which we know will be courses) and for each one we add an item to the branch.&lt;br /&gt;
When adding items here, like above, we need to give it the following:&lt;br /&gt;
# A label &#039;&#039;&#039;$coursenode-&amp;gt;get_content()&#039;&#039;&#039; returns us the text in the navigation node.&lt;br /&gt;
# A url &#039;&#039;&#039;$coursenode-&amp;gt;action&#039;&#039;&#039; which is the URL for the node.&lt;br /&gt;
# A title &#039;&#039;&#039;$coursenode-&amp;gt;get_title()&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In this case we don&#039;t need to set a sort order because the navigation has already ordered them correctly!&lt;br /&gt;
&lt;br /&gt;
So now we are through the if statement and there is only one line of code left:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
return parent::render_custom_menu($menu);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This line of code simply calls the original &#039;&#039;&#039;core_renderer::render_custom_menu&#039;&#039;&#039; method to do all of the remaining work. Because we don&#039;t need to change the display at all we don&#039;t need to redo what it does, we can just use it!.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
How easy way that?! it&#039;s all done, if you open you site in your browser and log in the custom menu should now contain a my courses branch (providing you are enrolled in courses).&lt;br /&gt;
&lt;br /&gt;
==Loading labels from language files==&lt;br /&gt;
If you run a site that is available in more than one language &#039;&#039;&#039;and&#039;&#039;&#039; you want to make use of the custom menu then you will probably be very interested in this.&lt;br /&gt;
&lt;br /&gt;
The idea behind this extension is to load the labels and titles that get shown in the custom menu from the theme&#039;s language files rather than having just the fixed strings you type into the admin setting.&lt;br /&gt;
&lt;br /&gt;
In order to achieve this we need to do somehow override the custom_menu_item class so that it loads the strings from the database if they match a special pattern. We can then update the admin setting to use our patter and wallah! things should load from the language files.&lt;br /&gt;
&lt;br /&gt;
What makes this tricky is that we can&#039;t just override the custom_menu_item class, we also need to override the thing that makes create custom_menu_item instances which in this case is the core_renderer::render_custom_menu_item method.&lt;br /&gt;
&lt;br /&gt;
===Overriding the custom_menu_item class===&lt;br /&gt;
Within your themes lib.php file add the following lines of code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
class transmuted_custom_menu_item extends custom_menu_item {&lt;br /&gt;
    public function __construct(custom_menu_item $menunode) {&lt;br /&gt;
        // Our code will go here&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
What we have done here is create a overridden custom_menu_item class called &#039;&#039;&#039;transmuted_custom_menu_item&#039;&#039;&#039;.&lt;br /&gt;
Within that class we are overriding the constructor, the constructor will be given the original menu item and we will need to instatiate this object with the properties of the original.&lt;br /&gt;
Once we have instantiated it with the properties of the original we can alter then as we like.&lt;br /&gt;
&lt;br /&gt;
Next we need to write the contents of the &#039;&#039;__construct&#039;&#039; method:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
parent::__construct($menunode-&amp;gt;get_text(), $menunode-&amp;gt;get_url(), $menunode-&amp;gt;get_title(), $menunode-&amp;gt;get_sort_order(), $menunode-&amp;gt;get_parent());&lt;br /&gt;
$this-&amp;gt;children = $menunode-&amp;gt;get_children();&lt;br /&gt;
&lt;br /&gt;
$matches = array();&lt;br /&gt;
if (preg_match(&#039;/^\[\[([a-zA-Z0-9\-\_\:]+)\]\]$/&#039;, $this-&amp;gt;text, $matches)) {&lt;br /&gt;
    try {&lt;br /&gt;
        $this-&amp;gt;text = get_string($matches[1], &#039;theme_themename&#039;);&lt;br /&gt;
    } catch (Exception $e) {&lt;br /&gt;
        $this-&amp;gt;text = $matches[1];&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$matches = array();&lt;br /&gt;
if (preg_match(&#039;/^\[\[([a-zA-Z0-9\-\_\:]+)\]\]$/&#039;, $this-&amp;gt;title, $matches)) {&lt;br /&gt;
    try {&lt;br /&gt;
        $this-&amp;gt;title = get_string($matches[1], &#039;theme_themename&#039;);&lt;br /&gt;
    } catch (Exception $e) {&lt;br /&gt;
        $this-&amp;gt;title = $matches[1];&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So there are essentially four things going on here.&lt;br /&gt;
&lt;br /&gt;
Firs we need to populate this object with the properties of the original item. We do this by calling the original constructor with $menunode&#039;s properties as shown below.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
parent::__construct($menunode-&amp;gt;get_text(), $menunode-&amp;gt;get_url(), $menunode-&amp;gt;get_title(), $menunode-&amp;gt;get_sort_order(), $menunode-&amp;gt;get_parent());&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we need to copy the properties that arn&#039;t included in the original constructor, in this case there is only one &#039;&#039;&#039;$this-&amp;gt;children&#039;&#039;&#039;. This should be an array of all of this items children (sub items).&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$this-&amp;gt;children = $menunode-&amp;gt;get_children();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that we have all the properties set up we can modify them. In our case we want to check if the items label and title match a special pattern and if they do we want to fetch them from the language file instead.&lt;br /&gt;
The special pattern is &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;[[stringname]]&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; where stringname is the name of the string that we want to get from the language file.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$matches = array();&lt;br /&gt;
if (preg_match(&#039;/^\[\[([a-zA-Z0-9\-\_\:]+)\]\]$/&#039;, $this-&amp;gt;text, $matches)) {&lt;br /&gt;
    try {&lt;br /&gt;
        $this-&amp;gt;text = get_string($matches[1], &#039;theme_themename&#039;);&lt;br /&gt;
    } catch (Exception $e) {&lt;br /&gt;
        $this-&amp;gt;text = $matches[1];&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
In the code above we do the following:&lt;br /&gt;
# Create an array $matches which will hold the stringname if the label matches the pattern.&lt;br /&gt;
# We attempt to match the label to the pattern. If it does the $matches array now contains the stringname.&lt;br /&gt;
# If it did match we call get string as shown.&lt;br /&gt;
&lt;br /&gt;
The third and final thing is to do the above again but this time for the title.&lt;br /&gt;
&lt;br /&gt;
With that done our transmutable_custom_menu_item class is complete. Next step is to make use of it.&lt;br /&gt;
&lt;br /&gt;
===Overriding render_custom_menu_item===&lt;br /&gt;
The next step is make use of the transmutable_custom_menu_item class we created previously. &lt;br /&gt;
&lt;br /&gt;
We can do this by overriding the &#039;&#039;&#039;core_renderer::render_custom_menu_item&#039;&#039;&#039; method within our renderers.php file as shown below.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
protected function render_custom_menu_item(custom_menu_item $menunode) {&lt;br /&gt;
    $transmutedmenunode = new transmuted_custom_menu_item($menunode);&lt;br /&gt;
    return parent::render_custom_menu_item($transmutedmenunode);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is pretty simply, essentially we are using our transmuted_custom_menu_item class like a façade to the original custom_menu_item class by creating a new transmuted instance using the original.&lt;br /&gt;
Once we have the transmuted object we can call the original render_custom_menu_item method with it.&lt;br /&gt;
&lt;br /&gt;
And that is it! Congratulations if you got it this far.&lt;br /&gt;
&lt;br /&gt;
The only thing left to do is add strings to your themes language file as required!&lt;br /&gt;
&lt;br /&gt;
==Complete source==&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// theme/themename/renderers.php&lt;br /&gt;
&lt;br /&gt;
class theme_themename_core_renderer extends core_renderer {&lt;br /&gt;
&lt;br /&gt;
    protected function render_custom_menu(custom_menu $menu) {&lt;br /&gt;
        &lt;br /&gt;
        $mycourses = $this-&amp;gt;page-&amp;gt;navigation-&amp;gt;get(&#039;mycourses&#039;);&lt;br /&gt;
&lt;br /&gt;
        if (isloggedin() &amp;amp;&amp;amp; $mycourses &amp;amp;&amp;amp; $mycourses-&amp;gt;has_children()) {&lt;br /&gt;
            $branchlabel = get_string(&#039;mycourses&#039;);&lt;br /&gt;
            $branchurl   = new moodle_url(&#039;/course/index.php&#039;);&lt;br /&gt;
            $branchtitle = $branchlabel;&lt;br /&gt;
            $branchsort  = 10000;&lt;br /&gt;
&lt;br /&gt;
            $branch = $menu-&amp;gt;add($branchlabel, $branchurl, $branchtitle, $branchsort);&lt;br /&gt;
&lt;br /&gt;
            foreach ($mycourses-&amp;gt;children as $coursenode) {&lt;br /&gt;
                $branch-&amp;gt;add($coursenode-&amp;gt;get_content(), $coursenode-&amp;gt;action, $coursenode-&amp;gt;get_title());&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return parent::render_custom_menu($menu);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    protected function render_custom_menu_item(custom_menu_item $menunode) {&lt;br /&gt;
        $transmutedmenunode = new transmuted_custom_menu_item($menunode);&lt;br /&gt;
        return parent::render_custom_menu_item($transmutedmenunode);&lt;br /&gt;
    }&lt;br /&gt;
&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;
// theme/themename/lib.php&lt;br /&gt;
&lt;br /&gt;
class transmuted_custom_menu_item extends custom_menu_item {&lt;br /&gt;
    public function __construct(custom_menu_item $menunode) {&lt;br /&gt;
        parent::__construct($menunode-&amp;gt;get_text(), $menunode-&amp;gt;get_url(), $menunode-&amp;gt;get_title(), $menunode-&amp;gt;get_sort_order(), $menunode-&amp;gt;get_parent());&lt;br /&gt;
        $this-&amp;gt;children = $menunode-&amp;gt;get_children();&lt;br /&gt;
&lt;br /&gt;
        $matches = array();&lt;br /&gt;
        if (preg_match(&#039;/^\[\[([a-zA-Z0-9\-\_\:]+)\]\]$/&#039;, $this-&amp;gt;text, $matches)) {&lt;br /&gt;
            try {&lt;br /&gt;
                $this-&amp;gt;text = get_string($matches[1], &#039;theme_themename&#039;);&lt;br /&gt;
            } catch (Exception $e) {&lt;br /&gt;
                $this-&amp;gt;text = $matches[1];&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $matches = array();&lt;br /&gt;
        if (preg_match(&#039;/^\[\[([a-zA-Z0-9\-\_\:]+)\]\]$/&#039;, $this-&amp;gt;title, $matches)) {&lt;br /&gt;
            try {&lt;br /&gt;
                $this-&amp;gt;title = get_string($matches[1], &#039;theme_themename&#039;);&lt;br /&gt;
            } catch (Exception $e) {&lt;br /&gt;
                $this-&amp;gt;title = $matches[1];&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]]&lt;br /&gt;
* [[Development:Themes 2.0 overriding a renderer]]&lt;br /&gt;
* [[Development:Themes 2.0 adding courses and categories to the custom menu]]&lt;br /&gt;
* [http://developer.yahoo.com/yui/3/node-menunav/ YUI 3 Menunav component the custom menu uses]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0&amp;diff=83283</id>
		<title>Development:Themes 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0&amp;diff=83283"/>
		<updated>2011-05-06T03:01:57Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* See also */&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 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>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_adding_courses_and_categories_to_the_custom_menu&amp;diff=83282</id>
		<title>Development:Themes 2.0 adding courses and categories to the custom menu</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_adding_courses_and_categories_to_the_custom_menu&amp;diff=83282"/>
		<updated>2011-05-06T02:55:54Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* lang/en/theme_ */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello this is going to be a very brief tutorial on how to add a courses and categories tree to the custom menu.&amp;lt;br /&amp;gt;&lt;br /&gt;
The reason for writing this tutorial is simply that this seems to be a request that is being made over and over again.&lt;br /&gt;
&lt;br /&gt;
==Before we get started==&lt;br /&gt;
Please please please make sure you are familiar with the other Themes 2.0 tutorials before attempting this tutorial.&lt;br /&gt;
&lt;br /&gt;
In particular I would recommend being familiar with the following documents and tutorials as I&#039;m going to move through this tutorial at a fast pace.&lt;br /&gt;
&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]]&lt;br /&gt;
* [[Development:Themes 2.0 overriding a renderer]]&lt;br /&gt;
* [[Development:Themes 2.0 extending the custom menu]]&lt;br /&gt;
&lt;br /&gt;
Providing you are familiar with the above you should manage just fine with this tutorial and if you ever get stuck don&#039;t forget to ask in the theme&#039;s forums, there is always someone around who can help.&lt;br /&gt;
&lt;br /&gt;
==Laying the ground work==&lt;br /&gt;
Alright I don&#039;t want this tutorial to drag out so get ready. For this tutorial I am just going to extend the standard theme, I&#039;m going to make absolutely no changes to the design and layout of the theme or the custom menu I am ONLY going to add a list of courses and categories to it.&lt;br /&gt;
&lt;br /&gt;
So to begin with within your Moodle themes directory create a new directory coursecategorymenu in which I want you to create three files, the first config.php which is obviously required, the second renderers.php as we are going to achieve this by overriding a renderer, and the third the English language file for this theme.&lt;br /&gt;
&lt;br /&gt;
You should end up with:&lt;br /&gt;
&lt;br /&gt;
* moodle/theme/coursecategorymenu&lt;br /&gt;
* moodle/theme/coursecategorymenu/config.php&lt;br /&gt;
* moodle/theme/coursecategorymenu/renderers.php&lt;br /&gt;
* moodle/theme/coursecategorymenu/lang/en/theme_coursecategorymenu.php&lt;br /&gt;
&lt;br /&gt;
==config.php==&lt;br /&gt;
Obviously because all I want to base this theme off the standard theme and only override a renderer the config.php file is going to be VERY basic, so much so that I&#039;m not going to go into details about it, as you&#039;ve read the recommended tutorials you will already be completely familiar with everything it is doing.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;name = &#039;coursecategorymenu&#039;;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;, &#039;base&#039;);&lt;br /&gt;
$THEME-&amp;gt;rendererfactory = &#039;theme_overridden_renderer_factory&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==renderers.php==&lt;br /&gt;
This is of course where the magic is going to happen.&lt;br /&gt;
&lt;br /&gt;
In my case I want to add a branch to the end of the custom menu titled &#039;&#039;Courses&#039;&#039; and then I want to add the category and course structure to that branch.&lt;br /&gt;
&lt;br /&gt;
So like the [[Development:Themes 2.0 extending the custom menu|extending the custom menu]] tutorial I will be overriding the core renderer and I will also be overriding the render_custom_menu_method.&lt;br /&gt;
&lt;br /&gt;
So the code for this:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
class theme_coursecategorymenu_core_renderer extends core_renderer {&lt;br /&gt;
 &lt;br /&gt;
    protected function render_custom_menu(custom_menu $menu) {&lt;br /&gt;
        // Our code will go here shortly&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice that is identical to the starting code for the extending custom menu tutorial.&lt;br /&gt;
&lt;br /&gt;
The difference comes in the code that we are going to populate it with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
require_once($CFG-&amp;gt;dirroot.&#039;/course/lib.php&#039;);&lt;br /&gt;
        &lt;br /&gt;
$branch = $menu-&amp;gt;add(get_string(&#039;courses&#039;, &#039;theme_coursecategorymenu&#039;), null, null, 10000);&lt;br /&gt;
&lt;br /&gt;
$categorytree = get_course_category_tree();&lt;br /&gt;
foreach ($categorytree as $category) {&lt;br /&gt;
    $this-&amp;gt;add_category_to_custommenu($branch, $category);&lt;br /&gt;
}&lt;br /&gt;
        &lt;br /&gt;
return parent::render_custom_menu($menu);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So lets work through this code line by line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
require_once($CFG-&amp;gt;dirroot.&#039;/course/lib.php&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This we need to do because we are going to use part of the course API, in particular a function called &#039;&#039;get_course_category_tree()&#039;&#039; that we&#039;ll look at shortly.&lt;br /&gt;
The function we want to use exists within the course lib file and in order to be sure its always available we need to include this file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$branch = $menu-&amp;gt;add(get_string(&#039;courses&#039;, &#039;theme_coursecategorymenu&#039;), null, null, 10000);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This line adds the &#039;&#039;Courses&#039;&#039; branch to the custom menu into which we will add the category and course structure.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$categorytree = get_course_category_tree();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This line is the main one to note, here we are calling a Moodle function that will return us a category and course tree, because all courses need to be within a category the initial return is an array of categories, each category in the array will have the properties of the category as well as two additional properties, the first property &#039;&#039;&#039;categories&#039;&#039;&#039; is an array containing all of this categories sub categories, and the second property &#039;&#039;&#039;courses&#039;&#039;&#039; is also an array containing all of the courses within this category.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$categorytree = get_course_category_tree();&lt;br /&gt;
foreach ($categorytree as $category) {&lt;br /&gt;
    $this-&amp;gt;add_category_to_custommenu($branch, $category);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now these lines of code deal with the initial array of categories returned by the &#039;&#039;get_course_category_tree&#039;&#039; function.&lt;br /&gt;
&lt;br /&gt;
In this case we iterate of the initial categories and for each one we call a method of the renderer &#039;&#039;&#039;add_category_to_custommenu&#039;&#039;&#039; now those of you who are clued in will realise that this method doesn&#039;t exist yet... and you are correct - we need to write this method which is what we will look at next.&amp;lt;br /&amp;gt;&lt;br /&gt;
As a heads up the reason that we need to write another method is because we need a method that we can call recursivily as there are potentially infinite category branches all contains sub categories and courses.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
return parent::render_custom_menu($menu);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final line of code simply calls the original render_custom_menu method now that we have extended the custom menu as we want.&lt;br /&gt;
&lt;br /&gt;
Now that we have looked at the render_custom_menu lets write the function we just talked about &#039;&#039;&#039;add_category_to_custommenu&#039;&#039;&#039;.&amp;lt;br /&amp;gt;&lt;br /&gt;
This function as discussed above is special in that we intend to call it recursively, that means we want to call it once for EVERY category that exists in the tree. We will need to give it the categories parent menu item as well as the category object we want added.&lt;br /&gt;
&lt;br /&gt;
Lets look at the code for this method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
protected function add_category_to_custommenu(custom_menu_item $parent, stdClass $category) {&lt;br /&gt;
    $branch = $parent-&amp;gt;add($category-&amp;gt;name, new moodle_url(&#039;/course/category.php&#039;, array(&#039;id&#039; =&amp;gt;  $category-&amp;gt;id)));&lt;br /&gt;
    if (!empty($category-&amp;gt;categories)) {&lt;br /&gt;
        foreach ($category-&amp;gt;categories as $subcategory) {&lt;br /&gt;
            $this-&amp;gt;add_category_to_custommenu($branch, $subcategory);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    if (!empty($category-&amp;gt;courses)) {&lt;br /&gt;
        foreach ($category-&amp;gt;courses as $course) {&lt;br /&gt;
            $branch-&amp;gt;add($course-&amp;gt;shortname, new moodle_url(&#039;/course/view.php&#039;, array(&#039;id&#039; =&amp;gt; $course-&amp;gt;id)), $course-&amp;gt;fullname);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ok so that doesn&#039;t look too bad, as you&#039;ve already read the extending custom menu tutorial you will be able to spot some of the things it is doing, none the less lets walk through the code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
protected function add_category_to_custommenu(custom_menu_item $parent, stdClass $category) {&lt;br /&gt;
    .....&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First up the function definition, this function is going to be private because only we need it and it is going to take two arguments, the first $parent has to be a custom_menu_item, the second $category has to be the category object.&lt;br /&gt;
&lt;br /&gt;
The objective of this method is to add a category node to the custom menu, in regards to our arguments we want to add $category as a child of $parent.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$branch = $parent-&amp;gt;add($category-&amp;gt;name, new moodle_url(&#039;/course/category.php&#039;, array(&#039;id&#039; =&amp;gt;  $category-&amp;gt;id)));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This line looks very familiar, here we are adding a node for the category to the $parent, we are also collecting the newly added node as $branch.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($category-&amp;gt;categories)) {&lt;br /&gt;
    foreach ($category-&amp;gt;categories as $subcategory) {&lt;br /&gt;
        $this-&amp;gt;add_category_to_custommenu($branch, $subcategory);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now this code is responsible for add the sub categories of this category to the menu as well, first we need to check that the categories property isn&#039;t empty (if it is there is nothing to add).&lt;br /&gt;
Assuming there are sub categories we need go through each of them and call this method on them so that they get added to the custom menu as well.&amp;lt;br /&amp;gt;&lt;br /&gt;
This is called recursion.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($category-&amp;gt;courses)) {&lt;br /&gt;
    foreach ($category-&amp;gt;courses as $course) {&lt;br /&gt;
        $branch-&amp;gt;add($course-&amp;gt;shortname, new moodle_url(&#039;/course/view.php&#039;, array(&#039;id&#039; =&amp;gt; $course-&amp;gt;id)), $course-&amp;gt;fullname);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This code is very similar to the above code except that we are looking at the courses within this category.&amp;lt;br /&amp;gt;&lt;br /&gt;
Also note that this bit of code doesn&#039;t call add_category_to_custommenu recursivily, it doesn&#039;t need to as courses are the last bit we want to display on the menu within the category.&lt;br /&gt;
&lt;br /&gt;
And that is it, time to tidy up and we&#039;re done.&lt;br /&gt;
&lt;br /&gt;
==Finishing up==&lt;br /&gt;
All of the code is written now there is only last thing to do in order to tidy up however and that is to add the &#039;&#039;courses&#039;&#039; string that we used earlier... did you spot it?&lt;br /&gt;
&lt;br /&gt;
This is of course very easy, open up &#039;&#039;&#039;moodle/theme/coursecategorymenu/lang/en/theme_coursecategorymenu.php&#039;&#039;&#039; and add the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
$string[&#039;courses&#039;] = &#039;Courses&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And we&#039;re done. If you now browse to your site and change to the new theme you should see the Courses branch at the end of your custom menu that contains all of the categories, sub categories and courses for your site.&lt;br /&gt;
&lt;br /&gt;
==Full source==&lt;br /&gt;
===config.php===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;name = &#039;coursecategorymenu&#039;;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;, &#039;base&#039;);&lt;br /&gt;
$THEME-&amp;gt;rendererfactory = &#039;theme_overridden_renderer_factory&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
===renderers.php===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
class theme_coursecategorymenu_core_renderer extends core_renderer {&lt;br /&gt;
 &lt;br /&gt;
    protected function render_custom_menu(custom_menu $menu) {&lt;br /&gt;
        global $CFG;&lt;br /&gt;
        &lt;br /&gt;
        require_once($CFG-&amp;gt;dirroot.&#039;/course/lib.php&#039;);&lt;br /&gt;
        &lt;br /&gt;
        $branch = $menu-&amp;gt;add(get_string(&#039;courses&#039;, &#039;theme_coursecategorymenu&#039;), null, null, 10000);&lt;br /&gt;
        &lt;br /&gt;
        $categorytree = get_course_category_tree();&lt;br /&gt;
        foreach ($categorytree as $category) {&lt;br /&gt;
            $this-&amp;gt;add_category_to_custommenu($branch, $category);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return parent::render_custom_menu($menu);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    protected function add_category_to_custommenu(custom_menu_item $parent, stdClass $category) {&lt;br /&gt;
        $branch = $parent-&amp;gt;add($category-&amp;gt;name, new moodle_url(&#039;/course/category.php&#039;, array(&#039;id&#039; =&amp;gt;  $category-&amp;gt;id)));&lt;br /&gt;
        if (!empty($category-&amp;gt;categories)) {&lt;br /&gt;
            foreach ($category-&amp;gt;categories as $subcategory) {&lt;br /&gt;
                $this-&amp;gt;add_category_to_custommenu($branch, $subcategory);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if (!empty($category-&amp;gt;courses)) {&lt;br /&gt;
            foreach ($category-&amp;gt;courses as $course) {&lt;br /&gt;
                $branch-&amp;gt;add($course-&amp;gt;shortname, new moodle_url(&#039;/course/view.php&#039;, array(&#039;id&#039; =&amp;gt; $course-&amp;gt;id)), $course-&amp;gt;fullname);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
===lang/en/theme_coursecategorymenu.php===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
$string[&#039;courses&#039;] = &#039;Courses&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]]&lt;br /&gt;
* [[Development:Themes 2.0 overriding a renderer]]&lt;br /&gt;
* [http://developer.yahoo.com/yui/3/node-menunav/ YUI 3 Menunav component the custom menu uses]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_adding_courses_and_categories_to_the_custom_menu&amp;diff=83281</id>
		<title>Development:Themes 2.0 adding courses and categories to the custom menu</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_adding_courses_and_categories_to_the_custom_menu&amp;diff=83281"/>
		<updated>2011-05-06T02:55:38Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: Created page with &amp;quot;Hello this is going to be a very brief tutorial on how to add a courses and categories tree to the custom menu.&amp;lt;br /&amp;gt; The reason for writing this tutorial is simply that this see...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello this is going to be a very brief tutorial on how to add a courses and categories tree to the custom menu.&amp;lt;br /&amp;gt;&lt;br /&gt;
The reason for writing this tutorial is simply that this seems to be a request that is being made over and over again.&lt;br /&gt;
&lt;br /&gt;
==Before we get started==&lt;br /&gt;
Please please please make sure you are familiar with the other Themes 2.0 tutorials before attempting this tutorial.&lt;br /&gt;
&lt;br /&gt;
In particular I would recommend being familiar with the following documents and tutorials as I&#039;m going to move through this tutorial at a fast pace.&lt;br /&gt;
&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]]&lt;br /&gt;
* [[Development:Themes 2.0 overriding a renderer]]&lt;br /&gt;
* [[Development:Themes 2.0 extending the custom menu]]&lt;br /&gt;
&lt;br /&gt;
Providing you are familiar with the above you should manage just fine with this tutorial and if you ever get stuck don&#039;t forget to ask in the theme&#039;s forums, there is always someone around who can help.&lt;br /&gt;
&lt;br /&gt;
==Laying the ground work==&lt;br /&gt;
Alright I don&#039;t want this tutorial to drag out so get ready. For this tutorial I am just going to extend the standard theme, I&#039;m going to make absolutely no changes to the design and layout of the theme or the custom menu I am ONLY going to add a list of courses and categories to it.&lt;br /&gt;
&lt;br /&gt;
So to begin with within your Moodle themes directory create a new directory coursecategorymenu in which I want you to create three files, the first config.php which is obviously required, the second renderers.php as we are going to achieve this by overriding a renderer, and the third the English language file for this theme.&lt;br /&gt;
&lt;br /&gt;
You should end up with:&lt;br /&gt;
&lt;br /&gt;
* moodle/theme/coursecategorymenu&lt;br /&gt;
* moodle/theme/coursecategorymenu/config.php&lt;br /&gt;
* moodle/theme/coursecategorymenu/renderers.php&lt;br /&gt;
* moodle/theme/coursecategorymenu/lang/en/theme_coursecategorymenu.php&lt;br /&gt;
&lt;br /&gt;
==config.php==&lt;br /&gt;
Obviously because all I want to base this theme off the standard theme and only override a renderer the config.php file is going to be VERY basic, so much so that I&#039;m not going to go into details about it, as you&#039;ve read the recommended tutorials you will already be completely familiar with everything it is doing.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;name = &#039;coursecategorymenu&#039;;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;, &#039;base&#039;);&lt;br /&gt;
$THEME-&amp;gt;rendererfactory = &#039;theme_overridden_renderer_factory&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==renderers.php==&lt;br /&gt;
This is of course where the magic is going to happen.&lt;br /&gt;
&lt;br /&gt;
In my case I want to add a branch to the end of the custom menu titled &#039;&#039;Courses&#039;&#039; and then I want to add the category and course structure to that branch.&lt;br /&gt;
&lt;br /&gt;
So like the [[Development:Themes 2.0 extending the custom menu|extending the custom menu]] tutorial I will be overriding the core renderer and I will also be overriding the render_custom_menu_method.&lt;br /&gt;
&lt;br /&gt;
So the code for this:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
class theme_coursecategorymenu_core_renderer extends core_renderer {&lt;br /&gt;
 &lt;br /&gt;
    protected function render_custom_menu(custom_menu $menu) {&lt;br /&gt;
        // Our code will go here shortly&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice that is identical to the starting code for the extending custom menu tutorial.&lt;br /&gt;
&lt;br /&gt;
The difference comes in the code that we are going to populate it with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
require_once($CFG-&amp;gt;dirroot.&#039;/course/lib.php&#039;);&lt;br /&gt;
        &lt;br /&gt;
$branch = $menu-&amp;gt;add(get_string(&#039;courses&#039;, &#039;theme_coursecategorymenu&#039;), null, null, 10000);&lt;br /&gt;
&lt;br /&gt;
$categorytree = get_course_category_tree();&lt;br /&gt;
foreach ($categorytree as $category) {&lt;br /&gt;
    $this-&amp;gt;add_category_to_custommenu($branch, $category);&lt;br /&gt;
}&lt;br /&gt;
        &lt;br /&gt;
return parent::render_custom_menu($menu);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So lets work through this code line by line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
require_once($CFG-&amp;gt;dirroot.&#039;/course/lib.php&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This we need to do because we are going to use part of the course API, in particular a function called &#039;&#039;get_course_category_tree()&#039;&#039; that we&#039;ll look at shortly.&lt;br /&gt;
The function we want to use exists within the course lib file and in order to be sure its always available we need to include this file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$branch = $menu-&amp;gt;add(get_string(&#039;courses&#039;, &#039;theme_coursecategorymenu&#039;), null, null, 10000);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This line adds the &#039;&#039;Courses&#039;&#039; branch to the custom menu into which we will add the category and course structure.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$categorytree = get_course_category_tree();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This line is the main one to note, here we are calling a Moodle function that will return us a category and course tree, because all courses need to be within a category the initial return is an array of categories, each category in the array will have the properties of the category as well as two additional properties, the first property &#039;&#039;&#039;categories&#039;&#039;&#039; is an array containing all of this categories sub categories, and the second property &#039;&#039;&#039;courses&#039;&#039;&#039; is also an array containing all of the courses within this category.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$categorytree = get_course_category_tree();&lt;br /&gt;
foreach ($categorytree as $category) {&lt;br /&gt;
    $this-&amp;gt;add_category_to_custommenu($branch, $category);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now these lines of code deal with the initial array of categories returned by the &#039;&#039;get_course_category_tree&#039;&#039; function.&lt;br /&gt;
&lt;br /&gt;
In this case we iterate of the initial categories and for each one we call a method of the renderer &#039;&#039;&#039;add_category_to_custommenu&#039;&#039;&#039; now those of you who are clued in will realise that this method doesn&#039;t exist yet... and you are correct - we need to write this method which is what we will look at next.&amp;lt;br /&amp;gt;&lt;br /&gt;
As a heads up the reason that we need to write another method is because we need a method that we can call recursivily as there are potentially infinite category branches all contains sub categories and courses.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
return parent::render_custom_menu($menu);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The final line of code simply calls the original render_custom_menu method now that we have extended the custom menu as we want.&lt;br /&gt;
&lt;br /&gt;
Now that we have looked at the render_custom_menu lets write the function we just talked about &#039;&#039;&#039;add_category_to_custommenu&#039;&#039;&#039;.&amp;lt;br /&amp;gt;&lt;br /&gt;
This function as discussed above is special in that we intend to call it recursively, that means we want to call it once for EVERY category that exists in the tree. We will need to give it the categories parent menu item as well as the category object we want added.&lt;br /&gt;
&lt;br /&gt;
Lets look at the code for this method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
protected function add_category_to_custommenu(custom_menu_item $parent, stdClass $category) {&lt;br /&gt;
    $branch = $parent-&amp;gt;add($category-&amp;gt;name, new moodle_url(&#039;/course/category.php&#039;, array(&#039;id&#039; =&amp;gt;  $category-&amp;gt;id)));&lt;br /&gt;
    if (!empty($category-&amp;gt;categories)) {&lt;br /&gt;
        foreach ($category-&amp;gt;categories as $subcategory) {&lt;br /&gt;
            $this-&amp;gt;add_category_to_custommenu($branch, $subcategory);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    if (!empty($category-&amp;gt;courses)) {&lt;br /&gt;
        foreach ($category-&amp;gt;courses as $course) {&lt;br /&gt;
            $branch-&amp;gt;add($course-&amp;gt;shortname, new moodle_url(&#039;/course/view.php&#039;, array(&#039;id&#039; =&amp;gt; $course-&amp;gt;id)), $course-&amp;gt;fullname);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ok so that doesn&#039;t look too bad, as you&#039;ve already read the extending custom menu tutorial you will be able to spot some of the things it is doing, none the less lets walk through the code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
protected function add_category_to_custommenu(custom_menu_item $parent, stdClass $category) {&lt;br /&gt;
    .....&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First up the function definition, this function is going to be private because only we need it and it is going to take two arguments, the first $parent has to be a custom_menu_item, the second $category has to be the category object.&lt;br /&gt;
&lt;br /&gt;
The objective of this method is to add a category node to the custom menu, in regards to our arguments we want to add $category as a child of $parent.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$branch = $parent-&amp;gt;add($category-&amp;gt;name, new moodle_url(&#039;/course/category.php&#039;, array(&#039;id&#039; =&amp;gt;  $category-&amp;gt;id)));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This line looks very familiar, here we are adding a node for the category to the $parent, we are also collecting the newly added node as $branch.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($category-&amp;gt;categories)) {&lt;br /&gt;
    foreach ($category-&amp;gt;categories as $subcategory) {&lt;br /&gt;
        $this-&amp;gt;add_category_to_custommenu($branch, $subcategory);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now this code is responsible for add the sub categories of this category to the menu as well, first we need to check that the categories property isn&#039;t empty (if it is there is nothing to add).&lt;br /&gt;
Assuming there are sub categories we need go through each of them and call this method on them so that they get added to the custom menu as well.&amp;lt;br /&amp;gt;&lt;br /&gt;
This is called recursion.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (!empty($category-&amp;gt;courses)) {&lt;br /&gt;
    foreach ($category-&amp;gt;courses as $course) {&lt;br /&gt;
        $branch-&amp;gt;add($course-&amp;gt;shortname, new moodle_url(&#039;/course/view.php&#039;, array(&#039;id&#039; =&amp;gt; $course-&amp;gt;id)), $course-&amp;gt;fullname);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This code is very similar to the above code except that we are looking at the courses within this category.&amp;lt;br /&amp;gt;&lt;br /&gt;
Also note that this bit of code doesn&#039;t call add_category_to_custommenu recursivily, it doesn&#039;t need to as courses are the last bit we want to display on the menu within the category.&lt;br /&gt;
&lt;br /&gt;
And that is it, time to tidy up and we&#039;re done.&lt;br /&gt;
&lt;br /&gt;
==Finishing up==&lt;br /&gt;
All of the code is written now there is only last thing to do in order to tidy up however and that is to add the &#039;&#039;courses&#039;&#039; string that we used earlier... did you spot it?&lt;br /&gt;
&lt;br /&gt;
This is of course very easy, open up &#039;&#039;&#039;moodle/theme/coursecategorymenu/lang/en/theme_coursecategorymenu.php&#039;&#039;&#039; and add the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
$string[&#039;courses&#039;] = &#039;Courses&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And we&#039;re done. If you now browse to your site and change to the new theme you should see the Courses branch at the end of your custom menu that contains all of the categories, sub categories and courses for your site.&lt;br /&gt;
&lt;br /&gt;
==Full source==&lt;br /&gt;
===config.php===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;name = &#039;coursecategorymenu&#039;;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;, &#039;base&#039;);&lt;br /&gt;
$THEME-&amp;gt;rendererfactory = &#039;theme_overridden_renderer_factory&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
===renderers.php===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
class theme_coursecategorymenu_core_renderer extends core_renderer {&lt;br /&gt;
 &lt;br /&gt;
    protected function render_custom_menu(custom_menu $menu) {&lt;br /&gt;
        global $CFG;&lt;br /&gt;
        &lt;br /&gt;
        require_once($CFG-&amp;gt;dirroot.&#039;/course/lib.php&#039;);&lt;br /&gt;
        &lt;br /&gt;
        $branch = $menu-&amp;gt;add(get_string(&#039;courses&#039;, &#039;theme_coursecategorymenu&#039;), null, null, 10000);&lt;br /&gt;
        &lt;br /&gt;
        $categorytree = get_course_category_tree();&lt;br /&gt;
        foreach ($categorytree as $category) {&lt;br /&gt;
            $this-&amp;gt;add_category_to_custommenu($branch, $category);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return parent::render_custom_menu($menu);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    protected function add_category_to_custommenu(custom_menu_item $parent, stdClass $category) {&lt;br /&gt;
        $branch = $parent-&amp;gt;add($category-&amp;gt;name, new moodle_url(&#039;/course/category.php&#039;, array(&#039;id&#039; =&amp;gt;  $category-&amp;gt;id)));&lt;br /&gt;
        if (!empty($category-&amp;gt;categories)) {&lt;br /&gt;
            foreach ($category-&amp;gt;categories as $subcategory) {&lt;br /&gt;
                $this-&amp;gt;add_category_to_custommenu($branch, $subcategory);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if (!empty($category-&amp;gt;courses)) {&lt;br /&gt;
            foreach ($category-&amp;gt;courses as $course) {&lt;br /&gt;
                $branch-&amp;gt;add($course-&amp;gt;shortname, new moodle_url(&#039;/course/view.php&#039;, array(&#039;id&#039; =&amp;gt; $course-&amp;gt;id)), $course-&amp;gt;fullname);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
===lang/en/theme_===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
$string[&#039;courses&#039;] = &#039;Courses&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]]&lt;br /&gt;
* [[Development:Themes 2.0 overriding a renderer]]&lt;br /&gt;
* [http://developer.yahoo.com/yui/3/node-menunav/ YUI 3 Menunav component the custom menu uses]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk&amp;diff=82884</id>
		<title>User:Sam Hemelryk</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk&amp;diff=82884"/>
		<updated>2011-04-19T03:28:14Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello, I am a senior developer at Moodle and have been with the project since the June 2009.&lt;br /&gt;
&lt;br /&gt;
For those interested I have written a tutorial on my Moodle development process with Git: [[User:Sam_Hemelryk/My_Moodle_Git_workflow]]&lt;br /&gt;
&lt;br /&gt;
A short list of helpful documents I have created:&lt;br /&gt;
&lt;br /&gt;
* [[Development:Themes 2.0]]&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:Using jQuery with Moodle 2.0]]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82883</id>
		<title>User:Sam Hemelryk/My Moodle Git workflow</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82883"/>
		<updated>2011-04-19T03:23:23Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* What to do when your work gets rejected */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document is a sort of tutorial/inspection of my personal development workflow when working on Moodle with Git.&lt;br /&gt;
&lt;br /&gt;
==Creating the repositories==&lt;br /&gt;
Ok so the very first step is to create several Moodle git repositories, one for each major branch of Moodle being worked on.&lt;br /&gt;
&lt;br /&gt;
At the time of writing the major branches are MOODLE_19_STABLE, MOODLE_20_STABLE and master.&lt;br /&gt;
&lt;br /&gt;
The reason for this is that that way we have a separate site for each Moodle branch that we can test on easily. Yes you will have three sites but you won&#039;t have to worry about swtiching your site when you change branches.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Create a directory to create the repositories within===&lt;br /&gt;
&lt;br /&gt;
Personally I use Ubuntu (Linux) and I chose to create my repositories within a folder I created in /var/www. If you are using windows I would instead suggest creating C:/www/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www&lt;br /&gt;
mkdir repositories&lt;br /&gt;
cd repositories&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 2: Create a master repository===&lt;br /&gt;
This is the easiest of the branches to create a repository for.&lt;br /&gt;
&lt;br /&gt;
Within your repositories directory create a new directory called master and move into it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir master&lt;br /&gt;
cd master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we want to clone the Moodle source from the offical Moodle git repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new directory called moodle within the master directory we created just before.&lt;br /&gt;
&lt;br /&gt;
That new moodle directory should contain the Moodle source code as a git repository.&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our main git repository we need to add our github account as a remote so that we can push to it later:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd moodle&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This adds your moodle repository on github as a remote called github that you can push to later.&lt;br /&gt;
&lt;br /&gt;
Finally before we move onto the next repository we need to create a data directory because we know we will need that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 3: Create a MOODLE_20_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
The next repository we create will be for the MOODLE_20_STABLE branch.&lt;br /&gt;
To start with get back to the repositories directory that we created earlier and create a directory called MOODLE_20_STABLE within that.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_20_STABLE&lt;br /&gt;
cd MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now create a new clone of the main Moodle repository like we did for the master branch above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have done that move into the moodle directory.&lt;br /&gt;
&lt;br /&gt;
By default the master branch is the branch that is created, however we don&#039;t want that for this repository. Instead we want the MOODLE_20_STABLE branch.&lt;br /&gt;
&lt;br /&gt;
To do this we checkout local branch based upon the official MOODLE_20_STABLE branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have created that branch we can delete the local master branch so that we don&#039;t accidentally ever work on it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git branch -D master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then like we did for master we add our github repository as a remote:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And finally create a data directory we can use when we have install the site:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 4: Create a MOODLE_19_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
This step is identical to the above step except we are using the MOODLE_19_STABLE branch instead of the MOODLE_20_STABLE branch.&lt;br /&gt;
The commands for this are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_19_STABLE&lt;br /&gt;
cd MOODLE_19_STABLE&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
git checkout -b MOODLE_19_STABLE origin/MOODLE_19_STABLE&lt;br /&gt;
git branch -D master&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 5: Install the sites===&lt;br /&gt;
Now I can&#039;t tell you how to do this on your own machine however what I would recommend is that you create a link from your web root to the moodle directory of each branch.&lt;br /&gt;
&lt;br /&gt;
If you are using linux and your webroot is /var/www/localhost you would do it as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/localhost/&lt;br /&gt;
ln -s /var/www/repositories/master/moodle master&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_20_STABLE/moodle MOODLE_20_STABLE&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_19_STABLE/moodle MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done you should be able to browse to each repository with the following URL&#039;s&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://localhost/master/&lt;br /&gt;
http://localhost/MOODLE_20_STABLE/&lt;br /&gt;
http://localhost/MOODLE_19_STABLE/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that is done you need to browse to each site and complete the installation.&lt;br /&gt;
&lt;br /&gt;
Under this method your will need to ensure you set the configuration option sessioncookiepath to the URI of your site. You can either do this in the admin interfaces or add the following to your config.php file for each site.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// For the master site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/master/&#039;;&lt;br /&gt;
// For the MOODLE_20_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_20_STABLE/&#039;;&lt;br /&gt;
// For the MOODLE_19_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_19_STABLE/&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Failure to do this will mean that when you log in at one site and then visit the next you will have to log in again and your session on the first site will no longer work.&lt;br /&gt;
&lt;br /&gt;
Now that you have got 3 repositories, one for each main branch, and set up a site for each you are ready to start development.&lt;br /&gt;
&lt;br /&gt;
==Before you start work each day==&lt;br /&gt;
Before you start work each day you should update each of the repositories you have created to ensure that you are always working with up to date versions of Moodle.&lt;br /&gt;
&lt;br /&gt;
You should also take this opportunity to update the repositories on your github account to ensure they are always up to date.&lt;br /&gt;
&lt;br /&gt;
To start with lets update the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This moves to the master repository and then tells git for fetch all of the changes from your remote repositories and clean up any old branches it is aware of.&lt;br /&gt;
&lt;br /&gt;
Once that operation has completed you should update your master branch&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Before you do that it pays to make sure you don&#039;t have any uncommit changes, if you do DON&#039;T TRY IT. There would be a good chance you will encounter problems. Instead finish what you are working on, commit your changes and then update your master branch.&lt;br /&gt;
&lt;br /&gt;
Next we will update the github repositories by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github refs/remotes/origin/master:master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This tells git to push the master branch from origin (the offical Moodle repository) to the master branch on our github account.&lt;br /&gt;
&lt;br /&gt;
Now that you&#039;ve updated the master repository and your github account its time to update the MOODLE_20_STABLE and MOODLE_19_STABLE branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_20_STABLE:MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_19_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_19_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_19_STABLE:MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Working on a Moodle issue==&lt;br /&gt;
&lt;br /&gt;
This part of the document looks at how I go about working on an MDL issue from the Moodle tracker.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ we use the scrum methodology we sees us choose several issues to include in a scrum which we then work on for the period of the scrum. As a community member its more likely you will just be choosing issues that you are passionate about.&lt;br /&gt;
&lt;br /&gt;
Either way once you have found an issue to work on you are ready to start.&lt;br /&gt;
&lt;br /&gt;
For the purpose of this part of the document lets say I am going to work on bug MDL-12345.&lt;br /&gt;
&lt;br /&gt;
==Fixing a bug on the master repository - MDL-12345==&lt;br /&gt;
&lt;br /&gt;
The first step is to create a local branch to make changes on, to do this we will start our work on the master repository.&lt;br /&gt;
&lt;br /&gt;
When fixing an issue I find it easiest to fix the issue on the master branch first and then move my changes to the other branches.&lt;br /&gt;
&lt;br /&gt;
The VERY first thing you should do when you start working on a Moodle issue is make sure you have assigned it to yourself and then click the start progress button.&lt;br /&gt;
&lt;br /&gt;
This way other users know that you are activly working on the bug and no one from HQ will steal it from you.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local branch===&lt;br /&gt;
&lt;br /&gt;
So first get to the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there we create a new branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-master origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command checks out a new branch called wip-MDL-12345-master that is based upon origin/master.&lt;br /&gt;
&lt;br /&gt;
origin/master is of course the master branch on the official Moodle repository (git.moodle.org/moodle.git).&lt;br /&gt;
&lt;br /&gt;
The name of the branch is also very important. It is essentially telling us three things.&lt;br /&gt;
&lt;br /&gt;
; wip : This stands for work in progress, it helps people see that you are currently working on this branch and that they shouldn&#039;t base there work on it because it will likely change.&lt;br /&gt;
; MDL-12345 : This is of course the Moodle bug number. It helps people quickly identify what you are working on.&lt;br /&gt;
; master : This is the branch we are making changes on. It helps people quickly understand where the changes are being made.&lt;br /&gt;
&lt;br /&gt;
You can optionally add more to the end of the branch name such as a key word that identifies the area or a date at which you started work e.g.&lt;br /&gt;
&lt;br /&gt;
* wip-MDL-12345-master-navigation-changes&lt;br /&gt;
* wip-MDL-12345-master-20110418&lt;br /&gt;
&lt;br /&gt;
That is up to you, personally I&#039;m not a fan of it, however the rest is all required to help integrate your work.&lt;br /&gt;
&lt;br /&gt;
Either way now you have a branch, mine is called wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Make changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have created you branch you are ready to make changes.&lt;br /&gt;
&lt;br /&gt;
I&#039;ll let you make whatever changes you are need, once you have made changes move onto the next step.&lt;br /&gt;
&lt;br /&gt;
Before you do move on however make sure that your code meets the high quality of code Moodle requires.&lt;br /&gt;
&lt;br /&gt;
You can find information about that on the moodle docs here: https://docs.moodle.org/en/Development:Coding_style&lt;br /&gt;
&lt;br /&gt;
The following are common mistakes:&lt;br /&gt;
&lt;br /&gt;
* Incorrect white space&lt;br /&gt;
** Tabs instead of spaces&lt;br /&gt;
** Extra spaces at the end of lines&lt;br /&gt;
** Multiple new lines&lt;br /&gt;
** Forgetting to put spaces between function arguments&lt;br /&gt;
* Incorrect commit messages (read on to find out about writing a good commit message)&lt;br /&gt;
* Incorrect variable or function names&lt;br /&gt;
&lt;br /&gt;
Making these sort of mistakes can lead to your code being rejected despite it working correctly.&lt;br /&gt;
&lt;br /&gt;
I would &#039;&#039;&#039;strongly&#039;&#039;&#039; suggest while learning Moodle development that you use [[User:Tim Hunt|Tim Hunt&#039;s]] fantastic [https://github.com/timhunt/moodle-local_codechecker Code Checker] plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
You&#039;ll find information on how to use it within its README file and it will pick up many of the things that may lead to your work being rejected.&lt;br /&gt;
&lt;br /&gt;
Or course it will be reviewed in regards to security, usability and the other important factors of code development.&lt;br /&gt;
&lt;br /&gt;
===Step 3: Commit your changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have made your changes you are getting ready to commit them.&lt;br /&gt;
&lt;br /&gt;
The first thing to do is check your changes. To do this run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see all of the files you have changes highlighted in red.&lt;br /&gt;
&lt;br /&gt;
Next you need to stage all of the files you want to commit.&lt;br /&gt;
&lt;br /&gt;
To do this you add the files to the stage using the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git add lib/modifiedfile.php&lt;br /&gt;
git add lib/newfile.php&lt;br /&gt;
git add theme/base/style/core.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Why not just commit all changes. Many of the git guides you read will tell you above git commit -a which commits all of the changes you have made.&lt;br /&gt;
&lt;br /&gt;
We&#039;ve hardly being using git here at Moodle and already I&#039;ve seen several people accidentally commit changes that they didn&#039;t mean to.&lt;br /&gt;
&lt;br /&gt;
Staging files like this ENSURES you only commit things you intend to.&lt;br /&gt;
&lt;br /&gt;
Now that you have staged your changes/new files you are ready to commit. The following command commits your changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git commit -m &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command commits your changes with the commit message &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;.&lt;br /&gt;
It&#039;s very important to Moodle that you format your commit messages like this.&lt;br /&gt;
They consist of three parts:&lt;br /&gt;
&lt;br /&gt;
# The MDL bug number in this case MDL-12345&lt;br /&gt;
# The area you made changes to in this case enrol&lt;br /&gt;
# A short description of what you did, in this case I fixed a couple of enrolment bugs.&lt;br /&gt;
&lt;br /&gt;
When you commit your message you will see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[master 19a484e] changes&lt;br /&gt;
 1 files changed, 16 insertions(+), 18 deletions(-)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
There is one thing here you need to note down for later, that is the number that appears within the square brackets after the branch name, in my case it is 19a484e. This is the commit id of the commit I just made.&lt;br /&gt;
&lt;br /&gt;
===Step 4: Pushing your changes to your github account===&lt;br /&gt;
&lt;br /&gt;
Now that you have made changes to your local branch you should push it to your github account so that it can be reviewed and hopefully integrated into Moodle.&lt;br /&gt;
&lt;br /&gt;
Doing this is very simple just run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are telling git to push the branch wip-MDL-12345-master to the remote called github which we added when setting up our git repositories.&lt;br /&gt;
And just like that you&#039;ve made a branch that contains your work and pushed it to github ready to get it reviewed.&lt;br /&gt;
&lt;br /&gt;
==Moving your changes to another branch==&lt;br /&gt;
Now that you have made changes to the master branch you need to decide whether it is appropriate make those changes on any of the other branches.&lt;br /&gt;
Most likely if you are fixing a bug you will need to make the changes on the MOODLE_20_STABLE branch as well, and perhaps the MOODLE_19_STABLE branch if it is a security bug.&lt;br /&gt;
&lt;br /&gt;
Lets assume for MDL-12345 that I fixed earlier that it should be ported to MOODLE_20_STABLE as well.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local MOODLE_20_STABLE branch===&lt;br /&gt;
&lt;br /&gt;
To start with I need to move to the MOODLE_20_STABLE repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there I need to create a new branch based upon the MOODLE_20_STABLE branch that is going to contain my changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very similar to the branch we created for the changes to the master branch except that I have subsituted MOODLE_20_STABLE in place of master. This is because the new branch we are creating is based upon the MOODLE_20_STABLE branch on the offical Moodle git repository and contains changes for that branch.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Cherry-picking my changes===&lt;br /&gt;
Once we have a branch for our changes I am ready to make them again. There is however with git an easy way to do this, cherry-picking.&lt;br /&gt;
&lt;br /&gt;
Cherry-picking is the process of copying a single commit from one branch to another. In this case I want to cherry pick the commit I made earlier onto the branch I&#039;ve just created.&lt;br /&gt;
&lt;br /&gt;
However before I can do this I need to fetch the changes I made from the github repository. I need to do this because I made that changes of a totally separate local repository remember.&lt;br /&gt;
&lt;br /&gt;
So to update my repository with the latest changes I run the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command tells git to look at each remote and get any new changes (it also removes any branches that have been deleted).&lt;br /&gt;
Once it has completed you will be ready to cherry pick the commit. To do so you use the following command but replace my commit is with yours.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git cherry-pick 19a484e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Providing there are no conflicts your branch will now contain a copy of the changes you made to the master branch.&lt;br /&gt;
If there are conficts that you will need to resolve them and commit your changes however you can search for another tutorial about how to do that,&lt;br /&gt;
&lt;br /&gt;
Now I know at this point that there will be some of you who are saying &#039;Whoops I forgot what my commit id was!&#039;. If this is you don&#039;t worry, its pretty easy to find it providing you used a proper commit message like I described above.&lt;br /&gt;
Simply run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git log --oneline origin/master..github/wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the commits that are in the wip-MDL-12345-master at your github account but are not in the master branch at the offical Moodle repository.&lt;br /&gt;
You can then cherry-pick the commits shown there (the commit ID&#039;s should be highlighted in yellow).&lt;br /&gt;
&lt;br /&gt;
Once you have cherry-picked your commits its time to check that everything worked, run the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# On branch wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
# Your branch is ahead of &#039;origin/MOODLE_20_STABLE&#039; by 1 commit.&lt;br /&gt;
#&lt;br /&gt;
nothing to commit (working directory clean)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very handy as it tells you that your branch is ahead of the offical MOODLE_20_STABLE branch by one commit.&lt;br /&gt;
You can also check that your commit contains the changes you think by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git diff origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the changes you have made as a diff.&lt;br /&gt;
&lt;br /&gt;
Now that you know that your commit is there you and that it is correct it is time to push it to your github account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And thats it.&lt;br /&gt;
&lt;br /&gt;
You github account should now have two branches on it:&lt;br /&gt;
&lt;br /&gt;
; wip-MDL-12345-master : This branch is the changes you have made for the master branch&lt;br /&gt;
; wip-MDL-12345-MOODLE_20_STABLE : This branch is those same changes but for the MOODLE_20_STABLE branch&lt;br /&gt;
&lt;br /&gt;
Now you are ready to create PULL requests so that your work gets reviewed and hopefully integrated.&lt;br /&gt;
&lt;br /&gt;
==Creating PULL requests==&lt;br /&gt;
Now that you&#039;ve got a branch with changes for your MDL issue its time to create some PULL requests to get it integrated.&lt;br /&gt;
&lt;br /&gt;
===Creating a PULL request for the master branch===&lt;br /&gt;
&lt;br /&gt;
So you have successfully fixed the bug MDL-12345, you have created two branches one for master and one for MOODLE_20_STABLE. It is time to create a PULL request for each of these branches.&lt;br /&gt;
&lt;br /&gt;
First lets create a PULL request for the master branch:&lt;br /&gt;
&lt;br /&gt;
# Browse to tracker.moodle.org/browse/MDL-12345&lt;br /&gt;
# When the page loads log in if you haven&#039;t already.&lt;br /&gt;
# Click on the button in the top right labelled `Create issue`&lt;br /&gt;
# Change Project to `Pull Requests`&lt;br /&gt;
# Change Issue type to `Pull Request`&lt;br /&gt;
# Click create&lt;br /&gt;
&lt;br /&gt;
This takes you to a screen where you can enter the details for the PULL request.&lt;br /&gt;
&lt;br /&gt;
You should fill it out in the following way:&lt;br /&gt;
&lt;br /&gt;
====Summary====&lt;br /&gt;
This is the summary for the PULL request, you should copy and paste the summary from the MDL issue here.&lt;br /&gt;
For MDL-12345 the summary is `alphabetization of UI different on left and right sides` so that&#039;s what I will use.&lt;br /&gt;
&lt;br /&gt;
====Affects Versions====&lt;br /&gt;
This is the version that your branch is changing, in the case of this PULL request I will select `master`.&lt;br /&gt;
&lt;br /&gt;
====Security level====&lt;br /&gt;
If the issue you are working on is a security issue you should set this to the same level that the issue is set to. If its not a security issue or you don&#039;t know just leave it as none.&lt;br /&gt;
&lt;br /&gt;
====Pull from repository====&lt;br /&gt;
This is the repository that the branch is at, for you this will be your github accont. If you head to http://github.com/yourname/moodle you will see a box that has three options SSH, HTTP, and Git read only, click Git Read Only and then copy the contents of the text box into the repositry field of the PULL request. &lt;br /&gt;
For me that is git://github.com/yourname/moodle.git&lt;br /&gt;
&lt;br /&gt;
====Pull branch====&lt;br /&gt;
This is the name of the branch that contains your changes. For me that is wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
====Pull Diff URL====&lt;br /&gt;
This is the URL to a page that shows the changes that you&#039;ve made on your branch. Github is nice in that it has a pretty interface for that. To get to the interface follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Browse to https://github.com/youraccount/moodle&lt;br /&gt;
# Click `Switch Branches` and then click on the branch you changes are based upon, in my case master.&lt;br /&gt;
# Click the button labelled `Branch List`&lt;br /&gt;
# Locate your branch in the list and click the `Compare button` for me this was the compare button to the right of wip-MDL-12345-master.&lt;br /&gt;
# Copy the URL in your browse and paste it into the Pull Diff URL of the PULL request.&lt;br /&gt;
&lt;br /&gt;
For me this URL was: https://github.com/yourname/moodle/compare/master...wip-MDL-23532-master&lt;br /&gt;
For the MOODLE_20_STABLE branch this would be: https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
&lt;br /&gt;
====Description====&lt;br /&gt;
The description should contain several bits of important information:&lt;br /&gt;
&lt;br /&gt;
# A short description of what your patch does&lt;br /&gt;
# Notes about that changes you&#039;ve made that might help the integrator understand what you did when he/she is reviewing it.&lt;br /&gt;
# Testing instructions that guide the testers through testing your changes.&lt;br /&gt;
&lt;br /&gt;
====Components====&lt;br /&gt;
Select general from the components list, general is the only option.&lt;br /&gt;
&lt;br /&gt;
====Finishing up====&lt;br /&gt;
Once you have filled in the fields as above click `Create`. This should create you PULL request and then take you to view it.&lt;br /&gt;
&lt;br /&gt;
Its important to remember that there is still one thing you need to do and that is link to the original issue.&lt;br /&gt;
While you are still logged in click the `More Actions` button and select `Link issue`, in the dialoug that pops up change the `This issue` field to `will help resolve`, type MDL-12345 into the issues field, and then type `Linking to MDL-12345` into the comments box. Once you&#039;ve done that simple click Link.&amp;lt;br /&amp;gt;I should add that the comment isn&#039;t really required. It&#039;s just something I personally like doing.&lt;br /&gt;
&lt;br /&gt;
Time to create the PULL request for the other branches.&lt;br /&gt;
&lt;br /&gt;
===Creating the PULL request for MOODLE_20_STABLE===&lt;br /&gt;
Once you&#039;ve created the PULL request for the master branch it is time to create the PULL request for the MOODLE_20_STABLE branch.&lt;br /&gt;
This is as easy as can be, click Create Issue in the top right, select PULL project and choose Pull Request and then click create.&lt;br /&gt;
On the next screen enter the following details:&lt;br /&gt;
&lt;br /&gt;
; Summary : Copy the summary from the previous PULL Request&lt;br /&gt;
; Affects Versions : Select MOODLE_20_STABLE&lt;br /&gt;
; Security level : Same as the MDL&lt;br /&gt;
; Pull from repository : Copy from the previous PULL request&lt;br /&gt;
; Pull Branch : wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
; Pull Diff URL : https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
; Description : Copy from the previous PULL request&lt;br /&gt;
; Component : general&lt;br /&gt;
&lt;br /&gt;
Then click create to create the PULL request.&lt;br /&gt;
&lt;br /&gt;
Once the PULL request has been create don&#039;t forget to link to the MDL issue like we did for the previous PULL request.&lt;br /&gt;
&lt;br /&gt;
==Resolving the issue==&lt;br /&gt;
The final step for the MDL issue now that you have created the two PULL requests is to Resolve the issue (do not close it, just resolve).&lt;br /&gt;
&lt;br /&gt;
You can do this by logging into tracker, browsing to the MDL issue, and clicking the resolve button.&lt;br /&gt;
&lt;br /&gt;
If your fixes are integrated the tester will close the issue, otherwise if it doesn&#039;t get integrated someone will reopen the MDL.&lt;br /&gt;
&lt;br /&gt;
==Rebasing after the weekly release==&lt;br /&gt;
As many of you will be aware on Wednesday after the latest weekly has been released a comment will be added to all PULL requests that are still open.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The main moodle.git repository has just been updated with latest weekly modifications.&lt;br /&gt;
You may wish to rebase your PULL branches to simplify history and avoid any possible merge conflicts. This would also make integrator&#039;s life easier next week.&lt;br /&gt;
&lt;br /&gt;
TIA and ciao :)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is a message that is bulk added as is done so as a polite request. While it&#039;s not essential for you to rebase your work it really does help the integrators as its much easier to see what is going on and greatly reduces the chance of conflicts (because you&#039;ll solve them when you rebase).&lt;br /&gt;
&lt;br /&gt;
The good news is that rebasing your work is EASY!&lt;br /&gt;
&lt;br /&gt;
For the following example lets assume I created the two PULL requests above on Wednesday morning and the weekly was released on Wednesday afternoon. This means that my branch doesn&#039;t have the changes that have just been released and I need to rebase them.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Rebasing the wip-MDL-12345-master===&lt;br /&gt;
&lt;br /&gt;
The first step is to rebase my work that is based upon the master branch. So first move to the master repository.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next thing we have to do is get all of the changes from the remote repositories, this will fetch down all of the latest changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now before the next step make sure that you don&#039;t have any uncommit changes, if you do finish that work, commit it, then proceed to the next step which is updating your local master.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
git push master github&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that your local master is up to date, and has you&#039;ve updated you master branch at github you are ready to rebase!&lt;br /&gt;
At this point we want to checkout the branch we are going to rebase, in this case wip-MDL-12345-master and then we are going to rebase origin/master which is the official Moodle master branch (and the branch our branch is based upon).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout wip-MDL-12345-master&lt;br /&gt;
git rebase origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that command has completed your branch wip-MDL-12345-master will be completely up to date. Before you are done however you need to push the rebased wip-MDL-12345-master up to your github account so that its the branch the integrator sees.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push -f github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that command is just about identical to the command we used when we first pushed our branch to our github account, there is however one VERY important difference, the &#039;&#039;&#039;-f&#039;&#039;&#039; option.&lt;br /&gt;
The &#039;&#039;&#039;-f&#039;&#039;&#039; option tells git to force the push, this is required because when you rebase all of your commit id&#039;s will change and unless you tell git to force it will see that they have changed and not allow you to push your work.&lt;br /&gt;
&lt;br /&gt;
Thats it! you&#039;ve now rebased your work and the integrators will be happy again :)&lt;br /&gt;
&lt;br /&gt;
===Step 2: Rebasing wip-MDL-12345-MOODLE_20_STABLE===&lt;br /&gt;
Now that we&#039;ve rebased our work that was based upon the master branch it is time to rebase the MOODLE_20_STABLE version.&lt;br /&gt;
This step is just about identical to the previous step except we substitute &#039;&#039;master&#039;&#039; for &#039;&#039;MOODLE_20_STABLE&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github MOODLE_20_STABLE&lt;br /&gt;
git checkout wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
git rebase origin/MOODLE_20_STABLE&lt;br /&gt;
git push -f github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&lt;br /&gt;
==So your work got rejected... what now?==&lt;br /&gt;
First up don&#039;t give up, we (Moodle integrators) don&#039;t just reject code willy-nilly, we always provide a reason.&lt;br /&gt;
&lt;br /&gt;
There are a couple of different paths that this may lead you down:&lt;br /&gt;
# More work needed: This happens if you have fixed half of the bug, or some of the bugs, but not all/completely. In this case you just need to finish off the MDL and then create new PULL requests.&lt;br /&gt;
# Bugs + white space issues: If this is the case you need to fix up what ever was spotted and then create new PULL requests.&lt;br /&gt;
# Not appropriate for a stable branch: This happens if the integrator decides that your work shouldn&#039;t get into the STABLE branch but is still OK for the master branch. Things like new features or improvements are likely to head down this path. If this is the case then everything is done, your work will have been integrated into master and you will just have to wait until the next major release (2.1, 2.2 etc).&lt;br /&gt;
# Not appropriate for core: If this happens it means that the integrator has decided that the work you&#039;ve done isn&#039;t suitable to go into the main Moodle code base. If this is the case and you still want to use your branches that is fine, just leave them up on your github account and whenever you need to use them just merge your branch into your sites repository.&lt;br /&gt;
&lt;br /&gt;
==The extra mile==&lt;br /&gt;
Now as many of you may have guessed by the time you are working on several different issues and managing several repositories the process I&#039;ve described here seems VERY repetitive. And it &#039;&#039;&#039;IS!&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
If you talk to any HQ developer they will tell you they deal with it in their own way, anything from scripts, to custom config files, through to virtual machine snapshots.&lt;br /&gt;
&lt;br /&gt;
Personally I have a couple of bash scripts that I wrote to help me manage my workflow.&lt;br /&gt;
&lt;br /&gt;
The first script I use I run after each weekly release and it does the following things:&lt;br /&gt;
&lt;br /&gt;
* Moves to each repository and does the following&lt;br /&gt;
*# Fetches all remote changes&lt;br /&gt;
*# Checks whether it is safe to update my local main release branches and does that if it is safe&lt;br /&gt;
*# Updates all main release branches on my github account&lt;br /&gt;
&lt;br /&gt;
The second script I run on every site that I have installed, it does the following&lt;br /&gt;
&lt;br /&gt;
* Goes to each site I have installed and does the following&lt;br /&gt;
*# Overwrites the database with a stable snapshot&lt;br /&gt;
*# Overwrites the moodle data directory with a stable snapshot taken at the same time as the database one.&lt;br /&gt;
*# Upgrades the moodle site if required&lt;br /&gt;
*# Takes a snapshot of the database and Moodle data directory.&lt;br /&gt;
&lt;br /&gt;
The third script I run whenever I start working on a new issue and it restores the stable snapshot of a sites database and moodle data directory.&lt;br /&gt;
&lt;br /&gt;
These three scripts allow me to very easily ensure I am working with the latest changes and that I can easily restore to a point I know is stable and safe.&lt;br /&gt;
&lt;br /&gt;
There was a fourth script I used to use but don&#039;t any more that also rebased any unmerged branches however I found it to be far to problematic and I prefer to do it myself so that I know exactly what is going on.&lt;br /&gt;
&lt;br /&gt;
==Useful links==&lt;br /&gt;
The following are links I found useful while learning Git.&lt;br /&gt;
&lt;br /&gt;
* [http://help.github.com Github help (http://help.github.com)] Provides EXCELLENT help tutorials that very clearly explain the basic through to the advanced.&lt;br /&gt;
* [http://cheat.errtheblog.com/s/git/ $ cheat git] This is my favourite cheat sheet, straight forward to the point, if you know the concept you&#039;ll find the answer here.&lt;br /&gt;
* [http://gitster.livejournal.com/28309.html Gitsters journal - Fun with FETCH_HEAD] David Mudrak pointed me at this entry which I found INCREDIBLY useful when reviewing other peoples work.&lt;br /&gt;
* [[Development:Git tips]] Moodle docs page with a few handy tips about using Git for Moodle development.&lt;br /&gt;
&lt;br /&gt;
I you&#039;re looking to read/buy a book on Git I&#039;d strongly recommend [http://progit.org/ Pro Git]. I certainly found that the most useful book I read.&lt;br /&gt;
&lt;br /&gt;
[[Category:Git]]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82882</id>
		<title>User:Sam Hemelryk/My Moodle Git workflow</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82882"/>
		<updated>2011-04-19T03:16:40Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* Step 2: Rebasing wip-MDL-12345-MOODLE_20_STABLE */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document is a sort of tutorial/inspection of my personal development workflow when working on Moodle with Git.&lt;br /&gt;
&lt;br /&gt;
==Creating the repositories==&lt;br /&gt;
Ok so the very first step is to create several Moodle git repositories, one for each major branch of Moodle being worked on.&lt;br /&gt;
&lt;br /&gt;
At the time of writing the major branches are MOODLE_19_STABLE, MOODLE_20_STABLE and master.&lt;br /&gt;
&lt;br /&gt;
The reason for this is that that way we have a separate site for each Moodle branch that we can test on easily. Yes you will have three sites but you won&#039;t have to worry about swtiching your site when you change branches.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Create a directory to create the repositories within===&lt;br /&gt;
&lt;br /&gt;
Personally I use Ubuntu (Linux) and I chose to create my repositories within a folder I created in /var/www. If you are using windows I would instead suggest creating C:/www/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www&lt;br /&gt;
mkdir repositories&lt;br /&gt;
cd repositories&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 2: Create a master repository===&lt;br /&gt;
This is the easiest of the branches to create a repository for.&lt;br /&gt;
&lt;br /&gt;
Within your repositories directory create a new directory called master and move into it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir master&lt;br /&gt;
cd master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we want to clone the Moodle source from the offical Moodle git repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new directory called moodle within the master directory we created just before.&lt;br /&gt;
&lt;br /&gt;
That new moodle directory should contain the Moodle source code as a git repository.&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our main git repository we need to add our github account as a remote so that we can push to it later:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd moodle&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This adds your moodle repository on github as a remote called github that you can push to later.&lt;br /&gt;
&lt;br /&gt;
Finally before we move onto the next repository we need to create a data directory because we know we will need that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 3: Create a MOODLE_20_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
The next repository we create will be for the MOODLE_20_STABLE branch.&lt;br /&gt;
To start with get back to the repositories directory that we created earlier and create a directory called MOODLE_20_STABLE within that.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_20_STABLE&lt;br /&gt;
cd MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now create a new clone of the main Moodle repository like we did for the master branch above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have done that move into the moodle directory.&lt;br /&gt;
&lt;br /&gt;
By default the master branch is the branch that is created, however we don&#039;t want that for this repository. Instead we want the MOODLE_20_STABLE branch.&lt;br /&gt;
&lt;br /&gt;
To do this we checkout local branch based upon the official MOODLE_20_STABLE branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have created that branch we can delete the local master branch so that we don&#039;t accidentally ever work on it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git branch -D master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then like we did for master we add our github repository as a remote:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And finally create a data directory we can use when we have install the site:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 4: Create a MOODLE_19_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
This step is identical to the above step except we are using the MOODLE_19_STABLE branch instead of the MOODLE_20_STABLE branch.&lt;br /&gt;
The commands for this are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_19_STABLE&lt;br /&gt;
cd MOODLE_19_STABLE&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
git checkout -b MOODLE_19_STABLE origin/MOODLE_19_STABLE&lt;br /&gt;
git branch -D master&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 5: Install the sites===&lt;br /&gt;
Now I can&#039;t tell you how to do this on your own machine however what I would recommend is that you create a link from your web root to the moodle directory of each branch.&lt;br /&gt;
&lt;br /&gt;
If you are using linux and your webroot is /var/www/localhost you would do it as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/localhost/&lt;br /&gt;
ln -s /var/www/repositories/master/moodle master&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_20_STABLE/moodle MOODLE_20_STABLE&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_19_STABLE/moodle MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done you should be able to browse to each repository with the following URL&#039;s&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://localhost/master/&lt;br /&gt;
http://localhost/MOODLE_20_STABLE/&lt;br /&gt;
http://localhost/MOODLE_19_STABLE/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that is done you need to browse to each site and complete the installation.&lt;br /&gt;
&lt;br /&gt;
Under this method your will need to ensure you set the configuration option sessioncookiepath to the URI of your site. You can either do this in the admin interfaces or add the following to your config.php file for each site.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// For the master site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/master/&#039;;&lt;br /&gt;
// For the MOODLE_20_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_20_STABLE/&#039;;&lt;br /&gt;
// For the MOODLE_19_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_19_STABLE/&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Failure to do this will mean that when you log in at one site and then visit the next you will have to log in again and your session on the first site will no longer work.&lt;br /&gt;
&lt;br /&gt;
Now that you have got 3 repositories, one for each main branch, and set up a site for each you are ready to start development.&lt;br /&gt;
&lt;br /&gt;
==Before you start work each day==&lt;br /&gt;
Before you start work each day you should update each of the repositories you have created to ensure that you are always working with up to date versions of Moodle.&lt;br /&gt;
&lt;br /&gt;
You should also take this opportunity to update the repositories on your github account to ensure they are always up to date.&lt;br /&gt;
&lt;br /&gt;
To start with lets update the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This moves to the master repository and then tells git for fetch all of the changes from your remote repositories and clean up any old branches it is aware of.&lt;br /&gt;
&lt;br /&gt;
Once that operation has completed you should update your master branch&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Before you do that it pays to make sure you don&#039;t have any uncommit changes, if you do DON&#039;T TRY IT. There would be a good chance you will encounter problems. Instead finish what you are working on, commit your changes and then update your master branch.&lt;br /&gt;
&lt;br /&gt;
Next we will update the github repositories by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github refs/remotes/origin/master:master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This tells git to push the master branch from origin (the offical Moodle repository) to the master branch on our github account.&lt;br /&gt;
&lt;br /&gt;
Now that you&#039;ve updated the master repository and your github account its time to update the MOODLE_20_STABLE and MOODLE_19_STABLE branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_20_STABLE:MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_19_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_19_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_19_STABLE:MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Working on a Moodle issue==&lt;br /&gt;
&lt;br /&gt;
This part of the document looks at how I go about working on an MDL issue from the Moodle tracker.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ we use the scrum methodology we sees us choose several issues to include in a scrum which we then work on for the period of the scrum. As a community member its more likely you will just be choosing issues that you are passionate about.&lt;br /&gt;
&lt;br /&gt;
Either way once you have found an issue to work on you are ready to start.&lt;br /&gt;
&lt;br /&gt;
For the purpose of this part of the document lets say I am going to work on bug MDL-12345.&lt;br /&gt;
&lt;br /&gt;
==Fixing a bug on the master repository - MDL-12345==&lt;br /&gt;
&lt;br /&gt;
The first step is to create a local branch to make changes on, to do this we will start our work on the master repository.&lt;br /&gt;
&lt;br /&gt;
When fixing an issue I find it easiest to fix the issue on the master branch first and then move my changes to the other branches.&lt;br /&gt;
&lt;br /&gt;
The VERY first thing you should do when you start working on a Moodle issue is make sure you have assigned it to yourself and then click the start progress button.&lt;br /&gt;
&lt;br /&gt;
This way other users know that you are activly working on the bug and no one from HQ will steal it from you.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local branch===&lt;br /&gt;
&lt;br /&gt;
So first get to the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there we create a new branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-master origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command checks out a new branch called wip-MDL-12345-master that is based upon origin/master.&lt;br /&gt;
&lt;br /&gt;
origin/master is of course the master branch on the official Moodle repository (git.moodle.org/moodle.git).&lt;br /&gt;
&lt;br /&gt;
The name of the branch is also very important. It is essentially telling us three things.&lt;br /&gt;
&lt;br /&gt;
; wip : This stands for work in progress, it helps people see that you are currently working on this branch and that they shouldn&#039;t base there work on it because it will likely change.&lt;br /&gt;
; MDL-12345 : This is of course the Moodle bug number. It helps people quickly identify what you are working on.&lt;br /&gt;
; master : This is the branch we are making changes on. It helps people quickly understand where the changes are being made.&lt;br /&gt;
&lt;br /&gt;
You can optionally add more to the end of the branch name such as a key word that identifies the area or a date at which you started work e.g.&lt;br /&gt;
&lt;br /&gt;
* wip-MDL-12345-master-navigation-changes&lt;br /&gt;
* wip-MDL-12345-master-20110418&lt;br /&gt;
&lt;br /&gt;
That is up to you, personally I&#039;m not a fan of it, however the rest is all required to help integrate your work.&lt;br /&gt;
&lt;br /&gt;
Either way now you have a branch, mine is called wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Make changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have created you branch you are ready to make changes.&lt;br /&gt;
&lt;br /&gt;
I&#039;ll let you make whatever changes you are need, once you have made changes move onto the next step.&lt;br /&gt;
&lt;br /&gt;
Before you do move on however make sure that your code meets the high quality of code Moodle requires.&lt;br /&gt;
&lt;br /&gt;
You can find information about that on the moodle docs here: https://docs.moodle.org/en/Development:Coding_style&lt;br /&gt;
&lt;br /&gt;
The following are common mistakes:&lt;br /&gt;
&lt;br /&gt;
* Incorrect white space&lt;br /&gt;
** Tabs instead of spaces&lt;br /&gt;
** Extra spaces at the end of lines&lt;br /&gt;
** Multiple new lines&lt;br /&gt;
** Forgetting to put spaces between function arguments&lt;br /&gt;
* Incorrect commit messages (read on to find out about writing a good commit message)&lt;br /&gt;
* Incorrect variable or function names&lt;br /&gt;
&lt;br /&gt;
Making these sort of mistakes can lead to your code being rejected despite it working correctly.&lt;br /&gt;
&lt;br /&gt;
I would &#039;&#039;&#039;strongly&#039;&#039;&#039; suggest while learning Moodle development that you use [[User:Tim Hunt|Tim Hunt&#039;s]] fantastic [https://github.com/timhunt/moodle-local_codechecker Code Checker] plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
You&#039;ll find information on how to use it within its README file and it will pick up many of the things that may lead to your work being rejected.&lt;br /&gt;
&lt;br /&gt;
Or course it will be reviewed in regards to security, usability and the other important factors of code development.&lt;br /&gt;
&lt;br /&gt;
===Step 3: Commit your changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have made your changes you are getting ready to commit them.&lt;br /&gt;
&lt;br /&gt;
The first thing to do is check your changes. To do this run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see all of the files you have changes highlighted in red.&lt;br /&gt;
&lt;br /&gt;
Next you need to stage all of the files you want to commit.&lt;br /&gt;
&lt;br /&gt;
To do this you add the files to the stage using the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git add lib/modifiedfile.php&lt;br /&gt;
git add lib/newfile.php&lt;br /&gt;
git add theme/base/style/core.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Why not just commit all changes. Many of the git guides you read will tell you above git commit -a which commits all of the changes you have made.&lt;br /&gt;
&lt;br /&gt;
We&#039;ve hardly being using git here at Moodle and already I&#039;ve seen several people accidentally commit changes that they didn&#039;t mean to.&lt;br /&gt;
&lt;br /&gt;
Staging files like this ENSURES you only commit things you intend to.&lt;br /&gt;
&lt;br /&gt;
Now that you have staged your changes/new files you are ready to commit. The following command commits your changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git commit -m &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command commits your changes with the commit message &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;.&lt;br /&gt;
It&#039;s very important to Moodle that you format your commit messages like this.&lt;br /&gt;
They consist of three parts:&lt;br /&gt;
&lt;br /&gt;
# The MDL bug number in this case MDL-12345&lt;br /&gt;
# The area you made changes to in this case enrol&lt;br /&gt;
# A short description of what you did, in this case I fixed a couple of enrolment bugs.&lt;br /&gt;
&lt;br /&gt;
When you commit your message you will see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[master 19a484e] changes&lt;br /&gt;
 1 files changed, 16 insertions(+), 18 deletions(-)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
There is one thing here you need to note down for later, that is the number that appears within the square brackets after the branch name, in my case it is 19a484e. This is the commit id of the commit I just made.&lt;br /&gt;
&lt;br /&gt;
===Step 4: Pushing your changes to your github account===&lt;br /&gt;
&lt;br /&gt;
Now that you have made changes to your local branch you should push it to your github account so that it can be reviewed and hopefully integrated into Moodle.&lt;br /&gt;
&lt;br /&gt;
Doing this is very simple just run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are telling git to push the branch wip-MDL-12345-master to the remote called github which we added when setting up our git repositories.&lt;br /&gt;
And just like that you&#039;ve made a branch that contains your work and pushed it to github ready to get it reviewed.&lt;br /&gt;
&lt;br /&gt;
==Moving your changes to another branch==&lt;br /&gt;
Now that you have made changes to the master branch you need to decide whether it is appropriate make those changes on any of the other branches.&lt;br /&gt;
Most likely if you are fixing a bug you will need to make the changes on the MOODLE_20_STABLE branch as well, and perhaps the MOODLE_19_STABLE branch if it is a security bug.&lt;br /&gt;
&lt;br /&gt;
Lets assume for MDL-12345 that I fixed earlier that it should be ported to MOODLE_20_STABLE as well.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local MOODLE_20_STABLE branch===&lt;br /&gt;
&lt;br /&gt;
To start with I need to move to the MOODLE_20_STABLE repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there I need to create a new branch based upon the MOODLE_20_STABLE branch that is going to contain my changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very similar to the branch we created for the changes to the master branch except that I have subsituted MOODLE_20_STABLE in place of master. This is because the new branch we are creating is based upon the MOODLE_20_STABLE branch on the offical Moodle git repository and contains changes for that branch.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Cherry-picking my changes===&lt;br /&gt;
Once we have a branch for our changes I am ready to make them again. There is however with git an easy way to do this, cherry-picking.&lt;br /&gt;
&lt;br /&gt;
Cherry-picking is the process of copying a single commit from one branch to another. In this case I want to cherry pick the commit I made earlier onto the branch I&#039;ve just created.&lt;br /&gt;
&lt;br /&gt;
However before I can do this I need to fetch the changes I made from the github repository. I need to do this because I made that changes of a totally separate local repository remember.&lt;br /&gt;
&lt;br /&gt;
So to update my repository with the latest changes I run the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command tells git to look at each remote and get any new changes (it also removes any branches that have been deleted).&lt;br /&gt;
Once it has completed you will be ready to cherry pick the commit. To do so you use the following command but replace my commit is with yours.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git cherry-pick 19a484e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Providing there are no conflicts your branch will now contain a copy of the changes you made to the master branch.&lt;br /&gt;
If there are conficts that you will need to resolve them and commit your changes however you can search for another tutorial about how to do that,&lt;br /&gt;
&lt;br /&gt;
Now I know at this point that there will be some of you who are saying &#039;Whoops I forgot what my commit id was!&#039;. If this is you don&#039;t worry, its pretty easy to find it providing you used a proper commit message like I described above.&lt;br /&gt;
Simply run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git log --oneline origin/master..github/wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the commits that are in the wip-MDL-12345-master at your github account but are not in the master branch at the offical Moodle repository.&lt;br /&gt;
You can then cherry-pick the commits shown there (the commit ID&#039;s should be highlighted in yellow).&lt;br /&gt;
&lt;br /&gt;
Once you have cherry-picked your commits its time to check that everything worked, run the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# On branch wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
# Your branch is ahead of &#039;origin/MOODLE_20_STABLE&#039; by 1 commit.&lt;br /&gt;
#&lt;br /&gt;
nothing to commit (working directory clean)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very handy as it tells you that your branch is ahead of the offical MOODLE_20_STABLE branch by one commit.&lt;br /&gt;
You can also check that your commit contains the changes you think by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git diff origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the changes you have made as a diff.&lt;br /&gt;
&lt;br /&gt;
Now that you know that your commit is there you and that it is correct it is time to push it to your github account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And thats it.&lt;br /&gt;
&lt;br /&gt;
You github account should now have two branches on it:&lt;br /&gt;
&lt;br /&gt;
; wip-MDL-12345-master : This branch is the changes you have made for the master branch&lt;br /&gt;
; wip-MDL-12345-MOODLE_20_STABLE : This branch is those same changes but for the MOODLE_20_STABLE branch&lt;br /&gt;
&lt;br /&gt;
Now you are ready to create PULL requests so that your work gets reviewed and hopefully integrated.&lt;br /&gt;
&lt;br /&gt;
==Creating PULL requests==&lt;br /&gt;
Now that you&#039;ve got a branch with changes for your MDL issue its time to create some PULL requests to get it integrated.&lt;br /&gt;
&lt;br /&gt;
===Creating a PULL request for the master branch===&lt;br /&gt;
&lt;br /&gt;
So you have successfully fixed the bug MDL-12345, you have created two branches one for master and one for MOODLE_20_STABLE. It is time to create a PULL request for each of these branches.&lt;br /&gt;
&lt;br /&gt;
First lets create a PULL request for the master branch:&lt;br /&gt;
&lt;br /&gt;
# Browse to tracker.moodle.org/browse/MDL-12345&lt;br /&gt;
# When the page loads log in if you haven&#039;t already.&lt;br /&gt;
# Click on the button in the top right labelled `Create issue`&lt;br /&gt;
# Change Project to `Pull Requests`&lt;br /&gt;
# Change Issue type to `Pull Request`&lt;br /&gt;
# Click create&lt;br /&gt;
&lt;br /&gt;
This takes you to a screen where you can enter the details for the PULL request.&lt;br /&gt;
&lt;br /&gt;
You should fill it out in the following way:&lt;br /&gt;
&lt;br /&gt;
====Summary====&lt;br /&gt;
This is the summary for the PULL request, you should copy and paste the summary from the MDL issue here.&lt;br /&gt;
For MDL-12345 the summary is `alphabetization of UI different on left and right sides` so that&#039;s what I will use.&lt;br /&gt;
&lt;br /&gt;
====Affects Versions====&lt;br /&gt;
This is the version that your branch is changing, in the case of this PULL request I will select `master`.&lt;br /&gt;
&lt;br /&gt;
====Security level====&lt;br /&gt;
If the issue you are working on is a security issue you should set this to the same level that the issue is set to. If its not a security issue or you don&#039;t know just leave it as none.&lt;br /&gt;
&lt;br /&gt;
====Pull from repository====&lt;br /&gt;
This is the repository that the branch is at, for you this will be your github accont. If you head to http://github.com/yourname/moodle you will see a box that has three options SSH, HTTP, and Git read only, click Git Read Only and then copy the contents of the text box into the repositry field of the PULL request. &lt;br /&gt;
For me that is git://github.com/yourname/moodle.git&lt;br /&gt;
&lt;br /&gt;
====Pull branch====&lt;br /&gt;
This is the name of the branch that contains your changes. For me that is wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
====Pull Diff URL====&lt;br /&gt;
This is the URL to a page that shows the changes that you&#039;ve made on your branch. Github is nice in that it has a pretty interface for that. To get to the interface follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Browse to https://github.com/youraccount/moodle&lt;br /&gt;
# Click `Switch Branches` and then click on the branch you changes are based upon, in my case master.&lt;br /&gt;
# Click the button labelled `Branch List`&lt;br /&gt;
# Locate your branch in the list and click the `Compare button` for me this was the compare button to the right of wip-MDL-12345-master.&lt;br /&gt;
# Copy the URL in your browse and paste it into the Pull Diff URL of the PULL request.&lt;br /&gt;
&lt;br /&gt;
For me this URL was: https://github.com/yourname/moodle/compare/master...wip-MDL-23532-master&lt;br /&gt;
For the MOODLE_20_STABLE branch this would be: https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
&lt;br /&gt;
====Description====&lt;br /&gt;
The description should contain several bits of important information:&lt;br /&gt;
&lt;br /&gt;
# A short description of what your patch does&lt;br /&gt;
# Notes about that changes you&#039;ve made that might help the integrator understand what you did when he/she is reviewing it.&lt;br /&gt;
# Testing instructions that guide the testers through testing your changes.&lt;br /&gt;
&lt;br /&gt;
====Components====&lt;br /&gt;
Select general from the components list, general is the only option.&lt;br /&gt;
&lt;br /&gt;
====Finishing up====&lt;br /&gt;
Once you have filled in the fields as above click `Create`. This should create you PULL request and then take you to view it.&lt;br /&gt;
&lt;br /&gt;
Its important to remember that there is still one thing you need to do and that is link to the original issue.&lt;br /&gt;
While you are still logged in click the `More Actions` button and select `Link issue`, in the dialoug that pops up change the `This issue` field to `will help resolve`, type MDL-12345 into the issues field, and then type `Linking to MDL-12345` into the comments box. Once you&#039;ve done that simple click Link.&amp;lt;br /&amp;gt;I should add that the comment isn&#039;t really required. It&#039;s just something I personally like doing.&lt;br /&gt;
&lt;br /&gt;
Time to create the PULL request for the other branches.&lt;br /&gt;
&lt;br /&gt;
===Creating the PULL request for MOODLE_20_STABLE===&lt;br /&gt;
Once you&#039;ve created the PULL request for the master branch it is time to create the PULL request for the MOODLE_20_STABLE branch.&lt;br /&gt;
This is as easy as can be, click Create Issue in the top right, select PULL project and choose Pull Request and then click create.&lt;br /&gt;
On the next screen enter the following details:&lt;br /&gt;
&lt;br /&gt;
; Summary : Copy the summary from the previous PULL Request&lt;br /&gt;
; Affects Versions : Select MOODLE_20_STABLE&lt;br /&gt;
; Security level : Same as the MDL&lt;br /&gt;
; Pull from repository : Copy from the previous PULL request&lt;br /&gt;
; Pull Branch : wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
; Pull Diff URL : https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
; Description : Copy from the previous PULL request&lt;br /&gt;
; Component : general&lt;br /&gt;
&lt;br /&gt;
Then click create to create the PULL request.&lt;br /&gt;
&lt;br /&gt;
Once the PULL request has been create don&#039;t forget to link to the MDL issue like we did for the previous PULL request.&lt;br /&gt;
&lt;br /&gt;
==Resolving the issue==&lt;br /&gt;
The final step for the MDL issue now that you have created the two PULL requests is to Resolve the issue (do not close it, just resolve).&lt;br /&gt;
&lt;br /&gt;
You can do this by logging into tracker, browsing to the MDL issue, and clicking the resolve button.&lt;br /&gt;
&lt;br /&gt;
If your fixes are integrated the tester will close the issue, otherwise if it doesn&#039;t get integrated someone will reopen the MDL.&lt;br /&gt;
&lt;br /&gt;
==Rebasing after the weekly release==&lt;br /&gt;
As many of you will be aware on Wednesday after the latest weekly has been released a comment will be added to all PULL requests that are still open.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The main moodle.git repository has just been updated with latest weekly modifications.&lt;br /&gt;
You may wish to rebase your PULL branches to simplify history and avoid any possible merge conflicts. This would also make integrator&#039;s life easier next week.&lt;br /&gt;
&lt;br /&gt;
TIA and ciao :)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is a message that is bulk added as is done so as a polite request. While it&#039;s not essential for you to rebase your work it really does help the integrators as its much easier to see what is going on and greatly reduces the chance of conflicts (because you&#039;ll solve them when you rebase).&lt;br /&gt;
&lt;br /&gt;
The good news is that rebasing your work is EASY!&lt;br /&gt;
&lt;br /&gt;
For the following example lets assume I created the two PULL requests above on Wednesday morning and the weekly was released on Wednesday afternoon. This means that my branch doesn&#039;t have the changes that have just been released and I need to rebase them.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Rebasing the wip-MDL-12345-master===&lt;br /&gt;
&lt;br /&gt;
The first step is to rebase my work that is based upon the master branch. So first move to the master repository.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next thing we have to do is get all of the changes from the remote repositories, this will fetch down all of the latest changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now before the next step make sure that you don&#039;t have any uncommit changes, if you do finish that work, commit it, then proceed to the next step which is updating your local master.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
git push master github&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that your local master is up to date, and has you&#039;ve updated you master branch at github you are ready to rebase!&lt;br /&gt;
At this point we want to checkout the branch we are going to rebase, in this case wip-MDL-12345-master and then we are going to rebase origin/master which is the official Moodle master branch (and the branch our branch is based upon).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout wip-MDL-12345-master&lt;br /&gt;
git rebase origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that command has completed your branch wip-MDL-12345-master will be completely up to date. Before you are done however you need to push the rebased wip-MDL-12345-master up to your github account so that its the branch the integrator sees.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push -f github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that command is just about identical to the command we used when we first pushed our branch to our github account, there is however one VERY important difference, the &#039;&#039;&#039;-f&#039;&#039;&#039; option.&lt;br /&gt;
The &#039;&#039;&#039;-f&#039;&#039;&#039; option tells git to force the push, this is required because when you rebase all of your commit id&#039;s will change and unless you tell git to force it will see that they have changed and not allow you to push your work.&lt;br /&gt;
&lt;br /&gt;
Thats it! you&#039;ve now rebased your work and the integrators will be happy again :)&lt;br /&gt;
&lt;br /&gt;
===Step 2: Rebasing wip-MDL-12345-MOODLE_20_STABLE===&lt;br /&gt;
Now that we&#039;ve rebased our work that was based upon the master branch it is time to rebase the MOODLE_20_STABLE version.&lt;br /&gt;
This step is just about identical to the previous step except we substitute &#039;&#039;master&#039;&#039; for &#039;&#039;MOODLE_20_STABLE&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github MOODLE_20_STABLE&lt;br /&gt;
git checkout wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
git rebase origin/MOODLE_20_STABLE&lt;br /&gt;
git push -f github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&lt;br /&gt;
==What to do when your work gets rejected==&lt;br /&gt;
&lt;br /&gt;
==The extra mile==&lt;br /&gt;
Now as many of you may have guessed by the time you are working on several different issues and managing several repositories the process I&#039;ve described here seems VERY repetitive. And it &#039;&#039;&#039;IS!&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
If you talk to any HQ developer they will tell you they deal with it in their own way, anything from scripts, to custom config files, through to virtual machine snapshots.&lt;br /&gt;
&lt;br /&gt;
Personally I have a couple of bash scripts that I wrote to help me manage my workflow.&lt;br /&gt;
&lt;br /&gt;
The first script I use I run after each weekly release and it does the following things:&lt;br /&gt;
&lt;br /&gt;
* Moves to each repository and does the following&lt;br /&gt;
*# Fetches all remote changes&lt;br /&gt;
*# Checks whether it is safe to update my local main release branches and does that if it is safe&lt;br /&gt;
*# Updates all main release branches on my github account&lt;br /&gt;
&lt;br /&gt;
The second script I run on every site that I have installed, it does the following&lt;br /&gt;
&lt;br /&gt;
* Goes to each site I have installed and does the following&lt;br /&gt;
*# Overwrites the database with a stable snapshot&lt;br /&gt;
*# Overwrites the moodle data directory with a stable snapshot taken at the same time as the database one.&lt;br /&gt;
*# Upgrades the moodle site if required&lt;br /&gt;
*# Takes a snapshot of the database and Moodle data directory.&lt;br /&gt;
&lt;br /&gt;
The third script I run whenever I start working on a new issue and it restores the stable snapshot of a sites database and moodle data directory.&lt;br /&gt;
&lt;br /&gt;
These three scripts allow me to very easily ensure I am working with the latest changes and that I can easily restore to a point I know is stable and safe.&lt;br /&gt;
&lt;br /&gt;
There was a fourth script I used to use but don&#039;t any more that also rebased any unmerged branches however I found it to be far to problematic and I prefer to do it myself so that I know exactly what is going on.&lt;br /&gt;
&lt;br /&gt;
==Useful links==&lt;br /&gt;
The following are links I found useful while learning Git.&lt;br /&gt;
&lt;br /&gt;
* [http://help.github.com Github help (http://help.github.com)] Provides EXCELLENT help tutorials that very clearly explain the basic through to the advanced.&lt;br /&gt;
* [http://cheat.errtheblog.com/s/git/ $ cheat git] This is my favourite cheat sheet, straight forward to the point, if you know the concept you&#039;ll find the answer here.&lt;br /&gt;
* [http://gitster.livejournal.com/28309.html Gitsters journal - Fun with FETCH_HEAD] David Mudrak pointed me at this entry which I found INCREDIBLY useful when reviewing other peoples work.&lt;br /&gt;
* [[Development:Git tips]] Moodle docs page with a few handy tips about using Git for Moodle development.&lt;br /&gt;
&lt;br /&gt;
I you&#039;re looking to read/buy a book on Git I&#039;d strongly recommend [http://progit.org/ Pro Git]. I certainly found that the most useful book I read.&lt;br /&gt;
&lt;br /&gt;
[[Category:Git]]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82881</id>
		<title>User:Sam Hemelryk/My Moodle Git workflow</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82881"/>
		<updated>2011-04-19T03:16:04Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* Creating the PULL request for MOODLE_20_STABLE */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document is a sort of tutorial/inspection of my personal development workflow when working on Moodle with Git.&lt;br /&gt;
&lt;br /&gt;
==Creating the repositories==&lt;br /&gt;
Ok so the very first step is to create several Moodle git repositories, one for each major branch of Moodle being worked on.&lt;br /&gt;
&lt;br /&gt;
At the time of writing the major branches are MOODLE_19_STABLE, MOODLE_20_STABLE and master.&lt;br /&gt;
&lt;br /&gt;
The reason for this is that that way we have a separate site for each Moodle branch that we can test on easily. Yes you will have three sites but you won&#039;t have to worry about swtiching your site when you change branches.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Create a directory to create the repositories within===&lt;br /&gt;
&lt;br /&gt;
Personally I use Ubuntu (Linux) and I chose to create my repositories within a folder I created in /var/www. If you are using windows I would instead suggest creating C:/www/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www&lt;br /&gt;
mkdir repositories&lt;br /&gt;
cd repositories&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 2: Create a master repository===&lt;br /&gt;
This is the easiest of the branches to create a repository for.&lt;br /&gt;
&lt;br /&gt;
Within your repositories directory create a new directory called master and move into it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir master&lt;br /&gt;
cd master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we want to clone the Moodle source from the offical Moodle git repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new directory called moodle within the master directory we created just before.&lt;br /&gt;
&lt;br /&gt;
That new moodle directory should contain the Moodle source code as a git repository.&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our main git repository we need to add our github account as a remote so that we can push to it later:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd moodle&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This adds your moodle repository on github as a remote called github that you can push to later.&lt;br /&gt;
&lt;br /&gt;
Finally before we move onto the next repository we need to create a data directory because we know we will need that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 3: Create a MOODLE_20_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
The next repository we create will be for the MOODLE_20_STABLE branch.&lt;br /&gt;
To start with get back to the repositories directory that we created earlier and create a directory called MOODLE_20_STABLE within that.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_20_STABLE&lt;br /&gt;
cd MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now create a new clone of the main Moodle repository like we did for the master branch above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have done that move into the moodle directory.&lt;br /&gt;
&lt;br /&gt;
By default the master branch is the branch that is created, however we don&#039;t want that for this repository. Instead we want the MOODLE_20_STABLE branch.&lt;br /&gt;
&lt;br /&gt;
To do this we checkout local branch based upon the official MOODLE_20_STABLE branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have created that branch we can delete the local master branch so that we don&#039;t accidentally ever work on it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git branch -D master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then like we did for master we add our github repository as a remote:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And finally create a data directory we can use when we have install the site:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 4: Create a MOODLE_19_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
This step is identical to the above step except we are using the MOODLE_19_STABLE branch instead of the MOODLE_20_STABLE branch.&lt;br /&gt;
The commands for this are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_19_STABLE&lt;br /&gt;
cd MOODLE_19_STABLE&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
git checkout -b MOODLE_19_STABLE origin/MOODLE_19_STABLE&lt;br /&gt;
git branch -D master&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 5: Install the sites===&lt;br /&gt;
Now I can&#039;t tell you how to do this on your own machine however what I would recommend is that you create a link from your web root to the moodle directory of each branch.&lt;br /&gt;
&lt;br /&gt;
If you are using linux and your webroot is /var/www/localhost you would do it as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/localhost/&lt;br /&gt;
ln -s /var/www/repositories/master/moodle master&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_20_STABLE/moodle MOODLE_20_STABLE&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_19_STABLE/moodle MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done you should be able to browse to each repository with the following URL&#039;s&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://localhost/master/&lt;br /&gt;
http://localhost/MOODLE_20_STABLE/&lt;br /&gt;
http://localhost/MOODLE_19_STABLE/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that is done you need to browse to each site and complete the installation.&lt;br /&gt;
&lt;br /&gt;
Under this method your will need to ensure you set the configuration option sessioncookiepath to the URI of your site. You can either do this in the admin interfaces or add the following to your config.php file for each site.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// For the master site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/master/&#039;;&lt;br /&gt;
// For the MOODLE_20_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_20_STABLE/&#039;;&lt;br /&gt;
// For the MOODLE_19_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_19_STABLE/&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Failure to do this will mean that when you log in at one site and then visit the next you will have to log in again and your session on the first site will no longer work.&lt;br /&gt;
&lt;br /&gt;
Now that you have got 3 repositories, one for each main branch, and set up a site for each you are ready to start development.&lt;br /&gt;
&lt;br /&gt;
==Before you start work each day==&lt;br /&gt;
Before you start work each day you should update each of the repositories you have created to ensure that you are always working with up to date versions of Moodle.&lt;br /&gt;
&lt;br /&gt;
You should also take this opportunity to update the repositories on your github account to ensure they are always up to date.&lt;br /&gt;
&lt;br /&gt;
To start with lets update the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This moves to the master repository and then tells git for fetch all of the changes from your remote repositories and clean up any old branches it is aware of.&lt;br /&gt;
&lt;br /&gt;
Once that operation has completed you should update your master branch&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Before you do that it pays to make sure you don&#039;t have any uncommit changes, if you do DON&#039;T TRY IT. There would be a good chance you will encounter problems. Instead finish what you are working on, commit your changes and then update your master branch.&lt;br /&gt;
&lt;br /&gt;
Next we will update the github repositories by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github refs/remotes/origin/master:master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This tells git to push the master branch from origin (the offical Moodle repository) to the master branch on our github account.&lt;br /&gt;
&lt;br /&gt;
Now that you&#039;ve updated the master repository and your github account its time to update the MOODLE_20_STABLE and MOODLE_19_STABLE branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_20_STABLE:MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_19_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_19_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_19_STABLE:MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Working on a Moodle issue==&lt;br /&gt;
&lt;br /&gt;
This part of the document looks at how I go about working on an MDL issue from the Moodle tracker.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ we use the scrum methodology we sees us choose several issues to include in a scrum which we then work on for the period of the scrum. As a community member its more likely you will just be choosing issues that you are passionate about.&lt;br /&gt;
&lt;br /&gt;
Either way once you have found an issue to work on you are ready to start.&lt;br /&gt;
&lt;br /&gt;
For the purpose of this part of the document lets say I am going to work on bug MDL-12345.&lt;br /&gt;
&lt;br /&gt;
==Fixing a bug on the master repository - MDL-12345==&lt;br /&gt;
&lt;br /&gt;
The first step is to create a local branch to make changes on, to do this we will start our work on the master repository.&lt;br /&gt;
&lt;br /&gt;
When fixing an issue I find it easiest to fix the issue on the master branch first and then move my changes to the other branches.&lt;br /&gt;
&lt;br /&gt;
The VERY first thing you should do when you start working on a Moodle issue is make sure you have assigned it to yourself and then click the start progress button.&lt;br /&gt;
&lt;br /&gt;
This way other users know that you are activly working on the bug and no one from HQ will steal it from you.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local branch===&lt;br /&gt;
&lt;br /&gt;
So first get to the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there we create a new branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-master origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command checks out a new branch called wip-MDL-12345-master that is based upon origin/master.&lt;br /&gt;
&lt;br /&gt;
origin/master is of course the master branch on the official Moodle repository (git.moodle.org/moodle.git).&lt;br /&gt;
&lt;br /&gt;
The name of the branch is also very important. It is essentially telling us three things.&lt;br /&gt;
&lt;br /&gt;
; wip : This stands for work in progress, it helps people see that you are currently working on this branch and that they shouldn&#039;t base there work on it because it will likely change.&lt;br /&gt;
; MDL-12345 : This is of course the Moodle bug number. It helps people quickly identify what you are working on.&lt;br /&gt;
; master : This is the branch we are making changes on. It helps people quickly understand where the changes are being made.&lt;br /&gt;
&lt;br /&gt;
You can optionally add more to the end of the branch name such as a key word that identifies the area or a date at which you started work e.g.&lt;br /&gt;
&lt;br /&gt;
* wip-MDL-12345-master-navigation-changes&lt;br /&gt;
* wip-MDL-12345-master-20110418&lt;br /&gt;
&lt;br /&gt;
That is up to you, personally I&#039;m not a fan of it, however the rest is all required to help integrate your work.&lt;br /&gt;
&lt;br /&gt;
Either way now you have a branch, mine is called wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Make changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have created you branch you are ready to make changes.&lt;br /&gt;
&lt;br /&gt;
I&#039;ll let you make whatever changes you are need, once you have made changes move onto the next step.&lt;br /&gt;
&lt;br /&gt;
Before you do move on however make sure that your code meets the high quality of code Moodle requires.&lt;br /&gt;
&lt;br /&gt;
You can find information about that on the moodle docs here: https://docs.moodle.org/en/Development:Coding_style&lt;br /&gt;
&lt;br /&gt;
The following are common mistakes:&lt;br /&gt;
&lt;br /&gt;
* Incorrect white space&lt;br /&gt;
** Tabs instead of spaces&lt;br /&gt;
** Extra spaces at the end of lines&lt;br /&gt;
** Multiple new lines&lt;br /&gt;
** Forgetting to put spaces between function arguments&lt;br /&gt;
* Incorrect commit messages (read on to find out about writing a good commit message)&lt;br /&gt;
* Incorrect variable or function names&lt;br /&gt;
&lt;br /&gt;
Making these sort of mistakes can lead to your code being rejected despite it working correctly.&lt;br /&gt;
&lt;br /&gt;
I would &#039;&#039;&#039;strongly&#039;&#039;&#039; suggest while learning Moodle development that you use [[User:Tim Hunt|Tim Hunt&#039;s]] fantastic [https://github.com/timhunt/moodle-local_codechecker Code Checker] plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
You&#039;ll find information on how to use it within its README file and it will pick up many of the things that may lead to your work being rejected.&lt;br /&gt;
&lt;br /&gt;
Or course it will be reviewed in regards to security, usability and the other important factors of code development.&lt;br /&gt;
&lt;br /&gt;
===Step 3: Commit your changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have made your changes you are getting ready to commit them.&lt;br /&gt;
&lt;br /&gt;
The first thing to do is check your changes. To do this run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see all of the files you have changes highlighted in red.&lt;br /&gt;
&lt;br /&gt;
Next you need to stage all of the files you want to commit.&lt;br /&gt;
&lt;br /&gt;
To do this you add the files to the stage using the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git add lib/modifiedfile.php&lt;br /&gt;
git add lib/newfile.php&lt;br /&gt;
git add theme/base/style/core.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Why not just commit all changes. Many of the git guides you read will tell you above git commit -a which commits all of the changes you have made.&lt;br /&gt;
&lt;br /&gt;
We&#039;ve hardly being using git here at Moodle and already I&#039;ve seen several people accidentally commit changes that they didn&#039;t mean to.&lt;br /&gt;
&lt;br /&gt;
Staging files like this ENSURES you only commit things you intend to.&lt;br /&gt;
&lt;br /&gt;
Now that you have staged your changes/new files you are ready to commit. The following command commits your changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git commit -m &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command commits your changes with the commit message &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;.&lt;br /&gt;
It&#039;s very important to Moodle that you format your commit messages like this.&lt;br /&gt;
They consist of three parts:&lt;br /&gt;
&lt;br /&gt;
# The MDL bug number in this case MDL-12345&lt;br /&gt;
# The area you made changes to in this case enrol&lt;br /&gt;
# A short description of what you did, in this case I fixed a couple of enrolment bugs.&lt;br /&gt;
&lt;br /&gt;
When you commit your message you will see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[master 19a484e] changes&lt;br /&gt;
 1 files changed, 16 insertions(+), 18 deletions(-)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
There is one thing here you need to note down for later, that is the number that appears within the square brackets after the branch name, in my case it is 19a484e. This is the commit id of the commit I just made.&lt;br /&gt;
&lt;br /&gt;
===Step 4: Pushing your changes to your github account===&lt;br /&gt;
&lt;br /&gt;
Now that you have made changes to your local branch you should push it to your github account so that it can be reviewed and hopefully integrated into Moodle.&lt;br /&gt;
&lt;br /&gt;
Doing this is very simple just run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are telling git to push the branch wip-MDL-12345-master to the remote called github which we added when setting up our git repositories.&lt;br /&gt;
And just like that you&#039;ve made a branch that contains your work and pushed it to github ready to get it reviewed.&lt;br /&gt;
&lt;br /&gt;
==Moving your changes to another branch==&lt;br /&gt;
Now that you have made changes to the master branch you need to decide whether it is appropriate make those changes on any of the other branches.&lt;br /&gt;
Most likely if you are fixing a bug you will need to make the changes on the MOODLE_20_STABLE branch as well, and perhaps the MOODLE_19_STABLE branch if it is a security bug.&lt;br /&gt;
&lt;br /&gt;
Lets assume for MDL-12345 that I fixed earlier that it should be ported to MOODLE_20_STABLE as well.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local MOODLE_20_STABLE branch===&lt;br /&gt;
&lt;br /&gt;
To start with I need to move to the MOODLE_20_STABLE repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there I need to create a new branch based upon the MOODLE_20_STABLE branch that is going to contain my changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very similar to the branch we created for the changes to the master branch except that I have subsituted MOODLE_20_STABLE in place of master. This is because the new branch we are creating is based upon the MOODLE_20_STABLE branch on the offical Moodle git repository and contains changes for that branch.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Cherry-picking my changes===&lt;br /&gt;
Once we have a branch for our changes I am ready to make them again. There is however with git an easy way to do this, cherry-picking.&lt;br /&gt;
&lt;br /&gt;
Cherry-picking is the process of copying a single commit from one branch to another. In this case I want to cherry pick the commit I made earlier onto the branch I&#039;ve just created.&lt;br /&gt;
&lt;br /&gt;
However before I can do this I need to fetch the changes I made from the github repository. I need to do this because I made that changes of a totally separate local repository remember.&lt;br /&gt;
&lt;br /&gt;
So to update my repository with the latest changes I run the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command tells git to look at each remote and get any new changes (it also removes any branches that have been deleted).&lt;br /&gt;
Once it has completed you will be ready to cherry pick the commit. To do so you use the following command but replace my commit is with yours.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git cherry-pick 19a484e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Providing there are no conflicts your branch will now contain a copy of the changes you made to the master branch.&lt;br /&gt;
If there are conficts that you will need to resolve them and commit your changes however you can search for another tutorial about how to do that,&lt;br /&gt;
&lt;br /&gt;
Now I know at this point that there will be some of you who are saying &#039;Whoops I forgot what my commit id was!&#039;. If this is you don&#039;t worry, its pretty easy to find it providing you used a proper commit message like I described above.&lt;br /&gt;
Simply run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git log --oneline origin/master..github/wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the commits that are in the wip-MDL-12345-master at your github account but are not in the master branch at the offical Moodle repository.&lt;br /&gt;
You can then cherry-pick the commits shown there (the commit ID&#039;s should be highlighted in yellow).&lt;br /&gt;
&lt;br /&gt;
Once you have cherry-picked your commits its time to check that everything worked, run the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# On branch wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
# Your branch is ahead of &#039;origin/MOODLE_20_STABLE&#039; by 1 commit.&lt;br /&gt;
#&lt;br /&gt;
nothing to commit (working directory clean)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very handy as it tells you that your branch is ahead of the offical MOODLE_20_STABLE branch by one commit.&lt;br /&gt;
You can also check that your commit contains the changes you think by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git diff origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the changes you have made as a diff.&lt;br /&gt;
&lt;br /&gt;
Now that you know that your commit is there you and that it is correct it is time to push it to your github account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And thats it.&lt;br /&gt;
&lt;br /&gt;
You github account should now have two branches on it:&lt;br /&gt;
&lt;br /&gt;
; wip-MDL-12345-master : This branch is the changes you have made for the master branch&lt;br /&gt;
; wip-MDL-12345-MOODLE_20_STABLE : This branch is those same changes but for the MOODLE_20_STABLE branch&lt;br /&gt;
&lt;br /&gt;
Now you are ready to create PULL requests so that your work gets reviewed and hopefully integrated.&lt;br /&gt;
&lt;br /&gt;
==Creating PULL requests==&lt;br /&gt;
Now that you&#039;ve got a branch with changes for your MDL issue its time to create some PULL requests to get it integrated.&lt;br /&gt;
&lt;br /&gt;
===Creating a PULL request for the master branch===&lt;br /&gt;
&lt;br /&gt;
So you have successfully fixed the bug MDL-12345, you have created two branches one for master and one for MOODLE_20_STABLE. It is time to create a PULL request for each of these branches.&lt;br /&gt;
&lt;br /&gt;
First lets create a PULL request for the master branch:&lt;br /&gt;
&lt;br /&gt;
# Browse to tracker.moodle.org/browse/MDL-12345&lt;br /&gt;
# When the page loads log in if you haven&#039;t already.&lt;br /&gt;
# Click on the button in the top right labelled `Create issue`&lt;br /&gt;
# Change Project to `Pull Requests`&lt;br /&gt;
# Change Issue type to `Pull Request`&lt;br /&gt;
# Click create&lt;br /&gt;
&lt;br /&gt;
This takes you to a screen where you can enter the details for the PULL request.&lt;br /&gt;
&lt;br /&gt;
You should fill it out in the following way:&lt;br /&gt;
&lt;br /&gt;
====Summary====&lt;br /&gt;
This is the summary for the PULL request, you should copy and paste the summary from the MDL issue here.&lt;br /&gt;
For MDL-12345 the summary is `alphabetization of UI different on left and right sides` so that&#039;s what I will use.&lt;br /&gt;
&lt;br /&gt;
====Affects Versions====&lt;br /&gt;
This is the version that your branch is changing, in the case of this PULL request I will select `master`.&lt;br /&gt;
&lt;br /&gt;
====Security level====&lt;br /&gt;
If the issue you are working on is a security issue you should set this to the same level that the issue is set to. If its not a security issue or you don&#039;t know just leave it as none.&lt;br /&gt;
&lt;br /&gt;
====Pull from repository====&lt;br /&gt;
This is the repository that the branch is at, for you this will be your github accont. If you head to http://github.com/yourname/moodle you will see a box that has three options SSH, HTTP, and Git read only, click Git Read Only and then copy the contents of the text box into the repositry field of the PULL request. &lt;br /&gt;
For me that is git://github.com/yourname/moodle.git&lt;br /&gt;
&lt;br /&gt;
====Pull branch====&lt;br /&gt;
This is the name of the branch that contains your changes. For me that is wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
====Pull Diff URL====&lt;br /&gt;
This is the URL to a page that shows the changes that you&#039;ve made on your branch. Github is nice in that it has a pretty interface for that. To get to the interface follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Browse to https://github.com/youraccount/moodle&lt;br /&gt;
# Click `Switch Branches` and then click on the branch you changes are based upon, in my case master.&lt;br /&gt;
# Click the button labelled `Branch List`&lt;br /&gt;
# Locate your branch in the list and click the `Compare button` for me this was the compare button to the right of wip-MDL-12345-master.&lt;br /&gt;
# Copy the URL in your browse and paste it into the Pull Diff URL of the PULL request.&lt;br /&gt;
&lt;br /&gt;
For me this URL was: https://github.com/yourname/moodle/compare/master...wip-MDL-23532-master&lt;br /&gt;
For the MOODLE_20_STABLE branch this would be: https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
&lt;br /&gt;
====Description====&lt;br /&gt;
The description should contain several bits of important information:&lt;br /&gt;
&lt;br /&gt;
# A short description of what your patch does&lt;br /&gt;
# Notes about that changes you&#039;ve made that might help the integrator understand what you did when he/she is reviewing it.&lt;br /&gt;
# Testing instructions that guide the testers through testing your changes.&lt;br /&gt;
&lt;br /&gt;
====Components====&lt;br /&gt;
Select general from the components list, general is the only option.&lt;br /&gt;
&lt;br /&gt;
====Finishing up====&lt;br /&gt;
Once you have filled in the fields as above click `Create`. This should create you PULL request and then take you to view it.&lt;br /&gt;
&lt;br /&gt;
Its important to remember that there is still one thing you need to do and that is link to the original issue.&lt;br /&gt;
While you are still logged in click the `More Actions` button and select `Link issue`, in the dialoug that pops up change the `This issue` field to `will help resolve`, type MDL-12345 into the issues field, and then type `Linking to MDL-12345` into the comments box. Once you&#039;ve done that simple click Link.&amp;lt;br /&amp;gt;I should add that the comment isn&#039;t really required. It&#039;s just something I personally like doing.&lt;br /&gt;
&lt;br /&gt;
Time to create the PULL request for the other branches.&lt;br /&gt;
&lt;br /&gt;
===Creating the PULL request for MOODLE_20_STABLE===&lt;br /&gt;
Once you&#039;ve created the PULL request for the master branch it is time to create the PULL request for the MOODLE_20_STABLE branch.&lt;br /&gt;
This is as easy as can be, click Create Issue in the top right, select PULL project and choose Pull Request and then click create.&lt;br /&gt;
On the next screen enter the following details:&lt;br /&gt;
&lt;br /&gt;
; Summary : Copy the summary from the previous PULL Request&lt;br /&gt;
; Affects Versions : Select MOODLE_20_STABLE&lt;br /&gt;
; Security level : Same as the MDL&lt;br /&gt;
; Pull from repository : Copy from the previous PULL request&lt;br /&gt;
; Pull Branch : wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
; Pull Diff URL : https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
; Description : Copy from the previous PULL request&lt;br /&gt;
; Component : general&lt;br /&gt;
&lt;br /&gt;
Then click create to create the PULL request.&lt;br /&gt;
&lt;br /&gt;
Once the PULL request has been create don&#039;t forget to link to the MDL issue like we did for the previous PULL request.&lt;br /&gt;
&lt;br /&gt;
==Resolving the issue==&lt;br /&gt;
The final step for the MDL issue now that you have created the two PULL requests is to Resolve the issue (do not close it, just resolve).&lt;br /&gt;
&lt;br /&gt;
You can do this by logging into tracker, browsing to the MDL issue, and clicking the resolve button.&lt;br /&gt;
&lt;br /&gt;
If your fixes are integrated the tester will close the issue, otherwise if it doesn&#039;t get integrated someone will reopen the MDL.&lt;br /&gt;
&lt;br /&gt;
==Rebasing after the weekly release==&lt;br /&gt;
As many of you will be aware on Wednesday after the latest weekly has been released a comment will be added to all PULL requests that are still open.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The main moodle.git repository has just been updated with latest weekly modifications.&lt;br /&gt;
You may wish to rebase your PULL branches to simplify history and avoid any possible merge conflicts. This would also make integrator&#039;s life easier next week.&lt;br /&gt;
&lt;br /&gt;
TIA and ciao :)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is a message that is bulk added as is done so as a polite request. While it&#039;s not essential for you to rebase your work it really does help the integrators as its much easier to see what is going on and greatly reduces the chance of conflicts (because you&#039;ll solve them when you rebase).&lt;br /&gt;
&lt;br /&gt;
The good news is that rebasing your work is EASY!&lt;br /&gt;
&lt;br /&gt;
For the following example lets assume I created the two PULL requests above on Wednesday morning and the weekly was released on Wednesday afternoon. This means that my branch doesn&#039;t have the changes that have just been released and I need to rebase them.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Rebasing the wip-MDL-12345-master===&lt;br /&gt;
&lt;br /&gt;
The first step is to rebase my work that is based upon the master branch. So first move to the master repository.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next thing we have to do is get all of the changes from the remote repositories, this will fetch down all of the latest changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now before the next step make sure that you don&#039;t have any uncommit changes, if you do finish that work, commit it, then proceed to the next step which is updating your local master.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
git push master github&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that your local master is up to date, and has you&#039;ve updated you master branch at github you are ready to rebase!&lt;br /&gt;
At this point we want to checkout the branch we are going to rebase, in this case wip-MDL-12345-master and then we are going to rebase origin/master which is the official Moodle master branch (and the branch our branch is based upon).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout wip-MDL-12345-master&lt;br /&gt;
git rebase origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that command has completed your branch wip-MDL-12345-master will be completely up to date. Before you are done however you need to push the rebased wip-MDL-12345-master up to your github account so that its the branch the integrator sees.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push -f github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that command is just about identical to the command we used when we first pushed our branch to our github account, there is however one VERY important difference, the &#039;&#039;&#039;-f&#039;&#039;&#039; option.&lt;br /&gt;
The &#039;&#039;&#039;-f&#039;&#039;&#039; option tells git to force the push, this is required because when you rebase all of your commit id&#039;s will change and unless you tell git to force it will see that they have changed and not allow you to push your work.&lt;br /&gt;
&lt;br /&gt;
Thats it! you&#039;ve now rebased your work and the integrators will be happy again :)&lt;br /&gt;
&lt;br /&gt;
===Step 2: Rebasing wip-MDL-12345-MOODLE_20_STABLE===&lt;br /&gt;
Now that we&#039;ve rebased our work that was based upon the master branch it is time to rebase the MOODLE_20_STABLE version.&lt;br /&gt;
This step is just about identical to the previous step except we substitute &#039;&#039;master&#039;&#039; for &#039;&#039;MOODLE_20_STABLE&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github MOODLE_20_STABLE&lt;br /&gt;
git checkout wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
git rebase origin/MOODLE_20_STABLE&lt;br /&gt;
git push -f github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&lt;br /&gt;
==The extra mile==&lt;br /&gt;
Now as many of you may have guessed by the time you are working on several different issues and managing several repositories the process I&#039;ve described here seems VERY repetitive. And it &#039;&#039;&#039;IS!&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
If you talk to any HQ developer they will tell you they deal with it in their own way, anything from scripts, to custom config files, through to virtual machine snapshots.&lt;br /&gt;
&lt;br /&gt;
Personally I have a couple of bash scripts that I wrote to help me manage my workflow.&lt;br /&gt;
&lt;br /&gt;
The first script I use I run after each weekly release and it does the following things:&lt;br /&gt;
&lt;br /&gt;
* Moves to each repository and does the following&lt;br /&gt;
*# Fetches all remote changes&lt;br /&gt;
*# Checks whether it is safe to update my local main release branches and does that if it is safe&lt;br /&gt;
*# Updates all main release branches on my github account&lt;br /&gt;
&lt;br /&gt;
The second script I run on every site that I have installed, it does the following&lt;br /&gt;
&lt;br /&gt;
* Goes to each site I have installed and does the following&lt;br /&gt;
*# Overwrites the database with a stable snapshot&lt;br /&gt;
*# Overwrites the moodle data directory with a stable snapshot taken at the same time as the database one.&lt;br /&gt;
*# Upgrades the moodle site if required&lt;br /&gt;
*# Takes a snapshot of the database and Moodle data directory.&lt;br /&gt;
&lt;br /&gt;
The third script I run whenever I start working on a new issue and it restores the stable snapshot of a sites database and moodle data directory.&lt;br /&gt;
&lt;br /&gt;
These three scripts allow me to very easily ensure I am working with the latest changes and that I can easily restore to a point I know is stable and safe.&lt;br /&gt;
&lt;br /&gt;
There was a fourth script I used to use but don&#039;t any more that also rebased any unmerged branches however I found it to be far to problematic and I prefer to do it myself so that I know exactly what is going on.&lt;br /&gt;
&lt;br /&gt;
==Useful links==&lt;br /&gt;
The following are links I found useful while learning Git.&lt;br /&gt;
&lt;br /&gt;
* [http://help.github.com Github help (http://help.github.com)] Provides EXCELLENT help tutorials that very clearly explain the basic through to the advanced.&lt;br /&gt;
* [http://cheat.errtheblog.com/s/git/ $ cheat git] This is my favourite cheat sheet, straight forward to the point, if you know the concept you&#039;ll find the answer here.&lt;br /&gt;
* [http://gitster.livejournal.com/28309.html Gitsters journal - Fun with FETCH_HEAD] David Mudrak pointed me at this entry which I found INCREDIBLY useful when reviewing other peoples work.&lt;br /&gt;
* [[Development:Git tips]] Moodle docs page with a few handy tips about using Git for Moodle development.&lt;br /&gt;
&lt;br /&gt;
I you&#039;re looking to read/buy a book on Git I&#039;d strongly recommend [http://progit.org/ Pro Git]. I certainly found that the most useful book I read.&lt;br /&gt;
&lt;br /&gt;
[[Category:Git]]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82880</id>
		<title>User:Sam Hemelryk/My Moodle Git workflow</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82880"/>
		<updated>2011-04-19T03:15:48Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* Creating a PULL request for the master branch */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document is a sort of tutorial/inspection of my personal development workflow when working on Moodle with Git.&lt;br /&gt;
&lt;br /&gt;
==Creating the repositories==&lt;br /&gt;
Ok so the very first step is to create several Moodle git repositories, one for each major branch of Moodle being worked on.&lt;br /&gt;
&lt;br /&gt;
At the time of writing the major branches are MOODLE_19_STABLE, MOODLE_20_STABLE and master.&lt;br /&gt;
&lt;br /&gt;
The reason for this is that that way we have a separate site for each Moodle branch that we can test on easily. Yes you will have three sites but you won&#039;t have to worry about swtiching your site when you change branches.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Create a directory to create the repositories within===&lt;br /&gt;
&lt;br /&gt;
Personally I use Ubuntu (Linux) and I chose to create my repositories within a folder I created in /var/www. If you are using windows I would instead suggest creating C:/www/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www&lt;br /&gt;
mkdir repositories&lt;br /&gt;
cd repositories&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 2: Create a master repository===&lt;br /&gt;
This is the easiest of the branches to create a repository for.&lt;br /&gt;
&lt;br /&gt;
Within your repositories directory create a new directory called master and move into it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir master&lt;br /&gt;
cd master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we want to clone the Moodle source from the offical Moodle git repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new directory called moodle within the master directory we created just before.&lt;br /&gt;
&lt;br /&gt;
That new moodle directory should contain the Moodle source code as a git repository.&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our main git repository we need to add our github account as a remote so that we can push to it later:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd moodle&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This adds your moodle repository on github as a remote called github that you can push to later.&lt;br /&gt;
&lt;br /&gt;
Finally before we move onto the next repository we need to create a data directory because we know we will need that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 3: Create a MOODLE_20_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
The next repository we create will be for the MOODLE_20_STABLE branch.&lt;br /&gt;
To start with get back to the repositories directory that we created earlier and create a directory called MOODLE_20_STABLE within that.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_20_STABLE&lt;br /&gt;
cd MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now create a new clone of the main Moodle repository like we did for the master branch above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have done that move into the moodle directory.&lt;br /&gt;
&lt;br /&gt;
By default the master branch is the branch that is created, however we don&#039;t want that for this repository. Instead we want the MOODLE_20_STABLE branch.&lt;br /&gt;
&lt;br /&gt;
To do this we checkout local branch based upon the official MOODLE_20_STABLE branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have created that branch we can delete the local master branch so that we don&#039;t accidentally ever work on it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git branch -D master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then like we did for master we add our github repository as a remote:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And finally create a data directory we can use when we have install the site:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 4: Create a MOODLE_19_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
This step is identical to the above step except we are using the MOODLE_19_STABLE branch instead of the MOODLE_20_STABLE branch.&lt;br /&gt;
The commands for this are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_19_STABLE&lt;br /&gt;
cd MOODLE_19_STABLE&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
git checkout -b MOODLE_19_STABLE origin/MOODLE_19_STABLE&lt;br /&gt;
git branch -D master&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 5: Install the sites===&lt;br /&gt;
Now I can&#039;t tell you how to do this on your own machine however what I would recommend is that you create a link from your web root to the moodle directory of each branch.&lt;br /&gt;
&lt;br /&gt;
If you are using linux and your webroot is /var/www/localhost you would do it as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/localhost/&lt;br /&gt;
ln -s /var/www/repositories/master/moodle master&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_20_STABLE/moodle MOODLE_20_STABLE&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_19_STABLE/moodle MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done you should be able to browse to each repository with the following URL&#039;s&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://localhost/master/&lt;br /&gt;
http://localhost/MOODLE_20_STABLE/&lt;br /&gt;
http://localhost/MOODLE_19_STABLE/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that is done you need to browse to each site and complete the installation.&lt;br /&gt;
&lt;br /&gt;
Under this method your will need to ensure you set the configuration option sessioncookiepath to the URI of your site. You can either do this in the admin interfaces or add the following to your config.php file for each site.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// For the master site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/master/&#039;;&lt;br /&gt;
// For the MOODLE_20_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_20_STABLE/&#039;;&lt;br /&gt;
// For the MOODLE_19_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_19_STABLE/&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Failure to do this will mean that when you log in at one site and then visit the next you will have to log in again and your session on the first site will no longer work.&lt;br /&gt;
&lt;br /&gt;
Now that you have got 3 repositories, one for each main branch, and set up a site for each you are ready to start development.&lt;br /&gt;
&lt;br /&gt;
==Before you start work each day==&lt;br /&gt;
Before you start work each day you should update each of the repositories you have created to ensure that you are always working with up to date versions of Moodle.&lt;br /&gt;
&lt;br /&gt;
You should also take this opportunity to update the repositories on your github account to ensure they are always up to date.&lt;br /&gt;
&lt;br /&gt;
To start with lets update the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This moves to the master repository and then tells git for fetch all of the changes from your remote repositories and clean up any old branches it is aware of.&lt;br /&gt;
&lt;br /&gt;
Once that operation has completed you should update your master branch&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Before you do that it pays to make sure you don&#039;t have any uncommit changes, if you do DON&#039;T TRY IT. There would be a good chance you will encounter problems. Instead finish what you are working on, commit your changes and then update your master branch.&lt;br /&gt;
&lt;br /&gt;
Next we will update the github repositories by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github refs/remotes/origin/master:master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This tells git to push the master branch from origin (the offical Moodle repository) to the master branch on our github account.&lt;br /&gt;
&lt;br /&gt;
Now that you&#039;ve updated the master repository and your github account its time to update the MOODLE_20_STABLE and MOODLE_19_STABLE branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_20_STABLE:MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_19_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_19_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_19_STABLE:MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Working on a Moodle issue==&lt;br /&gt;
&lt;br /&gt;
This part of the document looks at how I go about working on an MDL issue from the Moodle tracker.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ we use the scrum methodology we sees us choose several issues to include in a scrum which we then work on for the period of the scrum. As a community member its more likely you will just be choosing issues that you are passionate about.&lt;br /&gt;
&lt;br /&gt;
Either way once you have found an issue to work on you are ready to start.&lt;br /&gt;
&lt;br /&gt;
For the purpose of this part of the document lets say I am going to work on bug MDL-12345.&lt;br /&gt;
&lt;br /&gt;
==Fixing a bug on the master repository - MDL-12345==&lt;br /&gt;
&lt;br /&gt;
The first step is to create a local branch to make changes on, to do this we will start our work on the master repository.&lt;br /&gt;
&lt;br /&gt;
When fixing an issue I find it easiest to fix the issue on the master branch first and then move my changes to the other branches.&lt;br /&gt;
&lt;br /&gt;
The VERY first thing you should do when you start working on a Moodle issue is make sure you have assigned it to yourself and then click the start progress button.&lt;br /&gt;
&lt;br /&gt;
This way other users know that you are activly working on the bug and no one from HQ will steal it from you.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local branch===&lt;br /&gt;
&lt;br /&gt;
So first get to the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there we create a new branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-master origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command checks out a new branch called wip-MDL-12345-master that is based upon origin/master.&lt;br /&gt;
&lt;br /&gt;
origin/master is of course the master branch on the official Moodle repository (git.moodle.org/moodle.git).&lt;br /&gt;
&lt;br /&gt;
The name of the branch is also very important. It is essentially telling us three things.&lt;br /&gt;
&lt;br /&gt;
; wip : This stands for work in progress, it helps people see that you are currently working on this branch and that they shouldn&#039;t base there work on it because it will likely change.&lt;br /&gt;
; MDL-12345 : This is of course the Moodle bug number. It helps people quickly identify what you are working on.&lt;br /&gt;
; master : This is the branch we are making changes on. It helps people quickly understand where the changes are being made.&lt;br /&gt;
&lt;br /&gt;
You can optionally add more to the end of the branch name such as a key word that identifies the area or a date at which you started work e.g.&lt;br /&gt;
&lt;br /&gt;
* wip-MDL-12345-master-navigation-changes&lt;br /&gt;
* wip-MDL-12345-master-20110418&lt;br /&gt;
&lt;br /&gt;
That is up to you, personally I&#039;m not a fan of it, however the rest is all required to help integrate your work.&lt;br /&gt;
&lt;br /&gt;
Either way now you have a branch, mine is called wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Make changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have created you branch you are ready to make changes.&lt;br /&gt;
&lt;br /&gt;
I&#039;ll let you make whatever changes you are need, once you have made changes move onto the next step.&lt;br /&gt;
&lt;br /&gt;
Before you do move on however make sure that your code meets the high quality of code Moodle requires.&lt;br /&gt;
&lt;br /&gt;
You can find information about that on the moodle docs here: https://docs.moodle.org/en/Development:Coding_style&lt;br /&gt;
&lt;br /&gt;
The following are common mistakes:&lt;br /&gt;
&lt;br /&gt;
* Incorrect white space&lt;br /&gt;
** Tabs instead of spaces&lt;br /&gt;
** Extra spaces at the end of lines&lt;br /&gt;
** Multiple new lines&lt;br /&gt;
** Forgetting to put spaces between function arguments&lt;br /&gt;
* Incorrect commit messages (read on to find out about writing a good commit message)&lt;br /&gt;
* Incorrect variable or function names&lt;br /&gt;
&lt;br /&gt;
Making these sort of mistakes can lead to your code being rejected despite it working correctly.&lt;br /&gt;
&lt;br /&gt;
I would &#039;&#039;&#039;strongly&#039;&#039;&#039; suggest while learning Moodle development that you use [[User:Tim Hunt|Tim Hunt&#039;s]] fantastic [https://github.com/timhunt/moodle-local_codechecker Code Checker] plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
You&#039;ll find information on how to use it within its README file and it will pick up many of the things that may lead to your work being rejected.&lt;br /&gt;
&lt;br /&gt;
Or course it will be reviewed in regards to security, usability and the other important factors of code development.&lt;br /&gt;
&lt;br /&gt;
===Step 3: Commit your changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have made your changes you are getting ready to commit them.&lt;br /&gt;
&lt;br /&gt;
The first thing to do is check your changes. To do this run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see all of the files you have changes highlighted in red.&lt;br /&gt;
&lt;br /&gt;
Next you need to stage all of the files you want to commit.&lt;br /&gt;
&lt;br /&gt;
To do this you add the files to the stage using the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git add lib/modifiedfile.php&lt;br /&gt;
git add lib/newfile.php&lt;br /&gt;
git add theme/base/style/core.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Why not just commit all changes. Many of the git guides you read will tell you above git commit -a which commits all of the changes you have made.&lt;br /&gt;
&lt;br /&gt;
We&#039;ve hardly being using git here at Moodle and already I&#039;ve seen several people accidentally commit changes that they didn&#039;t mean to.&lt;br /&gt;
&lt;br /&gt;
Staging files like this ENSURES you only commit things you intend to.&lt;br /&gt;
&lt;br /&gt;
Now that you have staged your changes/new files you are ready to commit. The following command commits your changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git commit -m &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command commits your changes with the commit message &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;.&lt;br /&gt;
It&#039;s very important to Moodle that you format your commit messages like this.&lt;br /&gt;
They consist of three parts:&lt;br /&gt;
&lt;br /&gt;
# The MDL bug number in this case MDL-12345&lt;br /&gt;
# The area you made changes to in this case enrol&lt;br /&gt;
# A short description of what you did, in this case I fixed a couple of enrolment bugs.&lt;br /&gt;
&lt;br /&gt;
When you commit your message you will see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[master 19a484e] changes&lt;br /&gt;
 1 files changed, 16 insertions(+), 18 deletions(-)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
There is one thing here you need to note down for later, that is the number that appears within the square brackets after the branch name, in my case it is 19a484e. This is the commit id of the commit I just made.&lt;br /&gt;
&lt;br /&gt;
===Step 4: Pushing your changes to your github account===&lt;br /&gt;
&lt;br /&gt;
Now that you have made changes to your local branch you should push it to your github account so that it can be reviewed and hopefully integrated into Moodle.&lt;br /&gt;
&lt;br /&gt;
Doing this is very simple just run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are telling git to push the branch wip-MDL-12345-master to the remote called github which we added when setting up our git repositories.&lt;br /&gt;
And just like that you&#039;ve made a branch that contains your work and pushed it to github ready to get it reviewed.&lt;br /&gt;
&lt;br /&gt;
==Moving your changes to another branch==&lt;br /&gt;
Now that you have made changes to the master branch you need to decide whether it is appropriate make those changes on any of the other branches.&lt;br /&gt;
Most likely if you are fixing a bug you will need to make the changes on the MOODLE_20_STABLE branch as well, and perhaps the MOODLE_19_STABLE branch if it is a security bug.&lt;br /&gt;
&lt;br /&gt;
Lets assume for MDL-12345 that I fixed earlier that it should be ported to MOODLE_20_STABLE as well.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local MOODLE_20_STABLE branch===&lt;br /&gt;
&lt;br /&gt;
To start with I need to move to the MOODLE_20_STABLE repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there I need to create a new branch based upon the MOODLE_20_STABLE branch that is going to contain my changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very similar to the branch we created for the changes to the master branch except that I have subsituted MOODLE_20_STABLE in place of master. This is because the new branch we are creating is based upon the MOODLE_20_STABLE branch on the offical Moodle git repository and contains changes for that branch.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Cherry-picking my changes===&lt;br /&gt;
Once we have a branch for our changes I am ready to make them again. There is however with git an easy way to do this, cherry-picking.&lt;br /&gt;
&lt;br /&gt;
Cherry-picking is the process of copying a single commit from one branch to another. In this case I want to cherry pick the commit I made earlier onto the branch I&#039;ve just created.&lt;br /&gt;
&lt;br /&gt;
However before I can do this I need to fetch the changes I made from the github repository. I need to do this because I made that changes of a totally separate local repository remember.&lt;br /&gt;
&lt;br /&gt;
So to update my repository with the latest changes I run the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command tells git to look at each remote and get any new changes (it also removes any branches that have been deleted).&lt;br /&gt;
Once it has completed you will be ready to cherry pick the commit. To do so you use the following command but replace my commit is with yours.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git cherry-pick 19a484e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Providing there are no conflicts your branch will now contain a copy of the changes you made to the master branch.&lt;br /&gt;
If there are conficts that you will need to resolve them and commit your changes however you can search for another tutorial about how to do that,&lt;br /&gt;
&lt;br /&gt;
Now I know at this point that there will be some of you who are saying &#039;Whoops I forgot what my commit id was!&#039;. If this is you don&#039;t worry, its pretty easy to find it providing you used a proper commit message like I described above.&lt;br /&gt;
Simply run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git log --oneline origin/master..github/wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the commits that are in the wip-MDL-12345-master at your github account but are not in the master branch at the offical Moodle repository.&lt;br /&gt;
You can then cherry-pick the commits shown there (the commit ID&#039;s should be highlighted in yellow).&lt;br /&gt;
&lt;br /&gt;
Once you have cherry-picked your commits its time to check that everything worked, run the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# On branch wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
# Your branch is ahead of &#039;origin/MOODLE_20_STABLE&#039; by 1 commit.&lt;br /&gt;
#&lt;br /&gt;
nothing to commit (working directory clean)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very handy as it tells you that your branch is ahead of the offical MOODLE_20_STABLE branch by one commit.&lt;br /&gt;
You can also check that your commit contains the changes you think by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git diff origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the changes you have made as a diff.&lt;br /&gt;
&lt;br /&gt;
Now that you know that your commit is there you and that it is correct it is time to push it to your github account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And thats it.&lt;br /&gt;
&lt;br /&gt;
You github account should now have two branches on it:&lt;br /&gt;
&lt;br /&gt;
; wip-MDL-12345-master : This branch is the changes you have made for the master branch&lt;br /&gt;
; wip-MDL-12345-MOODLE_20_STABLE : This branch is those same changes but for the MOODLE_20_STABLE branch&lt;br /&gt;
&lt;br /&gt;
Now you are ready to create PULL requests so that your work gets reviewed and hopefully integrated.&lt;br /&gt;
&lt;br /&gt;
==Creating PULL requests==&lt;br /&gt;
Now that you&#039;ve got a branch with changes for your MDL issue its time to create some PULL requests to get it integrated.&lt;br /&gt;
&lt;br /&gt;
===Creating a PULL request for the master branch===&lt;br /&gt;
&lt;br /&gt;
So you have successfully fixed the bug MDL-12345, you have created two branches one for master and one for MOODLE_20_STABLE. It is time to create a PULL request for each of these branches.&lt;br /&gt;
&lt;br /&gt;
First lets create a PULL request for the master branch:&lt;br /&gt;
&lt;br /&gt;
# Browse to tracker.moodle.org/browse/MDL-12345&lt;br /&gt;
# When the page loads log in if you haven&#039;t already.&lt;br /&gt;
# Click on the button in the top right labelled `Create issue`&lt;br /&gt;
# Change Project to `Pull Requests`&lt;br /&gt;
# Change Issue type to `Pull Request`&lt;br /&gt;
# Click create&lt;br /&gt;
&lt;br /&gt;
This takes you to a screen where you can enter the details for the PULL request.&lt;br /&gt;
&lt;br /&gt;
You should fill it out in the following way:&lt;br /&gt;
&lt;br /&gt;
====Summary====&lt;br /&gt;
This is the summary for the PULL request, you should copy and paste the summary from the MDL issue here.&lt;br /&gt;
For MDL-12345 the summary is `alphabetization of UI different on left and right sides` so that&#039;s what I will use.&lt;br /&gt;
&lt;br /&gt;
====Affects Versions====&lt;br /&gt;
This is the version that your branch is changing, in the case of this PULL request I will select `master`.&lt;br /&gt;
&lt;br /&gt;
====Security level====&lt;br /&gt;
If the issue you are working on is a security issue you should set this to the same level that the issue is set to. If its not a security issue or you don&#039;t know just leave it as none.&lt;br /&gt;
&lt;br /&gt;
====Pull from repository====&lt;br /&gt;
This is the repository that the branch is at, for you this will be your github accont. If you head to http://github.com/yourname/moodle you will see a box that has three options SSH, HTTP, and Git read only, click Git Read Only and then copy the contents of the text box into the repositry field of the PULL request. &lt;br /&gt;
For me that is git://github.com/yourname/moodle.git&lt;br /&gt;
&lt;br /&gt;
====Pull branch====&lt;br /&gt;
This is the name of the branch that contains your changes. For me that is wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
====Pull Diff URL====&lt;br /&gt;
This is the URL to a page that shows the changes that you&#039;ve made on your branch. Github is nice in that it has a pretty interface for that. To get to the interface follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Browse to https://github.com/youraccount/moodle&lt;br /&gt;
# Click `Switch Branches` and then click on the branch you changes are based upon, in my case master.&lt;br /&gt;
# Click the button labelled `Branch List`&lt;br /&gt;
# Locate your branch in the list and click the `Compare button` for me this was the compare button to the right of wip-MDL-12345-master.&lt;br /&gt;
# Copy the URL in your browse and paste it into the Pull Diff URL of the PULL request.&lt;br /&gt;
&lt;br /&gt;
For me this URL was: https://github.com/yourname/moodle/compare/master...wip-MDL-23532-master&lt;br /&gt;
For the MOODLE_20_STABLE branch this would be: https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
&lt;br /&gt;
====Description====&lt;br /&gt;
The description should contain several bits of important information:&lt;br /&gt;
&lt;br /&gt;
# A short description of what your patch does&lt;br /&gt;
# Notes about that changes you&#039;ve made that might help the integrator understand what you did when he/she is reviewing it.&lt;br /&gt;
# Testing instructions that guide the testers through testing your changes.&lt;br /&gt;
&lt;br /&gt;
====Components====&lt;br /&gt;
Select general from the components list, general is the only option.&lt;br /&gt;
&lt;br /&gt;
====Finishing up====&lt;br /&gt;
Once you have filled in the fields as above click `Create`. This should create you PULL request and then take you to view it.&lt;br /&gt;
&lt;br /&gt;
Its important to remember that there is still one thing you need to do and that is link to the original issue.&lt;br /&gt;
While you are still logged in click the `More Actions` button and select `Link issue`, in the dialoug that pops up change the `This issue` field to `will help resolve`, type MDL-12345 into the issues field, and then type `Linking to MDL-12345` into the comments box. Once you&#039;ve done that simple click Link.&amp;lt;br /&amp;gt;I should add that the comment isn&#039;t really required. It&#039;s just something I personally like doing.&lt;br /&gt;
&lt;br /&gt;
Time to create the PULL request for the other branches.&lt;br /&gt;
&lt;br /&gt;
==Creating the PULL request for MOODLE_20_STABLE==&lt;br /&gt;
Once you&#039;ve created the PULL request for the master branch it is time to create the PULL request for the MOODLE_20_STABLE branch.&lt;br /&gt;
This is as easy as can be, click Create Issue in the top right, select PULL project and choose Pull Request and then click create.&lt;br /&gt;
On the next screen enter the following details:&lt;br /&gt;
&lt;br /&gt;
; Summary : Copy the summary from the previous PULL Request&lt;br /&gt;
; Affects Versions : Select MOODLE_20_STABLE&lt;br /&gt;
; Security level : Same as the MDL&lt;br /&gt;
; Pull from repository : Copy from the previous PULL request&lt;br /&gt;
; Pull Branch : wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
; Pull Diff URL : https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
; Description : Copy from the previous PULL request&lt;br /&gt;
; Component : general&lt;br /&gt;
&lt;br /&gt;
Then click create to create the PULL request.&lt;br /&gt;
&lt;br /&gt;
Once the PULL request has been create don&#039;t forget to link to the MDL issue like we did for the previous PULL request.&lt;br /&gt;
&lt;br /&gt;
==Resolving the issue==&lt;br /&gt;
The final step for the MDL issue now that you have created the two PULL requests is to Resolve the issue (do not close it, just resolve).&lt;br /&gt;
&lt;br /&gt;
You can do this by logging into tracker, browsing to the MDL issue, and clicking the resolve button.&lt;br /&gt;
&lt;br /&gt;
If your fixes are integrated the tester will close the issue, otherwise if it doesn&#039;t get integrated someone will reopen the MDL.&lt;br /&gt;
&lt;br /&gt;
==Rebasing after the weekly release==&lt;br /&gt;
As many of you will be aware on Wednesday after the latest weekly has been released a comment will be added to all PULL requests that are still open.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The main moodle.git repository has just been updated with latest weekly modifications.&lt;br /&gt;
You may wish to rebase your PULL branches to simplify history and avoid any possible merge conflicts. This would also make integrator&#039;s life easier next week.&lt;br /&gt;
&lt;br /&gt;
TIA and ciao :)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is a message that is bulk added as is done so as a polite request. While it&#039;s not essential for you to rebase your work it really does help the integrators as its much easier to see what is going on and greatly reduces the chance of conflicts (because you&#039;ll solve them when you rebase).&lt;br /&gt;
&lt;br /&gt;
The good news is that rebasing your work is EASY!&lt;br /&gt;
&lt;br /&gt;
For the following example lets assume I created the two PULL requests above on Wednesday morning and the weekly was released on Wednesday afternoon. This means that my branch doesn&#039;t have the changes that have just been released and I need to rebase them.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Rebasing the wip-MDL-12345-master===&lt;br /&gt;
&lt;br /&gt;
The first step is to rebase my work that is based upon the master branch. So first move to the master repository.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next thing we have to do is get all of the changes from the remote repositories, this will fetch down all of the latest changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now before the next step make sure that you don&#039;t have any uncommit changes, if you do finish that work, commit it, then proceed to the next step which is updating your local master.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
git push master github&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that your local master is up to date, and has you&#039;ve updated you master branch at github you are ready to rebase!&lt;br /&gt;
At this point we want to checkout the branch we are going to rebase, in this case wip-MDL-12345-master and then we are going to rebase origin/master which is the official Moodle master branch (and the branch our branch is based upon).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout wip-MDL-12345-master&lt;br /&gt;
git rebase origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that command has completed your branch wip-MDL-12345-master will be completely up to date. Before you are done however you need to push the rebased wip-MDL-12345-master up to your github account so that its the branch the integrator sees.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push -f github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that command is just about identical to the command we used when we first pushed our branch to our github account, there is however one VERY important difference, the &#039;&#039;&#039;-f&#039;&#039;&#039; option.&lt;br /&gt;
The &#039;&#039;&#039;-f&#039;&#039;&#039; option tells git to force the push, this is required because when you rebase all of your commit id&#039;s will change and unless you tell git to force it will see that they have changed and not allow you to push your work.&lt;br /&gt;
&lt;br /&gt;
Thats it! you&#039;ve now rebased your work and the integrators will be happy again :)&lt;br /&gt;
&lt;br /&gt;
===Step 2: Rebasing wip-MDL-12345-MOODLE_20_STABLE===&lt;br /&gt;
Now that we&#039;ve rebased our work that was based upon the master branch it is time to rebase the MOODLE_20_STABLE version.&lt;br /&gt;
This step is just about identical to the previous step except we substitute &#039;&#039;master&#039;&#039; for &#039;&#039;MOODLE_20_STABLE&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github MOODLE_20_STABLE&lt;br /&gt;
git checkout wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
git rebase origin/MOODLE_20_STABLE&lt;br /&gt;
git push -f github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&lt;br /&gt;
==The extra mile==&lt;br /&gt;
Now as many of you may have guessed by the time you are working on several different issues and managing several repositories the process I&#039;ve described here seems VERY repetitive. And it &#039;&#039;&#039;IS!&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
If you talk to any HQ developer they will tell you they deal with it in their own way, anything from scripts, to custom config files, through to virtual machine snapshots.&lt;br /&gt;
&lt;br /&gt;
Personally I have a couple of bash scripts that I wrote to help me manage my workflow.&lt;br /&gt;
&lt;br /&gt;
The first script I use I run after each weekly release and it does the following things:&lt;br /&gt;
&lt;br /&gt;
* Moves to each repository and does the following&lt;br /&gt;
*# Fetches all remote changes&lt;br /&gt;
*# Checks whether it is safe to update my local main release branches and does that if it is safe&lt;br /&gt;
*# Updates all main release branches on my github account&lt;br /&gt;
&lt;br /&gt;
The second script I run on every site that I have installed, it does the following&lt;br /&gt;
&lt;br /&gt;
* Goes to each site I have installed and does the following&lt;br /&gt;
*# Overwrites the database with a stable snapshot&lt;br /&gt;
*# Overwrites the moodle data directory with a stable snapshot taken at the same time as the database one.&lt;br /&gt;
*# Upgrades the moodle site if required&lt;br /&gt;
*# Takes a snapshot of the database and Moodle data directory.&lt;br /&gt;
&lt;br /&gt;
The third script I run whenever I start working on a new issue and it restores the stable snapshot of a sites database and moodle data directory.&lt;br /&gt;
&lt;br /&gt;
These three scripts allow me to very easily ensure I am working with the latest changes and that I can easily restore to a point I know is stable and safe.&lt;br /&gt;
&lt;br /&gt;
There was a fourth script I used to use but don&#039;t any more that also rebased any unmerged branches however I found it to be far to problematic and I prefer to do it myself so that I know exactly what is going on.&lt;br /&gt;
&lt;br /&gt;
==Useful links==&lt;br /&gt;
The following are links I found useful while learning Git.&lt;br /&gt;
&lt;br /&gt;
* [http://help.github.com Github help (http://help.github.com)] Provides EXCELLENT help tutorials that very clearly explain the basic through to the advanced.&lt;br /&gt;
* [http://cheat.errtheblog.com/s/git/ $ cheat git] This is my favourite cheat sheet, straight forward to the point, if you know the concept you&#039;ll find the answer here.&lt;br /&gt;
* [http://gitster.livejournal.com/28309.html Gitsters journal - Fun with FETCH_HEAD] David Mudrak pointed me at this entry which I found INCREDIBLY useful when reviewing other peoples work.&lt;br /&gt;
* [[Development:Git tips]] Moodle docs page with a few handy tips about using Git for Moodle development.&lt;br /&gt;
&lt;br /&gt;
I you&#039;re looking to read/buy a book on Git I&#039;d strongly recommend [http://progit.org/ Pro Git]. I certainly found that the most useful book I read.&lt;br /&gt;
&lt;br /&gt;
[[Category:Git]]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82879</id>
		<title>User:Sam Hemelryk/My Moodle Git workflow</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82879"/>
		<updated>2011-04-19T03:10:11Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* Creating the PULL request for MOODLE_20_STABLE */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document is a sort of tutorial/inspection of my personal development workflow when working on Moodle with Git.&lt;br /&gt;
&lt;br /&gt;
==Creating the repositories==&lt;br /&gt;
Ok so the very first step is to create several Moodle git repositories, one for each major branch of Moodle being worked on.&lt;br /&gt;
&lt;br /&gt;
At the time of writing the major branches are MOODLE_19_STABLE, MOODLE_20_STABLE and master.&lt;br /&gt;
&lt;br /&gt;
The reason for this is that that way we have a separate site for each Moodle branch that we can test on easily. Yes you will have three sites but you won&#039;t have to worry about swtiching your site when you change branches.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Create a directory to create the repositories within===&lt;br /&gt;
&lt;br /&gt;
Personally I use Ubuntu (Linux) and I chose to create my repositories within a folder I created in /var/www. If you are using windows I would instead suggest creating C:/www/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www&lt;br /&gt;
mkdir repositories&lt;br /&gt;
cd repositories&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 2: Create a master repository===&lt;br /&gt;
This is the easiest of the branches to create a repository for.&lt;br /&gt;
&lt;br /&gt;
Within your repositories directory create a new directory called master and move into it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir master&lt;br /&gt;
cd master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we want to clone the Moodle source from the offical Moodle git repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new directory called moodle within the master directory we created just before.&lt;br /&gt;
&lt;br /&gt;
That new moodle directory should contain the Moodle source code as a git repository.&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our main git repository we need to add our github account as a remote so that we can push to it later:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd moodle&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This adds your moodle repository on github as a remote called github that you can push to later.&lt;br /&gt;
&lt;br /&gt;
Finally before we move onto the next repository we need to create a data directory because we know we will need that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 3: Create a MOODLE_20_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
The next repository we create will be for the MOODLE_20_STABLE branch.&lt;br /&gt;
To start with get back to the repositories directory that we created earlier and create a directory called MOODLE_20_STABLE within that.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_20_STABLE&lt;br /&gt;
cd MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now create a new clone of the main Moodle repository like we did for the master branch above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have done that move into the moodle directory.&lt;br /&gt;
&lt;br /&gt;
By default the master branch is the branch that is created, however we don&#039;t want that for this repository. Instead we want the MOODLE_20_STABLE branch.&lt;br /&gt;
&lt;br /&gt;
To do this we checkout local branch based upon the official MOODLE_20_STABLE branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have created that branch we can delete the local master branch so that we don&#039;t accidentally ever work on it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git branch -D master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then like we did for master we add our github repository as a remote:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And finally create a data directory we can use when we have install the site:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 4: Create a MOODLE_19_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
This step is identical to the above step except we are using the MOODLE_19_STABLE branch instead of the MOODLE_20_STABLE branch.&lt;br /&gt;
The commands for this are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_19_STABLE&lt;br /&gt;
cd MOODLE_19_STABLE&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
git checkout -b MOODLE_19_STABLE origin/MOODLE_19_STABLE&lt;br /&gt;
git branch -D master&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 5: Install the sites===&lt;br /&gt;
Now I can&#039;t tell you how to do this on your own machine however what I would recommend is that you create a link from your web root to the moodle directory of each branch.&lt;br /&gt;
&lt;br /&gt;
If you are using linux and your webroot is /var/www/localhost you would do it as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/localhost/&lt;br /&gt;
ln -s /var/www/repositories/master/moodle master&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_20_STABLE/moodle MOODLE_20_STABLE&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_19_STABLE/moodle MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done you should be able to browse to each repository with the following URL&#039;s&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://localhost/master/&lt;br /&gt;
http://localhost/MOODLE_20_STABLE/&lt;br /&gt;
http://localhost/MOODLE_19_STABLE/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that is done you need to browse to each site and complete the installation.&lt;br /&gt;
&lt;br /&gt;
Under this method your will need to ensure you set the configuration option sessioncookiepath to the URI of your site. You can either do this in the admin interfaces or add the following to your config.php file for each site.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// For the master site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/master/&#039;;&lt;br /&gt;
// For the MOODLE_20_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_20_STABLE/&#039;;&lt;br /&gt;
// For the MOODLE_19_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_19_STABLE/&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Failure to do this will mean that when you log in at one site and then visit the next you will have to log in again and your session on the first site will no longer work.&lt;br /&gt;
&lt;br /&gt;
Now that you have got 3 repositories, one for each main branch, and set up a site for each you are ready to start development.&lt;br /&gt;
&lt;br /&gt;
==Before you start work each day==&lt;br /&gt;
Before you start work each day you should update each of the repositories you have created to ensure that you are always working with up to date versions of Moodle.&lt;br /&gt;
&lt;br /&gt;
You should also take this opportunity to update the repositories on your github account to ensure they are always up to date.&lt;br /&gt;
&lt;br /&gt;
To start with lets update the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This moves to the master repository and then tells git for fetch all of the changes from your remote repositories and clean up any old branches it is aware of.&lt;br /&gt;
&lt;br /&gt;
Once that operation has completed you should update your master branch&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Before you do that it pays to make sure you don&#039;t have any uncommit changes, if you do DON&#039;T TRY IT. There would be a good chance you will encounter problems. Instead finish what you are working on, commit your changes and then update your master branch.&lt;br /&gt;
&lt;br /&gt;
Next we will update the github repositories by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github refs/remotes/origin/master:master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This tells git to push the master branch from origin (the offical Moodle repository) to the master branch on our github account.&lt;br /&gt;
&lt;br /&gt;
Now that you&#039;ve updated the master repository and your github account its time to update the MOODLE_20_STABLE and MOODLE_19_STABLE branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_20_STABLE:MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_19_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_19_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_19_STABLE:MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Working on a Moodle issue==&lt;br /&gt;
&lt;br /&gt;
This part of the document looks at how I go about working on an MDL issue from the Moodle tracker.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ we use the scrum methodology we sees us choose several issues to include in a scrum which we then work on for the period of the scrum. As a community member its more likely you will just be choosing issues that you are passionate about.&lt;br /&gt;
&lt;br /&gt;
Either way once you have found an issue to work on you are ready to start.&lt;br /&gt;
&lt;br /&gt;
For the purpose of this part of the document lets say I am going to work on bug MDL-12345.&lt;br /&gt;
&lt;br /&gt;
==Fixing a bug on the master repository - MDL-12345==&lt;br /&gt;
&lt;br /&gt;
The first step is to create a local branch to make changes on, to do this we will start our work on the master repository.&lt;br /&gt;
&lt;br /&gt;
When fixing an issue I find it easiest to fix the issue on the master branch first and then move my changes to the other branches.&lt;br /&gt;
&lt;br /&gt;
The VERY first thing you should do when you start working on a Moodle issue is make sure you have assigned it to yourself and then click the start progress button.&lt;br /&gt;
&lt;br /&gt;
This way other users know that you are activly working on the bug and no one from HQ will steal it from you.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local branch===&lt;br /&gt;
&lt;br /&gt;
So first get to the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there we create a new branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-master origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command checks out a new branch called wip-MDL-12345-master that is based upon origin/master.&lt;br /&gt;
&lt;br /&gt;
origin/master is of course the master branch on the official Moodle repository (git.moodle.org/moodle.git).&lt;br /&gt;
&lt;br /&gt;
The name of the branch is also very important. It is essentially telling us three things.&lt;br /&gt;
&lt;br /&gt;
; wip : This stands for work in progress, it helps people see that you are currently working on this branch and that they shouldn&#039;t base there work on it because it will likely change.&lt;br /&gt;
; MDL-12345 : This is of course the Moodle bug number. It helps people quickly identify what you are working on.&lt;br /&gt;
; master : This is the branch we are making changes on. It helps people quickly understand where the changes are being made.&lt;br /&gt;
&lt;br /&gt;
You can optionally add more to the end of the branch name such as a key word that identifies the area or a date at which you started work e.g.&lt;br /&gt;
&lt;br /&gt;
* wip-MDL-12345-master-navigation-changes&lt;br /&gt;
* wip-MDL-12345-master-20110418&lt;br /&gt;
&lt;br /&gt;
That is up to you, personally I&#039;m not a fan of it, however the rest is all required to help integrate your work.&lt;br /&gt;
&lt;br /&gt;
Either way now you have a branch, mine is called wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Make changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have created you branch you are ready to make changes.&lt;br /&gt;
&lt;br /&gt;
I&#039;ll let you make whatever changes you are need, once you have made changes move onto the next step.&lt;br /&gt;
&lt;br /&gt;
Before you do move on however make sure that your code meets the high quality of code Moodle requires.&lt;br /&gt;
&lt;br /&gt;
You can find information about that on the moodle docs here: https://docs.moodle.org/en/Development:Coding_style&lt;br /&gt;
&lt;br /&gt;
The following are common mistakes:&lt;br /&gt;
&lt;br /&gt;
* Incorrect white space&lt;br /&gt;
** Tabs instead of spaces&lt;br /&gt;
** Extra spaces at the end of lines&lt;br /&gt;
** Multiple new lines&lt;br /&gt;
** Forgetting to put spaces between function arguments&lt;br /&gt;
* Incorrect commit messages (read on to find out about writing a good commit message)&lt;br /&gt;
* Incorrect variable or function names&lt;br /&gt;
&lt;br /&gt;
Making these sort of mistakes can lead to your code being rejected despite it working correctly.&lt;br /&gt;
&lt;br /&gt;
I would &#039;&#039;&#039;strongly&#039;&#039;&#039; suggest while learning Moodle development that you use [[User:Tim Hunt|Tim Hunt&#039;s]] fantastic [https://github.com/timhunt/moodle-local_codechecker Code Checker] plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
You&#039;ll find information on how to use it within its README file and it will pick up many of the things that may lead to your work being rejected.&lt;br /&gt;
&lt;br /&gt;
Or course it will be reviewed in regards to security, usability and the other important factors of code development.&lt;br /&gt;
&lt;br /&gt;
===Step 3: Commit your changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have made your changes you are getting ready to commit them.&lt;br /&gt;
&lt;br /&gt;
The first thing to do is check your changes. To do this run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see all of the files you have changes highlighted in red.&lt;br /&gt;
&lt;br /&gt;
Next you need to stage all of the files you want to commit.&lt;br /&gt;
&lt;br /&gt;
To do this you add the files to the stage using the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git add lib/modifiedfile.php&lt;br /&gt;
git add lib/newfile.php&lt;br /&gt;
git add theme/base/style/core.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Why not just commit all changes. Many of the git guides you read will tell you above git commit -a which commits all of the changes you have made.&lt;br /&gt;
&lt;br /&gt;
We&#039;ve hardly being using git here at Moodle and already I&#039;ve seen several people accidentally commit changes that they didn&#039;t mean to.&lt;br /&gt;
&lt;br /&gt;
Staging files like this ENSURES you only commit things you intend to.&lt;br /&gt;
&lt;br /&gt;
Now that you have staged your changes/new files you are ready to commit. The following command commits your changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git commit -m &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command commits your changes with the commit message &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;.&lt;br /&gt;
It&#039;s very important to Moodle that you format your commit messages like this.&lt;br /&gt;
They consist of three parts:&lt;br /&gt;
&lt;br /&gt;
# The MDL bug number in this case MDL-12345&lt;br /&gt;
# The area you made changes to in this case enrol&lt;br /&gt;
# A short description of what you did, in this case I fixed a couple of enrolment bugs.&lt;br /&gt;
&lt;br /&gt;
When you commit your message you will see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[master 19a484e] changes&lt;br /&gt;
 1 files changed, 16 insertions(+), 18 deletions(-)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
There is one thing here you need to note down for later, that is the number that appears within the square brackets after the branch name, in my case it is 19a484e. This is the commit id of the commit I just made.&lt;br /&gt;
&lt;br /&gt;
===Step 4: Pushing your changes to your github account===&lt;br /&gt;
&lt;br /&gt;
Now that you have made changes to your local branch you should push it to your github account so that it can be reviewed and hopefully integrated into Moodle.&lt;br /&gt;
&lt;br /&gt;
Doing this is very simple just run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are telling git to push the branch wip-MDL-12345-master to the remote called github which we added when setting up our git repositories.&lt;br /&gt;
And just like that you&#039;ve made a branch that contains your work and pushed it to github ready to get it reviewed.&lt;br /&gt;
&lt;br /&gt;
==Moving your changes to another branch==&lt;br /&gt;
Now that you have made changes to the master branch you need to decide whether it is appropriate make those changes on any of the other branches.&lt;br /&gt;
Most likely if you are fixing a bug you will need to make the changes on the MOODLE_20_STABLE branch as well, and perhaps the MOODLE_19_STABLE branch if it is a security bug.&lt;br /&gt;
&lt;br /&gt;
Lets assume for MDL-12345 that I fixed earlier that it should be ported to MOODLE_20_STABLE as well.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local MOODLE_20_STABLE branch===&lt;br /&gt;
&lt;br /&gt;
To start with I need to move to the MOODLE_20_STABLE repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there I need to create a new branch based upon the MOODLE_20_STABLE branch that is going to contain my changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very similar to the branch we created for the changes to the master branch except that I have subsituted MOODLE_20_STABLE in place of master. This is because the new branch we are creating is based upon the MOODLE_20_STABLE branch on the offical Moodle git repository and contains changes for that branch.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Cherry-picking my changes===&lt;br /&gt;
Once we have a branch for our changes I am ready to make them again. There is however with git an easy way to do this, cherry-picking.&lt;br /&gt;
&lt;br /&gt;
Cherry-picking is the process of copying a single commit from one branch to another. In this case I want to cherry pick the commit I made earlier onto the branch I&#039;ve just created.&lt;br /&gt;
&lt;br /&gt;
However before I can do this I need to fetch the changes I made from the github repository. I need to do this because I made that changes of a totally separate local repository remember.&lt;br /&gt;
&lt;br /&gt;
So to update my repository with the latest changes I run the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command tells git to look at each remote and get any new changes (it also removes any branches that have been deleted).&lt;br /&gt;
Once it has completed you will be ready to cherry pick the commit. To do so you use the following command but replace my commit is with yours.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git cherry-pick 19a484e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Providing there are no conflicts your branch will now contain a copy of the changes you made to the master branch.&lt;br /&gt;
If there are conficts that you will need to resolve them and commit your changes however you can search for another tutorial about how to do that,&lt;br /&gt;
&lt;br /&gt;
Now I know at this point that there will be some of you who are saying &#039;Whoops I forgot what my commit id was!&#039;. If this is you don&#039;t worry, its pretty easy to find it providing you used a proper commit message like I described above.&lt;br /&gt;
Simply run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git log --oneline origin/master..github/wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the commits that are in the wip-MDL-12345-master at your github account but are not in the master branch at the offical Moodle repository.&lt;br /&gt;
You can then cherry-pick the commits shown there (the commit ID&#039;s should be highlighted in yellow).&lt;br /&gt;
&lt;br /&gt;
Once you have cherry-picked your commits its time to check that everything worked, run the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# On branch wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
# Your branch is ahead of &#039;origin/MOODLE_20_STABLE&#039; by 1 commit.&lt;br /&gt;
#&lt;br /&gt;
nothing to commit (working directory clean)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very handy as it tells you that your branch is ahead of the offical MOODLE_20_STABLE branch by one commit.&lt;br /&gt;
You can also check that your commit contains the changes you think by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git diff origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the changes you have made as a diff.&lt;br /&gt;
&lt;br /&gt;
Now that you know that your commit is there you and that it is correct it is time to push it to your github account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And thats it.&lt;br /&gt;
&lt;br /&gt;
You github account should now have two branches on it:&lt;br /&gt;
&lt;br /&gt;
; wip-MDL-12345-master : This branch is the changes you have made for the master branch&lt;br /&gt;
; wip-MDL-12345-MOODLE_20_STABLE : This branch is those same changes but for the MOODLE_20_STABLE branch&lt;br /&gt;
&lt;br /&gt;
Now you are ready to create PULL requests so that your work gets reviewed and hopefully integrated.&lt;br /&gt;
&lt;br /&gt;
==Creating a PULL request for the master branch==&lt;br /&gt;
&lt;br /&gt;
So you have successfully fixed the bug MDL-12345, you have created two branches one for master and one for MOODLE_20_STABLE. It is time to create a PULL request for each of these branches.&lt;br /&gt;
&lt;br /&gt;
First lets create a PULL request for the master branch:&lt;br /&gt;
&lt;br /&gt;
# Browse to tracker.moodle.org/browse/MDL-12345&lt;br /&gt;
# When the page loads log in if you haven&#039;t already.&lt;br /&gt;
# Click on the button in the top right labelled `Create issue`&lt;br /&gt;
# Change Project to `Pull Requests`&lt;br /&gt;
# Change Issue type to `Pull Request`&lt;br /&gt;
# Click create&lt;br /&gt;
&lt;br /&gt;
This takes you to a screen where you can enter the details for the PULL request.&lt;br /&gt;
&lt;br /&gt;
You should fill it out in the following way:&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
This is the summary for the PULL request, you should copy and paste the summary from the MDL issue here.&lt;br /&gt;
For MDL-12345 the summary is `alphabetization of UI different on left and right sides` so that&#039;s what I will use.&lt;br /&gt;
&lt;br /&gt;
===Affects Versions===&lt;br /&gt;
This is the version that your branch is changing, in the case of this PULL request I will select `master`.&lt;br /&gt;
&lt;br /&gt;
===Security level===&lt;br /&gt;
If the issue you are working on is a security issue you should set this to the same level that the issue is set to. If its not a security issue or you don&#039;t know just leave it as none.&lt;br /&gt;
&lt;br /&gt;
===Pull from repository===&lt;br /&gt;
This is the repository that the branch is at, for you this will be your github accont. If you head to http://github.com/yourname/moodle you will see a box that has three options SSH, HTTP, and Git read only, click Git Read Only and then copy the contents of the text box into the repositry field of the PULL request. &lt;br /&gt;
For me that is git://github.com/yourname/moodle.git&lt;br /&gt;
&lt;br /&gt;
===Pull branch===&lt;br /&gt;
This is the name of the branch that contains your changes. For me that is wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Pull Diff URL===&lt;br /&gt;
This is the URL to a page that shows the changes that you&#039;ve made on your branch. Github is nice in that it has a pretty interface for that. To get to the interface follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Browse to https://github.com/youraccount/moodle&lt;br /&gt;
# Click `Switch Branches` and then click on the branch you changes are based upon, in my case master.&lt;br /&gt;
# Click the button labelled `Branch List`&lt;br /&gt;
# Locate your branch in the list and click the `Compare button` for me this was the compare button to the right of wip-MDL-12345-master.&lt;br /&gt;
# Copy the URL in your browse and paste it into the Pull Diff URL of the PULL request.&lt;br /&gt;
&lt;br /&gt;
For me this URL was: https://github.com/yourname/moodle/compare/master...wip-MDL-23532-master&lt;br /&gt;
For the MOODLE_20_STABLE branch this would be: https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
&lt;br /&gt;
===Description===&lt;br /&gt;
The description should contain several bits of important information:&lt;br /&gt;
&lt;br /&gt;
# A short description of what your patch does&lt;br /&gt;
# Notes about that changes you&#039;ve made that might help the integrator understand what you did when he/she is reviewing it.&lt;br /&gt;
# Testing instructions that guide the testers through testing your changes.&lt;br /&gt;
&lt;br /&gt;
===Components===&lt;br /&gt;
Select general from the components list, general is the only option.&lt;br /&gt;
&lt;br /&gt;
===Finishing up===&lt;br /&gt;
Once you have filled in the fields as above click `Create`. This should create you PULL request and then take you to view it.&lt;br /&gt;
&lt;br /&gt;
Its important to remember that there is still one thing you need to do and that is link to the original issue.&lt;br /&gt;
While you are still logged in click the `More Actions` button and select `Link issue`, in the dialoug that pops up change the `This issue` field to `will help resolve`, type MDL-12345 into the issues field, and then type `Linking to MDL-12345` into the comments box. Once you&#039;ve done that simple click Link.&amp;lt;br /&amp;gt;I should add that the comment isn&#039;t really required. It&#039;s just something I personally like doing.&lt;br /&gt;
&lt;br /&gt;
Time to create the PULL request for the other branches.&lt;br /&gt;
&lt;br /&gt;
==Creating the PULL request for MOODLE_20_STABLE==&lt;br /&gt;
Once you&#039;ve created the PULL request for the master branch it is time to create the PULL request for the MOODLE_20_STABLE branch.&lt;br /&gt;
This is as easy as can be, click Create Issue in the top right, select PULL project and choose Pull Request and then click create.&lt;br /&gt;
On the next screen enter the following details:&lt;br /&gt;
&lt;br /&gt;
; Summary : Copy the summary from the previous PULL Request&lt;br /&gt;
; Affects Versions : Select MOODLE_20_STABLE&lt;br /&gt;
; Security level : Same as the MDL&lt;br /&gt;
; Pull from repository : Copy from the previous PULL request&lt;br /&gt;
; Pull Branch : wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
; Pull Diff URL : https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
; Description : Copy from the previous PULL request&lt;br /&gt;
; Component : general&lt;br /&gt;
&lt;br /&gt;
Then click create to create the PULL request.&lt;br /&gt;
&lt;br /&gt;
Once the PULL request has been create don&#039;t forget to link to the MDL issue like we did for the previous PULL request.&lt;br /&gt;
&lt;br /&gt;
==Resolving the issue==&lt;br /&gt;
The final step for the MDL issue now that you have created the two PULL requests is to Resolve the issue (do not close it, just resolve).&lt;br /&gt;
&lt;br /&gt;
You can do this by logging into tracker, browsing to the MDL issue, and clicking the resolve button.&lt;br /&gt;
&lt;br /&gt;
If your fixes are integrated the tester will close the issue, otherwise if it doesn&#039;t get integrated someone will reopen the MDL.&lt;br /&gt;
&lt;br /&gt;
==Rebasing after the weekly release==&lt;br /&gt;
As many of you will be aware on Wednesday after the latest weekly has been released a comment will be added to all PULL requests that are still open.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The main moodle.git repository has just been updated with latest weekly modifications.&lt;br /&gt;
You may wish to rebase your PULL branches to simplify history and avoid any possible merge conflicts. This would also make integrator&#039;s life easier next week.&lt;br /&gt;
&lt;br /&gt;
TIA and ciao :)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is a message that is bulk added as is done so as a polite request. While it&#039;s not essential for you to rebase your work it really does help the integrators as its much easier to see what is going on and greatly reduces the chance of conflicts (because you&#039;ll solve them when you rebase).&lt;br /&gt;
&lt;br /&gt;
The good news is that rebasing your work is EASY!&lt;br /&gt;
&lt;br /&gt;
For the following example lets assume I created the two PULL requests above on Wednesday morning and the weekly was released on Wednesday afternoon. This means that my branch doesn&#039;t have the changes that have just been released and I need to rebase them.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Rebasing the wip-MDL-12345-master===&lt;br /&gt;
&lt;br /&gt;
The first step is to rebase my work that is based upon the master branch. So first move to the master repository.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next thing we have to do is get all of the changes from the remote repositories, this will fetch down all of the latest changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now before the next step make sure that you don&#039;t have any uncommit changes, if you do finish that work, commit it, then proceed to the next step which is updating your local master.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
git push master github&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that your local master is up to date, and has you&#039;ve updated you master branch at github you are ready to rebase!&lt;br /&gt;
At this point we want to checkout the branch we are going to rebase, in this case wip-MDL-12345-master and then we are going to rebase origin/master which is the official Moodle master branch (and the branch our branch is based upon).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout wip-MDL-12345-master&lt;br /&gt;
git rebase origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that command has completed your branch wip-MDL-12345-master will be completely up to date. Before you are done however you need to push the rebased wip-MDL-12345-master up to your github account so that its the branch the integrator sees.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push -f github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that command is just about identical to the command we used when we first pushed our branch to our github account, there is however one VERY important difference, the &#039;&#039;&#039;-f&#039;&#039;&#039; option.&lt;br /&gt;
The &#039;&#039;&#039;-f&#039;&#039;&#039; option tells git to force the push, this is required because when you rebase all of your commit id&#039;s will change and unless you tell git to force it will see that they have changed and not allow you to push your work.&lt;br /&gt;
&lt;br /&gt;
Thats it! you&#039;ve now rebased your work and the integrators will be happy again :)&lt;br /&gt;
&lt;br /&gt;
===Step 2: Rebasing wip-MDL-12345-MOODLE_20_STABLE===&lt;br /&gt;
Now that we&#039;ve rebased our work that was based upon the master branch it is time to rebase the MOODLE_20_STABLE version.&lt;br /&gt;
This step is just about identical to the previous step except we substitute &#039;&#039;master&#039;&#039; for &#039;&#039;MOODLE_20_STABLE&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github MOODLE_20_STABLE&lt;br /&gt;
git checkout wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
git rebase origin/MOODLE_20_STABLE&lt;br /&gt;
git push -f github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&lt;br /&gt;
==The extra mile==&lt;br /&gt;
Now as many of you may have guessed by the time you are working on several different issues and managing several repositories the process I&#039;ve described here seems VERY repetitive. And it &#039;&#039;&#039;IS!&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
If you talk to any HQ developer they will tell you they deal with it in their own way, anything from scripts, to custom config files, through to virtual machine snapshots.&lt;br /&gt;
&lt;br /&gt;
Personally I have a couple of bash scripts that I wrote to help me manage my workflow.&lt;br /&gt;
&lt;br /&gt;
The first script I use I run after each weekly release and it does the following things:&lt;br /&gt;
&lt;br /&gt;
* Moves to each repository and does the following&lt;br /&gt;
*# Fetches all remote changes&lt;br /&gt;
*# Checks whether it is safe to update my local main release branches and does that if it is safe&lt;br /&gt;
*# Updates all main release branches on my github account&lt;br /&gt;
&lt;br /&gt;
The second script I run on every site that I have installed, it does the following&lt;br /&gt;
&lt;br /&gt;
* Goes to each site I have installed and does the following&lt;br /&gt;
*# Overwrites the database with a stable snapshot&lt;br /&gt;
*# Overwrites the moodle data directory with a stable snapshot taken at the same time as the database one.&lt;br /&gt;
*# Upgrades the moodle site if required&lt;br /&gt;
*# Takes a snapshot of the database and Moodle data directory.&lt;br /&gt;
&lt;br /&gt;
The third script I run whenever I start working on a new issue and it restores the stable snapshot of a sites database and moodle data directory.&lt;br /&gt;
&lt;br /&gt;
These three scripts allow me to very easily ensure I am working with the latest changes and that I can easily restore to a point I know is stable and safe.&lt;br /&gt;
&lt;br /&gt;
There was a fourth script I used to use but don&#039;t any more that also rebased any unmerged branches however I found it to be far to problematic and I prefer to do it myself so that I know exactly what is going on.&lt;br /&gt;
&lt;br /&gt;
==Useful links==&lt;br /&gt;
The following are links I found useful while learning Git.&lt;br /&gt;
&lt;br /&gt;
* [http://help.github.com Github help (http://help.github.com)] Provides EXCELLENT help tutorials that very clearly explain the basic through to the advanced.&lt;br /&gt;
* [http://cheat.errtheblog.com/s/git/ $ cheat git] This is my favourite cheat sheet, straight forward to the point, if you know the concept you&#039;ll find the answer here.&lt;br /&gt;
* [http://gitster.livejournal.com/28309.html Gitsters journal - Fun with FETCH_HEAD] David Mudrak pointed me at this entry which I found INCREDIBLY useful when reviewing other peoples work.&lt;br /&gt;
* [[Development:Git tips]] Moodle docs page with a few handy tips about using Git for Moodle development.&lt;br /&gt;
&lt;br /&gt;
I you&#039;re looking to read/buy a book on Git I&#039;d strongly recommend [http://progit.org/ Pro Git]. I certainly found that the most useful book I read.&lt;br /&gt;
&lt;br /&gt;
[[Category:Git]]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82877</id>
		<title>User:Sam Hemelryk/My Moodle Git workflow</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82877"/>
		<updated>2011-04-19T02:08:28Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document is a sort of tutorial/inspection of my personal development workflow when working on Moodle with Git.&lt;br /&gt;
&lt;br /&gt;
==Creating the repositories==&lt;br /&gt;
Ok so the very first step is to create several Moodle git repositories, one for each major branch of Moodle being worked on.&lt;br /&gt;
&lt;br /&gt;
At the time of writing the major branches are MOODLE_19_STABLE, MOODLE_20_STABLE and master.&lt;br /&gt;
&lt;br /&gt;
The reason for this is that that way we have a separate site for each Moodle branch that we can test on easily. Yes you will have three sites but you won&#039;t have to worry about swtiching your site when you change branches.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Create a directory to create the repositories within===&lt;br /&gt;
&lt;br /&gt;
Personally I use Ubuntu (Linux) and I chose to create my repositories within a folder I created in /var/www. If you are using windows I would instead suggest creating C:/www/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www&lt;br /&gt;
mkdir repositories&lt;br /&gt;
cd repositories&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 2: Create a master repository===&lt;br /&gt;
This is the easiest of the branches to create a repository for.&lt;br /&gt;
&lt;br /&gt;
Within your repositories directory create a new directory called master and move into it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir master&lt;br /&gt;
cd master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we want to clone the Moodle source from the offical Moodle git repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new directory called moodle within the master directory we created just before.&lt;br /&gt;
&lt;br /&gt;
That new moodle directory should contain the Moodle source code as a git repository.&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our main git repository we need to add our github account as a remote so that we can push to it later:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd moodle&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This adds your moodle repository on github as a remote called github that you can push to later.&lt;br /&gt;
&lt;br /&gt;
Finally before we move onto the next repository we need to create a data directory because we know we will need that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 3: Create a MOODLE_20_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
The next repository we create will be for the MOODLE_20_STABLE branch.&lt;br /&gt;
To start with get back to the repositories directory that we created earlier and create a directory called MOODLE_20_STABLE within that.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_20_STABLE&lt;br /&gt;
cd MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now create a new clone of the main Moodle repository like we did for the master branch above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have done that move into the moodle directory.&lt;br /&gt;
&lt;br /&gt;
By default the master branch is the branch that is created, however we don&#039;t want that for this repository. Instead we want the MOODLE_20_STABLE branch.&lt;br /&gt;
&lt;br /&gt;
To do this we checkout local branch based upon the official MOODLE_20_STABLE branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have created that branch we can delete the local master branch so that we don&#039;t accidentally ever work on it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git branch -D master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then like we did for master we add our github repository as a remote:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And finally create a data directory we can use when we have install the site:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 4: Create a MOODLE_19_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
This step is identical to the above step except we are using the MOODLE_19_STABLE branch instead of the MOODLE_20_STABLE branch.&lt;br /&gt;
The commands for this are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_19_STABLE&lt;br /&gt;
cd MOODLE_19_STABLE&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
git checkout -b MOODLE_19_STABLE origin/MOODLE_19_STABLE&lt;br /&gt;
git branch -D master&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 5: Install the sites===&lt;br /&gt;
Now I can&#039;t tell you how to do this on your own machine however what I would recommend is that you create a link from your web root to the moodle directory of each branch.&lt;br /&gt;
&lt;br /&gt;
If you are using linux and your webroot is /var/www/localhost you would do it as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/localhost/&lt;br /&gt;
ln -s /var/www/repositories/master/moodle master&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_20_STABLE/moodle MOODLE_20_STABLE&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_19_STABLE/moodle MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done you should be able to browse to each repository with the following URL&#039;s&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://localhost/master/&lt;br /&gt;
http://localhost/MOODLE_20_STABLE/&lt;br /&gt;
http://localhost/MOODLE_19_STABLE/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that is done you need to browse to each site and complete the installation.&lt;br /&gt;
&lt;br /&gt;
Under this method your will need to ensure you set the configuration option sessioncookiepath to the URI of your site. You can either do this in the admin interfaces or add the following to your config.php file for each site.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// For the master site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/master/&#039;;&lt;br /&gt;
// For the MOODLE_20_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_20_STABLE/&#039;;&lt;br /&gt;
// For the MOODLE_19_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_19_STABLE/&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Failure to do this will mean that when you log in at one site and then visit the next you will have to log in again and your session on the first site will no longer work.&lt;br /&gt;
&lt;br /&gt;
Now that you have got 3 repositories, one for each main branch, and set up a site for each you are ready to start development.&lt;br /&gt;
&lt;br /&gt;
==Before you start work each day==&lt;br /&gt;
Before you start work each day you should update each of the repositories you have created to ensure that you are always working with up to date versions of Moodle.&lt;br /&gt;
&lt;br /&gt;
You should also take this opportunity to update the repositories on your github account to ensure they are always up to date.&lt;br /&gt;
&lt;br /&gt;
To start with lets update the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This moves to the master repository and then tells git for fetch all of the changes from your remote repositories and clean up any old branches it is aware of.&lt;br /&gt;
&lt;br /&gt;
Once that operation has completed you should update your master branch&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Before you do that it pays to make sure you don&#039;t have any uncommit changes, if you do DON&#039;T TRY IT. There would be a good chance you will encounter problems. Instead finish what you are working on, commit your changes and then update your master branch.&lt;br /&gt;
&lt;br /&gt;
Next we will update the github repositories by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github refs/remotes/origin/master:master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This tells git to push the master branch from origin (the offical Moodle repository) to the master branch on our github account.&lt;br /&gt;
&lt;br /&gt;
Now that you&#039;ve updated the master repository and your github account its time to update the MOODLE_20_STABLE and MOODLE_19_STABLE branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_20_STABLE:MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_19_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_19_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_19_STABLE:MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Working on a Moodle issue==&lt;br /&gt;
&lt;br /&gt;
This part of the document looks at how I go about working on an MDL issue from the Moodle tracker.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ we use the scrum methodology we sees us choose several issues to include in a scrum which we then work on for the period of the scrum. As a community member its more likely you will just be choosing issues that you are passionate about.&lt;br /&gt;
&lt;br /&gt;
Either way once you have found an issue to work on you are ready to start.&lt;br /&gt;
&lt;br /&gt;
For the purpose of this part of the document lets say I am going to work on bug MDL-12345.&lt;br /&gt;
&lt;br /&gt;
==Fixing a bug on the master repository - MDL-12345==&lt;br /&gt;
&lt;br /&gt;
The first step is to create a local branch to make changes on, to do this we will start our work on the master repository.&lt;br /&gt;
&lt;br /&gt;
When fixing an issue I find it easiest to fix the issue on the master branch first and then move my changes to the other branches.&lt;br /&gt;
&lt;br /&gt;
The VERY first thing you should do when you start working on a Moodle issue is make sure you have assigned it to yourself and then click the start progress button.&lt;br /&gt;
&lt;br /&gt;
This way other users know that you are activly working on the bug and no one from HQ will steal it from you.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local branch===&lt;br /&gt;
&lt;br /&gt;
So first get to the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there we create a new branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-master origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command checks out a new branch called wip-MDL-12345-master that is based upon origin/master.&lt;br /&gt;
&lt;br /&gt;
origin/master is of course the master branch on the official Moodle repository (git.moodle.org/moodle.git).&lt;br /&gt;
&lt;br /&gt;
The name of the branch is also very important. It is essentially telling us three things.&lt;br /&gt;
&lt;br /&gt;
; wip : This stands for work in progress, it helps people see that you are currently working on this branch and that they shouldn&#039;t base there work on it because it will likely change.&lt;br /&gt;
; MDL-12345 : This is of course the Moodle bug number. It helps people quickly identify what you are working on.&lt;br /&gt;
; master : This is the branch we are making changes on. It helps people quickly understand where the changes are being made.&lt;br /&gt;
&lt;br /&gt;
You can optionally add more to the end of the branch name such as a key word that identifies the area or a date at which you started work e.g.&lt;br /&gt;
&lt;br /&gt;
* wip-MDL-12345-master-navigation-changes&lt;br /&gt;
* wip-MDL-12345-master-20110418&lt;br /&gt;
&lt;br /&gt;
That is up to you, personally I&#039;m not a fan of it, however the rest is all required to help integrate your work.&lt;br /&gt;
&lt;br /&gt;
Either way now you have a branch, mine is called wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Make changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have created you branch you are ready to make changes.&lt;br /&gt;
&lt;br /&gt;
I&#039;ll let you make whatever changes you are need, once you have made changes move onto the next step.&lt;br /&gt;
&lt;br /&gt;
Before you do move on however make sure that your code meets the high quality of code Moodle requires.&lt;br /&gt;
&lt;br /&gt;
You can find information about that on the moodle docs here: https://docs.moodle.org/en/Development:Coding_style&lt;br /&gt;
&lt;br /&gt;
The following are common mistakes:&lt;br /&gt;
&lt;br /&gt;
* Incorrect white space&lt;br /&gt;
** Tabs instead of spaces&lt;br /&gt;
** Extra spaces at the end of lines&lt;br /&gt;
** Multiple new lines&lt;br /&gt;
** Forgetting to put spaces between function arguments&lt;br /&gt;
* Incorrect commit messages (read on to find out about writing a good commit message)&lt;br /&gt;
* Incorrect variable or function names&lt;br /&gt;
&lt;br /&gt;
Making these sort of mistakes can lead to your code being rejected despite it working correctly.&lt;br /&gt;
&lt;br /&gt;
I would &#039;&#039;&#039;strongly&#039;&#039;&#039; suggest while learning Moodle development that you use [[User:Tim Hunt|Tim Hunt&#039;s]] fantastic [https://github.com/timhunt/moodle-local_codechecker Code Checker] plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
You&#039;ll find information on how to use it within its README file and it will pick up many of the things that may lead to your work being rejected.&lt;br /&gt;
&lt;br /&gt;
Or course it will be reviewed in regards to security, usability and the other important factors of code development.&lt;br /&gt;
&lt;br /&gt;
===Step 3: Commit your changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have made your changes you are getting ready to commit them.&lt;br /&gt;
&lt;br /&gt;
The first thing to do is check your changes. To do this run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see all of the files you have changes highlighted in red.&lt;br /&gt;
&lt;br /&gt;
Next you need to stage all of the files you want to commit.&lt;br /&gt;
&lt;br /&gt;
To do this you add the files to the stage using the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git add lib/modifiedfile.php&lt;br /&gt;
git add lib/newfile.php&lt;br /&gt;
git add theme/base/style/core.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Why not just commit all changes. Many of the git guides you read will tell you above git commit -a which commits all of the changes you have made.&lt;br /&gt;
&lt;br /&gt;
We&#039;ve hardly being using git here at Moodle and already I&#039;ve seen several people accidentally commit changes that they didn&#039;t mean to.&lt;br /&gt;
&lt;br /&gt;
Staging files like this ENSURES you only commit things you intend to.&lt;br /&gt;
&lt;br /&gt;
Now that you have staged your changes/new files you are ready to commit. The following command commits your changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git commit -m &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command commits your changes with the commit message &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;.&lt;br /&gt;
It&#039;s very important to Moodle that you format your commit messages like this.&lt;br /&gt;
They consist of three parts:&lt;br /&gt;
&lt;br /&gt;
# The MDL bug number in this case MDL-12345&lt;br /&gt;
# The area you made changes to in this case enrol&lt;br /&gt;
# A short description of what you did, in this case I fixed a couple of enrolment bugs.&lt;br /&gt;
&lt;br /&gt;
When you commit your message you will see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[master 19a484e] changes&lt;br /&gt;
 1 files changed, 16 insertions(+), 18 deletions(-)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
There is one thing here you need to note down for later, that is the number that appears within the square brackets after the branch name, in my case it is 19a484e. This is the commit id of the commit I just made.&lt;br /&gt;
&lt;br /&gt;
===Step 4: Pushing your changes to your github account===&lt;br /&gt;
&lt;br /&gt;
Now that you have made changes to your local branch you should push it to your github account so that it can be reviewed and hopefully integrated into Moodle.&lt;br /&gt;
&lt;br /&gt;
Doing this is very simple just run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are telling git to push the branch wip-MDL-12345-master to the remote called github which we added when setting up our git repositories.&lt;br /&gt;
And just like that you&#039;ve made a branch that contains your work and pushed it to github ready to get it reviewed.&lt;br /&gt;
&lt;br /&gt;
==Moving your changes to another branch==&lt;br /&gt;
Now that you have made changes to the master branch you need to decide whether it is appropriate make those changes on any of the other branches.&lt;br /&gt;
Most likely if you are fixing a bug you will need to make the changes on the MOODLE_20_STABLE branch as well, and perhaps the MOODLE_19_STABLE branch if it is a security bug.&lt;br /&gt;
&lt;br /&gt;
Lets assume for MDL-12345 that I fixed earlier that it should be ported to MOODLE_20_STABLE as well.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local MOODLE_20_STABLE branch===&lt;br /&gt;
&lt;br /&gt;
To start with I need to move to the MOODLE_20_STABLE repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there I need to create a new branch based upon the MOODLE_20_STABLE branch that is going to contain my changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very similar to the branch we created for the changes to the master branch except that I have subsituted MOODLE_20_STABLE in place of master. This is because the new branch we are creating is based upon the MOODLE_20_STABLE branch on the offical Moodle git repository and contains changes for that branch.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Cherry-picking my changes===&lt;br /&gt;
Once we have a branch for our changes I am ready to make them again. There is however with git an easy way to do this, cherry-picking.&lt;br /&gt;
&lt;br /&gt;
Cherry-picking is the process of copying a single commit from one branch to another. In this case I want to cherry pick the commit I made earlier onto the branch I&#039;ve just created.&lt;br /&gt;
&lt;br /&gt;
However before I can do this I need to fetch the changes I made from the github repository. I need to do this because I made that changes of a totally separate local repository remember.&lt;br /&gt;
&lt;br /&gt;
So to update my repository with the latest changes I run the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command tells git to look at each remote and get any new changes (it also removes any branches that have been deleted).&lt;br /&gt;
Once it has completed you will be ready to cherry pick the commit. To do so you use the following command but replace my commit is with yours.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git cherry-pick 19a484e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Providing there are no conflicts your branch will now contain a copy of the changes you made to the master branch.&lt;br /&gt;
If there are conficts that you will need to resolve them and commit your changes however you can search for another tutorial about how to do that,&lt;br /&gt;
&lt;br /&gt;
Now I know at this point that there will be some of you who are saying &#039;Whoops I forgot what my commit id was!&#039;. If this is you don&#039;t worry, its pretty easy to find it providing you used a proper commit message like I described above.&lt;br /&gt;
Simply run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git log --oneline origin/master..github/wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the commits that are in the wip-MDL-12345-master at your github account but are not in the master branch at the offical Moodle repository.&lt;br /&gt;
You can then cherry-pick the commits shown there (the commit ID&#039;s should be highlighted in yellow).&lt;br /&gt;
&lt;br /&gt;
Once you have cherry-picked your commits its time to check that everything worked, run the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# On branch wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
# Your branch is ahead of &#039;origin/MOODLE_20_STABLE&#039; by 1 commit.&lt;br /&gt;
#&lt;br /&gt;
nothing to commit (working directory clean)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very handy as it tells you that your branch is ahead of the offical MOODLE_20_STABLE branch by one commit.&lt;br /&gt;
You can also check that your commit contains the changes you think by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git diff origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the changes you have made as a diff.&lt;br /&gt;
&lt;br /&gt;
Now that you know that your commit is there you and that it is correct it is time to push it to your github account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And thats it.&lt;br /&gt;
&lt;br /&gt;
You github account should now have two branches on it:&lt;br /&gt;
&lt;br /&gt;
; wip-MDL-12345-master : This branch is the changes you have made for the master branch&lt;br /&gt;
; wip-MDL-12345-MOODLE_20_STABLE : This branch is those same changes but for the MOODLE_20_STABLE branch&lt;br /&gt;
&lt;br /&gt;
Now you are ready to create PULL requests so that your work gets reviewed and hopefully integrated.&lt;br /&gt;
&lt;br /&gt;
==Creating a PULL request for the master branch==&lt;br /&gt;
&lt;br /&gt;
So you have successfully fixed the bug MDL-12345, you have created two branches one for master and one for MOODLE_20_STABLE. It is time to create a PULL request for each of these branches.&lt;br /&gt;
&lt;br /&gt;
First lets create a PULL request for the master branch:&lt;br /&gt;
&lt;br /&gt;
# Browse to tracker.moodle.org/browse/MDL-12345&lt;br /&gt;
# When the page loads log in if you haven&#039;t already.&lt;br /&gt;
# Click on the button in the top right labelled `Create issue`&lt;br /&gt;
# Change Project to `Pull Requests`&lt;br /&gt;
# Change Issue type to `Pull Request`&lt;br /&gt;
# Click create&lt;br /&gt;
&lt;br /&gt;
This takes you to a screen where you can enter the details for the PULL request.&lt;br /&gt;
&lt;br /&gt;
You should fill it out in the following way:&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
This is the summary for the PULL request, you should copy and paste the summary from the MDL issue here.&lt;br /&gt;
For MDL-12345 the summary is `alphabetization of UI different on left and right sides` so that&#039;s what I will use.&lt;br /&gt;
&lt;br /&gt;
===Affects Versions===&lt;br /&gt;
This is the version that your branch is changing, in the case of this PULL request I will select `master`.&lt;br /&gt;
&lt;br /&gt;
===Security level===&lt;br /&gt;
If the issue you are working on is a security issue you should set this to the same level that the issue is set to. If its not a security issue or you don&#039;t know just leave it as none.&lt;br /&gt;
&lt;br /&gt;
===Pull from repository===&lt;br /&gt;
This is the repository that the branch is at, for you this will be your github accont. If you head to http://github.com/yourname/moodle you will see a box that has three options SSH, HTTP, and Git read only, click Git Read Only and then copy the contents of the text box into the repositry field of the PULL request. &lt;br /&gt;
For me that is git://github.com/yourname/moodle.git&lt;br /&gt;
&lt;br /&gt;
===Pull branch===&lt;br /&gt;
This is the name of the branch that contains your changes. For me that is wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Pull Diff URL===&lt;br /&gt;
This is the URL to a page that shows the changes that you&#039;ve made on your branch. Github is nice in that it has a pretty interface for that. To get to the interface follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Browse to https://github.com/youraccount/moodle&lt;br /&gt;
# Click `Switch Branches` and then click on the branch you changes are based upon, in my case master.&lt;br /&gt;
# Click the button labelled `Branch List`&lt;br /&gt;
# Locate your branch in the list and click the `Compare button` for me this was the compare button to the right of wip-MDL-12345-master.&lt;br /&gt;
# Copy the URL in your browse and paste it into the Pull Diff URL of the PULL request.&lt;br /&gt;
&lt;br /&gt;
For me this URL was: https://github.com/yourname/moodle/compare/master...wip-MDL-23532-master&lt;br /&gt;
For the MOODLE_20_STABLE branch this would be: https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
&lt;br /&gt;
===Description===&lt;br /&gt;
The description should contain several bits of important information:&lt;br /&gt;
&lt;br /&gt;
# A short description of what your patch does&lt;br /&gt;
# Notes about that changes you&#039;ve made that might help the integrator understand what you did when he/she is reviewing it.&lt;br /&gt;
# Testing instructions that guide the testers through testing your changes.&lt;br /&gt;
&lt;br /&gt;
===Components===&lt;br /&gt;
Select general from the components list, general is the only option.&lt;br /&gt;
&lt;br /&gt;
===Finishing up===&lt;br /&gt;
Once you have filled in the fields as above click `Create`. This should create you PULL request and then take you to view it.&lt;br /&gt;
&lt;br /&gt;
Its important to remember that there is still one thing you need to do and that is link to the original issue.&lt;br /&gt;
While you are still logged in click the `More Actions` button and select `Link issue`, in the dialoug that pops up change the `This issue` field to `will help resolve`, type MDL-12345 into the issues field, and then type `Linking to MDL-12345` into the comments box. Once you&#039;ve done that simple click Link.&amp;lt;br /&amp;gt;I should add that the comment isn&#039;t really required. It&#039;s just something I personally like doing.&lt;br /&gt;
&lt;br /&gt;
Time to create the PULL request for the other branches.&lt;br /&gt;
&lt;br /&gt;
==Creating the PULL request for MOODLE_20_STABLE==&lt;br /&gt;
Once you&#039;ve created the PULL request for the master branch it is time to create the PULL request for the MOODLE_20_STABLE branch.&lt;br /&gt;
This is as easy as can be, click Create Issue in the top right, select PULL project and choose Pull Request and then click create.&lt;br /&gt;
On the next screen enter the following details:&lt;br /&gt;
&lt;br /&gt;
; Summary : Copy the summary from the previous PULL Request&lt;br /&gt;
; Affects Versions : Select MOODLE_20_STABLE&lt;br /&gt;
; Security level : Same as the MDL&lt;br /&gt;
; Pull from repository : Copy from the previous PULL request&lt;br /&gt;
; Pull Branch : wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
; Pull Diff URL : https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
; Description : Copy from the previous PULL request&lt;br /&gt;
; Component : general&lt;br /&gt;
&lt;br /&gt;
Then click create to create the PULL request.&lt;br /&gt;
&lt;br /&gt;
Once the PULL request has been create don&#039;t forget to link to the MDL issue like we did for the previous PULL request.&lt;br /&gt;
&lt;br /&gt;
==Rebasing after the weekly release==&lt;br /&gt;
As many of you will be aware on Wednesday after the latest weekly has been released a comment will be added to all PULL requests that are still open.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The main moodle.git repository has just been updated with latest weekly modifications.&lt;br /&gt;
You may wish to rebase your PULL branches to simplify history and avoid any possible merge conflicts. This would also make integrator&#039;s life easier next week.&lt;br /&gt;
&lt;br /&gt;
TIA and ciao :)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is a message that is bulk added as is done so as a polite request. While it&#039;s not essential for you to rebase your work it really does help the integrators as its much easier to see what is going on and greatly reduces the chance of conflicts (because you&#039;ll solve them when you rebase).&lt;br /&gt;
&lt;br /&gt;
The good news is that rebasing your work is EASY!&lt;br /&gt;
&lt;br /&gt;
For the following example lets assume I created the two PULL requests above on Wednesday morning and the weekly was released on Wednesday afternoon. This means that my branch doesn&#039;t have the changes that have just been released and I need to rebase them.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Rebasing the wip-MDL-12345-master===&lt;br /&gt;
&lt;br /&gt;
The first step is to rebase my work that is based upon the master branch. So first move to the master repository.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next thing we have to do is get all of the changes from the remote repositories, this will fetch down all of the latest changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now before the next step make sure that you don&#039;t have any uncommit changes, if you do finish that work, commit it, then proceed to the next step which is updating your local master.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
git push master github&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that your local master is up to date, and has you&#039;ve updated you master branch at github you are ready to rebase!&lt;br /&gt;
At this point we want to checkout the branch we are going to rebase, in this case wip-MDL-12345-master and then we are going to rebase origin/master which is the official Moodle master branch (and the branch our branch is based upon).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout wip-MDL-12345-master&lt;br /&gt;
git rebase origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that command has completed your branch wip-MDL-12345-master will be completely up to date. Before you are done however you need to push the rebased wip-MDL-12345-master up to your github account so that its the branch the integrator sees.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push -f github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that command is just about identical to the command we used when we first pushed our branch to our github account, there is however one VERY important difference, the &#039;&#039;&#039;-f&#039;&#039;&#039; option.&lt;br /&gt;
The &#039;&#039;&#039;-f&#039;&#039;&#039; option tells git to force the push, this is required because when you rebase all of your commit id&#039;s will change and unless you tell git to force it will see that they have changed and not allow you to push your work.&lt;br /&gt;
&lt;br /&gt;
Thats it! you&#039;ve now rebased your work and the integrators will be happy again :)&lt;br /&gt;
&lt;br /&gt;
===Step 2: Rebasing wip-MDL-12345-MOODLE_20_STABLE===&lt;br /&gt;
Now that we&#039;ve rebased our work that was based upon the master branch it is time to rebase the MOODLE_20_STABLE version.&lt;br /&gt;
This step is just about identical to the previous step except we substitute &#039;&#039;master&#039;&#039; for &#039;&#039;MOODLE_20_STABLE&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github MOODLE_20_STABLE&lt;br /&gt;
git checkout wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
git rebase origin/MOODLE_20_STABLE&lt;br /&gt;
git push -f github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&lt;br /&gt;
==The extra mile==&lt;br /&gt;
Now as many of you may have guessed by the time you are working on several different issues and managing several repositories the process I&#039;ve described here seems VERY repetitive. And it &#039;&#039;&#039;IS!&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
If you talk to any HQ developer they will tell you they deal with it in their own way, anything from scripts, to custom config files, through to virtual machine snapshots.&lt;br /&gt;
&lt;br /&gt;
Personally I have a couple of bash scripts that I wrote to help me manage my workflow.&lt;br /&gt;
&lt;br /&gt;
The first script I use I run after each weekly release and it does the following things:&lt;br /&gt;
&lt;br /&gt;
* Moves to each repository and does the following&lt;br /&gt;
*# Fetches all remote changes&lt;br /&gt;
*# Checks whether it is safe to update my local main release branches and does that if it is safe&lt;br /&gt;
*# Updates all main release branches on my github account&lt;br /&gt;
&lt;br /&gt;
The second script I run on every site that I have installed, it does the following&lt;br /&gt;
&lt;br /&gt;
* Goes to each site I have installed and does the following&lt;br /&gt;
*# Overwrites the database with a stable snapshot&lt;br /&gt;
*# Overwrites the moodle data directory with a stable snapshot taken at the same time as the database one.&lt;br /&gt;
*# Upgrades the moodle site if required&lt;br /&gt;
*# Takes a snapshot of the database and Moodle data directory.&lt;br /&gt;
&lt;br /&gt;
The third script I run whenever I start working on a new issue and it restores the stable snapshot of a sites database and moodle data directory.&lt;br /&gt;
&lt;br /&gt;
These three scripts allow me to very easily ensure I am working with the latest changes and that I can easily restore to a point I know is stable and safe.&lt;br /&gt;
&lt;br /&gt;
There was a fourth script I used to use but don&#039;t any more that also rebased any unmerged branches however I found it to be far to problematic and I prefer to do it myself so that I know exactly what is going on.&lt;br /&gt;
&lt;br /&gt;
==Useful links==&lt;br /&gt;
The following are links I found useful while learning Git.&lt;br /&gt;
&lt;br /&gt;
* [http://help.github.com Github help (http://help.github.com)] Provides EXCELLENT help tutorials that very clearly explain the basic through to the advanced.&lt;br /&gt;
* [http://cheat.errtheblog.com/s/git/ $ cheat git] This is my favourite cheat sheet, straight forward to the point, if you know the concept you&#039;ll find the answer here.&lt;br /&gt;
* [http://gitster.livejournal.com/28309.html Gitsters journal - Fun with FETCH_HEAD] David Mudrak pointed me at this entry which I found INCREDIBLY useful when reviewing other peoples work.&lt;br /&gt;
* [[Development:Git tips]] Moodle docs page with a few handy tips about using Git for Moodle development.&lt;br /&gt;
&lt;br /&gt;
I you&#039;re looking to read/buy a book on Git I&#039;d strongly recommend [http://progit.org/ Pro Git]. I certainly found that the most useful book I read.&lt;br /&gt;
&lt;br /&gt;
[[Category:Git]]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82876</id>
		<title>User:Sam Hemelryk/My Moodle Git workflow</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82876"/>
		<updated>2011-04-19T01:53:54Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* Step 2: Make changes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document is a sort of tutorial/inspection of my personal development workflow when working on Moodle with Git.&lt;br /&gt;
&lt;br /&gt;
==Creating the repositories==&lt;br /&gt;
Ok so the very first step is to create several Moodle git repositories, one for each major branch of Moodle being worked on.&lt;br /&gt;
&lt;br /&gt;
At the time of writing the major branches are MOODLE_19_STABLE, MOODLE_20_STABLE and master.&lt;br /&gt;
&lt;br /&gt;
The reason for this is that that way we have a separate site for each Moodle branch that we can test on easily. Yes you will have three sites but you won&#039;t have to worry about swtiching your site when you change branches.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Create a directory to create the repositories within===&lt;br /&gt;
&lt;br /&gt;
Personally I use Ubuntu (Linux) and I chose to create my repositories within a folder I created in /var/www. If you are using windows I would instead suggest creating C:/www/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www&lt;br /&gt;
mkdir repositories&lt;br /&gt;
cd repositories&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 2: Create a master repository===&lt;br /&gt;
This is the easiest of the branches to create a repository for.&lt;br /&gt;
&lt;br /&gt;
Within your repositories directory create a new directory called master and move into it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir master&lt;br /&gt;
cd master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we want to clone the Moodle source from the offical Moodle git repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new directory called moodle within the master directory we created just before.&lt;br /&gt;
&lt;br /&gt;
That new moodle directory should contain the Moodle source code as a git repository.&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our main git repository we need to add our github account as a remote so that we can push to it later:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd moodle&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This adds your moodle repository on github as a remote called github that you can push to later.&lt;br /&gt;
&lt;br /&gt;
Finally before we move onto the next repository we need to create a data directory because we know we will need that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 3: Create a MOODLE_20_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
The next repository we create will be for the MOODLE_20_STABLE branch.&lt;br /&gt;
To start with get back to the repositories directory that we created earlier and create a directory called MOODLE_20_STABLE within that.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_20_STABLE&lt;br /&gt;
cd MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now create a new clone of the main Moodle repository like we did for the master branch above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have done that move into the moodle directory.&lt;br /&gt;
&lt;br /&gt;
By default the master branch is the branch that is created, however we don&#039;t want that for this repository. Instead we want the MOODLE_20_STABLE branch.&lt;br /&gt;
&lt;br /&gt;
To do this we checkout local branch based upon the official MOODLE_20_STABLE branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have created that branch we can delete the local master branch so that we don&#039;t accidentally ever work on it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git branch -D master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then like we did for master we add our github repository as a remote:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And finally create a data directory we can use when we have install the site:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 4: Create a MOODLE_19_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
This step is identical to the above step except we are using the MOODLE_19_STABLE branch instead of the MOODLE_20_STABLE branch.&lt;br /&gt;
The commands for this are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_19_STABLE&lt;br /&gt;
cd MOODLE_19_STABLE&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
git checkout -b MOODLE_19_STABLE origin/MOODLE_19_STABLE&lt;br /&gt;
git branch -D master&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 5: Install the sites===&lt;br /&gt;
Now I can&#039;t tell you how to do this on your own machine however what I would recommend is that you create a link from your web root to the moodle directory of each branch.&lt;br /&gt;
&lt;br /&gt;
If you are using linux and your webroot is /var/www/localhost you would do it as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/localhost/&lt;br /&gt;
ln -s /var/www/repositories/master/moodle master&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_20_STABLE/moodle MOODLE_20_STABLE&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_19_STABLE/moodle MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done you should be able to browse to each repository with the following URL&#039;s&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://localhost/master/&lt;br /&gt;
http://localhost/MOODLE_20_STABLE/&lt;br /&gt;
http://localhost/MOODLE_19_STABLE/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that is done you need to browse to each site and complete the installation.&lt;br /&gt;
&lt;br /&gt;
Under this method your will need to ensure you set the configuration option sessioncookiepath to the URI of your site. You can either do this in the admin interfaces or add the following to your config.php file for each site.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// For the master site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/master/&#039;;&lt;br /&gt;
// For the MOODLE_20_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_20_STABLE/&#039;;&lt;br /&gt;
// For the MOODLE_19_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_19_STABLE/&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Failure to do this will mean that when you log in at one site and then visit the next you will have to log in again and your session on the first site will no longer work.&lt;br /&gt;
&lt;br /&gt;
Now that you have got 3 repositories, one for each main branch, and set up a site for each you are ready to start development.&lt;br /&gt;
&lt;br /&gt;
==Before you start work each day==&lt;br /&gt;
Before you start work each day you should update each of the repositories you have created to ensure that you are always working with up to date versions of Moodle.&lt;br /&gt;
&lt;br /&gt;
You should also take this opportunity to update the repositories on your github account to ensure they are always up to date.&lt;br /&gt;
&lt;br /&gt;
To start with lets update the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This moves to the master repository and then tells git for fetch all of the changes from your remote repositories and clean up any old branches it is aware of.&lt;br /&gt;
&lt;br /&gt;
Once that operation has completed you should update your master branch&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Before you do that it pays to make sure you don&#039;t have any uncommit changes, if you do DON&#039;T TRY IT. There would be a good chance you will encounter problems. Instead finish what you are working on, commit your changes and then update your master branch.&lt;br /&gt;
&lt;br /&gt;
Next we will update the github repositories by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github refs/remotes/origin/master:master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This tells git to push the master branch from origin (the offical Moodle repository) to the master branch on our github account.&lt;br /&gt;
&lt;br /&gt;
Now that you&#039;ve updated the master repository and your github account its time to update the MOODLE_20_STABLE and MOODLE_19_STABLE branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_20_STABLE:MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_19_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_19_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_19_STABLE:MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Working on a Moodle issue==&lt;br /&gt;
&lt;br /&gt;
This part of the document looks at how I go about working on an MDL issue from the Moodle tracker.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ we use the scrum methodology we sees us choose several issues to include in a scrum which we then work on for the period of the scrum. As a community member its more likely you will just be choosing issues that you are passionate about.&lt;br /&gt;
&lt;br /&gt;
Either way once you have found an issue to work on you are ready to start.&lt;br /&gt;
&lt;br /&gt;
For the purpose of this part of the document lets say I am going to work on bug MDL-12345.&lt;br /&gt;
&lt;br /&gt;
==Fixing a bug on the master repository - MDL-12345==&lt;br /&gt;
&lt;br /&gt;
The first step is to create a local branch to make changes on, to do this we will start our work on the master repository.&lt;br /&gt;
&lt;br /&gt;
When fixing an issue I find it easiest to fix the issue on the master branch first and then move my changes to the other branches.&lt;br /&gt;
&lt;br /&gt;
The VERY first thing you should do when you start working on a Moodle issue is make sure you have assigned it to yourself and then click the start progress button.&lt;br /&gt;
&lt;br /&gt;
This way other users know that you are activly working on the bug and no one from HQ will steal it from you.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local branch===&lt;br /&gt;
&lt;br /&gt;
So first get to the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there we create a new branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-master origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command checks out a new branch called wip-MDL-12345-master that is based upon origin/master.&lt;br /&gt;
&lt;br /&gt;
origin/master is of course the master branch on the official Moodle repository (git.moodle.org/moodle.git).&lt;br /&gt;
&lt;br /&gt;
The name of the branch is also very important. It is essentially telling us three things.&lt;br /&gt;
&lt;br /&gt;
; wip : This stands for work in progress, it helps people see that you are currently working on this branch and that they shouldn&#039;t base there work on it because it will likely change.&lt;br /&gt;
; MDL-12345 : This is of course the Moodle bug number. It helps people quickly identify what you are working on.&lt;br /&gt;
; master : This is the branch we are making changes on. It helps people quickly understand where the changes are being made.&lt;br /&gt;
&lt;br /&gt;
You can optionally add more to the end of the branch name such as a key word that identifies the area or a date at which you started work e.g.&lt;br /&gt;
&lt;br /&gt;
* wip-MDL-12345-master-navigation-changes&lt;br /&gt;
* wip-MDL-12345-master-20110418&lt;br /&gt;
&lt;br /&gt;
That is up to you, personally I&#039;m not a fan of it, however the rest is all required to help integrate your work.&lt;br /&gt;
&lt;br /&gt;
Either way now you have a branch, mine is called wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Make changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have created you branch you are ready to make changes.&lt;br /&gt;
&lt;br /&gt;
I&#039;ll let you make whatever changes you are need, once you have made changes move onto the next step.&lt;br /&gt;
&lt;br /&gt;
Before you do move on however make sure that your code meets the high quality of code Moodle requires.&lt;br /&gt;
&lt;br /&gt;
You can find information about that on the moodle docs here: https://docs.moodle.org/en/Development:Coding_style&lt;br /&gt;
&lt;br /&gt;
The following are common mistakes:&lt;br /&gt;
&lt;br /&gt;
* Incorrect white space&lt;br /&gt;
** Tabs instead of spaces&lt;br /&gt;
** Extra spaces at the end of lines&lt;br /&gt;
** Multiple new lines&lt;br /&gt;
** Forgetting to put spaces between function arguments&lt;br /&gt;
* Incorrect commit messages (read on to find out about writing a good commit message)&lt;br /&gt;
* Incorrect variable or function names&lt;br /&gt;
&lt;br /&gt;
Making these sort of mistakes can lead to your code being rejected despite it working correctly.&lt;br /&gt;
&lt;br /&gt;
I would &#039;&#039;&#039;strongly&#039;&#039;&#039; suggest while learning Moodle development that you use [[User:Tim Hunt|Tim Hunt&#039;s]] fantastic [https://github.com/timhunt/moodle-local_codechecker Code Checker] plugin.&amp;lt;br /&amp;gt;&lt;br /&gt;
You&#039;ll find information on how to use it within its README file and it will pick up many of the things that may lead to your work being rejected.&lt;br /&gt;
&lt;br /&gt;
Or course it will be reviewed in regards to security, usability and the other important factors of code development.&lt;br /&gt;
&lt;br /&gt;
===Step 3: Commit your changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have made your changes you are getting ready to commit them.&lt;br /&gt;
&lt;br /&gt;
The first thing to do is check your changes. To do this run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see all of the files you have changes highlighted in red.&lt;br /&gt;
&lt;br /&gt;
Next you need to stage all of the files you want to commit.&lt;br /&gt;
&lt;br /&gt;
To do this you add the files to the stage using the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git add lib/modifiedfile.php&lt;br /&gt;
git add lib/newfile.php&lt;br /&gt;
git add theme/base/style/core.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Why not just commit all changes. Many of the git guides you read will tell you above git commit -a which commits all of the changes you have made.&lt;br /&gt;
&lt;br /&gt;
We&#039;ve hardly being using git here at Moodle and already I&#039;ve seen several people accidentally commit changes that they didn&#039;t mean to.&lt;br /&gt;
&lt;br /&gt;
Staging files like this ENSURES you only commit things you intend to.&lt;br /&gt;
&lt;br /&gt;
Now that you have staged your changes/new files you are ready to commit. The following command commits your changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git commit -m &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command commits your changes with the commit message &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;.&lt;br /&gt;
It&#039;s very important to Moodle that you format your commit messages like this.&lt;br /&gt;
They consist of three parts:&lt;br /&gt;
&lt;br /&gt;
# The MDL bug number in this case MDL-12345&lt;br /&gt;
# The area you made changes to in this case enrol&lt;br /&gt;
# A short description of what you did, in this case I fixed a couple of enrolment bugs.&lt;br /&gt;
&lt;br /&gt;
When you commit your message you will see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[master 19a484e] changes&lt;br /&gt;
 1 files changed, 16 insertions(+), 18 deletions(-)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
There is one thing here you need to note down for later, that is the number that appears within the square brackets after the branch name, in my case it is 19a484e. This is the commit id of the commit I just made.&lt;br /&gt;
&lt;br /&gt;
===Step 4: Pushing your changes to your github account===&lt;br /&gt;
&lt;br /&gt;
Now that you have made changes to your local branch you should push it to your github account so that it can be reviewed and hopefully integrated into Moodle.&lt;br /&gt;
&lt;br /&gt;
Doing this is very simple just run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are telling git to push the branch wip-MDL-12345-master to the remote called github which we added when setting up our git repositories.&lt;br /&gt;
And just like that you&#039;ve made a branch that contains your work and pushed it to github ready to get it reviewed.&lt;br /&gt;
&lt;br /&gt;
==Moving your changes to another branch==&lt;br /&gt;
Now that you have made changes to the master branch you need to decide whether it is appropriate make those changes on any of the other branches.&lt;br /&gt;
Most likely if you are fixing a bug you will need to make the changes on the MOODLE_20_STABLE branch as well, and perhaps the MOODLE_19_STABLE branch if it is a security bug.&lt;br /&gt;
&lt;br /&gt;
Lets assume for MDL-12345 that I fixed earlier that it should be ported to MOODLE_20_STABLE as well.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local MOODLE_20_STABLE branch===&lt;br /&gt;
&lt;br /&gt;
To start with I need to move to the MOODLE_20_STABLE repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there I need to create a new branch based upon the MOODLE_20_STABLE branch that is going to contain my changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very similar to the branch we created for the changes to the master branch except that I have subsituted MOODLE_20_STABLE in place of master. This is because the new branch we are creating is based upon the MOODLE_20_STABLE branch on the offical Moodle git repository and contains changes for that branch.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Cherry-picking my changes===&lt;br /&gt;
Once we have a branch for our changes I am ready to make them again. There is however with git an easy way to do this, cherry-picking.&lt;br /&gt;
&lt;br /&gt;
Cherry-picking is the process of copying a single commit from one branch to another. In this case I want to cherry pick the commit I made earlier onto the branch I&#039;ve just created.&lt;br /&gt;
&lt;br /&gt;
However before I can do this I need to fetch the changes I made from the github repository. I need to do this because I made that changes of a totally separate local repository remember.&lt;br /&gt;
&lt;br /&gt;
So to update my repository with the latest changes I run the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command tells git to look at each remote and get any new changes (it also removes any branches that have been deleted).&lt;br /&gt;
Once it has completed you will be ready to cherry pick the commit. To do so you use the following command but replace my commit is with yours.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git cherry-pick 19a484e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Providing there are no conflicts your branch will now contain a copy of the changes you made to the master branch.&lt;br /&gt;
If there are conficts that you will need to resolve them and commit your changes however you can search for another tutorial about how to do that,&lt;br /&gt;
&lt;br /&gt;
Now I know at this point that there will be some of you who are saying &#039;Whoops I forgot what my commit id was!&#039;. If this is you don&#039;t worry, its pretty easy to find it providing you used a proper commit message like I described above.&lt;br /&gt;
Simply run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git log --oneline origin/master..github/wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the commits that are in the wip-MDL-12345-master at your github account but are not in the master branch at the offical Moodle repository.&lt;br /&gt;
You can then cherry-pick the commits shown there (the commit ID&#039;s should be highlighted in yellow).&lt;br /&gt;
&lt;br /&gt;
Once you have cherry-picked your commits its time to check that everything worked, run the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# On branch wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
# Your branch is ahead of &#039;origin/MOODLE_20_STABLE&#039; by 1 commit.&lt;br /&gt;
#&lt;br /&gt;
nothing to commit (working directory clean)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very handy as it tells you that your branch is ahead of the offical MOODLE_20_STABLE branch by one commit.&lt;br /&gt;
You can also check that your commit contains the changes you think by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git diff origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the changes you have made as a diff.&lt;br /&gt;
&lt;br /&gt;
Now that you know that your commit is there you and that it is correct it is time to push it to your github account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And thats it.&lt;br /&gt;
&lt;br /&gt;
You github account should now have two branches on it:&lt;br /&gt;
&lt;br /&gt;
; wip-MDL-12345-master : This branch is the changes you have made for the master branch&lt;br /&gt;
; wip-MDL-12345-MOODLE_20_STABLE : This branch is those same changes but for the MOODLE_20_STABLE branch&lt;br /&gt;
&lt;br /&gt;
Now you are ready to create PULL requests so that your work gets reviewed and hopefully integrated.&lt;br /&gt;
&lt;br /&gt;
==Creating a PULL request for the master branch==&lt;br /&gt;
&lt;br /&gt;
So you have successfully fixed the bug MDL-12345, you have created two branches one for master and one for MOODLE_20_STABLE. It is time to create a PULL request for each of these branches.&lt;br /&gt;
&lt;br /&gt;
First lets create a PULL request for the master branch:&lt;br /&gt;
&lt;br /&gt;
# Browse to tracker.moodle.org/browse/MDL-12345&lt;br /&gt;
# When the page loads log in if you haven&#039;t already.&lt;br /&gt;
# Click on the button in the top right labelled `Create issue`&lt;br /&gt;
# Change Project to `Pull Requests`&lt;br /&gt;
# Change Issue type to `Pull Request`&lt;br /&gt;
# Click create&lt;br /&gt;
&lt;br /&gt;
This takes you to a screen where you can enter the details for the PULL request.&lt;br /&gt;
&lt;br /&gt;
You should fill it out in the following way:&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
This is the summary for the PULL request, you should copy and paste the summary from the MDL issue here.&lt;br /&gt;
For MDL-12345 the summary is `alphabetization of UI different on left and right sides` so that&#039;s what I will use.&lt;br /&gt;
&lt;br /&gt;
===Affects Versions===&lt;br /&gt;
This is the version that your branch is changing, in the case of this PULL request I will select `master`.&lt;br /&gt;
&lt;br /&gt;
===Security level===&lt;br /&gt;
If the issue you are working on is a security issue you should set this to the same level that the issue is set to. If its not a security issue or you don&#039;t know just leave it as none.&lt;br /&gt;
&lt;br /&gt;
===Pull from repository===&lt;br /&gt;
This is the repository that the branch is at, for you this will be your github accont. If you head to http://github.com/yourname/moodle you will see a box that has three options SSH, HTTP, and Git read only, click Git Read Only and then copy the contents of the text box into the repositry field of the PULL request. &lt;br /&gt;
For me that is git://github.com/yourname/moodle.git&lt;br /&gt;
&lt;br /&gt;
===Pull branch===&lt;br /&gt;
This is the name of the branch that contains your changes. For me that is wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Pull Diff URL===&lt;br /&gt;
This is the URL to a page that shows the changes that you&#039;ve made on your branch. Github is nice in that it has a pretty interface for that. To get to the interface follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Browse to https://github.com/youraccount/moodle&lt;br /&gt;
# Click `Switch Branches` and then click on the branch you changes are based upon, in my case master.&lt;br /&gt;
# Click the button labelled `Branch List`&lt;br /&gt;
# Locate your branch in the list and click the `Compare button` for me this was the compare button to the right of wip-MDL-12345-master.&lt;br /&gt;
# Copy the URL in your browse and paste it into the Pull Diff URL of the PULL request.&lt;br /&gt;
&lt;br /&gt;
For me this URL was: https://github.com/yourname/moodle/compare/master...wip-MDL-23532-master&lt;br /&gt;
For the MOODLE_20_STABLE branch this would be: https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
&lt;br /&gt;
===Description===&lt;br /&gt;
The description should contain several bits of important information:&lt;br /&gt;
&lt;br /&gt;
# A short description of what your patch does&lt;br /&gt;
# Notes about that changes you&#039;ve made that might help the integrator understand what you did when he/she is reviewing it.&lt;br /&gt;
# Testing instructions that guide the testers through testing your changes.&lt;br /&gt;
&lt;br /&gt;
===Components===&lt;br /&gt;
Select general from the components list, general is the only option.&lt;br /&gt;
&lt;br /&gt;
===Finishing up===&lt;br /&gt;
Once you have filled in the fields as above click `Create`. This should create you PULL request and then take you to view it.&lt;br /&gt;
&lt;br /&gt;
Its important to remember that there is still one thing you need to do and that is link to the original issue.&lt;br /&gt;
While you are still logged in click the `More Actions` button and select `Link issue`, in the dialoug that pops up change the `This issue` field to `will help resolve`, type MDL-12345 into the issues field, and then type `Linking to MDL-12345` into the comments box. Once you&#039;ve done that simple click Link.&amp;lt;br /&amp;gt;I should add that the comment isn&#039;t really required. It&#039;s just something I personally like doing.&lt;br /&gt;
&lt;br /&gt;
Time to create the PULL request for the other branches.&lt;br /&gt;
&lt;br /&gt;
==Creating the PULL request for MOODLE_20_STABLE==&lt;br /&gt;
Once you&#039;ve created the PULL request for the master branch it is time to create the PULL request for the MOODLE_20_STABLE branch.&lt;br /&gt;
This is as easy as can be, click Create Issue in the top right, select PULL project and choose Pull Request and then click create.&lt;br /&gt;
On the next screen enter the following details:&lt;br /&gt;
&lt;br /&gt;
; Summary : Copy the summary from the previous PULL Request&lt;br /&gt;
; Affects Versions : Select MOODLE_20_STABLE&lt;br /&gt;
; Security level : Same as the MDL&lt;br /&gt;
; Pull from repository : Copy from the previous PULL request&lt;br /&gt;
; Pull Branch : wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
; Pull Diff URL : https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
; Description : Copy from the previous PULL request&lt;br /&gt;
; Component : general&lt;br /&gt;
&lt;br /&gt;
Then click create to create the PULL request.&lt;br /&gt;
&lt;br /&gt;
Once the PULL request has been create don&#039;t forget to link to the MDL issue like we did for the previous PULL request.&lt;br /&gt;
&lt;br /&gt;
==Rebasing after the weekly release==&lt;br /&gt;
As many of you will be aware on Wednesday after the latest weekly has been released a comment will be added to all PULL requests that are still open.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The main moodle.git repository has just been updated with latest weekly modifications.&lt;br /&gt;
You may wish to rebase your PULL branches to simplify history and avoid any possible merge conflicts. This would also make integrator&#039;s life easier next week.&lt;br /&gt;
&lt;br /&gt;
TIA and ciao :)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is a message that is bulk added as is done so as a polite request. While it&#039;s not essential for you to rebase your work it really does help the integrators as its much easier to see what is going on and greatly reduces the chance of conflicts (because you&#039;ll solve them when you rebase).&lt;br /&gt;
&lt;br /&gt;
The good news is that rebasing your work is EASY!&lt;br /&gt;
&lt;br /&gt;
For the following example lets assume I created the two PULL requests above on Wednesday morning and the weekly was released on Wednesday afternoon. This means that my branch doesn&#039;t have the changes that have just been released and I need to rebase them.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Rebasing the wip-MDL-12345-master===&lt;br /&gt;
&lt;br /&gt;
The first step is to rebase my work that is based upon the master branch. So first move to the master repository.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next thing we have to do is get all of the changes from the remote repositories, this will fetch down all of the latest changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now before the next step make sure that you don&#039;t have any uncommit changes, if you do finish that work, commit it, then proceed to the next step which is updating your local master.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
git push master github&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that your local master is up to date, and has you&#039;ve updated you master branch at github you are ready to rebase!&lt;br /&gt;
At this point we want to checkout the branch we are going to rebase, in this case wip-MDL-12345-master and then we are going to rebase origin/master which is the official Moodle master branch (and the branch our branch is based upon).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout wip-MDL-12345-master&lt;br /&gt;
git rebase origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that command has completed your branch wip-MDL-12345-master will be completely up to date. Before you are done however you need to push the rebased wip-MDL-12345-master up to your github account so that its the branch the integrator sees.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push -f github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that command is just about identical to the command we used when we first pushed our branch to our github account, there is however one VERY important difference, the &#039;&#039;&#039;-f&#039;&#039;&#039; option.&lt;br /&gt;
The &#039;&#039;&#039;-f&#039;&#039;&#039; option tells git to force the push, this is required because when you rebase all of your commit id&#039;s will change and unless you tell git to force it will see that they have changed and not allow you to push your work.&lt;br /&gt;
&lt;br /&gt;
Thats it! you&#039;ve now rebased your work and the integrators will be happy again :)&lt;br /&gt;
&lt;br /&gt;
===Step 2: Rebasing wip-MDL-12345-MOODLE_20_STABLE===&lt;br /&gt;
Now that we&#039;ve rebased our work that was based upon the master branch it is time to rebase the MOODLE_20_STABLE version.&lt;br /&gt;
This step is just about identical to the previous step except we substitute &#039;&#039;master&#039;&#039; for &#039;&#039;MOODLE_20_STABLE&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github MOODLE_20_STABLE&lt;br /&gt;
git checkout wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
git rebase origin/MOODLE_20_STABLE&lt;br /&gt;
git push -f github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&lt;br /&gt;
==Useful links==&lt;br /&gt;
The following are links I found useful while learning Git.&lt;br /&gt;
&lt;br /&gt;
* [http://help.github.com Github help (http://help.github.com)] Provides EXCELLENT help tutorials that very clearly explain the basic through to the advanced.&lt;br /&gt;
* [http://cheat.errtheblog.com/s/git/ $ cheat git] This is my favourite cheat sheet, straight forward to the point, if you know the concept you&#039;ll find the answer here.&lt;br /&gt;
* [http://gitster.livejournal.com/28309.html Gitsters journal - Fun with FETCH_HEAD] David Mudrak pointed me at this entry which I found INCREDIBLY useful when reviewing other peoples work.&lt;br /&gt;
* [[Development:Git tips]] Moodle docs page with a few handy tips about using Git for Moodle development.&lt;br /&gt;
&lt;br /&gt;
I you&#039;re looking to read/buy a book on Git I&#039;d strongly recommend [http://progit.org/ Pro Git]. I certainly found that the most useful book I read.&lt;br /&gt;
&lt;br /&gt;
[[Category:Git]]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82875</id>
		<title>User:Sam Hemelryk/My Moodle Git workflow</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82875"/>
		<updated>2011-04-19T01:49:16Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* Useful links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document is a sort of tutorial/inspection of my personal development workflow when working on Moodle with Git.&lt;br /&gt;
&lt;br /&gt;
==Creating the repositories==&lt;br /&gt;
Ok so the very first step is to create several Moodle git repositories, one for each major branch of Moodle being worked on.&lt;br /&gt;
&lt;br /&gt;
At the time of writing the major branches are MOODLE_19_STABLE, MOODLE_20_STABLE and master.&lt;br /&gt;
&lt;br /&gt;
The reason for this is that that way we have a separate site for each Moodle branch that we can test on easily. Yes you will have three sites but you won&#039;t have to worry about swtiching your site when you change branches.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Create a directory to create the repositories within===&lt;br /&gt;
&lt;br /&gt;
Personally I use Ubuntu (Linux) and I chose to create my repositories within a folder I created in /var/www. If you are using windows I would instead suggest creating C:/www/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www&lt;br /&gt;
mkdir repositories&lt;br /&gt;
cd repositories&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 2: Create a master repository===&lt;br /&gt;
This is the easiest of the branches to create a repository for.&lt;br /&gt;
&lt;br /&gt;
Within your repositories directory create a new directory called master and move into it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir master&lt;br /&gt;
cd master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we want to clone the Moodle source from the offical Moodle git repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new directory called moodle within the master directory we created just before.&lt;br /&gt;
&lt;br /&gt;
That new moodle directory should contain the Moodle source code as a git repository.&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our main git repository we need to add our github account as a remote so that we can push to it later:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd moodle&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This adds your moodle repository on github as a remote called github that you can push to later.&lt;br /&gt;
&lt;br /&gt;
Finally before we move onto the next repository we need to create a data directory because we know we will need that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 3: Create a MOODLE_20_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
The next repository we create will be for the MOODLE_20_STABLE branch.&lt;br /&gt;
To start with get back to the repositories directory that we created earlier and create a directory called MOODLE_20_STABLE within that.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_20_STABLE&lt;br /&gt;
cd MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now create a new clone of the main Moodle repository like we did for the master branch above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have done that move into the moodle directory.&lt;br /&gt;
&lt;br /&gt;
By default the master branch is the branch that is created, however we don&#039;t want that for this repository. Instead we want the MOODLE_20_STABLE branch.&lt;br /&gt;
&lt;br /&gt;
To do this we checkout local branch based upon the official MOODLE_20_STABLE branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have created that branch we can delete the local master branch so that we don&#039;t accidentally ever work on it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git branch -D master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then like we did for master we add our github repository as a remote:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And finally create a data directory we can use when we have install the site:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 4: Create a MOODLE_19_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
This step is identical to the above step except we are using the MOODLE_19_STABLE branch instead of the MOODLE_20_STABLE branch.&lt;br /&gt;
The commands for this are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_19_STABLE&lt;br /&gt;
cd MOODLE_19_STABLE&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
git checkout -b MOODLE_19_STABLE origin/MOODLE_19_STABLE&lt;br /&gt;
git branch -D master&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 5: Install the sites===&lt;br /&gt;
Now I can&#039;t tell you how to do this on your own machine however what I would recommend is that you create a link from your web root to the moodle directory of each branch.&lt;br /&gt;
&lt;br /&gt;
If you are using linux and your webroot is /var/www/localhost you would do it as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/localhost/&lt;br /&gt;
ln -s /var/www/repositories/master/moodle master&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_20_STABLE/moodle MOODLE_20_STABLE&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_19_STABLE/moodle MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done you should be able to browse to each repository with the following URL&#039;s&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://localhost/master/&lt;br /&gt;
http://localhost/MOODLE_20_STABLE/&lt;br /&gt;
http://localhost/MOODLE_19_STABLE/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that is done you need to browse to each site and complete the installation.&lt;br /&gt;
&lt;br /&gt;
Under this method your will need to ensure you set the configuration option sessioncookiepath to the URI of your site. You can either do this in the admin interfaces or add the following to your config.php file for each site.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// For the master site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/master/&#039;;&lt;br /&gt;
// For the MOODLE_20_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_20_STABLE/&#039;;&lt;br /&gt;
// For the MOODLE_19_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_19_STABLE/&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Failure to do this will mean that when you log in at one site and then visit the next you will have to log in again and your session on the first site will no longer work.&lt;br /&gt;
&lt;br /&gt;
Now that you have got 3 repositories, one for each main branch, and set up a site for each you are ready to start development.&lt;br /&gt;
&lt;br /&gt;
==Before you start work each day==&lt;br /&gt;
Before you start work each day you should update each of the repositories you have created to ensure that you are always working with up to date versions of Moodle.&lt;br /&gt;
&lt;br /&gt;
You should also take this opportunity to update the repositories on your github account to ensure they are always up to date.&lt;br /&gt;
&lt;br /&gt;
To start with lets update the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This moves to the master repository and then tells git for fetch all of the changes from your remote repositories and clean up any old branches it is aware of.&lt;br /&gt;
&lt;br /&gt;
Once that operation has completed you should update your master branch&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Before you do that it pays to make sure you don&#039;t have any uncommit changes, if you do DON&#039;T TRY IT. There would be a good chance you will encounter problems. Instead finish what you are working on, commit your changes and then update your master branch.&lt;br /&gt;
&lt;br /&gt;
Next we will update the github repositories by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github refs/remotes/origin/master:master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This tells git to push the master branch from origin (the offical Moodle repository) to the master branch on our github account.&lt;br /&gt;
&lt;br /&gt;
Now that you&#039;ve updated the master repository and your github account its time to update the MOODLE_20_STABLE and MOODLE_19_STABLE branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_20_STABLE:MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_19_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_19_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_19_STABLE:MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Working on a Moodle issue==&lt;br /&gt;
&lt;br /&gt;
This part of the document looks at how I go about working on an MDL issue from the Moodle tracker.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ we use the scrum methodology we sees us choose several issues to include in a scrum which we then work on for the period of the scrum. As a community member its more likely you will just be choosing issues that you are passionate about.&lt;br /&gt;
&lt;br /&gt;
Either way once you have found an issue to work on you are ready to start.&lt;br /&gt;
&lt;br /&gt;
For the purpose of this part of the document lets say I am going to work on bug MDL-12345.&lt;br /&gt;
&lt;br /&gt;
==Fixing a bug on the master repository - MDL-12345==&lt;br /&gt;
&lt;br /&gt;
The first step is to create a local branch to make changes on, to do this we will start our work on the master repository.&lt;br /&gt;
&lt;br /&gt;
When fixing an issue I find it easiest to fix the issue on the master branch first and then move my changes to the other branches.&lt;br /&gt;
&lt;br /&gt;
The VERY first thing you should do when you start working on a Moodle issue is make sure you have assigned it to yourself and then click the start progress button.&lt;br /&gt;
&lt;br /&gt;
This way other users know that you are activly working on the bug and no one from HQ will steal it from you.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local branch===&lt;br /&gt;
&lt;br /&gt;
So first get to the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there we create a new branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-master origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command checks out a new branch called wip-MDL-12345-master that is based upon origin/master.&lt;br /&gt;
&lt;br /&gt;
origin/master is of course the master branch on the official Moodle repository (git.moodle.org/moodle.git).&lt;br /&gt;
&lt;br /&gt;
The name of the branch is also very important. It is essentially telling us three things.&lt;br /&gt;
&lt;br /&gt;
; wip : This stands for work in progress, it helps people see that you are currently working on this branch and that they shouldn&#039;t base there work on it because it will likely change.&lt;br /&gt;
; MDL-12345 : This is of course the Moodle bug number. It helps people quickly identify what you are working on.&lt;br /&gt;
; master : This is the branch we are making changes on. It helps people quickly understand where the changes are being made.&lt;br /&gt;
&lt;br /&gt;
You can optionally add more to the end of the branch name such as a key word that identifies the area or a date at which you started work e.g.&lt;br /&gt;
&lt;br /&gt;
* wip-MDL-12345-master-navigation-changes&lt;br /&gt;
* wip-MDL-12345-master-20110418&lt;br /&gt;
&lt;br /&gt;
That is up to you, personally I&#039;m not a fan of it, however the rest is all required to help integrate your work.&lt;br /&gt;
&lt;br /&gt;
Either way now you have a branch, mine is called wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Make changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have created you branch you are ready to make changes.&lt;br /&gt;
&lt;br /&gt;
I&#039;ll let you make whatever changes you are need, once you have made changes move onto the next step.&lt;br /&gt;
&lt;br /&gt;
Before you do move on however make sure that your code meets the high quality of code Moodle requires.&lt;br /&gt;
&lt;br /&gt;
You can find information about that on the moodle docs here: https://docs.moodle.org/en/Development:Coding_style&lt;br /&gt;
&lt;br /&gt;
The following are common mistakes:&lt;br /&gt;
&lt;br /&gt;
* Incorrect white space&lt;br /&gt;
** Tabs instead of spaces&lt;br /&gt;
** Extra spaces at the end of lines&lt;br /&gt;
** Multiple new lines&lt;br /&gt;
** Forgetting to put spaces between function arguments&lt;br /&gt;
* Incorrect commit messages (read on to find out about writing a good commit message)&lt;br /&gt;
* Incorrect variable or function names&lt;br /&gt;
&lt;br /&gt;
Making these sort of mistakes can lead to your code being rejected despite it working correctly.&lt;br /&gt;
&lt;br /&gt;
Or course it will be reviewed in regards to security, usability and the other important factors of code development.&lt;br /&gt;
&lt;br /&gt;
===Step 3: Commit your changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have made your changes you are getting ready to commit them.&lt;br /&gt;
&lt;br /&gt;
The first thing to do is check your changes. To do this run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see all of the files you have changes highlighted in red.&lt;br /&gt;
&lt;br /&gt;
Next you need to stage all of the files you want to commit.&lt;br /&gt;
&lt;br /&gt;
To do this you add the files to the stage using the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git add lib/modifiedfile.php&lt;br /&gt;
git add lib/newfile.php&lt;br /&gt;
git add theme/base/style/core.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Why not just commit all changes. Many of the git guides you read will tell you above git commit -a which commits all of the changes you have made.&lt;br /&gt;
&lt;br /&gt;
We&#039;ve hardly being using git here at Moodle and already I&#039;ve seen several people accidentally commit changes that they didn&#039;t mean to.&lt;br /&gt;
&lt;br /&gt;
Staging files like this ENSURES you only commit things you intend to.&lt;br /&gt;
&lt;br /&gt;
Now that you have staged your changes/new files you are ready to commit. The following command commits your changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git commit -m &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command commits your changes with the commit message &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;.&lt;br /&gt;
It&#039;s very important to Moodle that you format your commit messages like this.&lt;br /&gt;
They consist of three parts:&lt;br /&gt;
&lt;br /&gt;
# The MDL bug number in this case MDL-12345&lt;br /&gt;
# The area you made changes to in this case enrol&lt;br /&gt;
# A short description of what you did, in this case I fixed a couple of enrolment bugs.&lt;br /&gt;
&lt;br /&gt;
When you commit your message you will see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[master 19a484e] changes&lt;br /&gt;
 1 files changed, 16 insertions(+), 18 deletions(-)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
There is one thing here you need to note down for later, that is the number that appears within the square brackets after the branch name, in my case it is 19a484e. This is the commit id of the commit I just made.&lt;br /&gt;
&lt;br /&gt;
===Step 4: Pushing your changes to your github account===&lt;br /&gt;
&lt;br /&gt;
Now that you have made changes to your local branch you should push it to your github account so that it can be reviewed and hopefully integrated into Moodle.&lt;br /&gt;
&lt;br /&gt;
Doing this is very simple just run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are telling git to push the branch wip-MDL-12345-master to the remote called github which we added when setting up our git repositories.&lt;br /&gt;
And just like that you&#039;ve made a branch that contains your work and pushed it to github ready to get it reviewed.&lt;br /&gt;
&lt;br /&gt;
==Moving your changes to another branch==&lt;br /&gt;
Now that you have made changes to the master branch you need to decide whether it is appropriate make those changes on any of the other branches.&lt;br /&gt;
Most likely if you are fixing a bug you will need to make the changes on the MOODLE_20_STABLE branch as well, and perhaps the MOODLE_19_STABLE branch if it is a security bug.&lt;br /&gt;
&lt;br /&gt;
Lets assume for MDL-12345 that I fixed earlier that it should be ported to MOODLE_20_STABLE as well.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local MOODLE_20_STABLE branch===&lt;br /&gt;
&lt;br /&gt;
To start with I need to move to the MOODLE_20_STABLE repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there I need to create a new branch based upon the MOODLE_20_STABLE branch that is going to contain my changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very similar to the branch we created for the changes to the master branch except that I have subsituted MOODLE_20_STABLE in place of master. This is because the new branch we are creating is based upon the MOODLE_20_STABLE branch on the offical Moodle git repository and contains changes for that branch.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Cherry-picking my changes===&lt;br /&gt;
Once we have a branch for our changes I am ready to make them again. There is however with git an easy way to do this, cherry-picking.&lt;br /&gt;
&lt;br /&gt;
Cherry-picking is the process of copying a single commit from one branch to another. In this case I want to cherry pick the commit I made earlier onto the branch I&#039;ve just created.&lt;br /&gt;
&lt;br /&gt;
However before I can do this I need to fetch the changes I made from the github repository. I need to do this because I made that changes of a totally separate local repository remember.&lt;br /&gt;
&lt;br /&gt;
So to update my repository with the latest changes I run the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command tells git to look at each remote and get any new changes (it also removes any branches that have been deleted).&lt;br /&gt;
Once it has completed you will be ready to cherry pick the commit. To do so you use the following command but replace my commit is with yours.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git cherry-pick 19a484e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Providing there are no conflicts your branch will now contain a copy of the changes you made to the master branch.&lt;br /&gt;
If there are conficts that you will need to resolve them and commit your changes however you can search for another tutorial about how to do that,&lt;br /&gt;
&lt;br /&gt;
Now I know at this point that there will be some of you who are saying &#039;Whoops I forgot what my commit id was!&#039;. If this is you don&#039;t worry, its pretty easy to find it providing you used a proper commit message like I described above.&lt;br /&gt;
Simply run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git log --oneline origin/master..github/wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the commits that are in the wip-MDL-12345-master at your github account but are not in the master branch at the offical Moodle repository.&lt;br /&gt;
You can then cherry-pick the commits shown there (the commit ID&#039;s should be highlighted in yellow).&lt;br /&gt;
&lt;br /&gt;
Once you have cherry-picked your commits its time to check that everything worked, run the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# On branch wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
# Your branch is ahead of &#039;origin/MOODLE_20_STABLE&#039; by 1 commit.&lt;br /&gt;
#&lt;br /&gt;
nothing to commit (working directory clean)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very handy as it tells you that your branch is ahead of the offical MOODLE_20_STABLE branch by one commit.&lt;br /&gt;
You can also check that your commit contains the changes you think by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git diff origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the changes you have made as a diff.&lt;br /&gt;
&lt;br /&gt;
Now that you know that your commit is there you and that it is correct it is time to push it to your github account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And thats it.&lt;br /&gt;
&lt;br /&gt;
You github account should now have two branches on it:&lt;br /&gt;
&lt;br /&gt;
; wip-MDL-12345-master : This branch is the changes you have made for the master branch&lt;br /&gt;
; wip-MDL-12345-MOODLE_20_STABLE : This branch is those same changes but for the MOODLE_20_STABLE branch&lt;br /&gt;
&lt;br /&gt;
Now you are ready to create PULL requests so that your work gets reviewed and hopefully integrated.&lt;br /&gt;
&lt;br /&gt;
==Creating a PULL request for the master branch==&lt;br /&gt;
&lt;br /&gt;
So you have successfully fixed the bug MDL-12345, you have created two branches one for master and one for MOODLE_20_STABLE. It is time to create a PULL request for each of these branches.&lt;br /&gt;
&lt;br /&gt;
First lets create a PULL request for the master branch:&lt;br /&gt;
&lt;br /&gt;
# Browse to tracker.moodle.org/browse/MDL-12345&lt;br /&gt;
# When the page loads log in if you haven&#039;t already.&lt;br /&gt;
# Click on the button in the top right labelled `Create issue`&lt;br /&gt;
# Change Project to `Pull Requests`&lt;br /&gt;
# Change Issue type to `Pull Request`&lt;br /&gt;
# Click create&lt;br /&gt;
&lt;br /&gt;
This takes you to a screen where you can enter the details for the PULL request.&lt;br /&gt;
&lt;br /&gt;
You should fill it out in the following way:&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
This is the summary for the PULL request, you should copy and paste the summary from the MDL issue here.&lt;br /&gt;
For MDL-12345 the summary is `alphabetization of UI different on left and right sides` so that&#039;s what I will use.&lt;br /&gt;
&lt;br /&gt;
===Affects Versions===&lt;br /&gt;
This is the version that your branch is changing, in the case of this PULL request I will select `master`.&lt;br /&gt;
&lt;br /&gt;
===Security level===&lt;br /&gt;
If the issue you are working on is a security issue you should set this to the same level that the issue is set to. If its not a security issue or you don&#039;t know just leave it as none.&lt;br /&gt;
&lt;br /&gt;
===Pull from repository===&lt;br /&gt;
This is the repository that the branch is at, for you this will be your github accont. If you head to http://github.com/yourname/moodle you will see a box that has three options SSH, HTTP, and Git read only, click Git Read Only and then copy the contents of the text box into the repositry field of the PULL request. &lt;br /&gt;
For me that is git://github.com/yourname/moodle.git&lt;br /&gt;
&lt;br /&gt;
===Pull branch===&lt;br /&gt;
This is the name of the branch that contains your changes. For me that is wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Pull Diff URL===&lt;br /&gt;
This is the URL to a page that shows the changes that you&#039;ve made on your branch. Github is nice in that it has a pretty interface for that. To get to the interface follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Browse to https://github.com/youraccount/moodle&lt;br /&gt;
# Click `Switch Branches` and then click on the branch you changes are based upon, in my case master.&lt;br /&gt;
# Click the button labelled `Branch List`&lt;br /&gt;
# Locate your branch in the list and click the `Compare button` for me this was the compare button to the right of wip-MDL-12345-master.&lt;br /&gt;
# Copy the URL in your browse and paste it into the Pull Diff URL of the PULL request.&lt;br /&gt;
&lt;br /&gt;
For me this URL was: https://github.com/yourname/moodle/compare/master...wip-MDL-23532-master&lt;br /&gt;
For the MOODLE_20_STABLE branch this would be: https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
&lt;br /&gt;
===Description===&lt;br /&gt;
The description should contain several bits of important information:&lt;br /&gt;
&lt;br /&gt;
# A short description of what your patch does&lt;br /&gt;
# Notes about that changes you&#039;ve made that might help the integrator understand what you did when he/she is reviewing it.&lt;br /&gt;
# Testing instructions that guide the testers through testing your changes.&lt;br /&gt;
&lt;br /&gt;
===Components===&lt;br /&gt;
Select general from the components list, general is the only option.&lt;br /&gt;
&lt;br /&gt;
===Finishing up===&lt;br /&gt;
Once you have filled in the fields as above click `Create`. This should create you PULL request and then take you to view it.&lt;br /&gt;
&lt;br /&gt;
Its important to remember that there is still one thing you need to do and that is link to the original issue.&lt;br /&gt;
While you are still logged in click the `More Actions` button and select `Link issue`, in the dialoug that pops up change the `This issue` field to `will help resolve`, type MDL-12345 into the issues field, and then type `Linking to MDL-12345` into the comments box. Once you&#039;ve done that simple click Link.&amp;lt;br /&amp;gt;I should add that the comment isn&#039;t really required. It&#039;s just something I personally like doing.&lt;br /&gt;
&lt;br /&gt;
Time to create the PULL request for the other branches.&lt;br /&gt;
&lt;br /&gt;
==Creating the PULL request for MOODLE_20_STABLE==&lt;br /&gt;
Once you&#039;ve created the PULL request for the master branch it is time to create the PULL request for the MOODLE_20_STABLE branch.&lt;br /&gt;
This is as easy as can be, click Create Issue in the top right, select PULL project and choose Pull Request and then click create.&lt;br /&gt;
On the next screen enter the following details:&lt;br /&gt;
&lt;br /&gt;
; Summary : Copy the summary from the previous PULL Request&lt;br /&gt;
; Affects Versions : Select MOODLE_20_STABLE&lt;br /&gt;
; Security level : Same as the MDL&lt;br /&gt;
; Pull from repository : Copy from the previous PULL request&lt;br /&gt;
; Pull Branch : wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
; Pull Diff URL : https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
; Description : Copy from the previous PULL request&lt;br /&gt;
; Component : general&lt;br /&gt;
&lt;br /&gt;
Then click create to create the PULL request.&lt;br /&gt;
&lt;br /&gt;
Once the PULL request has been create don&#039;t forget to link to the MDL issue like we did for the previous PULL request.&lt;br /&gt;
&lt;br /&gt;
==Rebasing after the weekly release==&lt;br /&gt;
As many of you will be aware on Wednesday after the latest weekly has been released a comment will be added to all PULL requests that are still open.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The main moodle.git repository has just been updated with latest weekly modifications.&lt;br /&gt;
You may wish to rebase your PULL branches to simplify history and avoid any possible merge conflicts. This would also make integrator&#039;s life easier next week.&lt;br /&gt;
&lt;br /&gt;
TIA and ciao :)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is a message that is bulk added as is done so as a polite request. While it&#039;s not essential for you to rebase your work it really does help the integrators as its much easier to see what is going on and greatly reduces the chance of conflicts (because you&#039;ll solve them when you rebase).&lt;br /&gt;
&lt;br /&gt;
The good news is that rebasing your work is EASY!&lt;br /&gt;
&lt;br /&gt;
For the following example lets assume I created the two PULL requests above on Wednesday morning and the weekly was released on Wednesday afternoon. This means that my branch doesn&#039;t have the changes that have just been released and I need to rebase them.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Rebasing the wip-MDL-12345-master===&lt;br /&gt;
&lt;br /&gt;
The first step is to rebase my work that is based upon the master branch. So first move to the master repository.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next thing we have to do is get all of the changes from the remote repositories, this will fetch down all of the latest changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now before the next step make sure that you don&#039;t have any uncommit changes, if you do finish that work, commit it, then proceed to the next step which is updating your local master.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
git push master github&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that your local master is up to date, and has you&#039;ve updated you master branch at github you are ready to rebase!&lt;br /&gt;
At this point we want to checkout the branch we are going to rebase, in this case wip-MDL-12345-master and then we are going to rebase origin/master which is the official Moodle master branch (and the branch our branch is based upon).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout wip-MDL-12345-master&lt;br /&gt;
git rebase origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that command has completed your branch wip-MDL-12345-master will be completely up to date. Before you are done however you need to push the rebased wip-MDL-12345-master up to your github account so that its the branch the integrator sees.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push -f github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that command is just about identical to the command we used when we first pushed our branch to our github account, there is however one VERY important difference, the &#039;&#039;&#039;-f&#039;&#039;&#039; option.&lt;br /&gt;
The &#039;&#039;&#039;-f&#039;&#039;&#039; option tells git to force the push, this is required because when you rebase all of your commit id&#039;s will change and unless you tell git to force it will see that they have changed and not allow you to push your work.&lt;br /&gt;
&lt;br /&gt;
Thats it! you&#039;ve now rebased your work and the integrators will be happy again :)&lt;br /&gt;
&lt;br /&gt;
===Step 2: Rebasing wip-MDL-12345-MOODLE_20_STABLE===&lt;br /&gt;
Now that we&#039;ve rebased our work that was based upon the master branch it is time to rebase the MOODLE_20_STABLE version.&lt;br /&gt;
This step is just about identical to the previous step except we substitute &#039;&#039;master&#039;&#039; for &#039;&#039;MOODLE_20_STABLE&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github MOODLE_20_STABLE&lt;br /&gt;
git checkout wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
git rebase origin/MOODLE_20_STABLE&lt;br /&gt;
git push -f github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&lt;br /&gt;
==Useful links==&lt;br /&gt;
The following are links I found useful while learning Git.&lt;br /&gt;
&lt;br /&gt;
* [http://help.github.com Github help (http://help.github.com)] Provides EXCELLENT help tutorials that very clearly explain the basic through to the advanced.&lt;br /&gt;
* [http://cheat.errtheblog.com/s/git/ $ cheat git] This is my favourite cheat sheet, straight forward to the point, if you know the concept you&#039;ll find the answer here.&lt;br /&gt;
* [http://gitster.livejournal.com/28309.html Gitsters journal - Fun with FETCH_HEAD] David Mudrak pointed me at this entry which I found INCREDIBLY useful when reviewing other peoples work.&lt;br /&gt;
* [[Development:Git tips]] Moodle docs page with a few handy tips about using Git for Moodle development.&lt;br /&gt;
&lt;br /&gt;
I you&#039;re looking to read/buy a book on Git I&#039;d strongly recommend [http://progit.org/ Pro Git]. I certainly found that the most useful book I read.&lt;br /&gt;
&lt;br /&gt;
[[Category:Git]]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82874</id>
		<title>User:Sam Hemelryk/My Moodle Git workflow</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82874"/>
		<updated>2011-04-19T01:48:10Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* Useful links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document is a sort of tutorial/inspection of my personal development workflow when working on Moodle with Git.&lt;br /&gt;
&lt;br /&gt;
==Creating the repositories==&lt;br /&gt;
Ok so the very first step is to create several Moodle git repositories, one for each major branch of Moodle being worked on.&lt;br /&gt;
&lt;br /&gt;
At the time of writing the major branches are MOODLE_19_STABLE, MOODLE_20_STABLE and master.&lt;br /&gt;
&lt;br /&gt;
The reason for this is that that way we have a separate site for each Moodle branch that we can test on easily. Yes you will have three sites but you won&#039;t have to worry about swtiching your site when you change branches.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Create a directory to create the repositories within===&lt;br /&gt;
&lt;br /&gt;
Personally I use Ubuntu (Linux) and I chose to create my repositories within a folder I created in /var/www. If you are using windows I would instead suggest creating C:/www/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www&lt;br /&gt;
mkdir repositories&lt;br /&gt;
cd repositories&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 2: Create a master repository===&lt;br /&gt;
This is the easiest of the branches to create a repository for.&lt;br /&gt;
&lt;br /&gt;
Within your repositories directory create a new directory called master and move into it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir master&lt;br /&gt;
cd master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we want to clone the Moodle source from the offical Moodle git repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new directory called moodle within the master directory we created just before.&lt;br /&gt;
&lt;br /&gt;
That new moodle directory should contain the Moodle source code as a git repository.&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our main git repository we need to add our github account as a remote so that we can push to it later:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd moodle&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This adds your moodle repository on github as a remote called github that you can push to later.&lt;br /&gt;
&lt;br /&gt;
Finally before we move onto the next repository we need to create a data directory because we know we will need that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 3: Create a MOODLE_20_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
The next repository we create will be for the MOODLE_20_STABLE branch.&lt;br /&gt;
To start with get back to the repositories directory that we created earlier and create a directory called MOODLE_20_STABLE within that.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_20_STABLE&lt;br /&gt;
cd MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now create a new clone of the main Moodle repository like we did for the master branch above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have done that move into the moodle directory.&lt;br /&gt;
&lt;br /&gt;
By default the master branch is the branch that is created, however we don&#039;t want that for this repository. Instead we want the MOODLE_20_STABLE branch.&lt;br /&gt;
&lt;br /&gt;
To do this we checkout local branch based upon the official MOODLE_20_STABLE branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have created that branch we can delete the local master branch so that we don&#039;t accidentally ever work on it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git branch -D master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then like we did for master we add our github repository as a remote:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And finally create a data directory we can use when we have install the site:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 4: Create a MOODLE_19_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
This step is identical to the above step except we are using the MOODLE_19_STABLE branch instead of the MOODLE_20_STABLE branch.&lt;br /&gt;
The commands for this are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_19_STABLE&lt;br /&gt;
cd MOODLE_19_STABLE&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
git checkout -b MOODLE_19_STABLE origin/MOODLE_19_STABLE&lt;br /&gt;
git branch -D master&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 5: Install the sites===&lt;br /&gt;
Now I can&#039;t tell you how to do this on your own machine however what I would recommend is that you create a link from your web root to the moodle directory of each branch.&lt;br /&gt;
&lt;br /&gt;
If you are using linux and your webroot is /var/www/localhost you would do it as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/localhost/&lt;br /&gt;
ln -s /var/www/repositories/master/moodle master&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_20_STABLE/moodle MOODLE_20_STABLE&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_19_STABLE/moodle MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done you should be able to browse to each repository with the following URL&#039;s&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://localhost/master/&lt;br /&gt;
http://localhost/MOODLE_20_STABLE/&lt;br /&gt;
http://localhost/MOODLE_19_STABLE/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that is done you need to browse to each site and complete the installation.&lt;br /&gt;
&lt;br /&gt;
Under this method your will need to ensure you set the configuration option sessioncookiepath to the URI of your site. You can either do this in the admin interfaces or add the following to your config.php file for each site.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// For the master site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/master/&#039;;&lt;br /&gt;
// For the MOODLE_20_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_20_STABLE/&#039;;&lt;br /&gt;
// For the MOODLE_19_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_19_STABLE/&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Failure to do this will mean that when you log in at one site and then visit the next you will have to log in again and your session on the first site will no longer work.&lt;br /&gt;
&lt;br /&gt;
Now that you have got 3 repositories, one for each main branch, and set up a site for each you are ready to start development.&lt;br /&gt;
&lt;br /&gt;
==Before you start work each day==&lt;br /&gt;
Before you start work each day you should update each of the repositories you have created to ensure that you are always working with up to date versions of Moodle.&lt;br /&gt;
&lt;br /&gt;
You should also take this opportunity to update the repositories on your github account to ensure they are always up to date.&lt;br /&gt;
&lt;br /&gt;
To start with lets update the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This moves to the master repository and then tells git for fetch all of the changes from your remote repositories and clean up any old branches it is aware of.&lt;br /&gt;
&lt;br /&gt;
Once that operation has completed you should update your master branch&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Before you do that it pays to make sure you don&#039;t have any uncommit changes, if you do DON&#039;T TRY IT. There would be a good chance you will encounter problems. Instead finish what you are working on, commit your changes and then update your master branch.&lt;br /&gt;
&lt;br /&gt;
Next we will update the github repositories by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github refs/remotes/origin/master:master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This tells git to push the master branch from origin (the offical Moodle repository) to the master branch on our github account.&lt;br /&gt;
&lt;br /&gt;
Now that you&#039;ve updated the master repository and your github account its time to update the MOODLE_20_STABLE and MOODLE_19_STABLE branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_20_STABLE:MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_19_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_19_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_19_STABLE:MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Working on a Moodle issue==&lt;br /&gt;
&lt;br /&gt;
This part of the document looks at how I go about working on an MDL issue from the Moodle tracker.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ we use the scrum methodology we sees us choose several issues to include in a scrum which we then work on for the period of the scrum. As a community member its more likely you will just be choosing issues that you are passionate about.&lt;br /&gt;
&lt;br /&gt;
Either way once you have found an issue to work on you are ready to start.&lt;br /&gt;
&lt;br /&gt;
For the purpose of this part of the document lets say I am going to work on bug MDL-12345.&lt;br /&gt;
&lt;br /&gt;
==Fixing a bug on the master repository - MDL-12345==&lt;br /&gt;
&lt;br /&gt;
The first step is to create a local branch to make changes on, to do this we will start our work on the master repository.&lt;br /&gt;
&lt;br /&gt;
When fixing an issue I find it easiest to fix the issue on the master branch first and then move my changes to the other branches.&lt;br /&gt;
&lt;br /&gt;
The VERY first thing you should do when you start working on a Moodle issue is make sure you have assigned it to yourself and then click the start progress button.&lt;br /&gt;
&lt;br /&gt;
This way other users know that you are activly working on the bug and no one from HQ will steal it from you.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local branch===&lt;br /&gt;
&lt;br /&gt;
So first get to the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there we create a new branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-master origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command checks out a new branch called wip-MDL-12345-master that is based upon origin/master.&lt;br /&gt;
&lt;br /&gt;
origin/master is of course the master branch on the official Moodle repository (git.moodle.org/moodle.git).&lt;br /&gt;
&lt;br /&gt;
The name of the branch is also very important. It is essentially telling us three things.&lt;br /&gt;
&lt;br /&gt;
; wip : This stands for work in progress, it helps people see that you are currently working on this branch and that they shouldn&#039;t base there work on it because it will likely change.&lt;br /&gt;
; MDL-12345 : This is of course the Moodle bug number. It helps people quickly identify what you are working on.&lt;br /&gt;
; master : This is the branch we are making changes on. It helps people quickly understand where the changes are being made.&lt;br /&gt;
&lt;br /&gt;
You can optionally add more to the end of the branch name such as a key word that identifies the area or a date at which you started work e.g.&lt;br /&gt;
&lt;br /&gt;
* wip-MDL-12345-master-navigation-changes&lt;br /&gt;
* wip-MDL-12345-master-20110418&lt;br /&gt;
&lt;br /&gt;
That is up to you, personally I&#039;m not a fan of it, however the rest is all required to help integrate your work.&lt;br /&gt;
&lt;br /&gt;
Either way now you have a branch, mine is called wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Make changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have created you branch you are ready to make changes.&lt;br /&gt;
&lt;br /&gt;
I&#039;ll let you make whatever changes you are need, once you have made changes move onto the next step.&lt;br /&gt;
&lt;br /&gt;
Before you do move on however make sure that your code meets the high quality of code Moodle requires.&lt;br /&gt;
&lt;br /&gt;
You can find information about that on the moodle docs here: https://docs.moodle.org/en/Development:Coding_style&lt;br /&gt;
&lt;br /&gt;
The following are common mistakes:&lt;br /&gt;
&lt;br /&gt;
* Incorrect white space&lt;br /&gt;
** Tabs instead of spaces&lt;br /&gt;
** Extra spaces at the end of lines&lt;br /&gt;
** Multiple new lines&lt;br /&gt;
** Forgetting to put spaces between function arguments&lt;br /&gt;
* Incorrect commit messages (read on to find out about writing a good commit message)&lt;br /&gt;
* Incorrect variable or function names&lt;br /&gt;
&lt;br /&gt;
Making these sort of mistakes can lead to your code being rejected despite it working correctly.&lt;br /&gt;
&lt;br /&gt;
Or course it will be reviewed in regards to security, usability and the other important factors of code development.&lt;br /&gt;
&lt;br /&gt;
===Step 3: Commit your changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have made your changes you are getting ready to commit them.&lt;br /&gt;
&lt;br /&gt;
The first thing to do is check your changes. To do this run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see all of the files you have changes highlighted in red.&lt;br /&gt;
&lt;br /&gt;
Next you need to stage all of the files you want to commit.&lt;br /&gt;
&lt;br /&gt;
To do this you add the files to the stage using the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git add lib/modifiedfile.php&lt;br /&gt;
git add lib/newfile.php&lt;br /&gt;
git add theme/base/style/core.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Why not just commit all changes. Many of the git guides you read will tell you above git commit -a which commits all of the changes you have made.&lt;br /&gt;
&lt;br /&gt;
We&#039;ve hardly being using git here at Moodle and already I&#039;ve seen several people accidentally commit changes that they didn&#039;t mean to.&lt;br /&gt;
&lt;br /&gt;
Staging files like this ENSURES you only commit things you intend to.&lt;br /&gt;
&lt;br /&gt;
Now that you have staged your changes/new files you are ready to commit. The following command commits your changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git commit -m &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command commits your changes with the commit message &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;.&lt;br /&gt;
It&#039;s very important to Moodle that you format your commit messages like this.&lt;br /&gt;
They consist of three parts:&lt;br /&gt;
&lt;br /&gt;
# The MDL bug number in this case MDL-12345&lt;br /&gt;
# The area you made changes to in this case enrol&lt;br /&gt;
# A short description of what you did, in this case I fixed a couple of enrolment bugs.&lt;br /&gt;
&lt;br /&gt;
When you commit your message you will see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[master 19a484e] changes&lt;br /&gt;
 1 files changed, 16 insertions(+), 18 deletions(-)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
There is one thing here you need to note down for later, that is the number that appears within the square brackets after the branch name, in my case it is 19a484e. This is the commit id of the commit I just made.&lt;br /&gt;
&lt;br /&gt;
===Step 4: Pushing your changes to your github account===&lt;br /&gt;
&lt;br /&gt;
Now that you have made changes to your local branch you should push it to your github account so that it can be reviewed and hopefully integrated into Moodle.&lt;br /&gt;
&lt;br /&gt;
Doing this is very simple just run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are telling git to push the branch wip-MDL-12345-master to the remote called github which we added when setting up our git repositories.&lt;br /&gt;
And just like that you&#039;ve made a branch that contains your work and pushed it to github ready to get it reviewed.&lt;br /&gt;
&lt;br /&gt;
==Moving your changes to another branch==&lt;br /&gt;
Now that you have made changes to the master branch you need to decide whether it is appropriate make those changes on any of the other branches.&lt;br /&gt;
Most likely if you are fixing a bug you will need to make the changes on the MOODLE_20_STABLE branch as well, and perhaps the MOODLE_19_STABLE branch if it is a security bug.&lt;br /&gt;
&lt;br /&gt;
Lets assume for MDL-12345 that I fixed earlier that it should be ported to MOODLE_20_STABLE as well.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local MOODLE_20_STABLE branch===&lt;br /&gt;
&lt;br /&gt;
To start with I need to move to the MOODLE_20_STABLE repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there I need to create a new branch based upon the MOODLE_20_STABLE branch that is going to contain my changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very similar to the branch we created for the changes to the master branch except that I have subsituted MOODLE_20_STABLE in place of master. This is because the new branch we are creating is based upon the MOODLE_20_STABLE branch on the offical Moodle git repository and contains changes for that branch.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Cherry-picking my changes===&lt;br /&gt;
Once we have a branch for our changes I am ready to make them again. There is however with git an easy way to do this, cherry-picking.&lt;br /&gt;
&lt;br /&gt;
Cherry-picking is the process of copying a single commit from one branch to another. In this case I want to cherry pick the commit I made earlier onto the branch I&#039;ve just created.&lt;br /&gt;
&lt;br /&gt;
However before I can do this I need to fetch the changes I made from the github repository. I need to do this because I made that changes of a totally separate local repository remember.&lt;br /&gt;
&lt;br /&gt;
So to update my repository with the latest changes I run the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command tells git to look at each remote and get any new changes (it also removes any branches that have been deleted).&lt;br /&gt;
Once it has completed you will be ready to cherry pick the commit. To do so you use the following command but replace my commit is with yours.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git cherry-pick 19a484e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Providing there are no conflicts your branch will now contain a copy of the changes you made to the master branch.&lt;br /&gt;
If there are conficts that you will need to resolve them and commit your changes however you can search for another tutorial about how to do that,&lt;br /&gt;
&lt;br /&gt;
Now I know at this point that there will be some of you who are saying &#039;Whoops I forgot what my commit id was!&#039;. If this is you don&#039;t worry, its pretty easy to find it providing you used a proper commit message like I described above.&lt;br /&gt;
Simply run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git log --oneline origin/master..github/wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the commits that are in the wip-MDL-12345-master at your github account but are not in the master branch at the offical Moodle repository.&lt;br /&gt;
You can then cherry-pick the commits shown there (the commit ID&#039;s should be highlighted in yellow).&lt;br /&gt;
&lt;br /&gt;
Once you have cherry-picked your commits its time to check that everything worked, run the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# On branch wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
# Your branch is ahead of &#039;origin/MOODLE_20_STABLE&#039; by 1 commit.&lt;br /&gt;
#&lt;br /&gt;
nothing to commit (working directory clean)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very handy as it tells you that your branch is ahead of the offical MOODLE_20_STABLE branch by one commit.&lt;br /&gt;
You can also check that your commit contains the changes you think by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git diff origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the changes you have made as a diff.&lt;br /&gt;
&lt;br /&gt;
Now that you know that your commit is there you and that it is correct it is time to push it to your github account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And thats it.&lt;br /&gt;
&lt;br /&gt;
You github account should now have two branches on it:&lt;br /&gt;
&lt;br /&gt;
; wip-MDL-12345-master : This branch is the changes you have made for the master branch&lt;br /&gt;
; wip-MDL-12345-MOODLE_20_STABLE : This branch is those same changes but for the MOODLE_20_STABLE branch&lt;br /&gt;
&lt;br /&gt;
Now you are ready to create PULL requests so that your work gets reviewed and hopefully integrated.&lt;br /&gt;
&lt;br /&gt;
==Creating a PULL request for the master branch==&lt;br /&gt;
&lt;br /&gt;
So you have successfully fixed the bug MDL-12345, you have created two branches one for master and one for MOODLE_20_STABLE. It is time to create a PULL request for each of these branches.&lt;br /&gt;
&lt;br /&gt;
First lets create a PULL request for the master branch:&lt;br /&gt;
&lt;br /&gt;
# Browse to tracker.moodle.org/browse/MDL-12345&lt;br /&gt;
# When the page loads log in if you haven&#039;t already.&lt;br /&gt;
# Click on the button in the top right labelled `Create issue`&lt;br /&gt;
# Change Project to `Pull Requests`&lt;br /&gt;
# Change Issue type to `Pull Request`&lt;br /&gt;
# Click create&lt;br /&gt;
&lt;br /&gt;
This takes you to a screen where you can enter the details for the PULL request.&lt;br /&gt;
&lt;br /&gt;
You should fill it out in the following way:&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
This is the summary for the PULL request, you should copy and paste the summary from the MDL issue here.&lt;br /&gt;
For MDL-12345 the summary is `alphabetization of UI different on left and right sides` so that&#039;s what I will use.&lt;br /&gt;
&lt;br /&gt;
===Affects Versions===&lt;br /&gt;
This is the version that your branch is changing, in the case of this PULL request I will select `master`.&lt;br /&gt;
&lt;br /&gt;
===Security level===&lt;br /&gt;
If the issue you are working on is a security issue you should set this to the same level that the issue is set to. If its not a security issue or you don&#039;t know just leave it as none.&lt;br /&gt;
&lt;br /&gt;
===Pull from repository===&lt;br /&gt;
This is the repository that the branch is at, for you this will be your github accont. If you head to http://github.com/yourname/moodle you will see a box that has three options SSH, HTTP, and Git read only, click Git Read Only and then copy the contents of the text box into the repositry field of the PULL request. &lt;br /&gt;
For me that is git://github.com/yourname/moodle.git&lt;br /&gt;
&lt;br /&gt;
===Pull branch===&lt;br /&gt;
This is the name of the branch that contains your changes. For me that is wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Pull Diff URL===&lt;br /&gt;
This is the URL to a page that shows the changes that you&#039;ve made on your branch. Github is nice in that it has a pretty interface for that. To get to the interface follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Browse to https://github.com/youraccount/moodle&lt;br /&gt;
# Click `Switch Branches` and then click on the branch you changes are based upon, in my case master.&lt;br /&gt;
# Click the button labelled `Branch List`&lt;br /&gt;
# Locate your branch in the list and click the `Compare button` for me this was the compare button to the right of wip-MDL-12345-master.&lt;br /&gt;
# Copy the URL in your browse and paste it into the Pull Diff URL of the PULL request.&lt;br /&gt;
&lt;br /&gt;
For me this URL was: https://github.com/yourname/moodle/compare/master...wip-MDL-23532-master&lt;br /&gt;
For the MOODLE_20_STABLE branch this would be: https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
&lt;br /&gt;
===Description===&lt;br /&gt;
The description should contain several bits of important information:&lt;br /&gt;
&lt;br /&gt;
# A short description of what your patch does&lt;br /&gt;
# Notes about that changes you&#039;ve made that might help the integrator understand what you did when he/she is reviewing it.&lt;br /&gt;
# Testing instructions that guide the testers through testing your changes.&lt;br /&gt;
&lt;br /&gt;
===Components===&lt;br /&gt;
Select general from the components list, general is the only option.&lt;br /&gt;
&lt;br /&gt;
===Finishing up===&lt;br /&gt;
Once you have filled in the fields as above click `Create`. This should create you PULL request and then take you to view it.&lt;br /&gt;
&lt;br /&gt;
Its important to remember that there is still one thing you need to do and that is link to the original issue.&lt;br /&gt;
While you are still logged in click the `More Actions` button and select `Link issue`, in the dialoug that pops up change the `This issue` field to `will help resolve`, type MDL-12345 into the issues field, and then type `Linking to MDL-12345` into the comments box. Once you&#039;ve done that simple click Link.&amp;lt;br /&amp;gt;I should add that the comment isn&#039;t really required. It&#039;s just something I personally like doing.&lt;br /&gt;
&lt;br /&gt;
Time to create the PULL request for the other branches.&lt;br /&gt;
&lt;br /&gt;
==Creating the PULL request for MOODLE_20_STABLE==&lt;br /&gt;
Once you&#039;ve created the PULL request for the master branch it is time to create the PULL request for the MOODLE_20_STABLE branch.&lt;br /&gt;
This is as easy as can be, click Create Issue in the top right, select PULL project and choose Pull Request and then click create.&lt;br /&gt;
On the next screen enter the following details:&lt;br /&gt;
&lt;br /&gt;
; Summary : Copy the summary from the previous PULL Request&lt;br /&gt;
; Affects Versions : Select MOODLE_20_STABLE&lt;br /&gt;
; Security level : Same as the MDL&lt;br /&gt;
; Pull from repository : Copy from the previous PULL request&lt;br /&gt;
; Pull Branch : wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
; Pull Diff URL : https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
; Description : Copy from the previous PULL request&lt;br /&gt;
; Component : general&lt;br /&gt;
&lt;br /&gt;
Then click create to create the PULL request.&lt;br /&gt;
&lt;br /&gt;
Once the PULL request has been create don&#039;t forget to link to the MDL issue like we did for the previous PULL request.&lt;br /&gt;
&lt;br /&gt;
==Rebasing after the weekly release==&lt;br /&gt;
As many of you will be aware on Wednesday after the latest weekly has been released a comment will be added to all PULL requests that are still open.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The main moodle.git repository has just been updated with latest weekly modifications.&lt;br /&gt;
You may wish to rebase your PULL branches to simplify history and avoid any possible merge conflicts. This would also make integrator&#039;s life easier next week.&lt;br /&gt;
&lt;br /&gt;
TIA and ciao :)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is a message that is bulk added as is done so as a polite request. While it&#039;s not essential for you to rebase your work it really does help the integrators as its much easier to see what is going on and greatly reduces the chance of conflicts (because you&#039;ll solve them when you rebase).&lt;br /&gt;
&lt;br /&gt;
The good news is that rebasing your work is EASY!&lt;br /&gt;
&lt;br /&gt;
For the following example lets assume I created the two PULL requests above on Wednesday morning and the weekly was released on Wednesday afternoon. This means that my branch doesn&#039;t have the changes that have just been released and I need to rebase them.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Rebasing the wip-MDL-12345-master===&lt;br /&gt;
&lt;br /&gt;
The first step is to rebase my work that is based upon the master branch. So first move to the master repository.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next thing we have to do is get all of the changes from the remote repositories, this will fetch down all of the latest changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now before the next step make sure that you don&#039;t have any uncommit changes, if you do finish that work, commit it, then proceed to the next step which is updating your local master.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
git push master github&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that your local master is up to date, and has you&#039;ve updated you master branch at github you are ready to rebase!&lt;br /&gt;
At this point we want to checkout the branch we are going to rebase, in this case wip-MDL-12345-master and then we are going to rebase origin/master which is the official Moodle master branch (and the branch our branch is based upon).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout wip-MDL-12345-master&lt;br /&gt;
git rebase origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that command has completed your branch wip-MDL-12345-master will be completely up to date. Before you are done however you need to push the rebased wip-MDL-12345-master up to your github account so that its the branch the integrator sees.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push -f github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that command is just about identical to the command we used when we first pushed our branch to our github account, there is however one VERY important difference, the &#039;&#039;&#039;-f&#039;&#039;&#039; option.&lt;br /&gt;
The &#039;&#039;&#039;-f&#039;&#039;&#039; option tells git to force the push, this is required because when you rebase all of your commit id&#039;s will change and unless you tell git to force it will see that they have changed and not allow you to push your work.&lt;br /&gt;
&lt;br /&gt;
Thats it! you&#039;ve now rebased your work and the integrators will be happy again :)&lt;br /&gt;
&lt;br /&gt;
===Step 2: Rebasing wip-MDL-12345-MOODLE_20_STABLE===&lt;br /&gt;
Now that we&#039;ve rebased our work that was based upon the master branch it is time to rebase the MOODLE_20_STABLE version.&lt;br /&gt;
This step is just about identical to the previous step except we substitute &#039;&#039;master&#039;&#039; for &#039;&#039;MOODLE_20_STABLE&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github MOODLE_20_STABLE&lt;br /&gt;
git checkout wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
git rebase origin/MOODLE_20_STABLE&lt;br /&gt;
git push -f github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&lt;br /&gt;
==Useful links==&lt;br /&gt;
The following are links I found useful while learning Git.&lt;br /&gt;
&lt;br /&gt;
* [http://help.github.com Github help (http://help.github.com)] Provides EXCELLENT help tutorials that very clearly explain the basic through to the advanced.&lt;br /&gt;
* [http://cheat.errtheblog.com/s/git/ $ cheat git] This is my favourite cheat sheet, straight forward to the point, if you know the concept you&#039;ll find the answer here.&lt;br /&gt;
* [http://gitster.livejournal.com/28309.html Gitsters journal - Fun with FETCH_HEAD] David Mudrak pointed me at this entry which I found INCREDIBLY useful when reviewing other peoples work.&lt;br /&gt;
* [[Development:Git tips]] Moodle docs page with a few handy tips about using Git for Moodle development.&lt;br /&gt;
&lt;br /&gt;
I you&#039;re looking to read/buy a book on Git I&#039;d strongly recommend [http://progit.org/ Pro Git]. I certainly found that the most useful book I read.&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=Development:Git_tips&amp;diff=82873</id>
		<title>Development:Git tips</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=Development:Git_tips&amp;diff=82873"/>
		<updated>2011-04-19T01:48:00Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Many developers find git a useful tool to help them with moodle development, here some tips and workflows can be shared to help others.&lt;br /&gt;
&lt;br /&gt;
== Thorough Resolved Bug QA review with git ==&lt;br /&gt;
&lt;br /&gt;
The power of having fast access to all of moodle commit history means we can search and checkout any point in moodle source code history which allows us to powerfully QA a bug.&lt;br /&gt;
&lt;br /&gt;
Please note this workflow might not be ideal for all scenarios (for example if lots of work has been done in the same area since).&lt;br /&gt;
&lt;br /&gt;
Example Workflow to QA MDL-16600:&lt;br /&gt;
&lt;br /&gt;
First checkout a new branch for us to work on testing the bug in MOODLE_19_STABLE. We can delete this branch later, its less dangerous than playing any of our &#039;live&#039; branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ git checkout -b QA-MDL-16600 origin/MOODLE_19_STABLE&lt;br /&gt;
Branch QA-MDL-16600 set up to track remote branch refs/remotes/origin/MOODLE_19_STABLE.&lt;br /&gt;
Switched to a new branch &amp;quot;QA-MDL-16600&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now search for any commits related to this bug fix:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$  git log --grep=&#039;MDL-16600&#039;&lt;br /&gt;
commit 1c2c8b09469ac27a3829e7267f399356a05b9810&lt;br /&gt;
Author: tjhunt &amp;lt;tjhunt&amp;gt;&lt;br /&gt;
Date:   Fri Sep 26 05:49:06 2008 +0000&lt;br /&gt;
&lt;br /&gt;
    MDL-16600 forcedownload broken for file resources.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to test that these commits fixed the bug, we will revert this commit, and then try to reproduce the reported bug:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ git revert -n 1c2c8b09469ac27a3829e7267f399356a05b9810 &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we&#039;ve reproduced the problem, we will reset our repository back to HEAD:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git reset --hard HEAD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now if the bug is fixed, it can be closed and we can delete our branch:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git branch -D QA-MDL-16600&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Backporting stuff from cvshead to stable git branches ==&lt;br /&gt;
&lt;br /&gt;
I (Penny) have to do this all the time and it sucks.  So I made a script to make it suck less.&lt;br /&gt;
&lt;br /&gt;
http://cvs.moodle.org/contrib/tools/devtools/bugstogitformatpatch?view=markup&lt;br /&gt;
&lt;br /&gt;
This little perl script takes a list of bug numbers, and generates patches that you can apply with git-am&lt;br /&gt;
&lt;br /&gt;
I backported Tim&#039;s roles UI work and this is how I did it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# make a new branch to work on&lt;br /&gt;
$ git checkout -b mdl19-rolesbackport origin/MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now create some file that contains a list of bug numbers... In the case that there&#039;s only one, you can do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ echo MDL-xxxxx | bugstogitformatpatch --otherargs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Else you can do either of:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ cat myplan | bugstogitformatpatch --otherargs&lt;br /&gt;
$ bugstogitformatpatch --grepfile myplan&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This file could be a whole file with documentation and everything, but the script &#039;&#039;&#039;does&#039;&#039;&#039; expect the bug numbers to be one per-line (but accepts other junk on the same line) and start with MDL-xxxx&lt;br /&gt;
&lt;br /&gt;
The script has some other options, like where to put the patches it generates, and what the revlog spec should look like (by default it will just do origin/cvshead, but you can restrict it to a different branch or even abcdefg..12345678 if you want, anything git-log can understand - see man git-rev-parse).&lt;br /&gt;
&lt;br /&gt;
See --help for more information.&lt;br /&gt;
&lt;br /&gt;
Now the script will run and actually much faster than I expected, for Moodle&#039;s entire history.  It will spit out git-format-patch formatted patches, which you can then happily apply with git-am.&lt;br /&gt;
&lt;br /&gt;
TIP:  For a large feature that goes into HEAD, it may happen that someone commits bugfixes to HEAD after you&#039;ve backported it, which you&#039;ll then subsequently want to apply.  To get around this, I did...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ git tag rolesbackportedtohead origin/cvshead&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After I was done... then the next time I wanted to run the script, I just used --revlist rolesbackportedtohere..origin/cvshead to only look at patches after the last time.&lt;br /&gt;
&lt;br /&gt;
== Local collaboration ==&lt;br /&gt;
You want to do this...&lt;br /&gt;
&lt;br /&gt;
* git.moodle.org&lt;br /&gt;
** my organisation&#039;s git repository: aka shared repo (pulled from git.moodle.org)&lt;br /&gt;
*** developer 1 (local git)&lt;br /&gt;
*** developer 3 (local git)&lt;br /&gt;
*** etc.&lt;br /&gt;
&lt;br /&gt;
You want to collaboratively develop Moodle stuff pushing and pulling from your local shared repository. On top of that you want the upstream repository itself to pull updates from the upstream git.moodle.org.&lt;br /&gt;
&lt;br /&gt;
Some names used in the examples:&lt;br /&gt;
&lt;br /&gt;
* devel-1: the first developer&lt;br /&gt;
* devel-2: the second developer&lt;br /&gt;
* shared-repo: the name of the shared repository directory&lt;br /&gt;
* git-moodle: the name of the unix group needed to use the shared repository&lt;br /&gt;
&lt;br /&gt;
Some assuptions for the examples:&lt;br /&gt;
&lt;br /&gt;
* Linux/Unix environment&lt;br /&gt;
* All the repositories are on the same machine (if not, only need to change git transports from git:// to git+ssh://, etc.)&lt;br /&gt;
&lt;br /&gt;
Devel-1: Create local repo and configure working environment:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /path/to/devel-1/dir&lt;br /&gt;
mkdir devel-1.git&lt;br /&gt;
cd devel-1.git&lt;br /&gt;
git init&lt;br /&gt;
git config --global user.name &#039;Devel-1 Real Name&#039;&lt;br /&gt;
git config --global user.email &#039;devel-1@email.address&#039;&lt;br /&gt;
git config --global i18n.commitEncoding &#039;utf8&#039;&lt;br /&gt;
git config --global i18n.logOutputEncoding &#039;utf8&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get branches from git.moodle.org repo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git remote add -t cvshead -t MOODLE_19_STABLE -t MOODLE_18_STABLE -m cvshead moodleorg git://git.moodle.org/moodle.git&lt;br /&gt;
git fetch moodleorg&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create local (work) branches:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git branch --track cvshead-devel-1 moodleorg/cvshead&lt;br /&gt;
git branch --track mdl19-devel-1 moodleorg/MOODLE_19_STABLE&lt;br /&gt;
git branch --track mdl18-devel-1 moodleorg/MOODLE_18_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Create local shared repo and configure it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /path/to/shared-repo/dir&lt;br /&gt;
mkdir shared-repo.git&lt;br /&gt;
cd shared-repo.git&lt;br /&gt;
git --bare init --shared=all&lt;br /&gt;
chmod g=rwxs,o=rx .          # Give appropiate permissions to users in&lt;br /&gt;
sudo chgrp -R git-moodle .   # group &#039;git-moodle&#039;.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Populate shared repo from local devel-1 repo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /path/to/devel-1/dir/devel-1.git&lt;br /&gt;
git remote add shared-repo /path/to/shared-repo/dir/shared-repo.git&lt;br /&gt;
git push shared-repo +cvshead-devel-1: +mdl19-devel-1: +mdl18-devel-1:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Configure Devel-1 local repo branches to merge the right remote branch when pulling. We need to do this only for the first developer, as the shared repo didn&#039;t exist when we created the branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /path/to/devel-1/dir/devel-1.git&lt;br /&gt;
git config branch.cvshead-devel-1.remote shared-repo&lt;br /&gt;
git config branch.cvshead-devel-1.merge refs/heads/cvshead-devel-1&lt;br /&gt;
git config branch.mdl19-devel-1.remote shared-repo&lt;br /&gt;
git config branch.mdl19-devel-1.merge refs/heads/mdl19-devel-1&lt;br /&gt;
git config branch.mdl18-devel-1.remote shared-repo&lt;br /&gt;
git config branch.mdl18-devel-1.merge refs/heads/mdl18-devel-1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Create Devel-2 local repo and configure working environment:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /path/to/devel-2/dir&lt;br /&gt;
git clone -o shared-repo /path/to/shared-repo/dir/shared-repo.git devel-2.git&lt;br /&gt;
cd devel-2.git&lt;br /&gt;
git config --global user.name &#039;Devel-2 Real Name&#039;&lt;br /&gt;
git config --global user.email &#039;devel-2@email.address&#039;&lt;br /&gt;
git config --global i18n.commitEncoding &#039;utf8&#039;&lt;br /&gt;
git config --global i18n.logOutputEncoding &#039;utf8&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Get branches from git.moodle.org repo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd devel-2.git&lt;br /&gt;
git remote add -t cvshead -t MOODLE_19_STABLE -t MOODLE_18_STABLE -m cvshead moodleorg git://git.moodle.org/moodle.git&lt;br /&gt;
git fetch moodleorg&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Create local (work) branches from moodle.org:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git branch --track cvshead-devel-2 moodleorg/cvshead&lt;br /&gt;
git branch --track mdl19-devel-2 moodleorg/MOODLE_19_STABLE&lt;br /&gt;
git branch --track mdl18-devel-2 moodleorg/MOODLE_18_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
From the shared-repo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git branch --track cvshead-devel-1 shared-repo/cvshead-devel-1&lt;br /&gt;
git branch --track mdl19-devel-1 shared-repo/mdl19-devel-1&lt;br /&gt;
git branch --track mdl18-devel-1 shared-repo/mdl18-devel-1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Configure local branches to merge the right remote branch when pulling:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Nothing to do :-)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can pull and push from any of the configured remote repositories (git.moodle.org and your shared local repo) by specifiying the remote repository name when using &#039;git pull&#039; or &#039;git push&#039;&lt;br /&gt;
&lt;br /&gt;
== Consider &#039;gitosis&#039; for shared development ==&lt;br /&gt;
&lt;br /&gt;
If you are using git with a shared git repository, while &#039;ssh&#039; access works it can be tricky to deal with permissions. &#039;Gitosis&#039; allows multiple users all to access the repository using a single user on the server. Access control uses key-pairs. The article at [http://scie.nti.st/2007/11/14/hosting-git-repositories-the-easy-and-secure-way scie.nti.st] is a good introduction. &lt;br /&gt;
&lt;br /&gt;
== Git &amp;quot;Undo&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
Well not really!  If you are about to do a git operation and you are really not sure it will save you time to simply take a copy of the entire repository first. It is likely to take orders of magnitude less time to replace the repository with the copy than to unpick a broken repository.&lt;br /&gt;
&lt;br /&gt;
== Use &#039;git status&#039; a lot ==&lt;br /&gt;
&lt;br /&gt;
Before doing pretty much anything run &#039;git status&#039; and read it. Make sure you are on the branch you think you are and that the list of changes to be committed (or not) is what you expect. It&#039;s easy to fix now than after you have done a commit (or worse still a push).&lt;br /&gt;
&lt;br /&gt;
== When you forget what all your branches are ==&lt;br /&gt;
&lt;br /&gt;
    gitk --all&lt;br /&gt;
&lt;br /&gt;
is incredibly useful for showing the relationships between branches visually.&lt;br /&gt;
&lt;br /&gt;
== Know your verbose commands ==&lt;br /&gt;
&lt;br /&gt;
You can get lots of information out of git, but it&#039;s not always completely obvious how. The following commands can be useful...&lt;br /&gt;
&lt;br /&gt;
    git branch -av&lt;br /&gt;
&lt;br /&gt;
...shows all the branches (both local and remote), the last commit message and tells you (for a branch that tracks a remote) if it is forward or behind (or both!)&lt;br /&gt;
&lt;br /&gt;
    git branch -vv&lt;br /&gt;
&lt;br /&gt;
...shows your local branches and &#039;&#039;&#039;which remotes they track&#039;&#039;&#039;. Very useful when you gave them a silly name and have forgotten what they track.&lt;br /&gt;
&lt;br /&gt;
    git remote -v&lt;br /&gt;
&lt;br /&gt;
...lists all the remotes AND their full URLs for when you forget what they all are. &lt;br /&gt;
&lt;br /&gt;
   git remote show &amp;lt;remote_name&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...provides all the information you could ever want about a remote&lt;br /&gt;
&lt;br /&gt;
== More tips please ==&lt;br /&gt;
(Please add your own tips here!)&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
* [[Using GIT to backup moodledata]]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=119016 Moodle Development with git]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=124570 Local collaboration and Git - Yeah another git question!!]&lt;br /&gt;
* [[User:Sam Hemelryk/My Moodle Git workflow]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer|Git tips]]&lt;br /&gt;
[[Category:Developer tools|Git]]&lt;br /&gt;
[[Category:Git]]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82872</id>
		<title>User:Sam Hemelryk/My Moodle Git workflow</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82872"/>
		<updated>2011-04-19T01:45:06Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* Rebasing after the weekly release */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document is a sort of tutorial/inspection of my personal development workflow when working on Moodle with Git.&lt;br /&gt;
&lt;br /&gt;
==Creating the repositories==&lt;br /&gt;
Ok so the very first step is to create several Moodle git repositories, one for each major branch of Moodle being worked on.&lt;br /&gt;
&lt;br /&gt;
At the time of writing the major branches are MOODLE_19_STABLE, MOODLE_20_STABLE and master.&lt;br /&gt;
&lt;br /&gt;
The reason for this is that that way we have a separate site for each Moodle branch that we can test on easily. Yes you will have three sites but you won&#039;t have to worry about swtiching your site when you change branches.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Create a directory to create the repositories within===&lt;br /&gt;
&lt;br /&gt;
Personally I use Ubuntu (Linux) and I chose to create my repositories within a folder I created in /var/www. If you are using windows I would instead suggest creating C:/www/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www&lt;br /&gt;
mkdir repositories&lt;br /&gt;
cd repositories&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 2: Create a master repository===&lt;br /&gt;
This is the easiest of the branches to create a repository for.&lt;br /&gt;
&lt;br /&gt;
Within your repositories directory create a new directory called master and move into it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir master&lt;br /&gt;
cd master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we want to clone the Moodle source from the offical Moodle git repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new directory called moodle within the master directory we created just before.&lt;br /&gt;
&lt;br /&gt;
That new moodle directory should contain the Moodle source code as a git repository.&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our main git repository we need to add our github account as a remote so that we can push to it later:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd moodle&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This adds your moodle repository on github as a remote called github that you can push to later.&lt;br /&gt;
&lt;br /&gt;
Finally before we move onto the next repository we need to create a data directory because we know we will need that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 3: Create a MOODLE_20_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
The next repository we create will be for the MOODLE_20_STABLE branch.&lt;br /&gt;
To start with get back to the repositories directory that we created earlier and create a directory called MOODLE_20_STABLE within that.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_20_STABLE&lt;br /&gt;
cd MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now create a new clone of the main Moodle repository like we did for the master branch above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have done that move into the moodle directory.&lt;br /&gt;
&lt;br /&gt;
By default the master branch is the branch that is created, however we don&#039;t want that for this repository. Instead we want the MOODLE_20_STABLE branch.&lt;br /&gt;
&lt;br /&gt;
To do this we checkout local branch based upon the official MOODLE_20_STABLE branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have created that branch we can delete the local master branch so that we don&#039;t accidentally ever work on it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git branch -D master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then like we did for master we add our github repository as a remote:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And finally create a data directory we can use when we have install the site:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 4: Create a MOODLE_19_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
This step is identical to the above step except we are using the MOODLE_19_STABLE branch instead of the MOODLE_20_STABLE branch.&lt;br /&gt;
The commands for this are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_19_STABLE&lt;br /&gt;
cd MOODLE_19_STABLE&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
git checkout -b MOODLE_19_STABLE origin/MOODLE_19_STABLE&lt;br /&gt;
git branch -D master&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 5: Install the sites===&lt;br /&gt;
Now I can&#039;t tell you how to do this on your own machine however what I would recommend is that you create a link from your web root to the moodle directory of each branch.&lt;br /&gt;
&lt;br /&gt;
If you are using linux and your webroot is /var/www/localhost you would do it as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/localhost/&lt;br /&gt;
ln -s /var/www/repositories/master/moodle master&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_20_STABLE/moodle MOODLE_20_STABLE&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_19_STABLE/moodle MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done you should be able to browse to each repository with the following URL&#039;s&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://localhost/master/&lt;br /&gt;
http://localhost/MOODLE_20_STABLE/&lt;br /&gt;
http://localhost/MOODLE_19_STABLE/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that is done you need to browse to each site and complete the installation.&lt;br /&gt;
&lt;br /&gt;
Under this method your will need to ensure you set the configuration option sessioncookiepath to the URI of your site. You can either do this in the admin interfaces or add the following to your config.php file for each site.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// For the master site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/master/&#039;;&lt;br /&gt;
// For the MOODLE_20_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_20_STABLE/&#039;;&lt;br /&gt;
// For the MOODLE_19_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_19_STABLE/&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Failure to do this will mean that when you log in at one site and then visit the next you will have to log in again and your session on the first site will no longer work.&lt;br /&gt;
&lt;br /&gt;
Now that you have got 3 repositories, one for each main branch, and set up a site for each you are ready to start development.&lt;br /&gt;
&lt;br /&gt;
==Before you start work each day==&lt;br /&gt;
Before you start work each day you should update each of the repositories you have created to ensure that you are always working with up to date versions of Moodle.&lt;br /&gt;
&lt;br /&gt;
You should also take this opportunity to update the repositories on your github account to ensure they are always up to date.&lt;br /&gt;
&lt;br /&gt;
To start with lets update the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This moves to the master repository and then tells git for fetch all of the changes from your remote repositories and clean up any old branches it is aware of.&lt;br /&gt;
&lt;br /&gt;
Once that operation has completed you should update your master branch&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Before you do that it pays to make sure you don&#039;t have any uncommit changes, if you do DON&#039;T TRY IT. There would be a good chance you will encounter problems. Instead finish what you are working on, commit your changes and then update your master branch.&lt;br /&gt;
&lt;br /&gt;
Next we will update the github repositories by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github refs/remotes/origin/master:master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This tells git to push the master branch from origin (the offical Moodle repository) to the master branch on our github account.&lt;br /&gt;
&lt;br /&gt;
Now that you&#039;ve updated the master repository and your github account its time to update the MOODLE_20_STABLE and MOODLE_19_STABLE branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_20_STABLE:MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_19_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_19_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_19_STABLE:MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Working on a Moodle issue==&lt;br /&gt;
&lt;br /&gt;
This part of the document looks at how I go about working on an MDL issue from the Moodle tracker.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ we use the scrum methodology we sees us choose several issues to include in a scrum which we then work on for the period of the scrum. As a community member its more likely you will just be choosing issues that you are passionate about.&lt;br /&gt;
&lt;br /&gt;
Either way once you have found an issue to work on you are ready to start.&lt;br /&gt;
&lt;br /&gt;
For the purpose of this part of the document lets say I am going to work on bug MDL-12345.&lt;br /&gt;
&lt;br /&gt;
==Fixing a bug on the master repository - MDL-12345==&lt;br /&gt;
&lt;br /&gt;
The first step is to create a local branch to make changes on, to do this we will start our work on the master repository.&lt;br /&gt;
&lt;br /&gt;
When fixing an issue I find it easiest to fix the issue on the master branch first and then move my changes to the other branches.&lt;br /&gt;
&lt;br /&gt;
The VERY first thing you should do when you start working on a Moodle issue is make sure you have assigned it to yourself and then click the start progress button.&lt;br /&gt;
&lt;br /&gt;
This way other users know that you are activly working on the bug and no one from HQ will steal it from you.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local branch===&lt;br /&gt;
&lt;br /&gt;
So first get to the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there we create a new branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-master origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command checks out a new branch called wip-MDL-12345-master that is based upon origin/master.&lt;br /&gt;
&lt;br /&gt;
origin/master is of course the master branch on the official Moodle repository (git.moodle.org/moodle.git).&lt;br /&gt;
&lt;br /&gt;
The name of the branch is also very important. It is essentially telling us three things.&lt;br /&gt;
&lt;br /&gt;
; wip : This stands for work in progress, it helps people see that you are currently working on this branch and that they shouldn&#039;t base there work on it because it will likely change.&lt;br /&gt;
; MDL-12345 : This is of course the Moodle bug number. It helps people quickly identify what you are working on.&lt;br /&gt;
; master : This is the branch we are making changes on. It helps people quickly understand where the changes are being made.&lt;br /&gt;
&lt;br /&gt;
You can optionally add more to the end of the branch name such as a key word that identifies the area or a date at which you started work e.g.&lt;br /&gt;
&lt;br /&gt;
* wip-MDL-12345-master-navigation-changes&lt;br /&gt;
* wip-MDL-12345-master-20110418&lt;br /&gt;
&lt;br /&gt;
That is up to you, personally I&#039;m not a fan of it, however the rest is all required to help integrate your work.&lt;br /&gt;
&lt;br /&gt;
Either way now you have a branch, mine is called wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Make changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have created you branch you are ready to make changes.&lt;br /&gt;
&lt;br /&gt;
I&#039;ll let you make whatever changes you are need, once you have made changes move onto the next step.&lt;br /&gt;
&lt;br /&gt;
Before you do move on however make sure that your code meets the high quality of code Moodle requires.&lt;br /&gt;
&lt;br /&gt;
You can find information about that on the moodle docs here: https://docs.moodle.org/en/Development:Coding_style&lt;br /&gt;
&lt;br /&gt;
The following are common mistakes:&lt;br /&gt;
&lt;br /&gt;
* Incorrect white space&lt;br /&gt;
** Tabs instead of spaces&lt;br /&gt;
** Extra spaces at the end of lines&lt;br /&gt;
** Multiple new lines&lt;br /&gt;
** Forgetting to put spaces between function arguments&lt;br /&gt;
* Incorrect commit messages (read on to find out about writing a good commit message)&lt;br /&gt;
* Incorrect variable or function names&lt;br /&gt;
&lt;br /&gt;
Making these sort of mistakes can lead to your code being rejected despite it working correctly.&lt;br /&gt;
&lt;br /&gt;
Or course it will be reviewed in regards to security, usability and the other important factors of code development.&lt;br /&gt;
&lt;br /&gt;
===Step 3: Commit your changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have made your changes you are getting ready to commit them.&lt;br /&gt;
&lt;br /&gt;
The first thing to do is check your changes. To do this run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see all of the files you have changes highlighted in red.&lt;br /&gt;
&lt;br /&gt;
Next you need to stage all of the files you want to commit.&lt;br /&gt;
&lt;br /&gt;
To do this you add the files to the stage using the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git add lib/modifiedfile.php&lt;br /&gt;
git add lib/newfile.php&lt;br /&gt;
git add theme/base/style/core.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Why not just commit all changes. Many of the git guides you read will tell you above git commit -a which commits all of the changes you have made.&lt;br /&gt;
&lt;br /&gt;
We&#039;ve hardly being using git here at Moodle and already I&#039;ve seen several people accidentally commit changes that they didn&#039;t mean to.&lt;br /&gt;
&lt;br /&gt;
Staging files like this ENSURES you only commit things you intend to.&lt;br /&gt;
&lt;br /&gt;
Now that you have staged your changes/new files you are ready to commit. The following command commits your changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git commit -m &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command commits your changes with the commit message &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;.&lt;br /&gt;
It&#039;s very important to Moodle that you format your commit messages like this.&lt;br /&gt;
They consist of three parts:&lt;br /&gt;
&lt;br /&gt;
# The MDL bug number in this case MDL-12345&lt;br /&gt;
# The area you made changes to in this case enrol&lt;br /&gt;
# A short description of what you did, in this case I fixed a couple of enrolment bugs.&lt;br /&gt;
&lt;br /&gt;
When you commit your message you will see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[master 19a484e] changes&lt;br /&gt;
 1 files changed, 16 insertions(+), 18 deletions(-)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
There is one thing here you need to note down for later, that is the number that appears within the square brackets after the branch name, in my case it is 19a484e. This is the commit id of the commit I just made.&lt;br /&gt;
&lt;br /&gt;
===Step 4: Pushing your changes to your github account===&lt;br /&gt;
&lt;br /&gt;
Now that you have made changes to your local branch you should push it to your github account so that it can be reviewed and hopefully integrated into Moodle.&lt;br /&gt;
&lt;br /&gt;
Doing this is very simple just run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are telling git to push the branch wip-MDL-12345-master to the remote called github which we added when setting up our git repositories.&lt;br /&gt;
And just like that you&#039;ve made a branch that contains your work and pushed it to github ready to get it reviewed.&lt;br /&gt;
&lt;br /&gt;
==Moving your changes to another branch==&lt;br /&gt;
Now that you have made changes to the master branch you need to decide whether it is appropriate make those changes on any of the other branches.&lt;br /&gt;
Most likely if you are fixing a bug you will need to make the changes on the MOODLE_20_STABLE branch as well, and perhaps the MOODLE_19_STABLE branch if it is a security bug.&lt;br /&gt;
&lt;br /&gt;
Lets assume for MDL-12345 that I fixed earlier that it should be ported to MOODLE_20_STABLE as well.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local MOODLE_20_STABLE branch===&lt;br /&gt;
&lt;br /&gt;
To start with I need to move to the MOODLE_20_STABLE repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there I need to create a new branch based upon the MOODLE_20_STABLE branch that is going to contain my changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very similar to the branch we created for the changes to the master branch except that I have subsituted MOODLE_20_STABLE in place of master. This is because the new branch we are creating is based upon the MOODLE_20_STABLE branch on the offical Moodle git repository and contains changes for that branch.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Cherry-picking my changes===&lt;br /&gt;
Once we have a branch for our changes I am ready to make them again. There is however with git an easy way to do this, cherry-picking.&lt;br /&gt;
&lt;br /&gt;
Cherry-picking is the process of copying a single commit from one branch to another. In this case I want to cherry pick the commit I made earlier onto the branch I&#039;ve just created.&lt;br /&gt;
&lt;br /&gt;
However before I can do this I need to fetch the changes I made from the github repository. I need to do this because I made that changes of a totally separate local repository remember.&lt;br /&gt;
&lt;br /&gt;
So to update my repository with the latest changes I run the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command tells git to look at each remote and get any new changes (it also removes any branches that have been deleted).&lt;br /&gt;
Once it has completed you will be ready to cherry pick the commit. To do so you use the following command but replace my commit is with yours.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git cherry-pick 19a484e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Providing there are no conflicts your branch will now contain a copy of the changes you made to the master branch.&lt;br /&gt;
If there are conficts that you will need to resolve them and commit your changes however you can search for another tutorial about how to do that,&lt;br /&gt;
&lt;br /&gt;
Now I know at this point that there will be some of you who are saying &#039;Whoops I forgot what my commit id was!&#039;. If this is you don&#039;t worry, its pretty easy to find it providing you used a proper commit message like I described above.&lt;br /&gt;
Simply run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git log --oneline origin/master..github/wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the commits that are in the wip-MDL-12345-master at your github account but are not in the master branch at the offical Moodle repository.&lt;br /&gt;
You can then cherry-pick the commits shown there (the commit ID&#039;s should be highlighted in yellow).&lt;br /&gt;
&lt;br /&gt;
Once you have cherry-picked your commits its time to check that everything worked, run the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# On branch wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
# Your branch is ahead of &#039;origin/MOODLE_20_STABLE&#039; by 1 commit.&lt;br /&gt;
#&lt;br /&gt;
nothing to commit (working directory clean)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very handy as it tells you that your branch is ahead of the offical MOODLE_20_STABLE branch by one commit.&lt;br /&gt;
You can also check that your commit contains the changes you think by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git diff origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the changes you have made as a diff.&lt;br /&gt;
&lt;br /&gt;
Now that you know that your commit is there you and that it is correct it is time to push it to your github account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And thats it.&lt;br /&gt;
&lt;br /&gt;
You github account should now have two branches on it:&lt;br /&gt;
&lt;br /&gt;
; wip-MDL-12345-master : This branch is the changes you have made for the master branch&lt;br /&gt;
; wip-MDL-12345-MOODLE_20_STABLE : This branch is those same changes but for the MOODLE_20_STABLE branch&lt;br /&gt;
&lt;br /&gt;
Now you are ready to create PULL requests so that your work gets reviewed and hopefully integrated.&lt;br /&gt;
&lt;br /&gt;
==Creating a PULL request for the master branch==&lt;br /&gt;
&lt;br /&gt;
So you have successfully fixed the bug MDL-12345, you have created two branches one for master and one for MOODLE_20_STABLE. It is time to create a PULL request for each of these branches.&lt;br /&gt;
&lt;br /&gt;
First lets create a PULL request for the master branch:&lt;br /&gt;
&lt;br /&gt;
# Browse to tracker.moodle.org/browse/MDL-12345&lt;br /&gt;
# When the page loads log in if you haven&#039;t already.&lt;br /&gt;
# Click on the button in the top right labelled `Create issue`&lt;br /&gt;
# Change Project to `Pull Requests`&lt;br /&gt;
# Change Issue type to `Pull Request`&lt;br /&gt;
# Click create&lt;br /&gt;
&lt;br /&gt;
This takes you to a screen where you can enter the details for the PULL request.&lt;br /&gt;
&lt;br /&gt;
You should fill it out in the following way:&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
This is the summary for the PULL request, you should copy and paste the summary from the MDL issue here.&lt;br /&gt;
For MDL-12345 the summary is `alphabetization of UI different on left and right sides` so that&#039;s what I will use.&lt;br /&gt;
&lt;br /&gt;
===Affects Versions===&lt;br /&gt;
This is the version that your branch is changing, in the case of this PULL request I will select `master`.&lt;br /&gt;
&lt;br /&gt;
===Security level===&lt;br /&gt;
If the issue you are working on is a security issue you should set this to the same level that the issue is set to. If its not a security issue or you don&#039;t know just leave it as none.&lt;br /&gt;
&lt;br /&gt;
===Pull from repository===&lt;br /&gt;
This is the repository that the branch is at, for you this will be your github accont. If you head to http://github.com/yourname/moodle you will see a box that has three options SSH, HTTP, and Git read only, click Git Read Only and then copy the contents of the text box into the repositry field of the PULL request. &lt;br /&gt;
For me that is git://github.com/yourname/moodle.git&lt;br /&gt;
&lt;br /&gt;
===Pull branch===&lt;br /&gt;
This is the name of the branch that contains your changes. For me that is wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Pull Diff URL===&lt;br /&gt;
This is the URL to a page that shows the changes that you&#039;ve made on your branch. Github is nice in that it has a pretty interface for that. To get to the interface follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Browse to https://github.com/youraccount/moodle&lt;br /&gt;
# Click `Switch Branches` and then click on the branch you changes are based upon, in my case master.&lt;br /&gt;
# Click the button labelled `Branch List`&lt;br /&gt;
# Locate your branch in the list and click the `Compare button` for me this was the compare button to the right of wip-MDL-12345-master.&lt;br /&gt;
# Copy the URL in your browse and paste it into the Pull Diff URL of the PULL request.&lt;br /&gt;
&lt;br /&gt;
For me this URL was: https://github.com/yourname/moodle/compare/master...wip-MDL-23532-master&lt;br /&gt;
For the MOODLE_20_STABLE branch this would be: https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
&lt;br /&gt;
===Description===&lt;br /&gt;
The description should contain several bits of important information:&lt;br /&gt;
&lt;br /&gt;
# A short description of what your patch does&lt;br /&gt;
# Notes about that changes you&#039;ve made that might help the integrator understand what you did when he/she is reviewing it.&lt;br /&gt;
# Testing instructions that guide the testers through testing your changes.&lt;br /&gt;
&lt;br /&gt;
===Components===&lt;br /&gt;
Select general from the components list, general is the only option.&lt;br /&gt;
&lt;br /&gt;
===Finishing up===&lt;br /&gt;
Once you have filled in the fields as above click `Create`. This should create you PULL request and then take you to view it.&lt;br /&gt;
&lt;br /&gt;
Its important to remember that there is still one thing you need to do and that is link to the original issue.&lt;br /&gt;
While you are still logged in click the `More Actions` button and select `Link issue`, in the dialoug that pops up change the `This issue` field to `will help resolve`, type MDL-12345 into the issues field, and then type `Linking to MDL-12345` into the comments box. Once you&#039;ve done that simple click Link.&amp;lt;br /&amp;gt;I should add that the comment isn&#039;t really required. It&#039;s just something I personally like doing.&lt;br /&gt;
&lt;br /&gt;
Time to create the PULL request for the other branches.&lt;br /&gt;
&lt;br /&gt;
==Creating the PULL request for MOODLE_20_STABLE==&lt;br /&gt;
Once you&#039;ve created the PULL request for the master branch it is time to create the PULL request for the MOODLE_20_STABLE branch.&lt;br /&gt;
This is as easy as can be, click Create Issue in the top right, select PULL project and choose Pull Request and then click create.&lt;br /&gt;
On the next screen enter the following details:&lt;br /&gt;
&lt;br /&gt;
; Summary : Copy the summary from the previous PULL Request&lt;br /&gt;
; Affects Versions : Select MOODLE_20_STABLE&lt;br /&gt;
; Security level : Same as the MDL&lt;br /&gt;
; Pull from repository : Copy from the previous PULL request&lt;br /&gt;
; Pull Branch : wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
; Pull Diff URL : https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
; Description : Copy from the previous PULL request&lt;br /&gt;
; Component : general&lt;br /&gt;
&lt;br /&gt;
Then click create to create the PULL request.&lt;br /&gt;
&lt;br /&gt;
Once the PULL request has been create don&#039;t forget to link to the MDL issue like we did for the previous PULL request.&lt;br /&gt;
&lt;br /&gt;
==Rebasing after the weekly release==&lt;br /&gt;
As many of you will be aware on Wednesday after the latest weekly has been released a comment will be added to all PULL requests that are still open.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The main moodle.git repository has just been updated with latest weekly modifications.&lt;br /&gt;
You may wish to rebase your PULL branches to simplify history and avoid any possible merge conflicts. This would also make integrator&#039;s life easier next week.&lt;br /&gt;
&lt;br /&gt;
TIA and ciao :)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is a message that is bulk added as is done so as a polite request. While it&#039;s not essential for you to rebase your work it really does help the integrators as its much easier to see what is going on and greatly reduces the chance of conflicts (because you&#039;ll solve them when you rebase).&lt;br /&gt;
&lt;br /&gt;
The good news is that rebasing your work is EASY!&lt;br /&gt;
&lt;br /&gt;
For the following example lets assume I created the two PULL requests above on Wednesday morning and the weekly was released on Wednesday afternoon. This means that my branch doesn&#039;t have the changes that have just been released and I need to rebase them.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Rebasing the wip-MDL-12345-master===&lt;br /&gt;
&lt;br /&gt;
The first step is to rebase my work that is based upon the master branch. So first move to the master repository.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next thing we have to do is get all of the changes from the remote repositories, this will fetch down all of the latest changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now before the next step make sure that you don&#039;t have any uncommit changes, if you do finish that work, commit it, then proceed to the next step which is updating your local master.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
git push master github&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that your local master is up to date, and has you&#039;ve updated you master branch at github you are ready to rebase!&lt;br /&gt;
At this point we want to checkout the branch we are going to rebase, in this case wip-MDL-12345-master and then we are going to rebase origin/master which is the official Moodle master branch (and the branch our branch is based upon).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout wip-MDL-12345-master&lt;br /&gt;
git rebase origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that command has completed your branch wip-MDL-12345-master will be completely up to date. Before you are done however you need to push the rebased wip-MDL-12345-master up to your github account so that its the branch the integrator sees.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push -f github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that command is just about identical to the command we used when we first pushed our branch to our github account, there is however one VERY important difference, the &#039;&#039;&#039;-f&#039;&#039;&#039; option.&lt;br /&gt;
The &#039;&#039;&#039;-f&#039;&#039;&#039; option tells git to force the push, this is required because when you rebase all of your commit id&#039;s will change and unless you tell git to force it will see that they have changed and not allow you to push your work.&lt;br /&gt;
&lt;br /&gt;
Thats it! you&#039;ve now rebased your work and the integrators will be happy again :)&lt;br /&gt;
&lt;br /&gt;
===Step 2: Rebasing wip-MDL-12345-MOODLE_20_STABLE===&lt;br /&gt;
Now that we&#039;ve rebased our work that was based upon the master branch it is time to rebase the MOODLE_20_STABLE version.&lt;br /&gt;
This step is just about identical to the previous step except we substitute &#039;&#039;master&#039;&#039; for &#039;&#039;MOODLE_20_STABLE&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github MOODLE_20_STABLE&lt;br /&gt;
git checkout wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
git rebase origin/MOODLE_20_STABLE&lt;br /&gt;
git push -f github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&lt;br /&gt;
==Useful links==&lt;br /&gt;
The following are links I found useful while learning Git.&lt;br /&gt;
&lt;br /&gt;
* [http://help.github.com Github help (http://help.github.com)] Provides EXCELLENT help tutorials that very clearly explain the basic through to the advanced.&lt;br /&gt;
* [http://cheat.errtheblog.com/s/git/ $ cheat git] This is my favourite cheat sheet, straight forward to the point, if you know the concept you&#039;ll find the answer here.&lt;br /&gt;
* [http://gitster.livejournal.com/28309.html Gitsters journal - Fun with FETCH_HEAD] David Mudrak pointed me at this entry which I found INCREDIBLY useful when reviewing other peoples work.&lt;br /&gt;
&lt;br /&gt;
I you&#039;re looking to read/buy a book on Git I&#039;d strongly recommend [http://progit.org/ Pro Git]. I certainly found that the most useful book I read.&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82871</id>
		<title>User:Sam Hemelryk/My Moodle Git workflow</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82871"/>
		<updated>2011-04-19T01:44:44Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* Rebasing after the weekly release */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document is a sort of tutorial/inspection of my personal development workflow when working on Moodle with Git.&lt;br /&gt;
&lt;br /&gt;
==Creating the repositories==&lt;br /&gt;
Ok so the very first step is to create several Moodle git repositories, one for each major branch of Moodle being worked on.&lt;br /&gt;
&lt;br /&gt;
At the time of writing the major branches are MOODLE_19_STABLE, MOODLE_20_STABLE and master.&lt;br /&gt;
&lt;br /&gt;
The reason for this is that that way we have a separate site for each Moodle branch that we can test on easily. Yes you will have three sites but you won&#039;t have to worry about swtiching your site when you change branches.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Create a directory to create the repositories within===&lt;br /&gt;
&lt;br /&gt;
Personally I use Ubuntu (Linux) and I chose to create my repositories within a folder I created in /var/www. If you are using windows I would instead suggest creating C:/www/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www&lt;br /&gt;
mkdir repositories&lt;br /&gt;
cd repositories&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 2: Create a master repository===&lt;br /&gt;
This is the easiest of the branches to create a repository for.&lt;br /&gt;
&lt;br /&gt;
Within your repositories directory create a new directory called master and move into it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir master&lt;br /&gt;
cd master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we want to clone the Moodle source from the offical Moodle git repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new directory called moodle within the master directory we created just before.&lt;br /&gt;
&lt;br /&gt;
That new moodle directory should contain the Moodle source code as a git repository.&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our main git repository we need to add our github account as a remote so that we can push to it later:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd moodle&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This adds your moodle repository on github as a remote called github that you can push to later.&lt;br /&gt;
&lt;br /&gt;
Finally before we move onto the next repository we need to create a data directory because we know we will need that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 3: Create a MOODLE_20_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
The next repository we create will be for the MOODLE_20_STABLE branch.&lt;br /&gt;
To start with get back to the repositories directory that we created earlier and create a directory called MOODLE_20_STABLE within that.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_20_STABLE&lt;br /&gt;
cd MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now create a new clone of the main Moodle repository like we did for the master branch above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have done that move into the moodle directory.&lt;br /&gt;
&lt;br /&gt;
By default the master branch is the branch that is created, however we don&#039;t want that for this repository. Instead we want the MOODLE_20_STABLE branch.&lt;br /&gt;
&lt;br /&gt;
To do this we checkout local branch based upon the official MOODLE_20_STABLE branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have created that branch we can delete the local master branch so that we don&#039;t accidentally ever work on it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git branch -D master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then like we did for master we add our github repository as a remote:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And finally create a data directory we can use when we have install the site:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 4: Create a MOODLE_19_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
This step is identical to the above step except we are using the MOODLE_19_STABLE branch instead of the MOODLE_20_STABLE branch.&lt;br /&gt;
The commands for this are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_19_STABLE&lt;br /&gt;
cd MOODLE_19_STABLE&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
git checkout -b MOODLE_19_STABLE origin/MOODLE_19_STABLE&lt;br /&gt;
git branch -D master&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 5: Install the sites===&lt;br /&gt;
Now I can&#039;t tell you how to do this on your own machine however what I would recommend is that you create a link from your web root to the moodle directory of each branch.&lt;br /&gt;
&lt;br /&gt;
If you are using linux and your webroot is /var/www/localhost you would do it as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/localhost/&lt;br /&gt;
ln -s /var/www/repositories/master/moodle master&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_20_STABLE/moodle MOODLE_20_STABLE&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_19_STABLE/moodle MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done you should be able to browse to each repository with the following URL&#039;s&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://localhost/master/&lt;br /&gt;
http://localhost/MOODLE_20_STABLE/&lt;br /&gt;
http://localhost/MOODLE_19_STABLE/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that is done you need to browse to each site and complete the installation.&lt;br /&gt;
&lt;br /&gt;
Under this method your will need to ensure you set the configuration option sessioncookiepath to the URI of your site. You can either do this in the admin interfaces or add the following to your config.php file for each site.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// For the master site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/master/&#039;;&lt;br /&gt;
// For the MOODLE_20_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_20_STABLE/&#039;;&lt;br /&gt;
// For the MOODLE_19_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_19_STABLE/&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Failure to do this will mean that when you log in at one site and then visit the next you will have to log in again and your session on the first site will no longer work.&lt;br /&gt;
&lt;br /&gt;
Now that you have got 3 repositories, one for each main branch, and set up a site for each you are ready to start development.&lt;br /&gt;
&lt;br /&gt;
==Before you start work each day==&lt;br /&gt;
Before you start work each day you should update each of the repositories you have created to ensure that you are always working with up to date versions of Moodle.&lt;br /&gt;
&lt;br /&gt;
You should also take this opportunity to update the repositories on your github account to ensure they are always up to date.&lt;br /&gt;
&lt;br /&gt;
To start with lets update the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This moves to the master repository and then tells git for fetch all of the changes from your remote repositories and clean up any old branches it is aware of.&lt;br /&gt;
&lt;br /&gt;
Once that operation has completed you should update your master branch&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Before you do that it pays to make sure you don&#039;t have any uncommit changes, if you do DON&#039;T TRY IT. There would be a good chance you will encounter problems. Instead finish what you are working on, commit your changes and then update your master branch.&lt;br /&gt;
&lt;br /&gt;
Next we will update the github repositories by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github refs/remotes/origin/master:master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This tells git to push the master branch from origin (the offical Moodle repository) to the master branch on our github account.&lt;br /&gt;
&lt;br /&gt;
Now that you&#039;ve updated the master repository and your github account its time to update the MOODLE_20_STABLE and MOODLE_19_STABLE branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_20_STABLE:MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_19_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_19_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_19_STABLE:MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Working on a Moodle issue==&lt;br /&gt;
&lt;br /&gt;
This part of the document looks at how I go about working on an MDL issue from the Moodle tracker.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ we use the scrum methodology we sees us choose several issues to include in a scrum which we then work on for the period of the scrum. As a community member its more likely you will just be choosing issues that you are passionate about.&lt;br /&gt;
&lt;br /&gt;
Either way once you have found an issue to work on you are ready to start.&lt;br /&gt;
&lt;br /&gt;
For the purpose of this part of the document lets say I am going to work on bug MDL-12345.&lt;br /&gt;
&lt;br /&gt;
==Fixing a bug on the master repository - MDL-12345==&lt;br /&gt;
&lt;br /&gt;
The first step is to create a local branch to make changes on, to do this we will start our work on the master repository.&lt;br /&gt;
&lt;br /&gt;
When fixing an issue I find it easiest to fix the issue on the master branch first and then move my changes to the other branches.&lt;br /&gt;
&lt;br /&gt;
The VERY first thing you should do when you start working on a Moodle issue is make sure you have assigned it to yourself and then click the start progress button.&lt;br /&gt;
&lt;br /&gt;
This way other users know that you are activly working on the bug and no one from HQ will steal it from you.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local branch===&lt;br /&gt;
&lt;br /&gt;
So first get to the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there we create a new branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-master origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command checks out a new branch called wip-MDL-12345-master that is based upon origin/master.&lt;br /&gt;
&lt;br /&gt;
origin/master is of course the master branch on the official Moodle repository (git.moodle.org/moodle.git).&lt;br /&gt;
&lt;br /&gt;
The name of the branch is also very important. It is essentially telling us three things.&lt;br /&gt;
&lt;br /&gt;
; wip : This stands for work in progress, it helps people see that you are currently working on this branch and that they shouldn&#039;t base there work on it because it will likely change.&lt;br /&gt;
; MDL-12345 : This is of course the Moodle bug number. It helps people quickly identify what you are working on.&lt;br /&gt;
; master : This is the branch we are making changes on. It helps people quickly understand where the changes are being made.&lt;br /&gt;
&lt;br /&gt;
You can optionally add more to the end of the branch name such as a key word that identifies the area or a date at which you started work e.g.&lt;br /&gt;
&lt;br /&gt;
* wip-MDL-12345-master-navigation-changes&lt;br /&gt;
* wip-MDL-12345-master-20110418&lt;br /&gt;
&lt;br /&gt;
That is up to you, personally I&#039;m not a fan of it, however the rest is all required to help integrate your work.&lt;br /&gt;
&lt;br /&gt;
Either way now you have a branch, mine is called wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Make changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have created you branch you are ready to make changes.&lt;br /&gt;
&lt;br /&gt;
I&#039;ll let you make whatever changes you are need, once you have made changes move onto the next step.&lt;br /&gt;
&lt;br /&gt;
Before you do move on however make sure that your code meets the high quality of code Moodle requires.&lt;br /&gt;
&lt;br /&gt;
You can find information about that on the moodle docs here: https://docs.moodle.org/en/Development:Coding_style&lt;br /&gt;
&lt;br /&gt;
The following are common mistakes:&lt;br /&gt;
&lt;br /&gt;
* Incorrect white space&lt;br /&gt;
** Tabs instead of spaces&lt;br /&gt;
** Extra spaces at the end of lines&lt;br /&gt;
** Multiple new lines&lt;br /&gt;
** Forgetting to put spaces between function arguments&lt;br /&gt;
* Incorrect commit messages (read on to find out about writing a good commit message)&lt;br /&gt;
* Incorrect variable or function names&lt;br /&gt;
&lt;br /&gt;
Making these sort of mistakes can lead to your code being rejected despite it working correctly.&lt;br /&gt;
&lt;br /&gt;
Or course it will be reviewed in regards to security, usability and the other important factors of code development.&lt;br /&gt;
&lt;br /&gt;
===Step 3: Commit your changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have made your changes you are getting ready to commit them.&lt;br /&gt;
&lt;br /&gt;
The first thing to do is check your changes. To do this run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see all of the files you have changes highlighted in red.&lt;br /&gt;
&lt;br /&gt;
Next you need to stage all of the files you want to commit.&lt;br /&gt;
&lt;br /&gt;
To do this you add the files to the stage using the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git add lib/modifiedfile.php&lt;br /&gt;
git add lib/newfile.php&lt;br /&gt;
git add theme/base/style/core.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Why not just commit all changes. Many of the git guides you read will tell you above git commit -a which commits all of the changes you have made.&lt;br /&gt;
&lt;br /&gt;
We&#039;ve hardly being using git here at Moodle and already I&#039;ve seen several people accidentally commit changes that they didn&#039;t mean to.&lt;br /&gt;
&lt;br /&gt;
Staging files like this ENSURES you only commit things you intend to.&lt;br /&gt;
&lt;br /&gt;
Now that you have staged your changes/new files you are ready to commit. The following command commits your changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git commit -m &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command commits your changes with the commit message &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;.&lt;br /&gt;
It&#039;s very important to Moodle that you format your commit messages like this.&lt;br /&gt;
They consist of three parts:&lt;br /&gt;
&lt;br /&gt;
# The MDL bug number in this case MDL-12345&lt;br /&gt;
# The area you made changes to in this case enrol&lt;br /&gt;
# A short description of what you did, in this case I fixed a couple of enrolment bugs.&lt;br /&gt;
&lt;br /&gt;
When you commit your message you will see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[master 19a484e] changes&lt;br /&gt;
 1 files changed, 16 insertions(+), 18 deletions(-)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
There is one thing here you need to note down for later, that is the number that appears within the square brackets after the branch name, in my case it is 19a484e. This is the commit id of the commit I just made.&lt;br /&gt;
&lt;br /&gt;
===Step 4: Pushing your changes to your github account===&lt;br /&gt;
&lt;br /&gt;
Now that you have made changes to your local branch you should push it to your github account so that it can be reviewed and hopefully integrated into Moodle.&lt;br /&gt;
&lt;br /&gt;
Doing this is very simple just run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are telling git to push the branch wip-MDL-12345-master to the remote called github which we added when setting up our git repositories.&lt;br /&gt;
And just like that you&#039;ve made a branch that contains your work and pushed it to github ready to get it reviewed.&lt;br /&gt;
&lt;br /&gt;
==Moving your changes to another branch==&lt;br /&gt;
Now that you have made changes to the master branch you need to decide whether it is appropriate make those changes on any of the other branches.&lt;br /&gt;
Most likely if you are fixing a bug you will need to make the changes on the MOODLE_20_STABLE branch as well, and perhaps the MOODLE_19_STABLE branch if it is a security bug.&lt;br /&gt;
&lt;br /&gt;
Lets assume for MDL-12345 that I fixed earlier that it should be ported to MOODLE_20_STABLE as well.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local MOODLE_20_STABLE branch===&lt;br /&gt;
&lt;br /&gt;
To start with I need to move to the MOODLE_20_STABLE repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there I need to create a new branch based upon the MOODLE_20_STABLE branch that is going to contain my changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very similar to the branch we created for the changes to the master branch except that I have subsituted MOODLE_20_STABLE in place of master. This is because the new branch we are creating is based upon the MOODLE_20_STABLE branch on the offical Moodle git repository and contains changes for that branch.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Cherry-picking my changes===&lt;br /&gt;
Once we have a branch for our changes I am ready to make them again. There is however with git an easy way to do this, cherry-picking.&lt;br /&gt;
&lt;br /&gt;
Cherry-picking is the process of copying a single commit from one branch to another. In this case I want to cherry pick the commit I made earlier onto the branch I&#039;ve just created.&lt;br /&gt;
&lt;br /&gt;
However before I can do this I need to fetch the changes I made from the github repository. I need to do this because I made that changes of a totally separate local repository remember.&lt;br /&gt;
&lt;br /&gt;
So to update my repository with the latest changes I run the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command tells git to look at each remote and get any new changes (it also removes any branches that have been deleted).&lt;br /&gt;
Once it has completed you will be ready to cherry pick the commit. To do so you use the following command but replace my commit is with yours.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git cherry-pick 19a484e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Providing there are no conflicts your branch will now contain a copy of the changes you made to the master branch.&lt;br /&gt;
If there are conficts that you will need to resolve them and commit your changes however you can search for another tutorial about how to do that,&lt;br /&gt;
&lt;br /&gt;
Now I know at this point that there will be some of you who are saying &#039;Whoops I forgot what my commit id was!&#039;. If this is you don&#039;t worry, its pretty easy to find it providing you used a proper commit message like I described above.&lt;br /&gt;
Simply run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git log --oneline origin/master..github/wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the commits that are in the wip-MDL-12345-master at your github account but are not in the master branch at the offical Moodle repository.&lt;br /&gt;
You can then cherry-pick the commits shown there (the commit ID&#039;s should be highlighted in yellow).&lt;br /&gt;
&lt;br /&gt;
Once you have cherry-picked your commits its time to check that everything worked, run the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# On branch wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
# Your branch is ahead of &#039;origin/MOODLE_20_STABLE&#039; by 1 commit.&lt;br /&gt;
#&lt;br /&gt;
nothing to commit (working directory clean)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very handy as it tells you that your branch is ahead of the offical MOODLE_20_STABLE branch by one commit.&lt;br /&gt;
You can also check that your commit contains the changes you think by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git diff origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the changes you have made as a diff.&lt;br /&gt;
&lt;br /&gt;
Now that you know that your commit is there you and that it is correct it is time to push it to your github account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And thats it.&lt;br /&gt;
&lt;br /&gt;
You github account should now have two branches on it:&lt;br /&gt;
&lt;br /&gt;
; wip-MDL-12345-master : This branch is the changes you have made for the master branch&lt;br /&gt;
; wip-MDL-12345-MOODLE_20_STABLE : This branch is those same changes but for the MOODLE_20_STABLE branch&lt;br /&gt;
&lt;br /&gt;
Now you are ready to create PULL requests so that your work gets reviewed and hopefully integrated.&lt;br /&gt;
&lt;br /&gt;
==Creating a PULL request for the master branch==&lt;br /&gt;
&lt;br /&gt;
So you have successfully fixed the bug MDL-12345, you have created two branches one for master and one for MOODLE_20_STABLE. It is time to create a PULL request for each of these branches.&lt;br /&gt;
&lt;br /&gt;
First lets create a PULL request for the master branch:&lt;br /&gt;
&lt;br /&gt;
# Browse to tracker.moodle.org/browse/MDL-12345&lt;br /&gt;
# When the page loads log in if you haven&#039;t already.&lt;br /&gt;
# Click on the button in the top right labelled `Create issue`&lt;br /&gt;
# Change Project to `Pull Requests`&lt;br /&gt;
# Change Issue type to `Pull Request`&lt;br /&gt;
# Click create&lt;br /&gt;
&lt;br /&gt;
This takes you to a screen where you can enter the details for the PULL request.&lt;br /&gt;
&lt;br /&gt;
You should fill it out in the following way:&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
This is the summary for the PULL request, you should copy and paste the summary from the MDL issue here.&lt;br /&gt;
For MDL-12345 the summary is `alphabetization of UI different on left and right sides` so that&#039;s what I will use.&lt;br /&gt;
&lt;br /&gt;
===Affects Versions===&lt;br /&gt;
This is the version that your branch is changing, in the case of this PULL request I will select `master`.&lt;br /&gt;
&lt;br /&gt;
===Security level===&lt;br /&gt;
If the issue you are working on is a security issue you should set this to the same level that the issue is set to. If its not a security issue or you don&#039;t know just leave it as none.&lt;br /&gt;
&lt;br /&gt;
===Pull from repository===&lt;br /&gt;
This is the repository that the branch is at, for you this will be your github accont. If you head to http://github.com/yourname/moodle you will see a box that has three options SSH, HTTP, and Git read only, click Git Read Only and then copy the contents of the text box into the repositry field of the PULL request. &lt;br /&gt;
For me that is git://github.com/yourname/moodle.git&lt;br /&gt;
&lt;br /&gt;
===Pull branch===&lt;br /&gt;
This is the name of the branch that contains your changes. For me that is wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Pull Diff URL===&lt;br /&gt;
This is the URL to a page that shows the changes that you&#039;ve made on your branch. Github is nice in that it has a pretty interface for that. To get to the interface follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Browse to https://github.com/youraccount/moodle&lt;br /&gt;
# Click `Switch Branches` and then click on the branch you changes are based upon, in my case master.&lt;br /&gt;
# Click the button labelled `Branch List`&lt;br /&gt;
# Locate your branch in the list and click the `Compare button` for me this was the compare button to the right of wip-MDL-12345-master.&lt;br /&gt;
# Copy the URL in your browse and paste it into the Pull Diff URL of the PULL request.&lt;br /&gt;
&lt;br /&gt;
For me this URL was: https://github.com/yourname/moodle/compare/master...wip-MDL-23532-master&lt;br /&gt;
For the MOODLE_20_STABLE branch this would be: https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
&lt;br /&gt;
===Description===&lt;br /&gt;
The description should contain several bits of important information:&lt;br /&gt;
&lt;br /&gt;
# A short description of what your patch does&lt;br /&gt;
# Notes about that changes you&#039;ve made that might help the integrator understand what you did when he/she is reviewing it.&lt;br /&gt;
# Testing instructions that guide the testers through testing your changes.&lt;br /&gt;
&lt;br /&gt;
===Components===&lt;br /&gt;
Select general from the components list, general is the only option.&lt;br /&gt;
&lt;br /&gt;
===Finishing up===&lt;br /&gt;
Once you have filled in the fields as above click `Create`. This should create you PULL request and then take you to view it.&lt;br /&gt;
&lt;br /&gt;
Its important to remember that there is still one thing you need to do and that is link to the original issue.&lt;br /&gt;
While you are still logged in click the `More Actions` button and select `Link issue`, in the dialoug that pops up change the `This issue` field to `will help resolve`, type MDL-12345 into the issues field, and then type `Linking to MDL-12345` into the comments box. Once you&#039;ve done that simple click Link.&amp;lt;br /&amp;gt;I should add that the comment isn&#039;t really required. It&#039;s just something I personally like doing.&lt;br /&gt;
&lt;br /&gt;
Time to create the PULL request for the other branches.&lt;br /&gt;
&lt;br /&gt;
==Creating the PULL request for MOODLE_20_STABLE==&lt;br /&gt;
Once you&#039;ve created the PULL request for the master branch it is time to create the PULL request for the MOODLE_20_STABLE branch.&lt;br /&gt;
This is as easy as can be, click Create Issue in the top right, select PULL project and choose Pull Request and then click create.&lt;br /&gt;
On the next screen enter the following details:&lt;br /&gt;
&lt;br /&gt;
; Summary : Copy the summary from the previous PULL Request&lt;br /&gt;
; Affects Versions : Select MOODLE_20_STABLE&lt;br /&gt;
; Security level : Same as the MDL&lt;br /&gt;
; Pull from repository : Copy from the previous PULL request&lt;br /&gt;
; Pull Branch : wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
; Pull Diff URL : https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
; Description : Copy from the previous PULL request&lt;br /&gt;
; Component : general&lt;br /&gt;
&lt;br /&gt;
Then click create to create the PULL request.&lt;br /&gt;
&lt;br /&gt;
Once the PULL request has been create don&#039;t forget to link to the MDL issue like we did for the previous PULL request.&lt;br /&gt;
&lt;br /&gt;
==Rebasing after the weekly release==&lt;br /&gt;
As many of you will be aware on Wednesday after the latest weekly has been released a comment will be added to all PULL requests that are still open.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The main moodle.git repository has just been updated with latest weekly modifications.&amp;lt;br /&amp;gt;You may wish to rebase your PULL branches to simplify history and avoid any possible merge conflicts. This would also make integrator&#039;s life easier next week.&lt;br /&gt;
&lt;br /&gt;
TIA and ciao :)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is a message that is bulk added as is done so as a polite request. While it&#039;s not essential for you to rebase your work it really does help the integrators as its much easier to see what is going on and greatly reduces the chance of conflicts (because you&#039;ll solve them when you rebase).&lt;br /&gt;
&lt;br /&gt;
The good news is that rebasing your work is EASY!&lt;br /&gt;
&lt;br /&gt;
For the following example lets assume I created the two PULL requests above on Wednesday morning and the weekly was released on Wednesday afternoon. This means that my branch doesn&#039;t have the changes that have just been released and I need to rebase them.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Rebasing the wip-MDL-12345-master===&lt;br /&gt;
&lt;br /&gt;
The first step is to rebase my work that is based upon the master branch. So first move to the master repository.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next thing we have to do is get all of the changes from the remote repositories, this will fetch down all of the latest changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now before the next step make sure that you don&#039;t have any uncommit changes, if you do finish that work, commit it, then proceed to the next step which is updating your local master.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
git push master github&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that your local master is up to date, and has you&#039;ve updated you master branch at github you are ready to rebase!&lt;br /&gt;
At this point we want to checkout the branch we are going to rebase, in this case wip-MDL-12345-master and then we are going to rebase origin/master which is the official Moodle master branch (and the branch our branch is based upon).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout wip-MDL-12345-master&lt;br /&gt;
git rebase origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that command has completed your branch wip-MDL-12345-master will be completely up to date. Before you are done however you need to push the rebased wip-MDL-12345-master up to your github account so that its the branch the integrator sees.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push -f github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that command is just about identical to the command we used when we first pushed our branch to our github account, there is however one VERY important difference, the &#039;&#039;&#039;-f&#039;&#039;&#039; option.&lt;br /&gt;
The &#039;&#039;&#039;-f&#039;&#039;&#039; option tells git to force the push, this is required because when you rebase all of your commit id&#039;s will change and unless you tell git to force it will see that they have changed and not allow you to push your work.&lt;br /&gt;
&lt;br /&gt;
Thats it! you&#039;ve now rebased your work and the integrators will be happy again :)&lt;br /&gt;
&lt;br /&gt;
===Step 2: Rebasing wip-MDL-12345-MOODLE_20_STABLE===&lt;br /&gt;
Now that we&#039;ve rebased our work that was based upon the master branch it is time to rebase the MOODLE_20_STABLE version.&lt;br /&gt;
This step is just about identical to the previous step except we substitute &#039;&#039;master&#039;&#039; for &#039;&#039;MOODLE_20_STABLE&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github MOODLE_20_STABLE&lt;br /&gt;
git checkout wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
git rebase origin/MOODLE_20_STABLE&lt;br /&gt;
git push -f github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&lt;br /&gt;
==Useful links==&lt;br /&gt;
The following are links I found useful while learning Git.&lt;br /&gt;
&lt;br /&gt;
* [http://help.github.com Github help (http://help.github.com)] Provides EXCELLENT help tutorials that very clearly explain the basic through to the advanced.&lt;br /&gt;
* [http://cheat.errtheblog.com/s/git/ $ cheat git] This is my favourite cheat sheet, straight forward to the point, if you know the concept you&#039;ll find the answer here.&lt;br /&gt;
* [http://gitster.livejournal.com/28309.html Gitsters journal - Fun with FETCH_HEAD] David Mudrak pointed me at this entry which I found INCREDIBLY useful when reviewing other peoples work.&lt;br /&gt;
&lt;br /&gt;
I you&#039;re looking to read/buy a book on Git I&#039;d strongly recommend [http://progit.org/ Pro Git]. I certainly found that the most useful book I read.&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82870</id>
		<title>User:Sam Hemelryk/My Moodle Git workflow</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82870"/>
		<updated>2011-04-19T01:44:26Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* Finishing up */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document is a sort of tutorial/inspection of my personal development workflow when working on Moodle with Git.&lt;br /&gt;
&lt;br /&gt;
==Creating the repositories==&lt;br /&gt;
Ok so the very first step is to create several Moodle git repositories, one for each major branch of Moodle being worked on.&lt;br /&gt;
&lt;br /&gt;
At the time of writing the major branches are MOODLE_19_STABLE, MOODLE_20_STABLE and master.&lt;br /&gt;
&lt;br /&gt;
The reason for this is that that way we have a separate site for each Moodle branch that we can test on easily. Yes you will have three sites but you won&#039;t have to worry about swtiching your site when you change branches.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Create a directory to create the repositories within===&lt;br /&gt;
&lt;br /&gt;
Personally I use Ubuntu (Linux) and I chose to create my repositories within a folder I created in /var/www. If you are using windows I would instead suggest creating C:/www/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www&lt;br /&gt;
mkdir repositories&lt;br /&gt;
cd repositories&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 2: Create a master repository===&lt;br /&gt;
This is the easiest of the branches to create a repository for.&lt;br /&gt;
&lt;br /&gt;
Within your repositories directory create a new directory called master and move into it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir master&lt;br /&gt;
cd master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we want to clone the Moodle source from the offical Moodle git repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new directory called moodle within the master directory we created just before.&lt;br /&gt;
&lt;br /&gt;
That new moodle directory should contain the Moodle source code as a git repository.&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our main git repository we need to add our github account as a remote so that we can push to it later:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd moodle&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This adds your moodle repository on github as a remote called github that you can push to later.&lt;br /&gt;
&lt;br /&gt;
Finally before we move onto the next repository we need to create a data directory because we know we will need that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 3: Create a MOODLE_20_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
The next repository we create will be for the MOODLE_20_STABLE branch.&lt;br /&gt;
To start with get back to the repositories directory that we created earlier and create a directory called MOODLE_20_STABLE within that.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_20_STABLE&lt;br /&gt;
cd MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now create a new clone of the main Moodle repository like we did for the master branch above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have done that move into the moodle directory.&lt;br /&gt;
&lt;br /&gt;
By default the master branch is the branch that is created, however we don&#039;t want that for this repository. Instead we want the MOODLE_20_STABLE branch.&lt;br /&gt;
&lt;br /&gt;
To do this we checkout local branch based upon the official MOODLE_20_STABLE branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have created that branch we can delete the local master branch so that we don&#039;t accidentally ever work on it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git branch -D master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then like we did for master we add our github repository as a remote:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And finally create a data directory we can use when we have install the site:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 4: Create a MOODLE_19_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
This step is identical to the above step except we are using the MOODLE_19_STABLE branch instead of the MOODLE_20_STABLE branch.&lt;br /&gt;
The commands for this are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_19_STABLE&lt;br /&gt;
cd MOODLE_19_STABLE&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
git checkout -b MOODLE_19_STABLE origin/MOODLE_19_STABLE&lt;br /&gt;
git branch -D master&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 5: Install the sites===&lt;br /&gt;
Now I can&#039;t tell you how to do this on your own machine however what I would recommend is that you create a link from your web root to the moodle directory of each branch.&lt;br /&gt;
&lt;br /&gt;
If you are using linux and your webroot is /var/www/localhost you would do it as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/localhost/&lt;br /&gt;
ln -s /var/www/repositories/master/moodle master&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_20_STABLE/moodle MOODLE_20_STABLE&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_19_STABLE/moodle MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done you should be able to browse to each repository with the following URL&#039;s&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://localhost/master/&lt;br /&gt;
http://localhost/MOODLE_20_STABLE/&lt;br /&gt;
http://localhost/MOODLE_19_STABLE/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that is done you need to browse to each site and complete the installation.&lt;br /&gt;
&lt;br /&gt;
Under this method your will need to ensure you set the configuration option sessioncookiepath to the URI of your site. You can either do this in the admin interfaces or add the following to your config.php file for each site.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// For the master site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/master/&#039;;&lt;br /&gt;
// For the MOODLE_20_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_20_STABLE/&#039;;&lt;br /&gt;
// For the MOODLE_19_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_19_STABLE/&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Failure to do this will mean that when you log in at one site and then visit the next you will have to log in again and your session on the first site will no longer work.&lt;br /&gt;
&lt;br /&gt;
Now that you have got 3 repositories, one for each main branch, and set up a site for each you are ready to start development.&lt;br /&gt;
&lt;br /&gt;
==Before you start work each day==&lt;br /&gt;
Before you start work each day you should update each of the repositories you have created to ensure that you are always working with up to date versions of Moodle.&lt;br /&gt;
&lt;br /&gt;
You should also take this opportunity to update the repositories on your github account to ensure they are always up to date.&lt;br /&gt;
&lt;br /&gt;
To start with lets update the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This moves to the master repository and then tells git for fetch all of the changes from your remote repositories and clean up any old branches it is aware of.&lt;br /&gt;
&lt;br /&gt;
Once that operation has completed you should update your master branch&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Before you do that it pays to make sure you don&#039;t have any uncommit changes, if you do DON&#039;T TRY IT. There would be a good chance you will encounter problems. Instead finish what you are working on, commit your changes and then update your master branch.&lt;br /&gt;
&lt;br /&gt;
Next we will update the github repositories by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github refs/remotes/origin/master:master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This tells git to push the master branch from origin (the offical Moodle repository) to the master branch on our github account.&lt;br /&gt;
&lt;br /&gt;
Now that you&#039;ve updated the master repository and your github account its time to update the MOODLE_20_STABLE and MOODLE_19_STABLE branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_20_STABLE:MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_19_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_19_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_19_STABLE:MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Working on a Moodle issue==&lt;br /&gt;
&lt;br /&gt;
This part of the document looks at how I go about working on an MDL issue from the Moodle tracker.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ we use the scrum methodology we sees us choose several issues to include in a scrum which we then work on for the period of the scrum. As a community member its more likely you will just be choosing issues that you are passionate about.&lt;br /&gt;
&lt;br /&gt;
Either way once you have found an issue to work on you are ready to start.&lt;br /&gt;
&lt;br /&gt;
For the purpose of this part of the document lets say I am going to work on bug MDL-12345.&lt;br /&gt;
&lt;br /&gt;
==Fixing a bug on the master repository - MDL-12345==&lt;br /&gt;
&lt;br /&gt;
The first step is to create a local branch to make changes on, to do this we will start our work on the master repository.&lt;br /&gt;
&lt;br /&gt;
When fixing an issue I find it easiest to fix the issue on the master branch first and then move my changes to the other branches.&lt;br /&gt;
&lt;br /&gt;
The VERY first thing you should do when you start working on a Moodle issue is make sure you have assigned it to yourself and then click the start progress button.&lt;br /&gt;
&lt;br /&gt;
This way other users know that you are activly working on the bug and no one from HQ will steal it from you.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local branch===&lt;br /&gt;
&lt;br /&gt;
So first get to the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there we create a new branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-master origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command checks out a new branch called wip-MDL-12345-master that is based upon origin/master.&lt;br /&gt;
&lt;br /&gt;
origin/master is of course the master branch on the official Moodle repository (git.moodle.org/moodle.git).&lt;br /&gt;
&lt;br /&gt;
The name of the branch is also very important. It is essentially telling us three things.&lt;br /&gt;
&lt;br /&gt;
; wip : This stands for work in progress, it helps people see that you are currently working on this branch and that they shouldn&#039;t base there work on it because it will likely change.&lt;br /&gt;
; MDL-12345 : This is of course the Moodle bug number. It helps people quickly identify what you are working on.&lt;br /&gt;
; master : This is the branch we are making changes on. It helps people quickly understand where the changes are being made.&lt;br /&gt;
&lt;br /&gt;
You can optionally add more to the end of the branch name such as a key word that identifies the area or a date at which you started work e.g.&lt;br /&gt;
&lt;br /&gt;
* wip-MDL-12345-master-navigation-changes&lt;br /&gt;
* wip-MDL-12345-master-20110418&lt;br /&gt;
&lt;br /&gt;
That is up to you, personally I&#039;m not a fan of it, however the rest is all required to help integrate your work.&lt;br /&gt;
&lt;br /&gt;
Either way now you have a branch, mine is called wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Make changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have created you branch you are ready to make changes.&lt;br /&gt;
&lt;br /&gt;
I&#039;ll let you make whatever changes you are need, once you have made changes move onto the next step.&lt;br /&gt;
&lt;br /&gt;
Before you do move on however make sure that your code meets the high quality of code Moodle requires.&lt;br /&gt;
&lt;br /&gt;
You can find information about that on the moodle docs here: https://docs.moodle.org/en/Development:Coding_style&lt;br /&gt;
&lt;br /&gt;
The following are common mistakes:&lt;br /&gt;
&lt;br /&gt;
* Incorrect white space&lt;br /&gt;
** Tabs instead of spaces&lt;br /&gt;
** Extra spaces at the end of lines&lt;br /&gt;
** Multiple new lines&lt;br /&gt;
** Forgetting to put spaces between function arguments&lt;br /&gt;
* Incorrect commit messages (read on to find out about writing a good commit message)&lt;br /&gt;
* Incorrect variable or function names&lt;br /&gt;
&lt;br /&gt;
Making these sort of mistakes can lead to your code being rejected despite it working correctly.&lt;br /&gt;
&lt;br /&gt;
Or course it will be reviewed in regards to security, usability and the other important factors of code development.&lt;br /&gt;
&lt;br /&gt;
===Step 3: Commit your changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have made your changes you are getting ready to commit them.&lt;br /&gt;
&lt;br /&gt;
The first thing to do is check your changes. To do this run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see all of the files you have changes highlighted in red.&lt;br /&gt;
&lt;br /&gt;
Next you need to stage all of the files you want to commit.&lt;br /&gt;
&lt;br /&gt;
To do this you add the files to the stage using the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git add lib/modifiedfile.php&lt;br /&gt;
git add lib/newfile.php&lt;br /&gt;
git add theme/base/style/core.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Why not just commit all changes. Many of the git guides you read will tell you above git commit -a which commits all of the changes you have made.&lt;br /&gt;
&lt;br /&gt;
We&#039;ve hardly being using git here at Moodle and already I&#039;ve seen several people accidentally commit changes that they didn&#039;t mean to.&lt;br /&gt;
&lt;br /&gt;
Staging files like this ENSURES you only commit things you intend to.&lt;br /&gt;
&lt;br /&gt;
Now that you have staged your changes/new files you are ready to commit. The following command commits your changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git commit -m &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command commits your changes with the commit message &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;.&lt;br /&gt;
It&#039;s very important to Moodle that you format your commit messages like this.&lt;br /&gt;
They consist of three parts:&lt;br /&gt;
&lt;br /&gt;
# The MDL bug number in this case MDL-12345&lt;br /&gt;
# The area you made changes to in this case enrol&lt;br /&gt;
# A short description of what you did, in this case I fixed a couple of enrolment bugs.&lt;br /&gt;
&lt;br /&gt;
When you commit your message you will see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[master 19a484e] changes&lt;br /&gt;
 1 files changed, 16 insertions(+), 18 deletions(-)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
There is one thing here you need to note down for later, that is the number that appears within the square brackets after the branch name, in my case it is 19a484e. This is the commit id of the commit I just made.&lt;br /&gt;
&lt;br /&gt;
===Step 4: Pushing your changes to your github account===&lt;br /&gt;
&lt;br /&gt;
Now that you have made changes to your local branch you should push it to your github account so that it can be reviewed and hopefully integrated into Moodle.&lt;br /&gt;
&lt;br /&gt;
Doing this is very simple just run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are telling git to push the branch wip-MDL-12345-master to the remote called github which we added when setting up our git repositories.&lt;br /&gt;
And just like that you&#039;ve made a branch that contains your work and pushed it to github ready to get it reviewed.&lt;br /&gt;
&lt;br /&gt;
==Moving your changes to another branch==&lt;br /&gt;
Now that you have made changes to the master branch you need to decide whether it is appropriate make those changes on any of the other branches.&lt;br /&gt;
Most likely if you are fixing a bug you will need to make the changes on the MOODLE_20_STABLE branch as well, and perhaps the MOODLE_19_STABLE branch if it is a security bug.&lt;br /&gt;
&lt;br /&gt;
Lets assume for MDL-12345 that I fixed earlier that it should be ported to MOODLE_20_STABLE as well.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local MOODLE_20_STABLE branch===&lt;br /&gt;
&lt;br /&gt;
To start with I need to move to the MOODLE_20_STABLE repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there I need to create a new branch based upon the MOODLE_20_STABLE branch that is going to contain my changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very similar to the branch we created for the changes to the master branch except that I have subsituted MOODLE_20_STABLE in place of master. This is because the new branch we are creating is based upon the MOODLE_20_STABLE branch on the offical Moodle git repository and contains changes for that branch.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Cherry-picking my changes===&lt;br /&gt;
Once we have a branch for our changes I am ready to make them again. There is however with git an easy way to do this, cherry-picking.&lt;br /&gt;
&lt;br /&gt;
Cherry-picking is the process of copying a single commit from one branch to another. In this case I want to cherry pick the commit I made earlier onto the branch I&#039;ve just created.&lt;br /&gt;
&lt;br /&gt;
However before I can do this I need to fetch the changes I made from the github repository. I need to do this because I made that changes of a totally separate local repository remember.&lt;br /&gt;
&lt;br /&gt;
So to update my repository with the latest changes I run the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command tells git to look at each remote and get any new changes (it also removes any branches that have been deleted).&lt;br /&gt;
Once it has completed you will be ready to cherry pick the commit. To do so you use the following command but replace my commit is with yours.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git cherry-pick 19a484e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Providing there are no conflicts your branch will now contain a copy of the changes you made to the master branch.&lt;br /&gt;
If there are conficts that you will need to resolve them and commit your changes however you can search for another tutorial about how to do that,&lt;br /&gt;
&lt;br /&gt;
Now I know at this point that there will be some of you who are saying &#039;Whoops I forgot what my commit id was!&#039;. If this is you don&#039;t worry, its pretty easy to find it providing you used a proper commit message like I described above.&lt;br /&gt;
Simply run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git log --oneline origin/master..github/wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the commits that are in the wip-MDL-12345-master at your github account but are not in the master branch at the offical Moodle repository.&lt;br /&gt;
You can then cherry-pick the commits shown there (the commit ID&#039;s should be highlighted in yellow).&lt;br /&gt;
&lt;br /&gt;
Once you have cherry-picked your commits its time to check that everything worked, run the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# On branch wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
# Your branch is ahead of &#039;origin/MOODLE_20_STABLE&#039; by 1 commit.&lt;br /&gt;
#&lt;br /&gt;
nothing to commit (working directory clean)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very handy as it tells you that your branch is ahead of the offical MOODLE_20_STABLE branch by one commit.&lt;br /&gt;
You can also check that your commit contains the changes you think by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git diff origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the changes you have made as a diff.&lt;br /&gt;
&lt;br /&gt;
Now that you know that your commit is there you and that it is correct it is time to push it to your github account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And thats it.&lt;br /&gt;
&lt;br /&gt;
You github account should now have two branches on it:&lt;br /&gt;
&lt;br /&gt;
; wip-MDL-12345-master : This branch is the changes you have made for the master branch&lt;br /&gt;
; wip-MDL-12345-MOODLE_20_STABLE : This branch is those same changes but for the MOODLE_20_STABLE branch&lt;br /&gt;
&lt;br /&gt;
Now you are ready to create PULL requests so that your work gets reviewed and hopefully integrated.&lt;br /&gt;
&lt;br /&gt;
==Creating a PULL request for the master branch==&lt;br /&gt;
&lt;br /&gt;
So you have successfully fixed the bug MDL-12345, you have created two branches one for master and one for MOODLE_20_STABLE. It is time to create a PULL request for each of these branches.&lt;br /&gt;
&lt;br /&gt;
First lets create a PULL request for the master branch:&lt;br /&gt;
&lt;br /&gt;
# Browse to tracker.moodle.org/browse/MDL-12345&lt;br /&gt;
# When the page loads log in if you haven&#039;t already.&lt;br /&gt;
# Click on the button in the top right labelled `Create issue`&lt;br /&gt;
# Change Project to `Pull Requests`&lt;br /&gt;
# Change Issue type to `Pull Request`&lt;br /&gt;
# Click create&lt;br /&gt;
&lt;br /&gt;
This takes you to a screen where you can enter the details for the PULL request.&lt;br /&gt;
&lt;br /&gt;
You should fill it out in the following way:&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
This is the summary for the PULL request, you should copy and paste the summary from the MDL issue here.&lt;br /&gt;
For MDL-12345 the summary is `alphabetization of UI different on left and right sides` so that&#039;s what I will use.&lt;br /&gt;
&lt;br /&gt;
===Affects Versions===&lt;br /&gt;
This is the version that your branch is changing, in the case of this PULL request I will select `master`.&lt;br /&gt;
&lt;br /&gt;
===Security level===&lt;br /&gt;
If the issue you are working on is a security issue you should set this to the same level that the issue is set to. If its not a security issue or you don&#039;t know just leave it as none.&lt;br /&gt;
&lt;br /&gt;
===Pull from repository===&lt;br /&gt;
This is the repository that the branch is at, for you this will be your github accont. If you head to http://github.com/yourname/moodle you will see a box that has three options SSH, HTTP, and Git read only, click Git Read Only and then copy the contents of the text box into the repositry field of the PULL request. &lt;br /&gt;
For me that is git://github.com/yourname/moodle.git&lt;br /&gt;
&lt;br /&gt;
===Pull branch===&lt;br /&gt;
This is the name of the branch that contains your changes. For me that is wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Pull Diff URL===&lt;br /&gt;
This is the URL to a page that shows the changes that you&#039;ve made on your branch. Github is nice in that it has a pretty interface for that. To get to the interface follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Browse to https://github.com/youraccount/moodle&lt;br /&gt;
# Click `Switch Branches` and then click on the branch you changes are based upon, in my case master.&lt;br /&gt;
# Click the button labelled `Branch List`&lt;br /&gt;
# Locate your branch in the list and click the `Compare button` for me this was the compare button to the right of wip-MDL-12345-master.&lt;br /&gt;
# Copy the URL in your browse and paste it into the Pull Diff URL of the PULL request.&lt;br /&gt;
&lt;br /&gt;
For me this URL was: https://github.com/yourname/moodle/compare/master...wip-MDL-23532-master&lt;br /&gt;
For the MOODLE_20_STABLE branch this would be: https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
&lt;br /&gt;
===Description===&lt;br /&gt;
The description should contain several bits of important information:&lt;br /&gt;
&lt;br /&gt;
# A short description of what your patch does&lt;br /&gt;
# Notes about that changes you&#039;ve made that might help the integrator understand what you did when he/she is reviewing it.&lt;br /&gt;
# Testing instructions that guide the testers through testing your changes.&lt;br /&gt;
&lt;br /&gt;
===Components===&lt;br /&gt;
Select general from the components list, general is the only option.&lt;br /&gt;
&lt;br /&gt;
===Finishing up===&lt;br /&gt;
Once you have filled in the fields as above click `Create`. This should create you PULL request and then take you to view it.&lt;br /&gt;
&lt;br /&gt;
Its important to remember that there is still one thing you need to do and that is link to the original issue.&lt;br /&gt;
While you are still logged in click the `More Actions` button and select `Link issue`, in the dialoug that pops up change the `This issue` field to `will help resolve`, type MDL-12345 into the issues field, and then type `Linking to MDL-12345` into the comments box. Once you&#039;ve done that simple click Link.&amp;lt;br /&amp;gt;I should add that the comment isn&#039;t really required. It&#039;s just something I personally like doing.&lt;br /&gt;
&lt;br /&gt;
Time to create the PULL request for the other branches.&lt;br /&gt;
&lt;br /&gt;
==Creating the PULL request for MOODLE_20_STABLE==&lt;br /&gt;
Once you&#039;ve created the PULL request for the master branch it is time to create the PULL request for the MOODLE_20_STABLE branch.&lt;br /&gt;
This is as easy as can be, click Create Issue in the top right, select PULL project and choose Pull Request and then click create.&lt;br /&gt;
On the next screen enter the following details:&lt;br /&gt;
&lt;br /&gt;
; Summary : Copy the summary from the previous PULL Request&lt;br /&gt;
; Affects Versions : Select MOODLE_20_STABLE&lt;br /&gt;
; Security level : Same as the MDL&lt;br /&gt;
; Pull from repository : Copy from the previous PULL request&lt;br /&gt;
; Pull Branch : wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
; Pull Diff URL : https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
; Description : Copy from the previous PULL request&lt;br /&gt;
; Component : general&lt;br /&gt;
&lt;br /&gt;
Then click create to create the PULL request.&lt;br /&gt;
&lt;br /&gt;
Once the PULL request has been create don&#039;t forget to link to the MDL issue like we did for the previous PULL request.&lt;br /&gt;
&lt;br /&gt;
==Rebasing after the weekly release==&lt;br /&gt;
As many of you will be aware on Wednesday after the latest weekly has been released a comment will be added to all PULL requests that are still open.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The main moodle.git repository has just been updated with latest weekly modifications. You may wish to rebase your PULL branches to simplify history and avoid any possible merge conflicts. This would also make integrator&#039;s life easier next week.&lt;br /&gt;
&lt;br /&gt;
TIA and ciao :)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is a message that is bulk added as is done so as a polite request. While it&#039;s not essential for you to rebase your work it really does help the integrators as its much easier to see what is going on and greatly reduces the chance of conflicts (because you&#039;ll solve them when you rebase).&lt;br /&gt;
&lt;br /&gt;
The good news is that rebasing your work is EASY!&lt;br /&gt;
&lt;br /&gt;
For the following example lets assume I created the two PULL requests above on Wednesday morning and the weekly was released on Wednesday afternoon. This means that my branch doesn&#039;t have the changes that have just been released and I need to rebase them.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Rebasing the wip-MDL-12345-master===&lt;br /&gt;
&lt;br /&gt;
The first step is to rebase my work that is based upon the master branch. So first move to the master repository.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next thing we have to do is get all of the changes from the remote repositories, this will fetch down all of the latest changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now before the next step make sure that you don&#039;t have any uncommit changes, if you do finish that work, commit it, then proceed to the next step which is updating your local master.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
git push master github&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that your local master is up to date, and has you&#039;ve updated you master branch at github you are ready to rebase!&lt;br /&gt;
At this point we want to checkout the branch we are going to rebase, in this case wip-MDL-12345-master and then we are going to rebase origin/master which is the official Moodle master branch (and the branch our branch is based upon).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout wip-MDL-12345-master&lt;br /&gt;
git rebase origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that command has completed your branch wip-MDL-12345-master will be completely up to date. Before you are done however you need to push the rebased wip-MDL-12345-master up to your github account so that its the branch the integrator sees.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push -f github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that command is just about identical to the command we used when we first pushed our branch to our github account, there is however one VERY important difference, the &#039;&#039;&#039;-f&#039;&#039;&#039; option.&lt;br /&gt;
The &#039;&#039;&#039;-f&#039;&#039;&#039; option tells git to force the push, this is required because when you rebase all of your commit id&#039;s will change and unless you tell git to force it will see that they have changed and not allow you to push your work.&lt;br /&gt;
&lt;br /&gt;
Thats it! you&#039;ve now rebased your work and the integrators will be happy again :)&lt;br /&gt;
&lt;br /&gt;
===Step 2: Rebasing wip-MDL-12345-MOODLE_20_STABLE===&lt;br /&gt;
Now that we&#039;ve rebased our work that was based upon the master branch it is time to rebase the MOODLE_20_STABLE version.&lt;br /&gt;
This step is just about identical to the previous step except we substitute &#039;&#039;master&#039;&#039; for &#039;&#039;MOODLE_20_STABLE&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github MOODLE_20_STABLE&lt;br /&gt;
git checkout wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
git rebase origin/MOODLE_20_STABLE&lt;br /&gt;
git push -f github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&lt;br /&gt;
==Useful links==&lt;br /&gt;
The following are links I found useful while learning Git.&lt;br /&gt;
&lt;br /&gt;
* [http://help.github.com Github help (http://help.github.com)] Provides EXCELLENT help tutorials that very clearly explain the basic through to the advanced.&lt;br /&gt;
* [http://cheat.errtheblog.com/s/git/ $ cheat git] This is my favourite cheat sheet, straight forward to the point, if you know the concept you&#039;ll find the answer here.&lt;br /&gt;
* [http://gitster.livejournal.com/28309.html Gitsters journal - Fun with FETCH_HEAD] David Mudrak pointed me at this entry which I found INCREDIBLY useful when reviewing other peoples work.&lt;br /&gt;
&lt;br /&gt;
I you&#039;re looking to read/buy a book on Git I&#039;d strongly recommend [http://progit.org/ Pro Git]. I certainly found that the most useful book I read.&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82869</id>
		<title>User:Sam Hemelryk/My Moodle Git workflow</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82869"/>
		<updated>2011-04-19T01:43:06Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* Useful links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document is a sort of tutorial/inspection of my personal development workflow when working on Moodle with Git.&lt;br /&gt;
&lt;br /&gt;
==Creating the repositories==&lt;br /&gt;
Ok so the very first step is to create several Moodle git repositories, one for each major branch of Moodle being worked on.&lt;br /&gt;
&lt;br /&gt;
At the time of writing the major branches are MOODLE_19_STABLE, MOODLE_20_STABLE and master.&lt;br /&gt;
&lt;br /&gt;
The reason for this is that that way we have a separate site for each Moodle branch that we can test on easily. Yes you will have three sites but you won&#039;t have to worry about swtiching your site when you change branches.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Create a directory to create the repositories within===&lt;br /&gt;
&lt;br /&gt;
Personally I use Ubuntu (Linux) and I chose to create my repositories within a folder I created in /var/www. If you are using windows I would instead suggest creating C:/www/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www&lt;br /&gt;
mkdir repositories&lt;br /&gt;
cd repositories&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 2: Create a master repository===&lt;br /&gt;
This is the easiest of the branches to create a repository for.&lt;br /&gt;
&lt;br /&gt;
Within your repositories directory create a new directory called master and move into it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir master&lt;br /&gt;
cd master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we want to clone the Moodle source from the offical Moodle git repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new directory called moodle within the master directory we created just before.&lt;br /&gt;
&lt;br /&gt;
That new moodle directory should contain the Moodle source code as a git repository.&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our main git repository we need to add our github account as a remote so that we can push to it later:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd moodle&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This adds your moodle repository on github as a remote called github that you can push to later.&lt;br /&gt;
&lt;br /&gt;
Finally before we move onto the next repository we need to create a data directory because we know we will need that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 3: Create a MOODLE_20_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
The next repository we create will be for the MOODLE_20_STABLE branch.&lt;br /&gt;
To start with get back to the repositories directory that we created earlier and create a directory called MOODLE_20_STABLE within that.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_20_STABLE&lt;br /&gt;
cd MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now create a new clone of the main Moodle repository like we did for the master branch above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have done that move into the moodle directory.&lt;br /&gt;
&lt;br /&gt;
By default the master branch is the branch that is created, however we don&#039;t want that for this repository. Instead we want the MOODLE_20_STABLE branch.&lt;br /&gt;
&lt;br /&gt;
To do this we checkout local branch based upon the official MOODLE_20_STABLE branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have created that branch we can delete the local master branch so that we don&#039;t accidentally ever work on it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git branch -D master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then like we did for master we add our github repository as a remote:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And finally create a data directory we can use when we have install the site:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 4: Create a MOODLE_19_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
This step is identical to the above step except we are using the MOODLE_19_STABLE branch instead of the MOODLE_20_STABLE branch.&lt;br /&gt;
The commands for this are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_19_STABLE&lt;br /&gt;
cd MOODLE_19_STABLE&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
git checkout -b MOODLE_19_STABLE origin/MOODLE_19_STABLE&lt;br /&gt;
git branch -D master&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 5: Install the sites===&lt;br /&gt;
Now I can&#039;t tell you how to do this on your own machine however what I would recommend is that you create a link from your web root to the moodle directory of each branch.&lt;br /&gt;
&lt;br /&gt;
If you are using linux and your webroot is /var/www/localhost you would do it as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/localhost/&lt;br /&gt;
ln -s /var/www/repositories/master/moodle master&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_20_STABLE/moodle MOODLE_20_STABLE&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_19_STABLE/moodle MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done you should be able to browse to each repository with the following URL&#039;s&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://localhost/master/&lt;br /&gt;
http://localhost/MOODLE_20_STABLE/&lt;br /&gt;
http://localhost/MOODLE_19_STABLE/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that is done you need to browse to each site and complete the installation.&lt;br /&gt;
&lt;br /&gt;
Under this method your will need to ensure you set the configuration option sessioncookiepath to the URI of your site. You can either do this in the admin interfaces or add the following to your config.php file for each site.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// For the master site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/master/&#039;;&lt;br /&gt;
// For the MOODLE_20_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_20_STABLE/&#039;;&lt;br /&gt;
// For the MOODLE_19_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_19_STABLE/&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Failure to do this will mean that when you log in at one site and then visit the next you will have to log in again and your session on the first site will no longer work.&lt;br /&gt;
&lt;br /&gt;
Now that you have got 3 repositories, one for each main branch, and set up a site for each you are ready to start development.&lt;br /&gt;
&lt;br /&gt;
==Before you start work each day==&lt;br /&gt;
Before you start work each day you should update each of the repositories you have created to ensure that you are always working with up to date versions of Moodle.&lt;br /&gt;
&lt;br /&gt;
You should also take this opportunity to update the repositories on your github account to ensure they are always up to date.&lt;br /&gt;
&lt;br /&gt;
To start with lets update the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This moves to the master repository and then tells git for fetch all of the changes from your remote repositories and clean up any old branches it is aware of.&lt;br /&gt;
&lt;br /&gt;
Once that operation has completed you should update your master branch&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Before you do that it pays to make sure you don&#039;t have any uncommit changes, if you do DON&#039;T TRY IT. There would be a good chance you will encounter problems. Instead finish what you are working on, commit your changes and then update your master branch.&lt;br /&gt;
&lt;br /&gt;
Next we will update the github repositories by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github refs/remotes/origin/master:master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This tells git to push the master branch from origin (the offical Moodle repository) to the master branch on our github account.&lt;br /&gt;
&lt;br /&gt;
Now that you&#039;ve updated the master repository and your github account its time to update the MOODLE_20_STABLE and MOODLE_19_STABLE branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_20_STABLE:MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_19_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_19_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_19_STABLE:MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Working on a Moodle issue==&lt;br /&gt;
&lt;br /&gt;
This part of the document looks at how I go about working on an MDL issue from the Moodle tracker.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ we use the scrum methodology we sees us choose several issues to include in a scrum which we then work on for the period of the scrum. As a community member its more likely you will just be choosing issues that you are passionate about.&lt;br /&gt;
&lt;br /&gt;
Either way once you have found an issue to work on you are ready to start.&lt;br /&gt;
&lt;br /&gt;
For the purpose of this part of the document lets say I am going to work on bug MDL-12345.&lt;br /&gt;
&lt;br /&gt;
==Fixing a bug on the master repository - MDL-12345==&lt;br /&gt;
&lt;br /&gt;
The first step is to create a local branch to make changes on, to do this we will start our work on the master repository.&lt;br /&gt;
&lt;br /&gt;
When fixing an issue I find it easiest to fix the issue on the master branch first and then move my changes to the other branches.&lt;br /&gt;
&lt;br /&gt;
The VERY first thing you should do when you start working on a Moodle issue is make sure you have assigned it to yourself and then click the start progress button.&lt;br /&gt;
&lt;br /&gt;
This way other users know that you are activly working on the bug and no one from HQ will steal it from you.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local branch===&lt;br /&gt;
&lt;br /&gt;
So first get to the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there we create a new branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-master origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command checks out a new branch called wip-MDL-12345-master that is based upon origin/master.&lt;br /&gt;
&lt;br /&gt;
origin/master is of course the master branch on the official Moodle repository (git.moodle.org/moodle.git).&lt;br /&gt;
&lt;br /&gt;
The name of the branch is also very important. It is essentially telling us three things.&lt;br /&gt;
&lt;br /&gt;
; wip : This stands for work in progress, it helps people see that you are currently working on this branch and that they shouldn&#039;t base there work on it because it will likely change.&lt;br /&gt;
; MDL-12345 : This is of course the Moodle bug number. It helps people quickly identify what you are working on.&lt;br /&gt;
; master : This is the branch we are making changes on. It helps people quickly understand where the changes are being made.&lt;br /&gt;
&lt;br /&gt;
You can optionally add more to the end of the branch name such as a key word that identifies the area or a date at which you started work e.g.&lt;br /&gt;
&lt;br /&gt;
* wip-MDL-12345-master-navigation-changes&lt;br /&gt;
* wip-MDL-12345-master-20110418&lt;br /&gt;
&lt;br /&gt;
That is up to you, personally I&#039;m not a fan of it, however the rest is all required to help integrate your work.&lt;br /&gt;
&lt;br /&gt;
Either way now you have a branch, mine is called wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Make changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have created you branch you are ready to make changes.&lt;br /&gt;
&lt;br /&gt;
I&#039;ll let you make whatever changes you are need, once you have made changes move onto the next step.&lt;br /&gt;
&lt;br /&gt;
Before you do move on however make sure that your code meets the high quality of code Moodle requires.&lt;br /&gt;
&lt;br /&gt;
You can find information about that on the moodle docs here: https://docs.moodle.org/en/Development:Coding_style&lt;br /&gt;
&lt;br /&gt;
The following are common mistakes:&lt;br /&gt;
&lt;br /&gt;
* Incorrect white space&lt;br /&gt;
** Tabs instead of spaces&lt;br /&gt;
** Extra spaces at the end of lines&lt;br /&gt;
** Multiple new lines&lt;br /&gt;
** Forgetting to put spaces between function arguments&lt;br /&gt;
* Incorrect commit messages (read on to find out about writing a good commit message)&lt;br /&gt;
* Incorrect variable or function names&lt;br /&gt;
&lt;br /&gt;
Making these sort of mistakes can lead to your code being rejected despite it working correctly.&lt;br /&gt;
&lt;br /&gt;
Or course it will be reviewed in regards to security, usability and the other important factors of code development.&lt;br /&gt;
&lt;br /&gt;
===Step 3: Commit your changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have made your changes you are getting ready to commit them.&lt;br /&gt;
&lt;br /&gt;
The first thing to do is check your changes. To do this run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see all of the files you have changes highlighted in red.&lt;br /&gt;
&lt;br /&gt;
Next you need to stage all of the files you want to commit.&lt;br /&gt;
&lt;br /&gt;
To do this you add the files to the stage using the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git add lib/modifiedfile.php&lt;br /&gt;
git add lib/newfile.php&lt;br /&gt;
git add theme/base/style/core.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Why not just commit all changes. Many of the git guides you read will tell you above git commit -a which commits all of the changes you have made.&lt;br /&gt;
&lt;br /&gt;
We&#039;ve hardly being using git here at Moodle and already I&#039;ve seen several people accidentally commit changes that they didn&#039;t mean to.&lt;br /&gt;
&lt;br /&gt;
Staging files like this ENSURES you only commit things you intend to.&lt;br /&gt;
&lt;br /&gt;
Now that you have staged your changes/new files you are ready to commit. The following command commits your changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git commit -m &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command commits your changes with the commit message &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;.&lt;br /&gt;
It&#039;s very important to Moodle that you format your commit messages like this.&lt;br /&gt;
They consist of three parts:&lt;br /&gt;
&lt;br /&gt;
# The MDL bug number in this case MDL-12345&lt;br /&gt;
# The area you made changes to in this case enrol&lt;br /&gt;
# A short description of what you did, in this case I fixed a couple of enrolment bugs.&lt;br /&gt;
&lt;br /&gt;
When you commit your message you will see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[master 19a484e] changes&lt;br /&gt;
 1 files changed, 16 insertions(+), 18 deletions(-)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
There is one thing here you need to note down for later, that is the number that appears within the square brackets after the branch name, in my case it is 19a484e. This is the commit id of the commit I just made.&lt;br /&gt;
&lt;br /&gt;
===Step 4: Pushing your changes to your github account===&lt;br /&gt;
&lt;br /&gt;
Now that you have made changes to your local branch you should push it to your github account so that it can be reviewed and hopefully integrated into Moodle.&lt;br /&gt;
&lt;br /&gt;
Doing this is very simple just run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are telling git to push the branch wip-MDL-12345-master to the remote called github which we added when setting up our git repositories.&lt;br /&gt;
And just like that you&#039;ve made a branch that contains your work and pushed it to github ready to get it reviewed.&lt;br /&gt;
&lt;br /&gt;
==Moving your changes to another branch==&lt;br /&gt;
Now that you have made changes to the master branch you need to decide whether it is appropriate make those changes on any of the other branches.&lt;br /&gt;
Most likely if you are fixing a bug you will need to make the changes on the MOODLE_20_STABLE branch as well, and perhaps the MOODLE_19_STABLE branch if it is a security bug.&lt;br /&gt;
&lt;br /&gt;
Lets assume for MDL-12345 that I fixed earlier that it should be ported to MOODLE_20_STABLE as well.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local MOODLE_20_STABLE branch===&lt;br /&gt;
&lt;br /&gt;
To start with I need to move to the MOODLE_20_STABLE repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there I need to create a new branch based upon the MOODLE_20_STABLE branch that is going to contain my changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very similar to the branch we created for the changes to the master branch except that I have subsituted MOODLE_20_STABLE in place of master. This is because the new branch we are creating is based upon the MOODLE_20_STABLE branch on the offical Moodle git repository and contains changes for that branch.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Cherry-picking my changes===&lt;br /&gt;
Once we have a branch for our changes I am ready to make them again. There is however with git an easy way to do this, cherry-picking.&lt;br /&gt;
&lt;br /&gt;
Cherry-picking is the process of copying a single commit from one branch to another. In this case I want to cherry pick the commit I made earlier onto the branch I&#039;ve just created.&lt;br /&gt;
&lt;br /&gt;
However before I can do this I need to fetch the changes I made from the github repository. I need to do this because I made that changes of a totally separate local repository remember.&lt;br /&gt;
&lt;br /&gt;
So to update my repository with the latest changes I run the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command tells git to look at each remote and get any new changes (it also removes any branches that have been deleted).&lt;br /&gt;
Once it has completed you will be ready to cherry pick the commit. To do so you use the following command but replace my commit is with yours.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git cherry-pick 19a484e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Providing there are no conflicts your branch will now contain a copy of the changes you made to the master branch.&lt;br /&gt;
If there are conficts that you will need to resolve them and commit your changes however you can search for another tutorial about how to do that,&lt;br /&gt;
&lt;br /&gt;
Now I know at this point that there will be some of you who are saying &#039;Whoops I forgot what my commit id was!&#039;. If this is you don&#039;t worry, its pretty easy to find it providing you used a proper commit message like I described above.&lt;br /&gt;
Simply run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git log --oneline origin/master..github/wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the commits that are in the wip-MDL-12345-master at your github account but are not in the master branch at the offical Moodle repository.&lt;br /&gt;
You can then cherry-pick the commits shown there (the commit ID&#039;s should be highlighted in yellow).&lt;br /&gt;
&lt;br /&gt;
Once you have cherry-picked your commits its time to check that everything worked, run the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# On branch wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
# Your branch is ahead of &#039;origin/MOODLE_20_STABLE&#039; by 1 commit.&lt;br /&gt;
#&lt;br /&gt;
nothing to commit (working directory clean)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very handy as it tells you that your branch is ahead of the offical MOODLE_20_STABLE branch by one commit.&lt;br /&gt;
You can also check that your commit contains the changes you think by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git diff origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the changes you have made as a diff.&lt;br /&gt;
&lt;br /&gt;
Now that you know that your commit is there you and that it is correct it is time to push it to your github account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And thats it.&lt;br /&gt;
&lt;br /&gt;
You github account should now have two branches on it:&lt;br /&gt;
&lt;br /&gt;
; wip-MDL-12345-master : This branch is the changes you have made for the master branch&lt;br /&gt;
; wip-MDL-12345-MOODLE_20_STABLE : This branch is those same changes but for the MOODLE_20_STABLE branch&lt;br /&gt;
&lt;br /&gt;
Now you are ready to create PULL requests so that your work gets reviewed and hopefully integrated.&lt;br /&gt;
&lt;br /&gt;
==Creating a PULL request for the master branch==&lt;br /&gt;
&lt;br /&gt;
So you have successfully fixed the bug MDL-12345, you have created two branches one for master and one for MOODLE_20_STABLE. It is time to create a PULL request for each of these branches.&lt;br /&gt;
&lt;br /&gt;
First lets create a PULL request for the master branch:&lt;br /&gt;
&lt;br /&gt;
# Browse to tracker.moodle.org/browse/MDL-12345&lt;br /&gt;
# When the page loads log in if you haven&#039;t already.&lt;br /&gt;
# Click on the button in the top right labelled `Create issue`&lt;br /&gt;
# Change Project to `Pull Requests`&lt;br /&gt;
# Change Issue type to `Pull Request`&lt;br /&gt;
# Click create&lt;br /&gt;
&lt;br /&gt;
This takes you to a screen where you can enter the details for the PULL request.&lt;br /&gt;
&lt;br /&gt;
You should fill it out in the following way:&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
This is the summary for the PULL request, you should copy and paste the summary from the MDL issue here.&lt;br /&gt;
For MDL-12345 the summary is `alphabetization of UI different on left and right sides` so that&#039;s what I will use.&lt;br /&gt;
&lt;br /&gt;
===Affects Versions===&lt;br /&gt;
This is the version that your branch is changing, in the case of this PULL request I will select `master`.&lt;br /&gt;
&lt;br /&gt;
===Security level===&lt;br /&gt;
If the issue you are working on is a security issue you should set this to the same level that the issue is set to. If its not a security issue or you don&#039;t know just leave it as none.&lt;br /&gt;
&lt;br /&gt;
===Pull from repository===&lt;br /&gt;
This is the repository that the branch is at, for you this will be your github accont. If you head to http://github.com/yourname/moodle you will see a box that has three options SSH, HTTP, and Git read only, click Git Read Only and then copy the contents of the text box into the repositry field of the PULL request. &lt;br /&gt;
For me that is git://github.com/yourname/moodle.git&lt;br /&gt;
&lt;br /&gt;
===Pull branch===&lt;br /&gt;
This is the name of the branch that contains your changes. For me that is wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Pull Diff URL===&lt;br /&gt;
This is the URL to a page that shows the changes that you&#039;ve made on your branch. Github is nice in that it has a pretty interface for that. To get to the interface follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Browse to https://github.com/youraccount/moodle&lt;br /&gt;
# Click `Switch Branches` and then click on the branch you changes are based upon, in my case master.&lt;br /&gt;
# Click the button labelled `Branch List`&lt;br /&gt;
# Locate your branch in the list and click the `Compare button` for me this was the compare button to the right of wip-MDL-12345-master.&lt;br /&gt;
# Copy the URL in your browse and paste it into the Pull Diff URL of the PULL request.&lt;br /&gt;
&lt;br /&gt;
For me this URL was: https://github.com/yourname/moodle/compare/master...wip-MDL-23532-master&lt;br /&gt;
For the MOODLE_20_STABLE branch this would be: https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
&lt;br /&gt;
===Description===&lt;br /&gt;
The description should contain several bits of important information:&lt;br /&gt;
&lt;br /&gt;
# A short description of what your patch does&lt;br /&gt;
# Notes about that changes you&#039;ve made that might help the integrator understand what you did when he/she is reviewing it.&lt;br /&gt;
# Testing instructions that guide the testers through testing your changes.&lt;br /&gt;
&lt;br /&gt;
===Components===&lt;br /&gt;
Select general from the components list, general is the only option.&lt;br /&gt;
&lt;br /&gt;
===Finishing up===&lt;br /&gt;
Once you have filled in the fields as above click `Create`. This should create you PULL request and then take you to view it.&lt;br /&gt;
&lt;br /&gt;
Its important to remember that there is still one thing you need to do and that is link to the original issue.&lt;br /&gt;
While you are still logged in click the `More Actions` button and select `Link issue`, in the dialoug that pops up change the `This issue` field to `will help resolve`, type MDL-12345 into the issues field, and then type `Linking to MDL-12345` into the comments box. Once you&#039;ve done that simple click Link.&lt;br /&gt;
&lt;br /&gt;
Time to create the PULL request for the other branches.&lt;br /&gt;
&lt;br /&gt;
==Creating the PULL request for MOODLE_20_STABLE==&lt;br /&gt;
Once you&#039;ve created the PULL request for the master branch it is time to create the PULL request for the MOODLE_20_STABLE branch.&lt;br /&gt;
This is as easy as can be, click Create Issue in the top right, select PULL project and choose Pull Request and then click create.&lt;br /&gt;
On the next screen enter the following details:&lt;br /&gt;
&lt;br /&gt;
; Summary : Copy the summary from the previous PULL Request&lt;br /&gt;
; Affects Versions : Select MOODLE_20_STABLE&lt;br /&gt;
; Security level : Same as the MDL&lt;br /&gt;
; Pull from repository : Copy from the previous PULL request&lt;br /&gt;
; Pull Branch : wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
; Pull Diff URL : https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
; Description : Copy from the previous PULL request&lt;br /&gt;
; Component : general&lt;br /&gt;
&lt;br /&gt;
Then click create to create the PULL request.&lt;br /&gt;
&lt;br /&gt;
Once the PULL request has been create don&#039;t forget to link to the MDL issue like we did for the previous PULL request.&lt;br /&gt;
&lt;br /&gt;
==Rebasing after the weekly release==&lt;br /&gt;
As many of you will be aware on Wednesday after the latest weekly has been released a comment will be added to all PULL requests that are still open.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The main moodle.git repository has just been updated with latest weekly modifications. You may wish to rebase your PULL branches to simplify history and avoid any possible merge conflicts. This would also make integrator&#039;s life easier next week.&lt;br /&gt;
&lt;br /&gt;
TIA and ciao :)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is a message that is bulk added as is done so as a polite request. While it&#039;s not essential for you to rebase your work it really does help the integrators as its much easier to see what is going on and greatly reduces the chance of conflicts (because you&#039;ll solve them when you rebase).&lt;br /&gt;
&lt;br /&gt;
The good news is that rebasing your work is EASY!&lt;br /&gt;
&lt;br /&gt;
For the following example lets assume I created the two PULL requests above on Wednesday morning and the weekly was released on Wednesday afternoon. This means that my branch doesn&#039;t have the changes that have just been released and I need to rebase them.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Rebasing the wip-MDL-12345-master===&lt;br /&gt;
&lt;br /&gt;
The first step is to rebase my work that is based upon the master branch. So first move to the master repository.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next thing we have to do is get all of the changes from the remote repositories, this will fetch down all of the latest changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now before the next step make sure that you don&#039;t have any uncommit changes, if you do finish that work, commit it, then proceed to the next step which is updating your local master.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
git push master github&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that your local master is up to date, and has you&#039;ve updated you master branch at github you are ready to rebase!&lt;br /&gt;
At this point we want to checkout the branch we are going to rebase, in this case wip-MDL-12345-master and then we are going to rebase origin/master which is the official Moodle master branch (and the branch our branch is based upon).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout wip-MDL-12345-master&lt;br /&gt;
git rebase origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that command has completed your branch wip-MDL-12345-master will be completely up to date. Before you are done however you need to push the rebased wip-MDL-12345-master up to your github account so that its the branch the integrator sees.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push -f github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that command is just about identical to the command we used when we first pushed our branch to our github account, there is however one VERY important difference, the &#039;&#039;&#039;-f&#039;&#039;&#039; option.&lt;br /&gt;
The &#039;&#039;&#039;-f&#039;&#039;&#039; option tells git to force the push, this is required because when you rebase all of your commit id&#039;s will change and unless you tell git to force it will see that they have changed and not allow you to push your work.&lt;br /&gt;
&lt;br /&gt;
Thats it! you&#039;ve now rebased your work and the integrators will be happy again :)&lt;br /&gt;
&lt;br /&gt;
===Step 2: Rebasing wip-MDL-12345-MOODLE_20_STABLE===&lt;br /&gt;
Now that we&#039;ve rebased our work that was based upon the master branch it is time to rebase the MOODLE_20_STABLE version.&lt;br /&gt;
This step is just about identical to the previous step except we substitute &#039;&#039;master&#039;&#039; for &#039;&#039;MOODLE_20_STABLE&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github MOODLE_20_STABLE&lt;br /&gt;
git checkout wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
git rebase origin/MOODLE_20_STABLE&lt;br /&gt;
git push -f github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&lt;br /&gt;
==Useful links==&lt;br /&gt;
The following are links I found useful while learning Git.&lt;br /&gt;
&lt;br /&gt;
* [http://help.github.com Github help (http://help.github.com)] Provides EXCELLENT help tutorials that very clearly explain the basic through to the advanced.&lt;br /&gt;
* [http://cheat.errtheblog.com/s/git/ $ cheat git] This is my favourite cheat sheet, straight forward to the point, if you know the concept you&#039;ll find the answer here.&lt;br /&gt;
* [http://gitster.livejournal.com/28309.html Gitsters journal - Fun with FETCH_HEAD] David Mudrak pointed me at this entry which I found INCREDIBLY useful when reviewing other peoples work.&lt;br /&gt;
&lt;br /&gt;
I you&#039;re looking to read/buy a book on Git I&#039;d strongly recommend [http://progit.org/ Pro Git]. I certainly found that the most useful book I read.&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82868</id>
		<title>User:Sam Hemelryk/My Moodle Git workflow</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82868"/>
		<updated>2011-04-19T01:41:41Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* Useful links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document is a sort of tutorial/inspection of my personal development workflow when working on Moodle with Git.&lt;br /&gt;
&lt;br /&gt;
==Creating the repositories==&lt;br /&gt;
Ok so the very first step is to create several Moodle git repositories, one for each major branch of Moodle being worked on.&lt;br /&gt;
&lt;br /&gt;
At the time of writing the major branches are MOODLE_19_STABLE, MOODLE_20_STABLE and master.&lt;br /&gt;
&lt;br /&gt;
The reason for this is that that way we have a separate site for each Moodle branch that we can test on easily. Yes you will have three sites but you won&#039;t have to worry about swtiching your site when you change branches.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Create a directory to create the repositories within===&lt;br /&gt;
&lt;br /&gt;
Personally I use Ubuntu (Linux) and I chose to create my repositories within a folder I created in /var/www. If you are using windows I would instead suggest creating C:/www/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www&lt;br /&gt;
mkdir repositories&lt;br /&gt;
cd repositories&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 2: Create a master repository===&lt;br /&gt;
This is the easiest of the branches to create a repository for.&lt;br /&gt;
&lt;br /&gt;
Within your repositories directory create a new directory called master and move into it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir master&lt;br /&gt;
cd master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we want to clone the Moodle source from the offical Moodle git repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new directory called moodle within the master directory we created just before.&lt;br /&gt;
&lt;br /&gt;
That new moodle directory should contain the Moodle source code as a git repository.&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our main git repository we need to add our github account as a remote so that we can push to it later:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd moodle&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This adds your moodle repository on github as a remote called github that you can push to later.&lt;br /&gt;
&lt;br /&gt;
Finally before we move onto the next repository we need to create a data directory because we know we will need that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 3: Create a MOODLE_20_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
The next repository we create will be for the MOODLE_20_STABLE branch.&lt;br /&gt;
To start with get back to the repositories directory that we created earlier and create a directory called MOODLE_20_STABLE within that.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_20_STABLE&lt;br /&gt;
cd MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now create a new clone of the main Moodle repository like we did for the master branch above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have done that move into the moodle directory.&lt;br /&gt;
&lt;br /&gt;
By default the master branch is the branch that is created, however we don&#039;t want that for this repository. Instead we want the MOODLE_20_STABLE branch.&lt;br /&gt;
&lt;br /&gt;
To do this we checkout local branch based upon the official MOODLE_20_STABLE branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have created that branch we can delete the local master branch so that we don&#039;t accidentally ever work on it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git branch -D master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then like we did for master we add our github repository as a remote:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And finally create a data directory we can use when we have install the site:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 4: Create a MOODLE_19_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
This step is identical to the above step except we are using the MOODLE_19_STABLE branch instead of the MOODLE_20_STABLE branch.&lt;br /&gt;
The commands for this are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_19_STABLE&lt;br /&gt;
cd MOODLE_19_STABLE&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
git checkout -b MOODLE_19_STABLE origin/MOODLE_19_STABLE&lt;br /&gt;
git branch -D master&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 5: Install the sites===&lt;br /&gt;
Now I can&#039;t tell you how to do this on your own machine however what I would recommend is that you create a link from your web root to the moodle directory of each branch.&lt;br /&gt;
&lt;br /&gt;
If you are using linux and your webroot is /var/www/localhost you would do it as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/localhost/&lt;br /&gt;
ln -s /var/www/repositories/master/moodle master&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_20_STABLE/moodle MOODLE_20_STABLE&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_19_STABLE/moodle MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done you should be able to browse to each repository with the following URL&#039;s&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://localhost/master/&lt;br /&gt;
http://localhost/MOODLE_20_STABLE/&lt;br /&gt;
http://localhost/MOODLE_19_STABLE/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that is done you need to browse to each site and complete the installation.&lt;br /&gt;
&lt;br /&gt;
Under this method your will need to ensure you set the configuration option sessioncookiepath to the URI of your site. You can either do this in the admin interfaces or add the following to your config.php file for each site.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// For the master site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/master/&#039;;&lt;br /&gt;
// For the MOODLE_20_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_20_STABLE/&#039;;&lt;br /&gt;
// For the MOODLE_19_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_19_STABLE/&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Failure to do this will mean that when you log in at one site and then visit the next you will have to log in again and your session on the first site will no longer work.&lt;br /&gt;
&lt;br /&gt;
Now that you have got 3 repositories, one for each main branch, and set up a site for each you are ready to start development.&lt;br /&gt;
&lt;br /&gt;
==Before you start work each day==&lt;br /&gt;
Before you start work each day you should update each of the repositories you have created to ensure that you are always working with up to date versions of Moodle.&lt;br /&gt;
&lt;br /&gt;
You should also take this opportunity to update the repositories on your github account to ensure they are always up to date.&lt;br /&gt;
&lt;br /&gt;
To start with lets update the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This moves to the master repository and then tells git for fetch all of the changes from your remote repositories and clean up any old branches it is aware of.&lt;br /&gt;
&lt;br /&gt;
Once that operation has completed you should update your master branch&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Before you do that it pays to make sure you don&#039;t have any uncommit changes, if you do DON&#039;T TRY IT. There would be a good chance you will encounter problems. Instead finish what you are working on, commit your changes and then update your master branch.&lt;br /&gt;
&lt;br /&gt;
Next we will update the github repositories by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github refs/remotes/origin/master:master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This tells git to push the master branch from origin (the offical Moodle repository) to the master branch on our github account.&lt;br /&gt;
&lt;br /&gt;
Now that you&#039;ve updated the master repository and your github account its time to update the MOODLE_20_STABLE and MOODLE_19_STABLE branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_20_STABLE:MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_19_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_19_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_19_STABLE:MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Working on a Moodle issue==&lt;br /&gt;
&lt;br /&gt;
This part of the document looks at how I go about working on an MDL issue from the Moodle tracker.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ we use the scrum methodology we sees us choose several issues to include in a scrum which we then work on for the period of the scrum. As a community member its more likely you will just be choosing issues that you are passionate about.&lt;br /&gt;
&lt;br /&gt;
Either way once you have found an issue to work on you are ready to start.&lt;br /&gt;
&lt;br /&gt;
For the purpose of this part of the document lets say I am going to work on bug MDL-12345.&lt;br /&gt;
&lt;br /&gt;
==Fixing a bug on the master repository - MDL-12345==&lt;br /&gt;
&lt;br /&gt;
The first step is to create a local branch to make changes on, to do this we will start our work on the master repository.&lt;br /&gt;
&lt;br /&gt;
When fixing an issue I find it easiest to fix the issue on the master branch first and then move my changes to the other branches.&lt;br /&gt;
&lt;br /&gt;
The VERY first thing you should do when you start working on a Moodle issue is make sure you have assigned it to yourself and then click the start progress button.&lt;br /&gt;
&lt;br /&gt;
This way other users know that you are activly working on the bug and no one from HQ will steal it from you.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local branch===&lt;br /&gt;
&lt;br /&gt;
So first get to the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there we create a new branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-master origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command checks out a new branch called wip-MDL-12345-master that is based upon origin/master.&lt;br /&gt;
&lt;br /&gt;
origin/master is of course the master branch on the official Moodle repository (git.moodle.org/moodle.git).&lt;br /&gt;
&lt;br /&gt;
The name of the branch is also very important. It is essentially telling us three things.&lt;br /&gt;
&lt;br /&gt;
; wip : This stands for work in progress, it helps people see that you are currently working on this branch and that they shouldn&#039;t base there work on it because it will likely change.&lt;br /&gt;
; MDL-12345 : This is of course the Moodle bug number. It helps people quickly identify what you are working on.&lt;br /&gt;
; master : This is the branch we are making changes on. It helps people quickly understand where the changes are being made.&lt;br /&gt;
&lt;br /&gt;
You can optionally add more to the end of the branch name such as a key word that identifies the area or a date at which you started work e.g.&lt;br /&gt;
&lt;br /&gt;
* wip-MDL-12345-master-navigation-changes&lt;br /&gt;
* wip-MDL-12345-master-20110418&lt;br /&gt;
&lt;br /&gt;
That is up to you, personally I&#039;m not a fan of it, however the rest is all required to help integrate your work.&lt;br /&gt;
&lt;br /&gt;
Either way now you have a branch, mine is called wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Make changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have created you branch you are ready to make changes.&lt;br /&gt;
&lt;br /&gt;
I&#039;ll let you make whatever changes you are need, once you have made changes move onto the next step.&lt;br /&gt;
&lt;br /&gt;
Before you do move on however make sure that your code meets the high quality of code Moodle requires.&lt;br /&gt;
&lt;br /&gt;
You can find information about that on the moodle docs here: https://docs.moodle.org/en/Development:Coding_style&lt;br /&gt;
&lt;br /&gt;
The following are common mistakes:&lt;br /&gt;
&lt;br /&gt;
* Incorrect white space&lt;br /&gt;
** Tabs instead of spaces&lt;br /&gt;
** Extra spaces at the end of lines&lt;br /&gt;
** Multiple new lines&lt;br /&gt;
** Forgetting to put spaces between function arguments&lt;br /&gt;
* Incorrect commit messages (read on to find out about writing a good commit message)&lt;br /&gt;
* Incorrect variable or function names&lt;br /&gt;
&lt;br /&gt;
Making these sort of mistakes can lead to your code being rejected despite it working correctly.&lt;br /&gt;
&lt;br /&gt;
Or course it will be reviewed in regards to security, usability and the other important factors of code development.&lt;br /&gt;
&lt;br /&gt;
===Step 3: Commit your changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have made your changes you are getting ready to commit them.&lt;br /&gt;
&lt;br /&gt;
The first thing to do is check your changes. To do this run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see all of the files you have changes highlighted in red.&lt;br /&gt;
&lt;br /&gt;
Next you need to stage all of the files you want to commit.&lt;br /&gt;
&lt;br /&gt;
To do this you add the files to the stage using the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git add lib/modifiedfile.php&lt;br /&gt;
git add lib/newfile.php&lt;br /&gt;
git add theme/base/style/core.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Why not just commit all changes. Many of the git guides you read will tell you above git commit -a which commits all of the changes you have made.&lt;br /&gt;
&lt;br /&gt;
We&#039;ve hardly being using git here at Moodle and already I&#039;ve seen several people accidentally commit changes that they didn&#039;t mean to.&lt;br /&gt;
&lt;br /&gt;
Staging files like this ENSURES you only commit things you intend to.&lt;br /&gt;
&lt;br /&gt;
Now that you have staged your changes/new files you are ready to commit. The following command commits your changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git commit -m &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command commits your changes with the commit message &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;.&lt;br /&gt;
It&#039;s very important to Moodle that you format your commit messages like this.&lt;br /&gt;
They consist of three parts:&lt;br /&gt;
&lt;br /&gt;
# The MDL bug number in this case MDL-12345&lt;br /&gt;
# The area you made changes to in this case enrol&lt;br /&gt;
# A short description of what you did, in this case I fixed a couple of enrolment bugs.&lt;br /&gt;
&lt;br /&gt;
When you commit your message you will see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[master 19a484e] changes&lt;br /&gt;
 1 files changed, 16 insertions(+), 18 deletions(-)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
There is one thing here you need to note down for later, that is the number that appears within the square brackets after the branch name, in my case it is 19a484e. This is the commit id of the commit I just made.&lt;br /&gt;
&lt;br /&gt;
===Step 4: Pushing your changes to your github account===&lt;br /&gt;
&lt;br /&gt;
Now that you have made changes to your local branch you should push it to your github account so that it can be reviewed and hopefully integrated into Moodle.&lt;br /&gt;
&lt;br /&gt;
Doing this is very simple just run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are telling git to push the branch wip-MDL-12345-master to the remote called github which we added when setting up our git repositories.&lt;br /&gt;
And just like that you&#039;ve made a branch that contains your work and pushed it to github ready to get it reviewed.&lt;br /&gt;
&lt;br /&gt;
==Moving your changes to another branch==&lt;br /&gt;
Now that you have made changes to the master branch you need to decide whether it is appropriate make those changes on any of the other branches.&lt;br /&gt;
Most likely if you are fixing a bug you will need to make the changes on the MOODLE_20_STABLE branch as well, and perhaps the MOODLE_19_STABLE branch if it is a security bug.&lt;br /&gt;
&lt;br /&gt;
Lets assume for MDL-12345 that I fixed earlier that it should be ported to MOODLE_20_STABLE as well.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local MOODLE_20_STABLE branch===&lt;br /&gt;
&lt;br /&gt;
To start with I need to move to the MOODLE_20_STABLE repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there I need to create a new branch based upon the MOODLE_20_STABLE branch that is going to contain my changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very similar to the branch we created for the changes to the master branch except that I have subsituted MOODLE_20_STABLE in place of master. This is because the new branch we are creating is based upon the MOODLE_20_STABLE branch on the offical Moodle git repository and contains changes for that branch.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Cherry-picking my changes===&lt;br /&gt;
Once we have a branch for our changes I am ready to make them again. There is however with git an easy way to do this, cherry-picking.&lt;br /&gt;
&lt;br /&gt;
Cherry-picking is the process of copying a single commit from one branch to another. In this case I want to cherry pick the commit I made earlier onto the branch I&#039;ve just created.&lt;br /&gt;
&lt;br /&gt;
However before I can do this I need to fetch the changes I made from the github repository. I need to do this because I made that changes of a totally separate local repository remember.&lt;br /&gt;
&lt;br /&gt;
So to update my repository with the latest changes I run the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command tells git to look at each remote and get any new changes (it also removes any branches that have been deleted).&lt;br /&gt;
Once it has completed you will be ready to cherry pick the commit. To do so you use the following command but replace my commit is with yours.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git cherry-pick 19a484e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Providing there are no conflicts your branch will now contain a copy of the changes you made to the master branch.&lt;br /&gt;
If there are conficts that you will need to resolve them and commit your changes however you can search for another tutorial about how to do that,&lt;br /&gt;
&lt;br /&gt;
Now I know at this point that there will be some of you who are saying &#039;Whoops I forgot what my commit id was!&#039;. If this is you don&#039;t worry, its pretty easy to find it providing you used a proper commit message like I described above.&lt;br /&gt;
Simply run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git log --oneline origin/master..github/wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the commits that are in the wip-MDL-12345-master at your github account but are not in the master branch at the offical Moodle repository.&lt;br /&gt;
You can then cherry-pick the commits shown there (the commit ID&#039;s should be highlighted in yellow).&lt;br /&gt;
&lt;br /&gt;
Once you have cherry-picked your commits its time to check that everything worked, run the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# On branch wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
# Your branch is ahead of &#039;origin/MOODLE_20_STABLE&#039; by 1 commit.&lt;br /&gt;
#&lt;br /&gt;
nothing to commit (working directory clean)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very handy as it tells you that your branch is ahead of the offical MOODLE_20_STABLE branch by one commit.&lt;br /&gt;
You can also check that your commit contains the changes you think by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git diff origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the changes you have made as a diff.&lt;br /&gt;
&lt;br /&gt;
Now that you know that your commit is there you and that it is correct it is time to push it to your github account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And thats it.&lt;br /&gt;
&lt;br /&gt;
You github account should now have two branches on it:&lt;br /&gt;
&lt;br /&gt;
; wip-MDL-12345-master : This branch is the changes you have made for the master branch&lt;br /&gt;
; wip-MDL-12345-MOODLE_20_STABLE : This branch is those same changes but for the MOODLE_20_STABLE branch&lt;br /&gt;
&lt;br /&gt;
Now you are ready to create PULL requests so that your work gets reviewed and hopefully integrated.&lt;br /&gt;
&lt;br /&gt;
==Creating a PULL request for the master branch==&lt;br /&gt;
&lt;br /&gt;
So you have successfully fixed the bug MDL-12345, you have created two branches one for master and one for MOODLE_20_STABLE. It is time to create a PULL request for each of these branches.&lt;br /&gt;
&lt;br /&gt;
First lets create a PULL request for the master branch:&lt;br /&gt;
&lt;br /&gt;
# Browse to tracker.moodle.org/browse/MDL-12345&lt;br /&gt;
# When the page loads log in if you haven&#039;t already.&lt;br /&gt;
# Click on the button in the top right labelled `Create issue`&lt;br /&gt;
# Change Project to `Pull Requests`&lt;br /&gt;
# Change Issue type to `Pull Request`&lt;br /&gt;
# Click create&lt;br /&gt;
&lt;br /&gt;
This takes you to a screen where you can enter the details for the PULL request.&lt;br /&gt;
&lt;br /&gt;
You should fill it out in the following way:&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
This is the summary for the PULL request, you should copy and paste the summary from the MDL issue here.&lt;br /&gt;
For MDL-12345 the summary is `alphabetization of UI different on left and right sides` so that&#039;s what I will use.&lt;br /&gt;
&lt;br /&gt;
===Affects Versions===&lt;br /&gt;
This is the version that your branch is changing, in the case of this PULL request I will select `master`.&lt;br /&gt;
&lt;br /&gt;
===Security level===&lt;br /&gt;
If the issue you are working on is a security issue you should set this to the same level that the issue is set to. If its not a security issue or you don&#039;t know just leave it as none.&lt;br /&gt;
&lt;br /&gt;
===Pull from repository===&lt;br /&gt;
This is the repository that the branch is at, for you this will be your github accont. If you head to http://github.com/yourname/moodle you will see a box that has three options SSH, HTTP, and Git read only, click Git Read Only and then copy the contents of the text box into the repositry field of the PULL request. &lt;br /&gt;
For me that is git://github.com/yourname/moodle.git&lt;br /&gt;
&lt;br /&gt;
===Pull branch===&lt;br /&gt;
This is the name of the branch that contains your changes. For me that is wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Pull Diff URL===&lt;br /&gt;
This is the URL to a page that shows the changes that you&#039;ve made on your branch. Github is nice in that it has a pretty interface for that. To get to the interface follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Browse to https://github.com/youraccount/moodle&lt;br /&gt;
# Click `Switch Branches` and then click on the branch you changes are based upon, in my case master.&lt;br /&gt;
# Click the button labelled `Branch List`&lt;br /&gt;
# Locate your branch in the list and click the `Compare button` for me this was the compare button to the right of wip-MDL-12345-master.&lt;br /&gt;
# Copy the URL in your browse and paste it into the Pull Diff URL of the PULL request.&lt;br /&gt;
&lt;br /&gt;
For me this URL was: https://github.com/yourname/moodle/compare/master...wip-MDL-23532-master&lt;br /&gt;
For the MOODLE_20_STABLE branch this would be: https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
&lt;br /&gt;
===Description===&lt;br /&gt;
The description should contain several bits of important information:&lt;br /&gt;
&lt;br /&gt;
# A short description of what your patch does&lt;br /&gt;
# Notes about that changes you&#039;ve made that might help the integrator understand what you did when he/she is reviewing it.&lt;br /&gt;
# Testing instructions that guide the testers through testing your changes.&lt;br /&gt;
&lt;br /&gt;
===Components===&lt;br /&gt;
Select general from the components list, general is the only option.&lt;br /&gt;
&lt;br /&gt;
===Finishing up===&lt;br /&gt;
Once you have filled in the fields as above click `Create`. This should create you PULL request and then take you to view it.&lt;br /&gt;
&lt;br /&gt;
Its important to remember that there is still one thing you need to do and that is link to the original issue.&lt;br /&gt;
While you are still logged in click the `More Actions` button and select `Link issue`, in the dialoug that pops up change the `This issue` field to `will help resolve`, type MDL-12345 into the issues field, and then type `Linking to MDL-12345` into the comments box. Once you&#039;ve done that simple click Link.&lt;br /&gt;
&lt;br /&gt;
Time to create the PULL request for the other branches.&lt;br /&gt;
&lt;br /&gt;
==Creating the PULL request for MOODLE_20_STABLE==&lt;br /&gt;
Once you&#039;ve created the PULL request for the master branch it is time to create the PULL request for the MOODLE_20_STABLE branch.&lt;br /&gt;
This is as easy as can be, click Create Issue in the top right, select PULL project and choose Pull Request and then click create.&lt;br /&gt;
On the next screen enter the following details:&lt;br /&gt;
&lt;br /&gt;
; Summary : Copy the summary from the previous PULL Request&lt;br /&gt;
; Affects Versions : Select MOODLE_20_STABLE&lt;br /&gt;
; Security level : Same as the MDL&lt;br /&gt;
; Pull from repository : Copy from the previous PULL request&lt;br /&gt;
; Pull Branch : wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
; Pull Diff URL : https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
; Description : Copy from the previous PULL request&lt;br /&gt;
; Component : general&lt;br /&gt;
&lt;br /&gt;
Then click create to create the PULL request.&lt;br /&gt;
&lt;br /&gt;
Once the PULL request has been create don&#039;t forget to link to the MDL issue like we did for the previous PULL request.&lt;br /&gt;
&lt;br /&gt;
==Rebasing after the weekly release==&lt;br /&gt;
As many of you will be aware on Wednesday after the latest weekly has been released a comment will be added to all PULL requests that are still open.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The main moodle.git repository has just been updated with latest weekly modifications. You may wish to rebase your PULL branches to simplify history and avoid any possible merge conflicts. This would also make integrator&#039;s life easier next week.&lt;br /&gt;
&lt;br /&gt;
TIA and ciao :)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is a message that is bulk added as is done so as a polite request. While it&#039;s not essential for you to rebase your work it really does help the integrators as its much easier to see what is going on and greatly reduces the chance of conflicts (because you&#039;ll solve them when you rebase).&lt;br /&gt;
&lt;br /&gt;
The good news is that rebasing your work is EASY!&lt;br /&gt;
&lt;br /&gt;
For the following example lets assume I created the two PULL requests above on Wednesday morning and the weekly was released on Wednesday afternoon. This means that my branch doesn&#039;t have the changes that have just been released and I need to rebase them.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Rebasing the wip-MDL-12345-master===&lt;br /&gt;
&lt;br /&gt;
The first step is to rebase my work that is based upon the master branch. So first move to the master repository.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next thing we have to do is get all of the changes from the remote repositories, this will fetch down all of the latest changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now before the next step make sure that you don&#039;t have any uncommit changes, if you do finish that work, commit it, then proceed to the next step which is updating your local master.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
git push master github&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that your local master is up to date, and has you&#039;ve updated you master branch at github you are ready to rebase!&lt;br /&gt;
At this point we want to checkout the branch we are going to rebase, in this case wip-MDL-12345-master and then we are going to rebase origin/master which is the official Moodle master branch (and the branch our branch is based upon).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout wip-MDL-12345-master&lt;br /&gt;
git rebase origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that command has completed your branch wip-MDL-12345-master will be completely up to date. Before you are done however you need to push the rebased wip-MDL-12345-master up to your github account so that its the branch the integrator sees.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push -f github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that command is just about identical to the command we used when we first pushed our branch to our github account, there is however one VERY important difference, the &#039;&#039;&#039;-f&#039;&#039;&#039; option.&lt;br /&gt;
The &#039;&#039;&#039;-f&#039;&#039;&#039; option tells git to force the push, this is required because when you rebase all of your commit id&#039;s will change and unless you tell git to force it will see that they have changed and not allow you to push your work.&lt;br /&gt;
&lt;br /&gt;
Thats it! you&#039;ve now rebased your work and the integrators will be happy again :)&lt;br /&gt;
&lt;br /&gt;
===Step 2: Rebasing wip-MDL-12345-MOODLE_20_STABLE===&lt;br /&gt;
Now that we&#039;ve rebased our work that was based upon the master branch it is time to rebase the MOODLE_20_STABLE version.&lt;br /&gt;
This step is just about identical to the previous step except we substitute &#039;&#039;master&#039;&#039; for &#039;&#039;MOODLE_20_STABLE&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github MOODLE_20_STABLE&lt;br /&gt;
git checkout wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
git rebase origin/MOODLE_20_STABLE&lt;br /&gt;
git push -f github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&lt;br /&gt;
==Useful links==&lt;br /&gt;
The following are links I found useful while learning Git.&lt;br /&gt;
&lt;br /&gt;
* [http://help.github.com Github help (http://help.github.com)] Provides EXCELLENT help tutorials that very clearly explain the basic through to the advanced.&lt;br /&gt;
* [http://cheat.errtheblog.com/s/git/ $ cheat git] This is my favourite cheat sheet, straight forward to the point, if you know the concept you&#039;ll find the answer here.&lt;br /&gt;
* [http://gitster.livejournal.com/28309.html Gitsters journal - Fun with FETCH_HEAD] David Mudrak pointed me at this entry which I found INCREDIBLY useful when reviewing other peoples work.&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82867</id>
		<title>User:Sam Hemelryk/My Moodle Git workflow</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82867"/>
		<updated>2011-04-19T01:35:42Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document is a sort of tutorial/inspection of my personal development workflow when working on Moodle with Git.&lt;br /&gt;
&lt;br /&gt;
==Creating the repositories==&lt;br /&gt;
Ok so the very first step is to create several Moodle git repositories, one for each major branch of Moodle being worked on.&lt;br /&gt;
&lt;br /&gt;
At the time of writing the major branches are MOODLE_19_STABLE, MOODLE_20_STABLE and master.&lt;br /&gt;
&lt;br /&gt;
The reason for this is that that way we have a separate site for each Moodle branch that we can test on easily. Yes you will have three sites but you won&#039;t have to worry about swtiching your site when you change branches.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Create a directory to create the repositories within===&lt;br /&gt;
&lt;br /&gt;
Personally I use Ubuntu (Linux) and I chose to create my repositories within a folder I created in /var/www. If you are using windows I would instead suggest creating C:/www/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www&lt;br /&gt;
mkdir repositories&lt;br /&gt;
cd repositories&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 2: Create a master repository===&lt;br /&gt;
This is the easiest of the branches to create a repository for.&lt;br /&gt;
&lt;br /&gt;
Within your repositories directory create a new directory called master and move into it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir master&lt;br /&gt;
cd master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we want to clone the Moodle source from the offical Moodle git repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new directory called moodle within the master directory we created just before.&lt;br /&gt;
&lt;br /&gt;
That new moodle directory should contain the Moodle source code as a git repository.&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our main git repository we need to add our github account as a remote so that we can push to it later:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd moodle&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This adds your moodle repository on github as a remote called github that you can push to later.&lt;br /&gt;
&lt;br /&gt;
Finally before we move onto the next repository we need to create a data directory because we know we will need that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 3: Create a MOODLE_20_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
The next repository we create will be for the MOODLE_20_STABLE branch.&lt;br /&gt;
To start with get back to the repositories directory that we created earlier and create a directory called MOODLE_20_STABLE within that.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_20_STABLE&lt;br /&gt;
cd MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now create a new clone of the main Moodle repository like we did for the master branch above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have done that move into the moodle directory.&lt;br /&gt;
&lt;br /&gt;
By default the master branch is the branch that is created, however we don&#039;t want that for this repository. Instead we want the MOODLE_20_STABLE branch.&lt;br /&gt;
&lt;br /&gt;
To do this we checkout local branch based upon the official MOODLE_20_STABLE branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have created that branch we can delete the local master branch so that we don&#039;t accidentally ever work on it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git branch -D master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then like we did for master we add our github repository as a remote:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And finally create a data directory we can use when we have install the site:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 4: Create a MOODLE_19_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
This step is identical to the above step except we are using the MOODLE_19_STABLE branch instead of the MOODLE_20_STABLE branch.&lt;br /&gt;
The commands for this are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_19_STABLE&lt;br /&gt;
cd MOODLE_19_STABLE&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
git checkout -b MOODLE_19_STABLE origin/MOODLE_19_STABLE&lt;br /&gt;
git branch -D master&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 5: Install the sites===&lt;br /&gt;
Now I can&#039;t tell you how to do this on your own machine however what I would recommend is that you create a link from your web root to the moodle directory of each branch.&lt;br /&gt;
&lt;br /&gt;
If you are using linux and your webroot is /var/www/localhost you would do it as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/localhost/&lt;br /&gt;
ln -s /var/www/repositories/master/moodle master&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_20_STABLE/moodle MOODLE_20_STABLE&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_19_STABLE/moodle MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done you should be able to browse to each repository with the following URL&#039;s&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://localhost/master/&lt;br /&gt;
http://localhost/MOODLE_20_STABLE/&lt;br /&gt;
http://localhost/MOODLE_19_STABLE/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that is done you need to browse to each site and complete the installation.&lt;br /&gt;
&lt;br /&gt;
Under this method your will need to ensure you set the configuration option sessioncookiepath to the URI of your site. You can either do this in the admin interfaces or add the following to your config.php file for each site.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// For the master site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/master/&#039;;&lt;br /&gt;
// For the MOODLE_20_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_20_STABLE/&#039;;&lt;br /&gt;
// For the MOODLE_19_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_19_STABLE/&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Failure to do this will mean that when you log in at one site and then visit the next you will have to log in again and your session on the first site will no longer work.&lt;br /&gt;
&lt;br /&gt;
Now that you have got 3 repositories, one for each main branch, and set up a site for each you are ready to start development.&lt;br /&gt;
&lt;br /&gt;
==Before you start work each day==&lt;br /&gt;
Before you start work each day you should update each of the repositories you have created to ensure that you are always working with up to date versions of Moodle.&lt;br /&gt;
&lt;br /&gt;
You should also take this opportunity to update the repositories on your github account to ensure they are always up to date.&lt;br /&gt;
&lt;br /&gt;
To start with lets update the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This moves to the master repository and then tells git for fetch all of the changes from your remote repositories and clean up any old branches it is aware of.&lt;br /&gt;
&lt;br /&gt;
Once that operation has completed you should update your master branch&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Before you do that it pays to make sure you don&#039;t have any uncommit changes, if you do DON&#039;T TRY IT. There would be a good chance you will encounter problems. Instead finish what you are working on, commit your changes and then update your master branch.&lt;br /&gt;
&lt;br /&gt;
Next we will update the github repositories by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github refs/remotes/origin/master:master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This tells git to push the master branch from origin (the offical Moodle repository) to the master branch on our github account.&lt;br /&gt;
&lt;br /&gt;
Now that you&#039;ve updated the master repository and your github account its time to update the MOODLE_20_STABLE and MOODLE_19_STABLE branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_20_STABLE:MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_19_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_19_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_19_STABLE:MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Working on a Moodle issue==&lt;br /&gt;
&lt;br /&gt;
This part of the document looks at how I go about working on an MDL issue from the Moodle tracker.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ we use the scrum methodology we sees us choose several issues to include in a scrum which we then work on for the period of the scrum. As a community member its more likely you will just be choosing issues that you are passionate about.&lt;br /&gt;
&lt;br /&gt;
Either way once you have found an issue to work on you are ready to start.&lt;br /&gt;
&lt;br /&gt;
For the purpose of this part of the document lets say I am going to work on bug MDL-12345.&lt;br /&gt;
&lt;br /&gt;
==Fixing a bug on the master repository - MDL-12345==&lt;br /&gt;
&lt;br /&gt;
The first step is to create a local branch to make changes on, to do this we will start our work on the master repository.&lt;br /&gt;
&lt;br /&gt;
When fixing an issue I find it easiest to fix the issue on the master branch first and then move my changes to the other branches.&lt;br /&gt;
&lt;br /&gt;
The VERY first thing you should do when you start working on a Moodle issue is make sure you have assigned it to yourself and then click the start progress button.&lt;br /&gt;
&lt;br /&gt;
This way other users know that you are activly working on the bug and no one from HQ will steal it from you.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local branch===&lt;br /&gt;
&lt;br /&gt;
So first get to the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there we create a new branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-master origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command checks out a new branch called wip-MDL-12345-master that is based upon origin/master.&lt;br /&gt;
&lt;br /&gt;
origin/master is of course the master branch on the official Moodle repository (git.moodle.org/moodle.git).&lt;br /&gt;
&lt;br /&gt;
The name of the branch is also very important. It is essentially telling us three things.&lt;br /&gt;
&lt;br /&gt;
; wip : This stands for work in progress, it helps people see that you are currently working on this branch and that they shouldn&#039;t base there work on it because it will likely change.&lt;br /&gt;
; MDL-12345 : This is of course the Moodle bug number. It helps people quickly identify what you are working on.&lt;br /&gt;
; master : This is the branch we are making changes on. It helps people quickly understand where the changes are being made.&lt;br /&gt;
&lt;br /&gt;
You can optionally add more to the end of the branch name such as a key word that identifies the area or a date at which you started work e.g.&lt;br /&gt;
&lt;br /&gt;
* wip-MDL-12345-master-navigation-changes&lt;br /&gt;
* wip-MDL-12345-master-20110418&lt;br /&gt;
&lt;br /&gt;
That is up to you, personally I&#039;m not a fan of it, however the rest is all required to help integrate your work.&lt;br /&gt;
&lt;br /&gt;
Either way now you have a branch, mine is called wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Make changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have created you branch you are ready to make changes.&lt;br /&gt;
&lt;br /&gt;
I&#039;ll let you make whatever changes you are need, once you have made changes move onto the next step.&lt;br /&gt;
&lt;br /&gt;
Before you do move on however make sure that your code meets the high quality of code Moodle requires.&lt;br /&gt;
&lt;br /&gt;
You can find information about that on the moodle docs here: https://docs.moodle.org/en/Development:Coding_style&lt;br /&gt;
&lt;br /&gt;
The following are common mistakes:&lt;br /&gt;
&lt;br /&gt;
* Incorrect white space&lt;br /&gt;
** Tabs instead of spaces&lt;br /&gt;
** Extra spaces at the end of lines&lt;br /&gt;
** Multiple new lines&lt;br /&gt;
** Forgetting to put spaces between function arguments&lt;br /&gt;
* Incorrect commit messages (read on to find out about writing a good commit message)&lt;br /&gt;
* Incorrect variable or function names&lt;br /&gt;
&lt;br /&gt;
Making these sort of mistakes can lead to your code being rejected despite it working correctly.&lt;br /&gt;
&lt;br /&gt;
Or course it will be reviewed in regards to security, usability and the other important factors of code development.&lt;br /&gt;
&lt;br /&gt;
===Step 3: Commit your changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have made your changes you are getting ready to commit them.&lt;br /&gt;
&lt;br /&gt;
The first thing to do is check your changes. To do this run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see all of the files you have changes highlighted in red.&lt;br /&gt;
&lt;br /&gt;
Next you need to stage all of the files you want to commit.&lt;br /&gt;
&lt;br /&gt;
To do this you add the files to the stage using the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git add lib/modifiedfile.php&lt;br /&gt;
git add lib/newfile.php&lt;br /&gt;
git add theme/base/style/core.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Why not just commit all changes. Many of the git guides you read will tell you above git commit -a which commits all of the changes you have made.&lt;br /&gt;
&lt;br /&gt;
We&#039;ve hardly being using git here at Moodle and already I&#039;ve seen several people accidentally commit changes that they didn&#039;t mean to.&lt;br /&gt;
&lt;br /&gt;
Staging files like this ENSURES you only commit things you intend to.&lt;br /&gt;
&lt;br /&gt;
Now that you have staged your changes/new files you are ready to commit. The following command commits your changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git commit -m &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command commits your changes with the commit message &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;.&lt;br /&gt;
It&#039;s very important to Moodle that you format your commit messages like this.&lt;br /&gt;
They consist of three parts:&lt;br /&gt;
&lt;br /&gt;
# The MDL bug number in this case MDL-12345&lt;br /&gt;
# The area you made changes to in this case enrol&lt;br /&gt;
# A short description of what you did, in this case I fixed a couple of enrolment bugs.&lt;br /&gt;
&lt;br /&gt;
When you commit your message you will see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[master 19a484e] changes&lt;br /&gt;
 1 files changed, 16 insertions(+), 18 deletions(-)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
There is one thing here you need to note down for later, that is the number that appears within the square brackets after the branch name, in my case it is 19a484e. This is the commit id of the commit I just made.&lt;br /&gt;
&lt;br /&gt;
===Step 4: Pushing your changes to your github account===&lt;br /&gt;
&lt;br /&gt;
Now that you have made changes to your local branch you should push it to your github account so that it can be reviewed and hopefully integrated into Moodle.&lt;br /&gt;
&lt;br /&gt;
Doing this is very simple just run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are telling git to push the branch wip-MDL-12345-master to the remote called github which we added when setting up our git repositories.&lt;br /&gt;
And just like that you&#039;ve made a branch that contains your work and pushed it to github ready to get it reviewed.&lt;br /&gt;
&lt;br /&gt;
==Moving your changes to another branch==&lt;br /&gt;
Now that you have made changes to the master branch you need to decide whether it is appropriate make those changes on any of the other branches.&lt;br /&gt;
Most likely if you are fixing a bug you will need to make the changes on the MOODLE_20_STABLE branch as well, and perhaps the MOODLE_19_STABLE branch if it is a security bug.&lt;br /&gt;
&lt;br /&gt;
Lets assume for MDL-12345 that I fixed earlier that it should be ported to MOODLE_20_STABLE as well.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local MOODLE_20_STABLE branch===&lt;br /&gt;
&lt;br /&gt;
To start with I need to move to the MOODLE_20_STABLE repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there I need to create a new branch based upon the MOODLE_20_STABLE branch that is going to contain my changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very similar to the branch we created for the changes to the master branch except that I have subsituted MOODLE_20_STABLE in place of master. This is because the new branch we are creating is based upon the MOODLE_20_STABLE branch on the offical Moodle git repository and contains changes for that branch.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Cherry-picking my changes===&lt;br /&gt;
Once we have a branch for our changes I am ready to make them again. There is however with git an easy way to do this, cherry-picking.&lt;br /&gt;
&lt;br /&gt;
Cherry-picking is the process of copying a single commit from one branch to another. In this case I want to cherry pick the commit I made earlier onto the branch I&#039;ve just created.&lt;br /&gt;
&lt;br /&gt;
However before I can do this I need to fetch the changes I made from the github repository. I need to do this because I made that changes of a totally separate local repository remember.&lt;br /&gt;
&lt;br /&gt;
So to update my repository with the latest changes I run the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command tells git to look at each remote and get any new changes (it also removes any branches that have been deleted).&lt;br /&gt;
Once it has completed you will be ready to cherry pick the commit. To do so you use the following command but replace my commit is with yours.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git cherry-pick 19a484e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Providing there are no conflicts your branch will now contain a copy of the changes you made to the master branch.&lt;br /&gt;
If there are conficts that you will need to resolve them and commit your changes however you can search for another tutorial about how to do that,&lt;br /&gt;
&lt;br /&gt;
Now I know at this point that there will be some of you who are saying &#039;Whoops I forgot what my commit id was!&#039;. If this is you don&#039;t worry, its pretty easy to find it providing you used a proper commit message like I described above.&lt;br /&gt;
Simply run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git log --oneline origin/master..github/wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the commits that are in the wip-MDL-12345-master at your github account but are not in the master branch at the offical Moodle repository.&lt;br /&gt;
You can then cherry-pick the commits shown there (the commit ID&#039;s should be highlighted in yellow).&lt;br /&gt;
&lt;br /&gt;
Once you have cherry-picked your commits its time to check that everything worked, run the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# On branch wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
# Your branch is ahead of &#039;origin/MOODLE_20_STABLE&#039; by 1 commit.&lt;br /&gt;
#&lt;br /&gt;
nothing to commit (working directory clean)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very handy as it tells you that your branch is ahead of the offical MOODLE_20_STABLE branch by one commit.&lt;br /&gt;
You can also check that your commit contains the changes you think by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git diff origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the changes you have made as a diff.&lt;br /&gt;
&lt;br /&gt;
Now that you know that your commit is there you and that it is correct it is time to push it to your github account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And thats it.&lt;br /&gt;
&lt;br /&gt;
You github account should now have two branches on it:&lt;br /&gt;
&lt;br /&gt;
; wip-MDL-12345-master : This branch is the changes you have made for the master branch&lt;br /&gt;
; wip-MDL-12345-MOODLE_20_STABLE : This branch is those same changes but for the MOODLE_20_STABLE branch&lt;br /&gt;
&lt;br /&gt;
Now you are ready to create PULL requests so that your work gets reviewed and hopefully integrated.&lt;br /&gt;
&lt;br /&gt;
==Creating a PULL request for the master branch==&lt;br /&gt;
&lt;br /&gt;
So you have successfully fixed the bug MDL-12345, you have created two branches one for master and one for MOODLE_20_STABLE. It is time to create a PULL request for each of these branches.&lt;br /&gt;
&lt;br /&gt;
First lets create a PULL request for the master branch:&lt;br /&gt;
&lt;br /&gt;
# Browse to tracker.moodle.org/browse/MDL-12345&lt;br /&gt;
# When the page loads log in if you haven&#039;t already.&lt;br /&gt;
# Click on the button in the top right labelled `Create issue`&lt;br /&gt;
# Change Project to `Pull Requests`&lt;br /&gt;
# Change Issue type to `Pull Request`&lt;br /&gt;
# Click create&lt;br /&gt;
&lt;br /&gt;
This takes you to a screen where you can enter the details for the PULL request.&lt;br /&gt;
&lt;br /&gt;
You should fill it out in the following way:&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
This is the summary for the PULL request, you should copy and paste the summary from the MDL issue here.&lt;br /&gt;
For MDL-12345 the summary is `alphabetization of UI different on left and right sides` so that&#039;s what I will use.&lt;br /&gt;
&lt;br /&gt;
===Affects Versions===&lt;br /&gt;
This is the version that your branch is changing, in the case of this PULL request I will select `master`.&lt;br /&gt;
&lt;br /&gt;
===Security level===&lt;br /&gt;
If the issue you are working on is a security issue you should set this to the same level that the issue is set to. If its not a security issue or you don&#039;t know just leave it as none.&lt;br /&gt;
&lt;br /&gt;
===Pull from repository===&lt;br /&gt;
This is the repository that the branch is at, for you this will be your github accont. If you head to http://github.com/yourname/moodle you will see a box that has three options SSH, HTTP, and Git read only, click Git Read Only and then copy the contents of the text box into the repositry field of the PULL request. &lt;br /&gt;
For me that is git://github.com/yourname/moodle.git&lt;br /&gt;
&lt;br /&gt;
===Pull branch===&lt;br /&gt;
This is the name of the branch that contains your changes. For me that is wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Pull Diff URL===&lt;br /&gt;
This is the URL to a page that shows the changes that you&#039;ve made on your branch. Github is nice in that it has a pretty interface for that. To get to the interface follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Browse to https://github.com/youraccount/moodle&lt;br /&gt;
# Click `Switch Branches` and then click on the branch you changes are based upon, in my case master.&lt;br /&gt;
# Click the button labelled `Branch List`&lt;br /&gt;
# Locate your branch in the list and click the `Compare button` for me this was the compare button to the right of wip-MDL-12345-master.&lt;br /&gt;
# Copy the URL in your browse and paste it into the Pull Diff URL of the PULL request.&lt;br /&gt;
&lt;br /&gt;
For me this URL was: https://github.com/yourname/moodle/compare/master...wip-MDL-23532-master&lt;br /&gt;
For the MOODLE_20_STABLE branch this would be: https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
&lt;br /&gt;
===Description===&lt;br /&gt;
The description should contain several bits of important information:&lt;br /&gt;
&lt;br /&gt;
# A short description of what your patch does&lt;br /&gt;
# Notes about that changes you&#039;ve made that might help the integrator understand what you did when he/she is reviewing it.&lt;br /&gt;
# Testing instructions that guide the testers through testing your changes.&lt;br /&gt;
&lt;br /&gt;
===Components===&lt;br /&gt;
Select general from the components list, general is the only option.&lt;br /&gt;
&lt;br /&gt;
===Finishing up===&lt;br /&gt;
Once you have filled in the fields as above click `Create`. This should create you PULL request and then take you to view it.&lt;br /&gt;
&lt;br /&gt;
Its important to remember that there is still one thing you need to do and that is link to the original issue.&lt;br /&gt;
While you are still logged in click the `More Actions` button and select `Link issue`, in the dialoug that pops up change the `This issue` field to `will help resolve`, type MDL-12345 into the issues field, and then type `Linking to MDL-12345` into the comments box. Once you&#039;ve done that simple click Link.&lt;br /&gt;
&lt;br /&gt;
Time to create the PULL request for the other branches.&lt;br /&gt;
&lt;br /&gt;
==Creating the PULL request for MOODLE_20_STABLE==&lt;br /&gt;
Once you&#039;ve created the PULL request for the master branch it is time to create the PULL request for the MOODLE_20_STABLE branch.&lt;br /&gt;
This is as easy as can be, click Create Issue in the top right, select PULL project and choose Pull Request and then click create.&lt;br /&gt;
On the next screen enter the following details:&lt;br /&gt;
&lt;br /&gt;
; Summary : Copy the summary from the previous PULL Request&lt;br /&gt;
; Affects Versions : Select MOODLE_20_STABLE&lt;br /&gt;
; Security level : Same as the MDL&lt;br /&gt;
; Pull from repository : Copy from the previous PULL request&lt;br /&gt;
; Pull Branch : wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
; Pull Diff URL : https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
; Description : Copy from the previous PULL request&lt;br /&gt;
; Component : general&lt;br /&gt;
&lt;br /&gt;
Then click create to create the PULL request.&lt;br /&gt;
&lt;br /&gt;
Once the PULL request has been create don&#039;t forget to link to the MDL issue like we did for the previous PULL request.&lt;br /&gt;
&lt;br /&gt;
==Rebasing after the weekly release==&lt;br /&gt;
As many of you will be aware on Wednesday after the latest weekly has been released a comment will be added to all PULL requests that are still open.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The main moodle.git repository has just been updated with latest weekly modifications. You may wish to rebase your PULL branches to simplify history and avoid any possible merge conflicts. This would also make integrator&#039;s life easier next week.&lt;br /&gt;
&lt;br /&gt;
TIA and ciao :)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is a message that is bulk added as is done so as a polite request. While it&#039;s not essential for you to rebase your work it really does help the integrators as its much easier to see what is going on and greatly reduces the chance of conflicts (because you&#039;ll solve them when you rebase).&lt;br /&gt;
&lt;br /&gt;
The good news is that rebasing your work is EASY!&lt;br /&gt;
&lt;br /&gt;
For the following example lets assume I created the two PULL requests above on Wednesday morning and the weekly was released on Wednesday afternoon. This means that my branch doesn&#039;t have the changes that have just been released and I need to rebase them.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Rebasing the wip-MDL-12345-master===&lt;br /&gt;
&lt;br /&gt;
The first step is to rebase my work that is based upon the master branch. So first move to the master repository.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next thing we have to do is get all of the changes from the remote repositories, this will fetch down all of the latest changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now before the next step make sure that you don&#039;t have any uncommit changes, if you do finish that work, commit it, then proceed to the next step which is updating your local master.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
git push master github&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that your local master is up to date, and has you&#039;ve updated you master branch at github you are ready to rebase!&lt;br /&gt;
At this point we want to checkout the branch we are going to rebase, in this case wip-MDL-12345-master and then we are going to rebase origin/master which is the official Moodle master branch (and the branch our branch is based upon).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout wip-MDL-12345-master&lt;br /&gt;
git rebase origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that command has completed your branch wip-MDL-12345-master will be completely up to date. Before you are done however you need to push the rebased wip-MDL-12345-master up to your github account so that its the branch the integrator sees.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push -f github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that command is just about identical to the command we used when we first pushed our branch to our github account, there is however one VERY important difference, the &#039;&#039;&#039;-f&#039;&#039;&#039; option.&lt;br /&gt;
The &#039;&#039;&#039;-f&#039;&#039;&#039; option tells git to force the push, this is required because when you rebase all of your commit id&#039;s will change and unless you tell git to force it will see that they have changed and not allow you to push your work.&lt;br /&gt;
&lt;br /&gt;
Thats it! you&#039;ve now rebased your work and the integrators will be happy again :)&lt;br /&gt;
&lt;br /&gt;
===Step 2: Rebasing wip-MDL-12345-MOODLE_20_STABLE===&lt;br /&gt;
Now that we&#039;ve rebased our work that was based upon the master branch it is time to rebase the MOODLE_20_STABLE version.&lt;br /&gt;
This step is just about identical to the previous step except we substitute &#039;&#039;master&#039;&#039; for &#039;&#039;MOODLE_20_STABLE&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github MOODLE_20_STABLE&lt;br /&gt;
git checkout wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
git rebase origin/MOODLE_20_STABLE&lt;br /&gt;
git push -f github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Done!&lt;br /&gt;
&lt;br /&gt;
==Useful links==&lt;br /&gt;
The following are links I found useful while learning Git.&lt;br /&gt;
&lt;br /&gt;
* [[http://help.github.com Github help]]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82866</id>
		<title>User:Sam Hemelryk/My Moodle Git workflow</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82866"/>
		<updated>2011-04-19T01:33:23Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document is a sort of tutorial/inspection of my personal development workflow when working on Moodle with Git.&lt;br /&gt;
&lt;br /&gt;
==Creating the repositories==&lt;br /&gt;
Ok so the very first step is to create several Moodle git repositories, one for each major branch of Moodle being worked on.&lt;br /&gt;
&lt;br /&gt;
At the time of writing the major branches are MOODLE_19_STABLE, MOODLE_20_STABLE and master.&lt;br /&gt;
&lt;br /&gt;
The reason for this is that that way we have a separate site for each Moodle branch that we can test on easily. Yes you will have three sites but you won&#039;t have to worry about swtiching your site when you change branches.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Create a directory to create the repositories within===&lt;br /&gt;
&lt;br /&gt;
Personally I use Ubuntu (Linux) and I chose to create my repositories within a folder I created in /var/www. If you are using windows I would instead suggest creating C:/www/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www&lt;br /&gt;
mkdir repositories&lt;br /&gt;
cd repositories&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 2: Create a master repository===&lt;br /&gt;
This is the easiest of the branches to create a repository for.&lt;br /&gt;
&lt;br /&gt;
Within your repositories directory create a new directory called master and move into it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir master&lt;br /&gt;
cd master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we want to clone the Moodle source from the offical Moodle git repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new directory called moodle within the master directory we created just before.&lt;br /&gt;
&lt;br /&gt;
That new moodle directory should contain the Moodle source code as a git repository.&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our main git repository we need to add our github account as a remote so that we can push to it later:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd moodle&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This adds your moodle repository on github as a remote called github that you can push to later.&lt;br /&gt;
&lt;br /&gt;
Finally before we move onto the next repository we need to create a data directory because we know we will need that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 3: Create a MOODLE_20_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
The next repository we create will be for the MOODLE_20_STABLE branch.&lt;br /&gt;
To start with get back to the repositories directory that we created earlier and create a directory called MOODLE_20_STABLE within that.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_20_STABLE&lt;br /&gt;
cd MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now create a new clone of the main Moodle repository like we did for the master branch above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have done that move into the moodle directory.&lt;br /&gt;
&lt;br /&gt;
By default the master branch is the branch that is created, however we don&#039;t want that for this repository. Instead we want the MOODLE_20_STABLE branch.&lt;br /&gt;
&lt;br /&gt;
To do this we checkout local branch based upon the official MOODLE_20_STABLE branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have created that branch we can delete the local master branch so that we don&#039;t accidentally ever work on it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git branch -D master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then like we did for master we add our github repository as a remote:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And finally create a data directory we can use when we have install the site:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 4: Create a MOODLE_19_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
This step is identical to the above step except we are using the MOODLE_19_STABLE branch instead of the MOODLE_20_STABLE branch.&lt;br /&gt;
The commands for this are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_19_STABLE&lt;br /&gt;
cd MOODLE_19_STABLE&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
git checkout -b MOODLE_19_STABLE origin/MOODLE_19_STABLE&lt;br /&gt;
git branch -D master&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 5: Install the sites===&lt;br /&gt;
Now I can&#039;t tell you how to do this on your own machine however what I would recommend is that you create a link from your web root to the moodle directory of each branch.&lt;br /&gt;
&lt;br /&gt;
If you are using linux and your webroot is /var/www/localhost you would do it as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/localhost/&lt;br /&gt;
ln -s /var/www/repositories/master/moodle master&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_20_STABLE/moodle MOODLE_20_STABLE&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_19_STABLE/moodle MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done you should be able to browse to each repository with the following URL&#039;s&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://localhost/master/&lt;br /&gt;
http://localhost/MOODLE_20_STABLE/&lt;br /&gt;
http://localhost/MOODLE_19_STABLE/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that is done you need to browse to each site and complete the installation.&lt;br /&gt;
&lt;br /&gt;
Under this method your will need to ensure you set the configuration option sessioncookiepath to the URI of your site. You can either do this in the admin interfaces or add the following to your config.php file for each site.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// For the master site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/master/&#039;;&lt;br /&gt;
// For the MOODLE_20_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_20_STABLE/&#039;;&lt;br /&gt;
// For the MOODLE_19_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_19_STABLE/&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Failure to do this will mean that when you log in at one site and then visit the next you will have to log in again and your session on the first site will no longer work.&lt;br /&gt;
&lt;br /&gt;
Now that you have got 3 repositories, one for each main branch, and set up a site for each you are ready to start development.&lt;br /&gt;
&lt;br /&gt;
==Before you start work each day==&lt;br /&gt;
Before you start work each day you should update each of the repositories you have created to ensure that you are always working with up to date versions of Moodle.&lt;br /&gt;
&lt;br /&gt;
You should also take this opportunity to update the repositories on your github account to ensure they are always up to date.&lt;br /&gt;
&lt;br /&gt;
To start with lets update the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This moves to the master repository and then tells git for fetch all of the changes from your remote repositories and clean up any old branches it is aware of.&lt;br /&gt;
&lt;br /&gt;
Once that operation has completed you should update your master branch&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Before you do that it pays to make sure you don&#039;t have any uncommit changes, if you do DON&#039;T TRY IT. There would be a good chance you will encounter problems. Instead finish what you are working on, commit your changes and then update your master branch.&lt;br /&gt;
&lt;br /&gt;
Next we will update the github repositories by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github refs/remotes/origin/master:master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This tells git to push the master branch from origin (the offical Moodle repository) to the master branch on our github account.&lt;br /&gt;
&lt;br /&gt;
Now that you&#039;ve updated the master repository and your github account its time to update the MOODLE_20_STABLE and MOODLE_19_STABLE branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_20_STABLE:MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_19_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_19_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_19_STABLE:MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Working on a Moodle issue==&lt;br /&gt;
&lt;br /&gt;
This part of the document looks at how I go about working on an MDL issue from the Moodle tracker.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ we use the scrum methodology we sees us choose several issues to include in a scrum which we then work on for the period of the scrum. As a community member its more likely you will just be choosing issues that you are passionate about.&lt;br /&gt;
&lt;br /&gt;
Either way once you have found an issue to work on you are ready to start.&lt;br /&gt;
&lt;br /&gt;
For the purpose of this part of the document lets say I am going to work on bug MDL-12345.&lt;br /&gt;
&lt;br /&gt;
==Fixing a bug on the master repository - MDL-12345==&lt;br /&gt;
&lt;br /&gt;
The first step is to create a local branch to make changes on, to do this we will start our work on the master repository.&lt;br /&gt;
&lt;br /&gt;
When fixing an issue I find it easiest to fix the issue on the master branch first and then move my changes to the other branches.&lt;br /&gt;
&lt;br /&gt;
The VERY first thing you should do when you start working on a Moodle issue is make sure you have assigned it to yourself and then click the start progress button.&lt;br /&gt;
&lt;br /&gt;
This way other users know that you are activly working on the bug and no one from HQ will steal it from you.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local branch===&lt;br /&gt;
&lt;br /&gt;
So first get to the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there we create a new branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-master origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command checks out a new branch called wip-MDL-12345-master that is based upon origin/master.&lt;br /&gt;
&lt;br /&gt;
origin/master is of course the master branch on the official Moodle repository (git.moodle.org/moodle.git).&lt;br /&gt;
&lt;br /&gt;
The name of the branch is also very important. It is essentially telling us three things.&lt;br /&gt;
&lt;br /&gt;
; wip : This stands for work in progress, it helps people see that you are currently working on this branch and that they shouldn&#039;t base there work on it because it will likely change.&lt;br /&gt;
; MDL-12345 : This is of course the Moodle bug number. It helps people quickly identify what you are working on.&lt;br /&gt;
; master : This is the branch we are making changes on. It helps people quickly understand where the changes are being made.&lt;br /&gt;
&lt;br /&gt;
You can optionally add more to the end of the branch name such as a key word that identifies the area or a date at which you started work e.g.&lt;br /&gt;
&lt;br /&gt;
* wip-MDL-12345-master-navigation-changes&lt;br /&gt;
* wip-MDL-12345-master-20110418&lt;br /&gt;
&lt;br /&gt;
That is up to you, personally I&#039;m not a fan of it, however the rest is all required to help integrate your work.&lt;br /&gt;
&lt;br /&gt;
Either way now you have a branch, mine is called wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Make changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have created you branch you are ready to make changes.&lt;br /&gt;
&lt;br /&gt;
I&#039;ll let you make whatever changes you are need, once you have made changes move onto the next step.&lt;br /&gt;
&lt;br /&gt;
Before you do move on however make sure that your code meets the high quality of code Moodle requires.&lt;br /&gt;
&lt;br /&gt;
You can find information about that on the moodle docs here: https://docs.moodle.org/en/Development:Coding_style&lt;br /&gt;
&lt;br /&gt;
The following are common mistakes:&lt;br /&gt;
&lt;br /&gt;
* Incorrect white space&lt;br /&gt;
** Tabs instead of spaces&lt;br /&gt;
** Extra spaces at the end of lines&lt;br /&gt;
** Multiple new lines&lt;br /&gt;
** Forgetting to put spaces between function arguments&lt;br /&gt;
* Incorrect commit messages (read on to find out about writing a good commit message)&lt;br /&gt;
* Incorrect variable or function names&lt;br /&gt;
&lt;br /&gt;
Making these sort of mistakes can lead to your code being rejected despite it working correctly.&lt;br /&gt;
&lt;br /&gt;
Or course it will be reviewed in regards to security, usability and the other important factors of code development.&lt;br /&gt;
&lt;br /&gt;
===Step 3: Commit your changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have made your changes you are getting ready to commit them.&lt;br /&gt;
&lt;br /&gt;
The first thing to do is check your changes. To do this run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see all of the files you have changes highlighted in red.&lt;br /&gt;
&lt;br /&gt;
Next you need to stage all of the files you want to commit.&lt;br /&gt;
&lt;br /&gt;
To do this you add the files to the stage using the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git add lib/modifiedfile.php&lt;br /&gt;
git add lib/newfile.php&lt;br /&gt;
git add theme/base/style/core.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Why not just commit all changes. Many of the git guides you read will tell you above git commit -a which commits all of the changes you have made.&lt;br /&gt;
&lt;br /&gt;
We&#039;ve hardly being using git here at Moodle and already I&#039;ve seen several people accidentally commit changes that they didn&#039;t mean to.&lt;br /&gt;
&lt;br /&gt;
Staging files like this ENSURES you only commit things you intend to.&lt;br /&gt;
&lt;br /&gt;
Now that you have staged your changes/new files you are ready to commit. The following command commits your changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git commit -m &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command commits your changes with the commit message &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;.&lt;br /&gt;
It&#039;s very important to Moodle that you format your commit messages like this.&lt;br /&gt;
They consist of three parts:&lt;br /&gt;
&lt;br /&gt;
# The MDL bug number in this case MDL-12345&lt;br /&gt;
# The area you made changes to in this case enrol&lt;br /&gt;
# A short description of what you did, in this case I fixed a couple of enrolment bugs.&lt;br /&gt;
&lt;br /&gt;
When you commit your message you will see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[master 19a484e] changes&lt;br /&gt;
 1 files changed, 16 insertions(+), 18 deletions(-)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
There is one thing here you need to note down for later, that is the number that appears within the square brackets after the branch name, in my case it is 19a484e. This is the commit id of the commit I just made.&lt;br /&gt;
&lt;br /&gt;
===Step 4: Pushing your changes to your github account===&lt;br /&gt;
&lt;br /&gt;
Now that you have made changes to your local branch you should push it to your github account so that it can be reviewed and hopefully integrated into Moodle.&lt;br /&gt;
&lt;br /&gt;
Doing this is very simple just run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are telling git to push the branch wip-MDL-12345-master to the remote called github which we added when setting up our git repositories.&lt;br /&gt;
And just like that you&#039;ve made a branch that contains your work and pushed it to github ready to get it reviewed.&lt;br /&gt;
&lt;br /&gt;
==Moving your changes to another branch==&lt;br /&gt;
Now that you have made changes to the master branch you need to decide whether it is appropriate make those changes on any of the other branches.&lt;br /&gt;
Most likely if you are fixing a bug you will need to make the changes on the MOODLE_20_STABLE branch as well, and perhaps the MOODLE_19_STABLE branch if it is a security bug.&lt;br /&gt;
&lt;br /&gt;
Lets assume for MDL-12345 that I fixed earlier that it should be ported to MOODLE_20_STABLE as well.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local MOODLE_20_STABLE branch===&lt;br /&gt;
&lt;br /&gt;
To start with I need to move to the MOODLE_20_STABLE repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there I need to create a new branch based upon the MOODLE_20_STABLE branch that is going to contain my changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very similar to the branch we created for the changes to the master branch except that I have subsituted MOODLE_20_STABLE in place of master. This is because the new branch we are creating is based upon the MOODLE_20_STABLE branch on the offical Moodle git repository and contains changes for that branch.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Cherry-picking my changes===&lt;br /&gt;
Once we have a branch for our changes I am ready to make them again. There is however with git an easy way to do this, cherry-picking.&lt;br /&gt;
&lt;br /&gt;
Cherry-picking is the process of copying a single commit from one branch to another. In this case I want to cherry pick the commit I made earlier onto the branch I&#039;ve just created.&lt;br /&gt;
&lt;br /&gt;
However before I can do this I need to fetch the changes I made from the github repository. I need to do this because I made that changes of a totally separate local repository remember.&lt;br /&gt;
&lt;br /&gt;
So to update my repository with the latest changes I run the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command tells git to look at each remote and get any new changes (it also removes any branches that have been deleted).&lt;br /&gt;
Once it has completed you will be ready to cherry pick the commit. To do so you use the following command but replace my commit is with yours.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git cherry-pick 19a484e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Providing there are no conflicts your branch will now contain a copy of the changes you made to the master branch.&lt;br /&gt;
If there are conficts that you will need to resolve them and commit your changes however you can search for another tutorial about how to do that,&lt;br /&gt;
&lt;br /&gt;
Now I know at this point that there will be some of you who are saying &#039;Whoops I forgot what my commit id was!&#039;. If this is you don&#039;t worry, its pretty easy to find it providing you used a proper commit message like I described above.&lt;br /&gt;
Simply run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git log --oneline origin/master..github/wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the commits that are in the wip-MDL-12345-master at your github account but are not in the master branch at the offical Moodle repository.&lt;br /&gt;
You can then cherry-pick the commits shown there (the commit ID&#039;s should be highlighted in yellow).&lt;br /&gt;
&lt;br /&gt;
Once you have cherry-picked your commits its time to check that everything worked, run the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# On branch wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
# Your branch is ahead of &#039;origin/MOODLE_20_STABLE&#039; by 1 commit.&lt;br /&gt;
#&lt;br /&gt;
nothing to commit (working directory clean)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very handy as it tells you that your branch is ahead of the offical MOODLE_20_STABLE branch by one commit.&lt;br /&gt;
You can also check that your commit contains the changes you think by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git diff origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the changes you have made as a diff.&lt;br /&gt;
&lt;br /&gt;
Now that you know that your commit is there you and that it is correct it is time to push it to your github account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And thats it.&lt;br /&gt;
&lt;br /&gt;
You github account should now have two branches on it:&lt;br /&gt;
&lt;br /&gt;
; wip-MDL-12345-master : This branch is the changes you have made for the master branch&lt;br /&gt;
; wip-MDL-12345-MOODLE_20_STABLE : This branch is those same changes but for the MOODLE_20_STABLE branch&lt;br /&gt;
&lt;br /&gt;
Now you are ready to create PULL requests so that your work gets reviewed and hopefully integrated.&lt;br /&gt;
&lt;br /&gt;
==Creating a PULL request for the master branch==&lt;br /&gt;
&lt;br /&gt;
So you have successfully fixed the bug MDL-12345, you have created two branches one for master and one for MOODLE_20_STABLE. It is time to create a PULL request for each of these branches.&lt;br /&gt;
&lt;br /&gt;
First lets create a PULL request for the master branch:&lt;br /&gt;
&lt;br /&gt;
# Browse to tracker.moodle.org/browse/MDL-12345&lt;br /&gt;
# When the page loads log in if you haven&#039;t already.&lt;br /&gt;
# Click on the button in the top right labelled `Create issue`&lt;br /&gt;
# Change Project to `Pull Requests`&lt;br /&gt;
# Change Issue type to `Pull Request`&lt;br /&gt;
# Click create&lt;br /&gt;
&lt;br /&gt;
This takes you to a screen where you can enter the details for the PULL request.&lt;br /&gt;
&lt;br /&gt;
You should fill it out in the following way:&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
This is the summary for the PULL request, you should copy and paste the summary from the MDL issue here.&lt;br /&gt;
For MDL-12345 the summary is `alphabetization of UI different on left and right sides` so that&#039;s what I will use.&lt;br /&gt;
&lt;br /&gt;
===Affects Versions===&lt;br /&gt;
This is the version that your branch is changing, in the case of this PULL request I will select `master`.&lt;br /&gt;
&lt;br /&gt;
===Security level===&lt;br /&gt;
If the issue you are working on is a security issue you should set this to the same level that the issue is set to. If its not a security issue or you don&#039;t know just leave it as none.&lt;br /&gt;
&lt;br /&gt;
===Pull from repository===&lt;br /&gt;
This is the repository that the branch is at, for you this will be your github accont. If you head to http://github.com/yourname/moodle you will see a box that has three options SSH, HTTP, and Git read only, click Git Read Only and then copy the contents of the text box into the repositry field of the PULL request. &lt;br /&gt;
For me that is git://github.com/yourname/moodle.git&lt;br /&gt;
&lt;br /&gt;
===Pull branch===&lt;br /&gt;
This is the name of the branch that contains your changes. For me that is wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Pull Diff URL===&lt;br /&gt;
This is the URL to a page that shows the changes that you&#039;ve made on your branch. Github is nice in that it has a pretty interface for that. To get to the interface follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Browse to https://github.com/youraccount/moodle&lt;br /&gt;
# Click `Switch Branches` and then click on the branch you changes are based upon, in my case master.&lt;br /&gt;
# Click the button labelled `Branch List`&lt;br /&gt;
# Locate your branch in the list and click the `Compare button` for me this was the compare button to the right of wip-MDL-12345-master.&lt;br /&gt;
# Copy the URL in your browse and paste it into the Pull Diff URL of the PULL request.&lt;br /&gt;
&lt;br /&gt;
For me this URL was: https://github.com/yourname/moodle/compare/master...wip-MDL-23532-master&lt;br /&gt;
For the MOODLE_20_STABLE branch this would be: https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
&lt;br /&gt;
===Description===&lt;br /&gt;
The description should contain several bits of important information:&lt;br /&gt;
&lt;br /&gt;
# A short description of what your patch does&lt;br /&gt;
# Notes about that changes you&#039;ve made that might help the integrator understand what you did when he/she is reviewing it.&lt;br /&gt;
# Testing instructions that guide the testers through testing your changes.&lt;br /&gt;
&lt;br /&gt;
===Components===&lt;br /&gt;
Select general from the components list, general is the only option.&lt;br /&gt;
&lt;br /&gt;
===Finishing up===&lt;br /&gt;
Once you have filled in the fields as above click `Create`. This should create you PULL request and then take you to view it.&lt;br /&gt;
&lt;br /&gt;
Its important to remember that there is still one thing you need to do and that is link to the original issue.&lt;br /&gt;
While you are still logged in click the `More Actions` button and select `Link issue`, in the dialoug that pops up change the `This issue` field to `will help resolve`, type MDL-12345 into the issues field, and then type `Linking to MDL-12345` into the comments box. Once you&#039;ve done that simple click Link.&lt;br /&gt;
&lt;br /&gt;
Time to create the PULL request for the other branches.&lt;br /&gt;
&lt;br /&gt;
==Creating the PULL request for MOODLE_20_STABLE==&lt;br /&gt;
Once you&#039;ve created the PULL request for the master branch it is time to create the PULL request for the MOODLE_20_STABLE branch.&lt;br /&gt;
This is as easy as can be, click Create Issue in the top right, select PULL project and choose Pull Request and then click create.&lt;br /&gt;
On the next screen enter the following details:&lt;br /&gt;
&lt;br /&gt;
; Summary : Copy the summary from the previous PULL Request&lt;br /&gt;
; Affects Versions : Select MOODLE_20_STABLE&lt;br /&gt;
; Security level : Same as the MDL&lt;br /&gt;
; Pull from repository : Copy from the previous PULL request&lt;br /&gt;
; Pull Branch : wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
; Pull Diff URL : https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
; Description : Copy from the previous PULL request&lt;br /&gt;
; Component : general&lt;br /&gt;
&lt;br /&gt;
Then click create to create the PULL request.&lt;br /&gt;
&lt;br /&gt;
Once the PULL request has been create don&#039;t forget to link to the MDL issue like we did for the previous PULL request.&lt;br /&gt;
&lt;br /&gt;
==Rebasing after the weekly release==&lt;br /&gt;
As many of you will be aware on Wednesday after the latest weekly has been released a comment will be added to all PULL requests that are still open.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The main moodle.git repository has just been updated with latest weekly modifications. You may wish to rebase your PULL branches to simplify history and avoid any possible merge conflicts. This would also make integrator&#039;s life easier next week.&lt;br /&gt;
&lt;br /&gt;
TIA and ciao :)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is a message that is bulk added as is done so as a polite request. While it&#039;s not essential for you to rebase your work it really does help the integrators as its much easier to see what is going on and greatly reduces the chance of conflicts (because you&#039;ll solve them when you rebase).&lt;br /&gt;
&lt;br /&gt;
The good news is that rebasing your work is EASY!&lt;br /&gt;
&lt;br /&gt;
For the following example lets assume I created the two PULL requests above on Wednesday morning and the weekly was released on Wednesday afternoon. This means that my branch doesn&#039;t have the changes that have just been released and I need to rebase them.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Rebasing the wip-MDL-12345-master===&lt;br /&gt;
&lt;br /&gt;
The first step is to rebase my work that is based upon the master branch. So first move to the master repository.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next thing we have to do is get all of the changes from the remote repositories, this will fetch down all of the latest changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now before the next step make sure that you don&#039;t have any uncommit changes, if you do finish that work, commit it, then proceed to the next step which is updating your local master.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
git push master github&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that your local master is up to date, and has you&#039;ve updated you master branch at github you are ready to rebase!&lt;br /&gt;
At this point we want to checkout the branch we are going to rebase, in this case wip-MDL-12345-master and then we are going to rebase origin/master which is the official Moodle master branch (and the branch our branch is based upon).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout wip-MDL-12345-master&lt;br /&gt;
git rebase origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that command has completed your branch wip-MDL-12345-master will be completely up to date. Before you are done however you need to push the rebased wip-MDL-12345-master up to your github account so that its the branch the integrator sees.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push -f github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that command is just about identical to the command we used when we first pushed our branch to our github account, there is however one VERY important difference, the &#039;&#039;&#039;-f&#039;&#039;&#039; option.&lt;br /&gt;
The &#039;&#039;&#039;-f&#039;&#039;&#039; option tells git to force the push, this is required because when you rebase all of your commit id&#039;s will change and unless you tell git to force it will see that they have changed and not allow you to push your work.&lt;br /&gt;
&lt;br /&gt;
Thats it! you&#039;ve now rebased your work and the integrators will be happy again :)&lt;br /&gt;
&lt;br /&gt;
===Step 2: Rebasing wip-MDL-12345-MOODLE_20_STABLE===&lt;br /&gt;
Now that we&#039;ve rebased our work that was based upon the master branch it is time to rebase the MOODLE_20_STABLE version.&lt;br /&gt;
This step is just about identical to the previous step except we substitute &#039;&#039;master&#039;&#039; for &#039;&#039;MOODLE_20_STABLE&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github MOODLE_20_STABLE&lt;br /&gt;
git checkout wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
git rebase origin/MOODLE_20_STABLE&lt;br /&gt;
git push -f github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Done!&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk&amp;diff=82845</id>
		<title>User:Sam Hemelryk</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk&amp;diff=82845"/>
		<updated>2011-04-18T10:07:44Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello, I am a senior developer at Moodle and have been with the project since the June 2009.&lt;br /&gt;
&lt;br /&gt;
For those interested I have written a tutorial on my Moodle development process with Git: [[User:Sam_Hemelryk/My_Moodle_Git_workflow]]&lt;br /&gt;
&lt;br /&gt;
A short list of helpful documents I have worked on:&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]]&lt;br /&gt;
* [[Development:Themes 2.0 overriding a renderer]]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82844</id>
		<title>User:Sam Hemelryk/My Moodle Git workflow</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82844"/>
		<updated>2011-04-18T10:03:51Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* Before you start work each day */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document is a sort of tutorial/inspection of my personal development workflow when working on Moodle with Git.&lt;br /&gt;
&lt;br /&gt;
==Creating the repositories==&lt;br /&gt;
Ok so the very first step is to create several Moodle git repositories, one for each major branch of Moodle being worked on.&lt;br /&gt;
&lt;br /&gt;
At the time of writing the major branches are MOODLE_19_STABLE, MOODLE_20_STABLE and master.&lt;br /&gt;
&lt;br /&gt;
The reason for this is that that way we have a separate site for each Moodle branch that we can test on easily. Yes you will have three sites but you won&#039;t have to worry about swtiching your site when you change branches.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Create a directory to create the repositories within===&lt;br /&gt;
&lt;br /&gt;
Personally I use Ubuntu (Linux) and I chose to create my repositories within a folder I created in /var/www. If you are using windows I would instead suggest creating C:/www/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www&lt;br /&gt;
mkdir repositories&lt;br /&gt;
cd repositories&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 2: Create a master repository===&lt;br /&gt;
This is the easiest of the branches to create a repository for.&lt;br /&gt;
&lt;br /&gt;
Within your repositories directory create a new directory called master and move into it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir master&lt;br /&gt;
cd master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we want to clone the Moodle source from the offical Moodle git repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new directory called moodle within the master directory we created just before.&lt;br /&gt;
&lt;br /&gt;
That new moodle directory should contain the Moodle source code as a git repository.&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our main git repository we need to add our github account as a remote so that we can push to it later:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd moodle&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This adds your moodle repository on github as a remote called github that you can push to later.&lt;br /&gt;
&lt;br /&gt;
Finally before we move onto the next repository we need to create a data directory because we know we will need that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 3: Create a MOODLE_20_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
The next repository we create will be for the MOODLE_20_STABLE branch.&lt;br /&gt;
To start with get back to the repositories directory that we created earlier and create a directory called MOODLE_20_STABLE within that.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_20_STABLE&lt;br /&gt;
cd MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now create a new clone of the main Moodle repository like we did for the master branch above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have done that move into the moodle directory.&lt;br /&gt;
&lt;br /&gt;
By default the master branch is the branch that is created, however we don&#039;t want that for this repository. Instead we want the MOODLE_20_STABLE branch.&lt;br /&gt;
&lt;br /&gt;
To do this we checkout local branch based upon the official MOODLE_20_STABLE branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have created that branch we can delete the local master branch so that we don&#039;t accidentally ever work on it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git branch -D master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then like we did for master we add our github repository as a remote:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And finally create a data directory we can use when we have install the site:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 4: Create a MOODLE_19_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
This step is identical to the above step except we are using the MOODLE_19_STABLE branch instead of the MOODLE_20_STABLE branch.&lt;br /&gt;
The commands for this are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_19_STABLE&lt;br /&gt;
cd MOODLE_19_STABLE&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
git checkout -b MOODLE_19_STABLE origin/MOODLE_19_STABLE&lt;br /&gt;
git branch -D master&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 5: Install the sites===&lt;br /&gt;
Now I can&#039;t tell you how to do this on your own machine however what I would recommend is that you create a link from your web root to the moodle directory of each branch.&lt;br /&gt;
&lt;br /&gt;
If you are using linux and your webroot is /var/www/localhost you would do it as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/localhost/&lt;br /&gt;
ln -s /var/www/repositories/master/moodle master&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_20_STABLE/moodle MOODLE_20_STABLE&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_19_STABLE/moodle MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done you should be able to browse to each repository with the following URL&#039;s&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://localhost/master/&lt;br /&gt;
http://localhost/MOODLE_20_STABLE/&lt;br /&gt;
http://localhost/MOODLE_19_STABLE/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that is done you need to browse to each site and complete the installation.&lt;br /&gt;
&lt;br /&gt;
Under this method your will need to ensure you set the configuration option sessioncookiepath to the URI of your site. You can either do this in the admin interfaces or add the following to your config.php file for each site.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// For the master site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/master/&#039;;&lt;br /&gt;
// For the MOODLE_20_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_20_STABLE/&#039;;&lt;br /&gt;
// For the MOODLE_19_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_19_STABLE/&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Failure to do this will mean that when you log in at one site and then visit the next you will have to log in again and your session on the first site will no longer work.&lt;br /&gt;
&lt;br /&gt;
Now that you have got 3 repositories, one for each main branch, and set up a site for each you are ready to start development.&lt;br /&gt;
&lt;br /&gt;
==Before you start work each day==&lt;br /&gt;
Before you start work each day you should update each of the repositories you have created to ensure that you are always working with up to date versions of Moodle.&lt;br /&gt;
&lt;br /&gt;
You should also take this opportunity to update the repositories on your github account to ensure they are always up to date.&lt;br /&gt;
&lt;br /&gt;
To start with lets update the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This moves to the master repository and then tells git for fetch all of the changes from your remote repositories and clean up any old branches it is aware of.&lt;br /&gt;
&lt;br /&gt;
Once that operation has completed you should update your master branch&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout master&lt;br /&gt;
git pull&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Before you do that it pays to make sure you don&#039;t have any uncommit changes, if you do DON&#039;T TRY IT. There would be a good chance you will encounter problems. Instead finish what you are working on, commit your changes and then update your master branch.&lt;br /&gt;
&lt;br /&gt;
Next we will update the github repositories by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github refs/remotes/origin/master:master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This tells git to push the master branch from origin (the offical Moodle repository) to the master branch on our github account.&lt;br /&gt;
&lt;br /&gt;
Now that you&#039;ve updated the master repository and your github account its time to update the MOODLE_20_STABLE and MOODLE_19_STABLE branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_20_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_20_STABLE:MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_19_STABLE/moodle&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
git checkout MOODLE_19_STABLE&lt;br /&gt;
git pull&lt;br /&gt;
git push github refs/remotes/origin/MOODLE_19_STABLE:MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Working on a Moodle issue==&lt;br /&gt;
&lt;br /&gt;
This part of the document looks at how I go about working on an MDL issue from the Moodle tracker.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ we use the scrum methodology we sees us choose several issues to include in a scrum which we then work on for the period of the scrum. As a community member its more likely you will just be choosing issues that you are passionate about.&lt;br /&gt;
&lt;br /&gt;
Either way once you have found an issue to work on you are ready to start.&lt;br /&gt;
&lt;br /&gt;
For the purpose of this part of the document lets say I am going to work on bug MDL-12345.&lt;br /&gt;
&lt;br /&gt;
==Fixing a bug on the master repository - MDL-12345==&lt;br /&gt;
&lt;br /&gt;
The first step is to create a local branch to make changes on, to do this we will start our work on the master repository.&lt;br /&gt;
&lt;br /&gt;
When fixing an issue I find it easiest to fix the issue on the master branch first and then move my changes to the other branches.&lt;br /&gt;
&lt;br /&gt;
The VERY first thing you should do when you start working on a Moodle issue is make sure you have assigned it to yourself and then click the start progress button.&lt;br /&gt;
&lt;br /&gt;
This way other users know that you are activly working on the bug and no one from HQ will steal it from you.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local branch===&lt;br /&gt;
&lt;br /&gt;
So first get to the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there we create a new branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-master origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command checks out a new branch called wip-MDL-12345-master that is based upon origin/master.&lt;br /&gt;
&lt;br /&gt;
origin/master is of course the master branch on the official Moodle repository (git.moodle.org/moodle.git).&lt;br /&gt;
&lt;br /&gt;
The name of the branch is also very important. It is essentially telling us three things.&lt;br /&gt;
&lt;br /&gt;
; wip : This stands for work in progress, it helps people see that you are currently working on this branch and that they shouldn&#039;t base there work on it because it will likely change.&lt;br /&gt;
; MDL-12345 : This is of course the Moodle bug number. It helps people quickly identify what you are working on.&lt;br /&gt;
; master : This is the branch we are making changes on. It helps people quickly understand where the changes are being made.&lt;br /&gt;
&lt;br /&gt;
You can optionally add more to the end of the branch name such as a key word that identifies the area or a date at which you started work e.g.&lt;br /&gt;
&lt;br /&gt;
* wip-MDL-12345-master-navigation-changes&lt;br /&gt;
* wip-MDL-12345-master-20110418&lt;br /&gt;
&lt;br /&gt;
That is up to you, personally I&#039;m not a fan of it, however the rest is all required to help integrate your work.&lt;br /&gt;
&lt;br /&gt;
Either way now you have a branch, mine is called wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Make changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have created you branch you are ready to make changes.&lt;br /&gt;
&lt;br /&gt;
I&#039;ll let you make whatever changes you are need, once you have made changes move onto the next step.&lt;br /&gt;
&lt;br /&gt;
Before you do move on however make sure that your code meets the high quality of code Moodle requires.&lt;br /&gt;
&lt;br /&gt;
You can find information about that on the moodle docs here: https://docs.moodle.org/en/Development:Coding_style&lt;br /&gt;
&lt;br /&gt;
The following are common mistakes:&lt;br /&gt;
&lt;br /&gt;
* Incorrect white space&lt;br /&gt;
** Tabs instead of spaces&lt;br /&gt;
** Extra spaces at the end of lines&lt;br /&gt;
** Multiple new lines&lt;br /&gt;
** Forgetting to put spaces between function arguments&lt;br /&gt;
* Incorrect commit messages (read on to find out about writing a good commit message)&lt;br /&gt;
* Incorrect variable or function names&lt;br /&gt;
&lt;br /&gt;
Making these sort of mistakes can lead to your code being rejected despite it working correctly.&lt;br /&gt;
&lt;br /&gt;
Or course it will be reviewed in regards to security, usability and the other important factors of code development.&lt;br /&gt;
&lt;br /&gt;
===Step 3: Commit your changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have made your changes you are getting ready to commit them.&lt;br /&gt;
&lt;br /&gt;
The first thing to do is check your changes. To do this run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see all of the files you have changes highlighted in red.&lt;br /&gt;
&lt;br /&gt;
Next you need to stage all of the files you want to commit.&lt;br /&gt;
&lt;br /&gt;
To do this you add the files to the stage using the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git add lib/modifiedfile.php&lt;br /&gt;
git add lib/newfile.php&lt;br /&gt;
git add theme/base/style/core.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Why not just commit all changes. Many of the git guides you read will tell you above git commit -a which commits all of the changes you have made.&lt;br /&gt;
&lt;br /&gt;
We&#039;ve hardly being using git here at Moodle and already I&#039;ve seen several people accidentally commit changes that they didn&#039;t mean to.&lt;br /&gt;
&lt;br /&gt;
Staging files like this ENSURES you only commit things you intend to.&lt;br /&gt;
&lt;br /&gt;
Now that you have staged your changes/new files you are ready to commit. The following command commits your changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git commit -m &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command commits your changes with the commit message &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;.&lt;br /&gt;
It&#039;s very important to Moodle that you format your commit messages like this.&lt;br /&gt;
They consist of three parts:&lt;br /&gt;
&lt;br /&gt;
# The MDL bug number in this case MDL-12345&lt;br /&gt;
# The area you made changes to in this case enrol&lt;br /&gt;
# A short description of what you did, in this case I fixed a couple of enrolment bugs.&lt;br /&gt;
&lt;br /&gt;
When you commit your message you will see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[master 19a484e] changes&lt;br /&gt;
 1 files changed, 16 insertions(+), 18 deletions(-)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
There is one thing here you need to note down for later, that is the number that appears within the square brackets after the branch name, in my case it is 19a484e. This is the commit id of the commit I just made.&lt;br /&gt;
&lt;br /&gt;
===Step 4: Pushing your changes to your github account===&lt;br /&gt;
&lt;br /&gt;
Now that you have made changes to your local branch you should push it to your github account so that it can be reviewed and hopefully integrated into Moodle.&lt;br /&gt;
&lt;br /&gt;
Doing this is very simple just run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are telling git to push the branch wip-MDL-12345-master to the remote called github which we added when setting up our git repositories.&lt;br /&gt;
And just like that you&#039;ve made a branch that contains your work and pushed it to github ready to get it reviewed.&lt;br /&gt;
&lt;br /&gt;
==Moving your changes to another branch==&lt;br /&gt;
Now that you have made changes to the master branch you need to decide whether it is appropriate make those changes on any of the other branches.&lt;br /&gt;
Most likely if you are fixing a bug you will need to make the changes on the MOODLE_20_STABLE branch as well, and perhaps the MOODLE_19_STABLE branch if it is a security bug.&lt;br /&gt;
&lt;br /&gt;
Lets assume for MDL-12345 that I fixed earlier that it should be ported to MOODLE_20_STABLE as well.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local MOODLE_20_STABLE branch===&lt;br /&gt;
&lt;br /&gt;
To start with I need to move to the MOODLE_20_STABLE repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there I need to create a new branch based upon the MOODLE_20_STABLE branch that is going to contain my changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very similar to the branch we created for the changes to the master branch except that I have subsituted MOODLE_20_STABLE in place of master. This is because the new branch we are creating is based upon the MOODLE_20_STABLE branch on the offical Moodle git repository and contains changes for that branch.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Cherry-picking my changes===&lt;br /&gt;
Once we have a branch for our changes I am ready to make them again. There is however with git an easy way to do this, cherry-picking.&lt;br /&gt;
&lt;br /&gt;
Cherry-picking is the process of copying a single commit from one branch to another. In this case I want to cherry pick the commit I made earlier onto the branch I&#039;ve just created.&lt;br /&gt;
&lt;br /&gt;
However before I can do this I need to fetch the changes I made from the github repository. I need to do this because I made that changes of a totally separate local repository remember.&lt;br /&gt;
&lt;br /&gt;
So to update my repository with the latest changes I run the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command tells git to look at each remote and get any new changes (it also removes any branches that have been deleted).&lt;br /&gt;
Once it has completed you will be ready to cherry pick the commit. To do so you use the following command but replace my commit is with yours.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git cherry-pick 19a484e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Providing there are no conflicts your branch will now contain a copy of the changes you made to the master branch.&lt;br /&gt;
If there are conficts that you will need to resolve them and commit your changes however you can search for another tutorial about how to do that,&lt;br /&gt;
&lt;br /&gt;
Now I know at this point that there will be some of you who are saying &#039;Whoops I forgot what my commit id was!&#039;. If this is you don&#039;t worry, its pretty easy to find it providing you used a proper commit message like I described above.&lt;br /&gt;
Simply run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git log --oneline origin/master..github/wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the commits that are in the wip-MDL-12345-master at your github account but are not in the master branch at the offical Moodle repository.&lt;br /&gt;
You can then cherry-pick the commits shown there (the commit ID&#039;s should be highlighted in yellow).&lt;br /&gt;
&lt;br /&gt;
Once you have cherry-picked your commits its time to check that everything worked, run the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# On branch wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
# Your branch is ahead of &#039;origin/MOODLE_20_STABLE&#039; by 1 commit.&lt;br /&gt;
#&lt;br /&gt;
nothing to commit (working directory clean)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very handy as it tells you that your branch is ahead of the offical MOODLE_20_STABLE branch by one commit.&lt;br /&gt;
You can also check that your commit contains the changes you think by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git diff origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the changes you have made as a diff.&lt;br /&gt;
&lt;br /&gt;
Now that you know that your commit is there you and that it is correct it is time to push it to your github account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And thats it.&lt;br /&gt;
&lt;br /&gt;
You github account should now have two branches on it:&lt;br /&gt;
&lt;br /&gt;
; wip-MDL-12345-master : This branch is the changes you have made for the master branch&lt;br /&gt;
; wip-MDL-12345-MOODLE_20_STABLE : This branch is those same changes but for the MOODLE_20_STABLE branch&lt;br /&gt;
&lt;br /&gt;
Now you are ready to create PULL requests so that your work gets reviewed and hopefully integrated.&lt;br /&gt;
&lt;br /&gt;
==Creating a PULL request for the master branch==&lt;br /&gt;
&lt;br /&gt;
So you have successfully fixed the bug MDL-12345, you have created two branches one for master and one for MOODLE_20_STABLE. It is time to create a PULL request for each of these branches.&lt;br /&gt;
&lt;br /&gt;
First lets create a PULL request for the master branch:&lt;br /&gt;
&lt;br /&gt;
# Browse to tracker.moodle.org/browse/MDL-12345&lt;br /&gt;
# When the page loads log in if you haven&#039;t already.&lt;br /&gt;
# Click on the button in the top right labelled `Create issue`&lt;br /&gt;
# Change Project to `Pull Requests`&lt;br /&gt;
# Change Issue type to `Pull Request`&lt;br /&gt;
# Click create&lt;br /&gt;
&lt;br /&gt;
This takes you to a screen where you can enter the details for the PULL request.&lt;br /&gt;
&lt;br /&gt;
You should fill it out in the following way:&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
This is the summary for the PULL request, you should copy and paste the summary from the MDL issue here.&lt;br /&gt;
For MDL-12345 the summary is `alphabetization of UI different on left and right sides` so that&#039;s what I will use.&lt;br /&gt;
&lt;br /&gt;
===Affects Versions===&lt;br /&gt;
This is the version that your branch is changing, in the case of this PULL request I will select `master`.&lt;br /&gt;
&lt;br /&gt;
===Security level===&lt;br /&gt;
If the issue you are working on is a security issue you should set this to the same level that the issue is set to. If its not a security issue or you don&#039;t know just leave it as none.&lt;br /&gt;
&lt;br /&gt;
===Pull from repository===&lt;br /&gt;
This is the repository that the branch is at, for you this will be your github accont. If you head to http://github.com/yourname/moodle you will see a box that has three options SSH, HTTP, and Git read only, click Git Read Only and then copy the contents of the text box into the repositry field of the PULL request. &lt;br /&gt;
For me that is git://github.com/yourname/moodle.git&lt;br /&gt;
&lt;br /&gt;
===Pull branch===&lt;br /&gt;
This is the name of the branch that contains your changes. For me that is wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Pull Diff URL===&lt;br /&gt;
This is the URL to a page that shows the changes that you&#039;ve made on your branch. Github is nice in that it has a pretty interface for that. To get to the interface follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Browse to https://github.com/youraccount/moodle&lt;br /&gt;
# Click `Switch Branches` and then click on the branch you changes are based upon, in my case master.&lt;br /&gt;
# Click the button labelled `Branch List`&lt;br /&gt;
# Locate your branch in the list and click the `Compare button` for me this was the compare button to the right of wip-MDL-12345-master.&lt;br /&gt;
# Copy the URL in your browse and paste it into the Pull Diff URL of the PULL request.&lt;br /&gt;
&lt;br /&gt;
For me this URL was: https://github.com/yourname/moodle/compare/master...wip-MDL-23532-master&lt;br /&gt;
For the MOODLE_20_STABLE branch this would be: https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
&lt;br /&gt;
===Description===&lt;br /&gt;
The description should contain several bits of important information:&lt;br /&gt;
&lt;br /&gt;
# A short description of what your patch does&lt;br /&gt;
# Notes about that changes you&#039;ve made that might help the integrator understand what you did when he/she is reviewing it.&lt;br /&gt;
# Testing instructions that guide the testers through testing your changes.&lt;br /&gt;
&lt;br /&gt;
===Components===&lt;br /&gt;
Select general from the components list, general is the only option.&lt;br /&gt;
&lt;br /&gt;
===Finishing up===&lt;br /&gt;
Once you have filled in the fields as above click `Create`. This should create you PULL request and then take you to view it.&lt;br /&gt;
&lt;br /&gt;
Its important to remember that there is still one thing you need to do and that is link to the original issue.&lt;br /&gt;
While you are still logged in click the `More Actions` button and select `Link issue`, in the dialoug that pops up change the `This issue` field to `will help resolve`, type MDL-12345 into the issues field, and then type `Linking to MDL-12345` into the comments box. Once you&#039;ve done that simple click Link.&lt;br /&gt;
&lt;br /&gt;
Time to create the PULL request for the other branches.&lt;br /&gt;
&lt;br /&gt;
==Creating the PULL request for MOODLE_20_STABLE==&lt;br /&gt;
Once you&#039;ve created the PULL request for the master branch it is time to create the PULL request for the MOODLE_20_STABLE branch.&lt;br /&gt;
This is as easy as can be, click Create Issue in the top right, select PULL project and choose Pull Request and then click create.&lt;br /&gt;
On the next screen enter the following details:&lt;br /&gt;
&lt;br /&gt;
; Summary : Copy the summary from the previous PULL Request&lt;br /&gt;
; Affects Versions : Select MOODLE_20_STABLE&lt;br /&gt;
; Security level : Same as the MDL&lt;br /&gt;
; Pull from repository : Copy from the previous PULL request&lt;br /&gt;
; Pull Branch : wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
; Pull Diff URL : https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
; Description : Copy from the previous PULL request&lt;br /&gt;
; Component : general&lt;br /&gt;
&lt;br /&gt;
Then click create to create the PULL request.&lt;br /&gt;
&lt;br /&gt;
Once the PULL request has been create don&#039;t forget to link to the MDL issue like we did for the previous PULL request.&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82843</id>
		<title>User:Sam Hemelryk/My Moodle Git workflow</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82843"/>
		<updated>2011-04-18T09:56:03Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document is a sort of tutorial/inspection of my personal development workflow when working on Moodle with Git.&lt;br /&gt;
&lt;br /&gt;
==Creating the repositories==&lt;br /&gt;
Ok so the very first step is to create several Moodle git repositories, one for each major branch of Moodle being worked on.&lt;br /&gt;
&lt;br /&gt;
At the time of writing the major branches are MOODLE_19_STABLE, MOODLE_20_STABLE and master.&lt;br /&gt;
&lt;br /&gt;
The reason for this is that that way we have a separate site for each Moodle branch that we can test on easily. Yes you will have three sites but you won&#039;t have to worry about swtiching your site when you change branches.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Create a directory to create the repositories within===&lt;br /&gt;
&lt;br /&gt;
Personally I use Ubuntu (Linux) and I chose to create my repositories within a folder I created in /var/www. If you are using windows I would instead suggest creating C:/www/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www&lt;br /&gt;
mkdir repositories&lt;br /&gt;
cd repositories&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 2: Create a master repository===&lt;br /&gt;
This is the easiest of the branches to create a repository for.&lt;br /&gt;
&lt;br /&gt;
Within your repositories directory create a new directory called master and move into it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir master&lt;br /&gt;
cd master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we want to clone the Moodle source from the offical Moodle git repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new directory called moodle within the master directory we created just before.&lt;br /&gt;
&lt;br /&gt;
That new moodle directory should contain the Moodle source code as a git repository.&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our main git repository we need to add our github account as a remote so that we can push to it later:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd moodle&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This adds your moodle repository on github as a remote called github that you can push to later.&lt;br /&gt;
&lt;br /&gt;
Finally before we move onto the next repository we need to create a data directory because we know we will need that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 3: Create a MOODLE_20_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
The next repository we create will be for the MOODLE_20_STABLE branch.&lt;br /&gt;
To start with get back to the repositories directory that we created earlier and create a directory called MOODLE_20_STABLE within that.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_20_STABLE&lt;br /&gt;
cd MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now create a new clone of the main Moodle repository like we did for the master branch above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have done that move into the moodle directory.&lt;br /&gt;
&lt;br /&gt;
By default the master branch is the branch that is created, however we don&#039;t want that for this repository. Instead we want the MOODLE_20_STABLE branch.&lt;br /&gt;
&lt;br /&gt;
To do this we checkout local branch based upon the official MOODLE_20_STABLE branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have created that branch we can delete the local master branch so that we don&#039;t accidentally ever work on it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git branch -D master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then like we did for master we add our github repository as a remote:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And finally create a data directory we can use when we have install the site:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 4: Create a MOODLE_19_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
This step is identical to the above step except we are using the MOODLE_19_STABLE branch instead of the MOODLE_20_STABLE branch.&lt;br /&gt;
The commands for this are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_19_STABLE&lt;br /&gt;
cd MOODLE_19_STABLE&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
git checkout -b MOODLE_19_STABLE origin/MOODLE_19_STABLE&lt;br /&gt;
git branch -D master&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 5: Install the sites===&lt;br /&gt;
Now I can&#039;t tell you how to do this on your own machine however what I would recommend is that you create a link from your web root to the moodle directory of each branch.&lt;br /&gt;
&lt;br /&gt;
If you are using linux and your webroot is /var/www/localhost you would do it as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/localhost/&lt;br /&gt;
ln -s /var/www/repositories/master/moodle master&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_20_STABLE/moodle MOODLE_20_STABLE&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_19_STABLE/moodle MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done you should be able to browse to each repository with the following URL&#039;s&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://localhost/master/&lt;br /&gt;
http://localhost/MOODLE_20_STABLE/&lt;br /&gt;
http://localhost/MOODLE_19_STABLE/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that is done you need to browse to each site and complete the installation.&lt;br /&gt;
&lt;br /&gt;
Under this method your will need to ensure you set the configuration option sessioncookiepath to the URI of your site. You can either do this in the admin interfaces or add the following to your config.php file for each site.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// For the master site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/master/&#039;;&lt;br /&gt;
// For the MOODLE_20_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_20_STABLE/&#039;;&lt;br /&gt;
// For the MOODLE_19_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_19_STABLE/&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Failure to do this will mean that when you log in at one site and then visit the next you will have to log in again and your session on the first site will no longer work.&lt;br /&gt;
&lt;br /&gt;
Now that you have got 3 repositories, one for each main branch, and set up a site for each you are ready to start development.&lt;br /&gt;
&lt;br /&gt;
==Before you start work each day==&lt;br /&gt;
Before you start work each day you should update each of the repositories you have created to ensure that you are always working with up to date versions of Moodle.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Working on a Moodle issue==&lt;br /&gt;
&lt;br /&gt;
This part of the document looks at how I go about working on an MDL issue from the Moodle tracker.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ we use the scrum methodology we sees us choose several issues to include in a scrum which we then work on for the period of the scrum. As a community member its more likely you will just be choosing issues that you are passionate about.&lt;br /&gt;
&lt;br /&gt;
Either way once you have found an issue to work on you are ready to start.&lt;br /&gt;
&lt;br /&gt;
For the purpose of this part of the document lets say I am going to work on bug MDL-12345.&lt;br /&gt;
&lt;br /&gt;
==Fixing a bug on the master repository - MDL-12345==&lt;br /&gt;
&lt;br /&gt;
The first step is to create a local branch to make changes on, to do this we will start our work on the master repository.&lt;br /&gt;
&lt;br /&gt;
When fixing an issue I find it easiest to fix the issue on the master branch first and then move my changes to the other branches.&lt;br /&gt;
&lt;br /&gt;
The VERY first thing you should do when you start working on a Moodle issue is make sure you have assigned it to yourself and then click the start progress button.&lt;br /&gt;
&lt;br /&gt;
This way other users know that you are activly working on the bug and no one from HQ will steal it from you.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local branch===&lt;br /&gt;
&lt;br /&gt;
So first get to the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there we create a new branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-master origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command checks out a new branch called wip-MDL-12345-master that is based upon origin/master.&lt;br /&gt;
&lt;br /&gt;
origin/master is of course the master branch on the official Moodle repository (git.moodle.org/moodle.git).&lt;br /&gt;
&lt;br /&gt;
The name of the branch is also very important. It is essentially telling us three things.&lt;br /&gt;
&lt;br /&gt;
; wip : This stands for work in progress, it helps people see that you are currently working on this branch and that they shouldn&#039;t base there work on it because it will likely change.&lt;br /&gt;
; MDL-12345 : This is of course the Moodle bug number. It helps people quickly identify what you are working on.&lt;br /&gt;
; master : This is the branch we are making changes on. It helps people quickly understand where the changes are being made.&lt;br /&gt;
&lt;br /&gt;
You can optionally add more to the end of the branch name such as a key word that identifies the area or a date at which you started work e.g.&lt;br /&gt;
&lt;br /&gt;
* wip-MDL-12345-master-navigation-changes&lt;br /&gt;
* wip-MDL-12345-master-20110418&lt;br /&gt;
&lt;br /&gt;
That is up to you, personally I&#039;m not a fan of it, however the rest is all required to help integrate your work.&lt;br /&gt;
&lt;br /&gt;
Either way now you have a branch, mine is called wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Make changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have created you branch you are ready to make changes.&lt;br /&gt;
&lt;br /&gt;
I&#039;ll let you make whatever changes you are need, once you have made changes move onto the next step.&lt;br /&gt;
&lt;br /&gt;
Before you do move on however make sure that your code meets the high quality of code Moodle requires.&lt;br /&gt;
&lt;br /&gt;
You can find information about that on the moodle docs here: https://docs.moodle.org/en/Development:Coding_style&lt;br /&gt;
&lt;br /&gt;
The following are common mistakes:&lt;br /&gt;
&lt;br /&gt;
* Incorrect white space&lt;br /&gt;
** Tabs instead of spaces&lt;br /&gt;
** Extra spaces at the end of lines&lt;br /&gt;
** Multiple new lines&lt;br /&gt;
** Forgetting to put spaces between function arguments&lt;br /&gt;
* Incorrect commit messages (read on to find out about writing a good commit message)&lt;br /&gt;
* Incorrect variable or function names&lt;br /&gt;
&lt;br /&gt;
Making these sort of mistakes can lead to your code being rejected despite it working correctly.&lt;br /&gt;
&lt;br /&gt;
Or course it will be reviewed in regards to security, usability and the other important factors of code development.&lt;br /&gt;
&lt;br /&gt;
===Step 3: Commit your changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have made your changes you are getting ready to commit them.&lt;br /&gt;
&lt;br /&gt;
The first thing to do is check your changes. To do this run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see all of the files you have changes highlighted in red.&lt;br /&gt;
&lt;br /&gt;
Next you need to stage all of the files you want to commit.&lt;br /&gt;
&lt;br /&gt;
To do this you add the files to the stage using the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git add lib/modifiedfile.php&lt;br /&gt;
git add lib/newfile.php&lt;br /&gt;
git add theme/base/style/core.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Why not just commit all changes. Many of the git guides you read will tell you above git commit -a which commits all of the changes you have made.&lt;br /&gt;
&lt;br /&gt;
We&#039;ve hardly being using git here at Moodle and already I&#039;ve seen several people accidentally commit changes that they didn&#039;t mean to.&lt;br /&gt;
&lt;br /&gt;
Staging files like this ENSURES you only commit things you intend to.&lt;br /&gt;
&lt;br /&gt;
Now that you have staged your changes/new files you are ready to commit. The following command commits your changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git commit -m &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command commits your changes with the commit message &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;.&lt;br /&gt;
It&#039;s very important to Moodle that you format your commit messages like this.&lt;br /&gt;
They consist of three parts:&lt;br /&gt;
&lt;br /&gt;
# The MDL bug number in this case MDL-12345&lt;br /&gt;
# The area you made changes to in this case enrol&lt;br /&gt;
# A short description of what you did, in this case I fixed a couple of enrolment bugs.&lt;br /&gt;
&lt;br /&gt;
When you commit your message you will see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[master 19a484e] changes&lt;br /&gt;
 1 files changed, 16 insertions(+), 18 deletions(-)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
There is one thing here you need to note down for later, that is the number that appears within the square brackets after the branch name, in my case it is 19a484e. This is the commit id of the commit I just made.&lt;br /&gt;
&lt;br /&gt;
===Step 4: Pushing your changes to your github account===&lt;br /&gt;
&lt;br /&gt;
Now that you have made changes to your local branch you should push it to your github account so that it can be reviewed and hopefully integrated into Moodle.&lt;br /&gt;
&lt;br /&gt;
Doing this is very simple just run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are telling git to push the branch wip-MDL-12345-master to the remote called github which we added when setting up our git repositories.&lt;br /&gt;
And just like that you&#039;ve made a branch that contains your work and pushed it to github ready to get it reviewed.&lt;br /&gt;
&lt;br /&gt;
==Moving your changes to another branch==&lt;br /&gt;
Now that you have made changes to the master branch you need to decide whether it is appropriate make those changes on any of the other branches.&lt;br /&gt;
Most likely if you are fixing a bug you will need to make the changes on the MOODLE_20_STABLE branch as well, and perhaps the MOODLE_19_STABLE branch if it is a security bug.&lt;br /&gt;
&lt;br /&gt;
Lets assume for MDL-12345 that I fixed earlier that it should be ported to MOODLE_20_STABLE as well.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local MOODLE_20_STABLE branch===&lt;br /&gt;
&lt;br /&gt;
To start with I need to move to the MOODLE_20_STABLE repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there I need to create a new branch based upon the MOODLE_20_STABLE branch that is going to contain my changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very similar to the branch we created for the changes to the master branch except that I have subsituted MOODLE_20_STABLE in place of master. This is because the new branch we are creating is based upon the MOODLE_20_STABLE branch on the offical Moodle git repository and contains changes for that branch.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Cherry-picking my changes===&lt;br /&gt;
Once we have a branch for our changes I am ready to make them again. There is however with git an easy way to do this, cherry-picking.&lt;br /&gt;
&lt;br /&gt;
Cherry-picking is the process of copying a single commit from one branch to another. In this case I want to cherry pick the commit I made earlier onto the branch I&#039;ve just created.&lt;br /&gt;
&lt;br /&gt;
However before I can do this I need to fetch the changes I made from the github repository. I need to do this because I made that changes of a totally separate local repository remember.&lt;br /&gt;
&lt;br /&gt;
So to update my repository with the latest changes I run the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command tells git to look at each remote and get any new changes (it also removes any branches that have been deleted).&lt;br /&gt;
Once it has completed you will be ready to cherry pick the commit. To do so you use the following command but replace my commit is with yours.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git cherry-pick 19a484e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Providing there are no conflicts your branch will now contain a copy of the changes you made to the master branch.&lt;br /&gt;
If there are conficts that you will need to resolve them and commit your changes however you can search for another tutorial about how to do that,&lt;br /&gt;
&lt;br /&gt;
Now I know at this point that there will be some of you who are saying &#039;Whoops I forgot what my commit id was!&#039;. If this is you don&#039;t worry, its pretty easy to find it providing you used a proper commit message like I described above.&lt;br /&gt;
Simply run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git log --oneline origin/master..github/wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the commits that are in the wip-MDL-12345-master at your github account but are not in the master branch at the offical Moodle repository.&lt;br /&gt;
You can then cherry-pick the commits shown there (the commit ID&#039;s should be highlighted in yellow).&lt;br /&gt;
&lt;br /&gt;
Once you have cherry-picked your commits its time to check that everything worked, run the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# On branch wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
# Your branch is ahead of &#039;origin/MOODLE_20_STABLE&#039; by 1 commit.&lt;br /&gt;
#&lt;br /&gt;
nothing to commit (working directory clean)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very handy as it tells you that your branch is ahead of the offical MOODLE_20_STABLE branch by one commit.&lt;br /&gt;
You can also check that your commit contains the changes you think by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git diff origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the changes you have made as a diff.&lt;br /&gt;
&lt;br /&gt;
Now that you know that your commit is there you and that it is correct it is time to push it to your github account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And thats it.&lt;br /&gt;
&lt;br /&gt;
You github account should now have two branches on it:&lt;br /&gt;
&lt;br /&gt;
; wip-MDL-12345-master : This branch is the changes you have made for the master branch&lt;br /&gt;
; wip-MDL-12345-MOODLE_20_STABLE : This branch is those same changes but for the MOODLE_20_STABLE branch&lt;br /&gt;
&lt;br /&gt;
Now you are ready to create PULL requests so that your work gets reviewed and hopefully integrated.&lt;br /&gt;
&lt;br /&gt;
==Creating a PULL request for the master branch==&lt;br /&gt;
&lt;br /&gt;
So you have successfully fixed the bug MDL-12345, you have created two branches one for master and one for MOODLE_20_STABLE. It is time to create a PULL request for each of these branches.&lt;br /&gt;
&lt;br /&gt;
First lets create a PULL request for the master branch:&lt;br /&gt;
&lt;br /&gt;
# Browse to tracker.moodle.org/browse/MDL-12345&lt;br /&gt;
# When the page loads log in if you haven&#039;t already.&lt;br /&gt;
# Click on the button in the top right labelled `Create issue`&lt;br /&gt;
# Change Project to `Pull Requests`&lt;br /&gt;
# Change Issue type to `Pull Request`&lt;br /&gt;
# Click create&lt;br /&gt;
&lt;br /&gt;
This takes you to a screen where you can enter the details for the PULL request.&lt;br /&gt;
&lt;br /&gt;
You should fill it out in the following way:&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
This is the summary for the PULL request, you should copy and paste the summary from the MDL issue here.&lt;br /&gt;
For MDL-12345 the summary is `alphabetization of UI different on left and right sides` so that&#039;s what I will use.&lt;br /&gt;
&lt;br /&gt;
===Affects Versions===&lt;br /&gt;
This is the version that your branch is changing, in the case of this PULL request I will select `master`.&lt;br /&gt;
&lt;br /&gt;
===Security level===&lt;br /&gt;
If the issue you are working on is a security issue you should set this to the same level that the issue is set to. If its not a security issue or you don&#039;t know just leave it as none.&lt;br /&gt;
&lt;br /&gt;
===Pull from repository===&lt;br /&gt;
This is the repository that the branch is at, for you this will be your github accont. If you head to http://github.com/yourname/moodle you will see a box that has three options SSH, HTTP, and Git read only, click Git Read Only and then copy the contents of the text box into the repositry field of the PULL request. &lt;br /&gt;
For me that is git://github.com/yourname/moodle.git&lt;br /&gt;
&lt;br /&gt;
===Pull branch===&lt;br /&gt;
This is the name of the branch that contains your changes. For me that is wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Pull Diff URL===&lt;br /&gt;
This is the URL to a page that shows the changes that you&#039;ve made on your branch. Github is nice in that it has a pretty interface for that. To get to the interface follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Browse to https://github.com/youraccount/moodle&lt;br /&gt;
# Click `Switch Branches` and then click on the branch you changes are based upon, in my case master.&lt;br /&gt;
# Click the button labelled `Branch List`&lt;br /&gt;
# Locate your branch in the list and click the `Compare button` for me this was the compare button to the right of wip-MDL-12345-master.&lt;br /&gt;
# Copy the URL in your browse and paste it into the Pull Diff URL of the PULL request.&lt;br /&gt;
&lt;br /&gt;
For me this URL was: https://github.com/yourname/moodle/compare/master...wip-MDL-23532-master&lt;br /&gt;
For the MOODLE_20_STABLE branch this would be: https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
&lt;br /&gt;
===Description===&lt;br /&gt;
The description should contain several bits of important information:&lt;br /&gt;
&lt;br /&gt;
# A short description of what your patch does&lt;br /&gt;
# Notes about that changes you&#039;ve made that might help the integrator understand what you did when he/she is reviewing it.&lt;br /&gt;
# Testing instructions that guide the testers through testing your changes.&lt;br /&gt;
&lt;br /&gt;
===Components===&lt;br /&gt;
Select general from the components list, general is the only option.&lt;br /&gt;
&lt;br /&gt;
===Finishing up===&lt;br /&gt;
Once you have filled in the fields as above click `Create`. This should create you PULL request and then take you to view it.&lt;br /&gt;
&lt;br /&gt;
Its important to remember that there is still one thing you need to do and that is link to the original issue.&lt;br /&gt;
While you are still logged in click the `More Actions` button and select `Link issue`, in the dialoug that pops up change the `This issue` field to `will help resolve`, type MDL-12345 into the issues field, and then type `Linking to MDL-12345` into the comments box. Once you&#039;ve done that simple click Link.&lt;br /&gt;
&lt;br /&gt;
Time to create the PULL request for the other branches.&lt;br /&gt;
&lt;br /&gt;
==Creating the PULL request for MOODLE_20_STABLE==&lt;br /&gt;
Once you&#039;ve created the PULL request for the master branch it is time to create the PULL request for the MOODLE_20_STABLE branch.&lt;br /&gt;
This is as easy as can be, click Create Issue in the top right, select PULL project and choose Pull Request and then click create.&lt;br /&gt;
On the next screen enter the following details:&lt;br /&gt;
&lt;br /&gt;
; Summary : Copy the summary from the previous PULL Request&lt;br /&gt;
; Affects Versions : Select MOODLE_20_STABLE&lt;br /&gt;
; Security level : Same as the MDL&lt;br /&gt;
; Pull from repository : Copy from the previous PULL request&lt;br /&gt;
; Pull Branch : wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
; Pull Diff URL : https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
; Description : Copy from the previous PULL request&lt;br /&gt;
; Component : general&lt;br /&gt;
&lt;br /&gt;
Then click create to create the PULL request.&lt;br /&gt;
&lt;br /&gt;
Once the PULL request has been create don&#039;t forget to link to the MDL issue like we did for the previous PULL request.&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82842</id>
		<title>User:Sam Hemelryk/My Moodle Git workflow</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=User:Sam_Hemelryk/My_Moodle_Git_workflow&amp;diff=82842"/>
		<updated>2011-04-18T09:54:25Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: Created page with &amp;quot;This document is a sort of tutorial/inspection of my personal development workflow when working on Moodle with Git.  ==Creating the repositories== Ok so the very first step is to...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document is a sort of tutorial/inspection of my personal development workflow when working on Moodle with Git.&lt;br /&gt;
&lt;br /&gt;
==Creating the repositories==&lt;br /&gt;
Ok so the very first step is to create several Moodle git repositories, one for each major branch of Moodle being worked on.&lt;br /&gt;
&lt;br /&gt;
At the time of writing the major branches are MOODLE_19_STABLE, MOODLE_20_STABLE and master.&lt;br /&gt;
&lt;br /&gt;
The reason for this is that that way we have a separate site for each Moodle branch that we can test on easily. Yes you will have three sites but you won&#039;t have to worry about swtiching your site when you change branches.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Create a directory to create the repositories within===&lt;br /&gt;
&lt;br /&gt;
Personally I use Ubuntu (Linux) and I chose to create my repositories within a folder I created in /var/www. If you are using windows I would instead suggest creating C:/www/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www&lt;br /&gt;
mkdir repositories&lt;br /&gt;
cd repositories&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 2: Create a master repository===&lt;br /&gt;
This is the easiest of the branches to create a repository for.&lt;br /&gt;
&lt;br /&gt;
Within your repositories directory create a new directory called master and move into it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir master&lt;br /&gt;
cd master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we want to clone the Moodle source from the offical Moodle git repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new directory called moodle within the master directory we created just before.&lt;br /&gt;
&lt;br /&gt;
That new moodle directory should contain the Moodle source code as a git repository.&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our main git repository we need to add our github account as a remote so that we can push to it later:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd moodle&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This adds your moodle repository on github as a remote called github that you can push to later.&lt;br /&gt;
&lt;br /&gt;
Finally before we move onto the next repository we need to create a data directory because we know we will need that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 3: Create a MOODLE_20_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
The next repository we create will be for the MOODLE_20_STABLE branch.&lt;br /&gt;
To start with get back to the repositories directory that we created earlier and create a directory called MOODLE_20_STABLE within that.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_20_STABLE&lt;br /&gt;
cd MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now create a new clone of the main Moodle repository like we did for the master branch above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have done that move into the moodle directory.&lt;br /&gt;
&lt;br /&gt;
By default the master branch is the branch that is created, however we don&#039;t want that for this repository. Instead we want the MOODLE_20_STABLE branch.&lt;br /&gt;
&lt;br /&gt;
To do this we checkout local branch based upon the official MOODLE_20_STABLE branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have created that branch we can delete the local master branch so that we don&#039;t accidentally ever work on it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git branch -D master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then like we did for master we add our github repository as a remote:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And finally create a data directory we can use when we have install the site:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 4: Create a MOODLE_19_STABLE repository===&lt;br /&gt;
&lt;br /&gt;
This step is identical to the above step except we are using the MOODLE_19_STABLE branch instead of the MOODLE_20_STABLE branch.&lt;br /&gt;
The commands for this are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories&lt;br /&gt;
mkdir MOODLE_19_STABLE&lt;br /&gt;
cd MOODLE_19_STABLE&lt;br /&gt;
git clone git://git.moodle.org/moodle.git moodle&lt;br /&gt;
git checkout -b MOODLE_19_STABLE origin/MOODLE_19_STABLE&lt;br /&gt;
git branch -D master&lt;br /&gt;
git remote add github git@github.com:yourname/moodle.git&lt;br /&gt;
cd ..&lt;br /&gt;
mkdir data&lt;br /&gt;
sudo chmod -R 777 data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Step 5: Install the sites===&lt;br /&gt;
Now I can&#039;t tell you how to do this on your own machine however what I would recommend is that you create a link from your web root to the moodle directory of each branch.&lt;br /&gt;
&lt;br /&gt;
If you are using linux and your webroot is /var/www/localhost you would do it as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/localhost/&lt;br /&gt;
ln -s /var/www/repositories/master/moodle master&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_20_STABLE/moodle MOODLE_20_STABLE&lt;br /&gt;
ln -s /var/www/repositories/MOODLE_19_STABLE/moodle MOODLE_19_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With that done you should be able to browse to each repository with the following URL&#039;s&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://localhost/master/&lt;br /&gt;
http://localhost/MOODLE_20_STABLE/&lt;br /&gt;
http://localhost/MOODLE_19_STABLE/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once that is done you need to browse to each site and complete the installation.&lt;br /&gt;
&lt;br /&gt;
Under this method your will need to ensure you set the configuration option sessioncookiepath to the URI of your site. You can either do this in the admin interfaces or add the following to your config.php file for each site.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// For the master site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/master/&#039;;&lt;br /&gt;
// For the MOODLE_20_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_20_STABLE/&#039;;&lt;br /&gt;
// For the MOODLE_19_STABLE site&lt;br /&gt;
$CFG-&amp;gt;sessioncookiepath = &#039;/MOODLE_19_STABLE/&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Failure to do this will mean that when you log in at one site and then visit the next you will have to log in again and your session on the first site will no longer work.&lt;br /&gt;
&lt;br /&gt;
Now that you have got 3 repositories, one for each main branch, and set up a site for each you are ready to start development.&lt;br /&gt;
&lt;br /&gt;
==Working on a Moodle issue==&lt;br /&gt;
&lt;br /&gt;
This part of the document looks at how I go about working on an MDL issue from the Moodle tracker.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ we use the scrum methodology we sees us choose several issues to include in a scrum which we then work on for the period of the scrum. As a community member its more likely you will just be choosing issues that you are passionate about.&lt;br /&gt;
&lt;br /&gt;
Either way once you have found an issue to work on you are ready to start.&lt;br /&gt;
&lt;br /&gt;
For the purpose of this part of the document lets say I am going to work on bug MDL-12345.&lt;br /&gt;
&lt;br /&gt;
==Fixing a bug on the master repository - MDL-12345==&lt;br /&gt;
&lt;br /&gt;
The first step is to create a local branch to make changes on, to do this we will start our work on the master repository.&lt;br /&gt;
&lt;br /&gt;
When fixing an issue I find it easiest to fix the issue on the master branch first and then move my changes to the other branches.&lt;br /&gt;
&lt;br /&gt;
The VERY first thing you should do when you start working on a Moodle issue is make sure you have assigned it to yourself and then click the start progress button.&lt;br /&gt;
&lt;br /&gt;
This way other users know that you are activly working on the bug and no one from HQ will steal it from you.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local branch===&lt;br /&gt;
&lt;br /&gt;
So first get to the master repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/master/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there we create a new branch as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-master origin/master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command checks out a new branch called wip-MDL-12345-master that is based upon origin/master.&lt;br /&gt;
&lt;br /&gt;
origin/master is of course the master branch on the official Moodle repository (git.moodle.org/moodle.git).&lt;br /&gt;
&lt;br /&gt;
The name of the branch is also very important. It is essentially telling us three things.&lt;br /&gt;
&lt;br /&gt;
; wip : This stands for work in progress, it helps people see that you are currently working on this branch and that they shouldn&#039;t base there work on it because it will likely change.&lt;br /&gt;
; MDL-12345 : This is of course the Moodle bug number. It helps people quickly identify what you are working on.&lt;br /&gt;
; master : This is the branch we are making changes on. It helps people quickly understand where the changes are being made.&lt;br /&gt;
&lt;br /&gt;
You can optionally add more to the end of the branch name such as a key word that identifies the area or a date at which you started work e.g.&lt;br /&gt;
&lt;br /&gt;
* wip-MDL-12345-master-navigation-changes&lt;br /&gt;
* wip-MDL-12345-master-20110418&lt;br /&gt;
&lt;br /&gt;
That is up to you, personally I&#039;m not a fan of it, however the rest is all required to help integrate your work.&lt;br /&gt;
&lt;br /&gt;
Either way now you have a branch, mine is called wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Make changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have created you branch you are ready to make changes.&lt;br /&gt;
&lt;br /&gt;
I&#039;ll let you make whatever changes you are need, once you have made changes move onto the next step.&lt;br /&gt;
&lt;br /&gt;
Before you do move on however make sure that your code meets the high quality of code Moodle requires.&lt;br /&gt;
&lt;br /&gt;
You can find information about that on the moodle docs here: https://docs.moodle.org/en/Development:Coding_style&lt;br /&gt;
&lt;br /&gt;
The following are common mistakes:&lt;br /&gt;
&lt;br /&gt;
* Incorrect white space&lt;br /&gt;
** Tabs instead of spaces&lt;br /&gt;
** Extra spaces at the end of lines&lt;br /&gt;
** Multiple new lines&lt;br /&gt;
** Forgetting to put spaces between function arguments&lt;br /&gt;
* Incorrect commit messages (read on to find out about writing a good commit message)&lt;br /&gt;
* Incorrect variable or function names&lt;br /&gt;
&lt;br /&gt;
Making these sort of mistakes can lead to your code being rejected despite it working correctly.&lt;br /&gt;
&lt;br /&gt;
Or course it will be reviewed in regards to security, usability and the other important factors of code development.&lt;br /&gt;
&lt;br /&gt;
===Step 3: Commit your changes===&lt;br /&gt;
&lt;br /&gt;
Now that you have made your changes you are getting ready to commit them.&lt;br /&gt;
&lt;br /&gt;
The first thing to do is check your changes. To do this run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see all of the files you have changes highlighted in red.&lt;br /&gt;
&lt;br /&gt;
Next you need to stage all of the files you want to commit.&lt;br /&gt;
&lt;br /&gt;
To do this you add the files to the stage using the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git add lib/modifiedfile.php&lt;br /&gt;
git add lib/newfile.php&lt;br /&gt;
git add theme/base/style/core.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Why not just commit all changes. Many of the git guides you read will tell you above git commit -a which commits all of the changes you have made.&lt;br /&gt;
&lt;br /&gt;
We&#039;ve hardly being using git here at Moodle and already I&#039;ve seen several people accidentally commit changes that they didn&#039;t mean to.&lt;br /&gt;
&lt;br /&gt;
Staging files like this ENSURES you only commit things you intend to.&lt;br /&gt;
&lt;br /&gt;
Now that you have staged your changes/new files you are ready to commit. The following command commits your changes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git commit -m &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command commits your changes with the commit message &amp;quot;MDL-12345 enrol - Fixed up a couple of enrolment bugs&amp;quot;.&lt;br /&gt;
It&#039;s very important to Moodle that you format your commit messages like this.&lt;br /&gt;
They consist of three parts:&lt;br /&gt;
&lt;br /&gt;
# The MDL bug number in this case MDL-12345&lt;br /&gt;
# The area you made changes to in this case enrol&lt;br /&gt;
# A short description of what you did, in this case I fixed a couple of enrolment bugs.&lt;br /&gt;
&lt;br /&gt;
When you commit your message you will see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[master 19a484e] changes&lt;br /&gt;
 1 files changed, 16 insertions(+), 18 deletions(-)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
There is one thing here you need to note down for later, that is the number that appears within the square brackets after the branch name, in my case it is 19a484e. This is the commit id of the commit I just made.&lt;br /&gt;
&lt;br /&gt;
===Step 4: Pushing your changes to your github account===&lt;br /&gt;
&lt;br /&gt;
Now that you have made changes to your local branch you should push it to your github account so that it can be reviewed and hopefully integrated into Moodle.&lt;br /&gt;
&lt;br /&gt;
Doing this is very simple just run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we are telling git to push the branch wip-MDL-12345-master to the remote called github which we added when setting up our git repositories.&lt;br /&gt;
And just like that you&#039;ve made a branch that contains your work and pushed it to github ready to get it reviewed.&lt;br /&gt;
&lt;br /&gt;
==Moving your changes to another branch==&lt;br /&gt;
Now that you have made changes to the master branch you need to decide whether it is appropriate make those changes on any of the other branches.&lt;br /&gt;
Most likely if you are fixing a bug you will need to make the changes on the MOODLE_20_STABLE branch as well, and perhaps the MOODLE_19_STABLE branch if it is a security bug.&lt;br /&gt;
&lt;br /&gt;
Lets assume for MDL-12345 that I fixed earlier that it should be ported to MOODLE_20_STABLE as well.&lt;br /&gt;
&lt;br /&gt;
===Step 1: Creating a local MOODLE_20_STABLE branch===&lt;br /&gt;
&lt;br /&gt;
To start with I need to move to the MOODLE_20_STABLE repository as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /var/www/repositories/MOODLE_20_STABLE/moodle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once there I need to create a new branch based upon the MOODLE_20_STABLE branch that is going to contain my changes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout -b wip-MDL-12345-MOODLE_20_STABLE origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very similar to the branch we created for the changes to the master branch except that I have subsituted MOODLE_20_STABLE in place of master. This is because the new branch we are creating is based upon the MOODLE_20_STABLE branch on the offical Moodle git repository and contains changes for that branch.&lt;br /&gt;
&lt;br /&gt;
===Step 2: Cherry-picking my changes===&lt;br /&gt;
Once we have a branch for our changes I am ready to make them again. There is however with git an easy way to do this, cherry-picking.&lt;br /&gt;
&lt;br /&gt;
Cherry-picking is the process of copying a single commit from one branch to another. In this case I want to cherry pick the commit I made earlier onto the branch I&#039;ve just created.&lt;br /&gt;
&lt;br /&gt;
However before I can do this I need to fetch the changes I made from the github repository. I need to do this because I made that changes of a totally separate local repository remember.&lt;br /&gt;
&lt;br /&gt;
So to update my repository with the latest changes I run the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git fetch --all --prune&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command tells git to look at each remote and get any new changes (it also removes any branches that have been deleted).&lt;br /&gt;
Once it has completed you will be ready to cherry pick the commit. To do so you use the following command but replace my commit is with yours.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git cherry-pick 19a484e&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Providing there are no conflicts your branch will now contain a copy of the changes you made to the master branch.&lt;br /&gt;
If there are conficts that you will need to resolve them and commit your changes however you can search for another tutorial about how to do that,&lt;br /&gt;
&lt;br /&gt;
Now I know at this point that there will be some of you who are saying &#039;Whoops I forgot what my commit id was!&#039;. If this is you don&#039;t worry, its pretty easy to find it providing you used a proper commit message like I described above.&lt;br /&gt;
Simply run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git log --oneline origin/master..github/wip-MDL-12345-master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the commits that are in the wip-MDL-12345-master at your github account but are not in the master branch at the offical Moodle repository.&lt;br /&gt;
You can then cherry-pick the commits shown there (the commit ID&#039;s should be highlighted in yellow).&lt;br /&gt;
&lt;br /&gt;
Once you have cherry-picked your commits its time to check that everything worked, run the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see something like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# On branch wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
# Your branch is ahead of &#039;origin/MOODLE_20_STABLE&#039; by 1 commit.&lt;br /&gt;
#&lt;br /&gt;
nothing to commit (working directory clean)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is very handy as it tells you that your branch is ahead of the offical MOODLE_20_STABLE branch by one commit.&lt;br /&gt;
You can also check that your commit contains the changes you think by running the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git diff origin/MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This command shows you all of the changes you have made as a diff.&lt;br /&gt;
&lt;br /&gt;
Now that you know that your commit is there you and that it is correct it is time to push it to your github account.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push github wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And thats it.&lt;br /&gt;
&lt;br /&gt;
You github account should now have two branches on it:&lt;br /&gt;
&lt;br /&gt;
; wip-MDL-12345-master : This branch is the changes you have made for the master branch&lt;br /&gt;
; wip-MDL-12345-MOODLE_20_STABLE : This branch is those same changes but for the MOODLE_20_STABLE branch&lt;br /&gt;
&lt;br /&gt;
Now you are ready to create PULL requests so that your work gets reviewed and hopefully integrated.&lt;br /&gt;
&lt;br /&gt;
==Creating a PULL request for the master branch==&lt;br /&gt;
&lt;br /&gt;
So you have successfully fixed the bug MDL-12345, you have created two branches one for master and one for MOODLE_20_STABLE. It is time to create a PULL request for each of these branches.&lt;br /&gt;
&lt;br /&gt;
First lets create a PULL request for the master branch:&lt;br /&gt;
&lt;br /&gt;
# Browse to tracker.moodle.org/browse/MDL-12345&lt;br /&gt;
# When the page loads log in if you haven&#039;t already.&lt;br /&gt;
# Click on the button in the top right labelled `Create issue`&lt;br /&gt;
# Change Project to `Pull Requests`&lt;br /&gt;
# Change Issue type to `Pull Request`&lt;br /&gt;
# Click create&lt;br /&gt;
&lt;br /&gt;
This takes you to a screen where you can enter the details for the PULL request.&lt;br /&gt;
&lt;br /&gt;
You should fill it out in the following way:&lt;br /&gt;
&lt;br /&gt;
===Summary===&lt;br /&gt;
This is the summary for the PULL request, you should copy and paste the summary from the MDL issue here.&lt;br /&gt;
For MDL-12345 the summary is `alphabetization of UI different on left and right sides` so that&#039;s what I will use.&lt;br /&gt;
&lt;br /&gt;
===Affects Versions===&lt;br /&gt;
This is the version that your branch is changing, in the case of this PULL request I will select `master`.&lt;br /&gt;
&lt;br /&gt;
===Security level===&lt;br /&gt;
If the issue you are working on is a security issue you should set this to the same level that the issue is set to. If its not a security issue or you don&#039;t know just leave it as none.&lt;br /&gt;
&lt;br /&gt;
===Pull from repository===&lt;br /&gt;
This is the repository that the branch is at, for you this will be your github accont. If you head to http://github.com/yourname/moodle you will see a box that has three options SSH, HTTP, and Git read only, click Git Read Only and then copy the contents of the text box into the repositry field of the PULL request. &lt;br /&gt;
For me that is git://github.com/yourname/moodle.git&lt;br /&gt;
&lt;br /&gt;
===Pull branch===&lt;br /&gt;
This is the name of the branch that contains your changes. For me that is wip-MDL-12345-master.&lt;br /&gt;
&lt;br /&gt;
===Pull Diff URL===&lt;br /&gt;
This is the URL to a page that shows the changes that you&#039;ve made on your branch. Github is nice in that it has a pretty interface for that. To get to the interface follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Browse to https://github.com/youraccount/moodle&lt;br /&gt;
# Click `Switch Branches` and then click on the branch you changes are based upon, in my case master.&lt;br /&gt;
# Click the button labelled `Branch List`&lt;br /&gt;
# Locate your branch in the list and click the `Compare button` for me this was the compare button to the right of wip-MDL-12345-master.&lt;br /&gt;
# Copy the URL in your browse and paste it into the Pull Diff URL of the PULL request.&lt;br /&gt;
&lt;br /&gt;
For me this URL was: https://github.com/yourname/moodle/compare/master...wip-MDL-23532-master&lt;br /&gt;
For the MOODLE_20_STABLE branch this would be: https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
&lt;br /&gt;
===Description===&lt;br /&gt;
The description should contain several bits of important information:&lt;br /&gt;
&lt;br /&gt;
# A short description of what your patch does&lt;br /&gt;
# Notes about that changes you&#039;ve made that might help the integrator understand what you did when he/she is reviewing it.&lt;br /&gt;
# Testing instructions that guide the testers through testing your changes.&lt;br /&gt;
&lt;br /&gt;
===Components===&lt;br /&gt;
Select general from the components list, general is the only option.&lt;br /&gt;
&lt;br /&gt;
===Finishing up===&lt;br /&gt;
Once you have filled in the fields as above click `Create`. This should create you PULL request and then take you to view it.&lt;br /&gt;
&lt;br /&gt;
Its important to remember that there is still one thing you need to do and that is link to the original issue.&lt;br /&gt;
While you are still logged in click the `More Actions` button and select `Link issue`, in the dialoug that pops up change the `This issue` field to `will help resolve`, type MDL-12345 into the issues field, and then type `Linking to MDL-12345` into the comments box. Once you&#039;ve done that simple click Link.&lt;br /&gt;
&lt;br /&gt;
Time to create the PULL request for the other branches.&lt;br /&gt;
&lt;br /&gt;
==Creating the PULL request for MOODLE_20_STABLE==&lt;br /&gt;
Once you&#039;ve created the PULL request for the master branch it is time to create the PULL request for the MOODLE_20_STABLE branch.&lt;br /&gt;
This is as easy as can be, click Create Issue in the top right, select PULL project and choose Pull Request and then click create.&lt;br /&gt;
On the next screen enter the following details:&lt;br /&gt;
&lt;br /&gt;
; Summary : Copy the summary from the previous PULL Request&lt;br /&gt;
; Affects Versions : Select MOODLE_20_STABLE&lt;br /&gt;
; Security level : Same as the MDL&lt;br /&gt;
; Pull from repository : Copy from the previous PULL request&lt;br /&gt;
; Pull Branch : wip-MDL-12345-MOODLE_20_STABLE&lt;br /&gt;
; Pull Diff URL : https://github.com/yourname/moodle/compare/MOODLE_20_STABLE...wip-MDL-23532-MOODLE_20_STABLE&lt;br /&gt;
; Description : Copy from the previous PULL request&lt;br /&gt;
; Component : general&lt;br /&gt;
&lt;br /&gt;
Then click create to create the PULL request.&lt;br /&gt;
&lt;br /&gt;
Once the PULL request has been create don&#039;t forget to link to the MDL issue like we did for the previous PULL request.&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_adding_upgrade_code&amp;diff=82693</id>
		<title>Development:Themes 2.0 adding upgrade code</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_adding_upgrade_code&amp;diff=82693"/>
		<updated>2011-04-11T07:23:30Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* Step 2: install.php */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;As theme&#039;s have got considerably more advanced in Moodle 2 there is now on occasion a need to write upgrade code for a theme. This quick tutorial looks at just how to do that.&lt;br /&gt;
&lt;br /&gt;
==Why?==&lt;br /&gt;
As part of the Moodle 2 revamp theme&#039;s have been given the same abilities as many of the other plugin types within Moodle. They are now able to have settings pages, database tables, they can override renderers, and they can do all sorts of great things.&lt;br /&gt;
&lt;br /&gt;
Unfortunately this change has its positives and negatives, on the positive you can now really get some cool stuff happening within a theme, the downside is just like any other plugin you need to think about those who are already using your theme when you make changes.&lt;br /&gt;
&lt;br /&gt;
If you are changing the name of a setting, or if you are changing the database schema for the theme you will need to add upgrade code to your theme so that those who are already using your theme are moved along nicely and don&#039;t lose the effort they&#039;ve put into customising and setting up your theme.&lt;br /&gt;
&lt;br /&gt;
==Step 1: version.php==&lt;br /&gt;
For those of you who are already familiar with writing Moodle plugins you will be familiar with the version.php, however for many themer&#039;s the reality is that they&#039;ve never gone beyond adding a settings page so this will be new.&lt;br /&gt;
&lt;br /&gt;
The version.php file is a requirement for many plugin types, however for theme&#039;s it is optional. The idea is that it contains just two or three lines of code that tell Moodle what version the plugin is and a little bit about where it is meant to be, or what version of Moodle it requires. The version.php file for a theme should be created within the theme&#039;s base directory e.g. &#039;&#039;moodle/theme/mythemename/version.php&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The following is an example of what a version.php file for a theme looks like.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This is the version.php file for my theme.&lt;br /&gt;
 */&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die;&lt;br /&gt;
&lt;br /&gt;
$plugin-&amp;gt;version   = 2011032900;&lt;br /&gt;
$plugin-&amp;gt;component = &#039;theme_mythemename&#039;;&lt;br /&gt;
$plugin-&amp;gt;requires  = 2010122500;&lt;br /&gt;
$plugin-&amp;gt;maturity  = MATURITY_STABLE;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first thing to notice here is that we are setting properties of an object called $plugin, this object will be used to describe our theme.&lt;br /&gt;
We are setting four properties here, version, component, requires, and maturity. The version property is required and the rest are optional however it is best practice to put them in as well.&lt;br /&gt;
===The version property===&lt;br /&gt;
The version property is the version number of our theme and needs to be an integer, although you can set it to any integer value you want it is &#039;&#039;&#039;HIGHLY&#039;&#039;&#039; recommended to use the date format shown above as it is used everywhere else throughout Moodle.&lt;br /&gt;
&lt;br /&gt;
The format is YYYYMMDDXX :&lt;br /&gt;
# YYYY is the four digit year, e.g. 2011&lt;br /&gt;
# MM is the month with preceding 0 if required, e.g. 03&lt;br /&gt;
# DD is the day with preceding 0 is required, e.g. 28&lt;br /&gt;
# XX is an incrementing value starting at 00, you can increment this if you add several upgrade code blocks on the same day.&lt;br /&gt;
&lt;br /&gt;
As a hint its easiest just to set the version property to today&#039;s date when adding upgrade code, or releasing a version of your theme that introduces something new such as a database table, or config setting.&lt;br /&gt;
&lt;br /&gt;
===The component property===&lt;br /&gt;
The component is used to describe the plugin and its type. In our case we are working with themes and the theme name I have used in my example is mythemename, therefore the component is theme_mythemename.&lt;br /&gt;
&lt;br /&gt;
When installing or upgrading a plugin Moodle checks the component and uses it to make sure that the plugin has been installed in the correct location. This is particularly helpful for the end user as it prevents nasty accidents where they accidentally put a plugin in the wrong place.&lt;br /&gt;
&lt;br /&gt;
If you are working on other types of plugins the component of course will differ, its best to refer to the docs for those plugin types to find out what you would have to use there.&lt;br /&gt;
&lt;br /&gt;
===The requires property===&lt;br /&gt;
The requires property sets the version of Moodle that is required by this plugin. This is particularly handy if your plugin makes use of a feature that was introduced in a specific version of Moodle, or if your plugin relies on a bug fix that was introduced in a specific version.&lt;br /&gt;
&lt;br /&gt;
You can find the current Moodle version by looking at main Moodle version.php file. In the example above I have set my theme to require Moodle 2.0.1 by setting the requires property to Moodle&#039;s version number when that was released. If you are trying to find out a specific version number you can do so by heading to https://github.com/moodle/moodle, changing the tag drop down to the version you desire, then inspecting the version.php file at the bottom of the files list. You should see $version = XXXXXXXXXX;.&lt;br /&gt;
&lt;br /&gt;
===The maturity property===&lt;br /&gt;
This is a property that is expected to be fully supported in Moodle 2.1. It informs Moodle about the state of the code and can be one of the following values:&lt;br /&gt;
; MATURITY_STABLE : Use this when the theme is stable and works well.&lt;br /&gt;
; MATURITY_RC : This marks the theme as a release candidate, users can expect the theme to contain one or two bugs but be largely stable and usable.&lt;br /&gt;
; MATURITY_BETA : This marks the theme as a beta release, users can expect the theme to contain several bugs and for it to be likely to change still.&lt;br /&gt;
; MATURITY_ALPHA : This marks the theme as an alpha release, this is the first release of a new theme and users will expect to find a lot still needs to be done.&lt;br /&gt;
&lt;br /&gt;
==Step 2: install.php==&lt;br /&gt;
If as part of this upgrade you are adding a version.php file to your theme then you will need to add your upgrade code to install.php rather than upgrade.php.&lt;br /&gt;
&lt;br /&gt;
The reason for this is because Moodle processes install.php the first time that a version number is used rather than upgrade.php.&lt;br /&gt;
&lt;br /&gt;
The install.php file should contain a single function that needs to be named following a strict naming scheme and it should be located in a directory called db located within your theme&#039;s directory, for example &#039;&#039;&#039;moodle/theme/mythemename/db/install.php&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
For this example I have called my theme &#039;&#039;mythemename&#039;&#039; so the function will be as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die();&lt;br /&gt;
&lt;br /&gt;
function xmldb_theme_mythemename_install() {&lt;br /&gt;
    // We&#039;ll look at what is in here shortly.&lt;br /&gt;
&lt;br /&gt;
    return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This special function is called when a theme is first installed (if it has a version.php file and it has been newly added to your Moodle site) or the first time that the theme has a version.php file if you are developing or upgrading a theme.&lt;br /&gt;
&lt;br /&gt;
The install function can perform any upgrade routines you require. For the following example lets assume I have two settings for my theme, &#039;&#039;mythemename_settingone&#039;&#039;, and &#039;&#039;mythemename_settingtwo&#039;&#039;. As part of my upgrade I want to rename the settings to mythemename_settinga, and mythemename_settingb.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die();&lt;br /&gt;
&lt;br /&gt;
function xmldb_theme_mythemename_install() {&lt;br /&gt;
    $currentsetting = get_config(&#039;theme_mythemename&#039;);&lt;br /&gt;
&lt;br /&gt;
    // Create a new config called settinga and give it settingone&#039;s value.&lt;br /&gt;
    set_config(&#039;settinga&#039;, $currentsetting-&amp;gt;settingone, &#039;theme_mythemename&#039;);&lt;br /&gt;
    // Remove settingone&lt;br /&gt;
    unset_config(&#039;settingone&#039;, &#039;theme_mythemename&#039;);&lt;br /&gt;
&lt;br /&gt;
    // Create a new config called settingb and give it settingtwo&#039;s value.&lt;br /&gt;
    set_config(&#039;settingb&#039;, $currentsetting-&amp;gt;settingtwo, &#039;theme_mythemename&#039;);&lt;br /&gt;
    // Remove settingtwo&lt;br /&gt;
    unset_config(&#039;settingtwo&#039;, &#039;theme_mythemename&#039;);&lt;br /&gt;
&lt;br /&gt;
    return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Looking at this code it does the following things:&lt;br /&gt;
# The install code gets the current settings so that we can change them.&lt;br /&gt;
# It creates a new setting called settinga and we give it settingb&#039;s value.&lt;br /&gt;
# It deletes settingone as we no longer want it.&lt;br /&gt;
# It repeats the last two steps for settingb/settingtwo.&lt;br /&gt;
# It returns true so that Moodle knows the installation was successful.&lt;br /&gt;
&lt;br /&gt;
And thats it, there&#039;s no need to add an upgrade.php file at this point.&lt;br /&gt;
&lt;br /&gt;
==Step 3: upgrade.php==&lt;br /&gt;
The upgrade.php script allows you to write upgrade code for subsequent upgrade requirements for your theme. If your theme already has a version.php then you should bump the version number there and add your upgrade code here.&lt;br /&gt;
&lt;br /&gt;
This is the main upgrade file. It should be located in a directory called &#039;&#039;db&#039;&#039; located within your theme&#039;s directory, for example &#039;&#039;&#039;moodle/theme/mythemename/db/upgrade.php&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The upgrade.php file should contain just a single function that needs to be named following a strict naming scheme. In the case of my theme that for this example I&#039;ve called mythemename that function will be as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die();&lt;br /&gt;
&lt;br /&gt;
function xmldb_theme_mythemename_upgrade($oldversion) {&lt;br /&gt;
    // We&#039;ll look at what is in here shortly.&lt;br /&gt;
&lt;br /&gt;
    return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This special function gets called when ever the admin is upgrading the site and gives our theme the opportunity to run any upgrade code it requires.&lt;br /&gt;
&lt;br /&gt;
Upgrade code within this function should be written in a special style where each operation is written as a block and the theme version is upgraded incrementally after each operation.&lt;br /&gt;
&lt;br /&gt;
For the following example lets assume I have two settings for my theme, &#039;&#039;mythemename_settingone&#039;&#039;, and &#039;&#039;mythemename_settingtwo&#039;&#039;. As part of my upgrade I want to rename the settings to mythemename_settinga, and mythemename_settingb.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die();&lt;br /&gt;
&lt;br /&gt;
function xmldb_theme_mythemename_upgrade($oldversion) {&lt;br /&gt;
    &lt;br /&gt;
    if ($oldversion &amp;lt; 2011032900) {&lt;br /&gt;
        $currentsetting = get_config(&#039;theme_mythemename&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Create a new config called settinga and give it settingone&#039;s value.&lt;br /&gt;
        set_config(&#039;settinga&#039;, $currentsetting-&amp;gt;settingone, &#039;theme_mythemename&#039;);&lt;br /&gt;
        // Remove settingone&lt;br /&gt;
        unset_config(&#039;settingone&#039;, &#039;theme_mythemename&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Create a new config called settingb and give it settingtwo&#039;s value.&lt;br /&gt;
        set_config(&#039;settingb&#039;, $currentsetting-&amp;gt;settingtwo, &#039;theme_mythemename&#039;);&lt;br /&gt;
        // Remove settingtwo&lt;br /&gt;
        unset_config(&#039;settingtwo&#039;, &#039;theme_mythemename&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Upgrade the version that Moodle knows is installed so that this upgrade&lt;br /&gt;
        // isn&#039;t run again.&lt;br /&gt;
        upgrade_plugin_savepoint(true, 2011032900, &#039;theme&#039;, &#039;mythemename&#039;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Looking at this code it does the following things:&lt;br /&gt;
# It compares and the &#039;&#039;&#039;$oldversion&#039;&#039;&#039; to the version we set (2011032900) and our version is newer it runs the upgrade code.&lt;br /&gt;
# The upgrade code gets the current settings so that we can change them.&lt;br /&gt;
# It creates a new setting called settinga and we give it settingb&#039;s value.&lt;br /&gt;
# It deletes settingone as we no longer want it.&lt;br /&gt;
# It repeats the last two steps for settingb/settingtwo.&lt;br /&gt;
# It updates the version Moodle knows is installed by calling &#039;&#039;upgrade_plugin_savepoint&#039;&#039;&lt;br /&gt;
# Finally the function returns true so that the rest of the upgrade continues.&lt;br /&gt;
&lt;br /&gt;
==Done==&lt;br /&gt;
Just like that we have added upgrade code to our theme that renames two settings. To do that we had to add a version.php file and a upgrade.php file.&lt;br /&gt;
&lt;br /&gt;
==More information==&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]]&lt;br /&gt;
* [[Development:Themes 2.0 adding a settings page]]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_adding_upgrade_code&amp;diff=82692</id>
		<title>Development:Themes 2.0 adding upgrade code</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_adding_upgrade_code&amp;diff=82692"/>
		<updated>2011-04-11T07:21:56Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* Step 2: install.php */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;As theme&#039;s have got considerably more advanced in Moodle 2 there is now on occasion a need to write upgrade code for a theme. This quick tutorial looks at just how to do that.&lt;br /&gt;
&lt;br /&gt;
==Why?==&lt;br /&gt;
As part of the Moodle 2 revamp theme&#039;s have been given the same abilities as many of the other plugin types within Moodle. They are now able to have settings pages, database tables, they can override renderers, and they can do all sorts of great things.&lt;br /&gt;
&lt;br /&gt;
Unfortunately this change has its positives and negatives, on the positive you can now really get some cool stuff happening within a theme, the downside is just like any other plugin you need to think about those who are already using your theme when you make changes.&lt;br /&gt;
&lt;br /&gt;
If you are changing the name of a setting, or if you are changing the database schema for the theme you will need to add upgrade code to your theme so that those who are already using your theme are moved along nicely and don&#039;t lose the effort they&#039;ve put into customising and setting up your theme.&lt;br /&gt;
&lt;br /&gt;
==Step 1: version.php==&lt;br /&gt;
For those of you who are already familiar with writing Moodle plugins you will be familiar with the version.php, however for many themer&#039;s the reality is that they&#039;ve never gone beyond adding a settings page so this will be new.&lt;br /&gt;
&lt;br /&gt;
The version.php file is a requirement for many plugin types, however for theme&#039;s it is optional. The idea is that it contains just two or three lines of code that tell Moodle what version the plugin is and a little bit about where it is meant to be, or what version of Moodle it requires. The version.php file for a theme should be created within the theme&#039;s base directory e.g. &#039;&#039;moodle/theme/mythemename/version.php&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The following is an example of what a version.php file for a theme looks like.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This is the version.php file for my theme.&lt;br /&gt;
 */&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die;&lt;br /&gt;
&lt;br /&gt;
$plugin-&amp;gt;version   = 2011032900;&lt;br /&gt;
$plugin-&amp;gt;component = &#039;theme_mythemename&#039;;&lt;br /&gt;
$plugin-&amp;gt;requires  = 2010122500;&lt;br /&gt;
$plugin-&amp;gt;maturity  = MATURITY_STABLE;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first thing to notice here is that we are setting properties of an object called $plugin, this object will be used to describe our theme.&lt;br /&gt;
We are setting four properties here, version, component, requires, and maturity. The version property is required and the rest are optional however it is best practice to put them in as well.&lt;br /&gt;
===The version property===&lt;br /&gt;
The version property is the version number of our theme and needs to be an integer, although you can set it to any integer value you want it is &#039;&#039;&#039;HIGHLY&#039;&#039;&#039; recommended to use the date format shown above as it is used everywhere else throughout Moodle.&lt;br /&gt;
&lt;br /&gt;
The format is YYYYMMDDXX :&lt;br /&gt;
# YYYY is the four digit year, e.g. 2011&lt;br /&gt;
# MM is the month with preceding 0 if required, e.g. 03&lt;br /&gt;
# DD is the day with preceding 0 is required, e.g. 28&lt;br /&gt;
# XX is an incrementing value starting at 00, you can increment this if you add several upgrade code blocks on the same day.&lt;br /&gt;
&lt;br /&gt;
As a hint its easiest just to set the version property to today&#039;s date when adding upgrade code, or releasing a version of your theme that introduces something new such as a database table, or config setting.&lt;br /&gt;
&lt;br /&gt;
===The component property===&lt;br /&gt;
The component is used to describe the plugin and its type. In our case we are working with themes and the theme name I have used in my example is mythemename, therefore the component is theme_mythemename.&lt;br /&gt;
&lt;br /&gt;
When installing or upgrading a plugin Moodle checks the component and uses it to make sure that the plugin has been installed in the correct location. This is particularly helpful for the end user as it prevents nasty accidents where they accidentally put a plugin in the wrong place.&lt;br /&gt;
&lt;br /&gt;
If you are working on other types of plugins the component of course will differ, its best to refer to the docs for those plugin types to find out what you would have to use there.&lt;br /&gt;
&lt;br /&gt;
===The requires property===&lt;br /&gt;
The requires property sets the version of Moodle that is required by this plugin. This is particularly handy if your plugin makes use of a feature that was introduced in a specific version of Moodle, or if your plugin relies on a bug fix that was introduced in a specific version.&lt;br /&gt;
&lt;br /&gt;
You can find the current Moodle version by looking at main Moodle version.php file. In the example above I have set my theme to require Moodle 2.0.1 by setting the requires property to Moodle&#039;s version number when that was released. If you are trying to find out a specific version number you can do so by heading to https://github.com/moodle/moodle, changing the tag drop down to the version you desire, then inspecting the version.php file at the bottom of the files list. You should see $version = XXXXXXXXXX;.&lt;br /&gt;
&lt;br /&gt;
===The maturity property===&lt;br /&gt;
This is a property that is expected to be fully supported in Moodle 2.1. It informs Moodle about the state of the code and can be one of the following values:&lt;br /&gt;
; MATURITY_STABLE : Use this when the theme is stable and works well.&lt;br /&gt;
; MATURITY_RC : This marks the theme as a release candidate, users can expect the theme to contain one or two bugs but be largely stable and usable.&lt;br /&gt;
; MATURITY_BETA : This marks the theme as a beta release, users can expect the theme to contain several bugs and for it to be likely to change still.&lt;br /&gt;
; MATURITY_ALPHA : This marks the theme as an alpha release, this is the first release of a new theme and users will expect to find a lot still needs to be done.&lt;br /&gt;
&lt;br /&gt;
==Step 2: install.php==&lt;br /&gt;
If as part of this upgrade you are adding a version.php file to your theme then you will need to add your upgrade code to install.php rather than upgrade.php.&lt;br /&gt;
&lt;br /&gt;
The reason for this is because Moodle processes install.php the first time that a version number is used rather than upgrade.php.&lt;br /&gt;
&lt;br /&gt;
The install.php file should contain a single function that needs to be named following a strict naming scheme and it should be located in a directory called db located within your theme&#039;s directory, for example moodle/theme/mythemename/db/install.php.&lt;br /&gt;
&lt;br /&gt;
For this example I have called my theme &#039;&#039;mythemename&#039;&#039; so the function will be as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die();&lt;br /&gt;
&lt;br /&gt;
function xmldb_theme_mythemename_install() {&lt;br /&gt;
    // We&#039;ll look at what is in here shortly.&lt;br /&gt;
&lt;br /&gt;
    return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This special function is called when a theme is first installed (if it has a version.php file and it has been newly added to your Moodle site) or the first time that the theme has a version.php file if you are developing or upgrading a theme.&lt;br /&gt;
&lt;br /&gt;
The install function can perform any upgrade routines you require. For the following example lets assume I have two settings for my theme, &#039;&#039;mythemename_settingone&#039;&#039;, and &#039;&#039;mythemename_settingtwo&#039;&#039;. As part of my upgrade I want to rename the settings to mythemename_settinga, and mythemename_settingb.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die();&lt;br /&gt;
&lt;br /&gt;
function xmldb_theme_mythemename_install() {&lt;br /&gt;
    $currentsetting = get_config(&#039;theme_mythemename&#039;);&lt;br /&gt;
&lt;br /&gt;
    // Create a new config called settinga and give it settingone&#039;s value.&lt;br /&gt;
    set_config(&#039;settinga&#039;, $currentsetting-&amp;gt;settingone, &#039;theme_mythemename&#039;);&lt;br /&gt;
    // Remove settingone&lt;br /&gt;
    unset_config(&#039;settingone&#039;, &#039;theme_mythemename&#039;);&lt;br /&gt;
&lt;br /&gt;
    // Create a new config called settingb and give it settingtwo&#039;s value.&lt;br /&gt;
    set_config(&#039;settingb&#039;, $currentsetting-&amp;gt;settingtwo, &#039;theme_mythemename&#039;);&lt;br /&gt;
    // Remove settingtwo&lt;br /&gt;
    unset_config(&#039;settingtwo&#039;, &#039;theme_mythemename&#039;);&lt;br /&gt;
&lt;br /&gt;
    return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Looking at this code it does the following things:&lt;br /&gt;
# The install code gets the current settings so that we can change them.&lt;br /&gt;
# It creates a new setting called settinga and we give it settingb&#039;s value.&lt;br /&gt;
# It deletes settingone as we no longer want it.&lt;br /&gt;
# It repeats the last two steps for settingb/settingtwo.&lt;br /&gt;
# It returns true so that Moodle knows the installation was successful.&lt;br /&gt;
&lt;br /&gt;
And thats it, there&#039;s no need to add an upgrade.php file at this point.&lt;br /&gt;
&lt;br /&gt;
==Step 3: upgrade.php==&lt;br /&gt;
The upgrade.php script allows you to write upgrade code for subsequent upgrade requirements for your theme. If your theme already has a version.php then you should bump the version number there and add your upgrade code here.&lt;br /&gt;
&lt;br /&gt;
This is the main upgrade file. It should be located in a directory called &#039;&#039;db&#039;&#039; located within your theme&#039;s directory, for example &#039;&#039;&#039;moodle/theme/mythemename/db/upgrade.php&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The upgrade.php file should contain just a single function that needs to be named following a strict naming scheme. In the case of my theme that for this example I&#039;ve called mythemename that function will be as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die();&lt;br /&gt;
&lt;br /&gt;
function xmldb_theme_mythemename_upgrade($oldversion) {&lt;br /&gt;
    // We&#039;ll look at what is in here shortly.&lt;br /&gt;
&lt;br /&gt;
    return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This special function gets called when ever the admin is upgrading the site and gives our theme the opportunity to run any upgrade code it requires.&lt;br /&gt;
&lt;br /&gt;
Upgrade code within this function should be written in a special style where each operation is written as a block and the theme version is upgraded incrementally after each operation.&lt;br /&gt;
&lt;br /&gt;
For the following example lets assume I have two settings for my theme, &#039;&#039;mythemename_settingone&#039;&#039;, and &#039;&#039;mythemename_settingtwo&#039;&#039;. As part of my upgrade I want to rename the settings to mythemename_settinga, and mythemename_settingb.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die();&lt;br /&gt;
&lt;br /&gt;
function xmldb_theme_mythemename_upgrade($oldversion) {&lt;br /&gt;
    &lt;br /&gt;
    if ($oldversion &amp;lt; 2011032900) {&lt;br /&gt;
        $currentsetting = get_config(&#039;theme_mythemename&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Create a new config called settinga and give it settingone&#039;s value.&lt;br /&gt;
        set_config(&#039;settinga&#039;, $currentsetting-&amp;gt;settingone, &#039;theme_mythemename&#039;);&lt;br /&gt;
        // Remove settingone&lt;br /&gt;
        unset_config(&#039;settingone&#039;, &#039;theme_mythemename&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Create a new config called settingb and give it settingtwo&#039;s value.&lt;br /&gt;
        set_config(&#039;settingb&#039;, $currentsetting-&amp;gt;settingtwo, &#039;theme_mythemename&#039;);&lt;br /&gt;
        // Remove settingtwo&lt;br /&gt;
        unset_config(&#039;settingtwo&#039;, &#039;theme_mythemename&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Upgrade the version that Moodle knows is installed so that this upgrade&lt;br /&gt;
        // isn&#039;t run again.&lt;br /&gt;
        upgrade_plugin_savepoint(true, 2011032900, &#039;theme&#039;, &#039;mythemename&#039;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Looking at this code it does the following things:&lt;br /&gt;
# It compares and the &#039;&#039;&#039;$oldversion&#039;&#039;&#039; to the version we set (2011032900) and our version is newer it runs the upgrade code.&lt;br /&gt;
# The upgrade code gets the current settings so that we can change them.&lt;br /&gt;
# It creates a new setting called settinga and we give it settingb&#039;s value.&lt;br /&gt;
# It deletes settingone as we no longer want it.&lt;br /&gt;
# It repeats the last two steps for settingb/settingtwo.&lt;br /&gt;
# It updates the version Moodle knows is installed by calling &#039;&#039;upgrade_plugin_savepoint&#039;&#039;&lt;br /&gt;
# Finally the function returns true so that the rest of the upgrade continues.&lt;br /&gt;
&lt;br /&gt;
==Done==&lt;br /&gt;
Just like that we have added upgrade code to our theme that renames two settings. To do that we had to add a version.php file and a upgrade.php file.&lt;br /&gt;
&lt;br /&gt;
==More information==&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]]&lt;br /&gt;
* [[Development:Themes 2.0 adding a settings page]]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_adding_upgrade_code&amp;diff=82691</id>
		<title>Development:Themes 2.0 adding upgrade code</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_adding_upgrade_code&amp;diff=82691"/>
		<updated>2011-04-11T07:06:44Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;As theme&#039;s have got considerably more advanced in Moodle 2 there is now on occasion a need to write upgrade code for a theme. This quick tutorial looks at just how to do that.&lt;br /&gt;
&lt;br /&gt;
==Why?==&lt;br /&gt;
As part of the Moodle 2 revamp theme&#039;s have been given the same abilities as many of the other plugin types within Moodle. They are now able to have settings pages, database tables, they can override renderers, and they can do all sorts of great things.&lt;br /&gt;
&lt;br /&gt;
Unfortunately this change has its positives and negatives, on the positive you can now really get some cool stuff happening within a theme, the downside is just like any other plugin you need to think about those who are already using your theme when you make changes.&lt;br /&gt;
&lt;br /&gt;
If you are changing the name of a setting, or if you are changing the database schema for the theme you will need to add upgrade code to your theme so that those who are already using your theme are moved along nicely and don&#039;t lose the effort they&#039;ve put into customising and setting up your theme.&lt;br /&gt;
&lt;br /&gt;
==Step 1: version.php==&lt;br /&gt;
For those of you who are already familiar with writing Moodle plugins you will be familiar with the version.php, however for many themer&#039;s the reality is that they&#039;ve never gone beyond adding a settings page so this will be new.&lt;br /&gt;
&lt;br /&gt;
The version.php file is a requirement for many plugin types, however for theme&#039;s it is optional. The idea is that it contains just two or three lines of code that tell Moodle what version the plugin is and a little bit about where it is meant to be, or what version of Moodle it requires. The version.php file for a theme should be created within the theme&#039;s base directory e.g. &#039;&#039;moodle/theme/mythemename/version.php&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The following is an example of what a version.php file for a theme looks like.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This is the version.php file for my theme.&lt;br /&gt;
 */&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die;&lt;br /&gt;
&lt;br /&gt;
$plugin-&amp;gt;version   = 2011032900;&lt;br /&gt;
$plugin-&amp;gt;component = &#039;theme_mythemename&#039;;&lt;br /&gt;
$plugin-&amp;gt;requires  = 2010122500;&lt;br /&gt;
$plugin-&amp;gt;maturity  = MATURITY_STABLE;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first thing to notice here is that we are setting properties of an object called $plugin, this object will be used to describe our theme.&lt;br /&gt;
We are setting four properties here, version, component, requires, and maturity. The version property is required and the rest are optional however it is best practice to put them in as well.&lt;br /&gt;
===The version property===&lt;br /&gt;
The version property is the version number of our theme and needs to be an integer, although you can set it to any integer value you want it is &#039;&#039;&#039;HIGHLY&#039;&#039;&#039; recommended to use the date format shown above as it is used everywhere else throughout Moodle.&lt;br /&gt;
&lt;br /&gt;
The format is YYYYMMDDXX :&lt;br /&gt;
# YYYY is the four digit year, e.g. 2011&lt;br /&gt;
# MM is the month with preceding 0 if required, e.g. 03&lt;br /&gt;
# DD is the day with preceding 0 is required, e.g. 28&lt;br /&gt;
# XX is an incrementing value starting at 00, you can increment this if you add several upgrade code blocks on the same day.&lt;br /&gt;
&lt;br /&gt;
As a hint its easiest just to set the version property to today&#039;s date when adding upgrade code, or releasing a version of your theme that introduces something new such as a database table, or config setting.&lt;br /&gt;
&lt;br /&gt;
===The component property===&lt;br /&gt;
The component is used to describe the plugin and its type. In our case we are working with themes and the theme name I have used in my example is mythemename, therefore the component is theme_mythemename.&lt;br /&gt;
&lt;br /&gt;
When installing or upgrading a plugin Moodle checks the component and uses it to make sure that the plugin has been installed in the correct location. This is particularly helpful for the end user as it prevents nasty accidents where they accidentally put a plugin in the wrong place.&lt;br /&gt;
&lt;br /&gt;
If you are working on other types of plugins the component of course will differ, its best to refer to the docs for those plugin types to find out what you would have to use there.&lt;br /&gt;
&lt;br /&gt;
===The requires property===&lt;br /&gt;
The requires property sets the version of Moodle that is required by this plugin. This is particularly handy if your plugin makes use of a feature that was introduced in a specific version of Moodle, or if your plugin relies on a bug fix that was introduced in a specific version.&lt;br /&gt;
&lt;br /&gt;
You can find the current Moodle version by looking at main Moodle version.php file. In the example above I have set my theme to require Moodle 2.0.1 by setting the requires property to Moodle&#039;s version number when that was released. If you are trying to find out a specific version number you can do so by heading to https://github.com/moodle/moodle, changing the tag drop down to the version you desire, then inspecting the version.php file at the bottom of the files list. You should see $version = XXXXXXXXXX;.&lt;br /&gt;
&lt;br /&gt;
===The maturity property===&lt;br /&gt;
This is a property that is expected to be fully supported in Moodle 2.1. It informs Moodle about the state of the code and can be one of the following values:&lt;br /&gt;
; MATURITY_STABLE : Use this when the theme is stable and works well.&lt;br /&gt;
; MATURITY_RC : This marks the theme as a release candidate, users can expect the theme to contain one or two bugs but be largely stable and usable.&lt;br /&gt;
; MATURITY_BETA : This marks the theme as a beta release, users can expect the theme to contain several bugs and for it to be likely to change still.&lt;br /&gt;
; MATURITY_ALPHA : This marks the theme as an alpha release, this is the first release of a new theme and users will expect to find a lot still needs to be done.&lt;br /&gt;
&lt;br /&gt;
==Step 2: install.php==&lt;br /&gt;
If as part of this upgrade you are adding a version.php file to your theme then you will need to add your upgrade code to install.php rather than upgrade.php.&lt;br /&gt;
&lt;br /&gt;
The reason for this is because Moodle processes install.php the first time that a version number is used rather than upgrade.php.&lt;br /&gt;
&lt;br /&gt;
The install.php file should contain a single function that needs to be named following a strict naming scheme.&lt;br /&gt;
For this example I have called my theme &#039;&#039;mythemename&#039;&#039; so the function will be as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die();&lt;br /&gt;
&lt;br /&gt;
function xmldb_theme_mythemename_install() {&lt;br /&gt;
    // We&#039;ll look at what is in here shortly.&lt;br /&gt;
&lt;br /&gt;
    return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This special function is called when a theme is first installed (if it has a version.php file and it has been newly added to your Moodle site) or the first time that the theme has a version.php file if you are developing or upgrading a theme.&lt;br /&gt;
&lt;br /&gt;
The install function can perform any upgrade routines you require. For the following example lets assume I have two settings for my theme, &#039;&#039;mythemename_settingone&#039;&#039;, and &#039;&#039;mythemename_settingtwo&#039;&#039;. As part of my upgrade I want to rename the settings to mythemename_settinga, and mythemename_settingb.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die();&lt;br /&gt;
&lt;br /&gt;
function xmldb_theme_mythemename_install() {&lt;br /&gt;
    $currentsetting = get_config(&#039;theme_mythemename&#039;);&lt;br /&gt;
&lt;br /&gt;
    // Create a new config called settinga and give it settingone&#039;s value.&lt;br /&gt;
    set_config(&#039;settinga&#039;, $currentsetting-&amp;gt;settingone, &#039;theme_mythemename&#039;);&lt;br /&gt;
    // Remove settingone&lt;br /&gt;
    unset_config(&#039;settingone&#039;, &#039;theme_mythemename&#039;);&lt;br /&gt;
&lt;br /&gt;
    // Create a new config called settingb and give it settingtwo&#039;s value.&lt;br /&gt;
    set_config(&#039;settingb&#039;, $currentsetting-&amp;gt;settingtwo, &#039;theme_mythemename&#039;);&lt;br /&gt;
    // Remove settingtwo&lt;br /&gt;
    unset_config(&#039;settingtwo&#039;, &#039;theme_mythemename&#039;);&lt;br /&gt;
&lt;br /&gt;
    return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Looking at this code it does the following things:&lt;br /&gt;
# The install code gets the current settings so that we can change them.&lt;br /&gt;
# It creates a new setting called settinga and we give it settingb&#039;s value.&lt;br /&gt;
# It deletes settingone as we no longer want it.&lt;br /&gt;
# It repeats the last two steps for settingb/settingtwo.&lt;br /&gt;
# It returns true so that Moodle knows the installation was successful.&lt;br /&gt;
&lt;br /&gt;
And thats it, there&#039;s no need to add an upgrade.php file at this point.&lt;br /&gt;
&lt;br /&gt;
==Step 3: upgrade.php==&lt;br /&gt;
The upgrade.php script allows you to write upgrade code for subsequent upgrade requirements for your theme. If your theme already has a version.php then you should bump the version number there and add your upgrade code here.&lt;br /&gt;
&lt;br /&gt;
This is the main upgrade file. It should be located in a directory called &#039;&#039;db&#039;&#039; located within your theme&#039;s directory, for example &#039;&#039;&#039;moodle/theme/mythemename/db/upgrade.php&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The upgrade.php file should contain just a single function that needs to be named following a strict naming scheme. In the case of my theme that for this example I&#039;ve called mythemename that function will be as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die();&lt;br /&gt;
&lt;br /&gt;
function xmldb_theme_mythemename_upgrade($oldversion) {&lt;br /&gt;
    // We&#039;ll look at what is in here shortly.&lt;br /&gt;
&lt;br /&gt;
    return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This special function gets called when ever the admin is upgrading the site and gives our theme the opportunity to run any upgrade code it requires.&lt;br /&gt;
&lt;br /&gt;
Upgrade code within this function should be written in a special style where each operation is written as a block and the theme version is upgraded incrementally after each operation.&lt;br /&gt;
&lt;br /&gt;
For the following example lets assume I have two settings for my theme, &#039;&#039;mythemename_settingone&#039;&#039;, and &#039;&#039;mythemename_settingtwo&#039;&#039;. As part of my upgrade I want to rename the settings to mythemename_settinga, and mythemename_settingb.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die();&lt;br /&gt;
&lt;br /&gt;
function xmldb_theme_mythemename_upgrade($oldversion) {&lt;br /&gt;
    &lt;br /&gt;
    if ($oldversion &amp;lt; 2011032900) {&lt;br /&gt;
        $currentsetting = get_config(&#039;theme_mythemename&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Create a new config called settinga and give it settingone&#039;s value.&lt;br /&gt;
        set_config(&#039;settinga&#039;, $currentsetting-&amp;gt;settingone, &#039;theme_mythemename&#039;);&lt;br /&gt;
        // Remove settingone&lt;br /&gt;
        unset_config(&#039;settingone&#039;, &#039;theme_mythemename&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Create a new config called settingb and give it settingtwo&#039;s value.&lt;br /&gt;
        set_config(&#039;settingb&#039;, $currentsetting-&amp;gt;settingtwo, &#039;theme_mythemename&#039;);&lt;br /&gt;
        // Remove settingtwo&lt;br /&gt;
        unset_config(&#039;settingtwo&#039;, &#039;theme_mythemename&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Upgrade the version that Moodle knows is installed so that this upgrade&lt;br /&gt;
        // isn&#039;t run again.&lt;br /&gt;
        upgrade_plugin_savepoint(true, 2011032900, &#039;theme&#039;, &#039;mythemename&#039;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Looking at this code it does the following things:&lt;br /&gt;
# It compares and the &#039;&#039;&#039;$oldversion&#039;&#039;&#039; to the version we set (2011032900) and our version is newer it runs the upgrade code.&lt;br /&gt;
# The upgrade code gets the current settings so that we can change them.&lt;br /&gt;
# It creates a new setting called settinga and we give it settingb&#039;s value.&lt;br /&gt;
# It deletes settingone as we no longer want it.&lt;br /&gt;
# It repeats the last two steps for settingb/settingtwo.&lt;br /&gt;
# It updates the version Moodle knows is installed by calling &#039;&#039;upgrade_plugin_savepoint&#039;&#039;&lt;br /&gt;
# Finally the function returns true so that the rest of the upgrade continues.&lt;br /&gt;
&lt;br /&gt;
==Done==&lt;br /&gt;
Just like that we have added upgrade code to our theme that renames two settings. To do that we had to add a version.php file and a upgrade.php file.&lt;br /&gt;
&lt;br /&gt;
==More information==&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]]&lt;br /&gt;
* [[Development:Themes 2.0 adding a settings page]]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_creating_your_first_theme&amp;diff=82355</id>
		<title>Development:Themes 2.0 creating your first theme</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_creating_your_first_theme&amp;diff=82355"/>
		<updated>2011-03-29T06:15:02Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: &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;
&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;
==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>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0&amp;diff=82354</id>
		<title>Development:Themes 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0&amp;diff=82354"/>
		<updated>2011-03-29T06:13:24Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: Better coding standard&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;
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>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_adding_a_settings_page&amp;diff=82353</id>
		<title>Development:Themes 2.0 adding a settings page</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_adding_a_settings_page&amp;diff=82353"/>
		<updated>2011-03-29T02:57:50Z</updated>

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

		<summary type="html">&lt;p&gt;Samhemelryk: /* See also */&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 echo $PAGE-&amp;gt;bodyid ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyclasses; ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_top_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;table id=&amp;quot;page&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
        &amp;lt;td colspan=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;h1 class=&amp;quot;headermain&amp;quot;&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;heading ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;headermenu&amp;quot;&amp;gt;&amp;lt;?php echo $OUTPUT-&amp;gt;login_info(); echo $PAGE-&amp;gt;headingmenu; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-pre&#039;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-post&#039;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
        &amp;lt;td colspan=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;p class=&amp;quot;helplink&amp;quot;&amp;gt;&amp;lt;?php echo page_doc_link(get_string(&#039;moodledocslink&#039;)) ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
            &amp;lt;?php&lt;br /&gt;
            echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
            echo $OUTPUT-&amp;gt;home_link();&lt;br /&gt;
            echo $OUTPUT-&amp;gt;standard_footer_html();&lt;br /&gt;
            ?&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_end_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lets assume you know a enough HTML to understand the basic structure above, what you probably don&#039;t understand are the PHP calls so lets look at them.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;doctype() ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This occurs at the VERY top of the page, it must be the first bit of output and is responsible for adding the (X)HTML document type definition to the page. This of course is determined by the settings of the site and is one of the things that the 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 echo $PAGE-&amp;gt;bodyid; ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyclasses; ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Much like the html tag above we have started writing the body tag and have asked for Moodle to get us the desired ID and classes that should be applied to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;h1 class=&amp;quot;headermain&amp;quot;&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;heading; ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;headermenu&amp;quot;&amp;gt;&amp;lt;?php echo $OUTPUT-&amp;gt;login_info(); echo $PAGE-&amp;gt;headingmenu; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are creating the header for the page. In this case we want the heading for the page, we want to display the login information which will be the current users username or a link to log in if they are not logged in, and we want the heading menu if there is one.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-pre&#039;) ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we get the HTML to display the blocks that have been added to the page. In this case we have asked for all blocks that have been added to the area labelled &#039;&#039;side-pre&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is one of the most important calls within the file, it determines where the actual content for the page gets inserted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-post&#039;) ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we get the HTML to display the blocks that have been added to the page. In this case we have asked for all blocks that have been added to the area labelled &#039;&#039;side-post&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
echo $OUTPUT-&amp;gt;home_link();&lt;br /&gt;
echo $OUTPUT-&amp;gt;standard_footer_html();&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This final bit of code gets the content for the footer of the page. It gets the login information which is the same as in the header, a home link, and the standard footer HTML which like the standard head HTML contains all of the script and style tags required by the page and requested to go in the footer.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note&#039;&#039;&#039;&#039;&#039;: Within Moodle 2.0 most of the JavaScript for the page will be included in the footer. This greatly helps reduce the loading time of the page.&lt;br /&gt;
&lt;br /&gt;
When writing layout files think about the different layouts and how the HTML that each makes use of will differ. You will most likely find you do not need a different layout file for each layout, most likely you will be able to reuse the layout files you create across several layouts. You can of course make use of layout options as well to further reduce the number of layout files you need to produce.&lt;br /&gt;
&lt;br /&gt;
Of course as mentioned above if you are customising an existing theme then you may not need to create any layouts or layout files at all.&lt;br /&gt;
&lt;br /&gt;
&#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;
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>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_adding_upgrade_code&amp;diff=82351</id>
		<title>Development:Themes 2.0 adding upgrade code</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_adding_upgrade_code&amp;diff=82351"/>
		<updated>2011-03-29T02:52:08Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;As theme&#039;s have got considerably more advanced in Moodle 2 there is now on occasion a need to write upgrade code for a theme. This quick tutorial looks at just how to do that.&lt;br /&gt;
&lt;br /&gt;
==Why?==&lt;br /&gt;
As part of the Moodle 2 revamp theme&#039;s have been given the same abilities as many of the other plugin types within Moodle. They are now able to have settings pages, database tables, they can override renderers, and they can do all sorts of great things.&lt;br /&gt;
&lt;br /&gt;
Unfortunately this change has its positives and negatives, on the positive you can now really get some cool stuff happening within a theme, the downside is just like any other plugin you need to think about those who are already using your theme when you make changes.&lt;br /&gt;
&lt;br /&gt;
If you are changing the name of a setting, or if you are changing the database schema for the theme you will need to add upgrade code to your theme so that those who are already using your theme are moved along nicely and don&#039;t lose the effort they&#039;ve put into customising and setting up your theme.&lt;br /&gt;
&lt;br /&gt;
==Step 1: version.php==&lt;br /&gt;
For those of you who are already familiar with writing Moodle plugins you will be familiar with the version.php, however for many themer&#039;s the reality is that they&#039;ve never gone beyond adding a settings page so this will be new.&lt;br /&gt;
&lt;br /&gt;
The version.php file is a requirement for many plugin types, however for theme&#039;s it is optional. The idea is that it contains just two or three lines of code that the tell Moodle what version the plugin is and a little bit about where it is meant to be, or what version of Moodle it requires. The version.php file for a theme should be created within the theme&#039;s base directory e.g. &#039;&#039;moodle/theme/mythemename/version.php&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The following is an example of what a version.php file for a theme looks like.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This is the version.php file for my theme.&lt;br /&gt;
 */&lt;br /&gt;
$plugin-&amp;gt;version   = 2011032900;&lt;br /&gt;
$plugin-&amp;gt;component = &#039;theme_mythemename&#039;;&lt;br /&gt;
$plugin-&amp;gt;requires  = 2010122500;&lt;br /&gt;
$plugin-&amp;gt;maturity  = MATURITY_STABLE;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first thing to notice here is that we are setting properties of an object called $plugin, this object will be used to describe our theme.&lt;br /&gt;
We are setting four properties here, version, component, requires, and maturity. The version property is required and the rest are optional however it is best practice to put the in as well.&lt;br /&gt;
===The version property===&lt;br /&gt;
The version property is the version number of our theme and needs to be an integer, although you can set it to any integer value you want it is &#039;&#039;&#039;HIGHLY&#039;&#039;&#039; recommended to use the date format shown above as it is used everywhere else throughout Moodle.&lt;br /&gt;
&lt;br /&gt;
The format is YYYYMMDDXX :&lt;br /&gt;
# YYYY is the four digit year, e.g. 2011&lt;br /&gt;
# MM is the month with preceding 0 if required, e.g. 03&lt;br /&gt;
# DD is the day with preceding 0 is required, e.g. 28&lt;br /&gt;
# XX is an incrementing value starting at 00, you can increment this if you add several upgrade code blocks on the same day.&lt;br /&gt;
&lt;br /&gt;
As a hint its easiest just to set the version property to today&#039;s date when adding upgrade code, or releasing a version of your theme that introduces something new such as a database table, or config setting.&lt;br /&gt;
&lt;br /&gt;
===The component property===&lt;br /&gt;
The component is used to describe the plugin and its type. In our case we are working with themes and the theme name I have used in my example is mythemename, therefore the component is theme_mythemename.&lt;br /&gt;
&lt;br /&gt;
When installing or upgrading a plugin Moodle checks the component and uses it to make sure that the plugin has been installed in the correct location. This is particularly helpful for the end user as it prevents nasty accidents where they accidentally put a plugin in the wrong place.&lt;br /&gt;
&lt;br /&gt;
If you are working on other types of plugins the component of course will differ, its best to refer to the docs for those plugin types to find out what you would have to use there.&lt;br /&gt;
&lt;br /&gt;
===The requires property===&lt;br /&gt;
The requires property sets the version of Moodle that is required by this plugin. This is particularly handy if your plugin makes use of a feature that was introduced in a specific version of Moodle, or if your plugin relies on a bug fix that was introduced in a specific version.&lt;br /&gt;
&lt;br /&gt;
You can find the current Moodle version by looking at main Moodle version.php file. In the example above I have set my theme to require Moodle 2.0.1 by setting the requires property to Moodle&#039;s version number when that was released. If you are trying to find out a specific version number you can do so by heading to https://github.com/moodle/moodle, changing the tag drop down to the version you desire, then inspecting the version.php file at the bottom of the files list. You should see $version = XXXXXXXXXX;.&lt;br /&gt;
&lt;br /&gt;
===The maturity property===&lt;br /&gt;
This is a property that is expected to be fully supported in Moodle 2.1. It informs Moodle about the state of the code and can be one of the following values:&lt;br /&gt;
; MATURITY_STABLE : Use this when the theme is stable and works well.&lt;br /&gt;
; MATURITY_RC : This marks the theme as a release candidate, users can expect the theme to contain one or two bugs but be largely stable and usable.&lt;br /&gt;
; MATURITY_BETA : This marks the theme as a beta release, users can expect the theme to contain several bugs and for it to be likely to change still.&lt;br /&gt;
; MATURITY_ALPHA : This marks the theme as an alpha release, this is the first release of a new theme and users will expect to find a lot still needs to be done.&lt;br /&gt;
&lt;br /&gt;
==Step 2: upgrade.php==&lt;br /&gt;
This is the main upgrade file. It should be located in a directory called &#039;&#039;db&#039;&#039; located within your theme&#039;s directory, for example &#039;&#039;&#039;moodle/theme/mythemename/db/upgrade.php&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The upgrade.php file should contain just a single function that needs to be named following a strict naming scheme. In the case of my theme that for this example I&#039;ve called mythemename that function will be as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
function xmldb_mythemename_anomaly_upgrade($oldversion) {&lt;br /&gt;
    // We&#039;ll look at what is in here shortly.&lt;br /&gt;
&lt;br /&gt;
    return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This special function gets called when ever the admin is upgrading the site and gives our theme the opportunity to run any upgrade code it requires.&lt;br /&gt;
&lt;br /&gt;
Upgrade code within this function should be written in a special style where each operation is written as a block and the theme version is upgraded incrementally after each operation.&lt;br /&gt;
&lt;br /&gt;
For the following example lets assume I have two settings for my theme, &#039;&#039;mythemename_settingone&#039;&#039;, and &#039;&#039;mythemename_settingtwo&#039;&#039;. As part of my upgrade I want to rename the settings to mythemename_settinga, and mythemename_settingb.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
function xmldb_theme_mythemename_upgrade($oldversion) {&lt;br /&gt;
    &lt;br /&gt;
    if ($oldversion &amp;lt; 2011032900) {&lt;br /&gt;
        $currentsetting = get_config(&#039;theme_mythemename&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Create a new config called settinga and give it settingone&#039;s value.&lt;br /&gt;
        set_config(&#039;settinga&#039;, $currentsetting-&amp;gt;settingone, &#039;theme_mythemename&#039;);&lt;br /&gt;
        // Remove settingone&lt;br /&gt;
        unset_config(&#039;settingone&#039;, &#039;theme_mythemename&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Create a new config called settingb and give it settingtwo&#039;s value.&lt;br /&gt;
        set_config(&#039;settingb&#039;, $currentsetting-&amp;gt;settingtwo, &#039;theme_mythemename&#039;);&lt;br /&gt;
        // Remove settingtwo&lt;br /&gt;
        unset_config(&#039;settingtwo&#039;, &#039;theme_mythemename&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Upgrade the version that Moodle knows is installed so that this upgrade&lt;br /&gt;
        // isn&#039;t run again.&lt;br /&gt;
        upgrade_plugin_savepoint(true, 2011032900, &#039;theme&#039;, &#039;mythemename&#039;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Looking at this code it does the following things:&lt;br /&gt;
# It compares and the &#039;&#039;&#039;$oldversion&#039;&#039;&#039; to the version we set (2011032900) and our version is newer it runs the upgrade code.&lt;br /&gt;
# The upgrade code gets the current settings so that we can change them.&lt;br /&gt;
# It creates a new setting called settinga and we give it settingb&#039;s value.&lt;br /&gt;
# It deletes settingone as we no longer want it.&lt;br /&gt;
# It repeats the last two steps for settingb/settingtwo.&lt;br /&gt;
# It updates the version Moodle knows is installed by calling &#039;&#039;upgrade_plugin_savepoint&#039;&#039;&lt;br /&gt;
# Finally the function returns true so that the rest of the upgrade continues.&lt;br /&gt;
&lt;br /&gt;
==Done==&lt;br /&gt;
Just like that we have added upgrade code to our theme that renames two settings. To do that we had to add a version.php file and a upgrade.php file.&lt;br /&gt;
&lt;br /&gt;
==More information==&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]]&lt;br /&gt;
* [[Development:Themes 2.0 adding a settings page]]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_adding_upgrade_code&amp;diff=82350</id>
		<title>Development:Themes 2.0 adding upgrade code</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_adding_upgrade_code&amp;diff=82350"/>
		<updated>2011-03-29T02:31:31Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* Step 1: version.php */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;As theme&#039;s have got considerably more advanced in Moodle 2 there is now on occasion a need to write upgrade code for a theme. This quick tutorial looks at just how to do that.&lt;br /&gt;
&lt;br /&gt;
==Why?==&lt;br /&gt;
As part of the Moodle 2 revamp theme&#039;s have been given the same abilities as many of the other plugin types within Moodle. They are now able to have settings pages, database tables, they can override renderers, and they can do all sorts of great things.&lt;br /&gt;
Unfortunately this change has its positives and negatives, on the positive you can now really get some cool stuff happening within a theme, the downside is just like any other plugin you need to think about those who are already using your theme when you make changes.&lt;br /&gt;
If you are changing the name of a setting, or if you are changing the database schema for the theme you will need to add upgrade code to your theme so that those who are already using your theme are moved along nicely and don&#039;t lose the effort they&#039;ve put into customising and setting up your theme.&lt;br /&gt;
&lt;br /&gt;
==Step 1: version.php==&lt;br /&gt;
For those of you who are already familiar with writing Moodle plugins you will be familiar with the version.php, however for many themer&#039;s the reality is that they&#039;ve never gone beyond adding a settings page so this will be new.&lt;br /&gt;
&lt;br /&gt;
The version.php file is a requirement for many plugin types, however for theme&#039;s it is optional. The idea is that it contains just two or three lines of code that the tell Moodle what version the plugin is and a little bit about where it is meant to be, or what version of Moodle it requires. The version.php file for a theme should be created within the theme&#039;s base directory e.g. &#039;&#039;moodle/theme/mythemename/version.php&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The following is an example of what a version.php file for a theme looks like.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This is the version.php file for my theme.&lt;br /&gt;
 */&lt;br /&gt;
$plugin-&amp;gt;version   = 2011032900;&lt;br /&gt;
$plugin-&amp;gt;component = &#039;theme_mythemename&#039;;&lt;br /&gt;
$plugin-&amp;gt;requires  = 2010122500;&lt;br /&gt;
$plugin-&amp;gt;maturity  = MATURITY_STABLE;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first thing to notice here is that we are setting properties of an object called $plugin, this object will be used to describe our theme.&lt;br /&gt;
We are setting four properties here, version, component, requires, and maturity. The version property is required and the rest are optional however it is best practice to put the in as well.&lt;br /&gt;
===The version property===&lt;br /&gt;
The version property is the version number of our theme and needs to be an integer, although you can set it to any integer value you want it is &#039;&#039;&#039;HIGHLY&#039;&#039;&#039; recommended to use the date format shown above as it is used everywhere else throughout Moodle.&lt;br /&gt;
&lt;br /&gt;
The format is YYYYMMDDXX :&lt;br /&gt;
# YYYY is the four digit year, e.g. 2011&lt;br /&gt;
# MM is the month with preceding 0 if required, e.g. 03&lt;br /&gt;
# DD is the day with preceding 0 is required, e.g. 28&lt;br /&gt;
# XX is an incrementing value starting at 00, you can increment this if you add several upgrade code blocks on the same day.&lt;br /&gt;
&lt;br /&gt;
As a hint its easiest just to set the version property to today&#039;s date when adding upgrade code, or releasing a version of your theme that introduces something new such as a database table, or config setting.&lt;br /&gt;
&lt;br /&gt;
===The component property===&lt;br /&gt;
The component is used to describe the plugin and its type. In our case we are working with themes and the theme name I have used in my example is mythemename, therefore the component is theme_mythemename.&lt;br /&gt;
&lt;br /&gt;
When installing or upgrading a plugin Moodle checks the component and uses it to make sure that the plugin has been installed in the correct location. This is particularly helpful for the end user as it prevents nasty accidents where they accidentally put a plugin in the wrong place.&lt;br /&gt;
&lt;br /&gt;
If you are working on other types of plugins the component of course will differ, its best to refer to the docs for those plugin types to find out what you would have to use there.&lt;br /&gt;
&lt;br /&gt;
===The requires property===&lt;br /&gt;
The requires property sets the version of Moodle that is required by this plugin. This is particularly handy if your plugin makes use of a feature that was introduced in a specific version of Moodle, or if your plugin relies on a bug fix that was introduced in a specific version.&lt;br /&gt;
&lt;br /&gt;
You can find the current Moodle version by looking at main Moodle version.php file. In the example above I have set my theme to require Moodle 2.0.1 by setting the requires property to Moodle&#039;s version number when that was released. If you are trying to find out a specific version number you can do so by heading to https://github.com/moodle/moodle, changing the tag drop down to the version you desire, then inspecting the version.php file at the bottom of the files list. You should see $version = XXXXXXXXXX;.&lt;br /&gt;
&lt;br /&gt;
===The maturity property===&lt;br /&gt;
This is a property that is expected to be fully supported in Moodle 2.1. It informs Moodle about the state of the code and can be one of the following values:&lt;br /&gt;
; MATURITY_STABLE : Use this when the theme is stable and works well.&lt;br /&gt;
; MATURITY_RC : This marks the theme as a release candidate, users can expect the theme to contain one or two bugs but be largely stable and usable.&lt;br /&gt;
; MATURITY_BETA : This marks the theme as a beta release, users can expect the theme to contain several bugs and for it to be likely to change still.&lt;br /&gt;
; MATURITY_ALPHA : This marks the theme as an alpha release, this is the first release of a new theme and users will expect to find alot still needs to be done.&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_adding_upgrade_code&amp;diff=82349</id>
		<title>Development:Themes 2.0 adding upgrade code</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_adding_upgrade_code&amp;diff=82349"/>
		<updated>2011-03-29T02:04:28Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: New page: As theme&amp;#039;s have got considerably more advanced in Moodle 2 there is now on occasion a need to write upgrade code for a theme. This quick tutorial looks at just how to do that.  ==Why?== As...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;As theme&#039;s have got considerably more advanced in Moodle 2 there is now on occasion a need to write upgrade code for a theme. This quick tutorial looks at just how to do that.&lt;br /&gt;
&lt;br /&gt;
==Why?==&lt;br /&gt;
As part of the Moodle 2 revamp theme&#039;s have been given the same abilities as many of the other plugin types within Moodle. They are now able to have settings pages, database tables, they can override renderers, and they can do all sorts of great things.&lt;br /&gt;
Unfortunately this change has its positives and negatives, on the positive you can now really get some cool stuff happening within a theme, the downside is just like any other plugin you need to think about those who are already using your theme when you make changes.&lt;br /&gt;
If you are changing the name of a setting, or if you are changing the database schema for the theme you will need to add upgrade code to your theme so that those who are already using your theme are moved along nicely and don&#039;t lose the effort they&#039;ve put into customising and setting up your theme.&lt;br /&gt;
&lt;br /&gt;
==Step 1: version.php==&lt;br /&gt;
For those of you who are already familiar with writing Moodle plugins you will be familiar with the version.php, however for many themer&#039;s the reality is that they&#039;ve never gone beyond adding a settings page so this will be new.&lt;br /&gt;
&lt;br /&gt;
The version.php file is a requirement for many plugin types, however for theme&#039;s it is optional. The idea is that it contains just two or three lines of code that the tell Moodle what version the plugin is and a little bit about where it is meant to be, or what version of Moodle it requires.&lt;br /&gt;
&lt;br /&gt;
The following is an example of what a version.php file for a theme looks like.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This is the version.php file for my theme.&lt;br /&gt;
 */&lt;br /&gt;
$plugin-&amp;gt;version = 2011032900;&lt;br /&gt;
$plugin-&amp;gt;maturity = MATURITY_STABLE;&lt;br /&gt;
$plugin-&amp;gt;requires = 2011021100;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_how_to_make_the_dock_horizontal&amp;diff=82013</id>
		<title>Development:Themes 2.0 how to make the dock horizontal</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_how_to_make_the_dock_horizontal&amp;diff=82013"/>
		<updated>2011-03-17T04:57:33Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* dockmod.js */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}{{Moodle 2.0}}This quick tutorial looks at how to move the dock from its vertical position on the left hand side of the screen to a horizontal position at the top of the screen.&amp;lt;br /&amp;gt;&lt;br /&gt;
This modification will be done entirely within a theme through the creation of a small amount of JavaScript and a few lines of CSS.&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
If you&#039;re new to Moodle and haven&#039;t yet read the tutorial on creating your first theme I strongly suggest you head there first.&amp;lt;br /&amp;gt;&lt;br /&gt;
I&#039;d also strongly suggest you read [[Development:Styling and customising the dock]] which explains the structure of the dock and a few of the things you will need to know in order to tackle this tutorial.&lt;br /&gt;
&lt;br /&gt;
In order to make this tutorial easier to understand I am going to create a new theme that we&#039;ll call &#039;&#039;&#039;dockmod&#039;&#039;&#039; in which we will create this modification.&lt;br /&gt;
So first step within your Moodle theme directory create a new directory called &#039;&#039;dockmod&#039;&#039;. Within this new directory we&#039;ll create two further directories JavaScript, and style.&lt;br /&gt;
You should now have a directory structure like the one shown below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
moodle/theme/dockmod&lt;br /&gt;
moodle/theme/dockmod/javascript&lt;br /&gt;
moodle/theme/dockmod/style&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next step is to create the three files we are going to need, config.php, dockmod.js, and dockmod.css.&lt;br /&gt;
# config.php is of course for our theme&#039;s configuration and as you know an essential for any theme.&lt;br /&gt;
# dockmod.js will be created in the JavaScript directory, this file will contain the bit of JavaScript we need to write to get our modification to work.&lt;br /&gt;
# dockmod.css will be created in the style directory, this file will contain the CSS we need in order to make the dock horizontal.&lt;br /&gt;
&lt;br /&gt;
You should end up with the following files:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
moodle/theme/dockmod/config.php&lt;br /&gt;
moodle/theme/dockmod/javascript/dockmod.js&lt;br /&gt;
moodle/theme/dockmod/style/dockmod.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==config.php==&lt;br /&gt;
In this step we will be setting up the config.php file for this theme, to be truthful there should be nothing new here for you, this is the easy part of the tutorial.&lt;br /&gt;
The idea of this theme is to simply extend the standard theme and make the dock modification. This has the advantage that our theme will only consist of the JS and CSS required to achieve the dock modification we want.&lt;br /&gt;
&lt;br /&gt;
So open the config.php file in your favourite editor and type the following in:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This is the config file for the dockmod theme.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;name = &#039;dockmod&#039;;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;dockmod&#039;);&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;, &#039;base&#039;);&lt;br /&gt;
$THEME-&amp;gt;enable_dock = true;&lt;br /&gt;
$THEME-&amp;gt;javascripts = array(&#039;dockmod&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So pretty simple really, the name of our theme is &#039;&#039;dockmod&#039;&#039;, you already knew that!&lt;br /&gt;
The parents for this new theme are standard and base as explained above.&lt;br /&gt;
We have one stylesheet also called dockmod (theme/dockmod/style/dockmod.css), and we have one JavaScript file also called dockmod (theme/dockmod/javascript/dockmod.js) and of course its essential we enable the dock, otherwise there&#039;s no point in creating this modification.&lt;br /&gt;
&lt;br /&gt;
==The JavaScript==&lt;br /&gt;
OK this is where the tutorial starts to enter the [potentially] unknown.&lt;br /&gt;
&lt;br /&gt;
The dock is pretty cool in that it looks for a specific JavaScript function when it loads and calls it if it exists, we can use this to modify the dock as we want. It also published several events that we are able to listen to in order to make further modifications when certain things happen.&lt;br /&gt;
&lt;br /&gt;
In our case we want to make the dock horizontal. Now this isn&#039;t actually as nasty as it sounds because in a limited way the dock supports this! When I first wrote the dock I had in mind that one day I would have time to extend the dock to make it moveable, as such I wrote some basic support into it to allow the position and orientation to be switched. I know that a few of you in the community who have looked at making a horizontal dock have found these properties. Functions that rely on the position or orientation of the dock such as making the titles vertical have code within them that checks it makes sense to do so based upon the values of those properties.&lt;br /&gt;
All in all this makes our modification a lot simpler as half the work is already done!&lt;br /&gt;
&lt;br /&gt;
To start with open &#039;&#039;javascript/dockmod.js&#039;&#039; in your favourite editor and type the following:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
function customise_dock_for_theme() {&lt;br /&gt;
    var dock = M.core_dock;&lt;br /&gt;
    dock.cfg.position = &#039;top&#039;;&lt;br /&gt;
    dock.cfg.orientation = &#039;horizontal&#039;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And that is it; It sounds hard, but as you see really it is very easy (although as you get through this tutorial you will see we actually add a bit more JS later on).&lt;br /&gt;
&lt;br /&gt;
So how this works:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
function customise_dock_for_theme() { .... }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
As mentioned above when the dock first loads it looks for a function and calls it, well this is the function &#039;&#039;&#039;customise_dock_for_theme&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
var dock = M.core_dock;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are collecting the dock into a variable. It is in this case available from the global M object.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
dock.cfg.position = &#039;top&#039;;&lt;br /&gt;
dock.cfg.orientation = &#039;horizontal&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
These two lines set two configuration variables for the dock, the position and the orientation. There are several other config properties that perhaps will be explored within another document or tutorial.&lt;br /&gt;
&lt;br /&gt;
==The CSS==&lt;br /&gt;
If you save you changes presently and view your theme in your browser you will likely see a big mess. That is because while the JavaScript supports a horizontal dock there is not yet any CSS to support displaying the dock horizontally.&lt;br /&gt;
&lt;br /&gt;
Because of this we will need to write a bit of CSS to ensure the dock is displayed correctly.&lt;br /&gt;
Open &#039;&#039;style/dockmod.css&#039;&#039; in your favourite editor and type the following:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
body.has_dock {margin-top:30px;margin-left:0;}&lt;br /&gt;
body.has_dock_top_horizontal #dock {width:100%;height:30px;background-image:url([[pix:theme|hgradient]]);background-repeat: repeat-x;border-right-width:0;border-bottom:1px solid #000;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .dockeditem_container {margin-top:0;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .dockeditem {display:inline-block;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .dockeditem .dockedtitle {background-image:url([[pix:theme|hgradient]]);background-repeat: repeat-x;background-position:0 10%;border-style:solid;border-width: 0 1px 0 0;border-color:#AAA;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .dockeditem .dockedtitle h2 {margin:0 12px;line-height:30px;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .dockeditem.firstdockitem {margin-left:10px;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .dockeditem.firstdockitem .dockedtitle {border-left-width:1px;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .controls {bottom:auto;right:10px;top:0;width:auto;line-height:30px;}&lt;br /&gt;
body.has_dock_top_horizontal #dock #dockeditempanel {position:absolute;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That&#039;s it!&lt;br /&gt;
&lt;br /&gt;
The first line of CSS is to correct the margin on the body that accommodates the dock, we need to remove the left margin and increase the top margin.&lt;br /&gt;
The other lines of CSS basically just correct change to horizontal images, change positioning from vertical to horizontal, and swap X/Y properties.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PLEASE NOTE:&#039;&#039;&#039; the above CSS using &#039;&#039;display:inline-block&#039;&#039; so this won&#039;t work in IE6/7, if this is a problem for anyone you could probably achieve something similar using floats.&lt;br /&gt;
&lt;br /&gt;
==Correcting a vertical bug==&lt;br /&gt;
If you now open your site in your browser and switch to your theme you should see a horizontal dock.&lt;br /&gt;
If you have a bit of a play with if you will notice that if you dock the settings block and fully expand it it will run off the bottom of the page and there will be no scroll bar.&lt;br /&gt;
This has happened because we changed the position attributes of the dock in our CSS above. Essentially we could tinker with the CSS and try to fix it there, however based upon the design of the block and the complexities of getting it to work cross browser I can tell you it&#039;s going to be hard. Instead I&#039;ll show you how we can fix it in JavaScript.&lt;br /&gt;
&lt;br /&gt;
Open your dockmod.js file again and type the following within the customize dock function below the three lines that are already in there.&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
dock.on(&#039;dock:resizepanelcomplete&#039;, theme_dockmod_handle_resize);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This line of code is adding an event listener to the dock so that when it fires the &#039;&#039;&#039;dock:resizepanelcomplete&#039;&#039;&#039; event the function &#039;&#039;&#039;theme_dockmod_handle_resize&#039;&#039;&#039; which we create shortly will get called.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;resizepanelcomplete&#039;&#039; function gets called &#039;&#039;&#039;after&#039;&#039;&#039; the panel that shows the content of a block has been resized. The panel gets resized any time it&#039;s display changes, e.g. when it is shown, or when the content within the panel changes (you expand something).&amp;lt;br /&amp;gt;&lt;br /&gt;
This event is perfect for our needs as when it is called we can look at the height of the panel and if it is more than the height of the screen we can add scrollbars to it and set the height so that the user can access all of the content of the panel.&lt;br /&gt;
&lt;br /&gt;
Now we need to write the &#039;&#039;theme_dockmod_handle_resize&#039;&#039; function. Below the customize dock function type the following:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
function theme_dockmod_handle_resize() {&lt;br /&gt;
    var dock = M.core_dock;&lt;br /&gt;
    var panel = dock.getPanel();&lt;br /&gt;
    var item = dock.getActiveItem();&lt;br /&gt;
    // Check its visible no point doing anything if its not.&lt;br /&gt;
    if (panel.visible === false || typeof(item) !== &#039;object&#039;) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    var buffer = dock.cfg.buffer;&lt;br /&gt;
    var screenheight = parseInt(dock.nodes.body.get(&#039;winHeight&#039;))-(buffer*2)-dock.nodes.dock.get(&#039;offsetHeight&#039;);&lt;br /&gt;
    var scrolltop = panel.contentBody.get(&#039;scrollTop&#039;);&lt;br /&gt;
    // Reset the height of the panel so that we can accurately measure it&lt;br /&gt;
    panel.contentBody.setStyle(&#039;height&#039;, &#039;auto&#039;);&lt;br /&gt;
    // Remove the oversized class if it is there.&lt;br /&gt;
    panel.removeClass(&#039;oversized_content&#039;);&lt;br /&gt;
    var panelheight = panel.get(&#039;offsetHeight&#039;);&lt;br /&gt;
    // Set the height of the panel if required and add the oversized class&lt;br /&gt;
    if (panelheight &amp;gt; screenheight) {&lt;br /&gt;
        panel.contentBody.setStyle(&#039;height&#039;, (screenheight - panel.contentHeader.get(&#039;offsetHeight&#039;))+&#039;px&#039;);&lt;br /&gt;
        panel.addClass(&#039;oversized_content&#039;);&lt;br /&gt;
    }&lt;br /&gt;
    // Set the scrolltop of the panel to what it was before we started.&lt;br /&gt;
    if (scrolltop) {&lt;br /&gt;
        panel.contentBody.set(&#039;scrollTop&#039;, scrolltop);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Save the file now, purge the Moodle cache, and reload the page.&lt;br /&gt;
If you try to replicate the bug now you should find instead you get scrollbars and things work fine.&lt;br /&gt;
&lt;br /&gt;
Congratulations, you&#039;ve successfully created a horizontal dock!&lt;br /&gt;
&lt;br /&gt;
==Complete source==&lt;br /&gt;
The following is the complete source files for this tutorial.&lt;br /&gt;
===config.php===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This is the config file for the dockmod theme.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;name = &#039;dockmod&#039;;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;dockmod&#039;);&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;, &#039;base&#039;);&lt;br /&gt;
$THEME-&amp;gt;enable_dock = true;&lt;br /&gt;
$THEME-&amp;gt;javascripts = array(&#039;dockmod&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===dockmod.css===&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
body.has_dock {margin-top:30px;margin-left:0;}&lt;br /&gt;
&lt;br /&gt;
/** This is the CSS to display the block on the top of the screen */&lt;br /&gt;
.has_dock_top_horizontal #dock {width:100%;height:30px;background-image:url([[pix:theme|hgradient]]);background-repeat: repeat-x;border-right-width:0;border-bottom:1px solid #000;}&lt;br /&gt;
.has_dock_top_horizontal #dock .dockeditem_container {margin-top:0;}&lt;br /&gt;
.has_dock_top_horizontal #dock .dockeditem {display:inline-block;}&lt;br /&gt;
.has_dock_top_horizontal #dock .dockeditem .dockedtitle {background-image:url([[pix:theme|hgradient]]);background-repeat: repeat-x;background-position:0 10%;border-style:solid;border-width: 0 1px 0 0;border-color:#AAA;}&lt;br /&gt;
.has_dock_top_horizontal #dock .dockeditem .dockedtitle h2 {margin:0 12px;line-height:30px;}&lt;br /&gt;
.has_dock_top_horizontal #dock .dockeditem.firstdockitem {margin-left:10px;}&lt;br /&gt;
.has_dock_top_horizontal #dock .dockeditem.firstdockitem .dockedtitle {border-left-width:1px;}&lt;br /&gt;
.has_dock_top_horizontal #dock .controls {bottom:auto;right:10px;top:0;width:auto;line-height:30px;}&lt;br /&gt;
.has_dock_top_horizontal #dock #dockeditempanel {position:absolute;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===dockmod.js===&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
function customise_dock_for_theme() {&lt;br /&gt;
    var dock = M.core_dock;&lt;br /&gt;
    dock.cfg.position = &#039;top&#039;;&lt;br /&gt;
    dock.cfg.orientation = &#039;horizontal&#039;;&lt;br /&gt;
    dock.on(&#039;dock:resizepanelcomplete&#039;, theme_dockmod_handle_resize);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function theme_dockmod_handle_resize() {&lt;br /&gt;
    var dock = M.core_dock;&lt;br /&gt;
    var panel = dock.getPanel();&lt;br /&gt;
    var item = dock.getActiveItem();&lt;br /&gt;
    // Check its visible no point doing anything if its not.&lt;br /&gt;
    if (panel.visible === false || typeof(item) !== &#039;object&#039;) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    var buffer = dock.cfg.buffer;&lt;br /&gt;
    var screenheight = parseInt(dock.nodes.body.get(&#039;winHeight&#039;))-(buffer*2)-dock.nodes.dock.get(&#039;offsetHeight&#039;);&lt;br /&gt;
    var scrolltop = panel.contentBody.get(&#039;scrollTop&#039;);&lt;br /&gt;
    // Reset the height of the panel so that we can accurately measure it&lt;br /&gt;
    panel.contentBody.setStyle(&#039;height&#039;, &#039;auto&#039;);&lt;br /&gt;
    // Remove the oversized class if it is there.&lt;br /&gt;
    panel.removeClass(&#039;oversized_content&#039;);&lt;br /&gt;
    var panelheight = panel.get(&#039;offsetHeight&#039;);&lt;br /&gt;
    // Set the height of the panel if required and add the oversized class&lt;br /&gt;
    if (panelheight &amp;gt; screenheight) {&lt;br /&gt;
        panel.contentBody.setStyle(&#039;height&#039;, (screenheight - panel.contentHeader.get(&#039;offsetHeight&#039;))+&#039;px&#039;);&lt;br /&gt;
        panel.addClass(&#039;oversized_content&#039;);&lt;br /&gt;
    }&lt;br /&gt;
    // Set the scrolltop of the panel to what it was before we started.&lt;br /&gt;
    if (scrolltop) {&lt;br /&gt;
        panel.contentBody.set(&#039;scrollTop&#039;, scrolltop);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Creating a moveable dock==&lt;br /&gt;
A while ago I created theme that like this one supports a horizontal dock, however it goes one step further by adding a button above the undock all button that when clicked moves the down to the next position (without refreshing the page).&lt;br /&gt;
&lt;br /&gt;
For those interested in having a look at that you can find it on my github account at: https://github.com/samhemelryk/moodle-theme_dockmod&lt;br /&gt;
&lt;br /&gt;
==More information==&lt;br /&gt;
&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]]&lt;br /&gt;
* [[Development:Styling and customising the dock]]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_how_to_make_the_dock_horizontal&amp;diff=81973</id>
		<title>Development:Themes 2.0 how to make the dock horizontal</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_how_to_make_the_dock_horizontal&amp;diff=81973"/>
		<updated>2011-03-16T03:02:26Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* The CSS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}{{Moodle 2.0}}This quick tutorial looks at how to move the dock from its vertical position on the left hand side of the screen to a horizontal position at the top of the screen.&amp;lt;br /&amp;gt;&lt;br /&gt;
This modification will be done entirely within a theme through the creation of a small amount of JavaScript and a few lines of CSS.&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
If you&#039;re new to Moodle and haven&#039;t yet read the tutorial on creating your first theme I strongly suggest you head there first.&amp;lt;br /&amp;gt;&lt;br /&gt;
I&#039;d also strongly suggest you read [[Development:Styling and customising the dock]] which explains the structure of the dock and a few of the things you will need to know in order to tackle this tutorial.&lt;br /&gt;
&lt;br /&gt;
In order to make this tutorial easier to understand I am going to create a new theme that we&#039;ll call &#039;&#039;&#039;dockmod&#039;&#039;&#039; in which we will create this modification.&lt;br /&gt;
So first step within your Moodle theme directory create a new directory called &#039;&#039;dockmod&#039;&#039;. Within this new directory we&#039;ll create two further directories JavaScript, and style.&lt;br /&gt;
You should now have a directory structure like the one shown below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
moodle/theme/dockmod&lt;br /&gt;
moodle/theme/dockmod/javascript&lt;br /&gt;
moodle/theme/dockmod/style&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next step is to create the three files we are going to need, config.php, dockmod.js, and dockmod.css.&lt;br /&gt;
# config.php is of course for our theme&#039;s configuration and as you know an essential for any theme.&lt;br /&gt;
# dockmod.js will be created in the JavaScript directory, this file will contain the bit of JavaScript we need to write to get our modification to work.&lt;br /&gt;
# dockmod.css will be created in the style directory, this file will contain the CSS we need in order to make the dock horizontal.&lt;br /&gt;
&lt;br /&gt;
You should end up with the following files:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
moodle/theme/dockmod/config.php&lt;br /&gt;
moodle/theme/dockmod/javascript/dockmod.js&lt;br /&gt;
moodle/theme/dockmod/style/dockmod.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==config.php==&lt;br /&gt;
In this step we will be setting up the config.php file for this theme, to be truthful there should be nothing new here for you, this is the easy part of the tutorial.&lt;br /&gt;
The idea of this theme is to simply extend the standard theme and make the dock modification. This has the advantage that our theme will only consist of the JS and CSS required to achieve the dock modification we want.&lt;br /&gt;
&lt;br /&gt;
So open the config.php file in your favourite editor and type the following in:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This is the config file for the dockmod theme.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;name = &#039;dockmod&#039;;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;dockmod&#039;);&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;, &#039;base&#039;);&lt;br /&gt;
$THEME-&amp;gt;enable_dock = true;&lt;br /&gt;
$THEME-&amp;gt;javascripts = array(&#039;dockmod&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So pretty simple really, the name of our theme is &#039;&#039;dockmod&#039;&#039;, you already knew that!&lt;br /&gt;
The parents for this new theme are standard and base as explained above.&lt;br /&gt;
We have one stylesheet also called dockmod (theme/dockmod/style/dockmod.css), and we have one JavaScript file also called dockmod (theme/dockmod/javascript/dockmod.js) and of course its essential we enable the dock, otherwise there&#039;s no point in creating this modification.&lt;br /&gt;
&lt;br /&gt;
==The JavaScript==&lt;br /&gt;
OK this is where the tutorial starts to enter the [potentially] unknown.&lt;br /&gt;
&lt;br /&gt;
The dock is pretty cool in that it looks for a specific JavaScript function when it loads and calls it if it exists, we can use this to modify the dock as we want. It also published several events that we are able to listen to in order to make further modifications when certain things happen.&lt;br /&gt;
&lt;br /&gt;
In our case we want to make the dock horizontal. Now this isn&#039;t actually as nasty as it sounds because in a limited way the dock supports this! When I first wrote the dock I had in mind that one day I would have time to extend the dock to make it moveable, as such I wrote some basic support into it to allow the position and orientation to be switched. I know that a few of you in the community who have looked at making a horizontal dock have found these properties. Functions that rely on the position or orientation of the dock such as making the titles vertical have code within them that checks it makes sense to do so based upon the values of those properties.&lt;br /&gt;
All in all this makes our modification a lot simpler as half the work is already done!&lt;br /&gt;
&lt;br /&gt;
To start with open &#039;&#039;javascript/dockmod.js&#039;&#039; in your favourite editor and type the following:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
function customise_dock_for_theme() {&lt;br /&gt;
    var dock = M.core_dock;&lt;br /&gt;
    dock.cfg.position = &#039;top&#039;;&lt;br /&gt;
    dock.cfg.orientation = &#039;horizontal&#039;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And that is it; It sounds hard, but as you see really it is very easy (although as you get through this tutorial you will see we actually add a bit more JS later on).&lt;br /&gt;
&lt;br /&gt;
So how this works:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
function customise_dock_for_theme() { .... }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
As mentioned above when the dock first loads it looks for a function and calls it, well this is the function &#039;&#039;&#039;customise_dock_for_theme&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
var dock = M.core_dock;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are collecting the dock into a variable. It is in this case available from the global M object.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
dock.cfg.position = &#039;top&#039;;&lt;br /&gt;
dock.cfg.orientation = &#039;horizontal&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
These two lines set two configuration variables for the dock, the position and the orientation. There are several other config properties that perhaps will be explored within another document or tutorial.&lt;br /&gt;
&lt;br /&gt;
==The CSS==&lt;br /&gt;
If you save you changes presently and view your theme in your browser you will likely see a big mess. That is because while the JavaScript supports a horizontal dock there is not yet any CSS to support displaying the dock horizontally.&lt;br /&gt;
&lt;br /&gt;
Because of this we will need to write a bit of CSS to ensure the dock is displayed correctly.&lt;br /&gt;
Open &#039;&#039;style/dockmod.css&#039;&#039; in your favourite editor and type the following:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
body.has_dock {margin-top:30px;margin-left:0;}&lt;br /&gt;
body.has_dock_top_horizontal #dock {width:100%;height:30px;background-image:url([[pix:theme|hgradient]]);background-repeat: repeat-x;border-right-width:0;border-bottom:1px solid #000;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .dockeditem_container {margin-top:0;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .dockeditem {display:inline-block;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .dockeditem .dockedtitle {background-image:url([[pix:theme|hgradient]]);background-repeat: repeat-x;background-position:0 10%;border-style:solid;border-width: 0 1px 0 0;border-color:#AAA;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .dockeditem .dockedtitle h2 {margin:0 12px;line-height:30px;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .dockeditem.firstdockitem {margin-left:10px;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .dockeditem.firstdockitem .dockedtitle {border-left-width:1px;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .controls {bottom:auto;right:10px;top:0;width:auto;line-height:30px;}&lt;br /&gt;
body.has_dock_top_horizontal #dock #dockeditempanel {position:absolute;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That&#039;s it!&lt;br /&gt;
&lt;br /&gt;
The first line of CSS is to correct the margin on the body that accommodates the dock, we need to remove the left margin and increase the top margin.&lt;br /&gt;
The other lines of CSS basically just correct change to horizontal images, change positioning from vertical to horizontal, and swap X/Y properties.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PLEASE NOTE:&#039;&#039;&#039; the above CSS using &#039;&#039;display:inline-block&#039;&#039; so this won&#039;t work in IE6/7, if this is a problem for anyone you could probably achieve something similar using floats.&lt;br /&gt;
&lt;br /&gt;
==Correcting a vertical bug==&lt;br /&gt;
If you now open your site in your browser and switch to your theme you should see a horizontal dock.&lt;br /&gt;
If you have a bit of a play with if you will notice that if you dock the settings block and fully expand it it will run off the bottom of the page and there will be no scroll bar.&lt;br /&gt;
This has happened because we changed the position attributes of the dock in our CSS above. Essentially we could tinker with the CSS and try to fix it there, however based upon the design of the block and the complexities of getting it to work cross browser I can tell you it&#039;s going to be hard. Instead I&#039;ll show you how we can fix it in JavaScript.&lt;br /&gt;
&lt;br /&gt;
Open your dockmod.js file again and type the following within the customize dock function below the three lines that are already in there.&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
dock.on(&#039;dock:resizepanelcomplete&#039;, theme_dockmod_handle_resize);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This line of code is adding an event listener to the dock so that when it fires the &#039;&#039;&#039;dock:resizepanelcomplete&#039;&#039;&#039; event the function &#039;&#039;&#039;theme_dockmod_handle_resize&#039;&#039;&#039; which we create shortly will get called.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;resizepanelcomplete&#039;&#039; function gets called &#039;&#039;&#039;after&#039;&#039;&#039; the panel that shows the content of a block has been resized. The panel gets resized any time it&#039;s display changes, e.g. when it is shown, or when the content within the panel changes (you expand something).&amp;lt;br /&amp;gt;&lt;br /&gt;
This event is perfect for our needs as when it is called we can look at the height of the panel and if it is more than the height of the screen we can add scrollbars to it and set the height so that the user can access all of the content of the panel.&lt;br /&gt;
&lt;br /&gt;
Now we need to write the &#039;&#039;theme_dockmod_handle_resize&#039;&#039; function. Below the customize dock function type the following:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
function theme_dockmod_handle_resize() {&lt;br /&gt;
    var dock = M.core_dock;&lt;br /&gt;
    var panel = dock.getPanel();&lt;br /&gt;
    var item = dock.getActiveItem();&lt;br /&gt;
    // Check its visible no point doing anything if its not.&lt;br /&gt;
    if (panel.visible === false || typeof(item) !== &#039;object&#039;) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    var buffer = dock.cfg.buffer;&lt;br /&gt;
    var screenheight = parseInt(dock.nodes.body.get(&#039;winHeight&#039;))-(buffer*2)-dock.nodes.dock.get(&#039;offsetHeight&#039;);&lt;br /&gt;
    var scrolltop = panel.contentBody.get(&#039;scrollTop&#039;);&lt;br /&gt;
    // Reset the height of the panel so that we can accurately measure it&lt;br /&gt;
    panel.contentBody.setStyle(&#039;height&#039;, &#039;auto&#039;);&lt;br /&gt;
    // Remove the oversized class if it is there.&lt;br /&gt;
    panel.removeClass(&#039;oversized_content&#039;);&lt;br /&gt;
    var panelheight = panel.get(&#039;offsetHeight&#039;);&lt;br /&gt;
    // Set the height of the panel if required and add the oversized class&lt;br /&gt;
    if (panelheight &amp;gt; screenheight) {&lt;br /&gt;
        panel.contentBody.setStyle(&#039;height&#039;, (screenheight - panel.contentHeader.get(&#039;offsetHeight&#039;))+&#039;px&#039;);&lt;br /&gt;
        panel.addClass(&#039;oversized_content&#039;);&lt;br /&gt;
    }&lt;br /&gt;
    // Set the scrolltop of the panel to what it was before we started.&lt;br /&gt;
    if (scrolltop) {&lt;br /&gt;
        panel.contentBody.set(&#039;scrollTop&#039;, scrolltop);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Save the file now, purge the Moodle cache, and reload the page.&lt;br /&gt;
If you try to replicate the bug now you should find instead you get scrollbars and things work fine.&lt;br /&gt;
&lt;br /&gt;
Congratulations, you&#039;ve successfully created a horizontal dock!&lt;br /&gt;
&lt;br /&gt;
==Complete source==&lt;br /&gt;
The following is the complete source files for this tutorial.&lt;br /&gt;
===config.php===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This is the config file for the dockmod theme.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;name = &#039;dockmod&#039;;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;dockmod&#039;);&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;, &#039;base&#039;);&lt;br /&gt;
$THEME-&amp;gt;enable_dock = true;&lt;br /&gt;
$THEME-&amp;gt;javascripts = array(&#039;dockmod&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===dockmod.css===&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
body.has_dock {margin-top:30px;margin-left:0;}&lt;br /&gt;
&lt;br /&gt;
/** This is the CSS to display the block on the top of the screen */&lt;br /&gt;
.has_dock_top_horizontal #dock {width:100%;height:30px;background-image:url([[pix:theme|hgradient]]);background-repeat: repeat-x;border-right-width:0;border-bottom:1px solid #000;}&lt;br /&gt;
.has_dock_top_horizontal #dock .dockeditem_container {margin-top:0;}&lt;br /&gt;
.has_dock_top_horizontal #dock .dockeditem {display:inline-block;}&lt;br /&gt;
.has_dock_top_horizontal #dock .dockeditem .dockedtitle {background-image:url([[pix:theme|hgradient]]);background-repeat: repeat-x;background-position:0 10%;border-style:solid;border-width: 0 1px 0 0;border-color:#AAA;}&lt;br /&gt;
.has_dock_top_horizontal #dock .dockeditem .dockedtitle h2 {margin:0 12px;line-height:30px;}&lt;br /&gt;
.has_dock_top_horizontal #dock .dockeditem.firstdockitem {margin-left:10px;}&lt;br /&gt;
.has_dock_top_horizontal #dock .dockeditem.firstdockitem .dockedtitle {border-left-width:1px;}&lt;br /&gt;
.has_dock_top_horizontal #dock .controls {bottom:auto;right:10px;top:0;width:auto;line-height:30px;}&lt;br /&gt;
.has_dock_top_horizontal #dock #dockeditempanel {position:absolute;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===dockmod.js===&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
function theme_dockmod_handle_resize() {&lt;br /&gt;
    var dock = M.core_dock;&lt;br /&gt;
    var panel = dock.getPanel();&lt;br /&gt;
    var item = dock.getActiveItem();&lt;br /&gt;
    // Check its visible no point doing anything if its not.&lt;br /&gt;
    if (panel.visible === false || typeof(item) !== &#039;object&#039;) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    var buffer = dock.cfg.buffer;&lt;br /&gt;
    var screenheight = parseInt(dock.nodes.body.get(&#039;winHeight&#039;))-(buffer*2)-dock.nodes.dock.get(&#039;offsetHeight&#039;);&lt;br /&gt;
    var scrolltop = panel.contentBody.get(&#039;scrollTop&#039;);&lt;br /&gt;
    // Reset the height of the panel so that we can accurately measure it&lt;br /&gt;
    panel.contentBody.setStyle(&#039;height&#039;, &#039;auto&#039;);&lt;br /&gt;
    // Remove the oversized class if it is there.&lt;br /&gt;
    panel.removeClass(&#039;oversized_content&#039;);&lt;br /&gt;
    var panelheight = panel.get(&#039;offsetHeight&#039;);&lt;br /&gt;
    // Set the height of the panel if required and add the oversized class&lt;br /&gt;
    if (panelheight &amp;gt; screenheight) {&lt;br /&gt;
        panel.contentBody.setStyle(&#039;height&#039;, (screenheight - panel.contentHeader.get(&#039;offsetHeight&#039;))+&#039;px&#039;);&lt;br /&gt;
        panel.addClass(&#039;oversized_content&#039;);&lt;br /&gt;
    }&lt;br /&gt;
    // Set the scrolltop of the panel to what it was before we started.&lt;br /&gt;
    if (scrolltop) {&lt;br /&gt;
        panel.contentBody.set(&#039;scrollTop&#039;, scrolltop);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Creating a moveable dock==&lt;br /&gt;
A while ago I created theme that like this one supports a horizontal dock, however it goes one step further by adding a button above the undock all button that when clicked moves the down to the next position (without refreshing the page).&lt;br /&gt;
&lt;br /&gt;
For those interested in having a look at that you can find it on my github account at: https://github.com/samhemelryk/moodle-theme_dockmod&lt;br /&gt;
&lt;br /&gt;
==More information==&lt;br /&gt;
&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]]&lt;br /&gt;
* [[Development:Styling and customising the dock]]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_how_to_make_the_dock_horizontal&amp;diff=81972</id>
		<title>Development:Themes 2.0 how to make the dock horizontal</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_how_to_make_the_dock_horizontal&amp;diff=81972"/>
		<updated>2011-03-16T02:57:23Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: Added categories and theme template&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}{{Moodle 2.0}}This quick tutorial looks at how to move the dock from its vertical position on the left hand side of the screen to a horizontal position at the top of the screen.&amp;lt;br /&amp;gt;&lt;br /&gt;
This modification will be done entirely within a theme through the creation of a small amount of JavaScript and a few lines of CSS.&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
If you&#039;re new to Moodle and haven&#039;t yet read the tutorial on creating your first theme I strongly suggest you head there first.&amp;lt;br /&amp;gt;&lt;br /&gt;
I&#039;d also strongly suggest you read [[Development:Styling and customising the dock]] which explains the structure of the dock and a few of the things you will need to know in order to tackle this tutorial.&lt;br /&gt;
&lt;br /&gt;
In order to make this tutorial easier to understand I am going to create a new theme that we&#039;ll call &#039;&#039;&#039;dockmod&#039;&#039;&#039; in which we will create this modification.&lt;br /&gt;
So first step within your Moodle theme directory create a new directory called &#039;&#039;dockmod&#039;&#039;. Within this new directory we&#039;ll create two further directories JavaScript, and style.&lt;br /&gt;
You should now have a directory structure like the one shown below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
moodle/theme/dockmod&lt;br /&gt;
moodle/theme/dockmod/javascript&lt;br /&gt;
moodle/theme/dockmod/style&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next step is to create the three files we are going to need, config.php, dockmod.js, and dockmod.css.&lt;br /&gt;
# config.php is of course for our theme&#039;s configuration and as you know an essential for any theme.&lt;br /&gt;
# dockmod.js will be created in the JavaScript directory, this file will contain the bit of JavaScript we need to write to get our modification to work.&lt;br /&gt;
# dockmod.css will be created in the style directory, this file will contain the CSS we need in order to make the dock horizontal.&lt;br /&gt;
&lt;br /&gt;
You should end up with the following files:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
moodle/theme/dockmod/config.php&lt;br /&gt;
moodle/theme/dockmod/javascript/dockmod.js&lt;br /&gt;
moodle/theme/dockmod/style/dockmod.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==config.php==&lt;br /&gt;
In this step we will be setting up the config.php file for this theme, to be truthful there should be nothing new here for you, this is the easy part of the tutorial.&lt;br /&gt;
The idea of this theme is to simply extend the standard theme and make the dock modification. This has the advantage that our theme will only consist of the JS and CSS required to achieve the dock modification we want.&lt;br /&gt;
&lt;br /&gt;
So open the config.php file in your favourite editor and type the following in:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This is the config file for the dockmod theme.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;name = &#039;dockmod&#039;;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;dockmod&#039;);&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;, &#039;base&#039;);&lt;br /&gt;
$THEME-&amp;gt;enable_dock = true;&lt;br /&gt;
$THEME-&amp;gt;javascripts = array(&#039;dockmod&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So pretty simple really, the name of our theme is &#039;&#039;dockmod&#039;&#039;, you already knew that!&lt;br /&gt;
The parents for this new theme are standard and base as explained above.&lt;br /&gt;
We have one stylesheet also called dockmod (theme/dockmod/style/dockmod.css), and we have one JavaScript file also called dockmod (theme/dockmod/javascript/dockmod.js) and of course its essential we enable the dock, otherwise there&#039;s no point in creating this modification.&lt;br /&gt;
&lt;br /&gt;
==The JavaScript==&lt;br /&gt;
OK this is where the tutorial starts to enter the [potentially] unknown.&lt;br /&gt;
&lt;br /&gt;
The dock is pretty cool in that it looks for a specific JavaScript function when it loads and calls it if it exists, we can use this to modify the dock as we want. It also published several events that we are able to listen to in order to make further modifications when certain things happen.&lt;br /&gt;
&lt;br /&gt;
In our case we want to make the dock horizontal. Now this isn&#039;t actually as nasty as it sounds because in a limited way the dock supports this! When I first wrote the dock I had in mind that one day I would have time to extend the dock to make it moveable, as such I wrote some basic support into it to allow the position and orientation to be switched. I know that a few of you in the community who have looked at making a horizontal dock have found these properties. Functions that rely on the position or orientation of the dock such as making the titles vertical have code within them that checks it makes sense to do so based upon the values of those properties.&lt;br /&gt;
All in all this makes our modification a lot simpler as half the work is already done!&lt;br /&gt;
&lt;br /&gt;
To start with open &#039;&#039;javascript/dockmod.js&#039;&#039; in your favourite editor and type the following:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
function customise_dock_for_theme() {&lt;br /&gt;
    var dock = M.core_dock;&lt;br /&gt;
    dock.cfg.position = &#039;top&#039;;&lt;br /&gt;
    dock.cfg.orientation = &#039;horizontal&#039;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And that is it; It sounds hard, but as you see really it is very easy (although as you get through this tutorial you will see we actually add a bit more JS later on).&lt;br /&gt;
&lt;br /&gt;
So how this works:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
function customise_dock_for_theme() { .... }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
As mentioned above when the dock first loads it looks for a function and calls it, well this is the function &#039;&#039;&#039;customise_dock_for_theme&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
var dock = M.core_dock;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are collecting the dock into a variable. It is in this case available from the global M object.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
dock.cfg.position = &#039;top&#039;;&lt;br /&gt;
dock.cfg.orientation = &#039;horizontal&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
These two lines set two configuration variables for the dock, the position and the orientation. There are several other config properties that perhaps will be explored within another document or tutorial.&lt;br /&gt;
&lt;br /&gt;
==The CSS==&lt;br /&gt;
If you save you changes presently and view your theme in your browser you will likely see a big mess. That is because while the JavaScript supports a horizontal dock there is not yet any CSS to support displaying the dock horizontally.&lt;br /&gt;
&lt;br /&gt;
Because of this we will need to write a bit of CSS to ensure the dock is displayed correctly.&lt;br /&gt;
Open &#039;&#039;style/dockmod.css&#039;&#039; in your favourite editor and type the following:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
body.has_dock {margin-top:30px;margin-left:0;}&lt;br /&gt;
body.has_dock_top_horizontal #dock {width:100%;height:30px;background-image:url([[pix:theme|hgradient]]);background-repeat: repeat-x;border-right-width:0;border-bottom:1px solid #000;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .dockeditem_container {margin-top:0;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .dockeditem {display:inline-block;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .dockeditem .dockedtitle {background-image:url([[pix:theme|hgradient]]);background-repeat: repeat-x;background-position:0 10%;border-style:solid;border-width: 0 1px 0 0;border-color:#AAA;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .dockeditem .dockedtitle h2 {margin:0 12px;line-height:30px;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .dockeditem.firstdockitem {margin-left:10px;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .dockeditem.firstdockitem .dockedtitle {border-left-width:1px;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .controls {bottom:auto;right:10px;top:0;width:auto;line-height:30px;}&lt;br /&gt;
body.has_dock_top_horizontal #dock #dockeditempanel {position:absolute;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That&#039;s it!&lt;br /&gt;
&lt;br /&gt;
The first line of CSS is to correct the margin on the body that accommodates the dock, we need to remove the left margin and increase the top margin.&lt;br /&gt;
The other lines of CSS basically just correct change to horizontal images, change positioning from vertical to horizontal, and swap X/Y properties.&lt;br /&gt;
&lt;br /&gt;
==Correcting a vertical bug==&lt;br /&gt;
If you now open your site in your browser and switch to your theme you should see a horizontal dock.&lt;br /&gt;
If you have a bit of a play with if you will notice that if you dock the settings block and fully expand it it will run off the bottom of the page and there will be no scroll bar.&lt;br /&gt;
This has happened because we changed the position attributes of the dock in our CSS above. Essentially we could tinker with the CSS and try to fix it there, however based upon the design of the block and the complexities of getting it to work cross browser I can tell you it&#039;s going to be hard. Instead I&#039;ll show you how we can fix it in JavaScript.&lt;br /&gt;
&lt;br /&gt;
Open your dockmod.js file again and type the following within the customize dock function below the three lines that are already in there.&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
dock.on(&#039;dock:resizepanelcomplete&#039;, theme_dockmod_handle_resize);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This line of code is adding an event listener to the dock so that when it fires the &#039;&#039;&#039;dock:resizepanelcomplete&#039;&#039;&#039; event the function &#039;&#039;&#039;theme_dockmod_handle_resize&#039;&#039;&#039; which we create shortly will get called.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;resizepanelcomplete&#039;&#039; function gets called &#039;&#039;&#039;after&#039;&#039;&#039; the panel that shows the content of a block has been resized. The panel gets resized any time it&#039;s display changes, e.g. when it is shown, or when the content within the panel changes (you expand something).&amp;lt;br /&amp;gt;&lt;br /&gt;
This event is perfect for our needs as when it is called we can look at the height of the panel and if it is more than the height of the screen we can add scrollbars to it and set the height so that the user can access all of the content of the panel.&lt;br /&gt;
&lt;br /&gt;
Now we need to write the &#039;&#039;theme_dockmod_handle_resize&#039;&#039; function. Below the customize dock function type the following:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
function theme_dockmod_handle_resize() {&lt;br /&gt;
    var dock = M.core_dock;&lt;br /&gt;
    var panel = dock.getPanel();&lt;br /&gt;
    var item = dock.getActiveItem();&lt;br /&gt;
    // Check its visible no point doing anything if its not.&lt;br /&gt;
    if (panel.visible === false || typeof(item) !== &#039;object&#039;) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    var buffer = dock.cfg.buffer;&lt;br /&gt;
    var screenheight = parseInt(dock.nodes.body.get(&#039;winHeight&#039;))-(buffer*2)-dock.nodes.dock.get(&#039;offsetHeight&#039;);&lt;br /&gt;
    var scrolltop = panel.contentBody.get(&#039;scrollTop&#039;);&lt;br /&gt;
    // Reset the height of the panel so that we can accurately measure it&lt;br /&gt;
    panel.contentBody.setStyle(&#039;height&#039;, &#039;auto&#039;);&lt;br /&gt;
    // Remove the oversized class if it is there.&lt;br /&gt;
    panel.removeClass(&#039;oversized_content&#039;);&lt;br /&gt;
    var panelheight = panel.get(&#039;offsetHeight&#039;);&lt;br /&gt;
    // Set the height of the panel if required and add the oversized class&lt;br /&gt;
    if (panelheight &amp;gt; screenheight) {&lt;br /&gt;
        panel.contentBody.setStyle(&#039;height&#039;, (screenheight - panel.contentHeader.get(&#039;offsetHeight&#039;))+&#039;px&#039;);&lt;br /&gt;
        panel.addClass(&#039;oversized_content&#039;);&lt;br /&gt;
    }&lt;br /&gt;
    // Set the scrolltop of the panel to what it was before we started.&lt;br /&gt;
    if (scrolltop) {&lt;br /&gt;
        panel.contentBody.set(&#039;scrollTop&#039;, scrolltop);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Save the file now, purge the Moodle cache, and reload the page.&lt;br /&gt;
If you try to replicate the bug now you should find instead you get scrollbars and things work fine.&lt;br /&gt;
&lt;br /&gt;
Congratulations, you&#039;ve successfully created a horizontal dock!&lt;br /&gt;
&lt;br /&gt;
==Complete source==&lt;br /&gt;
The following is the complete source files for this tutorial.&lt;br /&gt;
===config.php===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This is the config file for the dockmod theme.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;name = &#039;dockmod&#039;;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;dockmod&#039;);&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;, &#039;base&#039;);&lt;br /&gt;
$THEME-&amp;gt;enable_dock = true;&lt;br /&gt;
$THEME-&amp;gt;javascripts = array(&#039;dockmod&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===dockmod.css===&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
body.has_dock {margin-top:30px;margin-left:0;}&lt;br /&gt;
&lt;br /&gt;
/** This is the CSS to display the block on the top of the screen */&lt;br /&gt;
.has_dock_top_horizontal #dock {width:100%;height:30px;background-image:url([[pix:theme|hgradient]]);background-repeat: repeat-x;border-right-width:0;border-bottom:1px solid #000;}&lt;br /&gt;
.has_dock_top_horizontal #dock .dockeditem_container {margin-top:0;}&lt;br /&gt;
.has_dock_top_horizontal #dock .dockeditem {display:inline-block;}&lt;br /&gt;
.has_dock_top_horizontal #dock .dockeditem .dockedtitle {background-image:url([[pix:theme|hgradient]]);background-repeat: repeat-x;background-position:0 10%;border-style:solid;border-width: 0 1px 0 0;border-color:#AAA;}&lt;br /&gt;
.has_dock_top_horizontal #dock .dockeditem .dockedtitle h2 {margin:0 12px;line-height:30px;}&lt;br /&gt;
.has_dock_top_horizontal #dock .dockeditem.firstdockitem {margin-left:10px;}&lt;br /&gt;
.has_dock_top_horizontal #dock .dockeditem.firstdockitem .dockedtitle {border-left-width:1px;}&lt;br /&gt;
.has_dock_top_horizontal #dock .controls {bottom:auto;right:10px;top:0;width:auto;line-height:30px;}&lt;br /&gt;
.has_dock_top_horizontal #dock #dockeditempanel {position:absolute;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===dockmod.js===&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
function theme_dockmod_handle_resize() {&lt;br /&gt;
    var dock = M.core_dock;&lt;br /&gt;
    var panel = dock.getPanel();&lt;br /&gt;
    var item = dock.getActiveItem();&lt;br /&gt;
    // Check its visible no point doing anything if its not.&lt;br /&gt;
    if (panel.visible === false || typeof(item) !== &#039;object&#039;) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    var buffer = dock.cfg.buffer;&lt;br /&gt;
    var screenheight = parseInt(dock.nodes.body.get(&#039;winHeight&#039;))-(buffer*2)-dock.nodes.dock.get(&#039;offsetHeight&#039;);&lt;br /&gt;
    var scrolltop = panel.contentBody.get(&#039;scrollTop&#039;);&lt;br /&gt;
    // Reset the height of the panel so that we can accurately measure it&lt;br /&gt;
    panel.contentBody.setStyle(&#039;height&#039;, &#039;auto&#039;);&lt;br /&gt;
    // Remove the oversized class if it is there.&lt;br /&gt;
    panel.removeClass(&#039;oversized_content&#039;);&lt;br /&gt;
    var panelheight = panel.get(&#039;offsetHeight&#039;);&lt;br /&gt;
    // Set the height of the panel if required and add the oversized class&lt;br /&gt;
    if (panelheight &amp;gt; screenheight) {&lt;br /&gt;
        panel.contentBody.setStyle(&#039;height&#039;, (screenheight - panel.contentHeader.get(&#039;offsetHeight&#039;))+&#039;px&#039;);&lt;br /&gt;
        panel.addClass(&#039;oversized_content&#039;);&lt;br /&gt;
    }&lt;br /&gt;
    // Set the scrolltop of the panel to what it was before we started.&lt;br /&gt;
    if (scrolltop) {&lt;br /&gt;
        panel.contentBody.set(&#039;scrollTop&#039;, scrolltop);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Creating a moveable dock==&lt;br /&gt;
A while ago I created theme that like this one supports a horizontal dock, however it goes one step further by adding a button above the undock all button that when clicked moves the down to the next position (without refreshing the page).&lt;br /&gt;
&lt;br /&gt;
For those interested in having a look at that you can find it on my github account at: https://github.com/samhemelryk/moodle-theme_dockmod&lt;br /&gt;
&lt;br /&gt;
==More information==&lt;br /&gt;
&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]]&lt;br /&gt;
* [[Development:Styling and customising the dock]]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=Development:Styling_and_customising_the_dock&amp;diff=81971</id>
		<title>Development:Styling and customising the dock</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=Development:Styling_and_customising_the_dock&amp;diff=81971"/>
		<updated>2011-03-16T02:56:32Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* Tutorial: Creating a moveable dock */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}{{Moodle 2.0}}The dock is a new addition to Moodle 2.0, it allows the user to move blocks from the flow of the page onto a special bar that is displayed in a constant position on the side of the page by default.&lt;br /&gt;
This document looks at how to style the dock using CSS, as well as how to customise or manipulate it within JavaScript.&lt;br /&gt;
&lt;br /&gt;
==Styling the dock==&lt;br /&gt;
Styling the dock is really no different to styling anything else within a web site however there are a couple of things that may slow you down and reading the following document may help you in your understanding of how the dock works and how you should go about styling it.&lt;br /&gt;
&lt;br /&gt;
The following items are things that you should be aware of before starting to style the dock:&lt;br /&gt;
# When a block is docked the dock attempts to ensure that existing styles for the block are still applied by adding the standard block &#039;&#039;&#039;.block_&#039;&#039;blockname&#039;&#039;&#039;&#039;&#039;. Because of this trick we don&#039;t need to look at the actual content of a docked item it will always be the same as the block.&lt;br /&gt;
# The dock remembers what blocks are docked by saving the user&#039;s choices within the database using AJAX calls. This can be looked at to minimise display jumping within a theme&#039;s layoutfile. Read on to learn how.&lt;br /&gt;
# The dock uses CSS classes to transition the different states. These CSS classes control things such as the whether the dock is visible, whether the panel is visible, and how we know which item is being viewed. Read the section on [[#State_classes|state classes]] to learn more about these.&lt;br /&gt;
# The structure of the dock is built entirely by JavaScript. Because of this you will need a tool such as FireBug to inspect it within a page as it won&#039;t be there until JavaScript has run.&lt;br /&gt;
# Although the base theme doesn&#039;t support the dock it does contain some core CSS to structure the dock by default.&lt;br /&gt;
&lt;br /&gt;
So lets get started and look at the structure.&lt;br /&gt;
===The structure of the dock===&lt;br /&gt;
[[Image:Dock.structure.201005.png|300px|thumb|Dock structure]]&lt;br /&gt;
The first image to the left graphically describes the hierarchical structure of the dock. The first thing you will notice about this image is that it doesn&#039;t describe what each element is for. It is just to illustrate the html structure without at styles or transformation.&lt;br /&gt;
&lt;br /&gt;
So what are the important elements here?&lt;br /&gt;
&lt;br /&gt;
; div#dock.dock.dock_left_vertical : This is the bar on the left. Positioned by default to be fixed position in the top left hand corner of the screen and 30px wide.&lt;br /&gt;
; div.dockeditem_container : This box contains all of the buttons which when clicked or hovered over will display the docked item. Or more technically causing the docked item panel to be shown.&lt;br /&gt;
; div#dock_item_x.dockeditem : This represents one of possibly several docked item buttons containing the title of the docked item. There are two things to note about this element: First it is repeated for every docked item. Second the x within the id is the item instance and should not be used for styling.&lt;br /&gt;
; div.controls : This contains any special controls for the dock and by default is displayed at the bottom of the dock. As of Moodle 2 Preview Release the only control here is to undock all docked items.&lt;br /&gt;
; div#dockeditempanel : This is the panel in which docked items are shown. Although it is within the dock is it positioned outside of the page relative to the button for the item it is currently showing. This element is based loosely off the YUI3 overlay.&lt;br /&gt;
&lt;br /&gt;
===The layout of the dock===&lt;br /&gt;
[[Image:Dock.layout.201005.png|300px|thumb|Dock layout]]&lt;br /&gt;
The second image on the left shows the layout of these elements within the standard theme.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;So what has gone on here?&#039;&#039;&#039;&lt;br /&gt;
First up ignore the bright colours and margins. I have put these colours in simply to highlight everything and ensure there is space between elements so I can show them apart.&lt;br /&gt;
&lt;br /&gt;
; div#dock : So immediately you notice that the dock is in the top left of the screen and the is fixed width. This is achieved by setting a strict with of 30px and setting the position of the &#039;&#039;#dock&#039;&#039; to fixed. The reason that everything is within the one &#039;&#039;#dock&#039;&#039; element is because it makes positioning everything very simple, now that we have set the position of &#039;&#039;#dock&#039;&#039; we don&#039;t need to worry about anything other than the panel which we&#039;ll get to shortly. You should also note that because of the strict width and position you need to be careful when applying styles to this element as it can have nasty effects on everything else.&lt;br /&gt;
&lt;br /&gt;
; div.dockeditem_container : Next you should notice that the &#039;&#039;.dockeditem_container&#039;&#039; doesn&#039;t extend to the bottom of the dock. Because there is not special positioning here it is behaving as div&#039;s normally do and this is the perfect place to really start styling your dock.&lt;br /&gt;
&lt;br /&gt;
; div.controls : After that within the structure we have &#039;&#039;div.controls&#039;&#039;. This element is positioned absolutely at the bottom of the dock, is 100% wide (so the full width of the dock) and uses &#039;&#039;text-align:center&#039;&#039; to ensure that the controls are centred.&lt;br /&gt;
&lt;br /&gt;
; div.dockeditem : Simply representing a button that can be hovered over or clicked to display the docked item the only important thing to note about this is that you should change the cursor to a pointer so that it is clear you can interact with it.&lt;br /&gt;
&lt;br /&gt;
; div#dockeditempanel : After &#039;&#039;#dock&#039;&#039; this is the most serious element in the dock. This element will contain the docked item and needs to positioned to the left of the dock and at the same height as the title of the item that is being displayed. Luckily you don&#039;t need to worry about the top position of the element that will be automatically adjusted by JavaScript however you will need to push the element to the left. This can be done easily by setting the position of the element to relative, and then setting left to 100%. Note you shouldn&#039;t style this element unless you know what you are doing, like the main dock element the smallest change can cause some terrible effects.&lt;br /&gt;
&lt;br /&gt;
; div.dockeditempanel_container : This element is there specifically to give you the themer an easy place to start styling the panel.&lt;br /&gt;
&lt;br /&gt;
; div.dockeditempanel_hd : This element contains the title of the docked item plus controls to undock or close it.&lt;br /&gt;
&lt;br /&gt;
; div.dockeditempanel_bd : Contains is the main content area for the panel.&lt;br /&gt;
&lt;br /&gt;
===State classes===&lt;br /&gt;
There are several state classes that the dock makes use of to achieve things such as the visibility of the dock, visibility of the panel, and which item is active.&lt;br /&gt;
The following table illustrates where these state classes are used.&lt;br /&gt;
{|  class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
! Element&lt;br /&gt;
! Class&lt;br /&gt;
! Description&lt;br /&gt;
! Default CSS&lt;br /&gt;
|-&lt;br /&gt;
|body&lt;br /&gt;
|has_dock&lt;br /&gt;
|This class is added to the body element when the dock is visible.&lt;br /&gt;
|Margin-left: 30px&lt;br /&gt;
|-&lt;br /&gt;
|#dock&lt;br /&gt;
|nothingdocked&lt;br /&gt;
|This class is added to the dock when there is nothing docked.&lt;br /&gt;
|visibility: hidden; display: none;&lt;br /&gt;
|-&lt;br /&gt;
|#dock&lt;br /&gt;
|.dock_&#039;&#039;position&#039;&#039;_&#039;&#039;style&#039;&#039;&lt;br /&gt;
|A special class is added to describe the docks desired position e.g. dock_left_vertical&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|.dockeditem&lt;br /&gt;
|activeitem&lt;br /&gt;
|This class is added to the item that is currently being shown.&lt;br /&gt;
|Change the background colour&lt;br /&gt;
|-&lt;br /&gt;
|.dockeditem&lt;br /&gt;
|firstdockitem&lt;br /&gt;
|This class is added to the first dock item.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|.dockeditem h2&lt;br /&gt;
|filterrotate&lt;br /&gt;
|Added when the title is being rotated by an IE filter [Internet Explorer only]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|#dockeditempanel&lt;br /&gt;
|dockitempanel_hidden&lt;br /&gt;
|Added to the panel when it is not being shown.&lt;br /&gt;
|visibility: hidden; display: none;&lt;br /&gt;
|-&lt;br /&gt;
|#dockeditempanel&lt;br /&gt;
|oversized_content&lt;br /&gt;
|Added when the panel required scrolling to show everything.&lt;br /&gt;
|Set the overflow method&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Layout file changes===&lt;br /&gt;
There is only one thing that you need to make sure of within your layout files if you are creating your own. You need to add the class &#039;&#039;block-region&#039;&#039; to all of the block region div&#039;s as shown below.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;region-post&amp;quot; class=&amp;quot;block-region&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;/code&amp;gt;&lt;br /&gt;
Whilst there is nothing else you &#039;&#039;&#039;need&#039;&#039;&#039; to change within your layout files there one other thing that you may want to do.&lt;br /&gt;
&lt;br /&gt;
Because the dock is loaded entirely by JavaScript you will notice a visual jump on the page if all of the blocks within a region have been docked. This is because the dock shrinks sections that have been completely docked so that they don&#039;t wast page space.&lt;br /&gt;
&lt;br /&gt;
Within you layout files you can check whether a section has been completely docked and then if it has set the body classes so that it is shrunk when the page is delivered.&lt;br /&gt;
&lt;br /&gt;
I&#039;m going to assume that you have all read the [[Development:Themes 2.0 creating your first theme]]. If you haven&#039;t go read it now.&lt;br /&gt;
So now that you&#039;ve created your first theme think back to the code you wrote at the top of your layout files that checks whether a page has block regions pre and post. The code was as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&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;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Right below these two lines we are going to add two more:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$showsidepre = ($hassidepre &amp;amp;&amp;amp; !$PAGE-&amp;gt;blocks-&amp;gt;region_completely_docked(&#039;side-pre&#039;, $OUTPUT));&lt;br /&gt;
$showsidepost = ($hassidepost &amp;amp;&amp;amp; !$PAGE-&amp;gt;blocks-&amp;gt;region_completely_docked(&#039;side-post&#039;, $OUTPUT));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
What we have here is two variables that tell use whether we should show the block regions pre and post. The verbal interpretation of this string is to say &#039;&#039;We will show this side if this side has content and if there is at least one block that has not been docked.&#039;&#039; and we repeat it for each side.&lt;br /&gt;
&lt;br /&gt;
Now that we know for each region that it has content and that we should show it we need some way to tell the page what block regions to show.&lt;br /&gt;
This is achieved by adding special classes to the body element of the page as follows:&lt;br /&gt;
; side-pre-only : This gets added to the body if we only want to show the block region pre.&lt;br /&gt;
; side-post-only : Just like side-pre-only except for the post region.&lt;br /&gt;
; content-only : This gets added if don&#039;t want to show either block region.&lt;br /&gt;
By default we want to show both regions so we don&#039;t need to add any class for this.&lt;br /&gt;
So how to do this in PHP?&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$bodyclasses = array();&lt;br /&gt;
if ($showsidepre &amp;amp;&amp;amp; !$showsidepost) {&lt;br /&gt;
    $bodyclasses[] = &#039;side-pre-only&#039;;&lt;br /&gt;
} else if ($showsidepost &amp;amp;&amp;amp; !$showsidepre) {&lt;br /&gt;
    $bodyclasses[] = &#039;side-post-only&#039;;&lt;br /&gt;
} else if (!$showsidepost &amp;amp;&amp;amp; !$showsidepre) {&lt;br /&gt;
    $bodyclasses[] = &#039;content-only&#039;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
What we have here is three if-else statements, of which either one or none will be true.&lt;br /&gt;
# The first if statement says if we want to show the pre region but not the post region add the class &#039;&#039;side-pre-only&#039;&#039;&lt;br /&gt;
# The second if statement says if we want to show the post region but not the pre region add the class &#039;&#039;side-post-only&#039;&#039;&lt;br /&gt;
# The third class says if we don&#039;t want to display either region add the class &#039;&#039;content-only&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Now that we know which class we want to add to the body element we need to do so. This can be done as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyid ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyclasses.&#039; &#039;.join(&#039; &#039;, $bodyclasses) ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
You&#039;ll notice this is very similar to the body tag you wrote in your first theme, however we have added&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
join(&#039; &#039;, $bodyclasses)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This php command simply concatenates each body class putting a space between each.&lt;br /&gt;
&lt;br /&gt;
Now the final thing to do is make sure that we don&#039;t show a block region if we don&#039;t have content for it. This can be done by adding if statements around each block region as follows:&lt;br /&gt;
&amp;lt;code php&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; class=&amp;quot;block-region&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; class=&amp;quot;block-region&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;/code&amp;gt;&lt;br /&gt;
For each if statement we are saying &#039;&#039;If this region has content display it.&#039;&#039; You&#039;ll notice that here we are using &#039;&#039;$hasside...&#039;&#039; instead of &#039;&#039;$showside...&#039;&#039; this is because we want to add them if they have content even if they won&#039;t be shown. Otherwise the dock won&#039;t be able to find them and you simply won&#039;t see the block.&lt;br /&gt;
&lt;br /&gt;
Having made the above changes if you now look at the layout files for the base theme you start to notice that they are looking very similar and indeed they are. If at any point you get stuck or don&#039;t know how to proceed have a look at the base themes layout files and see how its done there.&lt;br /&gt;
&lt;br /&gt;
===The core CSS===&lt;br /&gt;
As mentioned in the key points at the start of this document the base theme although not supporting the dock does contain structural CSS that ensure the dock is functional on all themes that choose to support it.&lt;br /&gt;
Lets look at the CSS within &#039;&#039;theme/base/style/dock.css&#039;&#039;, this is the core structural CSS for the dock.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/* Put a margin on the body if the dock is shown */&lt;br /&gt;
body.has_dock {margin-left:30px;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Well this is very simple, if the dock is being shown apply a 30px margin to the body. This is done to ensure that the dock doesn&#039;t overlap the body.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/** For the dock itself */&lt;br /&gt;
#dock {width:30px;position:fixed;top:0px;left:0px;height:100%;background-color:#FFF;border-right:1px solid #000;z-index:11000;}&lt;br /&gt;
#dock.nothingdocked {visibility: hidden;display:none;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
These two rules style the dock itself. Note the second rule is only applied when nothing is docked in which case we will hide the empty dock.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
#dock .dockeditem .firstdockitem {margin-top:1em;}&lt;br /&gt;
#dock .dockeditem .dockedtitle {border-bottom:1px solid #000;border-top:1px solid #000;cursor:pointer;}&lt;br /&gt;
#dock .dockeditem .dockedtitle h2 {font-size:0.8em;line-height:100%;text-align:center;}&lt;br /&gt;
#dock .dockeditem .dockedtitle .filterrotate {margin-left:8px;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The four rules above style the buttons that will show the docked items. Each docked item has one. The styles being used here arn&#039;t doing anything to special other than setting the cursor to pointer so that it is recognised as an actionable element.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
#dock .controls {position:absolute;bottom:1em;text-align:center;width:100%;}&lt;br /&gt;
#dock .controls img {cursor:pointer;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Very simply this bit of CSS. It is positioning the controls for the dock at the bottom centre of the dock.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/** For the panel the docked blocks are shown in */&lt;br /&gt;
#dockeditempanel {min-width:200px;position:relative;z-index:12000;left:100%;}&lt;br /&gt;
#dockeditempanel.dockitempanel_hidden {display:none;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
These two lines are applied to the docked item panel&#039;s base element and are VERY important to the operation of the dock. They ensure that when shown the panel is top the left of the dock and that when it is not being displayed it is not visible.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
#dockeditempanel .dockeditempanel_content {background-color:#fff;border:1px solid #000;z-index:12050;}&lt;br /&gt;
#dockeditempanel .dockeditempanel_bd {overflow:auto;width:auto;}&lt;br /&gt;
#dockeditempanel .dockeditempanel_bd .block_docked {margin:10px;}&lt;br /&gt;
#dockeditempanel .dockeditempanel_hd {border-bottom:1px solid #000;text-align:right;}&lt;br /&gt;
#dockeditempanel .dockeditempanel_hd h2 {display:inline;margin:0;padding-right:1em;}&lt;br /&gt;
#dockeditempanel .dockeditempanel_hd .commands {display:inline;}&lt;br /&gt;
#dockeditempanel .dockeditempanel_hd .commands img {margin-right:2px;vertical-align:middle;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The above lines of CSS are used to style the internal content of the panel. Note the styles for the block will be applied as if it were not docked.&lt;br /&gt;
&lt;br /&gt;
And that is it!&lt;br /&gt;
&lt;br /&gt;
Whilst things don&#039;t look to difficult when styling things if you don&#039;t think carefully about where you are applying styles you can quickly dig yourself a big hole. I would suggest going slowly at first when applying more styles and making sure you don&#039;t apply too many styles to the base elements #dock and #dockeditempanel.&lt;br /&gt;
&lt;br /&gt;
==Customising the dock==&lt;br /&gt;
This section of the document looks at how to customise the dock using JavaScript.&lt;br /&gt;
&lt;br /&gt;
It was recognised early on during the development of the dock that it probably won&#039;t suit everyone&#039;s needs, nor would it appeal to everyone. Because of this during development and the frequent revisions that were occurring during Moodle 2.0s development there was always a focus on ensuring the dock was customisable and that someone with a bit of time on their hands and a good knowledge of JavaScript could hack it to bits and make it into the tool they desired.&lt;br /&gt;
&lt;br /&gt;
This document doesn&#039;t go into the full details of how to customise the dock but should get anyone keen started quickly. Those who fear JavaScript should leave now!&lt;br /&gt;
&lt;br /&gt;
===Getting started===&lt;br /&gt;
The dock is written to make use of YUI3 and all the functionality that it has to offer, the main dock object both looks for specific callback functions and adds manages and fires several important events. At the same time it is also object orientated JavaScript which has the advantage in JavaScript of allowing subsequent JavaScript events to redefine methods of the object.&lt;br /&gt;
&lt;br /&gt;
This allows you the theme designer to write JavaScript to customise the dock in two fashions. The first through events and callbacks. The second through manually overriding the methods the dock uses.&lt;br /&gt;
&lt;br /&gt;
We will look into these two methods in the subsequent sections of this document, for the time being what you need to learn about is the JavaScript structure of the dock.&lt;br /&gt;
&lt;br /&gt;
First all of the code for the dock within Moodle 2.0 is located within the file &#039;&#039;&#039;moodle/blocks/dock.js&#039;&#039;&#039; and can be viewed online through the CVS repository[http://cvs.moodle.org/moodle/blocks/dock.js?view=markup]&lt;br /&gt;
&lt;br /&gt;
There are three main objects that get used for the dock:&lt;br /&gt;
# First up is of course the dock, which is namespaced to M.core_dock.dock. It is instantiated only once per page and is essentially a static object that manages and operates the dock plus everything on it.&lt;br /&gt;
# Second is a generic block class. Every block on the page gets instantiated as a generic block unless it has a more specific class (that should extend the generic block class). This generic block class is responsible for moving a block between the dock and its normal block position. It is namespaced to M.core_dock.generic_block.&lt;br /&gt;
# The third class is the dock item class which is used to represent an item on the dock. It is responsible for showing the item when required and handles the events that the dock + user trigger. I can hear you asking now why not just add this functionality to the generic block class? because this keeps it open for things other than blocks to be docked.&lt;br /&gt;
&lt;br /&gt;
As well as the above three classes there are some important class objects and properties that you should also be aware of as you may want to work with them when customising the dock.&lt;br /&gt;
; M.core_dock.Y : Is a YUI instance for use with the dock.&lt;br /&gt;
; M.core_dock.nodes.dock : Is the façade for the dock itself (#dock) and is a YUI3 Node instance.&lt;br /&gt;
; M.core_dock.getPanel() : This will return the panel that is used to display docked item within. It is stored locally through M.core_dock.nodes.panel however as it is not initialised until it is required you should always use the getPanel method.&lt;br /&gt;
&lt;br /&gt;
The following are other important notes about the dock that you should read and understand before customising the dock.&lt;br /&gt;
# The dock emulates the YUI3 &#039;&#039;&#039;on&#039;&#039;&#039; method for listening to events. Because the dock requires initialisation which may occur through module dependencies we needed a method of exposing the dock to events prior to initialisation and this is it. It ensures that if you attach events to the dock before it is initialised everything still works fine.&lt;br /&gt;
# Both the dock and the item class inherit from Y.EventTarget and publish several events.&lt;br /&gt;
# The dock is designed to work both on old and modern browsers and as such there are several places where we branch based on browser and version.&lt;br /&gt;
# The generic block class should never be added to for the needs of a single block. Only things that are generic to all blocks should be added to this class. Independent needs should be handled by creating a block specific class that extends the generic block class. The navigation and settings blocks do this currently.&lt;br /&gt;
&lt;br /&gt;
===Extending the dock through events===&lt;br /&gt;
Under construction&lt;br /&gt;
&lt;br /&gt;
===Using custom methods for the dock===&lt;br /&gt;
Under construction&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==More information==&lt;br /&gt;
&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]]&lt;br /&gt;
* [[Development:Themes 2.0 how to make the dock horizontal]] - Modifying the dock to make it horizontal.&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=Development:Styling_and_customising_the_dock&amp;diff=81970</id>
		<title>Development:Styling and customising the dock</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=Development:Styling_and_customising_the_dock&amp;diff=81970"/>
		<updated>2011-03-16T02:56:14Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: /* More information */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}{{Moodle 2.0}}The dock is a new addition to Moodle 2.0, it allows the user to move blocks from the flow of the page onto a special bar that is displayed in a constant position on the side of the page by default.&lt;br /&gt;
This document looks at how to style the dock using CSS, as well as how to customise or manipulate it within JavaScript.&lt;br /&gt;
&lt;br /&gt;
==Styling the dock==&lt;br /&gt;
Styling the dock is really no different to styling anything else within a web site however there are a couple of things that may slow you down and reading the following document may help you in your understanding of how the dock works and how you should go about styling it.&lt;br /&gt;
&lt;br /&gt;
The following items are things that you should be aware of before starting to style the dock:&lt;br /&gt;
# When a block is docked the dock attempts to ensure that existing styles for the block are still applied by adding the standard block &#039;&#039;&#039;.block_&#039;&#039;blockname&#039;&#039;&#039;&#039;&#039;. Because of this trick we don&#039;t need to look at the actual content of a docked item it will always be the same as the block.&lt;br /&gt;
# The dock remembers what blocks are docked by saving the user&#039;s choices within the database using AJAX calls. This can be looked at to minimise display jumping within a theme&#039;s layoutfile. Read on to learn how.&lt;br /&gt;
# The dock uses CSS classes to transition the different states. These CSS classes control things such as the whether the dock is visible, whether the panel is visible, and how we know which item is being viewed. Read the section on [[#State_classes|state classes]] to learn more about these.&lt;br /&gt;
# The structure of the dock is built entirely by JavaScript. Because of this you will need a tool such as FireBug to inspect it within a page as it won&#039;t be there until JavaScript has run.&lt;br /&gt;
# Although the base theme doesn&#039;t support the dock it does contain some core CSS to structure the dock by default.&lt;br /&gt;
&lt;br /&gt;
So lets get started and look at the structure.&lt;br /&gt;
===The structure of the dock===&lt;br /&gt;
[[Image:Dock.structure.201005.png|300px|thumb|Dock structure]]&lt;br /&gt;
The first image to the left graphically describes the hierarchical structure of the dock. The first thing you will notice about this image is that it doesn&#039;t describe what each element is for. It is just to illustrate the html structure without at styles or transformation.&lt;br /&gt;
&lt;br /&gt;
So what are the important elements here?&lt;br /&gt;
&lt;br /&gt;
; div#dock.dock.dock_left_vertical : This is the bar on the left. Positioned by default to be fixed position in the top left hand corner of the screen and 30px wide.&lt;br /&gt;
; div.dockeditem_container : This box contains all of the buttons which when clicked or hovered over will display the docked item. Or more technically causing the docked item panel to be shown.&lt;br /&gt;
; div#dock_item_x.dockeditem : This represents one of possibly several docked item buttons containing the title of the docked item. There are two things to note about this element: First it is repeated for every docked item. Second the x within the id is the item instance and should not be used for styling.&lt;br /&gt;
; div.controls : This contains any special controls for the dock and by default is displayed at the bottom of the dock. As of Moodle 2 Preview Release the only control here is to undock all docked items.&lt;br /&gt;
; div#dockeditempanel : This is the panel in which docked items are shown. Although it is within the dock is it positioned outside of the page relative to the button for the item it is currently showing. This element is based loosely off the YUI3 overlay.&lt;br /&gt;
&lt;br /&gt;
===The layout of the dock===&lt;br /&gt;
[[Image:Dock.layout.201005.png|300px|thumb|Dock layout]]&lt;br /&gt;
The second image on the left shows the layout of these elements within the standard theme.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;So what has gone on here?&#039;&#039;&#039;&lt;br /&gt;
First up ignore the bright colours and margins. I have put these colours in simply to highlight everything and ensure there is space between elements so I can show them apart.&lt;br /&gt;
&lt;br /&gt;
; div#dock : So immediately you notice that the dock is in the top left of the screen and the is fixed width. This is achieved by setting a strict with of 30px and setting the position of the &#039;&#039;#dock&#039;&#039; to fixed. The reason that everything is within the one &#039;&#039;#dock&#039;&#039; element is because it makes positioning everything very simple, now that we have set the position of &#039;&#039;#dock&#039;&#039; we don&#039;t need to worry about anything other than the panel which we&#039;ll get to shortly. You should also note that because of the strict width and position you need to be careful when applying styles to this element as it can have nasty effects on everything else.&lt;br /&gt;
&lt;br /&gt;
; div.dockeditem_container : Next you should notice that the &#039;&#039;.dockeditem_container&#039;&#039; doesn&#039;t extend to the bottom of the dock. Because there is not special positioning here it is behaving as div&#039;s normally do and this is the perfect place to really start styling your dock.&lt;br /&gt;
&lt;br /&gt;
; div.controls : After that within the structure we have &#039;&#039;div.controls&#039;&#039;. This element is positioned absolutely at the bottom of the dock, is 100% wide (so the full width of the dock) and uses &#039;&#039;text-align:center&#039;&#039; to ensure that the controls are centred.&lt;br /&gt;
&lt;br /&gt;
; div.dockeditem : Simply representing a button that can be hovered over or clicked to display the docked item the only important thing to note about this is that you should change the cursor to a pointer so that it is clear you can interact with it.&lt;br /&gt;
&lt;br /&gt;
; div#dockeditempanel : After &#039;&#039;#dock&#039;&#039; this is the most serious element in the dock. This element will contain the docked item and needs to positioned to the left of the dock and at the same height as the title of the item that is being displayed. Luckily you don&#039;t need to worry about the top position of the element that will be automatically adjusted by JavaScript however you will need to push the element to the left. This can be done easily by setting the position of the element to relative, and then setting left to 100%. Note you shouldn&#039;t style this element unless you know what you are doing, like the main dock element the smallest change can cause some terrible effects.&lt;br /&gt;
&lt;br /&gt;
; div.dockeditempanel_container : This element is there specifically to give you the themer an easy place to start styling the panel.&lt;br /&gt;
&lt;br /&gt;
; div.dockeditempanel_hd : This element contains the title of the docked item plus controls to undock or close it.&lt;br /&gt;
&lt;br /&gt;
; div.dockeditempanel_bd : Contains is the main content area for the panel.&lt;br /&gt;
&lt;br /&gt;
===State classes===&lt;br /&gt;
There are several state classes that the dock makes use of to achieve things such as the visibility of the dock, visibility of the panel, and which item is active.&lt;br /&gt;
The following table illustrates where these state classes are used.&lt;br /&gt;
{|  class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
! Element&lt;br /&gt;
! Class&lt;br /&gt;
! Description&lt;br /&gt;
! Default CSS&lt;br /&gt;
|-&lt;br /&gt;
|body&lt;br /&gt;
|has_dock&lt;br /&gt;
|This class is added to the body element when the dock is visible.&lt;br /&gt;
|Margin-left: 30px&lt;br /&gt;
|-&lt;br /&gt;
|#dock&lt;br /&gt;
|nothingdocked&lt;br /&gt;
|This class is added to the dock when there is nothing docked.&lt;br /&gt;
|visibility: hidden; display: none;&lt;br /&gt;
|-&lt;br /&gt;
|#dock&lt;br /&gt;
|.dock_&#039;&#039;position&#039;&#039;_&#039;&#039;style&#039;&#039;&lt;br /&gt;
|A special class is added to describe the docks desired position e.g. dock_left_vertical&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|.dockeditem&lt;br /&gt;
|activeitem&lt;br /&gt;
|This class is added to the item that is currently being shown.&lt;br /&gt;
|Change the background colour&lt;br /&gt;
|-&lt;br /&gt;
|.dockeditem&lt;br /&gt;
|firstdockitem&lt;br /&gt;
|This class is added to the first dock item.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|.dockeditem h2&lt;br /&gt;
|filterrotate&lt;br /&gt;
|Added when the title is being rotated by an IE filter [Internet Explorer only]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|#dockeditempanel&lt;br /&gt;
|dockitempanel_hidden&lt;br /&gt;
|Added to the panel when it is not being shown.&lt;br /&gt;
|visibility: hidden; display: none;&lt;br /&gt;
|-&lt;br /&gt;
|#dockeditempanel&lt;br /&gt;
|oversized_content&lt;br /&gt;
|Added when the panel required scrolling to show everything.&lt;br /&gt;
|Set the overflow method&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Layout file changes===&lt;br /&gt;
There is only one thing that you need to make sure of within your layout files if you are creating your own. You need to add the class &#039;&#039;block-region&#039;&#039; to all of the block region div&#039;s as shown below.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;region-post&amp;quot; class=&amp;quot;block-region&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;/code&amp;gt;&lt;br /&gt;
Whilst there is nothing else you &#039;&#039;&#039;need&#039;&#039;&#039; to change within your layout files there one other thing that you may want to do.&lt;br /&gt;
&lt;br /&gt;
Because the dock is loaded entirely by JavaScript you will notice a visual jump on the page if all of the blocks within a region have been docked. This is because the dock shrinks sections that have been completely docked so that they don&#039;t wast page space.&lt;br /&gt;
&lt;br /&gt;
Within you layout files you can check whether a section has been completely docked and then if it has set the body classes so that it is shrunk when the page is delivered.&lt;br /&gt;
&lt;br /&gt;
I&#039;m going to assume that you have all read the [[Development:Themes 2.0 creating your first theme]]. If you haven&#039;t go read it now.&lt;br /&gt;
So now that you&#039;ve created your first theme think back to the code you wrote at the top of your layout files that checks whether a page has block regions pre and post. The code was as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&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;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Right below these two lines we are going to add two more:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$showsidepre = ($hassidepre &amp;amp;&amp;amp; !$PAGE-&amp;gt;blocks-&amp;gt;region_completely_docked(&#039;side-pre&#039;, $OUTPUT));&lt;br /&gt;
$showsidepost = ($hassidepost &amp;amp;&amp;amp; !$PAGE-&amp;gt;blocks-&amp;gt;region_completely_docked(&#039;side-post&#039;, $OUTPUT));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
What we have here is two variables that tell use whether we should show the block regions pre and post. The verbal interpretation of this string is to say &#039;&#039;We will show this side if this side has content and if there is at least one block that has not been docked.&#039;&#039; and we repeat it for each side.&lt;br /&gt;
&lt;br /&gt;
Now that we know for each region that it has content and that we should show it we need some way to tell the page what block regions to show.&lt;br /&gt;
This is achieved by adding special classes to the body element of the page as follows:&lt;br /&gt;
; side-pre-only : This gets added to the body if we only want to show the block region pre.&lt;br /&gt;
; side-post-only : Just like side-pre-only except for the post region.&lt;br /&gt;
; content-only : This gets added if don&#039;t want to show either block region.&lt;br /&gt;
By default we want to show both regions so we don&#039;t need to add any class for this.&lt;br /&gt;
So how to do this in PHP?&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$bodyclasses = array();&lt;br /&gt;
if ($showsidepre &amp;amp;&amp;amp; !$showsidepost) {&lt;br /&gt;
    $bodyclasses[] = &#039;side-pre-only&#039;;&lt;br /&gt;
} else if ($showsidepost &amp;amp;&amp;amp; !$showsidepre) {&lt;br /&gt;
    $bodyclasses[] = &#039;side-post-only&#039;;&lt;br /&gt;
} else if (!$showsidepost &amp;amp;&amp;amp; !$showsidepre) {&lt;br /&gt;
    $bodyclasses[] = &#039;content-only&#039;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
What we have here is three if-else statements, of which either one or none will be true.&lt;br /&gt;
# The first if statement says if we want to show the pre region but not the post region add the class &#039;&#039;side-pre-only&#039;&#039;&lt;br /&gt;
# The second if statement says if we want to show the post region but not the pre region add the class &#039;&#039;side-post-only&#039;&#039;&lt;br /&gt;
# The third class says if we don&#039;t want to display either region add the class &#039;&#039;content-only&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Now that we know which class we want to add to the body element we need to do so. This can be done as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyid ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyclasses.&#039; &#039;.join(&#039; &#039;, $bodyclasses) ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
You&#039;ll notice this is very similar to the body tag you wrote in your first theme, however we have added&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
join(&#039; &#039;, $bodyclasses)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This php command simply concatenates each body class putting a space between each.&lt;br /&gt;
&lt;br /&gt;
Now the final thing to do is make sure that we don&#039;t show a block region if we don&#039;t have content for it. This can be done by adding if statements around each block region as follows:&lt;br /&gt;
&amp;lt;code php&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; class=&amp;quot;block-region&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; class=&amp;quot;block-region&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;/code&amp;gt;&lt;br /&gt;
For each if statement we are saying &#039;&#039;If this region has content display it.&#039;&#039; You&#039;ll notice that here we are using &#039;&#039;$hasside...&#039;&#039; instead of &#039;&#039;$showside...&#039;&#039; this is because we want to add them if they have content even if they won&#039;t be shown. Otherwise the dock won&#039;t be able to find them and you simply won&#039;t see the block.&lt;br /&gt;
&lt;br /&gt;
Having made the above changes if you now look at the layout files for the base theme you start to notice that they are looking very similar and indeed they are. If at any point you get stuck or don&#039;t know how to proceed have a look at the base themes layout files and see how its done there.&lt;br /&gt;
&lt;br /&gt;
===The core CSS===&lt;br /&gt;
As mentioned in the key points at the start of this document the base theme although not supporting the dock does contain structural CSS that ensure the dock is functional on all themes that choose to support it.&lt;br /&gt;
Lets look at the CSS within &#039;&#039;theme/base/style/dock.css&#039;&#039;, this is the core structural CSS for the dock.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/* Put a margin on the body if the dock is shown */&lt;br /&gt;
body.has_dock {margin-left:30px;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Well this is very simple, if the dock is being shown apply a 30px margin to the body. This is done to ensure that the dock doesn&#039;t overlap the body.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/** For the dock itself */&lt;br /&gt;
#dock {width:30px;position:fixed;top:0px;left:0px;height:100%;background-color:#FFF;border-right:1px solid #000;z-index:11000;}&lt;br /&gt;
#dock.nothingdocked {visibility: hidden;display:none;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
These two rules style the dock itself. Note the second rule is only applied when nothing is docked in which case we will hide the empty dock.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
#dock .dockeditem .firstdockitem {margin-top:1em;}&lt;br /&gt;
#dock .dockeditem .dockedtitle {border-bottom:1px solid #000;border-top:1px solid #000;cursor:pointer;}&lt;br /&gt;
#dock .dockeditem .dockedtitle h2 {font-size:0.8em;line-height:100%;text-align:center;}&lt;br /&gt;
#dock .dockeditem .dockedtitle .filterrotate {margin-left:8px;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The four rules above style the buttons that will show the docked items. Each docked item has one. The styles being used here arn&#039;t doing anything to special other than setting the cursor to pointer so that it is recognised as an actionable element.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
#dock .controls {position:absolute;bottom:1em;text-align:center;width:100%;}&lt;br /&gt;
#dock .controls img {cursor:pointer;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Very simply this bit of CSS. It is positioning the controls for the dock at the bottom centre of the dock.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/** For the panel the docked blocks are shown in */&lt;br /&gt;
#dockeditempanel {min-width:200px;position:relative;z-index:12000;left:100%;}&lt;br /&gt;
#dockeditempanel.dockitempanel_hidden {display:none;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
These two lines are applied to the docked item panel&#039;s base element and are VERY important to the operation of the dock. They ensure that when shown the panel is top the left of the dock and that when it is not being displayed it is not visible.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
#dockeditempanel .dockeditempanel_content {background-color:#fff;border:1px solid #000;z-index:12050;}&lt;br /&gt;
#dockeditempanel .dockeditempanel_bd {overflow:auto;width:auto;}&lt;br /&gt;
#dockeditempanel .dockeditempanel_bd .block_docked {margin:10px;}&lt;br /&gt;
#dockeditempanel .dockeditempanel_hd {border-bottom:1px solid #000;text-align:right;}&lt;br /&gt;
#dockeditempanel .dockeditempanel_hd h2 {display:inline;margin:0;padding-right:1em;}&lt;br /&gt;
#dockeditempanel .dockeditempanel_hd .commands {display:inline;}&lt;br /&gt;
#dockeditempanel .dockeditempanel_hd .commands img {margin-right:2px;vertical-align:middle;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The above lines of CSS are used to style the internal content of the panel. Note the styles for the block will be applied as if it were not docked.&lt;br /&gt;
&lt;br /&gt;
And that is it!&lt;br /&gt;
&lt;br /&gt;
Whilst things don&#039;t look to difficult when styling things if you don&#039;t think carefully about where you are applying styles you can quickly dig yourself a big hole. I would suggest going slowly at first when applying more styles and making sure you don&#039;t apply too many styles to the base elements #dock and #dockeditempanel.&lt;br /&gt;
&lt;br /&gt;
==Customising the dock==&lt;br /&gt;
This section of the document looks at how to customise the dock using JavaScript.&lt;br /&gt;
&lt;br /&gt;
It was recognised early on during the development of the dock that it probably won&#039;t suit everyone&#039;s needs, nor would it appeal to everyone. Because of this during development and the frequent revisions that were occurring during Moodle 2.0s development there was always a focus on ensuring the dock was customisable and that someone with a bit of time on their hands and a good knowledge of JavaScript could hack it to bits and make it into the tool they desired.&lt;br /&gt;
&lt;br /&gt;
This document doesn&#039;t go into the full details of how to customise the dock but should get anyone keen started quickly. Those who fear JavaScript should leave now!&lt;br /&gt;
&lt;br /&gt;
===Getting started===&lt;br /&gt;
The dock is written to make use of YUI3 and all the functionality that it has to offer, the main dock object both looks for specific callback functions and adds manages and fires several important events. At the same time it is also object orientated JavaScript which has the advantage in JavaScript of allowing subsequent JavaScript events to redefine methods of the object.&lt;br /&gt;
&lt;br /&gt;
This allows you the theme designer to write JavaScript to customise the dock in two fashions. The first through events and callbacks. The second through manually overriding the methods the dock uses.&lt;br /&gt;
&lt;br /&gt;
We will look into these two methods in the subsequent sections of this document, for the time being what you need to learn about is the JavaScript structure of the dock.&lt;br /&gt;
&lt;br /&gt;
First all of the code for the dock within Moodle 2.0 is located within the file &#039;&#039;&#039;moodle/blocks/dock.js&#039;&#039;&#039; and can be viewed online through the CVS repository[http://cvs.moodle.org/moodle/blocks/dock.js?view=markup]&lt;br /&gt;
&lt;br /&gt;
There are three main objects that get used for the dock:&lt;br /&gt;
# First up is of course the dock, which is namespaced to M.core_dock.dock. It is instantiated only once per page and is essentially a static object that manages and operates the dock plus everything on it.&lt;br /&gt;
# Second is a generic block class. Every block on the page gets instantiated as a generic block unless it has a more specific class (that should extend the generic block class). This generic block class is responsible for moving a block between the dock and its normal block position. It is namespaced to M.core_dock.generic_block.&lt;br /&gt;
# The third class is the dock item class which is used to represent an item on the dock. It is responsible for showing the item when required and handles the events that the dock + user trigger. I can hear you asking now why not just add this functionality to the generic block class? because this keeps it open for things other than blocks to be docked.&lt;br /&gt;
&lt;br /&gt;
As well as the above three classes there are some important class objects and properties that you should also be aware of as you may want to work with them when customising the dock.&lt;br /&gt;
; M.core_dock.Y : Is a YUI instance for use with the dock.&lt;br /&gt;
; M.core_dock.nodes.dock : Is the façade for the dock itself (#dock) and is a YUI3 Node instance.&lt;br /&gt;
; M.core_dock.getPanel() : This will return the panel that is used to display docked item within. It is stored locally through M.core_dock.nodes.panel however as it is not initialised until it is required you should always use the getPanel method.&lt;br /&gt;
&lt;br /&gt;
The following are other important notes about the dock that you should read and understand before customising the dock.&lt;br /&gt;
# The dock emulates the YUI3 &#039;&#039;&#039;on&#039;&#039;&#039; method for listening to events. Because the dock requires initialisation which may occur through module dependencies we needed a method of exposing the dock to events prior to initialisation and this is it. It ensures that if you attach events to the dock before it is initialised everything still works fine.&lt;br /&gt;
# Both the dock and the item class inherit from Y.EventTarget and publish several events.&lt;br /&gt;
# The dock is designed to work both on old and modern browsers and as such there are several places where we branch based on browser and version.&lt;br /&gt;
# The generic block class should never be added to for the needs of a single block. Only things that are generic to all blocks should be added to this class. Independent needs should be handled by creating a block specific class that extends the generic block class. The navigation and settings blocks do this currently.&lt;br /&gt;
&lt;br /&gt;
===Extending the dock through events===&lt;br /&gt;
Under construction&lt;br /&gt;
&lt;br /&gt;
===Using custom methods for the dock===&lt;br /&gt;
Under construction&lt;br /&gt;
&lt;br /&gt;
===Tutorial: Creating a moveable dock===&lt;br /&gt;
Under construction&lt;br /&gt;
&lt;br /&gt;
==More information==&lt;br /&gt;
&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]]&lt;br /&gt;
* [[Development:Themes 2.0 how to make the dock horizontal]] - Modifying the dock to make it horizontal.&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=Development:Styling_and_customising_the_dock&amp;diff=81969</id>
		<title>Development:Styling and customising the dock</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=Development:Styling_and_customising_the_dock&amp;diff=81969"/>
		<updated>2011-03-16T02:55:23Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: Added link to horizontal dock tutorial&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}{{Moodle 2.0}}The dock is a new addition to Moodle 2.0, it allows the user to move blocks from the flow of the page onto a special bar that is displayed in a constant position on the side of the page by default.&lt;br /&gt;
This document looks at how to style the dock using CSS, as well as how to customise or manipulate it within JavaScript.&lt;br /&gt;
&lt;br /&gt;
==Styling the dock==&lt;br /&gt;
Styling the dock is really no different to styling anything else within a web site however there are a couple of things that may slow you down and reading the following document may help you in your understanding of how the dock works and how you should go about styling it.&lt;br /&gt;
&lt;br /&gt;
The following items are things that you should be aware of before starting to style the dock:&lt;br /&gt;
# When a block is docked the dock attempts to ensure that existing styles for the block are still applied by adding the standard block &#039;&#039;&#039;.block_&#039;&#039;blockname&#039;&#039;&#039;&#039;&#039;. Because of this trick we don&#039;t need to look at the actual content of a docked item it will always be the same as the block.&lt;br /&gt;
# The dock remembers what blocks are docked by saving the user&#039;s choices within the database using AJAX calls. This can be looked at to minimise display jumping within a theme&#039;s layoutfile. Read on to learn how.&lt;br /&gt;
# The dock uses CSS classes to transition the different states. These CSS classes control things such as the whether the dock is visible, whether the panel is visible, and how we know which item is being viewed. Read the section on [[#State_classes|state classes]] to learn more about these.&lt;br /&gt;
# The structure of the dock is built entirely by JavaScript. Because of this you will need a tool such as FireBug to inspect it within a page as it won&#039;t be there until JavaScript has run.&lt;br /&gt;
# Although the base theme doesn&#039;t support the dock it does contain some core CSS to structure the dock by default.&lt;br /&gt;
&lt;br /&gt;
So lets get started and look at the structure.&lt;br /&gt;
===The structure of the dock===&lt;br /&gt;
[[Image:Dock.structure.201005.png|300px|thumb|Dock structure]]&lt;br /&gt;
The first image to the left graphically describes the hierarchical structure of the dock. The first thing you will notice about this image is that it doesn&#039;t describe what each element is for. It is just to illustrate the html structure without at styles or transformation.&lt;br /&gt;
&lt;br /&gt;
So what are the important elements here?&lt;br /&gt;
&lt;br /&gt;
; div#dock.dock.dock_left_vertical : This is the bar on the left. Positioned by default to be fixed position in the top left hand corner of the screen and 30px wide.&lt;br /&gt;
; div.dockeditem_container : This box contains all of the buttons which when clicked or hovered over will display the docked item. Or more technically causing the docked item panel to be shown.&lt;br /&gt;
; div#dock_item_x.dockeditem : This represents one of possibly several docked item buttons containing the title of the docked item. There are two things to note about this element: First it is repeated for every docked item. Second the x within the id is the item instance and should not be used for styling.&lt;br /&gt;
; div.controls : This contains any special controls for the dock and by default is displayed at the bottom of the dock. As of Moodle 2 Preview Release the only control here is to undock all docked items.&lt;br /&gt;
; div#dockeditempanel : This is the panel in which docked items are shown. Although it is within the dock is it positioned outside of the page relative to the button for the item it is currently showing. This element is based loosely off the YUI3 overlay.&lt;br /&gt;
&lt;br /&gt;
===The layout of the dock===&lt;br /&gt;
[[Image:Dock.layout.201005.png|300px|thumb|Dock layout]]&lt;br /&gt;
The second image on the left shows the layout of these elements within the standard theme.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;So what has gone on here?&#039;&#039;&#039;&lt;br /&gt;
First up ignore the bright colours and margins. I have put these colours in simply to highlight everything and ensure there is space between elements so I can show them apart.&lt;br /&gt;
&lt;br /&gt;
; div#dock : So immediately you notice that the dock is in the top left of the screen and the is fixed width. This is achieved by setting a strict with of 30px and setting the position of the &#039;&#039;#dock&#039;&#039; to fixed. The reason that everything is within the one &#039;&#039;#dock&#039;&#039; element is because it makes positioning everything very simple, now that we have set the position of &#039;&#039;#dock&#039;&#039; we don&#039;t need to worry about anything other than the panel which we&#039;ll get to shortly. You should also note that because of the strict width and position you need to be careful when applying styles to this element as it can have nasty effects on everything else.&lt;br /&gt;
&lt;br /&gt;
; div.dockeditem_container : Next you should notice that the &#039;&#039;.dockeditem_container&#039;&#039; doesn&#039;t extend to the bottom of the dock. Because there is not special positioning here it is behaving as div&#039;s normally do and this is the perfect place to really start styling your dock.&lt;br /&gt;
&lt;br /&gt;
; div.controls : After that within the structure we have &#039;&#039;div.controls&#039;&#039;. This element is positioned absolutely at the bottom of the dock, is 100% wide (so the full width of the dock) and uses &#039;&#039;text-align:center&#039;&#039; to ensure that the controls are centred.&lt;br /&gt;
&lt;br /&gt;
; div.dockeditem : Simply representing a button that can be hovered over or clicked to display the docked item the only important thing to note about this is that you should change the cursor to a pointer so that it is clear you can interact with it.&lt;br /&gt;
&lt;br /&gt;
; div#dockeditempanel : After &#039;&#039;#dock&#039;&#039; this is the most serious element in the dock. This element will contain the docked item and needs to positioned to the left of the dock and at the same height as the title of the item that is being displayed. Luckily you don&#039;t need to worry about the top position of the element that will be automatically adjusted by JavaScript however you will need to push the element to the left. This can be done easily by setting the position of the element to relative, and then setting left to 100%. Note you shouldn&#039;t style this element unless you know what you are doing, like the main dock element the smallest change can cause some terrible effects.&lt;br /&gt;
&lt;br /&gt;
; div.dockeditempanel_container : This element is there specifically to give you the themer an easy place to start styling the panel.&lt;br /&gt;
&lt;br /&gt;
; div.dockeditempanel_hd : This element contains the title of the docked item plus controls to undock or close it.&lt;br /&gt;
&lt;br /&gt;
; div.dockeditempanel_bd : Contains is the main content area for the panel.&lt;br /&gt;
&lt;br /&gt;
===State classes===&lt;br /&gt;
There are several state classes that the dock makes use of to achieve things such as the visibility of the dock, visibility of the panel, and which item is active.&lt;br /&gt;
The following table illustrates where these state classes are used.&lt;br /&gt;
{|  class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
! Element&lt;br /&gt;
! Class&lt;br /&gt;
! Description&lt;br /&gt;
! Default CSS&lt;br /&gt;
|-&lt;br /&gt;
|body&lt;br /&gt;
|has_dock&lt;br /&gt;
|This class is added to the body element when the dock is visible.&lt;br /&gt;
|Margin-left: 30px&lt;br /&gt;
|-&lt;br /&gt;
|#dock&lt;br /&gt;
|nothingdocked&lt;br /&gt;
|This class is added to the dock when there is nothing docked.&lt;br /&gt;
|visibility: hidden; display: none;&lt;br /&gt;
|-&lt;br /&gt;
|#dock&lt;br /&gt;
|.dock_&#039;&#039;position&#039;&#039;_&#039;&#039;style&#039;&#039;&lt;br /&gt;
|A special class is added to describe the docks desired position e.g. dock_left_vertical&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|.dockeditem&lt;br /&gt;
|activeitem&lt;br /&gt;
|This class is added to the item that is currently being shown.&lt;br /&gt;
|Change the background colour&lt;br /&gt;
|-&lt;br /&gt;
|.dockeditem&lt;br /&gt;
|firstdockitem&lt;br /&gt;
|This class is added to the first dock item.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|.dockeditem h2&lt;br /&gt;
|filterrotate&lt;br /&gt;
|Added when the title is being rotated by an IE filter [Internet Explorer only]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|#dockeditempanel&lt;br /&gt;
|dockitempanel_hidden&lt;br /&gt;
|Added to the panel when it is not being shown.&lt;br /&gt;
|visibility: hidden; display: none;&lt;br /&gt;
|-&lt;br /&gt;
|#dockeditempanel&lt;br /&gt;
|oversized_content&lt;br /&gt;
|Added when the panel required scrolling to show everything.&lt;br /&gt;
|Set the overflow method&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Layout file changes===&lt;br /&gt;
There is only one thing that you need to make sure of within your layout files if you are creating your own. You need to add the class &#039;&#039;block-region&#039;&#039; to all of the block region div&#039;s as shown below.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;region-post&amp;quot; class=&amp;quot;block-region&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;/code&amp;gt;&lt;br /&gt;
Whilst there is nothing else you &#039;&#039;&#039;need&#039;&#039;&#039; to change within your layout files there one other thing that you may want to do.&lt;br /&gt;
&lt;br /&gt;
Because the dock is loaded entirely by JavaScript you will notice a visual jump on the page if all of the blocks within a region have been docked. This is because the dock shrinks sections that have been completely docked so that they don&#039;t wast page space.&lt;br /&gt;
&lt;br /&gt;
Within you layout files you can check whether a section has been completely docked and then if it has set the body classes so that it is shrunk when the page is delivered.&lt;br /&gt;
&lt;br /&gt;
I&#039;m going to assume that you have all read the [[Development:Themes 2.0 creating your first theme]]. If you haven&#039;t go read it now.&lt;br /&gt;
So now that you&#039;ve created your first theme think back to the code you wrote at the top of your layout files that checks whether a page has block regions pre and post. The code was as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&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;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Right below these two lines we are going to add two more:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$showsidepre = ($hassidepre &amp;amp;&amp;amp; !$PAGE-&amp;gt;blocks-&amp;gt;region_completely_docked(&#039;side-pre&#039;, $OUTPUT));&lt;br /&gt;
$showsidepost = ($hassidepost &amp;amp;&amp;amp; !$PAGE-&amp;gt;blocks-&amp;gt;region_completely_docked(&#039;side-post&#039;, $OUTPUT));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
What we have here is two variables that tell use whether we should show the block regions pre and post. The verbal interpretation of this string is to say &#039;&#039;We will show this side if this side has content and if there is at least one block that has not been docked.&#039;&#039; and we repeat it for each side.&lt;br /&gt;
&lt;br /&gt;
Now that we know for each region that it has content and that we should show it we need some way to tell the page what block regions to show.&lt;br /&gt;
This is achieved by adding special classes to the body element of the page as follows:&lt;br /&gt;
; side-pre-only : This gets added to the body if we only want to show the block region pre.&lt;br /&gt;
; side-post-only : Just like side-pre-only except for the post region.&lt;br /&gt;
; content-only : This gets added if don&#039;t want to show either block region.&lt;br /&gt;
By default we want to show both regions so we don&#039;t need to add any class for this.&lt;br /&gt;
So how to do this in PHP?&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$bodyclasses = array();&lt;br /&gt;
if ($showsidepre &amp;amp;&amp;amp; !$showsidepost) {&lt;br /&gt;
    $bodyclasses[] = &#039;side-pre-only&#039;;&lt;br /&gt;
} else if ($showsidepost &amp;amp;&amp;amp; !$showsidepre) {&lt;br /&gt;
    $bodyclasses[] = &#039;side-post-only&#039;;&lt;br /&gt;
} else if (!$showsidepost &amp;amp;&amp;amp; !$showsidepre) {&lt;br /&gt;
    $bodyclasses[] = &#039;content-only&#039;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
What we have here is three if-else statements, of which either one or none will be true.&lt;br /&gt;
# The first if statement says if we want to show the pre region but not the post region add the class &#039;&#039;side-pre-only&#039;&#039;&lt;br /&gt;
# The second if statement says if we want to show the post region but not the pre region add the class &#039;&#039;side-post-only&#039;&#039;&lt;br /&gt;
# The third class says if we don&#039;t want to display either region add the class &#039;&#039;content-only&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Now that we know which class we want to add to the body element we need to do so. This can be done as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;body id=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyid ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyclasses.&#039; &#039;.join(&#039; &#039;, $bodyclasses) ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
You&#039;ll notice this is very similar to the body tag you wrote in your first theme, however we have added&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
join(&#039; &#039;, $bodyclasses)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This php command simply concatenates each body class putting a space between each.&lt;br /&gt;
&lt;br /&gt;
Now the final thing to do is make sure that we don&#039;t show a block region if we don&#039;t have content for it. This can be done by adding if statements around each block region as follows:&lt;br /&gt;
&amp;lt;code php&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; class=&amp;quot;block-region&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; class=&amp;quot;block-region&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;/code&amp;gt;&lt;br /&gt;
For each if statement we are saying &#039;&#039;If this region has content display it.&#039;&#039; You&#039;ll notice that here we are using &#039;&#039;$hasside...&#039;&#039; instead of &#039;&#039;$showside...&#039;&#039; this is because we want to add them if they have content even if they won&#039;t be shown. Otherwise the dock won&#039;t be able to find them and you simply won&#039;t see the block.&lt;br /&gt;
&lt;br /&gt;
Having made the above changes if you now look at the layout files for the base theme you start to notice that they are looking very similar and indeed they are. If at any point you get stuck or don&#039;t know how to proceed have a look at the base themes layout files and see how its done there.&lt;br /&gt;
&lt;br /&gt;
===The core CSS===&lt;br /&gt;
As mentioned in the key points at the start of this document the base theme although not supporting the dock does contain structural CSS that ensure the dock is functional on all themes that choose to support it.&lt;br /&gt;
Lets look at the CSS within &#039;&#039;theme/base/style/dock.css&#039;&#039;, this is the core structural CSS for the dock.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/* Put a margin on the body if the dock is shown */&lt;br /&gt;
body.has_dock {margin-left:30px;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Well this is very simple, if the dock is being shown apply a 30px margin to the body. This is done to ensure that the dock doesn&#039;t overlap the body.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/** For the dock itself */&lt;br /&gt;
#dock {width:30px;position:fixed;top:0px;left:0px;height:100%;background-color:#FFF;border-right:1px solid #000;z-index:11000;}&lt;br /&gt;
#dock.nothingdocked {visibility: hidden;display:none;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
These two rules style the dock itself. Note the second rule is only applied when nothing is docked in which case we will hide the empty dock.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
#dock .dockeditem .firstdockitem {margin-top:1em;}&lt;br /&gt;
#dock .dockeditem .dockedtitle {border-bottom:1px solid #000;border-top:1px solid #000;cursor:pointer;}&lt;br /&gt;
#dock .dockeditem .dockedtitle h2 {font-size:0.8em;line-height:100%;text-align:center;}&lt;br /&gt;
#dock .dockeditem .dockedtitle .filterrotate {margin-left:8px;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The four rules above style the buttons that will show the docked items. Each docked item has one. The styles being used here arn&#039;t doing anything to special other than setting the cursor to pointer so that it is recognised as an actionable element.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
#dock .controls {position:absolute;bottom:1em;text-align:center;width:100%;}&lt;br /&gt;
#dock .controls img {cursor:pointer;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Very simply this bit of CSS. It is positioning the controls for the dock at the bottom centre of the dock.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/** For the panel the docked blocks are shown in */&lt;br /&gt;
#dockeditempanel {min-width:200px;position:relative;z-index:12000;left:100%;}&lt;br /&gt;
#dockeditempanel.dockitempanel_hidden {display:none;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
These two lines are applied to the docked item panel&#039;s base element and are VERY important to the operation of the dock. They ensure that when shown the panel is top the left of the dock and that when it is not being displayed it is not visible.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
#dockeditempanel .dockeditempanel_content {background-color:#fff;border:1px solid #000;z-index:12050;}&lt;br /&gt;
#dockeditempanel .dockeditempanel_bd {overflow:auto;width:auto;}&lt;br /&gt;
#dockeditempanel .dockeditempanel_bd .block_docked {margin:10px;}&lt;br /&gt;
#dockeditempanel .dockeditempanel_hd {border-bottom:1px solid #000;text-align:right;}&lt;br /&gt;
#dockeditempanel .dockeditempanel_hd h2 {display:inline;margin:0;padding-right:1em;}&lt;br /&gt;
#dockeditempanel .dockeditempanel_hd .commands {display:inline;}&lt;br /&gt;
#dockeditempanel .dockeditempanel_hd .commands img {margin-right:2px;vertical-align:middle;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The above lines of CSS are used to style the internal content of the panel. Note the styles for the block will be applied as if it were not docked.&lt;br /&gt;
&lt;br /&gt;
And that is it!&lt;br /&gt;
&lt;br /&gt;
Whilst things don&#039;t look to difficult when styling things if you don&#039;t think carefully about where you are applying styles you can quickly dig yourself a big hole. I would suggest going slowly at first when applying more styles and making sure you don&#039;t apply too many styles to the base elements #dock and #dockeditempanel.&lt;br /&gt;
&lt;br /&gt;
==Customising the dock==&lt;br /&gt;
This section of the document looks at how to customise the dock using JavaScript.&lt;br /&gt;
&lt;br /&gt;
It was recognised early on during the development of the dock that it probably won&#039;t suit everyone&#039;s needs, nor would it appeal to everyone. Because of this during development and the frequent revisions that were occurring during Moodle 2.0s development there was always a focus on ensuring the dock was customisable and that someone with a bit of time on their hands and a good knowledge of JavaScript could hack it to bits and make it into the tool they desired.&lt;br /&gt;
&lt;br /&gt;
This document doesn&#039;t go into the full details of how to customise the dock but should get anyone keen started quickly. Those who fear JavaScript should leave now!&lt;br /&gt;
&lt;br /&gt;
===Getting started===&lt;br /&gt;
The dock is written to make use of YUI3 and all the functionality that it has to offer, the main dock object both looks for specific callback functions and adds manages and fires several important events. At the same time it is also object orientated JavaScript which has the advantage in JavaScript of allowing subsequent JavaScript events to redefine methods of the object.&lt;br /&gt;
&lt;br /&gt;
This allows you the theme designer to write JavaScript to customise the dock in two fashions. The first through events and callbacks. The second through manually overriding the methods the dock uses.&lt;br /&gt;
&lt;br /&gt;
We will look into these two methods in the subsequent sections of this document, for the time being what you need to learn about is the JavaScript structure of the dock.&lt;br /&gt;
&lt;br /&gt;
First all of the code for the dock within Moodle 2.0 is located within the file &#039;&#039;&#039;moodle/blocks/dock.js&#039;&#039;&#039; and can be viewed online through the CVS repository[http://cvs.moodle.org/moodle/blocks/dock.js?view=markup]&lt;br /&gt;
&lt;br /&gt;
There are three main objects that get used for the dock:&lt;br /&gt;
# First up is of course the dock, which is namespaced to M.core_dock.dock. It is instantiated only once per page and is essentially a static object that manages and operates the dock plus everything on it.&lt;br /&gt;
# Second is a generic block class. Every block on the page gets instantiated as a generic block unless it has a more specific class (that should extend the generic block class). This generic block class is responsible for moving a block between the dock and its normal block position. It is namespaced to M.core_dock.generic_block.&lt;br /&gt;
# The third class is the dock item class which is used to represent an item on the dock. It is responsible for showing the item when required and handles the events that the dock + user trigger. I can hear you asking now why not just add this functionality to the generic block class? because this keeps it open for things other than blocks to be docked.&lt;br /&gt;
&lt;br /&gt;
As well as the above three classes there are some important class objects and properties that you should also be aware of as you may want to work with them when customising the dock.&lt;br /&gt;
; M.core_dock.Y : Is a YUI instance for use with the dock.&lt;br /&gt;
; M.core_dock.nodes.dock : Is the façade for the dock itself (#dock) and is a YUI3 Node instance.&lt;br /&gt;
; M.core_dock.getPanel() : This will return the panel that is used to display docked item within. It is stored locally through M.core_dock.nodes.panel however as it is not initialised until it is required you should always use the getPanel method.&lt;br /&gt;
&lt;br /&gt;
The following are other important notes about the dock that you should read and understand before customising the dock.&lt;br /&gt;
# The dock emulates the YUI3 &#039;&#039;&#039;on&#039;&#039;&#039; method for listening to events. Because the dock requires initialisation which may occur through module dependencies we needed a method of exposing the dock to events prior to initialisation and this is it. It ensures that if you attach events to the dock before it is initialised everything still works fine.&lt;br /&gt;
# Both the dock and the item class inherit from Y.EventTarget and publish several events.&lt;br /&gt;
# The dock is designed to work both on old and modern browsers and as such there are several places where we branch based on browser and version.&lt;br /&gt;
# The generic block class should never be added to for the needs of a single block. Only things that are generic to all blocks should be added to this class. Independent needs should be handled by creating a block specific class that extends the generic block class. The navigation and settings blocks do this currently.&lt;br /&gt;
&lt;br /&gt;
===Extending the dock through events===&lt;br /&gt;
Under construction&lt;br /&gt;
&lt;br /&gt;
===Using custom methods for the dock===&lt;br /&gt;
Under construction&lt;br /&gt;
&lt;br /&gt;
===Tutorial: Creating a moveable dock===&lt;br /&gt;
Under construction&lt;br /&gt;
&lt;br /&gt;
==More information==&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]]&lt;br /&gt;
* [[Development:Styling and customising the dock]] - How to style and customise the dock.&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0&amp;diff=81968</id>
		<title>Development:Themes 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0&amp;diff=81968"/>
		<updated>2011-03-16T02:54:37Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: Added link to horizontal dock tutorial&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 echo $PAGE-&amp;gt;bodyid ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyclasses; ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_top_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;table id=&amp;quot;page&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
        &amp;lt;td colspan=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;h1 class=&amp;quot;headermain&amp;quot;&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;heading ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;headermenu&amp;quot;&amp;gt;&amp;lt;?php echo $OUTPUT-&amp;gt;login_info(); echo $PAGE-&amp;gt;headingmenu; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-pre&#039;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-post&#039;) ?&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
        &amp;lt;td colspan=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;p class=&amp;quot;helplink&amp;quot;&amp;gt;&amp;lt;?php echo page_doc_link(get_string(&#039;moodledocslink&#039;)) ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
            &amp;lt;?php&lt;br /&gt;
            echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
            echo $OUTPUT-&amp;gt;home_link();&lt;br /&gt;
            echo $OUTPUT-&amp;gt;standard_footer_html();&lt;br /&gt;
            ?&amp;gt;&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;standard_end_of_body_html() ?&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lets assume you know a enough HTML to understand the basic structure above, what you probably don&#039;t understand are the PHP calls so lets look at them.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;doctype() ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This occurs at the VERY top of the page, it must be the first bit of output and is responsible for adding the (X)HTML document type definition to the page. This of course is determined by the settings of the site and is one of the things that the 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 echo $PAGE-&amp;gt;bodyid; ?&amp;gt;&amp;quot; class=&amp;quot;&amp;lt;?php echo $PAGE-&amp;gt;bodyclasses; ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Much like the html tag above we have started writing the body tag and have asked for Moodle to get us the desired ID and classes that should be applied to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;h1 class=&amp;quot;headermain&amp;quot;&amp;gt;&amp;lt;?php echo $PAGE-&amp;gt;heading; ?&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;headermenu&amp;quot;&amp;gt;&amp;lt;?php echo $OUTPUT-&amp;gt;login_info(); echo $PAGE-&amp;gt;headingmenu; ?&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are creating the header for the page. In this case we want the heading for the page, we want to display the login information which will be the current users username or a link to log in if they are not logged in, and we want the heading menu if there is one.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-pre&#039;) ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we get the HTML to display the blocks that have been added to the page. In this case we have asked for all blocks that have been added to the area labelled &#039;&#039;side-pre&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo core_renderer::MAIN_CONTENT_TOKEN ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is one of the most important calls within the file, it determines where the actual content for the page gets inserted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $OUTPUT-&amp;gt;blocks_for_region(&#039;side-post&#039;) ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we get the HTML to display the blocks that have been added to the page. In this case we have asked for all blocks that have been added to the area labelled &#039;&#039;side-post&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
echo $OUTPUT-&amp;gt;login_info();&lt;br /&gt;
echo $OUTPUT-&amp;gt;home_link();&lt;br /&gt;
echo $OUTPUT-&amp;gt;standard_footer_html();&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This final bit of code gets the content for the footer of the page. It gets the login information which is the same as in the header, a home link, and the standard footer HTML which like the standard head HTML contains all of the script and style tags required by the page and requested to go in the footer.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note&#039;&#039;&#039;&#039;&#039;: Within Moodle 2.0 most of the JavaScript for the page will be included in the footer. This greatly helps reduce the loading time of the page.&lt;br /&gt;
&lt;br /&gt;
When writing layout files think about the different layouts and how the HTML that each makes use of will differ. You will most likely find you do not need a different layout file for each layout, most likely you will be able to reuse the layout files you create across several layouts. You can of course make use of layout options as well to further reduce the number of layout files you need to produce.&lt;br /&gt;
&lt;br /&gt;
Of course as mentioned above if you are customising an existing theme then you may not need to create any layouts or layout files at all.&lt;br /&gt;
&lt;br /&gt;
&#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;
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: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>Samhemelryk</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_how_to_make_the_dock_horizontal&amp;diff=81967</id>
		<title>Development:Themes 2.0 how to make the dock horizontal</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/24/en/index.php?title=Development:Themes_2.0_how_to_make_the_dock_horizontal&amp;diff=81967"/>
		<updated>2011-03-16T02:53:07Z</updated>

		<summary type="html">&lt;p&gt;Samhemelryk: Intial creation of tutorial&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This quick tutorial looks at how to move the dock from its vertical position on the left hand side of the screen to a horizontal position at the top of the screen.&amp;lt;br /&amp;gt;&lt;br /&gt;
This modification will be done entirely within a theme through the creation of a small amount of JavaScript and a few lines of CSS.&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
If you&#039;re new to Moodle and haven&#039;t yet read the tutorial on creating your first theme I strongly suggest you head there first.&amp;lt;br /&amp;gt;&lt;br /&gt;
I&#039;d also strongly suggest you read [[Development:Styling and customising the dock]] which explains the structure of the dock and a few of the things you will need to know in order to tackle this tutorial.&lt;br /&gt;
&lt;br /&gt;
In order to make this tutorial easier to understand I am going to create a new theme that we&#039;ll call &#039;&#039;&#039;dockmod&#039;&#039;&#039; in which we will create this modification.&lt;br /&gt;
So first step within your Moodle theme directory create a new directory called &#039;&#039;dockmod&#039;&#039;. Within this new directory we&#039;ll create two further directories JavaScript, and style.&lt;br /&gt;
You should now have a directory structure like the one shown below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
moodle/theme/dockmod&lt;br /&gt;
moodle/theme/dockmod/javascript&lt;br /&gt;
moodle/theme/dockmod/style&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next step is to create the three files we are going to need, config.php, dockmod.js, and dockmod.css.&lt;br /&gt;
# config.php is of course for our theme&#039;s configuration and as you know an essential for any theme.&lt;br /&gt;
# dockmod.js will be created in the JavaScript directory, this file will contain the bit of JavaScript we need to write to get our modification to work.&lt;br /&gt;
# dockmod.css will be created in the style directory, this file will contain the CSS we need in order to make the dock horizontal.&lt;br /&gt;
&lt;br /&gt;
You should end up with the following files:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
moodle/theme/dockmod/config.php&lt;br /&gt;
moodle/theme/dockmod/javascript/dockmod.js&lt;br /&gt;
moodle/theme/dockmod/style/dockmod.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==config.php==&lt;br /&gt;
In this step we will be setting up the config.php file for this theme, to be truthful there should be nothing new here for you, this is the easy part of the tutorial.&lt;br /&gt;
The idea of this theme is to simply extend the standard theme and make the dock modification. This has the advantage that our theme will only consist of the JS and CSS required to achieve the dock modification we want.&lt;br /&gt;
&lt;br /&gt;
So open the config.php file in your favourite editor and type the following in:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This is the config file for the dockmod theme.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;name = &#039;dockmod&#039;;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;dockmod&#039;);&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;, &#039;base&#039;);&lt;br /&gt;
$THEME-&amp;gt;enable_dock = true;&lt;br /&gt;
$THEME-&amp;gt;javascripts = array(&#039;dockmod&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So pretty simple really, the name of our theme is &#039;&#039;dockmod&#039;&#039;, you already knew that!&lt;br /&gt;
The parents for this new theme are standard and base as explained above.&lt;br /&gt;
We have one stylesheet also called dockmod (theme/dockmod/style/dockmod.css), and we have one JavaScript file also called dockmod (theme/dockmod/javascript/dockmod.js) and of course its essential we enable the dock, otherwise there&#039;s no point in creating this modification.&lt;br /&gt;
&lt;br /&gt;
==The JavaScript==&lt;br /&gt;
OK this is where the tutorial starts to enter the [potentially] unknown.&lt;br /&gt;
&lt;br /&gt;
The dock is pretty cool in that it looks for a specific JavaScript function when it loads and calls it if it exists, we can use this to modify the dock as we want. It also published several events that we are able to listen to in order to make further modifications when certain things happen.&lt;br /&gt;
&lt;br /&gt;
In our case we want to make the dock horizontal. Now this isn&#039;t actually as nasty as it sounds because in a limited way the dock supports this! When I first wrote the dock I had in mind that one day I would have time to extend the dock to make it moveable, as such I wrote some basic support into it to allow the position and orientation to be switched. I know that a few of you in the community who have looked at making a horizontal dock have found these properties. Functions that rely on the position or orientation of the dock such as making the titles vertical have code within them that checks it makes sense to do so based upon the values of those properties.&lt;br /&gt;
All in all this makes our modification a lot simpler as half the work is already done!&lt;br /&gt;
&lt;br /&gt;
To start with open &#039;&#039;javascript/dockmod.js&#039;&#039; in your favourite editor and type the following:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
function customise_dock_for_theme() {&lt;br /&gt;
    var dock = M.core_dock;&lt;br /&gt;
    dock.cfg.position = &#039;top&#039;;&lt;br /&gt;
    dock.cfg.orientation = &#039;horizontal&#039;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And that is it; It sounds hard, but as you see really it is very easy (although as you get through this tutorial you will see we actually add a bit more JS later on).&lt;br /&gt;
&lt;br /&gt;
So how this works:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
function customise_dock_for_theme() { .... }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
As mentioned above when the dock first loads it looks for a function and calls it, well this is the function &#039;&#039;&#039;customise_dock_for_theme&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
var dock = M.core_dock;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here we are collecting the dock into a variable. It is in this case available from the global M object.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
dock.cfg.position = &#039;top&#039;;&lt;br /&gt;
dock.cfg.orientation = &#039;horizontal&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
These two lines set two configuration variables for the dock, the position and the orientation. There are several other config properties that perhaps will be explored within another document or tutorial.&lt;br /&gt;
&lt;br /&gt;
==The CSS==&lt;br /&gt;
If you save you changes presently and view your theme in your browser you will likely see a big mess. That is because while the JavaScript supports a horizontal dock there is not yet any CSS to support displaying the dock horizontally.&lt;br /&gt;
&lt;br /&gt;
Because of this we will need to write a bit of CSS to ensure the dock is displayed correctly.&lt;br /&gt;
Open &#039;&#039;style/dockmod.css&#039;&#039; in your favourite editor and type the following:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
body.has_dock {margin-top:30px;margin-left:0;}&lt;br /&gt;
body.has_dock_top_horizontal #dock {width:100%;height:30px;background-image:url([[pix:theme|hgradient]]);background-repeat: repeat-x;border-right-width:0;border-bottom:1px solid #000;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .dockeditem_container {margin-top:0;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .dockeditem {display:inline-block;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .dockeditem .dockedtitle {background-image:url([[pix:theme|hgradient]]);background-repeat: repeat-x;background-position:0 10%;border-style:solid;border-width: 0 1px 0 0;border-color:#AAA;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .dockeditem .dockedtitle h2 {margin:0 12px;line-height:30px;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .dockeditem.firstdockitem {margin-left:10px;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .dockeditem.firstdockitem .dockedtitle {border-left-width:1px;}&lt;br /&gt;
body.has_dock_top_horizontal #dock .controls {bottom:auto;right:10px;top:0;width:auto;line-height:30px;}&lt;br /&gt;
body.has_dock_top_horizontal #dock #dockeditempanel {position:absolute;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That&#039;s it!&lt;br /&gt;
&lt;br /&gt;
The first line of CSS is to correct the margin on the body that accommodates the dock, we need to remove the left margin and increase the top margin.&lt;br /&gt;
The other lines of CSS basically just correct change to horizontal images, change positioning from vertical to horizontal, and swap X/Y properties.&lt;br /&gt;
&lt;br /&gt;
==Correcting a vertical bug==&lt;br /&gt;
If you now open your site in your browser and switch to your theme you should see a horizontal dock.&lt;br /&gt;
If you have a bit of a play with if you will notice that if you dock the settings block and fully expand it it will run off the bottom of the page and there will be no scroll bar.&lt;br /&gt;
This has happened because we changed the position attributes of the dock in our CSS above. Essentially we could tinker with the CSS and try to fix it there, however based upon the design of the block and the complexities of getting it to work cross browser I can tell you it&#039;s going to be hard. Instead I&#039;ll show you how we can fix it in JavaScript.&lt;br /&gt;
&lt;br /&gt;
Open your dockmod.js file again and type the following within the customize dock function below the three lines that are already in there.&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
dock.on(&#039;dock:resizepanelcomplete&#039;, theme_dockmod_handle_resize);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This line of code is adding an event listener to the dock so that when it fires the &#039;&#039;&#039;dock:resizepanelcomplete&#039;&#039;&#039; event the function &#039;&#039;&#039;theme_dockmod_handle_resize&#039;&#039;&#039; which we create shortly will get called.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;resizepanelcomplete&#039;&#039; function gets called &#039;&#039;&#039;after&#039;&#039;&#039; the panel that shows the content of a block has been resized. The panel gets resized any time it&#039;s display changes, e.g. when it is shown, or when the content within the panel changes (you expand something).&amp;lt;br /&amp;gt;&lt;br /&gt;
This event is perfect for our needs as when it is called we can look at the height of the panel and if it is more than the height of the screen we can add scrollbars to it and set the height so that the user can access all of the content of the panel.&lt;br /&gt;
&lt;br /&gt;
Now we need to write the &#039;&#039;theme_dockmod_handle_resize&#039;&#039; function. Below the customize dock function type the following:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
function theme_dockmod_handle_resize() {&lt;br /&gt;
    var dock = M.core_dock;&lt;br /&gt;
    var panel = dock.getPanel();&lt;br /&gt;
    var item = dock.getActiveItem();&lt;br /&gt;
    // Check its visible no point doing anything if its not.&lt;br /&gt;
    if (panel.visible === false || typeof(item) !== &#039;object&#039;) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    var buffer = dock.cfg.buffer;&lt;br /&gt;
    var screenheight = parseInt(dock.nodes.body.get(&#039;winHeight&#039;))-(buffer*2)-dock.nodes.dock.get(&#039;offsetHeight&#039;);&lt;br /&gt;
    var scrolltop = panel.contentBody.get(&#039;scrollTop&#039;);&lt;br /&gt;
    // Reset the height of the panel so that we can accurately measure it&lt;br /&gt;
    panel.contentBody.setStyle(&#039;height&#039;, &#039;auto&#039;);&lt;br /&gt;
    // Remove the oversized class if it is there.&lt;br /&gt;
    panel.removeClass(&#039;oversized_content&#039;);&lt;br /&gt;
    var panelheight = panel.get(&#039;offsetHeight&#039;);&lt;br /&gt;
    // Set the height of the panel if required and add the oversized class&lt;br /&gt;
    if (panelheight &amp;gt; screenheight) {&lt;br /&gt;
        panel.contentBody.setStyle(&#039;height&#039;, (screenheight - panel.contentHeader.get(&#039;offsetHeight&#039;))+&#039;px&#039;);&lt;br /&gt;
        panel.addClass(&#039;oversized_content&#039;);&lt;br /&gt;
    }&lt;br /&gt;
    // Set the scrolltop of the panel to what it was before we started.&lt;br /&gt;
    if (scrolltop) {&lt;br /&gt;
        panel.contentBody.set(&#039;scrollTop&#039;, scrolltop);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Save the file now, purge the Moodle cache, and reload the page.&lt;br /&gt;
If you try to replicate the bug now you should find instead you get scrollbars and things work fine.&lt;br /&gt;
&lt;br /&gt;
Congratulations, you&#039;ve successfully created a horizontal dock!&lt;br /&gt;
&lt;br /&gt;
==Complete source==&lt;br /&gt;
The following is the complete source files for this tutorial.&lt;br /&gt;
===config.php===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * This is the config file for the dockmod theme.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
$THEME-&amp;gt;name = &#039;dockmod&#039;;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;dockmod&#039;);&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;, &#039;base&#039;);&lt;br /&gt;
$THEME-&amp;gt;enable_dock = true;&lt;br /&gt;
$THEME-&amp;gt;javascripts = array(&#039;dockmod&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===dockmod.css===&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
body.has_dock {margin-top:30px;margin-left:0;}&lt;br /&gt;
&lt;br /&gt;
/** This is the CSS to display the block on the top of the screen */&lt;br /&gt;
.has_dock_top_horizontal #dock {width:100%;height:30px;background-image:url([[pix:theme|hgradient]]);background-repeat: repeat-x;border-right-width:0;border-bottom:1px solid #000;}&lt;br /&gt;
.has_dock_top_horizontal #dock .dockeditem_container {margin-top:0;}&lt;br /&gt;
.has_dock_top_horizontal #dock .dockeditem {display:inline-block;}&lt;br /&gt;
.has_dock_top_horizontal #dock .dockeditem .dockedtitle {background-image:url([[pix:theme|hgradient]]);background-repeat: repeat-x;background-position:0 10%;border-style:solid;border-width: 0 1px 0 0;border-color:#AAA;}&lt;br /&gt;
.has_dock_top_horizontal #dock .dockeditem .dockedtitle h2 {margin:0 12px;line-height:30px;}&lt;br /&gt;
.has_dock_top_horizontal #dock .dockeditem.firstdockitem {margin-left:10px;}&lt;br /&gt;
.has_dock_top_horizontal #dock .dockeditem.firstdockitem .dockedtitle {border-left-width:1px;}&lt;br /&gt;
.has_dock_top_horizontal #dock .controls {bottom:auto;right:10px;top:0;width:auto;line-height:30px;}&lt;br /&gt;
.has_dock_top_horizontal #dock #dockeditempanel {position:absolute;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===dockmod.js===&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
function theme_dockmod_handle_resize() {&lt;br /&gt;
    var dock = M.core_dock;&lt;br /&gt;
    var panel = dock.getPanel();&lt;br /&gt;
    var item = dock.getActiveItem();&lt;br /&gt;
    // Check its visible no point doing anything if its not.&lt;br /&gt;
    if (panel.visible === false || typeof(item) !== &#039;object&#039;) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    var buffer = dock.cfg.buffer;&lt;br /&gt;
    var screenheight = parseInt(dock.nodes.body.get(&#039;winHeight&#039;))-(buffer*2)-dock.nodes.dock.get(&#039;offsetHeight&#039;);&lt;br /&gt;
    var scrolltop = panel.contentBody.get(&#039;scrollTop&#039;);&lt;br /&gt;
    // Reset the height of the panel so that we can accurately measure it&lt;br /&gt;
    panel.contentBody.setStyle(&#039;height&#039;, &#039;auto&#039;);&lt;br /&gt;
    // Remove the oversized class if it is there.&lt;br /&gt;
    panel.removeClass(&#039;oversized_content&#039;);&lt;br /&gt;
    var panelheight = panel.get(&#039;offsetHeight&#039;);&lt;br /&gt;
    // Set the height of the panel if required and add the oversized class&lt;br /&gt;
    if (panelheight &amp;gt; screenheight) {&lt;br /&gt;
        panel.contentBody.setStyle(&#039;height&#039;, (screenheight - panel.contentHeader.get(&#039;offsetHeight&#039;))+&#039;px&#039;);&lt;br /&gt;
        panel.addClass(&#039;oversized_content&#039;);&lt;br /&gt;
    }&lt;br /&gt;
    // Set the scrolltop of the panel to what it was before we started.&lt;br /&gt;
    if (scrolltop) {&lt;br /&gt;
        panel.contentBody.set(&#039;scrollTop&#039;, scrolltop);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Creating a moveable dock==&lt;br /&gt;
A while ago I created theme that like this one supports a horizontal dock, however it goes one step further by adding a button above the undock all button that when clicked moves the down to the next position (without refreshing the page).&lt;br /&gt;
&lt;br /&gt;
For those interested in having a look at that you can find it on my github account at: https://github.com/samhemelryk/moodle-theme_dockmod&lt;br /&gt;
&lt;br /&gt;
==More information==&lt;br /&gt;
&lt;br /&gt;
* [[Development:Themes 2.0]]&lt;br /&gt;
* [[Development:Themes 2.0 creating your first theme]]&lt;br /&gt;
* [[Development:Styling and customising the dock]]&lt;/div&gt;</summary>
		<author><name>Samhemelryk</name></author>
	</entry>
</feed>