<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Mattgibson</id>
	<title>MoodleDocs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Mattgibson"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/Special:Contributions/Mattgibson"/>
	<updated>2026-07-19T14:16:28Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Admin_settings&amp;diff=42198</id>
		<title>Admin settings</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Admin_settings&amp;diff=42198"/>
		<updated>2013-08-22T11:42:15Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* Individual settings */ Replaced CVS link with Github&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Moodle&#039;s configuration is stored in a mixture of the config, config_plugins, and a few other tables. These settings are edited through the administration screens, which can be accessed by going to the .../admin/index.php URL on your moodle site, or using the Administration block that appears to administrators of the Moodle front page. This page explains how the code for displaying and editing of these settings works.&lt;br /&gt;
&lt;br /&gt;
==Where to find the code==&lt;br /&gt;
&lt;br /&gt;
This is explained further below, but in summary:&lt;br /&gt;
* The library code is all in lib/adminlib.php.&lt;br /&gt;
* The definition of the all the parts of the admin tree is in admin/settings/* some of which call out to plugins to see if they have settings they want to add.&lt;br /&gt;
* The editing and saving of settings is managed by admin/settings.php, admin/upgradesettings.php, and admin/search.php.&lt;br /&gt;
* The administration blocks that appear on the front page and on most of the admin screens is in blocks/admin_tree and blocks/admin_bookmarks.&lt;br /&gt;
&lt;br /&gt;
In my experience most of this code is pretty easy to understand and work with, so here I will focus on giving an overview. For details, see the code.&lt;br /&gt;
&lt;br /&gt;
==The building blocks==&lt;br /&gt;
&lt;br /&gt;
All the settings are arranged into a tree structure. This tree structure is represented in memory as a tree of PHP objects.&lt;br /&gt;
&lt;br /&gt;
At the root of the tree is an &#039;&#039;&#039;admin_root&#039;&#039;&#039; object.&lt;br /&gt;
&lt;br /&gt;
That has children that are &#039;&#039;&#039;admin_category&#039;&#039;&#039;s.&lt;br /&gt;
&lt;br /&gt;
Admin categories contain other categories, &#039;&#039;&#039;admin_settingpage&#039;&#039;&#039;s, and &#039;&#039;&#039;admin_externalpage&#039;&#039;&#039;s.&lt;br /&gt;
&lt;br /&gt;
Settings pages contain individual &#039;&#039;&#039;admin_setting&#039;&#039;&#039;s.&lt;br /&gt;
&lt;br /&gt;
admin_setting is a base class with lots of subclasses like &#039;&#039;&#039;admin_setting_configtext&#039;&#039;&#039;, &#039;&#039;&#039;admin_setting_configcheckbox&#039;&#039;&#039;, and so on. If you need to, you can create new subclasses.&lt;br /&gt;
&lt;br /&gt;
External pages are for things that do not fit into the normal settings structure. For example the global assign roles page, or the page for managing activity modules.&lt;br /&gt;
&lt;br /&gt;
==How the tree is built==&lt;br /&gt;
&lt;br /&gt;
When Moodle needs the admin tree, it calls admin_get_root in lib/adminlib.php, which&lt;br /&gt;
# creates a global $ADMIN object which is an instance of admin_root.&lt;br /&gt;
# does require_once admin/settings/top.php, which adds the top level categories to $ADMIN.&lt;br /&gt;
# does require_once on all the other files in admin/settings to add more specific settings pages and the settings themselves. Some of these settings files additionally make calls out to various types of plugins. For example&lt;br /&gt;
#* admin/settings/plugins.php gives activity modules, blocks, question types, ... a chance to add admin settings.&lt;br /&gt;
# adds the admin reports to the tree.&lt;br /&gt;
&lt;br /&gt;
As an optimisation, before building each bit of the tree, some capability checks are performed, and bits of the tree are skipped if the current user does not have permission to access them.&lt;br /&gt;
&lt;br /&gt;
Exactly how different types of plugin should add their settings to the tree should be documented in the [[Developer_documentation#Make_a_new_plugin|instructions for writing that sort of plugin]].&lt;br /&gt;
&lt;br /&gt;
==Individual settings==&lt;br /&gt;
&lt;br /&gt;
Let us look at a simple example: [https://github.com/moodle/moodle/blob/master/mod/forum/settings.php mod/forum/settings.php]. This is included by admin/settings/plugins.php, which has already created $settings, which is an admin_settingpage that we can add to. The file contains lots of lines that look a bit like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $settings-&amp;gt;add(new admin_setting_configcheckbox(&#039;forum_replytouser&#039;, get_string(&#039;replytouser&#039;, &#039;forum&#039;),&lt;br /&gt;
                    get_string(&#039;replytouser_desc&#039;, &#039;forum&#039;), 1));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What this means is that to our settings page, we are adding a checkbox setting. To understand this in more detail, we need to know what arguments the constructor for an admin_setting takes. The definition of the constructor is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 function admin_setting($name, $visiblename, $description, $defaultsetting) {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, $name here is &#039;forum_replytouser&#039;. This means that this setting is stored in the database in the row of the config table where name=&#039;forum_replytouser&#039;, and is accessible as $CFG-&amp;gt;forum_replytouser.&lt;br /&gt;
&lt;br /&gt;
$visiblename is get_string(&#039;replytouser&#039;, &#039;forum&#039;), this is the label that is put in front of setting on the admin screen.&lt;br /&gt;
&lt;br /&gt;
$description is get_string(&#039;replytouser_desc&#039;, &#039;forum&#039;), this is a short bit of text displayed underneath the setting to explain it further.&lt;br /&gt;
&lt;br /&gt;
$defaultsetting is the default value for this setting. This value is used when Moodle is installed. For simple settings like checkboxes and text fields, this is a simple value. For some more complicated settings, this is an array.&lt;br /&gt;
&lt;br /&gt;
Let as now look at a more complicated example, from mod/quiz/settingstree.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $quizsettings-&amp;gt;add(new admin_setting_text_with_advanced(&#039;quiz/timelimit&#039;,&lt;br /&gt;
         get_string(&#039;timelimit&#039;, &#039;quiz&#039;), get_string(&#039;timelimit_desc&#039;, &#039;quiz&#039;),&lt;br /&gt;
         array(&#039;value&#039; =&amp;gt; &#039;0&#039;, &#039;fix&#039; =&amp;gt; false), PARAM_INT));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This shows two new things:&lt;br /&gt;
&lt;br /&gt;
$name here is &#039;quiz/timelimit&#039;. This is more complicated than a simple setting name. It means that this setting is stored in the config_plugins table, in the row where plugin=&#039;quiz&#039; and name=&#039;timelimit&#039;. It is not accessible through $CFG, to get it you can use get_config(&#039;quiz&#039;, &#039;timelimit&#039;).&lt;br /&gt;
&lt;br /&gt;
And this example shows a $defaultsetting that is an array.&lt;br /&gt;
&lt;br /&gt;
Normally, if you want a particular sort of setting, the easiest way is to look around the admin screens of your Moodle site, and find a setting like the one you want. Then go and copy the code and edit it. Therefore, we do not include a complete list of setting types here.&lt;br /&gt;
&lt;br /&gt;
==External pages==&lt;br /&gt;
&lt;br /&gt;
admin_externalpages represent screens of settings that do not fall into the standard pattern of admin_settings. The admin_externalpage object in the settings tree holds the URL of a PHP page that controls various settings.&lt;br /&gt;
&lt;br /&gt;
In that PHP page, near the start you need to call the function admin_externalpage_setup($pagename), then, instead of the usual print_header and print_footer functions, you use admin_externalpage_print_header() and admin_externalpage_print_footer() functions. This ensures that your page appears with the administration blocks and appropriate navigation.&lt;br /&gt;
&lt;br /&gt;
Note that if your external page relies on additional optional or required params, you may need to use the optional arguments to admin_externalpage_print_header to ensure that the Blocks editing on/off button works.&lt;br /&gt;
&lt;br /&gt;
Note that there are some subclasses of admin_externalpage, for example admin_page_managemods. In a lot of cases, these subclasses only exist to override the search method so this page can be found by appropriate searches.&lt;br /&gt;
&lt;br /&gt;
Once again, to understand this in more depth, your best approach is to look at how some of the external pages in Moodle work.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Modules|adding settings for activity modules]]&lt;br /&gt;
* [[Admin_reports#How_your_report_gets_included_in_the_admin_tree|adding admin reports to the tree]]&lt;br /&gt;
* [[Repository_plugins#APIs_for_Administration|configuration of repository plugins]]&lt;br /&gt;
* [[Filters#Adding_a_settings_screen|configuration for filter]]&lt;br /&gt;
* [[Developer_documentation|Other developer documentation]]&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=How_to_create_a_YUI_3_module&amp;diff=37207</id>
		<title>How to create a YUI 3 module</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=How_to_create_a_YUI_3_module&amp;diff=37207"/>
		<updated>2013-01-13T14:30:06Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* YUI 3 Moodle Module quick start */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}This document explains how to create a YUI 3 module in Moodle.&lt;br /&gt;
&lt;br /&gt;
= The two ways to write a YUI 3 module =&lt;br /&gt;
There is two ways to write a YUI 3 module. The two following paragraphs are sourced from a chat with Sam Hemelryk.&lt;br /&gt;
==The static module==&lt;br /&gt;
The static module is the simpler of the two, in this case you simply put your code into a module.js file within your plugin. Into that file you create a namespace and define any functions or objects you want to use.&lt;br /&gt;
&lt;br /&gt;
Within PHP static modules are also pretty easy to use. The first step if to create a module definition which tells moodle what your module is called, what it requires, and can optionally give it strings.&lt;br /&gt;
&lt;br /&gt;
Once the module is defined you can then use any of the several JS methods for including JS in your page and pass your module definition along.&lt;br /&gt;
&lt;br /&gt;
Whilst this method is simpler to write and understand especially when you are first starting out with JavaScript it isn&#039;t as easily flexible and has some quirks that you need will need to overcome, especially with more complex JavaScript.&lt;br /&gt;
&lt;br /&gt;
This method of writing a module should be used if you are just starting out with JavaScript or if the JS solution you are creating is going to be relatively simple in nature.&lt;br /&gt;
If you are writing something more complex I would strongly suggest looking at the other method as it will result in cleaner, easier to read code at the end of the day. However it will require you to learn your way around writing a Moodle module.&lt;br /&gt;
&lt;br /&gt;
==The YUI3 Moodle Module==&lt;br /&gt;
This method is certainly more complex than the previous method however it is much more flexible and when you have learnt and understand what you are doing it is much quicker to write and more versatile as well. These modules can also easily include other YUI3 Moodle modules, and can choose to include module specific CSS as well.&lt;br /&gt;
&lt;br /&gt;
In this method you create a &#039;&#039;&#039;yui&#039;&#039;&#039; directory within you plugin directory, and then sub directories for each module you wish to write, you name them the same as you want your module named.&lt;br /&gt;
Into the subdirectory you create a JavaScript file with the same name that you gave the subdirectory, e.g.&#039;&#039;&#039;/local/myplugin/yui/mymodule/mymodule.js&#039;&#039;&#039;&lt;br /&gt;
The JS that you then put into this file should then be written in the same way you would write a YUI module, before you ask it certainly requires a good understanding of YUI.&lt;br /&gt;
&lt;br /&gt;
I would recommend this method of writing a module providing you either have an understanding of how to write a YUI module, or you are happy to learn. It normally results in cleaner easier to read code, and if desired can easily be written in such as way as to make it VERY easy to re-use in other bits of code.... particularly helpful if you have several JavaScript objects in play at a time.&lt;br /&gt;
&lt;br /&gt;
= Static module quick start = &lt;br /&gt;
1. Create a module.js file somewhere &lt;br /&gt;
&lt;br /&gt;
2. The two ways Moodle can load this file are:&lt;br /&gt;
&lt;br /&gt;
a- the file is in core: declare the file into /lib/outputrequirementslib.php/find_module($component)&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
          //example:&lt;br /&gt;
          case &#039;core_rating&#039;:&lt;br /&gt;
                    $module = array(&#039;name&#039;     =&amp;gt; &#039;core_rating&#039;,&lt;br /&gt;
                                    &#039;fullpath&#039; =&amp;gt; &#039;/rating/module.js&#039;,&lt;br /&gt;
                                    &#039;requires&#039; =&amp;gt; array(&#039;node&#039;, &#039;event&#039;, &#039;overlay&#039;, &#039;io&#039;, &#039;json&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
b- the file is in a local plugin: the first line of your module should be&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
 M.local_xxx = {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
xxx being your plugin directory name.&lt;br /&gt;
&lt;br /&gt;
3. Write the module.js&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
  M.local_hub={&lt;br /&gt;
    Y : null,&lt;br /&gt;
    transaction : [],&lt;br /&gt;
    init : function(Y){&lt;br /&gt;
        alert(&#039;hub module initialisation&#039;);&lt;br /&gt;
        this.Y = Y;&lt;br /&gt;
    },&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
4. Call this module. The best place to do this is in your renderer class (since, if a theme overrides the renderer to change the HTML, they may also need to use different JavaScript.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $this-&amp;gt;page-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.local_hub.init&#039;); &lt;br /&gt;
You should now have loaded and called your first YUI 3 module in Moodle.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
5. If you want to load your module with some other YUI modules&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $jsmodule = array(&lt;br /&gt;
                &#039;name&#039; =&amp;gt; &#039;local_hub&#039;,&lt;br /&gt;
                &#039;fullpath&#039; =&amp;gt; &#039;/local/hub/module.js&#039;,&lt;br /&gt;
                &#039;requires&#039; =&amp;gt; array(&amp;quot;overlay&amp;quot;, &amp;quot;anim&amp;quot;, &amp;quot;plugin&amp;quot;)); //on this line you are loading three other YUI modules&lt;br /&gt;
   $this-&amp;gt;page-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.local_hub.init&#039;,&lt;br /&gt;
                 null, false, $jsmodule);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
6. If you want to pass parameter to the init function&lt;br /&gt;
&lt;br /&gt;
PHP:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $this-&amp;gt;page-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.local_hub.init&#039;,&lt;br /&gt;
                    array(&#039;this is the param1 value&#039;), false, $jsmodule);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
JS:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
    init : function(Y, params){&lt;br /&gt;
        alert(params);&lt;br /&gt;
        ....&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
7. Then you should be able to fill the module with your own YUI javascript from [http://developer.yahoo.com/yui/3/examples/ YUI examples].&lt;br /&gt;
&lt;br /&gt;
= YUI 3 Moodle Module quick start =&lt;br /&gt;
1. Create the module_name.js file in /local/pluginname/yui/module_name/modulename.js or in /mod/modname/yui/modulename/modulename.js&lt;br /&gt;
&lt;br /&gt;
2. The basic module_name.js structure is:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
  YUI.add(&#039;moodle-local_pluginname-modulename&#039;, function(Y) {&lt;br /&gt;
    var ModulenameNAME = &#039;this_is_a_module_name&#039;;&lt;br /&gt;
    var MODULENAME = function() {&lt;br /&gt;
        MODULENAME.superclass.constructor.apply(this, arguments);&lt;br /&gt;
    };&lt;br /&gt;
    Y.extend(MODULENAME, Y.Base, {&lt;br /&gt;
        initializer : function(config) { // &#039;config&#039; contains the parameter values&lt;br /&gt;
            alert(&#039;I am in initializer&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    }, {&lt;br /&gt;
        NAME : ModulenameNAME, //module name is something mandatory. &lt;br /&gt;
                                // It should be in lower case without space &lt;br /&gt;
                                // as YUI use it for name space sometimes.&lt;br /&gt;
        ATTRS : {&lt;br /&gt;
                 aparam : {}&lt;br /&gt;
        } // Attributes are the parameters sent when the $PAGE-&amp;gt;requires-&amp;gt;yui_module calls the module. &lt;br /&gt;
          // Here you can declare default values or run functions on the parameter. &lt;br /&gt;
          // The param names must be the same as the ones declared &lt;br /&gt;
          // in the $PAGE-&amp;gt;requires-&amp;gt;yui_module call.&lt;br /&gt;
    });&lt;br /&gt;
    M.local_pluginname = M.local_pluginname || {}; // This line use existing name path if it exists, otherwise create a new one. &lt;br /&gt;
                                                 // This is to avoid to overwrite previously loaded module with same name.&lt;br /&gt;
    M.local_pluginname.init_modulename = function(config) { // &#039;config&#039; contains the parameter values&lt;br /&gt;
        alert(&#039;I am in the javascript module, Yeah!&#039;);&lt;br /&gt;
        return new MODULENAME(config); // &#039;config&#039; contains the parameter values&lt;br /&gt;
    };&lt;br /&gt;
  }, &#039;@VERSION@&#039;, {&lt;br /&gt;
      requires:[&#039;base&#039;,&#039;another_required_YUI_module&#039;, &#039;a_moodle_YUI_module&#039;]&lt;br /&gt;
  });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
3. Call the javascript in PHP. Again, it is best to do this in a renderer class. (if you copied the previous javascript, 2 javascript alert should appear.)&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
  $this-&amp;gt;page-&amp;gt;requires-&amp;gt;yui_module(&#039;moodle-local_pluginname-modulename&#039;, &#039;M.local_pluginname.init_modulename&#039;,&lt;br /&gt;
                array(array(&#039;aparam&#039;=&amp;gt;&#039;paramvalue&#039;)));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
== Full simple example==&lt;br /&gt;
Once you understand and run the above quick start, here is simple YUI 3 example. It shows how to use another YUI 3 module in your module, and to use some events.&lt;br /&gt;
=== It includes===&lt;br /&gt;
* display a parameter value in two javascript alert boxes =&amp;gt; demonstrate how to pass a param to the initialize function in two different ways&lt;br /&gt;
* display an overlay when you click on an image&lt;br /&gt;
* hide the overlay when you click on the body&lt;br /&gt;
* some commented code to see how Moodle YUI exception works&lt;br /&gt;
&lt;br /&gt;
=== PHP ===&lt;br /&gt;
Create a [https://docs.moodle.org/en/Development:Local_customisation basic local plugin] (in this example it is named hub) in /local/hub/ and add this code into one of the plugin pages:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
   $PAGE-&amp;gt;requires-&amp;gt;yui_module(&#039;moodle-local_hub-comments&#039;, &#039;M.local_hub.init_comments&#039;,&lt;br /&gt;
                array(array(&#039;commentids&#039; =&amp;gt; &#039;1 , 23 ,45&#039;)));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== HTML ===&lt;br /&gt;
The plugin page should generate this HTML code:&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;!-- image to click on --&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;comments&amp;quot;&amp;gt;&amp;lt;img src=&#039;http://moodle.org/theme/moodle2/pix/moodle-logo.gif&#039; alt=&#039;the image to click on&#039;/&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- overlay --&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;commentoverlay&amp;quot; class=&amp;quot;yui3-overlay-loading&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;yui3-widget-hd&amp;quot;&amp;gt;Comment&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;yui3-widget-bd&amp;quot;&amp;gt;this is a comment&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;yui3-widget-bd&amp;quot;&amp;gt;this is another comment&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;
=== CSS ===&lt;br /&gt;
The plugin style.css should contain:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/* Hide overlay markup while loading, if js is enabled */&lt;br /&gt;
.yui3-js-enabled .yui3-overlay-loading {&lt;br /&gt;
    top:-1000em;&lt;br /&gt;
    left:-1000em;&lt;br /&gt;
    position:absolute;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Overlay Look/Feel */&lt;br /&gt;
.yui3-overlay-content {&lt;br /&gt;
    padding:3px;&lt;br /&gt;
    border:1px solid #000;&lt;br /&gt;
    background-color:#aaa;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.yui3-overlay-content .yui3-widget-hd {&lt;br /&gt;
    padding:5px;&lt;br /&gt;
    border:2px solid #aa0000;&lt;br /&gt;
    background-color:#fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.yui3-overlay-content .yui3-widget-bd {&lt;br /&gt;
    padding:5px;&lt;br /&gt;
    border:2px solid #0000aa;&lt;br /&gt;
    background-color:#fff;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== JS ===&lt;br /&gt;
In /local/hub/yui/comments/comments.js&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
YUI.add(&#039;moodle-local_hub-comments&#039;, function(Y) {&lt;br /&gt;
&lt;br /&gt;
    var COMMENTSNAME = &#039;hub_comments&#039;;&lt;br /&gt;
&lt;br /&gt;
    //we declare the overlay here so it&#039;s accessible to all the extended class function&#039;&lt;br /&gt;
    var overlay = new Y.Overlay({&lt;br /&gt;
                srcNode:&amp;quot;#commentoverlay&amp;quot;, //the main div with id = commentoverlay&lt;br /&gt;
                width:&amp;quot;10em&amp;quot;,&lt;br /&gt;
                height:&amp;quot;10em&amp;quot;,&lt;br /&gt;
                xy:[ 0, 0],&lt;br /&gt;
                visible: false //by default it is not displayed&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
    var COMMENTS = function() {&lt;br /&gt;
        COMMENTS.superclass.constructor.apply(this, arguments);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Y.extend(COMMENTS, Y.Base, {&lt;br /&gt;
&lt;br /&gt;
        event:null,&lt;br /&gt;
&lt;br /&gt;
        initializer : function(params) {&lt;br /&gt;
&lt;br /&gt;
            //Example how to retrieve the parameter,&lt;br /&gt;
            //see what happens if you don&#039;t pass the parameter in the call&lt;br /&gt;
            alert(this.get(&#039;commentids&#039;)); // You usually use an attribute because&lt;br /&gt;
                                           //a attribut can have default value.&lt;br /&gt;
                                           //use the ATTRS default value if not passed as parameter&lt;br /&gt;
            alert(params.commentids); // undefined if not passed as parameter&lt;br /&gt;
&lt;br /&gt;
            //render the overlay&lt;br /&gt;
            overlay.render();&lt;br /&gt;
&lt;br /&gt;
            // position the overlay in the middle of the web browser window&lt;br /&gt;
            var WidgetPositionAlign = Y.WidgetPositionAlign;&lt;br /&gt;
            overlay.set(&amp;quot;align&amp;quot;, {&lt;br /&gt;
                node:&amp;quot;&amp;quot;, //empty =&amp;gt; viewport&lt;br /&gt;
                points:[WidgetPositionAlign.CC, WidgetPositionAlign.CC]&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            //attach a show event on the div with id = comments&lt;br /&gt;
            //we also change the div style to display the click zone&lt;br /&gt;
            Y.one(&#039;#comments&#039;).setStyle(&amp;quot;border&amp;quot;, &amp;quot;1px solid red&amp;quot;).on(&#039;click&#039;, this.show, this);&lt;br /&gt;
&lt;br /&gt;
            //uncomment the try content to see how works exception in Moodle&lt;br /&gt;
            //this exception has been specially created for Moodle&lt;br /&gt;
            try {&lt;br /&gt;
              //surely_not_existing_js_function();&lt;br /&gt;
            } catch (exception) {&lt;br /&gt;
                new M.core.exception(exception);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        show : function (e) {&lt;br /&gt;
            overlay.show(); //show the overlay&lt;br /&gt;
           &lt;br /&gt;
            e.halt(); // we are going to attach a new &#039;hide overlay&#039; event to the body,&lt;br /&gt;
                      // because javascript always propagate event to parent tag,&lt;br /&gt;
                      // we need to tell Yahoo to stop to call the event on parent tag&lt;br /&gt;
                      // otherwise the hide event will be call right away.&lt;br /&gt;
&lt;br /&gt;
            //we add a new event on the body in order to hide the overlay for the next click&lt;br /&gt;
            this.event = Y.one(document.body).on(&#039;click&#039;,this.hide,this);&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        hide : function () {&lt;br /&gt;
            overlay.hide(); //hide the overlay&lt;br /&gt;
            this.event.detach(); //we need to detach the hide event&lt;br /&gt;
                                 //Note: it would work without but create js warning everytime&lt;br /&gt;
                                 //we click on the body&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }, {&lt;br /&gt;
        NAME : COMMENTSNAME,&lt;br /&gt;
        ATTRS : {&lt;br /&gt;
            commentids: {value : 450} //default value (has no purpose in this code except to show you&lt;br /&gt;
                                      // how to pass/use a param value)&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    M.local_hub = M.local_hub || {};&lt;br /&gt;
    M.local_hub.init_comments = function(params) {&lt;br /&gt;
        return new COMMENTS(params);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}, &#039;@VERSION@&#039;, {&lt;br /&gt;
    requires:[&#039;base&#039;,&#039;overlay&#039;, &#039;moodle-enrol-notification&#039;]&lt;br /&gt;
    //Note: &#039;moodle-enrol-notification&#039; contains Moodle YUI exception&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Where are my methods in the IDE?==&lt;br /&gt;
Some (all?) IDEs will fail to parse the above structure correctly and will not show you your methods in the structure/navigator pane. If this happens, use JSDoc format to mark the Y.extend() line as being a particular class:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;    &lt;br /&gt;
/**&lt;br /&gt;
 * @class M.local_hub.init_comments&lt;br /&gt;
 */&lt;br /&gt;
Y.extend(COMMENTS, Y.Base, {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This depends to a certain extent on how you choose to instantiate your objects. The above init_widget() method can be replaced with a more class based method like a lot of the YUI library uses.&lt;br /&gt;
&lt;br /&gt;
= What else to read =&lt;br /&gt;
Two pages are important to start with when you discover YUI 3&lt;br /&gt;
* you should read the [http://developer.yahoo.com/yui/3/base/ base YUI doc]. It is very useful to understand the YUI 3 Moodle module.&lt;br /&gt;
* you want to have a look to the [http://developer.yahoo.com/yui/3/examples/ YUI 3 examples]. Always open the examples in a window to have a look to the complete example codes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:AJAX]]&lt;br /&gt;
[[Category:Javascript]]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[Javascript and YUI 3 FAQ]]&lt;br /&gt;
* [[JavaScript FAQ]]&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=lib/formslib.php_Form_Definition&amp;diff=34932</id>
		<title>lib/formslib.php Form Definition</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=lib/formslib.php_Form_Definition&amp;diff=34932"/>
		<updated>2012-08-17T16:02:53Z</updated>

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

		<summary type="html">&lt;p&gt;Mattgibson: /* Where are my methods in the IDE? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}This document explains how to create a YUI 3 module in Moodle.&lt;br /&gt;
&lt;br /&gt;
= The two ways to write a YUI 3 module =&lt;br /&gt;
There is two ways to write a YUI 3 module. The two following paragraphs are sourced from a chat with Sam Hemelryk.&lt;br /&gt;
==The static module==&lt;br /&gt;
The static module is the simpler of the two, in this case you simply put your code into a module.js file within your plugin. Into that file you create a namespace and define any functions or objects you want to use.&lt;br /&gt;
&lt;br /&gt;
Within PHP static modules are also pretty easy to use. The first step if to create a module definition which tells moodle what your module is called, what it requires, and can optionally give it strings.&lt;br /&gt;
&lt;br /&gt;
Once the module is defined you can then use any of the several JS methods for including JS in your page and pass your module definition along.&lt;br /&gt;
&lt;br /&gt;
Whilst this method is simpler to write and understand especially when you are first starting out with JavaScript it isn&#039;t as easily flexible and has some quirks that you need will need to overcome, especially with more complex JavaScript.&lt;br /&gt;
&lt;br /&gt;
This method of writing a module should be used if you are just starting out with JavaScript or if the JS solution you are creating is going to be relatively simple in nature.&lt;br /&gt;
If you are writing something more complex I would strongly suggest looking at the other method as it will result in cleaner, easier to read code at the end of the day. However it will require you to learn your way around writing a Moodle module.&lt;br /&gt;
&lt;br /&gt;
==The YUI3 Moodle Module==&lt;br /&gt;
This method is certainly more complex than the previous method however it is much more flexible and when you have learnt and understand what you are doing it is much quicker to write and more versatile as well. These modules can also easily include other YUI3 Moodle modules, and can choose to include module specific CSS as well.&lt;br /&gt;
&lt;br /&gt;
In this method you create a &#039;&#039;&#039;yui&#039;&#039;&#039; directory within you plugin directory, and then sub directories for each module you wish to write, you name them the same as you want your module named.&lt;br /&gt;
Into the subdirectory you create a JavaScript file with the same name that you gave the subdirectory, e.g.&#039;&#039;&#039;/local/myplugin/yui/mymodule/mymodule.js&#039;&#039;&#039;&lt;br /&gt;
The JS that you then put into this file should then be written in the same way you would write a YUI module, before you ask it certainly requires a good understanding of YUI.&lt;br /&gt;
&lt;br /&gt;
I would recommend this method of writing a module providing you either have an understanding of how to write a YUI module, or you are happy to learn. It normally results in cleaner easier to read code, and if desired can easily be written in such as way as to make it VERY easy to re-use in other bits of code.... particularly helpful if you have several JavaScript objects in play at a time.&lt;br /&gt;
&lt;br /&gt;
= Static module quick start = &lt;br /&gt;
1. Create a module.js file somewhere &lt;br /&gt;
&lt;br /&gt;
2. The two ways Moodle can load this file are:&lt;br /&gt;
&lt;br /&gt;
a- the file is in core: declare the file into /lib/outputrequirementslib.php/find_module($component)&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
          //example:&lt;br /&gt;
          case &#039;core_rating&#039;:&lt;br /&gt;
                    $module = array(&#039;name&#039;     =&amp;gt; &#039;core_rating&#039;,&lt;br /&gt;
                                    &#039;fullpath&#039; =&amp;gt; &#039;/rating/module.js&#039;,&lt;br /&gt;
                                    &#039;requires&#039; =&amp;gt; array(&#039;node&#039;, &#039;event&#039;, &#039;overlay&#039;, &#039;io&#039;, &#039;json&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
b- the file is in a local plugin: the first line of your module should be&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
 M.local_xxx = {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
xxx being your plugin directory name.&lt;br /&gt;
&lt;br /&gt;
3. Write the module.js&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
  M.local_hub={&lt;br /&gt;
    Y : null,&lt;br /&gt;
    transaction : [],&lt;br /&gt;
    init : function(Y){&lt;br /&gt;
        alert(&#039;hub module initialisation&#039;);&lt;br /&gt;
        this.Y = Y;&lt;br /&gt;
    },&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
4. Call this module. The best place to do this is in your renderer class (since, if a theme overrides the renderer to change the HTML, they may also need to use different JavaScript.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $this-&amp;gt;page-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.local_hub.init&#039;); &lt;br /&gt;
You should now have loaded and called your first YUI 3 module in Moodle.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
5. If you want to load your module with some other YUI modules&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $jsmodule = array(&lt;br /&gt;
                &#039;name&#039; =&amp;gt; &#039;local_hub&#039;,&lt;br /&gt;
                &#039;fullpath&#039; =&amp;gt; &#039;/local/hub/module.js&#039;,&lt;br /&gt;
                &#039;requires&#039; =&amp;gt; array(&amp;quot;overlay&amp;quot;, &amp;quot;anim&amp;quot;, &amp;quot;plugin&amp;quot;)); //on this line you are loading three other YUI modules&lt;br /&gt;
   $this-&amp;gt;page-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.local_hub.init&#039;,&lt;br /&gt;
                 null, false, $jsmodule);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
6. If you want to pass parameter to the init function&lt;br /&gt;
&lt;br /&gt;
PHP:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $this-&amp;gt;page-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.local_hub.init&#039;,&lt;br /&gt;
                    array(&#039;this is the param1 value&#039;), false, $jsmodule);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
JS:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
    init : function(Y, params){&lt;br /&gt;
        alert(params);&lt;br /&gt;
        ....&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
7. Then you should be able to fill the module with your own YUI javascript from [http://developer.yahoo.com/yui/3/examples/ YUI examples].&lt;br /&gt;
&lt;br /&gt;
= YUI 3 Moodle Module quick start =&lt;br /&gt;
1. Create the module_name.js file in /local/pluginname/yui/module_name/modulename.js or in /mod/modname/yui/modulename/modulename.js&lt;br /&gt;
&lt;br /&gt;
2. The basic module_name.js structure is:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
  YUI.add(&#039;moodle-local_pluginname-modulename&#039;, function(Y) {&lt;br /&gt;
    var ModulenameNAME = &#039;this_is_a_module_name&#039;;&lt;br /&gt;
    var MODULENAME = function() {&lt;br /&gt;
        MODULENAME.superclass.constructor.apply(this, arguments);&lt;br /&gt;
    };&lt;br /&gt;
    Y.extend(MODULENAME, Y.Base, {&lt;br /&gt;
        initializer : function(config) { // &#039;config&#039; contains the parameter values&lt;br /&gt;
            alert(&#039;I am in initializer&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    }, {&lt;br /&gt;
        NAME : ModulenameNAME, //module name is something mandatory. &lt;br /&gt;
                                // It should be in lower case without space &lt;br /&gt;
                                // as YUI use it for name space sometimes.&lt;br /&gt;
        ATTRS : {&lt;br /&gt;
                 aparam : {}&lt;br /&gt;
        } // Attributes are the parameters sent when the $PAGE-&amp;gt;requires-&amp;gt;yui_module calls the module. &lt;br /&gt;
          // Here you can declare default values or run functions on the parameter. &lt;br /&gt;
          // The param names must be the same as the ones declared &lt;br /&gt;
          // in the $PAGE-&amp;gt;requires-&amp;gt;yui_module call.&lt;br /&gt;
    });&lt;br /&gt;
    M.local_pluginname = M.local_pluginname || {}; // This line use existing name path if it exists, ortherwise create a new one. &lt;br /&gt;
                                                 // This is to avoid to overwrite previously loaded module with same name.&lt;br /&gt;
    M.local_pluginname.init_modulename = function(config) { // &#039;config&#039; contains the parameter values&lt;br /&gt;
        alert(&#039;I am in the javascript module, Yeah!&#039;);&lt;br /&gt;
        return new MODULENAME(config); // &#039;config&#039; contains the parameter values&lt;br /&gt;
    }&lt;br /&gt;
  }, &#039;@VERSION@&#039;, {&lt;br /&gt;
      requires:[&#039;base&#039;,&#039;another_required_YUI_module&#039;, &#039;a_moodle_YUI_module&#039;]&lt;br /&gt;
  });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
3. Call the javascript in PHP. Again, it is best to do this in a renderer class. (if you copied the previous javascript, 2 javascript alert should appear.)&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
  $this-&amp;gt;page-&amp;gt;requires-&amp;gt;yui_module(&#039;moodle-local_pluginname-modulename&#039;, &#039;M.local_pluginname.init_modulename&#039;,&lt;br /&gt;
                array(array(&#039;aparam&#039;=&amp;gt;&#039;paramvalue&#039;)));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
== Full simple example==&lt;br /&gt;
Once you understand and run the above quick start, here is simple YUI 3 example. It shows how to use another YUI 3 module in your module, and to use some events.&lt;br /&gt;
=== It includes===&lt;br /&gt;
* display a parameter value in two javascript alert boxes =&amp;gt; demonstrate how to pass a param to the initialize function in two different ways&lt;br /&gt;
* display an overlay when you click on an image&lt;br /&gt;
* hide the overlay when you click on the body&lt;br /&gt;
* some commented code to see how Moodle YUI exception works&lt;br /&gt;
&lt;br /&gt;
=== PHP ===&lt;br /&gt;
Create a [https://docs.moodle.org/en/Development:Local_customisation basic local plugin] (in this example it is named hub) in /local/hub/ and add this code into one of the plugin pages:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
   $PAGE-&amp;gt;requires-&amp;gt;yui_module(&#039;moodle-local_hub-comments&#039;, &#039;M.local_hub.init_comments&#039;,&lt;br /&gt;
                array(array(&#039;commentids&#039; =&amp;gt; &#039;1 , 23 ,45&#039;)));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== HTML ===&lt;br /&gt;
The plugin page should generate this HTML code:&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;!-- image to click on --&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;comments&amp;quot;&amp;gt;&amp;lt;img src=&#039;http://moodle.org/theme/moodle2/pix/moodle-logo.gif&#039; alt=&#039;the image to click on&#039;/&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- overlay --&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;commentoverlay&amp;quot; class=&amp;quot;yui3-overlay-loading&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;yui3-widget-hd&amp;quot;&amp;gt;Comment&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;yui3-widget-bd&amp;quot;&amp;gt;this is a comment&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;yui3-widget-bd&amp;quot;&amp;gt;this is another comment&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;
=== CSS ===&lt;br /&gt;
The plugin style.css should contain:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/* Hide overlay markup while loading, if js is enabled */&lt;br /&gt;
.yui3-js-enabled .yui3-overlay-loading {&lt;br /&gt;
    top:-1000em;&lt;br /&gt;
    left:-1000em;&lt;br /&gt;
    position:absolute;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Overlay Look/Feel */&lt;br /&gt;
.yui3-overlay-content {&lt;br /&gt;
    padding:3px;&lt;br /&gt;
    border:1px solid #000;&lt;br /&gt;
    background-color:#aaa;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.yui3-overlay-content .yui3-widget-hd {&lt;br /&gt;
    padding:5px;&lt;br /&gt;
    border:2px solid #aa0000;&lt;br /&gt;
    background-color:#fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.yui3-overlay-content .yui3-widget-bd {&lt;br /&gt;
    padding:5px;&lt;br /&gt;
    border:2px solid #0000aa;&lt;br /&gt;
    background-color:#fff;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== JS ===&lt;br /&gt;
In /local/hub/yui/comments/comments.js&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
YUI.add(&#039;moodle-local_hub-comments&#039;, function(Y) {&lt;br /&gt;
&lt;br /&gt;
    var COMMENTSNAME = &#039;hub_comments&#039;;&lt;br /&gt;
&lt;br /&gt;
    //we declare the overlay here so it&#039;s accessible to all the extended class function&#039;&lt;br /&gt;
    var overlay = new Y.Overlay({&lt;br /&gt;
                srcNode:&amp;quot;#commentoverlay&amp;quot;, //the main div with id = commentoverlay&lt;br /&gt;
                width:&amp;quot;10em&amp;quot;,&lt;br /&gt;
                height:&amp;quot;10em&amp;quot;,&lt;br /&gt;
                xy:[ 0, 0],&lt;br /&gt;
                visible: false //by default it is not displayed&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
    var COMMENTS = function() {&lt;br /&gt;
        COMMENTS.superclass.constructor.apply(this, arguments);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Y.extend(COMMENTS, Y.Base, {&lt;br /&gt;
&lt;br /&gt;
        event:null,&lt;br /&gt;
&lt;br /&gt;
        initializer : function(params) {&lt;br /&gt;
&lt;br /&gt;
            //Example how to retrieve the parameter,&lt;br /&gt;
            //see what happens if you don&#039;t pass the parameter in the call&lt;br /&gt;
            alert(this.get(&#039;commentids&#039;)); // You usually use an attribute because&lt;br /&gt;
                                           //a attribut can have default value.&lt;br /&gt;
                                           //use the ATTRS default value if not passed as parameter&lt;br /&gt;
            alert(params.commentids); // undefined if not passed as parameter&lt;br /&gt;
&lt;br /&gt;
            //render the overlay&lt;br /&gt;
            overlay.render();&lt;br /&gt;
&lt;br /&gt;
            // position the overlay in the middle of the web browser window&lt;br /&gt;
            var WidgetPositionAlign = Y.WidgetPositionAlign;&lt;br /&gt;
            overlay.set(&amp;quot;align&amp;quot;, {&lt;br /&gt;
                node:&amp;quot;&amp;quot;, //empty =&amp;gt; viewport&lt;br /&gt;
                points:[WidgetPositionAlign.CC, WidgetPositionAlign.CC]&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            //attach a show event on the div with id = comments&lt;br /&gt;
            //we also change the div style to display the click zone&lt;br /&gt;
            Y.one(&#039;#comments&#039;).setStyle(&amp;quot;border&amp;quot;, &amp;quot;1px solid red&amp;quot;).on(&#039;click&#039;, this.show, this);&lt;br /&gt;
&lt;br /&gt;
            //uncomment the try content to see how works exception in Moodle&lt;br /&gt;
            //this exception has been specially created for Moodle&lt;br /&gt;
            try {&lt;br /&gt;
              //surely_not_existing_js_function();&lt;br /&gt;
            } catch (exception) {&lt;br /&gt;
                new M.core.exception(exception);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        show : function (e) {&lt;br /&gt;
            overlay.show(); //show the overlay&lt;br /&gt;
           &lt;br /&gt;
            e.halt(); // we are going to attach a new &#039;hide overlay&#039; event to the body,&lt;br /&gt;
                      // because javascript always propagate event to parent tag,&lt;br /&gt;
                      // we need to tell Yahoo to stop to call the event on parent tag&lt;br /&gt;
                      // otherwise the hide event will be call right away.&lt;br /&gt;
&lt;br /&gt;
            //we add a new event on the body in order to hide the overlay for the next click&lt;br /&gt;
            this.event = Y.one(document.body).on(&#039;click&#039;,this.hide,this);&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        hide : function () {&lt;br /&gt;
            overlay.hide(); //hide the overlay&lt;br /&gt;
            this.event.detach(); //we need to detach the hide event&lt;br /&gt;
                                 //Note: it would work without but create js warning everytime&lt;br /&gt;
                                 //we click on the body&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }, {&lt;br /&gt;
        NAME : COMMENTSNAME,&lt;br /&gt;
        ATTRS : {&lt;br /&gt;
            commentids: {value : 450} //default value (has no purpose in this code except to show you&lt;br /&gt;
                                      // how to pass/use a param value)&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    M.local_hub = M.local_hub || {};&lt;br /&gt;
    M.local_hub.init_comments = function(params) {&lt;br /&gt;
        return new COMMENTS(params);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}, &#039;@VERSION@&#039;, {&lt;br /&gt;
    requires:[&#039;base&#039;,&#039;overlay&#039;, &#039;moodle-enrol-notification&#039;]&lt;br /&gt;
    //Note: &#039;moodle-enrol-notification&#039; contains Moodle YUI exception&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Where are my methods in the IDE?==&lt;br /&gt;
Some (all?) IDEs will fail to parse the above structure correctly and will not show you your methods in the structure/navigator pane. If this happens, use JSDoc format to mark the Y.extend() line as being a particular class:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;    &lt;br /&gt;
/**&lt;br /&gt;
 * @class M.local_hub.init_comments&lt;br /&gt;
 */&lt;br /&gt;
Y.extend(COMMENTS, Y.Base, {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This depends to a certain extent on how you choose to instantiate your objects. The above init_widget() method can be replaced with a more class based method like a lot of the YUI library uses.&lt;br /&gt;
&lt;br /&gt;
= What else to read =&lt;br /&gt;
Two pages are important to start with when you discover YUI 3&lt;br /&gt;
* you should read the [http://developer.yahoo.com/yui/3/base/ base YUI doc]. It is very useful to understand the YUI 3 Moodle module.&lt;br /&gt;
* you want to have a look to the [http://developer.yahoo.com/yui/3/examples/ YUI 3 examples]. Always open the examples in a window to have a look to the complete example codes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:AJAX]]&lt;br /&gt;
[[Category:Javascript]]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[Javascript and YUI 3 FAQ]]&lt;br /&gt;
* [[JavaScript FAQ]]&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=How_to_create_a_YUI_3_module&amp;diff=34277</id>
		<title>How to create a YUI 3 module</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=How_to_create_a_YUI_3_module&amp;diff=34277"/>
		<updated>2012-06-25T11:02:36Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* Where are my methods in the IDE? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}This document explains how to create a YUI 3 module in Moodle.&lt;br /&gt;
&lt;br /&gt;
= The two ways to write a YUI 3 module =&lt;br /&gt;
There is two ways to write a YUI 3 module. The two following paragraphs are sourced from a chat with Sam Hemelryk.&lt;br /&gt;
==The static module==&lt;br /&gt;
The static module is the simpler of the two, in this case you simply put your code into a module.js file within your plugin. Into that file you create a namespace and define any functions or objects you want to use.&lt;br /&gt;
&lt;br /&gt;
Within PHP static modules are also pretty easy to use. The first step if to create a module definition which tells moodle what your module is called, what it requires, and can optionally give it strings.&lt;br /&gt;
&lt;br /&gt;
Once the module is defined you can then use any of the several JS methods for including JS in your page and pass your module definition along.&lt;br /&gt;
&lt;br /&gt;
Whilst this method is simpler to write and understand especially when you are first starting out with JavaScript it isn&#039;t as easily flexible and has some quirks that you need will need to overcome, especially with more complex JavaScript.&lt;br /&gt;
&lt;br /&gt;
This method of writing a module should be used if you are just starting out with JavaScript or if the JS solution you are creating is going to be relatively simple in nature.&lt;br /&gt;
If you are writing something more complex I would strongly suggest looking at the other method as it will result in cleaner, easier to read code at the end of the day. However it will require you to learn your way around writing a Moodle module.&lt;br /&gt;
&lt;br /&gt;
==The YUI3 Moodle Module==&lt;br /&gt;
This method is certainly more complex than the previous method however it is much more flexible and when you have learnt and understand what you are doing it is much quicker to write and more versatile as well. These modules can also easily include other YUI3 Moodle modules, and can choose to include module specific CSS as well.&lt;br /&gt;
&lt;br /&gt;
In this method you create a &#039;&#039;&#039;yui&#039;&#039;&#039; directory within you plugin directory, and then sub directories for each module you wish to write, you name them the same as you want your module named.&lt;br /&gt;
Into the subdirectory you create a JavaScript file with the same name that you gave the subdirectory, e.g.&#039;&#039;&#039;/local/myplugin/yui/mymodule/mymodule.js&#039;&#039;&#039;&lt;br /&gt;
The JS that you then put into this file should then be written in the same way you would write a YUI module, before you ask it certainly requires a good understanding of YUI.&lt;br /&gt;
&lt;br /&gt;
I would recommend this method of writing a module providing you either have an understanding of how to write a YUI module, or you are happy to learn. It normally results in cleaner easier to read code, and if desired can easily be written in such as way as to make it VERY easy to re-use in other bits of code.... particularly helpful if you have several JavaScript objects in play at a time.&lt;br /&gt;
&lt;br /&gt;
= Static module quick start = &lt;br /&gt;
1. Create a module.js file somewhere &lt;br /&gt;
&lt;br /&gt;
2. The two ways Moodle can load this file are:&lt;br /&gt;
&lt;br /&gt;
a- the file is in core: declare the file into /lib/outputrequirementslib.php/find_module($component)&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
          //example:&lt;br /&gt;
          case &#039;core_rating&#039;:&lt;br /&gt;
                    $module = array(&#039;name&#039;     =&amp;gt; &#039;core_rating&#039;,&lt;br /&gt;
                                    &#039;fullpath&#039; =&amp;gt; &#039;/rating/module.js&#039;,&lt;br /&gt;
                                    &#039;requires&#039; =&amp;gt; array(&#039;node&#039;, &#039;event&#039;, &#039;overlay&#039;, &#039;io&#039;, &#039;json&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
b- the file is in a local plugin: the first line of your module should be&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
 M.local_xxx = {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
xxx being your plugin directory name.&lt;br /&gt;
&lt;br /&gt;
3. Write the module.js&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
  M.local_hub={&lt;br /&gt;
    Y : null,&lt;br /&gt;
    transaction : [],&lt;br /&gt;
    init : function(Y){&lt;br /&gt;
        alert(&#039;hub module initialisation&#039;);&lt;br /&gt;
        this.Y = Y;&lt;br /&gt;
    },&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
4. Call this module. The best place to do this is in your renderer class (since, if a theme overrides the renderer to change the HTML, they may also need to use different JavaScript.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $this-&amp;gt;page-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.local_hub.init&#039;); &lt;br /&gt;
You should now have loaded and called your first YUI 3 module in Moodle.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
5. If you want to load your module with some other YUI modules&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $jsmodule = array(&lt;br /&gt;
                &#039;name&#039; =&amp;gt; &#039;local_hub&#039;,&lt;br /&gt;
                &#039;fullpath&#039; =&amp;gt; &#039;/local/hub/module.js&#039;,&lt;br /&gt;
                &#039;requires&#039; =&amp;gt; array(&amp;quot;overlay&amp;quot;, &amp;quot;anim&amp;quot;, &amp;quot;plugin&amp;quot;)); //on this line you are loading three other YUI modules&lt;br /&gt;
   $this-&amp;gt;page-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.local_hub.init&#039;,&lt;br /&gt;
                 null, false, $jsmodule);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
6. If you want to pass parameter to the init function&lt;br /&gt;
&lt;br /&gt;
PHP:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $this-&amp;gt;page-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.local_hub.init&#039;,&lt;br /&gt;
                    array(&#039;this is the param1 value&#039;), false, $jsmodule);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
JS:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
    init : function(Y, params){&lt;br /&gt;
        alert(params);&lt;br /&gt;
        ....&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
7. Then you should be able to fill the module with your own YUI javascript from [http://developer.yahoo.com/yui/3/examples/ YUI examples].&lt;br /&gt;
&lt;br /&gt;
= YUI 3 Moodle Module quick start =&lt;br /&gt;
1. Create the module_name.js file in /local/pluginname/yui/module_name/modulename.js or in /mod/modname/yui/modulename/modulename.js&lt;br /&gt;
&lt;br /&gt;
2. The basic module_name.js structure is:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
  YUI.add(&#039;moodle-local_pluginname-modulename&#039;, function(Y) {&lt;br /&gt;
    var ModulenameNAME = &#039;this_is_a_module_name&#039;;&lt;br /&gt;
    var MODULENAME = function() {&lt;br /&gt;
        MODULENAME.superclass.constructor.apply(this, arguments);&lt;br /&gt;
    };&lt;br /&gt;
    Y.extend(MODULENAME, Y.Base, {&lt;br /&gt;
        initializer : function(config) { // &#039;config&#039; contains the parameter values&lt;br /&gt;
            alert(&#039;I am in initializer&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    }, {&lt;br /&gt;
        NAME : ModulenameNAME, //module name is something mandatory. &lt;br /&gt;
                                // It should be in lower case without space &lt;br /&gt;
                                // as YUI use it for name space sometimes.&lt;br /&gt;
        ATTRS : {&lt;br /&gt;
                 aparam : {}&lt;br /&gt;
        } // Attributes are the parameters sent when the $PAGE-&amp;gt;requires-&amp;gt;yui_module calls the module. &lt;br /&gt;
          // Here you can declare default values or run functions on the parameter. &lt;br /&gt;
          // The param names must be the same as the ones declared &lt;br /&gt;
          // in the $PAGE-&amp;gt;requires-&amp;gt;yui_module call.&lt;br /&gt;
    });&lt;br /&gt;
    M.local_pluginname = M.local_pluginname || {}; // This line use existing name path if it exists, ortherwise create a new one. &lt;br /&gt;
                                                 // This is to avoid to overwrite previously loaded module with same name.&lt;br /&gt;
    M.local_pluginname.init_modulename = function(config) { // &#039;config&#039; contains the parameter values&lt;br /&gt;
        alert(&#039;I am in the javascript module, Yeah!&#039;);&lt;br /&gt;
        return new MODULENAME(config); // &#039;config&#039; contains the parameter values&lt;br /&gt;
    }&lt;br /&gt;
  }, &#039;@VERSION@&#039;, {&lt;br /&gt;
      requires:[&#039;base&#039;,&#039;another_required_YUI_module&#039;, &#039;a_moodle_YUI_module&#039;]&lt;br /&gt;
  });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
3. Call the javascript in PHP. Again, it is best to do this in a renderer class. (if you copied the previous javascript, 2 javascript alert should appear.)&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
  $this-&amp;gt;page-&amp;gt;requires-&amp;gt;yui_module(&#039;moodle-local_pluginname-modulename&#039;, &#039;M.local_pluginname.init_modulename&#039;,&lt;br /&gt;
                array(array(&#039;aparam&#039;=&amp;gt;&#039;paramvalue&#039;)));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
== Full simple example==&lt;br /&gt;
Once you understand and run the above quick start, here is simple YUI 3 example. It shows how to use another YUI 3 module in your module, and to use some events.&lt;br /&gt;
=== It includes===&lt;br /&gt;
* display a parameter value in two javascript alert boxes =&amp;gt; demonstrate how to pass a param to the initialize function in two different ways&lt;br /&gt;
* display an overlay when you click on an image&lt;br /&gt;
* hide the overlay when you click on the body&lt;br /&gt;
* some commented code to see how Moodle YUI exception works&lt;br /&gt;
&lt;br /&gt;
=== PHP ===&lt;br /&gt;
Create a [https://docs.moodle.org/en/Development:Local_customisation basic local plugin] (in this example it is named hub) in /local/hub/ and add this code into one of the plugin pages:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
   $PAGE-&amp;gt;requires-&amp;gt;yui_module(&#039;moodle-local_hub-comments&#039;, &#039;M.local_hub.init_comments&#039;,&lt;br /&gt;
                array(array(&#039;commentids&#039; =&amp;gt; &#039;1 , 23 ,45&#039;)));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== HTML ===&lt;br /&gt;
The plugin page should generate this HTML code:&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;!-- image to click on --&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;comments&amp;quot;&amp;gt;&amp;lt;img src=&#039;http://moodle.org/theme/moodle2/pix/moodle-logo.gif&#039; alt=&#039;the image to click on&#039;/&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- overlay --&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;commentoverlay&amp;quot; class=&amp;quot;yui3-overlay-loading&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;yui3-widget-hd&amp;quot;&amp;gt;Comment&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;yui3-widget-bd&amp;quot;&amp;gt;this is a comment&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;yui3-widget-bd&amp;quot;&amp;gt;this is another comment&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;
=== CSS ===&lt;br /&gt;
The plugin style.css should contain:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/* Hide overlay markup while loading, if js is enabled */&lt;br /&gt;
.yui3-js-enabled .yui3-overlay-loading {&lt;br /&gt;
    top:-1000em;&lt;br /&gt;
    left:-1000em;&lt;br /&gt;
    position:absolute;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Overlay Look/Feel */&lt;br /&gt;
.yui3-overlay-content {&lt;br /&gt;
    padding:3px;&lt;br /&gt;
    border:1px solid #000;&lt;br /&gt;
    background-color:#aaa;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.yui3-overlay-content .yui3-widget-hd {&lt;br /&gt;
    padding:5px;&lt;br /&gt;
    border:2px solid #aa0000;&lt;br /&gt;
    background-color:#fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.yui3-overlay-content .yui3-widget-bd {&lt;br /&gt;
    padding:5px;&lt;br /&gt;
    border:2px solid #0000aa;&lt;br /&gt;
    background-color:#fff;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== JS ===&lt;br /&gt;
In /local/hub/yui/comments/comments.js&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
YUI.add(&#039;moodle-local_hub-comments&#039;, function(Y) {&lt;br /&gt;
&lt;br /&gt;
    var COMMENTSNAME = &#039;hub_comments&#039;;&lt;br /&gt;
&lt;br /&gt;
    //we declare the overlay here so it&#039;s accessible to all the extended class function&#039;&lt;br /&gt;
    var overlay = new Y.Overlay({&lt;br /&gt;
                srcNode:&amp;quot;#commentoverlay&amp;quot;, //the main div with id = commentoverlay&lt;br /&gt;
                width:&amp;quot;10em&amp;quot;,&lt;br /&gt;
                height:&amp;quot;10em&amp;quot;,&lt;br /&gt;
                xy:[ 0, 0],&lt;br /&gt;
                visible: false //by default it is not displayed&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
    var COMMENTS = function() {&lt;br /&gt;
        COMMENTS.superclass.constructor.apply(this, arguments);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Y.extend(COMMENTS, Y.Base, {&lt;br /&gt;
&lt;br /&gt;
        event:null,&lt;br /&gt;
&lt;br /&gt;
        initializer : function(params) {&lt;br /&gt;
&lt;br /&gt;
            //Example how to retrieve the parameter,&lt;br /&gt;
            //see what happens if you don&#039;t pass the parameter in the call&lt;br /&gt;
            alert(this.get(&#039;commentids&#039;)); // You usually use an attribute because&lt;br /&gt;
                                           //a attribut can have default value.&lt;br /&gt;
                                           //use the ATTRS default value if not passed as parameter&lt;br /&gt;
            alert(params.commentids); // undefined if not passed as parameter&lt;br /&gt;
&lt;br /&gt;
            //render the overlay&lt;br /&gt;
            overlay.render();&lt;br /&gt;
&lt;br /&gt;
            // position the overlay in the middle of the web browser window&lt;br /&gt;
            var WidgetPositionAlign = Y.WidgetPositionAlign;&lt;br /&gt;
            overlay.set(&amp;quot;align&amp;quot;, {&lt;br /&gt;
                node:&amp;quot;&amp;quot;, //empty =&amp;gt; viewport&lt;br /&gt;
                points:[WidgetPositionAlign.CC, WidgetPositionAlign.CC]&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            //attach a show event on the div with id = comments&lt;br /&gt;
            //we also change the div style to display the click zone&lt;br /&gt;
            Y.one(&#039;#comments&#039;).setStyle(&amp;quot;border&amp;quot;, &amp;quot;1px solid red&amp;quot;).on(&#039;click&#039;, this.show, this);&lt;br /&gt;
&lt;br /&gt;
            //uncomment the try content to see how works exception in Moodle&lt;br /&gt;
            //this exception has been specially created for Moodle&lt;br /&gt;
            try {&lt;br /&gt;
              //surely_not_existing_js_function();&lt;br /&gt;
            } catch (exception) {&lt;br /&gt;
                new M.core.exception(exception);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        show : function (e) {&lt;br /&gt;
            overlay.show(); //show the overlay&lt;br /&gt;
           &lt;br /&gt;
            e.halt(); // we are going to attach a new &#039;hide overlay&#039; event to the body,&lt;br /&gt;
                      // because javascript always propagate event to parent tag,&lt;br /&gt;
                      // we need to tell Yahoo to stop to call the event on parent tag&lt;br /&gt;
                      // otherwise the hide event will be call right away.&lt;br /&gt;
&lt;br /&gt;
            //we add a new event on the body in order to hide the overlay for the next click&lt;br /&gt;
            this.event = Y.one(document.body).on(&#039;click&#039;,this.hide,this);&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        hide : function () {&lt;br /&gt;
            overlay.hide(); //hide the overlay&lt;br /&gt;
            this.event.detach(); //we need to detach the hide event&lt;br /&gt;
                                 //Note: it would work without but create js warning everytime&lt;br /&gt;
                                 //we click on the body&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }, {&lt;br /&gt;
        NAME : COMMENTSNAME,&lt;br /&gt;
        ATTRS : {&lt;br /&gt;
            commentids: {value : 450} //default value (has no purpose in this code except to show you&lt;br /&gt;
                                      // how to pass/use a param value)&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    M.local_hub = M.local_hub || {};&lt;br /&gt;
    M.local_hub.init_comments = function(params) {&lt;br /&gt;
        return new COMMENTS(params);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}, &#039;@VERSION@&#039;, {&lt;br /&gt;
    requires:[&#039;base&#039;,&#039;overlay&#039;, &#039;moodle-enrol-notification&#039;]&lt;br /&gt;
    //Note: &#039;moodle-enrol-notification&#039; contains Moodle YUI exception&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Where are my methods in the IDE?==&lt;br /&gt;
Some (all?) IDEs will fail to parse the above structure correctly and will not show you your methods in the structure/navigator pane. If this happens, use JSDoc format to mark the Y.extend() line as being a particular class:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
     /**&lt;br /&gt;
      * @class M.local_hub.init_comments&lt;br /&gt;
      */&lt;br /&gt;
    Y.extend(COMMENTS, Y.Base, {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This depends to a certain extent on how you choose to instantiate your objects. The above init_widget() method can be replaced with a more class based method like a lot of the YUI library uses.&lt;br /&gt;
&lt;br /&gt;
= What else to read =&lt;br /&gt;
Two pages are important to start with when you discover YUI 3&lt;br /&gt;
* you should read the [http://developer.yahoo.com/yui/3/base/ base YUI doc]. It is very useful to understand the YUI 3 Moodle module.&lt;br /&gt;
* you want to have a look to the [http://developer.yahoo.com/yui/3/examples/ YUI 3 examples]. Always open the examples in a window to have a look to the complete example codes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:AJAX]]&lt;br /&gt;
[[Category:Javascript]]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[Javascript and YUI 3 FAQ]]&lt;br /&gt;
* [[JavaScript FAQ]]&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=How_to_create_a_YUI_3_module&amp;diff=34276</id>
		<title>How to create a YUI 3 module</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=How_to_create_a_YUI_3_module&amp;diff=34276"/>
		<updated>2012-06-25T11:02:13Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* Full simple example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}This document explains how to create a YUI 3 module in Moodle.&lt;br /&gt;
&lt;br /&gt;
= The two ways to write a YUI 3 module =&lt;br /&gt;
There is two ways to write a YUI 3 module. The two following paragraphs are sourced from a chat with Sam Hemelryk.&lt;br /&gt;
==The static module==&lt;br /&gt;
The static module is the simpler of the two, in this case you simply put your code into a module.js file within your plugin. Into that file you create a namespace and define any functions or objects you want to use.&lt;br /&gt;
&lt;br /&gt;
Within PHP static modules are also pretty easy to use. The first step if to create a module definition which tells moodle what your module is called, what it requires, and can optionally give it strings.&lt;br /&gt;
&lt;br /&gt;
Once the module is defined you can then use any of the several JS methods for including JS in your page and pass your module definition along.&lt;br /&gt;
&lt;br /&gt;
Whilst this method is simpler to write and understand especially when you are first starting out with JavaScript it isn&#039;t as easily flexible and has some quirks that you need will need to overcome, especially with more complex JavaScript.&lt;br /&gt;
&lt;br /&gt;
This method of writing a module should be used if you are just starting out with JavaScript or if the JS solution you are creating is going to be relatively simple in nature.&lt;br /&gt;
If you are writing something more complex I would strongly suggest looking at the other method as it will result in cleaner, easier to read code at the end of the day. However it will require you to learn your way around writing a Moodle module.&lt;br /&gt;
&lt;br /&gt;
==The YUI3 Moodle Module==&lt;br /&gt;
This method is certainly more complex than the previous method however it is much more flexible and when you have learnt and understand what you are doing it is much quicker to write and more versatile as well. These modules can also easily include other YUI3 Moodle modules, and can choose to include module specific CSS as well.&lt;br /&gt;
&lt;br /&gt;
In this method you create a &#039;&#039;&#039;yui&#039;&#039;&#039; directory within you plugin directory, and then sub directories for each module you wish to write, you name them the same as you want your module named.&lt;br /&gt;
Into the subdirectory you create a JavaScript file with the same name that you gave the subdirectory, e.g.&#039;&#039;&#039;/local/myplugin/yui/mymodule/mymodule.js&#039;&#039;&#039;&lt;br /&gt;
The JS that you then put into this file should then be written in the same way you would write a YUI module, before you ask it certainly requires a good understanding of YUI.&lt;br /&gt;
&lt;br /&gt;
I would recommend this method of writing a module providing you either have an understanding of how to write a YUI module, or you are happy to learn. It normally results in cleaner easier to read code, and if desired can easily be written in such as way as to make it VERY easy to re-use in other bits of code.... particularly helpful if you have several JavaScript objects in play at a time.&lt;br /&gt;
&lt;br /&gt;
= Static module quick start = &lt;br /&gt;
1. Create a module.js file somewhere &lt;br /&gt;
&lt;br /&gt;
2. The two ways Moodle can load this file are:&lt;br /&gt;
&lt;br /&gt;
a- the file is in core: declare the file into /lib/outputrequirementslib.php/find_module($component)&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
          //example:&lt;br /&gt;
          case &#039;core_rating&#039;:&lt;br /&gt;
                    $module = array(&#039;name&#039;     =&amp;gt; &#039;core_rating&#039;,&lt;br /&gt;
                                    &#039;fullpath&#039; =&amp;gt; &#039;/rating/module.js&#039;,&lt;br /&gt;
                                    &#039;requires&#039; =&amp;gt; array(&#039;node&#039;, &#039;event&#039;, &#039;overlay&#039;, &#039;io&#039;, &#039;json&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
b- the file is in a local plugin: the first line of your module should be&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
 M.local_xxx = {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
xxx being your plugin directory name.&lt;br /&gt;
&lt;br /&gt;
3. Write the module.js&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
  M.local_hub={&lt;br /&gt;
    Y : null,&lt;br /&gt;
    transaction : [],&lt;br /&gt;
    init : function(Y){&lt;br /&gt;
        alert(&#039;hub module initialisation&#039;);&lt;br /&gt;
        this.Y = Y;&lt;br /&gt;
    },&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
4. Call this module. The best place to do this is in your renderer class (since, if a theme overrides the renderer to change the HTML, they may also need to use different JavaScript.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $this-&amp;gt;page-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.local_hub.init&#039;); &lt;br /&gt;
You should now have loaded and called your first YUI 3 module in Moodle.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
5. If you want to load your module with some other YUI modules&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $jsmodule = array(&lt;br /&gt;
                &#039;name&#039; =&amp;gt; &#039;local_hub&#039;,&lt;br /&gt;
                &#039;fullpath&#039; =&amp;gt; &#039;/local/hub/module.js&#039;,&lt;br /&gt;
                &#039;requires&#039; =&amp;gt; array(&amp;quot;overlay&amp;quot;, &amp;quot;anim&amp;quot;, &amp;quot;plugin&amp;quot;)); //on this line you are loading three other YUI modules&lt;br /&gt;
   $this-&amp;gt;page-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.local_hub.init&#039;,&lt;br /&gt;
                 null, false, $jsmodule);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
6. If you want to pass parameter to the init function&lt;br /&gt;
&lt;br /&gt;
PHP:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $this-&amp;gt;page-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.local_hub.init&#039;,&lt;br /&gt;
                    array(&#039;this is the param1 value&#039;), false, $jsmodule);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
JS:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
    init : function(Y, params){&lt;br /&gt;
        alert(params);&lt;br /&gt;
        ....&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
7. Then you should be able to fill the module with your own YUI javascript from [http://developer.yahoo.com/yui/3/examples/ YUI examples].&lt;br /&gt;
&lt;br /&gt;
= YUI 3 Moodle Module quick start =&lt;br /&gt;
1. Create the module_name.js file in /local/pluginname/yui/module_name/modulename.js or in /mod/modname/yui/modulename/modulename.js&lt;br /&gt;
&lt;br /&gt;
2. The basic module_name.js structure is:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
  YUI.add(&#039;moodle-local_pluginname-modulename&#039;, function(Y) {&lt;br /&gt;
    var ModulenameNAME = &#039;this_is_a_module_name&#039;;&lt;br /&gt;
    var MODULENAME = function() {&lt;br /&gt;
        MODULENAME.superclass.constructor.apply(this, arguments);&lt;br /&gt;
    };&lt;br /&gt;
    Y.extend(MODULENAME, Y.Base, {&lt;br /&gt;
        initializer : function(config) { // &#039;config&#039; contains the parameter values&lt;br /&gt;
            alert(&#039;I am in initializer&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    }, {&lt;br /&gt;
        NAME : ModulenameNAME, //module name is something mandatory. &lt;br /&gt;
                                // It should be in lower case without space &lt;br /&gt;
                                // as YUI use it for name space sometimes.&lt;br /&gt;
        ATTRS : {&lt;br /&gt;
                 aparam : {}&lt;br /&gt;
        } // Attributes are the parameters sent when the $PAGE-&amp;gt;requires-&amp;gt;yui_module calls the module. &lt;br /&gt;
          // Here you can declare default values or run functions on the parameter. &lt;br /&gt;
          // The param names must be the same as the ones declared &lt;br /&gt;
          // in the $PAGE-&amp;gt;requires-&amp;gt;yui_module call.&lt;br /&gt;
    });&lt;br /&gt;
    M.local_pluginname = M.local_pluginname || {}; // This line use existing name path if it exists, ortherwise create a new one. &lt;br /&gt;
                                                 // This is to avoid to overwrite previously loaded module with same name.&lt;br /&gt;
    M.local_pluginname.init_modulename = function(config) { // &#039;config&#039; contains the parameter values&lt;br /&gt;
        alert(&#039;I am in the javascript module, Yeah!&#039;);&lt;br /&gt;
        return new MODULENAME(config); // &#039;config&#039; contains the parameter values&lt;br /&gt;
    }&lt;br /&gt;
  }, &#039;@VERSION@&#039;, {&lt;br /&gt;
      requires:[&#039;base&#039;,&#039;another_required_YUI_module&#039;, &#039;a_moodle_YUI_module&#039;]&lt;br /&gt;
  });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
3. Call the javascript in PHP. Again, it is best to do this in a renderer class. (if you copied the previous javascript, 2 javascript alert should appear.)&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
  $this-&amp;gt;page-&amp;gt;requires-&amp;gt;yui_module(&#039;moodle-local_pluginname-modulename&#039;, &#039;M.local_pluginname.init_modulename&#039;,&lt;br /&gt;
                array(array(&#039;aparam&#039;=&amp;gt;&#039;paramvalue&#039;)));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
== Full simple example==&lt;br /&gt;
Once you understand and run the above quick start, here is simple YUI 3 example. It shows how to use another YUI 3 module in your module, and to use some events.&lt;br /&gt;
=== It includes===&lt;br /&gt;
* display a parameter value in two javascript alert boxes =&amp;gt; demonstrate how to pass a param to the initialize function in two different ways&lt;br /&gt;
* display an overlay when you click on an image&lt;br /&gt;
* hide the overlay when you click on the body&lt;br /&gt;
* some commented code to see how Moodle YUI exception works&lt;br /&gt;
&lt;br /&gt;
=== PHP ===&lt;br /&gt;
Create a [https://docs.moodle.org/en/Development:Local_customisation basic local plugin] (in this example it is named hub) in /local/hub/ and add this code into one of the plugin pages:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
   $PAGE-&amp;gt;requires-&amp;gt;yui_module(&#039;moodle-local_hub-comments&#039;, &#039;M.local_hub.init_comments&#039;,&lt;br /&gt;
                array(array(&#039;commentids&#039; =&amp;gt; &#039;1 , 23 ,45&#039;)));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== HTML ===&lt;br /&gt;
The plugin page should generate this HTML code:&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;!-- image to click on --&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;comments&amp;quot;&amp;gt;&amp;lt;img src=&#039;http://moodle.org/theme/moodle2/pix/moodle-logo.gif&#039; alt=&#039;the image to click on&#039;/&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- overlay --&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;commentoverlay&amp;quot; class=&amp;quot;yui3-overlay-loading&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;yui3-widget-hd&amp;quot;&amp;gt;Comment&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;yui3-widget-bd&amp;quot;&amp;gt;this is a comment&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;yui3-widget-bd&amp;quot;&amp;gt;this is another comment&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;
=== CSS ===&lt;br /&gt;
The plugin style.css should contain:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/* Hide overlay markup while loading, if js is enabled */&lt;br /&gt;
.yui3-js-enabled .yui3-overlay-loading {&lt;br /&gt;
    top:-1000em;&lt;br /&gt;
    left:-1000em;&lt;br /&gt;
    position:absolute;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Overlay Look/Feel */&lt;br /&gt;
.yui3-overlay-content {&lt;br /&gt;
    padding:3px;&lt;br /&gt;
    border:1px solid #000;&lt;br /&gt;
    background-color:#aaa;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.yui3-overlay-content .yui3-widget-hd {&lt;br /&gt;
    padding:5px;&lt;br /&gt;
    border:2px solid #aa0000;&lt;br /&gt;
    background-color:#fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.yui3-overlay-content .yui3-widget-bd {&lt;br /&gt;
    padding:5px;&lt;br /&gt;
    border:2px solid #0000aa;&lt;br /&gt;
    background-color:#fff;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== JS ===&lt;br /&gt;
In /local/hub/yui/comments/comments.js&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
YUI.add(&#039;moodle-local_hub-comments&#039;, function(Y) {&lt;br /&gt;
&lt;br /&gt;
    var COMMENTSNAME = &#039;hub_comments&#039;;&lt;br /&gt;
&lt;br /&gt;
    //we declare the overlay here so it&#039;s accessible to all the extended class function&#039;&lt;br /&gt;
    var overlay = new Y.Overlay({&lt;br /&gt;
                srcNode:&amp;quot;#commentoverlay&amp;quot;, //the main div with id = commentoverlay&lt;br /&gt;
                width:&amp;quot;10em&amp;quot;,&lt;br /&gt;
                height:&amp;quot;10em&amp;quot;,&lt;br /&gt;
                xy:[ 0, 0],&lt;br /&gt;
                visible: false //by default it is not displayed&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
    var COMMENTS = function() {&lt;br /&gt;
        COMMENTS.superclass.constructor.apply(this, arguments);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Y.extend(COMMENTS, Y.Base, {&lt;br /&gt;
&lt;br /&gt;
        event:null,&lt;br /&gt;
&lt;br /&gt;
        initializer : function(params) {&lt;br /&gt;
&lt;br /&gt;
            //Example how to retrieve the parameter,&lt;br /&gt;
            //see what happens if you don&#039;t pass the parameter in the call&lt;br /&gt;
            alert(this.get(&#039;commentids&#039;)); // You usually use an attribute because&lt;br /&gt;
                                           //a attribut can have default value.&lt;br /&gt;
                                           //use the ATTRS default value if not passed as parameter&lt;br /&gt;
            alert(params.commentids); // undefined if not passed as parameter&lt;br /&gt;
&lt;br /&gt;
            //render the overlay&lt;br /&gt;
            overlay.render();&lt;br /&gt;
&lt;br /&gt;
            // position the overlay in the middle of the web browser window&lt;br /&gt;
            var WidgetPositionAlign = Y.WidgetPositionAlign;&lt;br /&gt;
            overlay.set(&amp;quot;align&amp;quot;, {&lt;br /&gt;
                node:&amp;quot;&amp;quot;, //empty =&amp;gt; viewport&lt;br /&gt;
                points:[WidgetPositionAlign.CC, WidgetPositionAlign.CC]&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            //attach a show event on the div with id = comments&lt;br /&gt;
            //we also change the div style to display the click zone&lt;br /&gt;
            Y.one(&#039;#comments&#039;).setStyle(&amp;quot;border&amp;quot;, &amp;quot;1px solid red&amp;quot;).on(&#039;click&#039;, this.show, this);&lt;br /&gt;
&lt;br /&gt;
            //uncomment the try content to see how works exception in Moodle&lt;br /&gt;
            //this exception has been specially created for Moodle&lt;br /&gt;
            try {&lt;br /&gt;
              //surely_not_existing_js_function();&lt;br /&gt;
            } catch (exception) {&lt;br /&gt;
                new M.core.exception(exception);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        show : function (e) {&lt;br /&gt;
            overlay.show(); //show the overlay&lt;br /&gt;
           &lt;br /&gt;
            e.halt(); // we are going to attach a new &#039;hide overlay&#039; event to the body,&lt;br /&gt;
                      // because javascript always propagate event to parent tag,&lt;br /&gt;
                      // we need to tell Yahoo to stop to call the event on parent tag&lt;br /&gt;
                      // otherwise the hide event will be call right away.&lt;br /&gt;
&lt;br /&gt;
            //we add a new event on the body in order to hide the overlay for the next click&lt;br /&gt;
            this.event = Y.one(document.body).on(&#039;click&#039;,this.hide,this);&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        hide : function () {&lt;br /&gt;
            overlay.hide(); //hide the overlay&lt;br /&gt;
            this.event.detach(); //we need to detach the hide event&lt;br /&gt;
                                 //Note: it would work without but create js warning everytime&lt;br /&gt;
                                 //we click on the body&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }, {&lt;br /&gt;
        NAME : COMMENTSNAME,&lt;br /&gt;
        ATTRS : {&lt;br /&gt;
            commentids: {value : 450} //default value (has no purpose in this code except to show you&lt;br /&gt;
                                      // how to pass/use a param value)&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    M.local_hub = M.local_hub || {};&lt;br /&gt;
    M.local_hub.init_comments = function(params) {&lt;br /&gt;
        return new COMMENTS(params);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}, &#039;@VERSION@&#039;, {&lt;br /&gt;
    requires:[&#039;base&#039;,&#039;overlay&#039;, &#039;moodle-enrol-notification&#039;]&lt;br /&gt;
    //Note: &#039;moodle-enrol-notification&#039; contains Moodle YUI exception&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Where are my methods in the IDE?==&lt;br /&gt;
Some (all?) IDEs will fail to parse the above structure correctly and will not show you your methods in the structure/navigator pane. If this happens, use JSDoc format to mark the Y.extend() line as being a particular class:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
    /**&lt;br /&gt;
     * @class M.local_hub.init_comments&lt;br /&gt;
     */&lt;br /&gt;
    Y.extend(COMMENTS, Y.Base, {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This depends to a certain extent on how you choose to instantiate your objects. The above init_widget() method can be replaced with a more class based method like a lot of the YUI library uses.&lt;br /&gt;
&lt;br /&gt;
= What else to read =&lt;br /&gt;
Two pages are important to start with when you discover YUI 3&lt;br /&gt;
* you should read the [http://developer.yahoo.com/yui/3/base/ base YUI doc]. It is very useful to understand the YUI 3 Moodle module.&lt;br /&gt;
* you want to have a look to the [http://developer.yahoo.com/yui/3/examples/ YUI 3 examples]. Always open the examples in a window to have a look to the complete example codes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:AJAX]]&lt;br /&gt;
[[Category:Javascript]]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[Javascript and YUI 3 FAQ]]&lt;br /&gt;
* [[JavaScript FAQ]]&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=How_to_create_a_YUI_3_module&amp;diff=34176</id>
		<title>How to create a YUI 3 module</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=How_to_create_a_YUI_3_module&amp;diff=34176"/>
		<updated>2012-06-10T16:41:07Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* YUI 3 Moodle Module quick start */ Comments typo and spacing&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}This document explains how to create a YUI 3 module in Moodle.&lt;br /&gt;
&lt;br /&gt;
= The two ways to write a YUI 3 module =&lt;br /&gt;
There is two ways to write a YUI 3 module. The two following paragraphs are sourced from a chat with Sam Hemelryk.&lt;br /&gt;
==The static module==&lt;br /&gt;
The static module is the simpler of the two, in this case you simply put your code into a module.js file within your plugin. Into that file you create a namespace and define any functions or objects you want to use.&lt;br /&gt;
&lt;br /&gt;
Within PHP static modules are also pretty easy to use. The first step if to create a module definition which tells moodle what your module is called, what it requires, and can optionally give it strings.&lt;br /&gt;
&lt;br /&gt;
Once the module is defined you can then use any of the several JS methods for including JS in your page and pass your module definition along.&lt;br /&gt;
&lt;br /&gt;
Whilst this method is simpler to write and understand especially when you are first starting out with JavaScript it isn&#039;t as easily flexible and has some quirks that you need will need to overcome, especially with more complex JavaScript.&lt;br /&gt;
&lt;br /&gt;
This method of writing a module should be used if you are just starting out with JavaScript or if the JS solution you are creating is going to be relatively simple in nature.&lt;br /&gt;
If you are writing something more complex I would strongly suggest looking at the other method as it will result in cleaner, easier to read code at the end of the day. However it will require you to learn your way around writing a Moodle module.&lt;br /&gt;
&lt;br /&gt;
==The YUI3 Moodle Module==&lt;br /&gt;
This method is certainly more complex than the previous method however it is much more flexible and when you have learnt and understand what you are doing it is much quicker to write and more versatile as well. These modules can also easily include other YUI3 Moodle modules, and can choose to include module specific CSS as well.&lt;br /&gt;
&lt;br /&gt;
In this method you create a &#039;&#039;&#039;yui&#039;&#039;&#039; directory within you plugin directory, and then sub directories for each module you wish to write, you name them the same as you want your module named.&lt;br /&gt;
Into the subdirectory you create a JavaScript file with the same name that you gave the subdirectory, e.g.&#039;&#039;&#039;/local/myplugin/yui/mymodule/mymodule.js&#039;&#039;&#039;&lt;br /&gt;
The JS that you then put into this file should then be written in the same way you would write a YUI module, before you ask it certainly requires a good understanding of YUI.&lt;br /&gt;
&lt;br /&gt;
I would recommend this method of writing a module providing you either have an understanding of how to write a YUI module, or you are happy to learn. It normally results in cleaner easier to read code, and if desired can easily be written in such as way as to make it VERY easy to re-use in other bits of code.... particularly helpful if you have several JavaScript objects in play at a time.&lt;br /&gt;
&lt;br /&gt;
= Static module quick start = &lt;br /&gt;
1. Create a module.js file somewhere &lt;br /&gt;
&lt;br /&gt;
2. The two ways Moodle can load this file are:&lt;br /&gt;
&lt;br /&gt;
a- the file is in core: declare the file into /lib/outputrequirementslib.php/find_module($component)&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
          //example:&lt;br /&gt;
          case &#039;core_rating&#039;:&lt;br /&gt;
                    $module = array(&#039;name&#039;     =&amp;gt; &#039;core_rating&#039;,&lt;br /&gt;
                                    &#039;fullpath&#039; =&amp;gt; &#039;/rating/module.js&#039;,&lt;br /&gt;
                                    &#039;requires&#039; =&amp;gt; array(&#039;node&#039;, &#039;event&#039;, &#039;overlay&#039;, &#039;io&#039;, &#039;json&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
b- the file is in a local plugin: the first line of your module should be&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
 M.local_xxx = {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
xxx being your plugin directory name.&lt;br /&gt;
&lt;br /&gt;
3. Write the module.js&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
  M.local_hub={&lt;br /&gt;
    Y : null,&lt;br /&gt;
    transaction : [],&lt;br /&gt;
    init : function(Y){&lt;br /&gt;
        alert(&#039;hub module initialisation&#039;);&lt;br /&gt;
        this.Y = Y;&lt;br /&gt;
    },&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
4. Call this module. The best place to do this is in your renderer class (since, if a theme overrides the renderer to change the HTML, they may also need to use different JavaScript.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $this-&amp;gt;page-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.local_hub.init&#039;); &lt;br /&gt;
You should now have loaded and called your first YUI 3 module in Moodle.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
5. If you want to load your module with some other YUI modules&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $jsmodule = array(&lt;br /&gt;
                &#039;name&#039; =&amp;gt; &#039;local_hub&#039;,&lt;br /&gt;
                &#039;fullpath&#039; =&amp;gt; &#039;/local/hub/module.js&#039;,&lt;br /&gt;
                &#039;requires&#039; =&amp;gt; array(&amp;quot;overlay&amp;quot;, &amp;quot;anim&amp;quot;, &amp;quot;plugin&amp;quot;)); //on this line you are loading three other YUI modules&lt;br /&gt;
   $this-&amp;gt;page-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.local_hub.init&#039;,&lt;br /&gt;
                 null, false, $jsmodule);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
6. If you want to pass parameter to the init function&lt;br /&gt;
&lt;br /&gt;
PHP:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $this-&amp;gt;page-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.local_hub.init&#039;,&lt;br /&gt;
                    array(&#039;this is the param1 value&#039;), false, $jsmodule);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
JS:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
    init : function(Y, params){&lt;br /&gt;
        alert(params);&lt;br /&gt;
        ....&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
7. Then you should be able to fill the module with your own YUI javascript from [http://developer.yahoo.com/yui/3/examples/ YUI examples].&lt;br /&gt;
&lt;br /&gt;
= YUI 3 Moodle Module quick start =&lt;br /&gt;
1. Create the module_name.js file in /local/pluginname/yui/module_name/modulename.js or in /mod/modname/yui/modulename/modulename.js&lt;br /&gt;
&lt;br /&gt;
2. The basic module_name.js structure is:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
  YUI.add(&#039;moodle-local_pluginname-modulename&#039;, function(Y) {&lt;br /&gt;
    var ModulenameNAME = &#039;this_is_a_module_name&#039;;&lt;br /&gt;
    var MODULENAME = function() {&lt;br /&gt;
        MODULENAME.superclass.constructor.apply(this, arguments);&lt;br /&gt;
    };&lt;br /&gt;
    Y.extend(MODULENAME, Y.Base, {&lt;br /&gt;
        initializer : function(config) { // &#039;config&#039; contains the parameter values&lt;br /&gt;
            alert(&#039;I am in initializer&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    }, {&lt;br /&gt;
        NAME : ModulenameNAME, //module name is something mandatory. &lt;br /&gt;
                                // It should be in lower case without space &lt;br /&gt;
                                // as YUI use it for name space sometimes.&lt;br /&gt;
        ATTRS : {&lt;br /&gt;
                 aparam : {}&lt;br /&gt;
        } // Attributes are the parameters sent when the $PAGE-&amp;gt;requires-&amp;gt;yui_module calls the module. &lt;br /&gt;
          // Here you can declare default values or run functions on the parameter. &lt;br /&gt;
          // The param names must be the same as the ones declared &lt;br /&gt;
          // in the $PAGE-&amp;gt;requires-&amp;gt;yui_module call.&lt;br /&gt;
    });&lt;br /&gt;
    M.local_pluginname = M.local_pluginname || {}; // This line use existing name path if it exists, ortherwise create a new one. &lt;br /&gt;
                                                 // This is to avoid to overwrite previously loaded module with same name.&lt;br /&gt;
    M.local_pluginname.init_modulename = function(config) { // &#039;config&#039; contains the parameter values&lt;br /&gt;
        alert(&#039;I am in the javascript module, Yeah!&#039;);&lt;br /&gt;
        return new MODULENAME(config); // &#039;config&#039; contains the parameter values&lt;br /&gt;
    }&lt;br /&gt;
  }, &#039;@VERSION@&#039;, {&lt;br /&gt;
      requires:[&#039;base&#039;,&#039;another_required_YUI_module&#039;, &#039;a_moodle_YUI_module&#039;]&lt;br /&gt;
  });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
3. Call the javascript in PHP. Again, it is best to do this in a renderer class. (if you copied the previous javascript, 2 javascript alert should appear.)&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
  $this-&amp;gt;page-&amp;gt;requires-&amp;gt;yui_module(&#039;moodle-local_pluginname-modulename&#039;, &#039;M.local_pluginname.init_modulename&#039;,&lt;br /&gt;
                array(array(&#039;aparam&#039;=&amp;gt;&#039;paramvalue&#039;)));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
== Full simple example==&lt;br /&gt;
Once you understand and run the above quick start, here is simple YUI 3 example. It shows how to use another YUI 3 module in your module, and to use some events.&lt;br /&gt;
=== It includes===&lt;br /&gt;
* display a parameter value in two javascript alert boxes =&amp;gt; demonstrate how to pass a param to the initialize function in two different ways&lt;br /&gt;
* display an overlay when you click on an image&lt;br /&gt;
* hide the overlay when you click on the body&lt;br /&gt;
* some commented code to see how Moodle YUI exception works&lt;br /&gt;
&lt;br /&gt;
=== PHP ===&lt;br /&gt;
Create a [https://docs.moodle.org/en/Development:Local_customisation basic local plugin] (in this example it is named hub) in /local/hub/ and add this code into one of the plugin pages:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
   $PAGE-&amp;gt;requires-&amp;gt;yui_module(&#039;moodle-local_hub-comments&#039;, &#039;M.local_hub.init_comments&#039;,&lt;br /&gt;
                array(array(&#039;commentids&#039; =&amp;gt; &#039;1 , 23 ,45&#039;)));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== HTML ===&lt;br /&gt;
The plugin page should generate this HTML code:&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;!-- image to click on --&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;comments&amp;quot;&amp;gt;&amp;lt;img src=&#039;http://moodle.org/theme/moodle2/pix/moodle-logo.gif&#039; alt=&#039;the image to click on&#039;/&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- overlay --&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;commentoverlay&amp;quot; class=&amp;quot;yui3-overlay-loading&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;yui3-widget-hd&amp;quot;&amp;gt;Comment&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;yui3-widget-bd&amp;quot;&amp;gt;this is a comment&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;yui3-widget-bd&amp;quot;&amp;gt;this is another comment&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;
=== CSS ===&lt;br /&gt;
The plugin style.css should contain:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/* Hide overlay markup while loading, if js is enabled */&lt;br /&gt;
.yui3-js-enabled .yui3-overlay-loading {&lt;br /&gt;
    top:-1000em;&lt;br /&gt;
    left:-1000em;&lt;br /&gt;
    position:absolute;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Overlay Look/Feel */&lt;br /&gt;
.yui3-overlay-content {&lt;br /&gt;
    padding:3px;&lt;br /&gt;
    border:1px solid #000;&lt;br /&gt;
    background-color:#aaa;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.yui3-overlay-content .yui3-widget-hd {&lt;br /&gt;
    padding:5px;&lt;br /&gt;
    border:2px solid #aa0000;&lt;br /&gt;
    background-color:#fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.yui3-overlay-content .yui3-widget-bd {&lt;br /&gt;
    padding:5px;&lt;br /&gt;
    border:2px solid #0000aa;&lt;br /&gt;
    background-color:#fff;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== JS ===&lt;br /&gt;
In /local/hub/yui/comments/comments.js&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
YUI.add(&#039;moodle-local_hub-comments&#039;, function(Y) {&lt;br /&gt;
&lt;br /&gt;
    var COMMENTSNAME = &#039;hub_comments&#039;;&lt;br /&gt;
&lt;br /&gt;
    //we declare the overlay here so it&#039;s accessible to all the extended class function&#039;&lt;br /&gt;
    var overlay = new Y.Overlay({&lt;br /&gt;
                srcNode:&amp;quot;#commentoverlay&amp;quot;, //the main div with id = commentoverlay&lt;br /&gt;
                width:&amp;quot;10em&amp;quot;,&lt;br /&gt;
                height:&amp;quot;10em&amp;quot;,&lt;br /&gt;
                xy:[ 0, 0],&lt;br /&gt;
                visible: false //by default it is not displayed&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
    var COMMENTS = function() {&lt;br /&gt;
        COMMENTS.superclass.constructor.apply(this, arguments);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Y.extend(COMMENTS, Y.Base, {&lt;br /&gt;
&lt;br /&gt;
        event:null,&lt;br /&gt;
&lt;br /&gt;
        initializer : function(params) {&lt;br /&gt;
&lt;br /&gt;
            //Example how to retrieve the parameter,&lt;br /&gt;
            //see what happens if you don&#039;t pass the parameter in the call&lt;br /&gt;
            alert(this.get(&#039;commentids&#039;)); // You usually use an attribute because&lt;br /&gt;
                                           //a attribut can have default value.&lt;br /&gt;
                                           //use the ATTRS default value if not passed as parameter&lt;br /&gt;
            alert(params.commentids); // undefined if not passed as parameter&lt;br /&gt;
&lt;br /&gt;
            //render the overlay&lt;br /&gt;
            overlay.render();&lt;br /&gt;
&lt;br /&gt;
            // position the overlay in the middle of the web browser window&lt;br /&gt;
            var WidgetPositionAlign = Y.WidgetPositionAlign;&lt;br /&gt;
            overlay.set(&amp;quot;align&amp;quot;, {&lt;br /&gt;
                node:&amp;quot;&amp;quot;, //empty =&amp;gt; viewport&lt;br /&gt;
                points:[WidgetPositionAlign.CC, WidgetPositionAlign.CC]&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            //attach a show event on the div with id = comments&lt;br /&gt;
            //we also change the div style to display the click zone&lt;br /&gt;
            Y.one(&#039;#comments&#039;).setStyle(&amp;quot;border&amp;quot;, &amp;quot;1px solid red&amp;quot;).on(&#039;click&#039;, this.show, this);&lt;br /&gt;
&lt;br /&gt;
            //uncomment the try content to see how works exception in Moodle&lt;br /&gt;
            //this exception has been specially created for Moodle&lt;br /&gt;
            try {&lt;br /&gt;
              //surely_not_existing_js_function();&lt;br /&gt;
            } catch (exception) {&lt;br /&gt;
                new M.core.exception(exception);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        show : function (e) {&lt;br /&gt;
            overlay.show(); //show the overlay&lt;br /&gt;
           &lt;br /&gt;
            e.halt(); // we are going to attach a new &#039;hide overlay&#039; event to the body,&lt;br /&gt;
                      // because javascript always propagate event to parent tag,&lt;br /&gt;
                      // we need to tell Yahoo to stop to call the event on parent tag&lt;br /&gt;
                      // otherwise the hide event will be call right away.&lt;br /&gt;
&lt;br /&gt;
            //we add a new event on the body in order to hide the overlay for the next click&lt;br /&gt;
            this.event = Y.one(document.body).on(&#039;click&#039;,this.hide,this);&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        hide : function () {&lt;br /&gt;
            overlay.hide(); //hide the overlay&lt;br /&gt;
            this.event.detach(); //we need to detach the hide event&lt;br /&gt;
                                 //Note: it would work without but create js warning everytime&lt;br /&gt;
                                 //we click on the body&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }, {&lt;br /&gt;
        NAME : COMMENTSNAME,&lt;br /&gt;
        ATTRS : {&lt;br /&gt;
            commentids: {value : 450} //default value (has no purpose in this code except to show you&lt;br /&gt;
                                      // how to pass/use a param value)&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    M.local_hub = M.local_hub || {};&lt;br /&gt;
    M.local_hub.init_comments = function(params) {&lt;br /&gt;
        return new COMMENTS(params);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}, &#039;@VERSION@&#039;, {&lt;br /&gt;
    requires:[&#039;base&#039;,&#039;overlay&#039;, &#039;moodle-enrol-notification&#039;]&lt;br /&gt;
    //Note: &#039;moodle-enrol-notification&#039; contains Moodle YUI exception&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= What else to read =&lt;br /&gt;
Two pages are important to start with when you discover YUI 3&lt;br /&gt;
* you should read the [http://developer.yahoo.com/yui/3/base/ base YUI doc]. It is very useful to understand the YUI 3 Moodle module.&lt;br /&gt;
* you want to have a look to the [http://developer.yahoo.com/yui/3/examples/ YUI 3 examples]. Always open the examples in a window to have a look to the complete example codes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:AJAX]]&lt;br /&gt;
[[Category:Javascript]]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[Javascript and YUI 3 FAQ]]&lt;br /&gt;
* [[JavaScript FAQ]]&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=How_to_create_a_YUI_3_module&amp;diff=34175</id>
		<title>How to create a YUI 3 module</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=How_to_create_a_YUI_3_module&amp;diff=34175"/>
		<updated>2012-06-10T16:29:41Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* YUI 3 Moodle Module quick start */ Missing semicolon&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}This document explains how to create a YUI 3 module in Moodle.&lt;br /&gt;
&lt;br /&gt;
= The two ways to write a YUI 3 module =&lt;br /&gt;
There is two ways to write a YUI 3 module. The two following paragraphs are sourced from a chat with Sam Hemelryk.&lt;br /&gt;
==The static module==&lt;br /&gt;
The static module is the simpler of the two, in this case you simply put your code into a module.js file within your plugin. Into that file you create a namespace and define any functions or objects you want to use.&lt;br /&gt;
&lt;br /&gt;
Within PHP static modules are also pretty easy to use. The first step if to create a module definition which tells moodle what your module is called, what it requires, and can optionally give it strings.&lt;br /&gt;
&lt;br /&gt;
Once the module is defined you can then use any of the several JS methods for including JS in your page and pass your module definition along.&lt;br /&gt;
&lt;br /&gt;
Whilst this method is simpler to write and understand especially when you are first starting out with JavaScript it isn&#039;t as easily flexible and has some quirks that you need will need to overcome, especially with more complex JavaScript.&lt;br /&gt;
&lt;br /&gt;
This method of writing a module should be used if you are just starting out with JavaScript or if the JS solution you are creating is going to be relatively simple in nature.&lt;br /&gt;
If you are writing something more complex I would strongly suggest looking at the other method as it will result in cleaner, easier to read code at the end of the day. However it will require you to learn your way around writing a Moodle module.&lt;br /&gt;
&lt;br /&gt;
==The YUI3 Moodle Module==&lt;br /&gt;
This method is certainly more complex than the previous method however it is much more flexible and when you have learnt and understand what you are doing it is much quicker to write and more versatile as well. These modules can also easily include other YUI3 Moodle modules, and can choose to include module specific CSS as well.&lt;br /&gt;
&lt;br /&gt;
In this method you create a &#039;&#039;&#039;yui&#039;&#039;&#039; directory within you plugin directory, and then sub directories for each module you wish to write, you name them the same as you want your module named.&lt;br /&gt;
Into the subdirectory you create a JavaScript file with the same name that you gave the subdirectory, e.g.&#039;&#039;&#039;/local/myplugin/yui/mymodule/mymodule.js&#039;&#039;&#039;&lt;br /&gt;
The JS that you then put into this file should then be written in the same way you would write a YUI module, before you ask it certainly requires a good understanding of YUI.&lt;br /&gt;
&lt;br /&gt;
I would recommend this method of writing a module providing you either have an understanding of how to write a YUI module, or you are happy to learn. It normally results in cleaner easier to read code, and if desired can easily be written in such as way as to make it VERY easy to re-use in other bits of code.... particularly helpful if you have several JavaScript objects in play at a time.&lt;br /&gt;
&lt;br /&gt;
= Static module quick start = &lt;br /&gt;
1. Create a module.js file somewhere &lt;br /&gt;
&lt;br /&gt;
2. The two ways Moodle can load this file are:&lt;br /&gt;
&lt;br /&gt;
a- the file is in core: declare the file into /lib/outputrequirementslib.php/find_module($component)&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
          //example:&lt;br /&gt;
          case &#039;core_rating&#039;:&lt;br /&gt;
                    $module = array(&#039;name&#039;     =&amp;gt; &#039;core_rating&#039;,&lt;br /&gt;
                                    &#039;fullpath&#039; =&amp;gt; &#039;/rating/module.js&#039;,&lt;br /&gt;
                                    &#039;requires&#039; =&amp;gt; array(&#039;node&#039;, &#039;event&#039;, &#039;overlay&#039;, &#039;io&#039;, &#039;json&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
b- the file is in a local plugin: the first line of your module should be&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
 M.local_xxx = {&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
xxx being your plugin directory name.&lt;br /&gt;
&lt;br /&gt;
3. Write the module.js&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
  M.local_hub={&lt;br /&gt;
    Y : null,&lt;br /&gt;
    transaction : [],&lt;br /&gt;
    init : function(Y){&lt;br /&gt;
        alert(&#039;hub module initialisation&#039;);&lt;br /&gt;
        this.Y = Y;&lt;br /&gt;
    },&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
4. Call this module. The best place to do this is in your renderer class (since, if a theme overrides the renderer to change the HTML, they may also need to use different JavaScript.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $this-&amp;gt;page-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.local_hub.init&#039;); &lt;br /&gt;
You should now have loaded and called your first YUI 3 module in Moodle.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
5. If you want to load your module with some other YUI modules&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $jsmodule = array(&lt;br /&gt;
                &#039;name&#039; =&amp;gt; &#039;local_hub&#039;,&lt;br /&gt;
                &#039;fullpath&#039; =&amp;gt; &#039;/local/hub/module.js&#039;,&lt;br /&gt;
                &#039;requires&#039; =&amp;gt; array(&amp;quot;overlay&amp;quot;, &amp;quot;anim&amp;quot;, &amp;quot;plugin&amp;quot;)); //on this line you are loading three other YUI modules&lt;br /&gt;
   $this-&amp;gt;page-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.local_hub.init&#039;,&lt;br /&gt;
                 null, false, $jsmodule);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
6. If you want to pass parameter to the init function&lt;br /&gt;
&lt;br /&gt;
PHP:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $this-&amp;gt;page-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.local_hub.init&#039;,&lt;br /&gt;
                    array(&#039;this is the param1 value&#039;), false, $jsmodule);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
JS:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
    init : function(Y, params){&lt;br /&gt;
        alert(params);&lt;br /&gt;
        ....&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
7. Then you should be able to fill the module with your own YUI javascript from [http://developer.yahoo.com/yui/3/examples/ YUI examples].&lt;br /&gt;
&lt;br /&gt;
= YUI 3 Moodle Module quick start =&lt;br /&gt;
1. Create the module_name.js file in /local/pluginname/yui/module_name/modulename.js or in /mod/modname/yui/modulename/modulename.js&lt;br /&gt;
&lt;br /&gt;
2. The basic module_name.js structure is:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
  YUI.add(&#039;moodle-local_pluginname-modulename&#039;, function(Y) {&lt;br /&gt;
    var ModulenameNAME = &#039;this_is_a_module_name&#039;;&lt;br /&gt;
    var MODULENAME = function() {&lt;br /&gt;
        MODULENAME.superclass.constructor.apply(this, arguments);&lt;br /&gt;
    };&lt;br /&gt;
    Y.extend(MODULENAME, Y.Base, {&lt;br /&gt;
        initializer : function(config) { //&#039;config&#039; contains the parameter values&lt;br /&gt;
            alert(&#039;I am in initializer&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    }, {&lt;br /&gt;
        NAME : ModulenameNAME, //module name is something mandatory. &lt;br /&gt;
                                //It should be in lower case without space &lt;br /&gt;
                                //as YUI use it for name space sometimes.&lt;br /&gt;
        ATTRS : {&lt;br /&gt;
                 aparam : {}&lt;br /&gt;
        } // Attributs are the parameters sent when the $PAGE-&amp;gt;requires-&amp;gt;yui_module calls the module. &lt;br /&gt;
          // Here you can declare default values or run functions on the parameter. &lt;br /&gt;
          // The param names must be the same as the ones declared &lt;br /&gt;
          // in the $PAGE-&amp;gt;requires-&amp;gt;yui_module call.&lt;br /&gt;
    });&lt;br /&gt;
    M.local_pluginname = M.local_pluginname || {}; //this line use existing name path if it exists, ortherwise create a new one. &lt;br /&gt;
                                                 //This is to avoid to overwrite previously loaded module with same name.&lt;br /&gt;
    M.local_pluginname.init_modulename = function(config) { //&#039;config&#039; contains the parameter values&lt;br /&gt;
        alert(&#039;I am in the javascript module, Yeah!&#039;);&lt;br /&gt;
        return new MODULENAME(config); //&#039;config&#039; contains the parameter values&lt;br /&gt;
    }&lt;br /&gt;
  }, &#039;@VERSION@&#039;, {&lt;br /&gt;
      requires:[&#039;base&#039;,&#039;another_required_YUI_module&#039;, &#039;a_moodle_YUI_module&#039;]&lt;br /&gt;
  });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
3. Call the javascript in PHP. Again, it is best to do this in a renderer class. (if you copied the previous javascript, 2 javascript alert should appear.)&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
  $this-&amp;gt;page-&amp;gt;requires-&amp;gt;yui_module(&#039;moodle-local_pluginname-modulename&#039;, &#039;M.local_pluginname.init_modulename&#039;,&lt;br /&gt;
                array(array(&#039;aparam&#039;=&amp;gt;&#039;paramvalue&#039;)));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
== Full simple example==&lt;br /&gt;
Once you understand and run the above quick start, here is simple YUI 3 example. It shows how to use another YUI 3 module in your module, and to use some events.&lt;br /&gt;
=== It includes===&lt;br /&gt;
* display a parameter value in two javascript alert boxes =&amp;gt; demonstrate how to pass a param to the initialize function in two different ways&lt;br /&gt;
* display an overlay when you click on an image&lt;br /&gt;
* hide the overlay when you click on the body&lt;br /&gt;
* some commented code to see how Moodle YUI exception works&lt;br /&gt;
&lt;br /&gt;
=== PHP ===&lt;br /&gt;
Create a [https://docs.moodle.org/en/Development:Local_customisation basic local plugin] (in this example it is named hub) in /local/hub/ and add this code into one of the plugin pages:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
   $PAGE-&amp;gt;requires-&amp;gt;yui_module(&#039;moodle-local_hub-comments&#039;, &#039;M.local_hub.init_comments&#039;,&lt;br /&gt;
                array(array(&#039;commentids&#039; =&amp;gt; &#039;1 , 23 ,45&#039;)));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== HTML ===&lt;br /&gt;
The plugin page should generate this HTML code:&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;!-- image to click on --&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;comments&amp;quot;&amp;gt;&amp;lt;img src=&#039;http://moodle.org/theme/moodle2/pix/moodle-logo.gif&#039; alt=&#039;the image to click on&#039;/&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- overlay --&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;commentoverlay&amp;quot; class=&amp;quot;yui3-overlay-loading&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;yui3-widget-hd&amp;quot;&amp;gt;Comment&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;yui3-widget-bd&amp;quot;&amp;gt;this is a comment&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;yui3-widget-bd&amp;quot;&amp;gt;this is another comment&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;
=== CSS ===&lt;br /&gt;
The plugin style.css should contain:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/* Hide overlay markup while loading, if js is enabled */&lt;br /&gt;
.yui3-js-enabled .yui3-overlay-loading {&lt;br /&gt;
    top:-1000em;&lt;br /&gt;
    left:-1000em;&lt;br /&gt;
    position:absolute;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Overlay Look/Feel */&lt;br /&gt;
.yui3-overlay-content {&lt;br /&gt;
    padding:3px;&lt;br /&gt;
    border:1px solid #000;&lt;br /&gt;
    background-color:#aaa;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.yui3-overlay-content .yui3-widget-hd {&lt;br /&gt;
    padding:5px;&lt;br /&gt;
    border:2px solid #aa0000;&lt;br /&gt;
    background-color:#fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.yui3-overlay-content .yui3-widget-bd {&lt;br /&gt;
    padding:5px;&lt;br /&gt;
    border:2px solid #0000aa;&lt;br /&gt;
    background-color:#fff;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== JS ===&lt;br /&gt;
In /local/hub/yui/comments/comments.js&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
YUI.add(&#039;moodle-local_hub-comments&#039;, function(Y) {&lt;br /&gt;
&lt;br /&gt;
    var COMMENTSNAME = &#039;hub_comments&#039;;&lt;br /&gt;
&lt;br /&gt;
    //we declare the overlay here so it&#039;s accessible to all the extended class function&#039;&lt;br /&gt;
    var overlay = new Y.Overlay({&lt;br /&gt;
                srcNode:&amp;quot;#commentoverlay&amp;quot;, //the main div with id = commentoverlay&lt;br /&gt;
                width:&amp;quot;10em&amp;quot;,&lt;br /&gt;
                height:&amp;quot;10em&amp;quot;,&lt;br /&gt;
                xy:[ 0, 0],&lt;br /&gt;
                visible: false //by default it is not displayed&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
    var COMMENTS = function() {&lt;br /&gt;
        COMMENTS.superclass.constructor.apply(this, arguments);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Y.extend(COMMENTS, Y.Base, {&lt;br /&gt;
&lt;br /&gt;
        event:null,&lt;br /&gt;
&lt;br /&gt;
        initializer : function(params) {&lt;br /&gt;
&lt;br /&gt;
            //Example how to retrieve the parameter,&lt;br /&gt;
            //see what happens if you don&#039;t pass the parameter in the call&lt;br /&gt;
            alert(this.get(&#039;commentids&#039;)); // You usually use an attribute because&lt;br /&gt;
                                           //a attribut can have default value.&lt;br /&gt;
                                           //use the ATTRS default value if not passed as parameter&lt;br /&gt;
            alert(params.commentids); // undefined if not passed as parameter&lt;br /&gt;
&lt;br /&gt;
            //render the overlay&lt;br /&gt;
            overlay.render();&lt;br /&gt;
&lt;br /&gt;
            // position the overlay in the middle of the web browser window&lt;br /&gt;
            var WidgetPositionAlign = Y.WidgetPositionAlign;&lt;br /&gt;
            overlay.set(&amp;quot;align&amp;quot;, {&lt;br /&gt;
                node:&amp;quot;&amp;quot;, //empty =&amp;gt; viewport&lt;br /&gt;
                points:[WidgetPositionAlign.CC, WidgetPositionAlign.CC]&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            //attach a show event on the div with id = comments&lt;br /&gt;
            //we also change the div style to display the click zone&lt;br /&gt;
            Y.one(&#039;#comments&#039;).setStyle(&amp;quot;border&amp;quot;, &amp;quot;1px solid red&amp;quot;).on(&#039;click&#039;, this.show, this);&lt;br /&gt;
&lt;br /&gt;
            //uncomment the try content to see how works exception in Moodle&lt;br /&gt;
            //this exception has been specially created for Moodle&lt;br /&gt;
            try {&lt;br /&gt;
              //surely_not_existing_js_function();&lt;br /&gt;
            } catch (exception) {&lt;br /&gt;
                new M.core.exception(exception);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        show : function (e) {&lt;br /&gt;
            overlay.show(); //show the overlay&lt;br /&gt;
           &lt;br /&gt;
            e.halt(); // we are going to attach a new &#039;hide overlay&#039; event to the body,&lt;br /&gt;
                      // because javascript always propagate event to parent tag,&lt;br /&gt;
                      // we need to tell Yahoo to stop to call the event on parent tag&lt;br /&gt;
                      // otherwise the hide event will be call right away.&lt;br /&gt;
&lt;br /&gt;
            //we add a new event on the body in order to hide the overlay for the next click&lt;br /&gt;
            this.event = Y.one(document.body).on(&#039;click&#039;,this.hide,this);&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        hide : function () {&lt;br /&gt;
            overlay.hide(); //hide the overlay&lt;br /&gt;
            this.event.detach(); //we need to detach the hide event&lt;br /&gt;
                                 //Note: it would work without but create js warning everytime&lt;br /&gt;
                                 //we click on the body&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }, {&lt;br /&gt;
        NAME : COMMENTSNAME,&lt;br /&gt;
        ATTRS : {&lt;br /&gt;
            commentids: {value : 450} //default value (has no purpose in this code except to show you&lt;br /&gt;
                                      // how to pass/use a param value)&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    M.local_hub = M.local_hub || {};&lt;br /&gt;
    M.local_hub.init_comments = function(params) {&lt;br /&gt;
        return new COMMENTS(params);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}, &#039;@VERSION@&#039;, {&lt;br /&gt;
    requires:[&#039;base&#039;,&#039;overlay&#039;, &#039;moodle-enrol-notification&#039;]&lt;br /&gt;
    //Note: &#039;moodle-enrol-notification&#039; contains Moodle YUI exception&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= What else to read =&lt;br /&gt;
Two pages are important to start with when you discover YUI 3&lt;br /&gt;
* you should read the [http://developer.yahoo.com/yui/3/base/ base YUI doc]. It is very useful to understand the YUI 3 Moodle module.&lt;br /&gt;
* you want to have a look to the [http://developer.yahoo.com/yui/3/examples/ YUI 3 examples]. Always open the examples in a window to have a look to the complete example codes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:AJAX]]&lt;br /&gt;
[[Category:Javascript]]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[Javascript and YUI 3 FAQ]]&lt;br /&gt;
* [[JavaScript FAQ]]&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Plugin_contribution&amp;diff=29964</id>
		<title>Plugin contribution</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Plugin_contribution&amp;diff=29964"/>
		<updated>2011-10-10T18:30:52Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* Share code with modules and plugins database */ Added command to zip up a git repo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the various ways to share and work collaboratively on contributed code. In the past, Moodle CONTRIB code was often stored on the Moodle CVS server. As Moodle code transitions to [https://docs.moodle.org/en/Git Git], CONTRIB code will also be transitioning with a goal of having all code maintained via git repositories by August 2011. Don&#039;t worry if you have code on CVS and do not know Git as there are many people willing to help you with the transition especially [https://docs.moodle.org/en/User:Anthony_Borrow Anthony Borrow]. &lt;br /&gt;
&lt;br /&gt;
For those neither familiar with CVS nor Git, it is recommended that you [https://docs.moodle.org/en/Git#Books_and_tutorials learn Git basics]. The nice thing about using Git is that it will leave control of the code in the hands of contributor. &lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Sharing code&#039;&#039;&#039; - Contributed code will be shared and maintained using a public Git repository (i.e. github.com, gitorious.org, etc.).&lt;br /&gt;
*&#039;&#039;&#039;Reviewing code&#039;&#039;&#039; - If you would like your code to be tested and reviewed, please create an issue in the [http://tracker.moodle.org/ Moodle Tracker] under [http://tracker.moodle.org/browse/CONTRIB CONTRIB]. &lt;br /&gt;
*&#039;&#039;&#039;Documenting code&#039;&#039;&#039; - You can maintain helpful documentation of the features and installation instructions in [https://docs.moodle.org Moodle Docs]&lt;br /&gt;
*&#039;&#039;&#039;Distributing code&#039;&#039;&#039; - You can help others find your code by adding an entry to the [http://moodle.org/mod/data/view.php?id=6009 Modules and Plugins database] &lt;br /&gt;
*&#039;&#039;&#039;Discussing the code&#039;&#039;&#039; - You can discuss the functionality and answer questions about how to use your code in the [http://moodle.org/course/view.php?id=5 Using Moodle forums]. Users can ask questions, discuss possible ideas for improvement, etc. Once the discussion matures to a point where you may want to take action, then you can create an issue in the [http://tracker.moodle.org/ Moodle Tracker]. &lt;br /&gt;
*&#039;&#039;&#039;Maintaining code&#039;&#039;&#039; - You can further develop your code by fixing issues, adding features, and responding to other issues with the [http://tracker.moodle.org/ Moodle Tracker]. Each plugin or patch can have its own component in the CONTRIB project; however, you will need to request that the component be created in the CONTRIB project. Once created, users can easily create issues related to your contributed code. The primary maintainer of the code will be assigned as the component lead and have their tracker privileges bumped so that they can manage issues related to their contributed code. Those issues will automatically be assigned to the component lead/primary maintainer. &lt;br /&gt;
&lt;br /&gt;
==The CONTRIB Frequently Asked Question (FAQ)==&lt;br /&gt;
&#039;&#039;&#039;Question:&#039;&#039;&#039; I have written a new block, activity, patch or theme to share with the Moodle community. What is the process for contributing the code? &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Answer:&#039;&#039;&#039; First, thank you for your generosity and desire to share your work with the rest of the Moodle community. Code contributions are highly valued and Moodle wants to encourage creativity and generosity in keeping with [https://docs.moodle.org/en/Pedagogy Moodle&#039;s social constructionist pedagogy]. &lt;br /&gt;
&lt;br /&gt;
As mentioned, there are various tools to help you share and support your contribution. By using a consistent methodology, your Moodle related code will be more easily found, tested, used, maintained, documented, and evaluated by fellow Moodlers and developers. Learning to use the various tools common among Moodle developers will help you to efficiently and effectively develop, share and maintain your contributed code. &lt;br /&gt;
&lt;br /&gt;
==How to submit code==&lt;br /&gt;
You have created some code that you would like to contribute to the Moodle community.  The first step is to choose which Git code hosting site you want to use. Both [http://github.com/ github.com] and [http://gitorious.org/ gitorious.org] are popular. Follow the instructions for creating a public repository for your code. This will allow others to download your code as well as suggest possible patches. As you become more familiar with collaborating with others you can also control who else you want to be able to push changes into your repository (i.e. write access). &lt;br /&gt;
&lt;br /&gt;
In order to facilitate a common naming convention of Moodle related repositories, it is suggested that you use the following format: moodle-{plugintype}_{pluginname}. For example, the birthday block has a repository name of moodle-block_birthday and is located at https://github.com/arborrow/moodle-block_birthday. Other developers can fork the code and work from their repositories.&lt;br /&gt;
&lt;br /&gt;
==How to request that your code be tested/reviewed==&lt;br /&gt;
&lt;br /&gt;
#If you do not already have an account on the [http://tracker.moodle.org Moodle Tracker], create one and login. &lt;br /&gt;
#Create a new &amp;quot;Task&amp;quot; issue in the &amp;quot;Non-core contributed modules&amp;quot; project. Your issue will be a request that the code be tested and reviewed. &lt;br /&gt;
#Provide the link to the repository (i.e. https://github.com/arborrow/moodle-block_birthday) &lt;br /&gt;
#Provide a clear description of what the code does and the functionality that it adds to Moodle. &lt;br /&gt;
#Provide any other links to supporting documentation&lt;br /&gt;
&lt;br /&gt;
The Contrib Coordinator will then work directly with the code contributor via the Tracker to help evaluate the code, work on resolving any questions/issues found, etc. &lt;br /&gt;
&lt;br /&gt;
*Contributors are encouraged to follow Moodle&#039;s coding guidelines [[Coding]].&lt;br /&gt;
&lt;br /&gt;
*Contributors are encouraged to maintain a branch for each major Moodle release (i.e. 1.8, 1.9, etc.). The HEAD branch should be used as the development branch. &lt;br /&gt;
&lt;br /&gt;
*Contributors are encouraged to associate each change made to an issue in the tracker. This practice is done by Moodle core developers and it is a good habit to get into so that you can go back and see why various changes were made to the code. Simple practices like these help to create good documentation of the code as it develops and matures. Commits should begin with the Moodle tracker issue number followed by a brief description of the change.&lt;br /&gt;
&lt;br /&gt;
==How to provide documentation==&lt;br /&gt;
Having great code available to the community is wonderful. It is also important to educate users about how to use the code with documentation in [[:en:Main Page|Moodle Docs]]. See [[:en:MoodleDocs:Guidelines for contributors|guidelines for contributors]] for more help. &lt;br /&gt;
&lt;br /&gt;
A documentation page for a contributed module should have some basic elements.  A brief introduction of what the code does, a &amp;quot;Features&amp;quot; heading, perhaps a &amp;quot;Installation&amp;quot;, &amp;quot;Tips and tricks&amp;quot; and &amp;quot;See also&amp;quot; headings, all with content of course.  Sometimes a screenshot is worth 1000 words. In the &amp;quot;See also&amp;quot; put a link to the Modules and Plug database, with a note that this is the place to download versions, and the forum where questions can be answered at moodle.org.&lt;br /&gt;
&lt;br /&gt;
Other information might include: Languages Supported, Known Issues, Supported Versions (for Moodle 1.8, 1.9), and maybe which are being actively supported. The page should be added to the contributed code category by typing &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[Category:Contributed code]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; at the bottom of the page.&lt;br /&gt;
&lt;br /&gt;
===Possible format for a contributed code Moodle Docs page===&lt;br /&gt;
You can copy and paste the below into your Moodle documentation page.  Please add the URL links. &#039;&#039;&#039;This is only a suggestion&#039;&#039;&#039;. &lt;br /&gt;
 Start with a 2-4 line introduction. The Plug In Name works with the activity module. &lt;br /&gt;
 It makes the life of the teacher easier by ... &lt;br /&gt;
 ==Features==&lt;br /&gt;
 * Add features list or overview description here &amp;lt;nowiki&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; [[Image:Sample_screen_shot|thumb|500px|center|Title of screenshot]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 ==Installation==&lt;br /&gt;
 Place install instructions here&lt;br /&gt;
 ==Tips and tricks==&lt;br /&gt;
 *Optional section, usually added by users later&lt;br /&gt;
 ==See also==&lt;br /&gt;
 *[Place http_address_for_M&amp;amp;P_entry_here  Name of Entry here] is a Modules and plugins database page that has download links and more information.&lt;br /&gt;
 *Discussions: [Place http_address_for_moodle_forum_or_thread_here Name of forum]&lt;br /&gt;
 &lt;br /&gt;
When no thread or forum exists for discussion, put a link to the Contributed Code forum.&lt;br /&gt;
 *Discussions: Please create or find a discussion topic in the &amp;lt;nowiki&amp;gt;[http://moodle.org/mod/forum/view.php?id=44  Contributed Code forum]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Share code with modules and plugins database==&lt;br /&gt;
Now you have a place for users to get your code, how will they know it exists? Moodle users can easily find information about contributed code in the [http://moodle.org/mod/data/view.php?id=6009 Modules and Plugins database]. When you add an entry to this database, remember that it is searchable by any field. Every field is not required, but providing as much information as possible will help people who would like to find, read about, and then install your contribution.  In particular, the name of the module and the description of its function are important.  Screen shots are helpful (but please, not larger than 350px wide!). Links to discussion (on Moodle.org or other forum) and documentation (link to your page in the [https://docs.moodle.org Moodle docs] or another location) should be included if possible.  &lt;br /&gt;
&lt;br /&gt;
Users may leave comments on your entry, so please check it periodically for questions and bug reports.  If you include contact information or a link to a discussion, your users may be able to contact you more directly.  The comments are not emailed automatically.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that entries added to the [http://moodle.org/mod/data/view.php?id=6009 Modules and Plugins database] require approval by a moderator before they will be visible to other Moodle users.&lt;br /&gt;
&lt;br /&gt;
If you are using git to store your code, you will need to export the repository cleanly into a zip file containing one folder, named after your plugin. Use this code to do that:&lt;br /&gt;
&lt;br /&gt;
  git archive -o path/to/filename.zip --prefix=yourpluginname/ yourbranchname&lt;br /&gt;
&lt;br /&gt;
==Support code and get feedback with forums==&lt;br /&gt;
As users become familiar with the contributed code, discussions about the code are likely to emerge. We strongly urge you to place links to at least one forum at moodle.org in your Modules and Plugins entry as well as in MoodleDocs. &lt;br /&gt;
&lt;br /&gt;
It is important to respond to users who have questions about how to use the code, suggestions for how to make it better, etc. If it looks like there is sufficient need for some contributed code to have its own forum, please create a request via the tracker in the MDL-SITE section. Moodle has included many contributed code projects and ideas into its core. &lt;br /&gt;
&lt;br /&gt;
*[http://moodle.org/mod/forum/view.php?id=44 Contributed code forum] is a generic forum.  Maybe create a thread &amp;quot;New Mousetrap module&amp;quot;.&lt;br /&gt;
*[http://moodle.org/course/view.php?id=5 Using Moodle forums] The English speaking list of forums on many different subjects. &lt;br /&gt;
*[http://moodle.org/course/ A list of] other language forums and special areas in Moodle&lt;br /&gt;
&lt;br /&gt;
==Maintain and refine code with Tracker==&lt;br /&gt;
&lt;br /&gt;
In order to facilitate keeping track of feature requests, bugs, and other code issues, the contributor may request that a component be created in the CONTRIB section of the Moodle tracker. (This is the section where you initially made the request to have code included in CVS.moodle.org.)&lt;br /&gt;
&lt;br /&gt;
The contributor can be added to the group of CONTRIB developers in the tracker to manage the issues assigned to them and better coordinate with other developers. Users of the contributed code can then add issues which can be assigned directly to the maintainer. The tracker helps to manage the work flow involved in fixing bugs, working through feature requests, and maintaining the code. When committing changes, maintainers are strongly encouraged to begin the commit comment with a tracker number. &lt;br /&gt;
&lt;br /&gt;
We strongly encourage users to involve themselves in the process of creating a useful issue in tracker.  For the developer and code contributor,  describing the fix can help clarify the need for the code change. Further, it helps to establish good documentation about how the code developed. Others will be able to identify the issues addressed and understand why a particular decision was made.&lt;br /&gt;
&lt;br /&gt;
==Summary==&lt;br /&gt;
&lt;br /&gt;
It is hoped that following this procedure, will help guide contributors of code in the process of learning the tools and skills used by the Moodle developers. Learning to submit code by using the tracker, work the code with CVS, support the code by providing documentation, share code in Modules and Plugins, maintain the code by using the tracker, and evolve the code by using the Moodle.org forums will assist you in successfully contributing to the Moodle community and working with Moodle&#039;s developers. &lt;br /&gt;
&lt;br /&gt;
Throughout this process, the CONTRIB Coordinator is here to encourage and support those contributing code to the Moodle community and fostering the development of tomorrow&#039;s Moodle developers.&lt;br /&gt;
&lt;br /&gt;
Eventually, the community may wish for the code to become part of the Moodle core. By following the steps above, the developers will be able to evaluate the merit of the contributed code, understand how users have used the code, see the issues that have emerged and thus have more information to make an informed decision about whether or not to incorporate the contributed code into core.&lt;br /&gt;
&lt;br /&gt;
==Most common recommendations for contributed code==&lt;br /&gt;
&lt;br /&gt;
There are several small issues that the CONTRIB Coordinator will typically check for when reviewing the code prior to committing to the CVS server. These issues help to ensure consistency and quality of code. Any suggestions made by the CONTRIB Coordinator should be considered recommendations aimed to help folks new to the Moodle community collaborate in a way consistent with standard practices within the Moodle community. The suggestions are meant to help avoid potential issues and facilitate the acceptance of your code.&lt;br /&gt;
&lt;br /&gt;
=== Does the file structure conform to Moodle standards? ===&lt;br /&gt;
Generally speaking, each file should have an appropriate extension (i.e. php, html, css, txt, etc.). To avoid issues with case sensitivity, folders and files are normally lower case; however, there are exceptions to this. Another common recommendation is to place the lang folder within the block or module rather than asking the user to copy files into the main lang folder. Changes made in the get_string function for Moodle 1.9 and onward make it possible to do this which goes a long way in keeping things modular. Similarly, to respect the modular nature of Moodle if a block requires a library it is usually preferred to keep it as a subdirectory in the block&#039;s folder. This can be especially helpful if your code is dependent upon a particular version of an external library.&lt;br /&gt;
&lt;br /&gt;
=== Does the code work without any obvious errors? ===&lt;br /&gt;
The CONTRIB Coordinator will try to install the block or module on a fresh Moodle installation and report back any errors. This testing is done with Debugging set to show All PHP notices and errors (not developer mode). The most common notices have to do with attempting to use a variable that has not been initialized or checked for existence. &lt;br /&gt;
&lt;br /&gt;
=== Does the code use the config_plugins table? ===&lt;br /&gt;
&lt;br /&gt;
Contributed blocks and modules are encouraged to make use of the &#039;&#039;&#039;config_plugins&#039;&#039;&#039; table rather than the config table. Maintainers are encouraged to read the documentation provided for the [http://xref.moodle.org/lib/moodlelib.php.html#get_config get_config()] and [http://xref.moodle.org/lib/moodlelib.php.html#set_config set_config()]] functions in the /lib/moodlelib.php file to help ensure that the footprint for the global $CFG variable does not become bloated.&lt;br /&gt;
&lt;br /&gt;
=== Does the code follow the [[Coding|Coding Guidelines]]? ===&lt;br /&gt;
The CONTRIB Coordinator will look at the code for general readability and point out any obvious deviations from the [[Coding|Coding Guidelines]]. While not all code needs to conform with each and every guideline, maintainers are encouraged to follow those guidelines as closely as possible. One useful tool for Moodle 2.0 is the [http://moodle.org/mod/data/view.php?d=13&amp;amp;rid=4682|Code checker local plugin] which helps to identify many issues.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
*[[Migrating contrib code to 2.0]]&lt;br /&gt;
*[[contrib]] CONTRIB is an area in the Moodle CVS &lt;br /&gt;
*[[:en:Translation]] for information on the translation of contributed code&lt;br /&gt;
*[[Overview]]&lt;br /&gt;
*Using Moodle [http://moodle.org/mod/forum/discuss.php?d=99037 Best practices for code modification?] forum discussion&lt;br /&gt;
&lt;br /&gt;
[[Category:Guidelines for contributors]]&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=File_API&amp;diff=11545</id>
		<title>File API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=File_API&amp;diff=11545"/>
		<updated>2011-05-19T13:30:24Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* List area files */ Added code to list files as links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
The File API is for managing all the files stored by Moodle. If you are interested in how the file API works internally, see [[File API]]. The page is just about what you need to know to use the file API. Related is the [[Repository API]], which lets users get files into Moodle.&lt;br /&gt;
&lt;br /&gt;
If you are looking for an explanation on how to upgrade pre-2.0 code to using the file API, you most likely need to read [[Using_the_File_API_in_Moodle_forms|Using the File API in Moodle forms]].&lt;br /&gt;
&lt;br /&gt;
==File areas==&lt;br /&gt;
&lt;br /&gt;
Files are conceptually stored in &#039;&#039;&#039;file areas&#039;&#039;&#039;. A file area is uniquely identified by:&lt;br /&gt;
* A context id.&lt;br /&gt;
* full component name, for example &#039;course&#039;, &#039;mod_forum&#039;, &#039;mod_glossary&#039;.&lt;br /&gt;
* A file area type, for example &#039;intro&#039; or &#039;post&#039;.&lt;br /&gt;
* A unique itemid. Normally, the itemid relates to something depending on the file area type. For example, for a &#039;course&#039;, &#039;intro&#039; file area, the itemid is 0. For forum post, it is the post id.&lt;br /&gt;
&lt;br /&gt;
File areas are not listed separately anywhere, they are stored implicitly in the files table. Please note that each subsystem is allowed to access only own file areas, for example only code in /mod/assignment/* may access files with component &#039;mod_assignment&#039;.&lt;br /&gt;
&lt;br /&gt;
===Naming file areas===&lt;br /&gt;
&lt;br /&gt;
The names of the file areas are not strictly defined, but it is strongly recommended to use singulars and common names of areas if possible (intro, post, attachment, description, ...).&lt;br /&gt;
&lt;br /&gt;
==Serving files to users==&lt;br /&gt;
&lt;br /&gt;
You must refer to the file with a URL that includes a file-serving script, often pluginfile.php. For example&lt;br /&gt;
&lt;br /&gt;
The general form of the URL is something like&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$url = $CFG-&amp;gt;wwwroot/pluginfile.php/$contextid/$component/$filearea/arbitrary/extra/infomation.ext&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A specific example might be&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$url = $CFG-&amp;gt;wwwroot/pluginfile.php/$forumcontextid/mod_forum/post/$postid/image.jpg&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The file serving script then looks at the context id, and component name, and the file area name, and based on that arranges for the file to be served, following appropriate security checks.&lt;br /&gt;
&lt;br /&gt;
In most cases this is done by calling a callback function in the appropriate plugin, these functions are stored in lib.php files and named component_name_pluginfile() . The arbitrary/extra/infomation.ext is passed to the callback. For example, files in the mod_forum+post file area end up being served by the mod_forum_pluginfile function in mod/forum/lib.php.&lt;br /&gt;
&lt;br /&gt;
You normally use an API function to generate these URL automatically, most often the file_rewrite_pluginfile_urls function.&lt;br /&gt;
&lt;br /&gt;
==Getting files from the user==&lt;br /&gt;
&lt;br /&gt;
* See [[Using_the_File_API_in_Moodle_forms|Using the File API in Moodle forms]]&lt;br /&gt;
==Examples==&lt;br /&gt;
Please note that in reality developers outside of core will not deal with file api directly in majority of cases, instead use formslib elements which are doing all this automatically.&lt;br /&gt;
&lt;br /&gt;
===Browsing files===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$browser = get_file_browser();&lt;br /&gt;
$context = get_system_context();&lt;br /&gt;
&lt;br /&gt;
$filearea = null;&lt;br /&gt;
$itemid   = null;&lt;br /&gt;
$filename = null;&lt;br /&gt;
if ($fileinfo = $browser-&amp;gt;get_file_info($context, $component, $filearea, $itemid, &#039;/&#039;, $filename)) {&lt;br /&gt;
    // build a Breadcrumb trail&lt;br /&gt;
    $level = $fileinfo-&amp;gt;get_parent();&lt;br /&gt;
    while ($level) {&lt;br /&gt;
        $params = base64_encode(serialize($level-&amp;gt;get_params()));&lt;br /&gt;
        $path[] = array(&#039;name&#039;=&amp;gt;$level-&amp;gt;get_visible_name(), &#039;path&#039;=&amp;gt;$params);&lt;br /&gt;
        $level = $level-&amp;gt;get_parent();&lt;br /&gt;
    }&lt;br /&gt;
    $path = array_reverse($path);&lt;br /&gt;
    $children = $fileinfo-&amp;gt;get_children();&lt;br /&gt;
    foreach ($children as $child) {&lt;br /&gt;
        if ($child-&amp;gt;is_directory()) {&lt;br /&gt;
            echo $child-&amp;gt;get_visible_name();&lt;br /&gt;
            // display contextid, itemid, component, filepath and filename&lt;br /&gt;
            var_dump($child-&amp;gt;get_params());&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Moving files around===&lt;br /&gt;
&lt;br /&gt;
For example, if you have just built a file at the path&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $from_zip_file = $CFG-&amp;gt;dataroot . &#039;/temp/backup/&#039; . $preferences-&amp;gt;backup_unique_code .&lt;br /&gt;
         &#039;/&#039; . $preferences-&amp;gt;backup_name;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
And you want to move it into the course_backup file area, do&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $context = get_context_instance(CONTEXT_COURSE, $preferences-&amp;gt;backup_course);&lt;br /&gt;
 $fs = get_file_storage();&lt;br /&gt;
 $file_record = array(&#039;contextid&#039;=&amp;gt;$context-&amp;gt;id, &#039;component&#039;=&amp;gt;&#039;course&#039;, &#039;filearea&#039;=&amp;gt;&#039;backup&#039;,&lt;br /&gt;
         &#039;itemid&#039;=&amp;gt;0, &#039;filepath&#039;=&amp;gt;&#039;/&#039;, &#039;filename&#039;=&amp;gt;$preferences-&amp;gt;backup_name,&lt;br /&gt;
         &#039;timecreated&#039;=&amp;gt;time(), &#039;timemodified&#039;=&amp;gt;time());&lt;br /&gt;
 $fs-&amp;gt;create_file_from_pathname($file_record, $from_zip_file);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Create a copy of stored file===&lt;br /&gt;
 TODO: this example is bogus, nobody should ever write code like this (skodak)&lt;br /&gt;
If you need to create a copy of stored file (actually, it add a new record in database):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$context  = get_context_instance_by_id($contextid);&lt;br /&gt;
$file_info = $browser-&amp;gt;get_file_info($context, $component, $filearea, $fileitemid, $filepath, $filename);&lt;br /&gt;
// copy this file to draft area&lt;br /&gt;
$file_info-&amp;gt;copy_to_storage($user_context-&amp;gt;id, &#039;user&#039;, &#039;draft&#039;, $newitemid, &#039;/&#039;, $title);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code is intended for user-interface behaviour which respects the current user&#039;s permissions. If you need to write code which copies files at the back-end in areas which are not directly editable by users (for example, when copying a glossary entry to another glossary, and you want to copy its attachments), you do not need to use the user-level $browser at all. All operations are carried out with the file_storage object (usually $fs). The method to use is create_file_from_storedfile.&lt;br /&gt;
&lt;br /&gt;
For example, the glossary stores per-entry files in two areas (&#039;mod_glossary&#039;, &#039;attachment&#039; which stores attachments and &#039;mod_glossary&#039;, &#039;entry&#039; which stores files directly related to the HTML definition, such as embedded images). The following code copies all the files relating to a specific glossary entry from one such area to a different glossary item in a different glossary. Note that it changes the context ID and item ID of each file to represent the new context (for the different glossary module) and the new glossary entry (a new row was added to glossary_entries).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$fs = get_file_storage();&lt;br /&gt;
if ($files = $fs-&amp;gt;get_area_files($oldcontextid, &#039;mod_glossary&#039;, &#039;attachment&#039;, $oldentryid)) {&lt;br /&gt;
    foreach ($files as $file) {&lt;br /&gt;
        $fs-&amp;gt;create_file_from_storedfile(array(&lt;br /&gt;
                &#039;contextid&#039; =&amp;gt; $newcontextid,&lt;br /&gt;
                &#039;itemid&#039; =&amp;gt; $newentryid), $file);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== List area files ===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$fs = get_file_storage();&lt;br /&gt;
$files = $fs-&amp;gt;get_area_files($contextid, &#039;mod_assignment&#039;, &#039;submission&#039;, $submission-&amp;gt;id);&lt;br /&gt;
foreach ($files as $f) {&lt;br /&gt;
    // $f is an instance of stored_file&lt;br /&gt;
    echo $f-&amp;gt;get_filename();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or as links...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$out = array();&lt;br /&gt;
        &lt;br /&gt;
$fs = get_file_storage();&lt;br /&gt;
$files = $fs-&amp;gt;get_area_files($contextid, &#039;mod_assignment&#039;, &#039;submission&#039;, $submission-&amp;gt;id);&lt;br /&gt;
            &lt;br /&gt;
foreach ($files as $file) {&lt;br /&gt;
    $url = &amp;quot;{$CFG-&amp;gt;wwwroot}/pluginfile.php/{$file-&amp;gt;get_contextid()}/mod_assignment/submission}&amp;quot;;&lt;br /&gt;
    $filename = $file-&amp;gt;get_filename();&lt;br /&gt;
    $fileurl = $url.$file-&amp;gt;get_filepath().$file-&amp;gt;get_itemid().&#039;/&#039;.$filename;&lt;br /&gt;
    $out[] = html_writer::link($fileurl, $filename);&lt;br /&gt;
}&lt;br /&gt;
      &lt;br /&gt;
$br = html_writer::empty_tag(&#039;br&#039;);&lt;br /&gt;
        &lt;br /&gt;
return implode($br, $out);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create file ===&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how to create a file whose contents will be a text string. This is the equivalent of the PHP function &amp;lt;tt&amp;gt;file_put_contents&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$fs = get_file_storage();&lt;br /&gt;
&lt;br /&gt;
// Prepare file record object&lt;br /&gt;
$fileinfo = array(&lt;br /&gt;
    &#039;contextid&#039; =&amp;gt; $context-&amp;gt;id, // ID of context&lt;br /&gt;
    &#039;component&#039; =&amp;gt; &#039;mod_mymodule&#039;,     // usually = table name&lt;br /&gt;
    &#039;filearea&#039; =&amp;gt; &#039;myarea&#039;,     // usually = table name&lt;br /&gt;
    &#039;itemid&#039; =&amp;gt; 0,               // usually = ID of row in table&lt;br /&gt;
    &#039;filepath&#039; =&amp;gt; &#039;/&#039;,           // any path beginning and ending in /&lt;br /&gt;
    &#039;filename&#039; =&amp;gt; &#039;myfile.txt&#039;); // any filename&lt;br /&gt;
&lt;br /&gt;
// Create file containing text &#039;hello world&#039;&lt;br /&gt;
$fs-&amp;gt;create_file_from_string($fileinfo, &#039;hello world&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to create a file in the Moodle file area based on a &#039;real&#039; file e.g. in a temporary folder, you can use &amp;lt;tt&amp;gt;create_file_from_pathname&amp;lt;/tt&amp;gt; instead.&lt;br /&gt;
&lt;br /&gt;
Unlike with ordinary files, this method will not automatically overwrite an existing file. If you wish to overwrite a file, you must first get the file and (if it exists) delete it, and only then create it again.&lt;br /&gt;
&lt;br /&gt;
=== Read file ===&lt;br /&gt;
&lt;br /&gt;
This is a way to read a file, equivalent to &amp;lt;tt&amp;gt;file_get_contents&amp;lt;/tt&amp;gt;. &#039;&#039;&#039;Please note your are allowed to do this ONLY from mod/mymodule/* code, it is not acceptable to do this anywhere else.&#039;&#039;&#039; Other code has to use file_browser interface instead.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$fs = get_file_storage();&lt;br /&gt;
&lt;br /&gt;
// Prepare file record object&lt;br /&gt;
$fileinfo = array(&lt;br /&gt;
    &#039;component&#039; =&amp;gt; &#039;mod_mymodule&#039;,     // usually = table name&lt;br /&gt;
    &#039;filearea&#039; =&amp;gt; &#039;myarea&#039;,     // usually = table name&lt;br /&gt;
    &#039;itemid&#039; =&amp;gt; 0,               // usually = ID of row in table&lt;br /&gt;
    &#039;contextid&#039; =&amp;gt; $context-&amp;gt;id, // ID of context&lt;br /&gt;
    &#039;filepath&#039; =&amp;gt; &#039;/&#039;,           // any path beginning and ending in /&lt;br /&gt;
    &#039;filename&#039; =&amp;gt; &#039;myfile.txt&#039;); // any filename&lt;br /&gt;
&lt;br /&gt;
// Get file&lt;br /&gt;
$file = $fs-&amp;gt;get_file($fileinfo-&amp;gt;contextid, $fileinfo-&amp;gt;component, $fileinfo-&amp;gt;filearea, &lt;br /&gt;
        $fileinfo-&amp;gt;itemid, $fileinfo-&amp;gt;filepath, $fileinfo-&amp;gt;filename);&lt;br /&gt;
&lt;br /&gt;
// Read contents&lt;br /&gt;
if ($file) {&lt;br /&gt;
    $contents = $file-&amp;gt;get_content();&lt;br /&gt;
} else {&lt;br /&gt;
    // file doesn&#039;t exist - do something&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to access the file directly on disk, this is not permitted. Instead, you need to make a copy of the file in a temporary area and use that. You can do this with &amp;lt;tt&amp;gt;$file-&amp;gt;copy_content_to($pathname)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Delete file ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$fs = get_file_storage();&lt;br /&gt;
&lt;br /&gt;
// Prepare file record object&lt;br /&gt;
$fileinfo = array(&lt;br /&gt;
    &#039;component&#039; =&amp;gt; &#039;mod_mymodule&#039;,&lt;br /&gt;
    &#039;filearea&#039; =&amp;gt; &#039;myarea&#039;,     // usually = table name&lt;br /&gt;
    &#039;itemid&#039; =&amp;gt; 0,               // usually = ID of row in table&lt;br /&gt;
    &#039;contextid&#039; =&amp;gt; $context-&amp;gt;id, // ID of context&lt;br /&gt;
    &#039;filepath&#039; =&amp;gt; &#039;/&#039;,           // any path beginning and ending in /&lt;br /&gt;
    &#039;filename&#039; =&amp;gt; &#039;myfile.txt&#039;); // any filename&lt;br /&gt;
&lt;br /&gt;
// Get file&lt;br /&gt;
$file = $fs-&amp;gt;get_file($fileinfo-&amp;gt;contextid, $fileinfo-&amp;gt;component, $fileinfo-&amp;gt;filearea, &lt;br /&gt;
        $fileinfo-&amp;gt;itemid, $fileinfo-&amp;gt;filepath, $fileinfo-&amp;gt;filename);&lt;br /&gt;
&lt;br /&gt;
// Delete it if it exists&lt;br /&gt;
if ($file) {&lt;br /&gt;
    $file-&amp;gt;delete();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[File API]] how the File API works internally.&lt;br /&gt;
* [[Roadmap|Moodle 2.0 roadmap]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Files]]&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=XMLDB_defining_an_XML_structure&amp;diff=4771</id>
		<title>XMLDB defining an XML structure</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=XMLDB_defining_an_XML_structure&amp;diff=4771"/>
		<updated>2011-05-06T15:51:47Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* Conventions */ Fixed link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[XMLDB Documentation|XMLDB Documentation]] &amp;gt; [[XMLDB roadmap|Roadmap]] &amp;gt; Defining one XML structure&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Justification ==&lt;br /&gt;
&lt;br /&gt;
Before Moodle 1.7, all the DB install and upgrade was developed twice (once to handle MySQL installations and another to handle PostgreSQL installations). This approach, although working, has caused some headaches in the past, mainly because it was really difficult to keep both lines of development 100% on sync. Some developers do they work against one RDBMS and it was complex to develop to the other one (two test environments, skills on both databases, slower development cycle...). And all this was happening with &#039;&#039;only&#039;&#039; two supported RDBMS!&lt;br /&gt;
&lt;br /&gt;
One of the main objectives of Moodle 1.7 is to extend the the number of supported RDBMS to other flavours (more exactly, to Oracle and MSSQL). And the old approach (one line of development for each DB) could become an absolute nightmare. &lt;br /&gt;
&lt;br /&gt;
Because of this we have planned to build one structure to define all the DB objects used by Moodle. This structure will provide the necessary level of abstraction to be shared by all the RDBMS systems, so the &amp;quot;multiple lines of development&amp;quot; explained in the previous paragraph will be out forever, giving us one robust and well defined way to handle DB objects independently of the underlying RDBMS being used.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
Initially all our best wishes were to use the [http://phplens.com/lens/adodb/docs-datadict.htm#xmlschema AdoDB XML Schema]. As Moodle is using ADOdb libraries to communicate with databases it sounded like the natural approach to solve the problem. But, finally, two reasons prevented us to use it:&lt;br /&gt;
&lt;br /&gt;
# Although working, it seems to be one feature in progress, with important changes/evolutions arriving at the time of write this document.&lt;br /&gt;
# Its lack of support for &amp;quot;prefixes&amp;quot; (one Moodle key feature, to allow multiple instances to run in the same server), would force us to create some awful tricks to generate the objects.&lt;br /&gt;
&lt;br /&gt;
So, finally, we decided to build our own XML files, with everything we need to define every object present in the DB.&lt;br /&gt;
&lt;br /&gt;
== The XMLDB editor ==&lt;br /&gt;
[[XMLDB_editor | Main article]]&lt;br /&gt;
&lt;br /&gt;
Although the XML is pretty simple to read (and to write), one of the major drawbacks was its easy and error-prone adoption by the developers. Also some problems with versioning systems getting crazy with XML files (thanks ML!) pointed us to the requirement to use one high-density format (it means, physically &#039;&#039;&#039;long lines&#039;&#039;&#039;) in our XML files. &lt;br /&gt;
&lt;br /&gt;
After some intense thoughts we decided to build one specialised editor for our XML format. This editor should be easy to use and provide support for all the objects present one Moodle DB. And it&#039;s done (and will support future enhancements easily, we hope).&lt;br /&gt;
&lt;br /&gt;
The XMLDB Editor makes the addition of tables/fields/keys/indexes practically a trivial task, allowing the developer to spend  the time coding and improving things instead of fighting against XML files and the errors caused by manual editing (of course, the developer is free to use such extra-time as desired, beers, dance, books, music...) ;-)&lt;br /&gt;
&lt;br /&gt;
All the new &#039;&#039;&#039;install.xml&#039;&#039;&#039; files, present under each &#039;&#039;&#039;db&#039;&#039;&#039; directory in Moodle can be edited (and we recommend it) with just some clicks and keystrokes. Those &#039;&#039;&#039;install.xml&#039;&#039;&#039; will contain all the info needed to generate the specific objects needed for each RDBMS supported. Obviously, such files, are the neutral replacement for all the *.sql files used until now.&lt;br /&gt;
&lt;br /&gt;
=== Launching ===&lt;br /&gt;
&lt;br /&gt;
Just login to your server as an administrator and, under the Miscellaneous tab of the Administration Block, you&#039;ll see a new link pointing to the &amp;quot;XMLDB Editor&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
One &#039;&#039;&#039;important note&#039;&#039;&#039; is that, to be able to handle files properly, the web server needs write access to all those &amp;quot;db&amp;quot; directories where the &amp;quot;install.xml&amp;quot; files reside (and to the files themselves, of course). ;-)&lt;br /&gt;
&lt;br /&gt;
That&#039;s all!&lt;br /&gt;
&lt;br /&gt;
=== Use===&lt;br /&gt;
&lt;br /&gt;
We really think the XMLDB Editor is pretty easy to use, so here you won&#039;t see a complete guide to use it. We highly recommend you to play with it for a while, viewing how it works and how it modifies the &#039;&#039;&#039;install.xml&#039;&#039;&#039; files.&lt;br /&gt;
&lt;br /&gt;
It&#039;s organised in a top-botton structure, where you start &#039;&#039;&#039;loading&#039;&#039;&#039; (or &#039;&#039;&#039;creating&#039;&#039;&#039;) a new XMLDB file. Then, you can &#039;&#039;&#039;edit&#039;&#039;&#039; such file and its &#039;&#039;&#039;general structure&#039;&#039;&#039; will be showed. This structure have two type of elements, &#039;&#039;&#039;tables&#039;&#039;&#039; and &#039;&#039;&#039;statements&#039;&#039;&#039; and the XMLDB Editor allows you to &#039;&#039;&#039;add&#039;&#039;&#039;, &#039;&#039;&#039;edit&#039;&#039;&#039;, &#039;&#039;&#039;delete&#039;&#039;&#039;, and &#039;&#039;&#039;move&#039;&#039;&#039; them easily. Also, for initial creation of tables, one small but effective &#039;&#039;&#039;reverse-enginery&#039;&#039;&#039; tool has been developed (only under MySQL) allowing you to retrofit any table from the DB to the XMLDB Editor.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note: If you can&#039;t click on the create links....&#039;&#039;&#039; you must first create the /db folder (as shown in the list, but it may not really exist) and then make sure it is writeable by the webserver&lt;br /&gt;
&lt;br /&gt;
While editing tables you will see their &#039;&#039;&#039;fields&#039;&#039;&#039;, &#039;&#039;&#039;keys&#039;&#039;&#039; and &#039;&#039;&#039;indexes&#039;&#039;&#039; and you&#039;ll be able to handle all them easily. Note that some fields can be no-editable. It uses to be because they are being used in some way (part of one key or index) and the idea is to warn you about that.&lt;br /&gt;
&lt;br /&gt;
Fields can be edited and you can specify their &#039;&#039;&#039;name&#039;&#039;&#039;, &#039;&#039;&#039;type&#039;&#039;&#039;, &#039;&#039;&#039;length&#039;&#039;&#039;, &#039;&#039;&#039;decimals&#039;&#039;&#039;, &#039;&#039;&#039;null-ability&#039;&#039;&#039;, &#039;&#039;&#039;defaults&#039;&#039;&#039; and so one. Exactly the same for both &#039;&#039;&#039;keys&#039;&#039;&#039; and &#039;&#039;&#039;indexes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
While editing statements, you must think about them like &amp;quot;collections of sentences&amp;quot;. Once you select the &#039;&#039;&#039;type&#039;&#039;&#039; (only inserts are allowed for now) and &#039;&#039;&#039;table&#039;&#039;&#039; you are interested you&#039;ll be able to introduce the exact values easily, being able to &#039;&#039;&#039;duplicate&#039;&#039;&#039; them easily to gain some speed if you have a lot of sentences in your development. Sentences can be &#039;&#039;&#039;edited&#039;&#039;&#039; and &#039;&#039;&#039;deleted&#039;&#039;&#039; easily too.&lt;br /&gt;
&lt;br /&gt;
One interesting feature is that all the XMLDB Editor pages allow you to enter one &#039;&#039;&#039;comment&#039;&#039;&#039; about the item being modified (table, index, key, field, statement...). Use it at your entire needs, sure it helps other developers to understand a bit more the DB model.&lt;br /&gt;
&lt;br /&gt;
Please, don&#039;t forget to read and understand the next section, where we talk about &#039;&#039;&#039;some important guidelines&#039;&#039;&#039; to create and handle XMLDB files.&lt;br /&gt;
&lt;br /&gt;
== Conventions ==&lt;br /&gt;
&lt;br /&gt;
Apart of the [[Database| Database Structures guidelines]], some more conventions should be followed:&lt;br /&gt;
&lt;br /&gt;
# About names:&lt;br /&gt;
## All lowercase names (tables, indexes, keys and fields).&lt;br /&gt;
## Table names and field names must use only a-z, 0-9 and _ chars. Table names can be at most 28 characters long; column names at most 30 characters.&lt;br /&gt;
## Key and index names under the XMLDB Files must be formed by concatenating the name of the fields present in the key/index with the &#039;&amp;quot;-&amp;quot; (minus) character.&lt;br /&gt;
## Primary key always must be named &amp;quot;primary&amp;quot; (this is one exception to the previous convention).&lt;br /&gt;
## It&#039;s highly recommended to avoid [[XMLDB_reserved_words|reserved words]] completely. We know we have some of them now but they should be completely out for next releases.&lt;br /&gt;
# About NULLS&lt;br /&gt;
## Avoid to create all the fields as NOT NULL with the &#039;&#039;silly&#039;&#039; default value &amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt; (empty string). The underlying code used to create tables will handle it properly but the XMLDB structure must be REAL. Read more in the [[XMLDB_Problems#NOT_NULL_fields_using_a_DEFAULT_.27.27_clause|Problems Page]].&lt;br /&gt;
# About FOREIGN KEYS&lt;br /&gt;
## Under the tables of every XMLDB file, you must define the existing &#039;&#039;&#039;Foreign Keys&#039;&#039;&#039; (FK) properly. This will allow everybody to know a bit better the structure, allow to evolve to a better constrained system in the future and will provide the underlying code with the needed info to create the proper indexes. &lt;br /&gt;
## Note that, if you define any field combination as FK you won&#039;t have to create any index on that fields, the code will do it automatically! &lt;br /&gt;
## This convention is only applicable for relations INSIDE one file. Don&#039;t generate FK constraints against other files (courseid, userid), use indexes there.&lt;br /&gt;
## Respect Convention 1.3&lt;br /&gt;
# About UNIQUE KEYS&lt;br /&gt;
## Declare any fields as UNIQUE KEY (UK) only if they are going to be used as target for one FK. Create unique indexes instead.&lt;br /&gt;
## Respect Convention 1.3&lt;br /&gt;
&lt;br /&gt;
== One example: the assignment module ==&lt;br /&gt;
&lt;br /&gt;
Here we are going to examine the [http://cvs.moodle.org/moodle/mod/assignment/db/install.xml?view=markup current implementation of the XMLDB Schema for the assignment module] (a simple one). It has been completely generated with the XMLDB Editor but it&#039;s nice to know a bit more about the XML internals.&lt;br /&gt;
&lt;br /&gt;
As you can see the structure is pretty simple:&lt;br /&gt;
&lt;br /&gt;
* XMLDB&lt;br /&gt;
** TABLES, one or more, each one with&lt;br /&gt;
*** FIELDS&lt;br /&gt;
*** KEYS&lt;br /&gt;
*** INDEXES&lt;br /&gt;
** STATEMENTS, none or more, each one with&lt;br /&gt;
*** SENTENCES&lt;br /&gt;
&lt;br /&gt;
First of all you should note that all the elements contain the &#039;&#039;&#039;PREVIOUS&#039;&#039;&#039; and &#039;&#039;&#039;NEXT&#039;&#039;&#039; attributes. They allow us to keep everything ordered although it isn&#039;t meaningful at all from the RDBMS perspective. Also the &#039;&#039;&#039;COMMENT&#039;&#039;&#039; field is present everywhere to be used as desired.&lt;br /&gt;
&lt;br /&gt;
=== The TABLE element ===&lt;br /&gt;
&lt;br /&gt;
We can ignore the TABLE element, as it&#039;s simply one container for the internals (FIELDS, KEYS and INDEXES). Let&#039;s go to examine them a bit more:&lt;br /&gt;
&lt;br /&gt;
==== The FIELD element ====&lt;br /&gt;
&lt;br /&gt;
It maps with one field in the DB (obviously). For each field you can define its &#039;&#039;&#039;name&#039;&#039;&#039;, &#039;&#039;&#039;type&#039;&#039;&#039; (from a list of [[XMLDB column types|neutral types]]), &#039;&#039;&#039;length&#039;&#039;&#039;, &#039;&#039;&#039;decimals&#039;&#039;&#039; (for some types), &#039;&#039;&#039;notnull&#039;&#039;&#039; (true/false), &#039;&#039;&#039;unsigned&#039;&#039;&#039; (true/false), &#039;&#039;&#039;sequence&#039;&#039;&#039; (if it&#039;s autonumeric or serial, true/false), &#039;&#039;&#039;enum&#039;&#039;&#039; (true/false), &#039;&#039;&#039;enumvalues&#039;&#039;&#039; (the list of values if the field has been declared as enum, for example &amp;lt;tt&amp;gt;&#039;frog&#039;,&#039;toad&#039;,&#039;newt&#039;&amp;lt;/tt&amp;gt;) and &#039;&#039;&#039;default&#039;&#039;&#039; (to assign a default value).&lt;br /&gt;
&lt;br /&gt;
So, in our example, we have two tables, assignment and assignment_submissions, each one with its own fields, defining all the information related above. Please note that naming conventions are followed.&lt;br /&gt;
&lt;br /&gt;
==== The KEY element ====&lt;br /&gt;
&lt;br /&gt;
Here is where all the PRIMARY KEYS (PK), UNIQUE KEYS (UK) and FOREIGN KEYS (FK) will be defined. For each key we define its &#039;&#039;&#039;name&#039;&#039;&#039;, &#039;&#039;&#039;type&#039;&#039;&#039;, &#039;&#039;&#039;fields&#039;&#039;&#039; (that belongs to it) and optionally (if the key is one FK) the target &#039;&#039;&#039;reftable&#039;&#039;&#039; and &#039;&#039;&#039;reffields&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In our example, the assignment table has one (mandatory!) PK (called, &amp;quot;primary&amp;quot;, rules are rules) built with the &amp;quot;id&amp;quot; field. &lt;br /&gt;
&lt;br /&gt;
The other table, the &amp;quot;assignment_submissions&amp;quot; one, also has its PK (called &amp;quot;primary&amp;quot; once more) and one FK, with the field &amp;quot;assignment&amp;quot; pointing to the field &amp;quot;id&amp;quot; of the table &amp;quot;assignment&amp;quot;. Note that the FK follows the name conventions and its name is, simply, the name of the fields being part of it (&amp;quot;assignment&amp;quot;). Also, the FK has as target to one PK of the same module.&lt;br /&gt;
&lt;br /&gt;
Finally, note that there isn&#039;t any index created for all these keys. Moodle will generate them automatically when the table is created. All the keys will have their corresponding index. Point. ;-)&lt;br /&gt;
&lt;br /&gt;
==== The INDEX element ====&lt;br /&gt;
&lt;br /&gt;
Where all the indexes will be defined. For each index you can define its &#039;&#039;&#039;name&#039;&#039;&#039;, &#039;&#039;&#039;unique&#039;&#039;&#039; (true/false) and the &#039;&#039;&#039;fields&#039;&#039;&#039; that conform it. Please note that naming conventions are followed.&lt;br /&gt;
&lt;br /&gt;
Also, some &amp;quot;obvious index&amp;quot;, like the one based in the &amp;quot;assignment&amp;quot; field of the &amp;quot;assignment_submissions&amp;quot; table doesn&#039;t exist. Yes, you know why: Because such column has been defined as a FK and the index will be automatically created (see previous section).&lt;br /&gt;
&lt;br /&gt;
=== The STATEMENT element ===&lt;br /&gt;
&lt;br /&gt;
This is the other &#039;&#039;&#039;big container&#039;&#039;&#039; in the XMLDB Schema (at the same level as the &#039;&#039;&#039;TABLES&#039;&#039;&#039; one) and we can define its &#039;&#039;&#039;name&#039;&#039;&#039;, &#039;&#039;&#039;type&#039;&#039;&#039; (only insert allowed for now) and &#039;&#039;&#039;table&#039;&#039;&#039; (against the sentences will be executed).&lt;br /&gt;
&lt;br /&gt;
Every statement is a collection of &#039;&#039;&#039;sentences&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
==== The SENTENCE element ====&lt;br /&gt;
&lt;br /&gt;
Each sentence implies one simple action to be performed against the DB and it can be defined as the &amp;quot;missing part of the SQL statement&amp;quot;. In our example, we have one statement, of type &amp;quot;insert&amp;quot; on table &amp;quot;log_display&amp;quot;. With this Moodle knows the initial part of the sentence, i.e:&lt;br /&gt;
&lt;br /&gt;
 INSERT INTO log_display &lt;br /&gt;
&lt;br /&gt;
and then the text will be added to create this:&lt;br /&gt;
&lt;br /&gt;
 INSERT INTO log_display &lt;br /&gt;
   (module, action, mtable, field) &lt;br /&gt;
 VALUES &lt;br /&gt;
   (&#039;assignment&#039;, &#039;view&#039;, &#039;assignment&#039;, &#039;name&#039;)&lt;br /&gt;
&lt;br /&gt;
There is one important trick when handling sentences, although they aren&#039;t in the assignment example. Take a look to the [http://cvs.moodle.org/moodle/lib/db/install.xml?view=co Core Tables XML Schema] (it&#039;s a huge one!). If you go near the end, to the statements section, you will see some sentences like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;SENTENCE TEXT=&amp;quot;....VALUES (&#039;user&#039;, &#039;view&#039;, &#039;user&#039;, &#039;CONCAT(firstname,&amp;quot; &amp;quot;,lastname)&#039;)&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Such &amp;quot;CONCAT&amp;quot; function isn&#039;t standard at all (only MySQL supports it), but don&#039;t worry, we&#039;ll transform it to the correct concatenation operators for other RDBMS. Just be sure to use the syntax showed above.&lt;br /&gt;
&lt;br /&gt;
== DTD and XML schema ==&lt;br /&gt;
&lt;br /&gt;
Not sure if this will be usable for somebody but here you can find one [http://cvs.moodle.org/moodle/lib/xmldb/xmldb.dtd?view=co automatically generated DTD] for the XMLDB files. Also one [http://cvs.moodle.org/moodle/lib/xmldb/xmldb.xsd?view=co automatically generated XML Schema] is available. Any improvement/fix to them will be welcome!&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[XMLB List of files to create|List of files to create]]: The list of files to be created from scratch. Used to follow the progress.&lt;br /&gt;
* http://www.hitsw.com/xml_utilites/: One online XML-DTD-Schema converter.&lt;br /&gt;
&lt;br /&gt;
[[Category:XMLDB]]&lt;br /&gt;
[[Category:DB]]&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Creating_a_theme_settings_page&amp;diff=17840</id>
		<title>Creating a theme settings page</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Creating_a_theme_settings_page&amp;diff=17840"/>
		<updated>2011-05-03T22:56:58Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* How settings pages work in Moodle */ typo&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 [[Themes 2.0 creating your first theme|creating your first theme]]. If you haven&#039;t go read it now because I&#039;m not going to go into much detail until we get to the actual process of customising the theme and introducing the settings page.&lt;br /&gt;
&lt;br /&gt;
So before we finally get this started please ensure you can check off everything on the following requirements list.&lt;br /&gt;
* Have a Moodle installation that has already been installed and configured and is ready to use.&lt;br /&gt;
* Have full read/write access to that installation.&lt;br /&gt;
* Be prepared to delete that installation at the end of this... we will destroy it!&lt;br /&gt;
* Have a development environment prepared and ready to use. This includes:&lt;br /&gt;
** Your favourite editor installed, running, and pointed at the themes directory of your installation.&lt;br /&gt;
** Your browser open and your site visible.&lt;br /&gt;
** A bottomless coffee pot... decaf won&#039;t help you with this one.&lt;br /&gt;
* Have set the following settings:&lt;br /&gt;
** &#039;&#039;&#039;themedesignermode&#039;&#039;&#039; if you don&#039;t know what this is please read the [[Themes 2.0 creating your first theme|creating your first theme]] tutorial.&lt;br /&gt;
** &#039;&#039;&#039;allowthemechangeonurl&#039;&#039;&#039; turn this on, it allows you to change themes on the URL and is very handy when developing themes. &#039;&#039;Site Administration &amp;gt; Appearance &amp;gt; Themes &amp;gt; Theme settings&#039;&#039;&lt;br /&gt;
** &#039;&#039;&#039;langstringcache&#039;&#039;&#039; if you don&#039;t turn this off you won&#039;t see your strings when they are added. &#039;&#039;Site Administration &amp;gt; Language &amp;gt; Language settings&#039;&#039;&lt;br /&gt;
* And finally an insane ambition to create a customisable theme.&lt;br /&gt;
&lt;br /&gt;
For those interested the theme that I create throughout this tutorial can be downloaded from the forum post in which I announce this document: http://moodle.org/mod/forum/discuss.php?d=152053&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:right;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Our goals for this tutorial==&lt;br /&gt;
The following is just a list goals that I hope to achieve during this tutorial. They are laid out here so that I can easily refer back to them and so that you can easily find them.&lt;br /&gt;
# Create a new theme called &#039;&#039;&#039;demystified&#039;&#039;&#039; based upon the standard theme within Moodle 2.0.&lt;br /&gt;
# Make some minor changes to that theme to allow us to more easily see what is going on.&lt;br /&gt;
# Create a settings page for the demystified theme.&lt;br /&gt;
# Add several settings to our settings page.&lt;br /&gt;
# Use some of those settings to alter our CSS.&lt;br /&gt;
# Use the rest of those settings within our layout file..&lt;br /&gt;
# Discuss the good, the bad, and limits of what we have just created.&lt;br /&gt;
&lt;br /&gt;
So I can see you are all very excited about this point and that you would love to know what settings we are going to create; So here they are:&lt;br /&gt;
&lt;br /&gt;
A setting to ...&lt;br /&gt;
* change the background colour (CSS).&lt;br /&gt;
* set the path to an image that we will use as a logo on all pages (Layout files).&lt;br /&gt;
* override the width of the block regions (CSS).&lt;br /&gt;
* allow a note to be added to the footer of all pages (Layout files).&lt;br /&gt;
* allow custom CSS to be written to do anything the user wants. (CSS)&lt;br /&gt;
&lt;br /&gt;
==Creating the demystified theme==&lt;br /&gt;
Before we start here I want to remind you that I am going to look at this only briefly as I am making the assumption that you have read the [[Themes 2.0 creating your first theme|creating your first theme]] tutorial.&lt;br /&gt;
&lt;br /&gt;
Well lets get into it....&lt;br /&gt;
&lt;br /&gt;
The first thing we need to do is create a directory for our theme which we will call demystified. &lt;br /&gt;
&lt;br /&gt;
So within your Moodle directory create the following folder &#039;&#039;&#039;moodle/theme/demystified&#039;&#039;&#039;. At the same time you can also create the following files and folders which we will get to soon.&lt;br /&gt;
* The file &#039;&#039;&#039;moodle/theme/demystified/config.php&#039;&#039;&#039; for our config information.&lt;br /&gt;
* The directory &#039;&#039;&#039;moodle/theme/demystified/layout&#039;&#039;&#039; for our layout files.&lt;br /&gt;
* The directory &#039;&#039;&#039;moodle/theme/demystified/style&#039;&#039;&#039; for our css files.&lt;br /&gt;
* The file &#039;&#039;&#039;moodle/theme/demystified/style/core.css&#039;&#039;&#039; which will contain our special CSS.&lt;br /&gt;
&lt;br /&gt;
Next we will copy the layout files from the base theme to our new theme demystified. We are basing the demystified theme on the standard theme however that doesn&#039;t use it&#039;s own layout files it uses the base theme&#039;s layout files so those are the ones we want. &lt;br /&gt;
&lt;br /&gt;
The reason that we are coping these layout files is that later on in this tutorial we will be modifying them to make use of our new settings... so copy all of the layout files from &#039;&#039;&#039;moodle/theme/base/layout&#039;&#039;&#039; to &#039;&#039;&#039;moodle/theme/demystified/layout&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
There should be three files that you just copied:&lt;br /&gt;
# embedded.php&lt;br /&gt;
# frontpage.php&lt;br /&gt;
# general.php&lt;br /&gt;
&lt;br /&gt;
Now we need to populate demystified/config.php with the settings for our new theme. They are as follows:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;name = &#039;demystified&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Simply sets the name of our theme.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;,&#039;base&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This theme is extending both the standard theme and the base theme. Remember when extending a theme you also need to extend its parents or things might not work correctly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;core&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This tells our theme that we want to use the file &#039;&#039;&#039;demystified/style/core.css&#039;&#039;&#039; with this theme.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;height:300px;overflow-y:scroll;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Most backwards compatible layout without the blocks - this is the layout used by default&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
    ),&lt;br /&gt;
    // Standard layout with blocks, this is recommended for most pages with general information&lt;br /&gt;
    &#039;standard&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // Main course page&lt;br /&gt;
    &#039;course&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;coursecategory&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // part of course, typical for modules - default page layout if $cm specified in require_login()&lt;br /&gt;
    &#039;incourse&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // The site home page.&lt;br /&gt;
    &#039;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;frontpage.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // Server administration scripts.&lt;br /&gt;
    &#039;admin&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // My dashboard page&lt;br /&gt;
    &#039;mydashboard&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // My public page&lt;br /&gt;
    &#039;mypublic&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;login&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    // Pages that appear in pop-up windows - no navigation, no blocks, no header.&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // No blocks and minimal footer - used for legacy frame layouts only!&lt;br /&gt;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible&lt;br /&gt;
    &#039;embedded&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Used during upgrade and install, and for the &#039;This site is undergoing maintenance&#039; message.&lt;br /&gt;
    // This must not have any blocks, and it is good idea if it does not have links to&lt;br /&gt;
    // other places - for example there should not be a home link in the footer...&lt;br /&gt;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Now that all looks very complicated however its really not too bad as it is just copied from the base theme&#039;s config.php file. We can do this because we copied the layout files from the base theme to begin with and for the time being there are no changes that we wish to make. Simply open up &#039;&#039;&#039;theme/base/config.php&#039;&#039;&#039; and copy the layouts from there.&lt;br /&gt;
&lt;br /&gt;
And that is it. The config.php file for our demystified theme is complete. The full source is shown below:&lt;br /&gt;
&amp;lt;div style=&amp;quot;height:300px;overflow-y:scroll;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
// This file is part of Moodle - http://moodle.org/&lt;br /&gt;
//&lt;br /&gt;
// Moodle is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// Moodle is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with Moodle.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * The demystified theme config file&lt;br /&gt;
 *&lt;br /&gt;
 * This theme was created to document the process of adding a settings page to a theme&lt;br /&gt;
 *&lt;br /&gt;
 * @copyright 2010 Sam Hemelryk&lt;br /&gt;
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
// The name of our theme&lt;br /&gt;
$THEME-&amp;gt;name = &#039;demystified&#039;;&lt;br /&gt;
&lt;br /&gt;
// The other themes this theme extends&lt;br /&gt;
$THEME-&amp;gt;parents = array(&#039;standard&#039;,&#039;base&#039;);&lt;br /&gt;
&lt;br /&gt;
// The CSS files this theme uses (located in the style directory)&lt;br /&gt;
$THEME-&amp;gt;sheets = array(&#039;core&#039;);&lt;br /&gt;
&lt;br /&gt;
// The layout definitions for this theme&lt;br /&gt;
$THEME-&amp;gt;layouts = array(&lt;br /&gt;
    // Most backwards compatible layout without the blocks - this is the layout used by default&lt;br /&gt;
    &#039;base&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
    ),&lt;br /&gt;
    // Standard layout with blocks, this is recommended for most pages with general information&lt;br /&gt;
    &#039;standard&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // Main course page&lt;br /&gt;
    &#039;course&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;coursecategory&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // part of course, typical for modules - default page layout if $cm specified in require_login()&lt;br /&gt;
    &#039;incourse&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // The site home page.&lt;br /&gt;
    &#039;frontpage&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;frontpage.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // Server administration scripts.&lt;br /&gt;
    &#039;admin&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-pre&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    // My dashboard page&lt;br /&gt;
    &#039;mydashboard&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // My public page&lt;br /&gt;
    &#039;mypublic&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(&#039;side-pre&#039;, &#039;side-post&#039;),&lt;br /&gt;
        &#039;defaultregion&#039; =&amp;gt; &#039;side-post&#039;,&lt;br /&gt;
    ),&lt;br /&gt;
    &#039;login&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;langmenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
    // Pages that appear in pop-up windows - no navigation, no blocks, no header.&lt;br /&gt;
    &#039;popup&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // No blocks and minimal footer - used for legacy frame layouts only!&lt;br /&gt;
    &#039;frametop&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible&lt;br /&gt;
    &#039;embedded&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;embedded.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
    // Used during upgrade and install, and for the &#039;This site is undergoing maintenance&#039; message.&lt;br /&gt;
    // This must not have any blocks, and it is good idea if it does not have links to&lt;br /&gt;
    // other places - for example there should not be a home link in the footer...&lt;br /&gt;
    &#039;maintenance&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;file&#039; =&amp;gt; &#039;general.php&#039;,&lt;br /&gt;
        &#039;regions&#039; =&amp;gt; array(),&lt;br /&gt;
        &#039;options&#039; =&amp;gt; array(&#039;noblocks&#039;=&amp;gt;true, &#039;nofooter&#039;=&amp;gt;true, &#039;nonavbar&#039;=&amp;gt;true, &#039;nocustommenu&#039;=&amp;gt;true),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The screenshot below shows both the directory structure we have now created and the theme presently.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.01.png]]&lt;br /&gt;
&lt;br /&gt;
To view the theme so far open you browser and enter the URL of your site followed by &#039;&#039;&#039;?theme=demystified&#039;&#039;&#039;. You should see the theme that we just created which will look exactly like the base standard theme.&lt;br /&gt;
&lt;br /&gt;
The final thing that we want to do is add a little bit of CSS to the demystified theme that will both visually set this theme apart from the standard theme and second build a the base which our settings can later extend.&lt;br /&gt;
&lt;br /&gt;
I added the following snippet of CSS to the file &#039;&#039;&#039;demystified/style/core.css&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
html {background-color:#DDD;}&lt;br /&gt;
body {margin:30px;padding:0;border:1px solid #333;border-width:0 10px 0 10px;background-color:#333;}&lt;br /&gt;
body #page {background-color:#FFF;position:relative;top:-10px;}&lt;br /&gt;
.block .header {background-image:none;background-color:#0C5CAC;border:1px solid #0C5CAC;color:#FFF;}&lt;br /&gt;
.block {border-color:#4BA7FF;background-color:#DDEEFF;}&lt;br /&gt;
.block .content {background-color:#F1F8FF;}&lt;br /&gt;
a:link,&lt;br /&gt;
a:visited {color:#0C5CAC;}&lt;br /&gt;
a:hover {color:#C77500;}&lt;br /&gt;
#page #page-header {background-color:#0C5CAC;margin:0;padding:0;width:100%;color:#fff;}&lt;br /&gt;
#page #page-header a:link, #page #page-header a:visited {color:#FFAC02}&lt;br /&gt;
#page #page-header .navbar, #page #page-header .navbar a:link, #page #page-header .navbar a:visited {color:#0C5CAC;}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The CSS that we have just added to our theme sets a couple of colours on the front page. Presently this is the only CSS I will add, I know it isn&#039;t complete by any means but it achieves it&#039;s purpose as the screenshot below illustrates.&lt;br /&gt;
&lt;br /&gt;
[[Image:Theme.settings.page.02.png|715px|thumb|left|The newly styles demystified theme]]&amp;lt;br style=&amp;quot;clear:both;&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And with that I will move on to the real purpose of this tutorial, creating the settings page&lt;br /&gt;
&lt;br /&gt;
==Setting up the settings page==&lt;br /&gt;
With the demystified theme set up it is time to create the settings page. This is where the real PHP fun begins.&lt;br /&gt;
&lt;br /&gt;
For those of you who happen to be familiar with development of modules, blocks or other plugin types you have probably encountered settings pages before and this is not going to be any different.&lt;br /&gt;
&lt;br /&gt;
However for those who haven&#039;t which I imagine is most of you this is going to be quite a challenge. I will try to walk through this step by step however if at any point you get stuck don&#039;t hesitate to ask in the forums as I imagine you will get a speedy response.&lt;br /&gt;
&lt;br /&gt;
===How settings pages work in Moodle===&lt;br /&gt;
Settings pages can be used by nearly every plugin type, of which themes is of course one. The way in which it all works isn&#039;t too tricky to understand. &lt;br /&gt;
&lt;br /&gt;
All of the settings for Moodle can be configured through the administrator interfaces when logged in. I am sure that everyone here has seen those pages and has changed a setting or two before so you will all know what I am talking about. Well the settings page for a theme is no different. It will be shown in the administration pages tree under &#039;&#039;&#039;Appearance &amp;gt; Themes&#039;&#039;&#039; and all we have to do is tell Moodle what settings there are.&lt;br /&gt;
&lt;br /&gt;
This is done by creating a settings.php file within our theme into which we will add code that tells Moodle about the settings we want to add/use.&lt;br /&gt;
&lt;br /&gt;
When telling Moodle about each setting we are simply creating a new &#039;&#039;admin_setting&#039;&#039; instance of the type we want and the properties we want and then adding it to our settings page.&lt;br /&gt;
&lt;br /&gt;
There is really not much more too it at this level. Things can get very complex very fast so the best thing we can do now is start creating our settings.php file for the demystified theme and see where it leads us.&lt;br /&gt;
&lt;br /&gt;
===Creating the settings page===&lt;br /&gt;
So as mentioned before we need a settings.php file which we will create now. To begin with create the file &#039;&#039;&#039;theme/demystified/settings.php&#039;&#039;&#039; and open it in your favourite editor so its ready to go.&lt;br /&gt;
&lt;br /&gt;
Before we start adding code however lets just remember the settings that we want to create:&lt;br /&gt;
* change the background colour (CSS).&lt;br /&gt;
* set the path to an image that we will use as a logo on all pages (Layout files).&lt;br /&gt;
* override the width of the block regions (CSS).&lt;br /&gt;
* allow a note to be added to the footer of all pages (Layout files).&lt;br /&gt;
* allow custom CSS to be written to do anything the user wants. (CSS)&lt;br /&gt;
&lt;br /&gt;
Alright.&lt;br /&gt;
&lt;br /&gt;
Now thinking about this the first setting is as basic as it gets, all we need is a text box that the user can type a colour into.&lt;br /&gt;
&lt;br /&gt;
The second is to allow a logo to be used in the header of each page. What we want here is a path but should it be a physical path e.g. C:/path/to/image.png or should it be a web path e.g. &amp;lt;nowiki&amp;gt;http://mysite.com/path/to/image.png&amp;lt;/nowiki&amp;gt;?&lt;br /&gt;
For the purpose of this tutorial I am going to go with a web path because it is going to be easier to code and will hopefully be a little easier to understand to begin with.&lt;br /&gt;
&lt;br /&gt;
The third setting is a little more complex. For this I want a drop down box with some specific widths that the administrator can select.&lt;br /&gt;
&lt;br /&gt;
The forth and the fifth settings are both pretty straight forward, there we want a textarea into which the user can enter what ever they want and we will do something useful with it.&lt;br /&gt;
&lt;br /&gt;
Now that we have an understanding about the settings we wish to define pull up your editor and lets start coding....&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Settings for the demystified theme&lt;br /&gt;
 */&lt;br /&gt;
&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;
* [[Themes 2.0]]&lt;br /&gt;
* [[Themes 2.0 creating your first theme]]&lt;br /&gt;
* [[Themes 2.0 overriding a renderer]]&lt;br /&gt;
* [[Themes_2.0 adding upgrade code]]&lt;br /&gt;
* [[Styling and customising the dock]]&lt;br /&gt;
* http://moodle.org/mod/forum/discuss.php?d=152053&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Database&amp;diff=13571</id>
		<title>Database</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Database&amp;diff=13571"/>
		<updated>2011-02-14T14:11:35Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: Added bit about pluralised table names&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Database structures==&lt;br /&gt;
&lt;br /&gt;
To help you create tables that meet these guidelines, we recommend you use the built in [[XMLDB_defining_an_XML_structure#The_XMLDB_editor|database definition (XMLDB) editor]].&lt;br /&gt;
&lt;br /&gt;
# Every table must have an auto-incrementing id field (INT10) as primary key. (see [[IdColumnReasons]])&lt;br /&gt;
# The main table containing instances of each module must have the same name as the module (eg widget) and contain the following minimum fields:&lt;br /&gt;
#* id - as described above&lt;br /&gt;
#* course - the id of the course that each instance belongs to&lt;br /&gt;
#* name - the full name of each instance of the module&lt;br /&gt;
# Other tables associated with a module that contain information about &#039;things&#039; should be named widget_things (note the plural).&lt;br /&gt;
# Core tables in general should have single word names non-pluralised, and double word names pluralised only for the last letter e.g. &#039;course&#039;, &#039;course_categories&#039;. The only exceptions should be for reserved words e.g. &#039;files&#039;. Some tables don&#039;t fit this pattern right now for historical reasons, but this will eventually be changed.&lt;br /&gt;
# Table and column names should avoid using [[Database reserved words|reserved words in any database]]. Please check them before creation. Table names may be up to 28 characters long, and Column names up to 30 characters. &lt;br /&gt;
# Column names should be always lowercase, simple and short, following the same rules as for variable names.&lt;br /&gt;
# Where possible, columns that contain a reference to the id field of another table (eg widget) should be called widgetid. (Note that this convention is newish and not followed in some older tables)&lt;br /&gt;
# Boolean fields should be implemented as small integer fields (eg INT4) containing 0 or 1, to allow for later expansion of values if necessary.&lt;br /&gt;
# Most tables should have a timemodified field (INT10) which is updated with a current timestamp obtained with the PHP time() function.&lt;br /&gt;
# Always define a default value for each field (and make it sensible)&lt;br /&gt;
# Each table name should start with the database prefix ($CFG-&amp;gt;prefix). In a lot of cases, this is taken care of for you automatically. Also, under Postgres, the name of every index must start with the prefix too.&lt;br /&gt;
# In order to guarantee [[XMLDB problems#Table and column aliases - the AS keyword|cross-db compatibility]] follow these simple rules about the use of the &#039;&#039;&#039;AS&#039;&#039;&#039; keyword (only if you need table/column aliases, of course):&lt;br /&gt;
#* &#039;&#039;&#039;Don&#039;t use&#039;&#039;&#039; the &#039;&#039;&#039;AS&#039;&#039;&#039; keyword for &#039;&#039;&#039;table aliases&#039;&#039;&#039;.&lt;br /&gt;
#* &#039;&#039;&#039;Do use&#039;&#039;&#039; the &#039;&#039;&#039;AS&#039;&#039;&#039; keyword for &#039;&#039;&#039;column aliases&#039;&#039;&#039;.&lt;br /&gt;
# &#039;&#039;&#039;Never&#039;&#039;&#039; create UNIQUE KEYs (constraints) at all. Instead use UNIQUE INDEXes. In the future, if we decide to add referential integrity to Moodle and we need UNIQUE KEYs they will be used, but not now. Please note that the XMLDB editor allows you to specify both XMLDB-only UNIQUE and FOREIGN constraints (and that&#039;s good, in order to have the XML well defined) but only underlying INDEXes will be generated. &lt;br /&gt;
# Those XMLDB-only UNIQUE KEYs (read previous point) only must be defined if such field/fields &#039;&#039;&#039;are going to be the target&#039;&#039;&#039; for some (XMLDB-only too) FOREIGN KEY. Else, create them as simple UNIQUE INDEXes.&lt;br /&gt;
# Tables associated &#039;&#039;&#039;with one block&#039;&#039;&#039; must follow this convention with their names: &#039;&#039;&#039;$CFG-&amp;gt;prefix + &amp;quot;block_&amp;quot; + name_of_the_block + anything_else&#039;&#039;&#039;. For example, assuming that $CFG-&amp;gt;prefix is &#039;mdl_&#039;, all the tables for the block &amp;quot;rss_client&amp;quot; must start by &#039;mdl_block_rss_client&#039; (being possible to add more words at the end, i.e. &#039;mdl_block_rss_client_anothertable&#039;...). This rule will be 100% enforced with Moodle 2.0, giving time to developers until then. See [http://tracker.moodle.org/browse/MDL-6786 Task 6786] for more info about this.&lt;br /&gt;
# &#039;&#039;&#039;Never&#039;&#039;&#039; make database changes in the STABLE branches.  If we did, then users upgrading from one stable version to the next would have duplicate changes occurring, which may cause serious errors.&lt;br /&gt;
# When refering to integer variable in SQL queries, do not surround the value in quotes. For example, get_records_select(&#039;question&#039;, &amp;quot;category=$catid&amp;quot;) is right. get_records_select(&#039;question&#039;, &amp;quot;category=&#039;$catid&#039;&amp;quot;) is wrong. It hides bugs where $catid is undefined. ([http://moodle.org/mod/forum/discuss.php?d=80629 This thread explains].)&lt;br /&gt;
&lt;br /&gt;
[[Category:Coding guidelines|Database]]&lt;br /&gt;
[[Category:DB|Database]]&lt;br /&gt;
[[Category:XMLDB|Database]]&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=DB_layer_2.0_migration_docs&amp;diff=9128</id>
		<title>DB layer 2.0 migration docs</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=DB_layer_2.0_migration_docs&amp;diff=9128"/>
		<updated>2011-02-08T16:23:22Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* The golden changes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Development:dmllib 2.0}}{{Moodle_2.0}}&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Much of the following documentation will not make much sense unless you first read [[XMLDB_Documentation|the XMLDB documentation]]. Please read it first if you would like to join the effort to convert Moodle&#039;s code to the new dmllib.&lt;br /&gt;
&lt;br /&gt;
Also, it&#039;s recommended to read the whole [[wikipedia:Data_Definition_Language|DDL]] and [[wikipedia:Data_Manipulation_Language|DML]] documentation before starting with the migration. That will allow you to have some initial knowledge about the new architecture.&lt;br /&gt;
&lt;br /&gt;
This article defines all the changes that need to be performed in Moodle 1.9 code in order to make it run properly under the new Moodle 2.0 DB layer. The changes below are grouped into 2 main blocks, [[XMLDB_Documentation|XMLDB]] and [[wikipedia:Data_Manipulation_Language|DML]], to keep them organised. Additional minor changes may be required in the [[wikipedia:Data_Definition_Language|DDL]] code, but won&#039;t be documented here.&lt;br /&gt;
&lt;br /&gt;
Although the order of changes shown on this page isn&#039;t mandatory at all, it can be interesting to follow the migration progress to be able to understand and learn a bit more about all them. That way, you&#039;ll end up knowing not only what to change but how and why those changes are required.&lt;br /&gt;
&lt;br /&gt;
Each change will be as simple as possible, representing one easy rule to follow to adapt the code. When anything becomes too complex to be explained as one simple rule, it will contain one link to the [[dmllib_2.0_examples|examples page]].&lt;br /&gt;
&lt;br /&gt;
For any problem in the migration of code, it&#039;s recommended to use the [http://moodle.org/mod/forum/view.php?id=45 Databases forum] at [http://moodle.org moodle.org]. Also if you find a bug in the process, please report it in the [http://tracker.moodle.org/browse/MDL-14679 Moodle Tracker], so that developers will be able to fix it ASAP.&lt;br /&gt;
&lt;br /&gt;
The Glossary module was used as the basis for many of the examples below.&lt;br /&gt;
&lt;br /&gt;
And finally, feel free to complete/fix the list below with the changes you find in the progress of migration; that will certainly help many developers. Thanks!&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== check_db_syntax: One helper script ==&lt;br /&gt;
&lt;br /&gt;
Before you start migrating your code to Moodle 2.0, it&#039;s recommended you install and run the [http://cvs.moodle.org/contrib/tools/check_db_syntax/ check_db_syntax.php] script. Simply copy it to the main folder of your plugin and execute it (from command line or via web). It will show you a list of old DB usages that need to be transformed following the information below in this article.&lt;br /&gt;
&lt;br /&gt;
If you think that something is missing in the script or have any ideas to improve it, feel free to do that yourself, commenting about it in MDL-15237. Thanks!&lt;br /&gt;
&lt;br /&gt;
Also, this (perl-compatible - works in Eclipse, hopefully elsewhere) regex:&lt;br /&gt;
&lt;br /&gt;
 (?&amp;lt;!-&amp;gt;)(?&amp;lt;!function )(?&amp;lt;!\$)\b(?:(?:count|delete|get|insert|update)_record(?!s_csv)|[gs]et_field|record_exists|execute_sql)|\$CFG-&amp;gt;prefix|rs_(?:fetch|close)|(add|strip)slashes(?!_js)&lt;br /&gt;
&lt;br /&gt;
will find most of the things in your code that need attention, with few false positives.&lt;br /&gt;
&lt;br /&gt;
== XMLDB/DDL changes ==&lt;br /&gt;
&lt;br /&gt;
=== Some comments ===&lt;br /&gt;
&lt;br /&gt;
* When changing DB structures it&#039;s highly recommended to use the [[XMLDB editor|XMLDB Editor]] (Admin-&amp;gt;Development-&amp;gt;XMLDB Editor). It is a safe way to edit install.xml files and to get correct PHP code to be used in upgrade.php scripts.&lt;br /&gt;
* If you have some doubts about the list of changes below, it&#039;s highly recommended to take a look at some code in core modules, blocks... whatever you need. They are a good reference.&lt;br /&gt;
* The most noticeable change (from a migration perspective) in the DDL stuff is that, starting with Moodle 2.0, we have decided to &#039;&#039;&#039;drop support for enum (check constraint) fields completely&#039;&#039;&#039;. See MDL-18577 and [http://moodle.org/mod/forum/discuss.php?d=118852 this discussion]. That implies changes in different parts of the DB stuff (XML files, function parameters, dropping existing enums...) and are commented with more detail below.&lt;br /&gt;
&lt;br /&gt;
=== The changes ===&lt;br /&gt;
* STATEMENTS section was replaced by db/install.php code and db/log.php&lt;br /&gt;
* Few other changes are required in install.xml files (that&#039;s good news!). Although you must know these:&lt;br /&gt;
** The &#039;&#039;&#039;ENUM&#039;&#039;&#039; and &#039;&#039;&#039;ENUMVALUES&#039;&#039;&#039; attributes present in your install.xml files will be completely ignored both by the DLL generation stuff and by the XMLDB Editor.&lt;br /&gt;
** In Moodle 2.1, those attributes (&#039;&#039;&#039;ENUM&#039;&#039;&#039; and &#039;&#039;&#039;ENUMVALUES&#039;&#039;&#039;) will be 100% forbidden, so it&#039;s highly recommended to erase them beginning now (Moodle 2.0).&lt;br /&gt;
** The XMLDB Editor will detect them when loading any install.xml file and will suggest you to fix that easily with one 1-click® option.&lt;br /&gt;
** No matter if you have fixed that with the 1-click® option when loading the files... the [[XMLDB editor|XMLDB Editor]] will save any edited install.xml files without those attributes.&lt;br /&gt;
** If your Moodle 1.9.x code &#039;&#039;&#039;has some enum defined in the database&#039;&#039;&#039;, you will need to create one upgrade block (in db/upgrade.php) to drop it (the enum, not the field! ;-) as part of the migration from Moodle 1.9 to 2.0 by using the new &#039;&#039;&#039;[[DB layer 2.0 examples#Dropping one enum from one field|drop_enum_from_field()]]&#039;&#039;&#039; method.&lt;br /&gt;
** Of course, if you don&#039;t use/like the XMLDB Editor, you can erase them manually with something like this:&lt;br /&gt;
 perl -p -e &#039;s/ENUM(VALUES)?=&amp;quot;.*?&amp;quot; //g&#039; &amp;lt; install.xml &amp;gt; install.xml.new&lt;br /&gt;
&lt;br /&gt;
* All upgrade.php scripts, within the main xxxx_upgrade function must have &#039;&#039;&#039;$DB&#039;&#039;&#039; (uppercase) in the globals declaration (along with others if needed). Example (from the Glossary module):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function xmldb_glossary_upgrade($oldversion=0) {&lt;br /&gt;
    &lt;br /&gt;
    global $CFG, $THEME, $DB;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
* All upgrade.php scripts must NOT have &#039;&#039;&#039;$db&#039;&#039;&#039; (lowercase) in the globals declaration. Delete it if present.&lt;br /&gt;
* After the global declaration in the points above, this line must be present (we&#039;ll need it later):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$dbman = $DB-&amp;gt;get_manager(); /// loads ddl manager and xmldb classes&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
* All &#039;&#039;&#039;XMLDBTable&#039;&#039;&#039; instances in your upgrade code must be replaced by &#039;&#039;&#039;xmldb_table&#039;&#039;&#039; (no change in parameters)&lt;br /&gt;
* All &#039;&#039;&#039;XMLDBField&#039;&#039;&#039; instances in your upgrade code must be replaced by &#039;&#039;&#039;xmldb_field&#039;&#039;&#039; (with change in params, both $enum and $enumvalues are out from function declaration!)&lt;br /&gt;
* All &#039;&#039;&#039;XMLDBIndex&#039;&#039;&#039; instances in your upgrade code must be replaced by &#039;&#039;&#039;xmldb_index&#039;&#039;&#039; (no change in parameters)&lt;br /&gt;
* All &#039;&#039;&#039;XMLDBKey&#039;&#039;&#039; instances in your upgrade code must be replaced by &#039;&#039;&#039;xmldb_key&#039;&#039;&#039; (no change in parameters)&lt;br /&gt;
* All the &#039;&#039;&#039;addFieldInfo()&#039;&#039;&#039; methods must be replaced by &#039;&#039;&#039;add_field()&#039;&#039;&#039; (with change in params, both $enum and $enumvalues (the 7th and 8th parameters) are out from function declaration!)&lt;br /&gt;
* All the &#039;&#039;&#039;addIndexInfo()&#039;&#039;&#039; methods must be replaced by &#039;&#039;&#039;add_index()&#039;&#039;&#039; (no change in parameters)&lt;br /&gt;
* All the &#039;&#039;&#039;addKeyInfo()&#039;&#039;&#039; methods must be replaced by &#039;&#039;&#039;add_key()&#039;&#039;&#039; (no change in parameters)&lt;br /&gt;
* All the &#039;&#039;&#039;setAttributes()&#039;&#039;&#039; methods must be replaced by &#039;&#039;&#039;set_attributes()&#039;&#039;&#039; (with change in params, both $enum and $enumvalues (the 6th and 7th parameters) are out from function declaration!)&lt;br /&gt;
* All the DDL functions used in your upgrade code must be transformed as detailed below (it&#039;s simply about adding &#039;&#039;&#039;&amp;quot;$dbman-&amp;gt;&amp;quot;&#039;&#039;&#039; - without the quotes - before each function call). No changes in parameters are required:&lt;br /&gt;
** table_exists ==&amp;gt; $dbman-&amp;gt;table_exists&lt;br /&gt;
** field_exists ==&amp;gt; $dbman-&amp;gt;field_exists&lt;br /&gt;
** index_exists ==&amp;gt; $dbman-&amp;gt;index_exists&lt;br /&gt;
** find_index_name ==&amp;gt; $dbman-&amp;gt;find_index_name&lt;br /&gt;
** find_check_constraint_name ==&amp;gt; $dbman-&amp;gt;find_check_constraint_name (&#039;&#039;&#039;DEPRECATED in 2.0. OUT in 2.1&#039;&#039;&#039;)&lt;br /&gt;
** check_constraint_exists ==&amp;gt; $dbman-&amp;gt;check_constraint_exists (&#039;&#039;&#039;DEPRECATED in 2.0. OUT in 2.1&#039;&#039;&#039;)&lt;br /&gt;
** find_sequence_name ==&amp;gt; &#039;&#039;&#039;OUT in 2.0&#039;&#039;&#039;, see MDL-20349&lt;br /&gt;
** create_table ==&amp;gt; $dbman-&amp;gt;create_table&lt;br /&gt;
** drop_table ==&amp;gt; $dbman-&amp;gt;drop_table&lt;br /&gt;
** rename_table ==&amp;gt; $dbman-&amp;gt;rename_table&lt;br /&gt;
** add_field ==&amp;gt; $dbman-&amp;gt;add_field&lt;br /&gt;
** drop_field ==&amp;gt; $dbman-&amp;gt;drop field&lt;br /&gt;
** rename_field ==&amp;gt; $dbman-&amp;gt;rename_field&lt;br /&gt;
** change_field_type ==&amp;gt; $dbman-&amp;gt;change_field_type&lt;br /&gt;
** change_field_precision =&amp;gt; $dbman-&amp;gt;change_field_precision&lt;br /&gt;
** change_field_unsigned ==&amp;gt; $dbman-&amp;gt;change_field_unsigned&lt;br /&gt;
** change_field_notnull ==&amp;gt; $dbman-&amp;gt;change_field_notnull&lt;br /&gt;
** change_field_enum ==&amp;gt; $dbman-&amp;gt;change_field_enum (&#039;&#039;&#039;OUT in 2.0&#039;&#039;&#039;, see &#039;&#039;&#039;[[DB layer 2.0 examples#Dropping one enum from one field|drop_enum_from_field()]]&#039;&#039;&#039; to get rid of remaining ENUMs in code).&lt;br /&gt;
** change_field_default ==&amp;gt; $dbman-&amp;gt;change_field_default&lt;br /&gt;
** add_key ==&amp;gt; $dbman-&amp;gt;add_key&lt;br /&gt;
** drop_key ==&amp;gt; $dbman-&amp;gt;drop_key&lt;br /&gt;
** add_index ==&amp;gt; $dbman-&amp;gt;add_index&lt;br /&gt;
** drop_index ==&amp;gt; $dbman-&amp;gt;drop_index&lt;br /&gt;
* The DDL functions that change things (create/drop/rename/add)_(table/field/index) no longer return boolean. Instead, they throw an exception if they fail. So your upgrade.php no longer needs to use a &#039;&#039;&#039;$result&#039;&#039;&#039; variable, and instead should use the &#039;&#039;&#039;upgrade_mod_savepoint()&#039;&#039;&#039; function:&lt;br /&gt;
&amp;lt;code php&amp;gt;/** old way **/&lt;br /&gt;
if ($result &amp;amp;&amp;amp; $oldversion &amp;lt; 2008061000) {&lt;br /&gt;
    $table = new xmldb_table(&#039;facetoface_submissions&#039;);&lt;br /&gt;
    $field = new xmldb_field(&#039;notificationtype&#039;);&lt;br /&gt;
    $field-&amp;gt;set_attributes(XMLDB_TYPE_INTEGER, &#039;10&#039;, XMLDB_UNSIGNED, XMLDB_NOTNULL, null, &#039;0&#039;, &#039;timemodified&#039;);&lt;br /&gt;
&lt;br /&gt;
    $result = $result &amp;amp;&amp;amp; $dbman-&amp;gt;add_field($table, $field);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/** new way **/&lt;br /&gt;
if ($oldversion &amp;lt; 2008061000) {&lt;br /&gt;
    $table = new xmldb_table(&#039;facetoface_submissions&#039;);&lt;br /&gt;
    $field = new xmldb_field(&#039;notificationtype&#039;);&lt;br /&gt;
    $field-&amp;gt;set_attributes(XMLDB_TYPE_INTEGER, &#039;10&#039;, XMLDB_UNSIGNED, XMLDB_NOTNULL, null, &#039;0&#039;, &#039;timemodified&#039;);&lt;br /&gt;
&lt;br /&gt;
    $dbman-&amp;gt;add_field($table, $field);&lt;br /&gt;
    upgrade_mod_savepoint(true, 2008061000, &#039;facetoface&#039;);&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Finally, and not less important, your code (module, block... plugin) must guarantee that it can be upgraded &#039;&#039;&#039;ONLY&#039;&#039;&#039; from Moodle 1.9, so any previous upgrade code can be safely deleted. &#039;&#039;&#039;Moodle 2.0 requires Moodle 1.9&#039;&#039;&#039; to be upgraded, so everybody will run the 1.9 =&amp;gt; 2.0 upgrade (with other paths like 1.8 =&amp;gt; 2.0 not being possible). This is a good time to clean-up your upgrade code a bit ;-). Don&#039;t forget to take a look at the [[XMLDB editor|XMLDB Editor]] and the core modules to see how [http://cvs.moodle.org/moodle/lib/db/upgrade.php?view=markup upgrade.php] files should look in Moodle 2.0.&lt;br /&gt;
&lt;br /&gt;
== DML changes ==&lt;br /&gt;
&lt;br /&gt;
=== Some comments ===&lt;br /&gt;
* The ENTIRE CODEBASE requires an update of ALL database query function calls. Expect most moodle files to be affected by this change.&lt;br /&gt;
&lt;br /&gt;
* This is the more complex part to migrate to have the code working under Moodle 2.0, not because of the complexity of the changes themselves (90% of them will be really easy), but because you&#039;ll need to triple-check everything works as expected after changes.&lt;br /&gt;
&lt;br /&gt;
* Along the changes below, you&#039;ll find links to some examples that will try to make things easier. Anyway, if you are blocked at any point, please ask in forums or tracker (see links at the beginning of the page). Sure it has a good enough solution.&lt;br /&gt;
&lt;br /&gt;
* Once more it&#039;s highly recommended to take a look to Moodle core code, searching for similar examples. Of course, new meaningful examples are welcome, and also any clarification in the list of changes below. Feel free to do it, this is a wiki!&lt;br /&gt;
&lt;br /&gt;
* Finally, one more explanation: The changes below have been split into three sections. First one, (called &#039;&#039;&#039;&amp;quot;The golden changes&amp;quot;&#039;&#039;&#039;) are modifications that must be applied to ALL the transformations defined in the second section (&#039;&#039;&#039;&amp;quot;The iron changes&amp;quot;&#039;&#039;&#039;). Sure you&#039;ll understand that after reading them (it&#039;s basically a matter of not repeating the golden ones within each iron one, just imagine they are everywhere). Finally other changes details can be found in the &#039;&#039;&#039;&amp;quot;The tin changes&amp;quot;&#039;&#039;&#039; section.&lt;br /&gt;
&lt;br /&gt;
=== The golden changes ===&lt;br /&gt;
&#039;&#039;PLEASE read the API before going crazy with search &amp;amp; replace&#039;&#039;! You can find all the new methods in lib/dml/moodle_database.php. This is essential because some method signatures have changed (params are different), and some method names have even changed (execute_sql() is now execute()).&lt;br /&gt;
&lt;br /&gt;
Each of the golden changes below is given one short name (G1, G2, G3...) for further reference in the rest of the documentation. Let&#039;s go:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span id=&amp;quot;g1&amp;quot;&amp;gt;&amp;lt;b&amp;gt;G1&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;: Wherever old functions are used (get_record*, get_field*, set_field, insert_record, update_record, count_records*, delete_records, record_exists), the global $DB must be used as the object on which these functions are called (e.g. get_record_select() becomes $DB-&amp;gt;get_record_select()).&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
// Old syntax&lt;br /&gt;
$sql = &amp;quot;WHERE id = 1&amp;quot;;&lt;br /&gt;
get_record_select($sql);&lt;br /&gt;
  &lt;br /&gt;
// New syntax&lt;br /&gt;
global $DB;&lt;br /&gt;
$sql = &amp;quot;WHERE id = 1&amp;quot;;&lt;br /&gt;
$DB-&amp;gt;get_record_select($sql);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
::Note: for some functions, the $params array is not the second function parameter. For example, set_field:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Old syntax&lt;br /&gt;
set_field(&#039;user&#039;, &#039;firstname&#039;, &#039;Peter&#039;, &#039;id&#039;, 1);&lt;br /&gt;
  &lt;br /&gt;
// New syntax&lt;br /&gt;
global $DB;&lt;br /&gt;
$DB-&amp;gt;set_field(&#039;user&#039;, &#039;firstname&#039;, &#039;Peter&#039;, array(&#039;id&#039; =&amp;gt; 1));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span id=&amp;quot;g2&amp;quot;&amp;gt;&amp;lt;b&amp;gt;G2&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;: All uses of addslashes() &#039;&#039;&#039;must be removed&#039;&#039;&#039;. They are no longer needed&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span id=&amp;quot;g3&amp;quot;&amp;gt;&amp;lt;b&amp;gt;G3&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;: All the functions that used to accept a list of string params in the form &amp;quot;param1, value1, param2, value2&amp;quot; now need to be given an array of key=&amp;gt;value pairs as a replacement for these params. Other params remain as before. Check the new API for any exceptions.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
// Old syntax:&lt;br /&gt;
$user = get_record(&amp;quot;user&amp;quot;, &amp;quot;firstname&amp;quot;, &amp;quot;Peter&amp;quot;, &amp;quot;lastname&amp;quot;, &amp;quot;Cantrophus&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// New syntax:&lt;br /&gt;
global $DB;&lt;br /&gt;
$conditions = array(&amp;quot;firstname&amp;quot; =&amp;gt; &amp;quot;Peter&amp;quot;, &amp;quot;lastname&amp;quot; =&amp;gt; &amp;quot;Cantrophus&amp;quot;);&lt;br /&gt;
$user = $DB-&amp;gt;get_record(&amp;quot;user&amp;quot;, $conditions);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
::Note: The example above has been written out in full for clarity. You can use the array() directly within the function call, without using a temporary variable, if you prefer:&#039;&#039;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
global $DB;&lt;br /&gt;
$user = $DB-&amp;gt;get_record(&amp;quot;user&amp;quot;, array(&amp;quot;firstname&amp;quot; =&amp;gt; &amp;quot;Peter&amp;quot;, &amp;quot;lastname&amp;quot; =&amp;gt; &amp;quot;Cantrophus&amp;quot;) );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span id=&amp;quot;g4&amp;quot;&amp;gt;&amp;lt;b&amp;gt;G4&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;: rs_fetch_next_record($rs) is deprecated, in favour of the simple foreach($rs as $var). Calls to rs_close() must be replaced by $rs-&amp;gt;close();&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
// Old syntax&lt;br /&gt;
while($result = rs_fetch_next_record($rs)) {&lt;br /&gt;
    ...&lt;br /&gt;
}&lt;br /&gt;
rs_close();&lt;br /&gt;
&lt;br /&gt;
// New syntax&lt;br /&gt;
foreach ($rs as $result) {&lt;br /&gt;
    ...&lt;br /&gt;
}&lt;br /&gt;
$rs-&amp;gt;close();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span id=&amp;quot;g5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;G5&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;: Placeholders must be used for table names. Instead of {$CFG-&amp;gt;prefix}tablename, use {tablename}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
// Old syntax&lt;br /&gt;
$sql = &amp;quot;SELECT * FROM {$CFG-&amp;gt;prefix}user&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// New syntax&lt;br /&gt;
$sql = &amp;quot;SELECT * FROM {user}&amp;quot;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span id=&amp;quot;g6&amp;quot;&amp;gt;&amp;lt;b&amp;gt;G6&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;: When PHP variables are used in SQL queries, they must be replaced by parameters. You have the choice between two approaches: ordered parameters, or named parameters.&lt;br /&gt;
** Ordered parameters use a simple array of values, which are given to the DML function as $params. The values in the SQL code are simply question marks (?) replacing the values. They are replaced by the DML code one by one, substituting each question mark (?) with the next value in the $params array.&lt;br /&gt;
** Named parameters use an associative array of name =&amp;gt; value pairs as the $params array. The values in the SQL code are replaced with a colon (:) followed by the key associated with the value, in the $params array. Note that named params &#039;&#039;&#039;must be unique&#039;&#039;&#039;, no matter if the value passed is the same.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
// Old syntax&lt;br /&gt;
$sql = &amp;quot;SELECT id, firstname FROM {$CFG-&amp;gt;prefix}user WHERE firstname = &#039;Peter&#039; AND lastname = &#039;Cantrophus&#039;&amp;quot;;&lt;br /&gt;
$user = get_record_sql($sql);&lt;br /&gt;
  &lt;br /&gt;
// New syntax: ordered params&lt;br /&gt;
global $DB;&lt;br /&gt;
$params = array(&#039;Peter&#039;, &#039;Cantrophus&#039;);&lt;br /&gt;
$sql = &amp;quot;SELECT id, firstname FROM {user} WHERE firstname = ? AND lastname = ?&amp;quot;;&lt;br /&gt;
$user = $DB-&amp;gt;get_record_sql($sql, $params);&lt;br /&gt;
&lt;br /&gt;
// New syntax: named params&lt;br /&gt;
global $DB;&lt;br /&gt;
$params = array(&#039;firstname&#039; =&amp;gt; &#039;Peter&#039;, &#039;lastname&#039; =&amp;gt; &#039;Cantrophus&#039;);&lt;br /&gt;
$sql = &amp;quot;SELECT id, firstname FROM {user} WHERE firstname = :firstname AND lastname = :lastname&amp;quot;;&lt;br /&gt;
$user = $DB-&amp;gt;get_record_sql($sql, $params);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To obtain a value for the LIKE operator, include any % signs into the parameter string. For example, code that was previously &amp;lt;tt&amp;gt;&amp;quot;LIKE &#039;$value%&#039;&amp;quot;&amp;lt;/tt&amp;gt; becomes &amp;lt;tt&amp;gt;&amp;quot;LIKE ?&amp;quot;&amp;lt;/tt&amp;gt; with the parameter &amp;lt;tt&amp;gt;$value.&#039;%&#039;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span id=&amp;quot;g7&amp;quot;&amp;gt;&amp;lt;b&amp;gt;G7&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;: Replacement of the IN(...) syntax: We no longer hard-code this in our SQL queries, we use a function which determines whether the IN() syntax is needed, or, if there is only one value to compare, the equal (=) sign can be used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
// Old syntax:&lt;br /&gt;
$depends_on = array(1, 43, 553);&lt;br /&gt;
$gis = implode(&#039;,&#039;, $depends_on);&lt;br /&gt;
$sql = &amp;quot;SELECT *&lt;br /&gt;
          FROM {$CFG-&amp;gt;prefix}grade_items&lt;br /&gt;
         WHERE id IN ($gis)&amp;quot;;&lt;br /&gt;
$items = $DB-&amp;gt;get_records_sql($sql);&lt;br /&gt;
  &lt;br /&gt;
// new syntax&lt;br /&gt;
global $DB;&lt;br /&gt;
$depends_on = array(1, 43, 553);&lt;br /&gt;
list($usql, $params) = $DB-&amp;gt;get_in_or_equal($depends_on);&lt;br /&gt;
$sql = &amp;quot;SELECT *&lt;br /&gt;
          FROM {grade_items}&lt;br /&gt;
         WHERE id $usql&amp;quot;;&lt;br /&gt;
$items = $DB-&amp;gt;get_records_sql($sql, $params);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; to combine the last two, do the G7 IN SQL stuff first to generate the params array, then do something like&lt;br /&gt;
  $params[&#039;firstname&#039;] = &#039;peter&#039;;&lt;br /&gt;
to add the stuff for G6&lt;br /&gt;
&lt;br /&gt;
=== The iron changes ===&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;span id=&amp;quot;I1&amp;quot;&amp;gt;&amp;lt;b&amp;gt;I1&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;: Originally the &#039;&#039;&#039;sql_substr()&#039;&#039;&#039; function was used without parameters and it returned only the name of the &amp;quot;substring&amp;quot; function to be used under each DB. In Moodle 2.0 and upwards, it has 3 parameters (2 being mandatory) and it returns the complete SQL text to be used when handling substrings. Note that positions in this function are 1-based (first char has index 1).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
// Old syntax&lt;br /&gt;
$records = get_records_sql(&amp;quot;SELECT &amp;quot; . sql_substr() . &amp;quot;(firstname, 1, 20)&amp;quot; . &amp;quot; FROM ... ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// New syntax&lt;br /&gt;
$records = $DB-&amp;gt;get_records_sql(&amp;quot;SELECT &amp;quot; . $DB-&amp;gt;sql_substr(&#039;firstname&#039;, 1, 20) . &amp;quot; FROM ... ...&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The tin changes ===&lt;br /&gt;
List of minor changes&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span id=&amp;quot;g1&amp;quot;&amp;gt;&amp;lt;b&amp;gt;T1&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;: Originally get_records() and similar functions were returning false if no records found. All these methods are now always returning arrays, empty array in case of no records found. Please note that get_record() still returns false if specified record not found.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
// Old syntax&lt;br /&gt;
if (!$posts = get_records(&#039;forum_posts&#039;, &#039;parent&#039;, 666)) {&lt;br /&gt;
    $posts = array()&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// New syntax&lt;br /&gt;
global $DB;&lt;br /&gt;
$posts = $DB-&amp;gt;get_records(&#039;forum_posts&#039;, array(&#039;parent&#039;=&amp;gt;666));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span id=&amp;quot;g1&amp;quot;&amp;gt;&amp;lt;b&amp;gt;T2&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;: Originally DML functions were returning &#039;&#039;false&#039;&#039; if error occurred - &#039;&#039;dml_exception&#039;&#039; is thrown now instead.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
// Old syntax&lt;br /&gt;
$record = new object();&lt;br /&gt;
$record-&amp;gt;course = 5;&lt;br /&gt;
if (!$id = insert_record(&#039;sometable&#039;, $record)) {&lt;br /&gt;
   error(&#039;can not insert new record&#039;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// New syntax&lt;br /&gt;
global $DB;&lt;br /&gt;
$record = new object();&lt;br /&gt;
$record-&amp;gt;course = 5;&lt;br /&gt;
$id = $DB-&amp;gt;insert_record(&#039;sometable&#039;, $record);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[XMLDB Documentation|XMLDB Documentation]]: where both xmldb and ddl stuff is explained.&lt;br /&gt;
* [[DDL functions|DDL functions]] - Documentation for all the Data Definition Language (DDL) functions available inside Moodle.&lt;br /&gt;
* [[DML functions|DML functions]] - Documentation for all the Data Manipulation Language (DML) functions available inside Moodle.&lt;br /&gt;
* [[DDL exceptions|DDL exceptions]] - DDL exceptions information.&lt;br /&gt;
* [[DML exceptions|DML exceptions]] - DML exceptions information.&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Enrolment_plugins&amp;diff=3598</id>
		<title>Enrolment plugins</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Enrolment_plugins&amp;diff=3598"/>
		<updated>2010-11-09T13:44:26Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* How to write an Enrolment plugin in Moodle 1.9 */  Added warning over PARAM_ALPHA for plugin names&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==How to write an Enrolment plugin in Moodle 1.9==&lt;br /&gt;
&lt;br /&gt;
Create a new directory called &amp;lt;code&amp;gt;/enrol/&amp;lt;/code&amp;gt;&#039;&#039;&#039;&amp;lt;code&amp;gt;PLUGINNAME&amp;lt;/code&amp;gt;&#039;&#039;&#039;. Within this directory, create a file &amp;lt;code&amp;gt;/enrol/&amp;lt;/code&amp;gt;&#039;&#039;&#039;&amp;lt;code&amp;gt;PLUGINNAME&amp;lt;/code&amp;gt;&#039;&#039;&#039;&amp;lt;code&amp;gt;/enrol.php&amp;lt;/code&amp;gt; which contains the declaration for a class called &amp;lt;code&amp;gt;enrolment_plugin_&amp;lt;/code&amp;gt;&#039;&#039;&#039;&amp;lt;code&amp;gt;PLUGINNAME&amp;lt;/code&amp;gt;&#039;&#039;&#039;. Note that PLUGINNAME must be letters only as it is passed through PARAM_ALPHA.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
class enrolment_plugin_PLUGINNAME {&lt;br /&gt;
    // Functions go here&lt;br /&gt;
    // ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mandatory functions ===&lt;br /&gt;
&lt;br /&gt;
Your enrolment plugin class is required to define these two functions, which print and process a configuration form.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    /**&lt;br /&gt;
     * Prints out the configuration form for this plugin. All we need&lt;br /&gt;
     * to provide is the form fields. The &amp;lt;form&amp;gt; tags and submit button will&lt;br /&gt;
     * be provided for us by Moodle.&lt;br /&gt;
     *&lt;br /&gt;
     * @param object $formdata Equal to the global $CFG variable, or if&lt;br /&gt;
     *      process_config() returned false, the form contents&lt;br /&gt;
     * @return void&lt;br /&gt;
     */&lt;br /&gt;
    public function config_form( $formdata ){&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Process the data from the configuration form.&lt;br /&gt;
     *&lt;br /&gt;
     * @param object $formdata&lt;br /&gt;
     * @return boolean True if configuration was successful, False if the user&lt;br /&gt;
     *      should be kicked back to config_form() again.&lt;br /&gt;
     */&lt;br /&gt;
    public function process_config( $formdata ){&lt;br /&gt;
        return true;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Optional functions ===&lt;br /&gt;
&lt;br /&gt;
==== Automated enrolment ====&lt;br /&gt;
&lt;br /&gt;
To handle automated enrolment, your function may contain a &amp;lt;code&amp;gt;setup_enrolments($user)&amp;lt;/code&amp;gt; function. This will be called each time a user logs in, to allow the plugin to make any changes to their enrolments.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    /**&lt;br /&gt;
     * OPTIONAL: Set up non-interactive enrolments for user. This is the most&lt;br /&gt;
     * important function for non-interactive enrolment plugins (such as LDAP&lt;br /&gt;
     * and external database). It is called each time a user logs in.&lt;br /&gt;
     * &lt;br /&gt;
     * @param object $user&lt;br /&gt;
     * @return void&lt;br /&gt;
     */&lt;br /&gt;
    public function setup_enrolments( $user ){&lt;br /&gt;
        // Note that when you&#039;re setting up role assignments, you should use the&lt;br /&gt;
        // mdl_role_assignment.enrol column to indicate which role assignments&lt;br /&gt;
        // are from this plugin.&lt;br /&gt;
        role_assign($someroleid, $user-&amp;gt;id, null, $somecontextid, 0, 0, 0, &#039;PLUGINNAME&#039;);&lt;br /&gt;
        role_unassign($someroleid, $user-&amp;gt;id, null, $somecontextid, &#039;PLUGINNAME&#039;);&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Interactive enrolment ====&lt;br /&gt;
&lt;br /&gt;
Your plugin can handle interactive enrolment (i.e. self-enrolment) by implementing these four functions. (See the manual enrolment plugin &amp;lt;code&amp;gt;enrol/manual/enrol.php&amp;lt;/code&amp;gt; for an example that uses all of these.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    /**&lt;br /&gt;
     * OPTIONAL: Prints the entry form/page for interactive enrolment into a course.&lt;br /&gt;
     * &lt;br /&gt;
     * This is only called from course/enrol.php. Most plugins will probably&lt;br /&gt;
     * override this to print payment forms, etc, or even just a notice to say&lt;br /&gt;
     * that manual enrollment is disabled.&lt;br /&gt;
     * &lt;br /&gt;
     * @param object $course&lt;br /&gt;
     * @return void&lt;br /&gt;
     */&lt;br /&gt;
    public function print_entry(){&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * OPTIONAL: The other half to print_entry(), this checks the form data.&lt;br /&gt;
     * &lt;br /&gt;
     * This function checks that the user has completed the task on the enrollment&lt;br /&gt;
     * entry page and enrolls them.&lt;br /&gt;
     * &lt;br /&gt;
     * @param object $form&lt;br /&gt;
     * @param object $course &lt;br /&gt;
     * @return void&lt;br /&gt;
     */&lt;br /&gt;
    public function check_entry( $form, $course ){&lt;br /&gt;
        // some logic&lt;br /&gt;
        // some role_assign();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * OPTIONAL: Check if the given enrolment key matches a group enrolment key for&lt;br /&gt;
     * the given course.&lt;br /&gt;
     * &lt;br /&gt;
     * @param int $courseid&lt;br /&gt;
     * @param string $enrolmentkey&lt;br /&gt;
     * @return mixed The group id of the group which the key matches, or false&lt;br /&gt;
     *       if it matches none&lt;br /&gt;
     */&lt;br /&gt;
    public function check_group_entry( $courseid, $password ){&lt;br /&gt;
        // some logic&lt;br /&gt;
        if ( $itlooksgood ){&lt;br /&gt;
            return $groupid;&lt;br /&gt;
        } else {&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * OPTIONAL: Return a string with icons that give enrolment information&lt;br /&gt;
     * for this course.&lt;br /&gt;
     * &lt;br /&gt;
     * @param object $course&lt;br /&gt;
     * @return string&lt;br /&gt;
     */&lt;br /&gt;
    public function get_access_icons( $course ){&lt;br /&gt;
        return &#039;put icons here&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Cron ====&lt;br /&gt;
&lt;br /&gt;
Your plugin can perform cron tasks if it contains a &amp;lt;code&amp;gt;cron()&amp;lt;/code&amp;gt; function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    /**&lt;br /&gt;
     * OPTIONAL: If this function exists, it will be called each time&lt;br /&gt;
     * admin/cron.php runs. It takes no arguments and returns no values,&lt;br /&gt;
     * but anything written to $this-&amp;gt;log will be printed to the cron output.&lt;br /&gt;
     * &lt;br /&gt;
     * @return void&lt;br /&gt;
     */&lt;br /&gt;
    public function cron(){&lt;br /&gt;
        $this-&amp;gt;log = &#039;Print this in the cron log!&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Language Strings ===&lt;br /&gt;
&lt;br /&gt;
Create a lang directory and file under your plugin&#039;s directory, like this &#039;&#039;&#039;&amp;lt;code&amp;gt;enrol/PLUGINNAME/lang/en_utf8/enrol_PLUGINNAME.php&amp;lt;/code&amp;gt;&#039;&#039;&#039;. Plugins are expected to provide at least these two strings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
// The name of your plugin. Displayed on admin menus.&lt;br /&gt;
$string[&#039;enrolname&#039;] = &#039;My plugin&#039;;&lt;br /&gt;
&lt;br /&gt;
// Description of your plugin. Shown on the plugin&#039;s configuration screen.&lt;br /&gt;
$string[&#039;description&#039;] = &#039;This is what my plugin does.&#039;;&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Those two strings will be accessed automatically by Moodle in various situations. You can (and should) of course include other [[Places to search for lang strings|language strings]] in your plugin&#039;s lang file(s). These can be accessed like normal language strings, using &amp;quot;enrol_PLUGINNAME&amp;quot; as the module name, e.g. &amp;lt;code&amp;gt;get_string(&#039;anotherstring&#039;, &#039;enrol_PLUGINNAME&#039;)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
If your plugin needs to have its own Moodle database tables, create a file called &amp;lt;code&amp;gt;enrol/PLUGINNAME/version.php&amp;lt;/code&amp;gt; like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&amp;lt;?php&lt;br /&gt;
$plugin-&amp;gt;version = 2010091600; // Version of your plugin&lt;br /&gt;
$plugin-&amp;gt;requires = 2007101000; // Required Moodle version (from /version.php)&lt;br /&gt;
?&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then create a directory &amp;lt;code&amp;gt;enrol/PLUGINNAME/db&amp;lt;/code&amp;gt;, and use the [[XMLDB editor]] to set up your tables.&lt;br /&gt;
&lt;br /&gt;
==Testing paypal using the paypal developer sandbox==&lt;br /&gt;
&lt;br /&gt;
=== For moodle 1.4 - 1.8 ===&lt;br /&gt;
&lt;br /&gt;
If you follow these steps, you can test paypal payments using the paypal developer sandbox instead of the real paypal site.  No money is actually charged to any account.  All other actions are the same as if you were using the real paypal site.&lt;br /&gt;
* create a paypal developer account at https://developer.paypal.com/cgi-bin/devscr?cmd=_home&lt;br /&gt;
* change the address being used to send data to paypal to use the sandbox. in enrol/paypal/enrol.html:&lt;br /&gt;
** change the form post action to be https://www.sandbox.paypal.com/cgi-bin/webscr instead of https://www.paypal.com/cgi-bin/webscr&lt;br /&gt;
* change the address that is used to check the acknowledgment from paypal.  in enrol/paypal/ipn.php, change:&lt;br /&gt;
** $fp = fsockopen (&#039;www.paypal.com&#039;, 80, $errno, $errstr, 30);&lt;br /&gt;
* to&lt;br /&gt;
** $fp = fsockopen (&#039;www.sandbox.paypal.com&#039;, 80, $errno, $errstr, 30);&lt;br /&gt;
* create a couple of user accounts in the paypal sandbox and test enrolling in a course that requires payment (note that you need to be logged into the paypal sandbox while doing this testing)&lt;br /&gt;
* under the &amp;quot;business&amp;quot; sandbox account you created, log in, go to &amp;quot;Profile&amp;quot;, &amp;quot;Instant Payment Notification&amp;quot;, and enter the full web-visible HTTPS URL to ../enrol/paypal/ipn.php. Failing to do this is a common mistake, and the cause of most headaches with this plugin.&lt;br /&gt;
&lt;br /&gt;
=== For moodle 1.8.2 - 1.9.x ===&lt;br /&gt;
&lt;br /&gt;
The above changes to the code were made part of the release starting with version 1.8.2&lt;br /&gt;
&lt;br /&gt;
If you follow these steps, you can test paypal payments using the paypal developer sandbox instead of the real paypal site.  No money is actually charged to any account.  All other actions are the same as if you were using the real paypal site.&lt;br /&gt;
* create a paypal developer account at https://developer.paypal.com/cgi-bin/devscr?cmd=_home&lt;br /&gt;
* create a couple of user accounts in the paypal sandbox and test enrolling in a course that requires payment (note that you need to be logged into the paypal sandbox while doing this testing)&lt;br /&gt;
* under the &amp;quot;business&amp;quot; sandbox account you created, log in, go to &amp;quot;Profile&amp;quot;, &amp;quot;Instant Payment Notification&amp;quot;, and enter the full web-visible HTTPS URL to ../enrol/paypal/ipn.php. Failing to do this is a common mistake, and the cause of most headaches with this plugin.&lt;br /&gt;
* add the following line to config.php located in the root directory of your installation (where you installed Moodle). &lt;br /&gt;
** $CFG-&amp;gt;usepaypalsandbox = &#039;TRUE&#039;;&lt;br /&gt;
* Add the business account email address from &amp;quot;business&amp;quot; account you created to the paypal module settings (in 1.9.x - Site Administration&amp;gt;Courses&amp;gt;Enrolments&amp;gt;Paypal&amp;gt;Edit)&lt;br /&gt;
* You should be ready to test&lt;br /&gt;
* When finished be sure to remove the line that was added to config.php in your root directory.&lt;br /&gt;
&lt;br /&gt;
=== Note about Paypal Sandbox ===&lt;br /&gt;
&lt;br /&gt;
Only implement these changes if the above is not working and Moodle is returning the &amp;quot;...Unfortunately your payment...&amp;quot; message after returning from Paypal Sandbox.&lt;br /&gt;
&lt;br /&gt;
At the time of this writing (14 June 2008) some changes are necessary to test successfully in the Paypal Sandbox. Details can be found [http://www.pdncommunity.com/pdn/board/message?board.id=sandbox&amp;amp;view=by_date_ascending&amp;amp;message.id=9802#M9802 here]. This could change at any time at which point this may become unnecessary. For now do the following (only tested in 1.9.x so far):&lt;br /&gt;
&lt;br /&gt;
* Locate ipn.php in your installation on your server by migrating to to ../enrol/paypal/ipn.php&lt;br /&gt;
* Create a backup copy of ipn.php and give it a name something like ipn.php-backup &lt;br /&gt;
* Return to ipn.php and locate the following code :&amp;lt;br /&amp;gt;&lt;br /&gt;
$header = &#039;&#039;;&amp;lt;br /&amp;gt;&lt;br /&gt;
$header .= &amp;quot;POST /cgi-bin/webscr HTTP/1.0\r\n&amp;quot;;&amp;lt;br /&amp;gt;&lt;br /&gt;
$header .= &amp;quot;Content-Type: application/x-www-form-urlencoded\r\n&amp;quot;;&amp;lt;br /&amp;gt;&lt;br /&gt;
$header .= &amp;quot;Content-Length: &amp;quot; . strlen($req) . &amp;quot;\r\n\r\n&amp;quot;;&amp;lt;br /&amp;gt;&lt;br /&gt;
$paypaladdr = empty($CFG-&amp;gt;usepaypalsandbox) ? &#039;www.paypal.com&#039; : &#039;www.sandbox.paypal.com&#039;;&amp;lt;br /&amp;gt;&lt;br /&gt;
$fp = fsockopen ($paypaladdr, 80, $errno, $errstr, 30);&lt;br /&gt;
* Change that code to :&amp;lt;br /&amp;gt;&lt;br /&gt;
$header = &#039;&#039;;&amp;lt;br /&amp;gt;&lt;br /&gt;
$header .= &amp;quot;POST /cgi-bin/webscr HTTP/1.0\r\n&amp;quot;;&amp;lt;br /&amp;gt;&lt;br /&gt;
$header .= &amp;quot;Content-Type: application/x-www-form-urlencoded\r\n&amp;quot;;&amp;lt;br /&amp;gt;&lt;br /&gt;
$header .= &amp;quot;Content-Length: &amp;quot; . strlen($req) . &amp;quot;\r\n\r\n&amp;quot;;&amp;lt;br /&amp;gt;&lt;br /&gt;
$paypaladdr = empty($CFG-&amp;gt;usepaypalsandbox) ? &#039;www.paypal.com&#039; : &#039;ssl://www.sandbox.paypal.com&#039;;&amp;lt;br /&amp;gt;&lt;br /&gt;
$fp = fsockopen ($paypaladdr, 443, $errno, $errstr, 30);&amp;lt;br /&amp;gt;&lt;br /&gt;
* Try the course purchase again. &lt;br /&gt;
&lt;br /&gt;
If the above still is not working you will need to seek help in the [http://moodle.org/mod/forum/view.php?id=2981 Enrolment Plugins] Forum.&lt;br /&gt;
&lt;br /&gt;
==Enrolment plugins 1.7==&lt;br /&gt;
&lt;br /&gt;
===Background===&lt;br /&gt;
# isteacher(), isstudent(), isadmin(), iscoursecreator() are all deprecated and should be replaced with checks on has_capability instead.&lt;br /&gt;
# enrol_student() and add_teacher() are obsolete, so use the generic role_assign() or the convenience function for &amp;quot;students&amp;quot; called enrol_into_course() instead.&lt;br /&gt;
# unenrol_student() and remove_teacher() are obsolete, so use the generic role_unassign() instead.&lt;br /&gt;
# All the roles have a &amp;quot;shortname&amp;quot;, so by default we can refer to them using &amp;quot;teacher&amp;quot;, &amp;quot;student&amp;quot;, &amp;quot;editingteacher&amp;quot; etc.  Note that new roles may have different names.  Enrolment plugins can use these to map outside data onto the inside roles without needing to know internal role id numbers.   For example, it would be really handy for the flatfile plugin to refer to roles directly like this.&lt;br /&gt;
# Each plugin used to implement get_student_courses() and get_teacher_courses() for use at login time.  These now need to be converted to one new function called $enrol-&amp;gt;setup_enrolments($user) which looks up sets all enrolments for a given user (using role_assign and role_unassign).&lt;br /&gt;
# All the session arrays like $USER-&amp;gt;student[] and $USER-&amp;gt;teacher[] are gone and should not be relied on.  You can check what roles a user already has by calling get_user_roles() on that course context.&lt;br /&gt;
&lt;br /&gt;
===What&#039;s been done===&lt;br /&gt;
&lt;br /&gt;
#enrol/manual has been converted to use the new functions&lt;br /&gt;
#enrol/imsenterprise has been converted - testing needed though&lt;br /&gt;
&lt;br /&gt;
===What still needs to be done===&lt;br /&gt;
&lt;br /&gt;
#enrol/authorize&lt;br /&gt;
#enrol/database&lt;br /&gt;
#enrol/flatfile&lt;br /&gt;
#enrol/ldap&lt;br /&gt;
#enrol/paypal&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[[Enrolment plugins|Enrolment plugins (administrator)]]&lt;br /&gt;
*Using Moodle [http://moodle.org/mod/forum/view.php?id=2981 Enrolment Plugins] forum&lt;br /&gt;
&lt;br /&gt;
[[Category:Enrolment plugins]]&lt;br /&gt;
[[Category:Enrolment]]&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Setting_up_Netbeans&amp;diff=8987</id>
		<title>Setting up Netbeans</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Setting_up_Netbeans&amp;diff=8987"/>
		<updated>2010-06-06T19:53:04Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* Checkout of contrib code */ Added symlink tip&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.netbeans.org/features/php/index.html NetBeans] has got a good PHP support. You find a host of information on the website (tutorials, developer blog, screen casts, etc.).&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
* CVS integration: see all changes, lines deletion, diff in real time, show annotations, diff history...&lt;br /&gt;
* Ctrl+Click: Go to declaration&lt;br /&gt;
* Export/Import Diff Patch&lt;br /&gt;
* Easy navigation&lt;br /&gt;
* List of functions&lt;br /&gt;
* Code completion&lt;br /&gt;
* Instant rename&lt;br /&gt;
* HTML, CSS, JavaScript support&lt;br /&gt;
* MySQL manager&lt;br /&gt;
* Quick Search&lt;br /&gt;
* Very few bugs&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
* Download the latest [http://netbeans.org/community/releases/68/ 6.8 version] with PHP support, only 25 MB.&lt;br /&gt;
* Install and run it.&lt;br /&gt;
&lt;br /&gt;
== Set up for Moodle development ==&lt;br /&gt;
&lt;br /&gt;
* Checkout your Moodle project with a &#039;&#039;&#039;CVS client&#039;&#039;&#039; - see [[CVS for Administrators]] or [[CVS for developers|CVS for Developers]].&lt;br /&gt;
&lt;br /&gt;
* Open File &amp;gt; New Project &amp;gt; PHP &amp;gt; PHP Application &amp;gt; Next &lt;br /&gt;
: You&#039;re going to set the project now. &#039;&#039;Name&#039;&#039;, &#039;&#039;Location&#039;&#039; and &#039;&#039;Folder&#039;&#039; are used by NetBeans and are not related to the source code. So you can choose whatever you like, except your source folder. &#039;&#039;Sources&#039;&#039; has to be your checked out Moodle branch/head folder. The rest is clear enough. Don&#039;t forget to choose UTF-8 for &#039;&#039;Default Encoding&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
: Example:&lt;br /&gt;
&lt;br /&gt;
 Project Name:        Moodle 1.9 Stable&lt;br /&gt;
 Project Location:    C:\Users\jerome\Documents\NetBeansProjects&lt;br /&gt;
 Project Folder:      C:\Users\jerome\Documents\NetBeansProjects\Moodle 1.9 Stable&lt;br /&gt;
 Project Sources:     C:\Users\jerome\Projects\branch19_STABLE\moodle&lt;br /&gt;
 Project URL:         http://localhost/moodle19/&lt;br /&gt;
 Index File:          index.php&lt;br /&gt;
 Create:              unchecked&lt;br /&gt;
 Default Encoding:    UTF-8&lt;br /&gt;
 Set as Main Project: unchecked&lt;br /&gt;
&lt;br /&gt;
* Click on Finish.&lt;br /&gt;
&lt;br /&gt;
* Start coding!&lt;br /&gt;
&lt;br /&gt;
== CVS with NetBeans ==&lt;br /&gt;
&lt;br /&gt;
NetBeans comes with &#039;&#039;&#039;integrated CVS support&#039;&#039;&#039; which might be the easiest way to check out Moodle.&lt;br /&gt;
&lt;br /&gt;
=== Anonymous checkout ===&lt;br /&gt;
&lt;br /&gt;
# In NetBeans, select Window-&amp;gt;Versioning-&amp;gt;CVS-&amp;gt;Checkout&lt;br /&gt;
# Select Team-&amp;gt;CVS-&amp;gt;Checkout&lt;br /&gt;
# Enter into CVS Root: &#039;&#039;:pserver:anonymous@us.cvs.moodle.org:/cvsroot/moodle&#039;&#039;&lt;br /&gt;
: (Non-US-residents might use one of the other [https://docs.moodle.org/en/CVS_for_Administrators#CVS_Servers Moodle CVS servers] nearer to them.)&lt;br /&gt;
# Click &#039;&#039;Next&#039;&#039;&lt;br /&gt;
# Browse or enter into &#039;&#039;Module:&#039;&#039; moodle&lt;br /&gt;
# Browse or enter into &#039;&#039;Branch:&#039;&#039; MOODLE_19_STABLE&lt;br /&gt;
# Browse or enter into &#039;&#039;Local Folder:&#039;&#039; C:\xampp\htdocs&lt;br /&gt;
# Click &#039;&#039;Finish&#039;&#039; (and wait a few minutes for Moodle to be checked out)&lt;br /&gt;
# When you get the dialog box &amp;quot;Do you want to create an IDE project from the checked-out sources?&amp;quot;, Click &amp;quot;Create Project...&amp;quot;&lt;br /&gt;
# Select PHP Application with Existing Sources, and click Next&lt;br /&gt;
# Browse or enter into &#039;&#039;Sources Folder&#039;&#039; C:\xampp\htdocs\moodle&lt;br /&gt;
# Enter into &#039;&#039;Project Name:&#039;&#039; moodle&lt;br /&gt;
# Keep the other defaults and click next&lt;br /&gt;
# &#039;&#039;Run As:&#039;&#039; should have selected &#039;&#039;Local Web Site (running on local web server)&#039;&#039;&lt;br /&gt;
# Enter into Project URL http://localhost/moodle/&lt;br /&gt;
# Browse or enter into &#039;&#039;Index File:&#039;&#039; index.php&lt;br /&gt;
# Click &#039;&#039;Finish&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checkout for developers with write access ===&lt;br /&gt;
&lt;br /&gt;
As far as I can tell, there is no way to get NetBeans to work with CVS keys on Mac/Linux via the system SSH binary, so you will ned to use the internal SSH and your password (which you can choose to save).&lt;br /&gt;
&lt;br /&gt;
If you wish to use NetBeans CVS and have CVS write access, the procedure is as follows:&lt;br /&gt;
&lt;br /&gt;
====Checkout of main Moodle codebase====&lt;br /&gt;
&lt;br /&gt;
# Follow the above instructions except for point 3&lt;br /&gt;
# At part 3, substitute &#039;&#039;:ext:yourusername&#039;&#039; for the part before the @ and remove the country code from after it, leaving it like this  &#039;&#039;&#039;&#039;&#039;:ext:yourusername&#039;&#039;&#039;@cvs.moodle.org:/cvsroot/moodle&#039;&#039;&lt;br /&gt;
# Follow the rest of the instructions as above&lt;br /&gt;
&lt;br /&gt;
If you wish to work with a plugin, you will need to check this out separately and add it to the Moodle code project you have just made. This because for some reason, the &#039;Do you want to create a project&#039; option fails to show any of the files once you open it if you try to check out the plugin on its own (NetBeans 6.7.1 on a Mac).&lt;br /&gt;
&lt;br /&gt;
====Checkout of contrib code====&lt;br /&gt;
&lt;br /&gt;
# Follow the above steps up to point 3, and again substitute &#039;&#039;:ext:yourusername&#039;&#039; and click &#039;next&#039;. Note that you should not try to specify the full contrib repository path yet.&lt;br /&gt;
# Click &#039;Browse...&#039; next to the &#039;Module&#039; dialogue&lt;br /&gt;
# Find the plugin you wish to work with in CONTRIB&lt;br /&gt;
# Click &#039;OK&#039;&lt;br /&gt;
# Proceed as before up to point 6, then press &#039;Close&#039; when asked if you want to create a new project.&lt;br /&gt;
# Now navigate to the folder you earlier specified in the &#039;local folder&#039; dialogue and you will find a folder marked &#039;contrib&#039;.&lt;br /&gt;
# navigate to the plugin folder, copy that folder, and then navigate to your main Moodle project folder and paste it where it belongs.&lt;br /&gt;
&lt;br /&gt;
Note that the last three points may cause you some grief when attempting to commit changes. CVS doesn&#039;t seem to like having subfolders with different origins. A workaround that operates well for me is to check out the contrib code manually into a folder using the command line as specified in the CVS for developers instructions, then import that code as a new project with existing sources. This allows easy commits and updates, whilst keeping it separate. You can then make a symlink from you main Moodle project to your contrib directory, restart NetBeans (the CVS info and symlink stuff is only refreshed on restart) and then right click the linked directory and choose &#039;Ignore&#039;, then do the same and choose &#039;Exclude from commit&#039;. You can now use the code as if it were part of Moodle, still getting all the code completion stuff, and also do clean updates and commits from the secondary project. [[User:Matt Gibson|Matt Gibson]] 19:53, 6 June 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
===Adding a branch to your plugin===&lt;br /&gt;
Your plugin will likely start with just a HEAD tag and at some point, you will want to branch it so that you can have versions for different Moodles. To add a MOODLE_20_STABLE branch, for example, do the following.&lt;br /&gt;
&lt;br /&gt;
# Checkout as above, but use the MOODLE_20_STABLE branch instead of MOODLE_19_STABLE&lt;br /&gt;
# You will end up with an empty folder, which you copy into place as above.&lt;br /&gt;
# Find the folder in NetBeans, then right click and choose CVS-&amp;gt;Merge changes from branch...&lt;br /&gt;
# Choose to merge from whatever branch has all the current code, using the help link if not sure what to do.&lt;br /&gt;
&lt;br /&gt;
There is a small chance that the Merge link will not be there, in which case, you will have to copy the files into the directory by hand outside netbeans and then check them in. If you do this, make sure you don&#039;t copy over the &#039;CVS&#039; folders that will have been made when you checked out the MOODLE_19_STABLE code.&lt;br /&gt;
&lt;br /&gt;
=== A few warnings ===&lt;br /&gt;
&lt;br /&gt;
Some of these warnings could also apply to other IDEs:&lt;br /&gt;
&lt;br /&gt;
* If you want to delete a file from your computer but not from CVS, delete it from Windows Explorer/Nautilus/Finder. Otherwise your next commit could delete the file from CVS. &amp;lt;br/&amp;gt;In case you have already deleted a wrong file from NetBeans:  with Windows Explorer/Nautilus/Finder, delete all the folder content of this deleted file (including the CVS folder) and update the folder.&lt;br /&gt;
* If you rename files and that other people are working on them, NetBeans could end up to mess up your CVS folder (even though that is quite rare). Then NetBeans CVS will refuse to update your code displaying a no explicit error as &#039;&#039;&#039;Update Failed&#039;&#039;&#039;. In this case, delete the content of the damaged folder with Windows Explorer/Nautilus/Finder. Then update this folder.&lt;br /&gt;
* If you create a patch or a new PHP file with NetBeans on Microsoft Windows, please check that it&#039;s a Unix format file. You may want to use another software to create Unix format patch/php files.&lt;br /&gt;
&lt;br /&gt;
== Git with NetBeans ==&lt;br /&gt;
&lt;br /&gt;
=== NBGit | Git Support for NetBeans ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;NBGit is a module for the NetBeans IDE that adds support for working with the Git version control system. It uses the JGit library created as part of EGit to interact with Git repositories. Because the module is Java code all the way, it should work better cross-platform modulo platform specific differences, such as file system behavior. It is based on the NetBeans Mercurial module.&amp;quot; &lt;br /&gt;
(http://nbgit.org)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
Unfortunately, the key word in that quote is &#039;&#039;&#039;should&#039;&#039;&#039;. In reality, because JGit is a rewrite from scratch of the tried-and-tested git core C code, it is still buggy, incomplete and unreliable. Therefore, the NetBeans and Eclipse git plugins are still only beta quality, and pretty sucky. Well, they mostly work for browsing the contents of the repository, but there is a small chance that if you use them for update operations, they will corrupt your repository. Hence, I am still doing git from the command-line.--[[User:Tim Hunt|Tim Hunt]] 11:11, 19 January 2010 (UTC)&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Optimization ==&lt;br /&gt;
&lt;br /&gt;
1. You may want to run NetBeans with the Sun JDK. NetBeans seems to work a bit better with the [http://java.sun.com/javase/downloads/index.jsp Sun JDK]. You&#039;ll have to edit NetBeans config file. Open netbeans/etc/netbeans.conf. Then uncomment and edit: &lt;br /&gt;
&lt;br /&gt;
 netbeans_jdkhome=&amp;quot;your_JDK_path&amp;quot;&lt;br /&gt;
&lt;br /&gt;
2. To change the NetBeans look and feel run netbeans in the command line with this parameter:&lt;br /&gt;
 &amp;quot;netbeans&amp;quot;  --laf javax.swing.plaf.metal.MetalLookAndFeel &lt;br /&gt;
&lt;br /&gt;
3. If NetBeans starts to slow down, give it more memory&lt;br /&gt;
 &amp;quot;netbeans&amp;quot; -J-Xmx600m&lt;br /&gt;
See FAQ for more [http://wiki.netbeans.org/FaqSettingHeapSize details on memory optimisation].&lt;br /&gt;
&lt;br /&gt;
== Coding faster ==&lt;br /&gt;
&lt;br /&gt;
=== Keyboard shortcuts ===&lt;br /&gt;
(Note: Some shortcuts might not work for PHP development.)&lt;br /&gt;
* [http://www.phpmag.ru/2009/01/23/extremely-usefull-netbeans-shortcuts/ Extremely Useful NetBeans Shortcuts] &lt;br /&gt;
* [http://netbeanside61.blogspot.com/2008/04/top-10-netbeans-ide-keyboard-shortcuts.html Top 10 NetBeans IDE Keyboard Shortcuts I use the most]&lt;br /&gt;
* [http://wiki.netbeans.org/KeymapProfileFor60 NetBeans IDE 6.x Keyboard Shortcuts Specification]&lt;br /&gt;
&lt;br /&gt;
=== PHPUnit support ===&lt;br /&gt;
See [http://blogs.sun.com/netbeansphp/entry/recent_improvements_in_phpunit_support &amp;quot;Recent improvements in PHPUnit-support&amp;quot;] on how to use PHPUnit with NetBeans.&lt;br /&gt;
&lt;br /&gt;
===JIRA support===&lt;br /&gt;
You can install the optional JIRA module in order to be able to interact with the Moodle Tracker from within netbeans. This has the advantage of avoiding constantly switching back and forth from the browser and works quite well. Go to Tools-&amp;gt;plugins-&amp;gt;available plugins and search for JIRA. Once installed, right click &#039;issue trackers&#039; in the &#039;services&#039; pane to make a new tracker instance, then enter your details.&lt;br /&gt;
&lt;br /&gt;
== See also: ==&lt;br /&gt;
Moodle forums &lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=112972 NetBeans 6.5 for moodle/PHP/debugging is a better experience v.s Eclipse]&lt;br /&gt;
&lt;br /&gt;
Online resources&lt;br /&gt;
* [http://www.netbeans.org/kb/trails/php.html NetBeans PHP Learning Trail]&lt;br /&gt;
* [http://wiki.netbeans.org/PHP NetBeans PHP Wiki]&lt;br /&gt;
* Sun&#039;s [http://blogs.sun.com/netbeansphp/ NetBeans PHP Team Blog]&lt;br /&gt;
&lt;br /&gt;
Book&lt;br /&gt;
* [http://www.packtpub.com/netbeans-platform-6-8-developers-guide/book NetBeans Platform 6.8 Developer&#039;s Guide] by Jürgen Petri (March 2010), focus on Java and Swing &lt;br /&gt;
&lt;br /&gt;
[[Category:NetBeans]]&lt;br /&gt;
[[Category:Developer tools|NetBeans]]&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Setting_up_Netbeans&amp;diff=8986</id>
		<title>Setting up Netbeans</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Setting_up_Netbeans&amp;diff=8986"/>
		<updated>2010-06-05T13:21:25Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* Checkout for developers with write access */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.netbeans.org/features/php/index.html NetBeans] has got a good PHP support. You find a host of information on the website (tutorials, developer blog, screen casts, etc.).&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
* CVS integration: see all changes, lines deletion, diff in real time, show annotations, diff history...&lt;br /&gt;
* Ctrl+Click: Go to declaration&lt;br /&gt;
* Export/Import Diff Patch&lt;br /&gt;
* Easy navigation&lt;br /&gt;
* List of functions&lt;br /&gt;
* Code completion&lt;br /&gt;
* Instant rename&lt;br /&gt;
* HTML, CSS, JavaScript support&lt;br /&gt;
* MySQL manager&lt;br /&gt;
* Quick Search&lt;br /&gt;
* Very few bugs&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
* Download the latest [http://netbeans.org/community/releases/68/ 6.8 version] with PHP support, only 25 MB.&lt;br /&gt;
* Install and run it.&lt;br /&gt;
&lt;br /&gt;
== Set up for Moodle development ==&lt;br /&gt;
&lt;br /&gt;
* Checkout your Moodle project with a &#039;&#039;&#039;CVS client&#039;&#039;&#039; - see [[CVS for Administrators]] or [[CVS for developers|CVS for Developers]].&lt;br /&gt;
&lt;br /&gt;
* Open File &amp;gt; New Project &amp;gt; PHP &amp;gt; PHP Application &amp;gt; Next &lt;br /&gt;
: You&#039;re going to set the project now. &#039;&#039;Name&#039;&#039;, &#039;&#039;Location&#039;&#039; and &#039;&#039;Folder&#039;&#039; are used by NetBeans and are not related to the source code. So you can choose whatever you like, except your source folder. &#039;&#039;Sources&#039;&#039; has to be your checked out Moodle branch/head folder. The rest is clear enough. Don&#039;t forget to choose UTF-8 for &#039;&#039;Default Encoding&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
: Example:&lt;br /&gt;
&lt;br /&gt;
 Project Name:        Moodle 1.9 Stable&lt;br /&gt;
 Project Location:    C:\Users\jerome\Documents\NetBeansProjects&lt;br /&gt;
 Project Folder:      C:\Users\jerome\Documents\NetBeansProjects\Moodle 1.9 Stable&lt;br /&gt;
 Project Sources:     C:\Users\jerome\Projects\branch19_STABLE\moodle&lt;br /&gt;
 Project URL:         http://localhost/moodle19/&lt;br /&gt;
 Index File:          index.php&lt;br /&gt;
 Create:              unchecked&lt;br /&gt;
 Default Encoding:    UTF-8&lt;br /&gt;
 Set as Main Project: unchecked&lt;br /&gt;
&lt;br /&gt;
* Click on Finish.&lt;br /&gt;
&lt;br /&gt;
* Start coding!&lt;br /&gt;
&lt;br /&gt;
== CVS with NetBeans ==&lt;br /&gt;
&lt;br /&gt;
NetBeans comes with &#039;&#039;&#039;integrated CVS support&#039;&#039;&#039; which might be the easiest way to check out Moodle.&lt;br /&gt;
&lt;br /&gt;
=== Anonymous checkout ===&lt;br /&gt;
&lt;br /&gt;
# In NetBeans, select Window-&amp;gt;Versioning-&amp;gt;CVS-&amp;gt;Checkout&lt;br /&gt;
# Select Team-&amp;gt;CVS-&amp;gt;Checkout&lt;br /&gt;
# Enter into CVS Root: &#039;&#039;:pserver:anonymous@us.cvs.moodle.org:/cvsroot/moodle&#039;&#039;&lt;br /&gt;
: (Non-US-residents might use one of the other [https://docs.moodle.org/en/CVS_for_Administrators#CVS_Servers Moodle CVS servers] nearer to them.)&lt;br /&gt;
# Click &#039;&#039;Next&#039;&#039;&lt;br /&gt;
# Browse or enter into &#039;&#039;Module:&#039;&#039; moodle&lt;br /&gt;
# Browse or enter into &#039;&#039;Branch:&#039;&#039; MOODLE_19_STABLE&lt;br /&gt;
# Browse or enter into &#039;&#039;Local Folder:&#039;&#039; C:\xampp\htdocs&lt;br /&gt;
# Click &#039;&#039;Finish&#039;&#039; (and wait a few minutes for Moodle to be checked out)&lt;br /&gt;
# When you get the dialog box &amp;quot;Do you want to create an IDE project from the checked-out sources?&amp;quot;, Click &amp;quot;Create Project...&amp;quot;&lt;br /&gt;
# Select PHP Application with Existing Sources, and click Next&lt;br /&gt;
# Browse or enter into &#039;&#039;Sources Folder&#039;&#039; C:\xampp\htdocs\moodle&lt;br /&gt;
# Enter into &#039;&#039;Project Name:&#039;&#039; moodle&lt;br /&gt;
# Keep the other defaults and click next&lt;br /&gt;
# &#039;&#039;Run As:&#039;&#039; should have selected &#039;&#039;Local Web Site (running on local web server)&#039;&#039;&lt;br /&gt;
# Enter into Project URL http://localhost/moodle/&lt;br /&gt;
# Browse or enter into &#039;&#039;Index File:&#039;&#039; index.php&lt;br /&gt;
# Click &#039;&#039;Finish&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checkout for developers with write access ===&lt;br /&gt;
&lt;br /&gt;
As far as I can tell, there is no way to get NetBeans to work with CVS keys on Mac/Linux via the system SSH binary, so you will ned to use the internal SSH and your password (which you can choose to save).&lt;br /&gt;
&lt;br /&gt;
If you wish to use NetBeans CVS and have CVS write access, the procedure is as follows:&lt;br /&gt;
&lt;br /&gt;
====Checkout of main Moodle codebase====&lt;br /&gt;
&lt;br /&gt;
# Follow the above instructions except for point 3&lt;br /&gt;
# At part 3, substitute &#039;&#039;:ext:yourusername&#039;&#039; for the part before the @ and remove the country code from after it, leaving it like this  &#039;&#039;&#039;&#039;&#039;:ext:yourusername&#039;&#039;&#039;@cvs.moodle.org:/cvsroot/moodle&#039;&#039;&lt;br /&gt;
# Follow the rest of the instructions as above&lt;br /&gt;
&lt;br /&gt;
If you wish to work with a plugin, you will need to check this out separately and add it to the Moodle code project you have just made. This because for some reason, the &#039;Do you want to create a project&#039; option fails to show any of the files once you open it if you try to check out the plugin on its own (NetBeans 6.7.1 on a Mac).&lt;br /&gt;
&lt;br /&gt;
====Checkout of contrib code====&lt;br /&gt;
&lt;br /&gt;
# Follow the above steps up to point 3, and again substitute &#039;&#039;:ext:yourusername&#039;&#039; and click &#039;next&#039;. Note that you should not try to specify the full contrib repository path yet.&lt;br /&gt;
# Click &#039;Browse...&#039; next to the &#039;Module&#039; dialogue&lt;br /&gt;
# Find the plugin you wish to work with in CONTRIB&lt;br /&gt;
# Click &#039;OK&#039;&lt;br /&gt;
# Proceed as before up to point 6, then press &#039;Close&#039; when asked if you want to create a new project.&lt;br /&gt;
# Now navigate to the folder you earlier specified in the &#039;local folder&#039; dialogue and you will find a folder marked &#039;contrib&#039;.&lt;br /&gt;
# navigate to the plugin folder, copy that folder, and then navigate to your main Moodle project folder and paste it where it belongs.&lt;br /&gt;
&lt;br /&gt;
===Adding a branch to your plugin===&lt;br /&gt;
Your plugin will likely start with just a HEAD tag and at some point, you will want to branch it so that you can have versions for different Moodles. To add a MOODLE_20_STABLE branch, for example, do the following.&lt;br /&gt;
&lt;br /&gt;
# Checkout as above, but use the MOODLE_20_STABLE branch instead of MOODLE_19_STABLE&lt;br /&gt;
# You will end up with an empty folder, which you copy into place as above.&lt;br /&gt;
# Find the folder in NetBeans, then right click and choose CVS-&amp;gt;Merge changes from branch...&lt;br /&gt;
# Choose to merge from whatever branch has all the current code, using the help link if not sure what to do.&lt;br /&gt;
&lt;br /&gt;
There is a small chance that the Merge link will not be there, in which case, you will have to copy the files into the directory by hand outside netbeans and then check them in. If you do this, make sure you don&#039;t copy over the &#039;CVS&#039; folders that will have been made when you checked out the MOODLE_19_STABLE code.&lt;br /&gt;
&lt;br /&gt;
=== A few warnings ===&lt;br /&gt;
&lt;br /&gt;
Some of these warnings could also apply to other IDEs:&lt;br /&gt;
&lt;br /&gt;
* If you want to delete a file from your computer but not from CVS, delete it from Windows Explorer/Nautilus/Finder. Otherwise your next commit could delete the file from CVS. &amp;lt;br/&amp;gt;In case you have already deleted a wrong file from NetBeans:  with Windows Explorer/Nautilus/Finder, delete all the folder content of this deleted file (including the CVS folder) and update the folder.&lt;br /&gt;
* If you rename files and that other people are working on them, NetBeans could end up to mess up your CVS folder (even though that is quite rare). Then NetBeans CVS will refuse to update your code displaying a no explicit error as &#039;&#039;&#039;Update Failed&#039;&#039;&#039;. In this case, delete the content of the damaged folder with Windows Explorer/Nautilus/Finder. Then update this folder.&lt;br /&gt;
* If you create a patch or a new PHP file with NetBeans on Microsoft Windows, please check that it&#039;s a Unix format file. You may want to use another software to create Unix format patch/php files.&lt;br /&gt;
&lt;br /&gt;
== Git with NetBeans ==&lt;br /&gt;
&lt;br /&gt;
=== NBGit | Git Support for NetBeans ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;NBGit is a module for the NetBeans IDE that adds support for working with the Git version control system. It uses the JGit library created as part of EGit to interact with Git repositories. Because the module is Java code all the way, it should work better cross-platform modulo platform specific differences, such as file system behavior. It is based on the NetBeans Mercurial module.&amp;quot; &lt;br /&gt;
(http://nbgit.org)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
Unfortunately, the key word in that quote is &#039;&#039;&#039;should&#039;&#039;&#039;. In reality, because JGit is a rewrite from scratch of the tried-and-tested git core C code, it is still buggy, incomplete and unreliable. Therefore, the NetBeans and Eclipse git plugins are still only beta quality, and pretty sucky. Well, they mostly work for browsing the contents of the repository, but there is a small chance that if you use them for update operations, they will corrupt your repository. Hence, I am still doing git from the command-line.--[[User:Tim Hunt|Tim Hunt]] 11:11, 19 January 2010 (UTC)&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Optimization ==&lt;br /&gt;
&lt;br /&gt;
1. You may want to run NetBeans with the Sun JDK. NetBeans seems to work a bit better with the [http://java.sun.com/javase/downloads/index.jsp Sun JDK]. You&#039;ll have to edit NetBeans config file. Open netbeans/etc/netbeans.conf. Then uncomment and edit: &lt;br /&gt;
&lt;br /&gt;
 netbeans_jdkhome=&amp;quot;your_JDK_path&amp;quot;&lt;br /&gt;
&lt;br /&gt;
2. To change the NetBeans look and feel run netbeans in the command line with this parameter:&lt;br /&gt;
 &amp;quot;netbeans&amp;quot;  --laf javax.swing.plaf.metal.MetalLookAndFeel &lt;br /&gt;
&lt;br /&gt;
3. If NetBeans starts to slow down, give it more memory&lt;br /&gt;
 &amp;quot;netbeans&amp;quot; -J-Xmx600m&lt;br /&gt;
See FAQ for more [http://wiki.netbeans.org/FaqSettingHeapSize details on memory optimisation].&lt;br /&gt;
&lt;br /&gt;
== Coding faster ==&lt;br /&gt;
&lt;br /&gt;
=== Keyboard shortcuts ===&lt;br /&gt;
(Note: Some shortcuts might not work for PHP development.)&lt;br /&gt;
* [http://www.phpmag.ru/2009/01/23/extremely-usefull-netbeans-shortcuts/ Extremely Useful NetBeans Shortcuts] &lt;br /&gt;
* [http://netbeanside61.blogspot.com/2008/04/top-10-netbeans-ide-keyboard-shortcuts.html Top 10 NetBeans IDE Keyboard Shortcuts I use the most]&lt;br /&gt;
* [http://wiki.netbeans.org/KeymapProfileFor60 NetBeans IDE 6.x Keyboard Shortcuts Specification]&lt;br /&gt;
&lt;br /&gt;
=== PHPUnit support ===&lt;br /&gt;
See [http://blogs.sun.com/netbeansphp/entry/recent_improvements_in_phpunit_support &amp;quot;Recent improvements in PHPUnit-support&amp;quot;] on how to use PHPUnit with NetBeans.&lt;br /&gt;
&lt;br /&gt;
===JIRA support===&lt;br /&gt;
You can install the optional JIRA module in order to be able to interact with the Moodle Tracker from within netbeans. This has the advantage of avoiding constantly switching back and forth from the browser and works quite well. Go to Tools-&amp;gt;plugins-&amp;gt;available plugins and search for JIRA. Once installed, right click &#039;issue trackers&#039; in the &#039;services&#039; pane to make a new tracker instance, then enter your details.&lt;br /&gt;
&lt;br /&gt;
== See also: ==&lt;br /&gt;
Moodle forums &lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=112972 NetBeans 6.5 for moodle/PHP/debugging is a better experience v.s Eclipse]&lt;br /&gt;
&lt;br /&gt;
Online resources&lt;br /&gt;
* [http://www.netbeans.org/kb/trails/php.html NetBeans PHP Learning Trail]&lt;br /&gt;
* [http://wiki.netbeans.org/PHP NetBeans PHP Wiki]&lt;br /&gt;
* Sun&#039;s [http://blogs.sun.com/netbeansphp/ NetBeans PHP Team Blog]&lt;br /&gt;
&lt;br /&gt;
Book&lt;br /&gt;
* [http://www.packtpub.com/netbeans-platform-6-8-developers-guide/book NetBeans Platform 6.8 Developer&#039;s Guide] by Jürgen Petri (March 2010), focus on Java and Swing &lt;br /&gt;
&lt;br /&gt;
[[Category:NetBeans]]&lt;br /&gt;
[[Category:Developer tools|NetBeans]]&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Setting_up_Netbeans&amp;diff=8985</id>
		<title>Setting up Netbeans</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Setting_up_Netbeans&amp;diff=8985"/>
		<updated>2010-06-05T13:17:31Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* Checkout for developers with write access */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.netbeans.org/features/php/index.html NetBeans] has got a good PHP support. You find a host of information on the website (tutorials, developer blog, screen casts, etc.).&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
* CVS integration: see all changes, lines deletion, diff in real time, show annotations, diff history...&lt;br /&gt;
* Ctrl+Click: Go to declaration&lt;br /&gt;
* Export/Import Diff Patch&lt;br /&gt;
* Easy navigation&lt;br /&gt;
* List of functions&lt;br /&gt;
* Code completion&lt;br /&gt;
* Instant rename&lt;br /&gt;
* HTML, CSS, JavaScript support&lt;br /&gt;
* MySQL manager&lt;br /&gt;
* Quick Search&lt;br /&gt;
* Very few bugs&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
* Download the latest [http://netbeans.org/community/releases/68/ 6.8 version] with PHP support, only 25 MB.&lt;br /&gt;
* Install and run it.&lt;br /&gt;
&lt;br /&gt;
== Set up for Moodle development ==&lt;br /&gt;
&lt;br /&gt;
* Checkout your Moodle project with a &#039;&#039;&#039;CVS client&#039;&#039;&#039; - see [[CVS for Administrators]] or [[CVS for developers|CVS for Developers]].&lt;br /&gt;
&lt;br /&gt;
* Open File &amp;gt; New Project &amp;gt; PHP &amp;gt; PHP Application &amp;gt; Next &lt;br /&gt;
: You&#039;re going to set the project now. &#039;&#039;Name&#039;&#039;, &#039;&#039;Location&#039;&#039; and &#039;&#039;Folder&#039;&#039; are used by NetBeans and are not related to the source code. So you can choose whatever you like, except your source folder. &#039;&#039;Sources&#039;&#039; has to be your checked out Moodle branch/head folder. The rest is clear enough. Don&#039;t forget to choose UTF-8 for &#039;&#039;Default Encoding&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
: Example:&lt;br /&gt;
&lt;br /&gt;
 Project Name:        Moodle 1.9 Stable&lt;br /&gt;
 Project Location:    C:\Users\jerome\Documents\NetBeansProjects&lt;br /&gt;
 Project Folder:      C:\Users\jerome\Documents\NetBeansProjects\Moodle 1.9 Stable&lt;br /&gt;
 Project Sources:     C:\Users\jerome\Projects\branch19_STABLE\moodle&lt;br /&gt;
 Project URL:         http://localhost/moodle19/&lt;br /&gt;
 Index File:          index.php&lt;br /&gt;
 Create:              unchecked&lt;br /&gt;
 Default Encoding:    UTF-8&lt;br /&gt;
 Set as Main Project: unchecked&lt;br /&gt;
&lt;br /&gt;
* Click on Finish.&lt;br /&gt;
&lt;br /&gt;
* Start coding!&lt;br /&gt;
&lt;br /&gt;
== CVS with NetBeans ==&lt;br /&gt;
&lt;br /&gt;
NetBeans comes with &#039;&#039;&#039;integrated CVS support&#039;&#039;&#039; which might be the easiest way to check out Moodle.&lt;br /&gt;
&lt;br /&gt;
=== Anonymous checkout ===&lt;br /&gt;
&lt;br /&gt;
# In NetBeans, select Window-&amp;gt;Versioning-&amp;gt;CVS-&amp;gt;Checkout&lt;br /&gt;
# Select Team-&amp;gt;CVS-&amp;gt;Checkout&lt;br /&gt;
# Enter into CVS Root: &#039;&#039;:pserver:anonymous@us.cvs.moodle.org:/cvsroot/moodle&#039;&#039;&lt;br /&gt;
: (Non-US-residents might use one of the other [https://docs.moodle.org/en/CVS_for_Administrators#CVS_Servers Moodle CVS servers] nearer to them.)&lt;br /&gt;
# Click &#039;&#039;Next&#039;&#039;&lt;br /&gt;
# Browse or enter into &#039;&#039;Module:&#039;&#039; moodle&lt;br /&gt;
# Browse or enter into &#039;&#039;Branch:&#039;&#039; MOODLE_19_STABLE&lt;br /&gt;
# Browse or enter into &#039;&#039;Local Folder:&#039;&#039; C:\xampp\htdocs&lt;br /&gt;
# Click &#039;&#039;Finish&#039;&#039; (and wait a few minutes for Moodle to be checked out)&lt;br /&gt;
# When you get the dialog box &amp;quot;Do you want to create an IDE project from the checked-out sources?&amp;quot;, Click &amp;quot;Create Project...&amp;quot;&lt;br /&gt;
# Select PHP Application with Existing Sources, and click Next&lt;br /&gt;
# Browse or enter into &#039;&#039;Sources Folder&#039;&#039; C:\xampp\htdocs\moodle&lt;br /&gt;
# Enter into &#039;&#039;Project Name:&#039;&#039; moodle&lt;br /&gt;
# Keep the other defaults and click next&lt;br /&gt;
# &#039;&#039;Run As:&#039;&#039; should have selected &#039;&#039;Local Web Site (running on local web server)&#039;&#039;&lt;br /&gt;
# Enter into Project URL http://localhost/moodle/&lt;br /&gt;
# Browse or enter into &#039;&#039;Index File:&#039;&#039; index.php&lt;br /&gt;
# Click &#039;&#039;Finish&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checkout for developers with write access ===&lt;br /&gt;
&lt;br /&gt;
IF you wish to use NetBeans CVS and have CVS write access, the procedure is as follows:&lt;br /&gt;
&lt;br /&gt;
====Checkout of main Moodle codebase====&lt;br /&gt;
&lt;br /&gt;
# Follow the above instructions except for point 3&lt;br /&gt;
# At part 3, substitute &#039;&#039;:ext:yourusername&#039;&#039; for the part before the @ and remove the country code from after it, leaving it like this  &#039;&#039;&#039;&#039;&#039;:ext:yourusername&#039;&#039;&#039;@cvs.moodle.org:/cvsroot/moodle&#039;&#039;&lt;br /&gt;
# Follow the rest of the instructions as above&lt;br /&gt;
&lt;br /&gt;
If you wish to work with a plugin, you will need to check this out separately and add it to the Moodle code project you have just made. This because for some reason, the &#039;Do you want to create a project&#039; option fails to show any of the files once you open it if you try to check out the plugin on its own (NetBeans 6.7.1 on a Mac).&lt;br /&gt;
&lt;br /&gt;
====Checkout of contrib code====&lt;br /&gt;
&lt;br /&gt;
# Follow the above steps up to point 3, and again substitute &#039;&#039;:ext:yourusername&#039;&#039; and click &#039;next&#039;. Note that you should not try to specify the full contrib repository path yet.&lt;br /&gt;
# Click &#039;Browse...&#039; next to the &#039;Module&#039; dialogue&lt;br /&gt;
# Find the plugin you wish to work with in CONTRIB&lt;br /&gt;
# Click &#039;OK&#039;&lt;br /&gt;
# Proceed as before up to point 6, then press &#039;Close&#039; when asked if you want to create a new project.&lt;br /&gt;
# Now navigate to the folder you earlier specified in the &#039;local folder&#039; dialogue and you will find a folder marked &#039;contrib&#039;.&lt;br /&gt;
# navigate to the plugin folder, copy that folder, and then navigate to your main Moodle project folder and paste it where it belongs.&lt;br /&gt;
&lt;br /&gt;
===Adding a branch to your plugin===&lt;br /&gt;
Your plugin will likely start with just a HEAD tag and at some point, you will want to branch it so that you can have versions for different Moodles. To add a MOODLE_20_STABLE branch, for example, do the following.&lt;br /&gt;
&lt;br /&gt;
# Checkout as above, but use the MOODLE_20_STABLE branch instead of MOODLE_19_STABLE&lt;br /&gt;
# You will end up with an empty folder, which you copy into place as above.&lt;br /&gt;
# Find the folder in NetBeans, then right click and choose CVS-&amp;gt;Merge changes from branch...&lt;br /&gt;
# Choose to merge from whatever branch has all the current code, using the help link if not sure what to do.&lt;br /&gt;
&lt;br /&gt;
There is a small chance that the Merge link will not be there, in which case, you will have to copy the files into the directory by hand outside netbeans and then check them in. If you do this, make sure you don&#039;t copy over the &#039;CVS&#039; folders that will have been made when you checked out the MOODLE_19_STABLE code.&lt;br /&gt;
&lt;br /&gt;
=== A few warnings ===&lt;br /&gt;
&lt;br /&gt;
Some of these warnings could also apply to other IDEs:&lt;br /&gt;
&lt;br /&gt;
* If you want to delete a file from your computer but not from CVS, delete it from Windows Explorer/Nautilus/Finder. Otherwise your next commit could delete the file from CVS. &amp;lt;br/&amp;gt;In case you have already deleted a wrong file from NetBeans:  with Windows Explorer/Nautilus/Finder, delete all the folder content of this deleted file (including the CVS folder) and update the folder.&lt;br /&gt;
* If you rename files and that other people are working on them, NetBeans could end up to mess up your CVS folder (even though that is quite rare). Then NetBeans CVS will refuse to update your code displaying a no explicit error as &#039;&#039;&#039;Update Failed&#039;&#039;&#039;. In this case, delete the content of the damaged folder with Windows Explorer/Nautilus/Finder. Then update this folder.&lt;br /&gt;
* If you create a patch or a new PHP file with NetBeans on Microsoft Windows, please check that it&#039;s a Unix format file. You may want to use another software to create Unix format patch/php files.&lt;br /&gt;
&lt;br /&gt;
== Git with NetBeans ==&lt;br /&gt;
&lt;br /&gt;
=== NBGit | Git Support for NetBeans ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;NBGit is a module for the NetBeans IDE that adds support for working with the Git version control system. It uses the JGit library created as part of EGit to interact with Git repositories. Because the module is Java code all the way, it should work better cross-platform modulo platform specific differences, such as file system behavior. It is based on the NetBeans Mercurial module.&amp;quot; &lt;br /&gt;
(http://nbgit.org)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
Unfortunately, the key word in that quote is &#039;&#039;&#039;should&#039;&#039;&#039;. In reality, because JGit is a rewrite from scratch of the tried-and-tested git core C code, it is still buggy, incomplete and unreliable. Therefore, the NetBeans and Eclipse git plugins are still only beta quality, and pretty sucky. Well, they mostly work for browsing the contents of the repository, but there is a small chance that if you use them for update operations, they will corrupt your repository. Hence, I am still doing git from the command-line.--[[User:Tim Hunt|Tim Hunt]] 11:11, 19 January 2010 (UTC)&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Optimization ==&lt;br /&gt;
&lt;br /&gt;
1. You may want to run NetBeans with the Sun JDK. NetBeans seems to work a bit better with the [http://java.sun.com/javase/downloads/index.jsp Sun JDK]. You&#039;ll have to edit NetBeans config file. Open netbeans/etc/netbeans.conf. Then uncomment and edit: &lt;br /&gt;
&lt;br /&gt;
 netbeans_jdkhome=&amp;quot;your_JDK_path&amp;quot;&lt;br /&gt;
&lt;br /&gt;
2. To change the NetBeans look and feel run netbeans in the command line with this parameter:&lt;br /&gt;
 &amp;quot;netbeans&amp;quot;  --laf javax.swing.plaf.metal.MetalLookAndFeel &lt;br /&gt;
&lt;br /&gt;
3. If NetBeans starts to slow down, give it more memory&lt;br /&gt;
 &amp;quot;netbeans&amp;quot; -J-Xmx600m&lt;br /&gt;
See FAQ for more [http://wiki.netbeans.org/FaqSettingHeapSize details on memory optimisation].&lt;br /&gt;
&lt;br /&gt;
== Coding faster ==&lt;br /&gt;
&lt;br /&gt;
=== Keyboard shortcuts ===&lt;br /&gt;
(Note: Some shortcuts might not work for PHP development.)&lt;br /&gt;
* [http://www.phpmag.ru/2009/01/23/extremely-usefull-netbeans-shortcuts/ Extremely Useful NetBeans Shortcuts] &lt;br /&gt;
* [http://netbeanside61.blogspot.com/2008/04/top-10-netbeans-ide-keyboard-shortcuts.html Top 10 NetBeans IDE Keyboard Shortcuts I use the most]&lt;br /&gt;
* [http://wiki.netbeans.org/KeymapProfileFor60 NetBeans IDE 6.x Keyboard Shortcuts Specification]&lt;br /&gt;
&lt;br /&gt;
=== PHPUnit support ===&lt;br /&gt;
See [http://blogs.sun.com/netbeansphp/entry/recent_improvements_in_phpunit_support &amp;quot;Recent improvements in PHPUnit-support&amp;quot;] on how to use PHPUnit with NetBeans.&lt;br /&gt;
&lt;br /&gt;
===JIRA support===&lt;br /&gt;
You can install the optional JIRA module in order to be able to interact with the Moodle Tracker from within netbeans. This has the advantage of avoiding constantly switching back and forth from the browser and works quite well. Go to Tools-&amp;gt;plugins-&amp;gt;available plugins and search for JIRA. Once installed, right click &#039;issue trackers&#039; in the &#039;services&#039; pane to make a new tracker instance, then enter your details.&lt;br /&gt;
&lt;br /&gt;
== See also: ==&lt;br /&gt;
Moodle forums &lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=112972 NetBeans 6.5 for moodle/PHP/debugging is a better experience v.s Eclipse]&lt;br /&gt;
&lt;br /&gt;
Online resources&lt;br /&gt;
* [http://www.netbeans.org/kb/trails/php.html NetBeans PHP Learning Trail]&lt;br /&gt;
* [http://wiki.netbeans.org/PHP NetBeans PHP Wiki]&lt;br /&gt;
* Sun&#039;s [http://blogs.sun.com/netbeansphp/ NetBeans PHP Team Blog]&lt;br /&gt;
&lt;br /&gt;
Book&lt;br /&gt;
* [http://www.packtpub.com/netbeans-platform-6-8-developers-guide/book NetBeans Platform 6.8 Developer&#039;s Guide] by Jürgen Petri (March 2010), focus on Java and Swing &lt;br /&gt;
&lt;br /&gt;
[[Category:NetBeans]]&lt;br /&gt;
[[Category:Developer tools|NetBeans]]&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Setting_up_Netbeans&amp;diff=8984</id>
		<title>Setting up Netbeans</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Setting_up_Netbeans&amp;diff=8984"/>
		<updated>2010-06-05T13:14:30Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* Checkout for developers with write access */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.netbeans.org/features/php/index.html NetBeans] has got a good PHP support. You find a host of information on the website (tutorials, developer blog, screen casts, etc.).&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
* CVS integration: see all changes, lines deletion, diff in real time, show annotations, diff history...&lt;br /&gt;
* Ctrl+Click: Go to declaration&lt;br /&gt;
* Export/Import Diff Patch&lt;br /&gt;
* Easy navigation&lt;br /&gt;
* List of functions&lt;br /&gt;
* Code completion&lt;br /&gt;
* Instant rename&lt;br /&gt;
* HTML, CSS, JavaScript support&lt;br /&gt;
* MySQL manager&lt;br /&gt;
* Quick Search&lt;br /&gt;
* Very few bugs&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
* Download the latest [http://netbeans.org/community/releases/68/ 6.8 version] with PHP support, only 25 MB.&lt;br /&gt;
* Install and run it.&lt;br /&gt;
&lt;br /&gt;
== Set up for Moodle development ==&lt;br /&gt;
&lt;br /&gt;
* Checkout your Moodle project with a &#039;&#039;&#039;CVS client&#039;&#039;&#039; - see [[CVS for Administrators]] or [[CVS for developers|CVS for Developers]].&lt;br /&gt;
&lt;br /&gt;
* Open File &amp;gt; New Project &amp;gt; PHP &amp;gt; PHP Application &amp;gt; Next &lt;br /&gt;
: You&#039;re going to set the project now. &#039;&#039;Name&#039;&#039;, &#039;&#039;Location&#039;&#039; and &#039;&#039;Folder&#039;&#039; are used by NetBeans and are not related to the source code. So you can choose whatever you like, except your source folder. &#039;&#039;Sources&#039;&#039; has to be your checked out Moodle branch/head folder. The rest is clear enough. Don&#039;t forget to choose UTF-8 for &#039;&#039;Default Encoding&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
: Example:&lt;br /&gt;
&lt;br /&gt;
 Project Name:        Moodle 1.9 Stable&lt;br /&gt;
 Project Location:    C:\Users\jerome\Documents\NetBeansProjects&lt;br /&gt;
 Project Folder:      C:\Users\jerome\Documents\NetBeansProjects\Moodle 1.9 Stable&lt;br /&gt;
 Project Sources:     C:\Users\jerome\Projects\branch19_STABLE\moodle&lt;br /&gt;
 Project URL:         http://localhost/moodle19/&lt;br /&gt;
 Index File:          index.php&lt;br /&gt;
 Create:              unchecked&lt;br /&gt;
 Default Encoding:    UTF-8&lt;br /&gt;
 Set as Main Project: unchecked&lt;br /&gt;
&lt;br /&gt;
* Click on Finish.&lt;br /&gt;
&lt;br /&gt;
* Start coding!&lt;br /&gt;
&lt;br /&gt;
== CVS with NetBeans ==&lt;br /&gt;
&lt;br /&gt;
NetBeans comes with &#039;&#039;&#039;integrated CVS support&#039;&#039;&#039; which might be the easiest way to check out Moodle.&lt;br /&gt;
&lt;br /&gt;
=== Anonymous checkout ===&lt;br /&gt;
&lt;br /&gt;
# In NetBeans, select Window-&amp;gt;Versioning-&amp;gt;CVS-&amp;gt;Checkout&lt;br /&gt;
# Select Team-&amp;gt;CVS-&amp;gt;Checkout&lt;br /&gt;
# Enter into CVS Root: &#039;&#039;:pserver:anonymous@us.cvs.moodle.org:/cvsroot/moodle&#039;&#039;&lt;br /&gt;
: (Non-US-residents might use one of the other [https://docs.moodle.org/en/CVS_for_Administrators#CVS_Servers Moodle CVS servers] nearer to them.)&lt;br /&gt;
# Click &#039;&#039;Next&#039;&#039;&lt;br /&gt;
# Browse or enter into &#039;&#039;Module:&#039;&#039; moodle&lt;br /&gt;
# Browse or enter into &#039;&#039;Branch:&#039;&#039; MOODLE_19_STABLE&lt;br /&gt;
# Browse or enter into &#039;&#039;Local Folder:&#039;&#039; C:\xampp\htdocs&lt;br /&gt;
# Click &#039;&#039;Finish&#039;&#039; (and wait a few minutes for Moodle to be checked out)&lt;br /&gt;
# When you get the dialog box &amp;quot;Do you want to create an IDE project from the checked-out sources?&amp;quot;, Click &amp;quot;Create Project...&amp;quot;&lt;br /&gt;
# Select PHP Application with Existing Sources, and click Next&lt;br /&gt;
# Browse or enter into &#039;&#039;Sources Folder&#039;&#039; C:\xampp\htdocs\moodle&lt;br /&gt;
# Enter into &#039;&#039;Project Name:&#039;&#039; moodle&lt;br /&gt;
# Keep the other defaults and click next&lt;br /&gt;
# &#039;&#039;Run As:&#039;&#039; should have selected &#039;&#039;Local Web Site (running on local web server)&#039;&#039;&lt;br /&gt;
# Enter into Project URL http://localhost/moodle/&lt;br /&gt;
# Browse or enter into &#039;&#039;Index File:&#039;&#039; index.php&lt;br /&gt;
# Click &#039;&#039;Finish&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checkout for developers with write access ===&lt;br /&gt;
&lt;br /&gt;
IF you wish to use NetBeans CVS and have CVS write access, the procedure is as follows:&lt;br /&gt;
&lt;br /&gt;
# Follow the above instructions except for point 3&lt;br /&gt;
# At part 3, substitute &#039;&#039;:ext:yourusername&#039;&#039; for the part before the @ and remove the country code from after it, leaving it like this  &#039;&#039;&#039;&#039;&#039;:ext:yourusername&#039;&#039;&#039;@cvs.moodle.org:/cvsroot/moodle&#039;&#039;&lt;br /&gt;
# Follow the rest of the instructions as above&lt;br /&gt;
&lt;br /&gt;
If you wish to work with a plugin, you will need to check this out separately and add it to the Moodle code project you have just made. This because for some reason, the &#039;Do you want to create a project&#039; option fails to show any of the files once you open it if you try to check out the plugin on its own (NetBeans 6.7.1 on a Mac).&lt;br /&gt;
&lt;br /&gt;
# Follow the above steps up to point 3, and again substitute &#039;&#039;:ext:yourusername&#039;&#039; and click &#039;next&#039;&lt;br /&gt;
# Click &#039;Browse...&#039; next to the &#039;Module&#039; dialogue&lt;br /&gt;
# Find the plugin you wish to work with in CONTRIB&lt;br /&gt;
# Click &#039;OK&#039;&lt;br /&gt;
# Proceed as before up to point 6, then press &#039;Close&#039; when asked if you want to create a new project.&lt;br /&gt;
# Now navigate to the folder you earlier specified in the &#039;local folder&#039; dialogue and you will find a folder marked &#039;contrib&#039;.&lt;br /&gt;
# navigate to the plugin folder, copy that folder, and then navigate to your main Moodle project folder and paste it where it belongs.&lt;br /&gt;
&lt;br /&gt;
===Adding a branch to your plugin===&lt;br /&gt;
Your plugin will likely start with just a HEAD tag and at some point, you will want to branch it so that you can have versions for different Moodles. To add a MOODLE_20_STABLE branch, for example, do the following.&lt;br /&gt;
&lt;br /&gt;
# Checkout as above, but use the MOODLE_20_STABLE branch instead of MOODLE_19_STABLE&lt;br /&gt;
# You will end up with an empty folder, which you copy into place as above.&lt;br /&gt;
# Find the folder in NetBeans, then right click and choose CVS-&amp;gt;Merge changes from branch...&lt;br /&gt;
# Choose to merge from whatever branch has all the current code, using the help link if not sure what to do.&lt;br /&gt;
&lt;br /&gt;
There is a small chance that the Merge link will not be there, in which case, you will have to copy the files into the directory by hand outside netbeans and then check them in. If you do this, make sure you don&#039;t copy over the &#039;CVS&#039; folders that will have been made when you checked out the MOODLE_19_STABLE code.&lt;br /&gt;
&lt;br /&gt;
=== A few warnings ===&lt;br /&gt;
&lt;br /&gt;
Some of these warnings could also apply to other IDEs:&lt;br /&gt;
&lt;br /&gt;
* If you want to delete a file from your computer but not from CVS, delete it from Windows Explorer/Nautilus/Finder. Otherwise your next commit could delete the file from CVS. &amp;lt;br/&amp;gt;In case you have already deleted a wrong file from NetBeans:  with Windows Explorer/Nautilus/Finder, delete all the folder content of this deleted file (including the CVS folder) and update the folder.&lt;br /&gt;
* If you rename files and that other people are working on them, NetBeans could end up to mess up your CVS folder (even though that is quite rare). Then NetBeans CVS will refuse to update your code displaying a no explicit error as &#039;&#039;&#039;Update Failed&#039;&#039;&#039;. In this case, delete the content of the damaged folder with Windows Explorer/Nautilus/Finder. Then update this folder.&lt;br /&gt;
* If you create a patch or a new PHP file with NetBeans on Microsoft Windows, please check that it&#039;s a Unix format file. You may want to use another software to create Unix format patch/php files.&lt;br /&gt;
&lt;br /&gt;
== Git with NetBeans ==&lt;br /&gt;
&lt;br /&gt;
=== NBGit | Git Support for NetBeans ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;NBGit is a module for the NetBeans IDE that adds support for working with the Git version control system. It uses the JGit library created as part of EGit to interact with Git repositories. Because the module is Java code all the way, it should work better cross-platform modulo platform specific differences, such as file system behavior. It is based on the NetBeans Mercurial module.&amp;quot; &lt;br /&gt;
(http://nbgit.org)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
Unfortunately, the key word in that quote is &#039;&#039;&#039;should&#039;&#039;&#039;. In reality, because JGit is a rewrite from scratch of the tried-and-tested git core C code, it is still buggy, incomplete and unreliable. Therefore, the NetBeans and Eclipse git plugins are still only beta quality, and pretty sucky. Well, they mostly work for browsing the contents of the repository, but there is a small chance that if you use them for update operations, they will corrupt your repository. Hence, I am still doing git from the command-line.--[[User:Tim Hunt|Tim Hunt]] 11:11, 19 January 2010 (UTC)&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Optimization ==&lt;br /&gt;
&lt;br /&gt;
1. You may want to run NetBeans with the Sun JDK. NetBeans seems to work a bit better with the [http://java.sun.com/javase/downloads/index.jsp Sun JDK]. You&#039;ll have to edit NetBeans config file. Open netbeans/etc/netbeans.conf. Then uncomment and edit: &lt;br /&gt;
&lt;br /&gt;
 netbeans_jdkhome=&amp;quot;your_JDK_path&amp;quot;&lt;br /&gt;
&lt;br /&gt;
2. To change the NetBeans look and feel run netbeans in the command line with this parameter:&lt;br /&gt;
 &amp;quot;netbeans&amp;quot;  --laf javax.swing.plaf.metal.MetalLookAndFeel &lt;br /&gt;
&lt;br /&gt;
3. If NetBeans starts to slow down, give it more memory&lt;br /&gt;
 &amp;quot;netbeans&amp;quot; -J-Xmx600m&lt;br /&gt;
See FAQ for more [http://wiki.netbeans.org/FaqSettingHeapSize details on memory optimisation].&lt;br /&gt;
&lt;br /&gt;
== Coding faster ==&lt;br /&gt;
&lt;br /&gt;
=== Keyboard shortcuts ===&lt;br /&gt;
(Note: Some shortcuts might not work for PHP development.)&lt;br /&gt;
* [http://www.phpmag.ru/2009/01/23/extremely-usefull-netbeans-shortcuts/ Extremely Useful NetBeans Shortcuts] &lt;br /&gt;
* [http://netbeanside61.blogspot.com/2008/04/top-10-netbeans-ide-keyboard-shortcuts.html Top 10 NetBeans IDE Keyboard Shortcuts I use the most]&lt;br /&gt;
* [http://wiki.netbeans.org/KeymapProfileFor60 NetBeans IDE 6.x Keyboard Shortcuts Specification]&lt;br /&gt;
&lt;br /&gt;
=== PHPUnit support ===&lt;br /&gt;
See [http://blogs.sun.com/netbeansphp/entry/recent_improvements_in_phpunit_support &amp;quot;Recent improvements in PHPUnit-support&amp;quot;] on how to use PHPUnit with NetBeans.&lt;br /&gt;
&lt;br /&gt;
===JIRA support===&lt;br /&gt;
You can install the optional JIRA module in order to be able to interact with the Moodle Tracker from within netbeans. This has the advantage of avoiding constantly switching back and forth from the browser and works quite well. Go to Tools-&amp;gt;plugins-&amp;gt;available plugins and search for JIRA. Once installed, right click &#039;issue trackers&#039; in the &#039;services&#039; pane to make a new tracker instance, then enter your details.&lt;br /&gt;
&lt;br /&gt;
== See also: ==&lt;br /&gt;
Moodle forums &lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=112972 NetBeans 6.5 for moodle/PHP/debugging is a better experience v.s Eclipse]&lt;br /&gt;
&lt;br /&gt;
Online resources&lt;br /&gt;
* [http://www.netbeans.org/kb/trails/php.html NetBeans PHP Learning Trail]&lt;br /&gt;
* [http://wiki.netbeans.org/PHP NetBeans PHP Wiki]&lt;br /&gt;
* Sun&#039;s [http://blogs.sun.com/netbeansphp/ NetBeans PHP Team Blog]&lt;br /&gt;
&lt;br /&gt;
Book&lt;br /&gt;
* [http://www.packtpub.com/netbeans-platform-6-8-developers-guide/book NetBeans Platform 6.8 Developer&#039;s Guide] by Jürgen Petri (March 2010), focus on Java and Swing &lt;br /&gt;
&lt;br /&gt;
[[Category:NetBeans]]&lt;br /&gt;
[[Category:Developer tools|NetBeans]]&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Migrating_contrib_code_to_2.0&amp;diff=17557</id>
		<title>Migrating contrib code to 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Migrating_contrib_code_to_2.0&amp;diff=17557"/>
		<updated>2010-05-18T16:25:02Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;WARNING: Under construction RIGHT NOW!&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The goal of this page is to provide a checklist of tasks to be considered to upgrade CONTRIB code to Moodle 2.0. Several significant changes have taken place including the File API, DB Layer, Navigation, Output renderer, etc. It would be good if we had a list that contributors could follow to help move them toward being able to migrate the code. Any help in building up this list is greatly appreciated. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Please add useful links...&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [[DB_layer_2.0_migration_docs]]&lt;br /&gt;
* [[Using the File API in Moodle forms]]&lt;br /&gt;
* [[Output_renderers]]&lt;br /&gt;
* [[Migrating_your_code_to_the_2.0_rendering_API]] (n.b., some info outdated and may need updating)&lt;br /&gt;
* [[Themes_2.0]]&lt;br /&gt;
&lt;br /&gt;
Some details of how to re-design image CSS for plugin code ar in the main themes documentation: [[Themes_2.0_creating_your_first_theme#Using_images_within_CSS]]&lt;br /&gt;
&lt;br /&gt;
Be aware that themes are now cached on the server and so emptying your browser cache will not refresh the CSS. This can only be done by going to the site administration-&amp;gt;appearance-&amp;gt;themes-&amp;gt;theme selector page and clicking the &#039;invalidate theme caches&#039; button.&lt;br /&gt;
&lt;br /&gt;
Javascript is included in different ways now and will need to be migrated, see the PHPDoc comments in /lib/outputrequirements.lib and some (slightly outdated) advice here: [[JavaScript_guidelines]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* CONTRIB-1988&lt;br /&gt;
* http://cvs.moodle.org/moodle/blocks/upgrade.txt?view=markup&lt;br /&gt;
* http://cvs.moodle.org/moodle/mod/upgrade.txt?view=markup&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Migrating_contrib_code_to_2.0&amp;diff=17556</id>
		<title>Migrating contrib code to 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Migrating_contrib_code_to_2.0&amp;diff=17556"/>
		<updated>2010-05-18T16:22:11Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;WARNING: Under construction RIGHT NOW!&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The goal of this page is to provide a checklist of tasks to be considered to upgrade CONTRIB code to Moodle 2.0. Several significant changes have taken place including the File API, DB Layer, Navigation, Output renderer, etc. It would be good if we had a list that contributors could follow to help move them toward being able to migrate the code. Any help in building up this list is greatly appreciated. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Please add useful links...&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [[DB_layer_2.0_migration_docs]]&lt;br /&gt;
* [[Using the File API in Moodle forms]]&lt;br /&gt;
* [[Output_renderers]]&lt;br /&gt;
* [[Migrating_your_code_to_the_2.0_rendering_API]] (n.b., some info outdated and may need updating)&lt;br /&gt;
* [[Themes_2.0]]&lt;br /&gt;
&lt;br /&gt;
Some details of how to re-design image CSS for plugin code ar in the main themes documentation: [[Themes_2.0_creating_your_first_theme#Using_images_within_CSS]]&lt;br /&gt;
&lt;br /&gt;
Javascript is included in different ways now and will need to be migrated, see the PHPDoc comments in /lib/outputrequirements.lib and some (slightly outdated) advice here: [[JavaScript_guidelines]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* CONTRIB-1988&lt;br /&gt;
* http://cvs.moodle.org/moodle/blocks/upgrade.txt?view=markup&lt;br /&gt;
* http://cvs.moodle.org/moodle/mod/upgrade.txt?view=markup&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=DB_layer_2.0_migration_docs&amp;diff=9112</id>
		<title>DB layer 2.0 migration docs</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=DB_layer_2.0_migration_docs&amp;diff=9112"/>
		<updated>2010-05-03T21:21:49Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* The golden changes */ Added note on how to combine G6 and G7&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Development:dmllib 2.0}}{{Moodle_2.0}}&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Much of the following documentation will not make much sense unless you first read [[XMLDB_Documentation|the XMLDB documentation]]. Please read it first if you would like to join the effort to convert Moodle&#039;s code to the new dmllib.&lt;br /&gt;
&lt;br /&gt;
Also, it&#039;s recommended to read the whole [[wikipedia:Data_Definition_Language|DDL]] and [[wikipedia:Data_Manipulation_Language|DML]] documentation before start with the migration. That will allow you to have some initial knowledge about the new architecture.&lt;br /&gt;
&lt;br /&gt;
This article defines all the changes that need to be performed in Moodle 1.9 code in order to make it run properly under new Moodle 2.0 DB layer. Changes below are grouped into 2 main blocks ([[XMLDB_Documentation|xmldb]] and [[wikipedia:Data_Manipulation_Language|dml]]) to have them organised. Additional minor changes may be required in the [[wikipedia:Data_Definition_Language|ddl]] code, but won&#039;t be documented here.&lt;br /&gt;
&lt;br /&gt;
Although the order of changes showed in this page isn&#039;t mandatory at all, it can be interesting to follow it in the migration progress to be able to understand and learn a bit more about all them. That way, you&#039;ll end up knowing not only what to change but how and why those changes are required.&lt;br /&gt;
&lt;br /&gt;
Each change will be as simple as possible, representing one easy rule to follow to adapt the code. When anything become too complex to be explained as one simple rule, it will contain one link to the [[dmllib_2.0_examples|examples page]].&lt;br /&gt;
&lt;br /&gt;
For any problem in the migration of code, it&#039;s recommended to use the [http://moodle.org/mod/forum/view.php?id=45 Databases forum] at [http://moodle.org moodle.org]. Also if you find any bug in the process, please report it in the [http://tracker.moodle.org/browse/MDL-14679 Moodle Tracker], that way developers will be able to fix it ASAP.&lt;br /&gt;
&lt;br /&gt;
The Glossary module was used as the basis for many of the examples below.&lt;br /&gt;
&lt;br /&gt;
And finally, feel free to complete/fix the list below with the changes you find in the progress of migration, that will certainly help many developers. Thanks!&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== check_db_syntax: One helper script ==&lt;br /&gt;
&lt;br /&gt;
Before start migrating your code to Moodle 2.0, it&#039;s recommended to install and run the [http://cvs.moodle.org/contrib/tools/check_db_syntax/ check_db_syntax.php] script. Simply copy it to the main folder of your plugin and execute it (from command line or via web). I&#039;ll show you the list of old DB usages that need to be transformed following the information below in this article.&lt;br /&gt;
&lt;br /&gt;
If you think that something is missing in the script or have any idea to improve it, feel free to do that yourself, commenting about it in MDL-15237. Thanks!&lt;br /&gt;
&lt;br /&gt;
Also, this (perl-compatible - works in Eclipse, hopefully elsewhere) regex:&lt;br /&gt;
&lt;br /&gt;
 (?&amp;lt;!-&amp;gt;)(?&amp;lt;!function )(?&amp;lt;!\$)\b(?:(?:count|delete|get|insert|udpate)_record(?!s_csv)|[gs]et_field|record_exists|execute_sql)|\$CFG-&amp;gt;prefix|rs_(?:fetch|close)|addslashes(?!_js)&lt;br /&gt;
&lt;br /&gt;
Will find most of the things in your code that need attention, with few false positives.&lt;br /&gt;
&lt;br /&gt;
== XMLDB/DDL changes ==&lt;br /&gt;
&lt;br /&gt;
=== Some comments ===&lt;br /&gt;
&lt;br /&gt;
* When changing DB structures it&#039;s highly recommended to use the [[XMLDB editor|XMLDB Editor]] (Admin-&amp;gt;Development-&amp;gt;XMLDB Editor). It is a safe way to edit install.xml files and to get correct PHP code to be used in upgrade.php scripts.&lt;br /&gt;
* If you have some doubts about the list of changes below, it&#039;s highly recommended to take a look at some code in core modules, blocks... whatever you need. They are a good reference.&lt;br /&gt;
* The most noticeable change (from a migration perspective) in the DDL stuff is that, starting with Moodle 2.0, we have decided to &#039;&#039;&#039;drop support for enum (check constraint) fields completely&#039;&#039;&#039;. See MDL-18577 and [http://moodle.org/mod/forum/discuss.php?d=118852 this discussion]. That implies changes in different parts of the DB stuff (xml files, function parameters, dropping existing enums...) and are commented with more detail below.&lt;br /&gt;
&lt;br /&gt;
=== The changes ===&lt;br /&gt;
&lt;br /&gt;
* No changes are required in install.xml files at all (that&#039;s good news!). Although you must know these:&lt;br /&gt;
** The &#039;&#039;&#039;ENUM&#039;&#039;&#039; and &#039;&#039;&#039;ENUMVALUES&#039;&#039;&#039; attributes present in your install.xml files will be completely ignored both by the DLL generation stuff and by the XMLDB Editor.&lt;br /&gt;
** In Moodle 2.1, those attributes (&#039;&#039;&#039;ENUM&#039;&#039;&#039; and &#039;&#039;&#039;ENUMVALUES&#039;&#039;&#039;) will be 100% forbidden, so it&#039;s highly recommended to erase them since now (Moodle 2.0).&lt;br /&gt;
** The XMLDB Editor will detect them when loading any install.xml file and will suggest you to fix that easily with one 1-click® option.&lt;br /&gt;
** No matter if you have fixed that with the 1-click® option when loading the files... the [[XMLDB editor|XMLDB Editor]] will save any edited install.xml files without those attributes.&lt;br /&gt;
** If your Moodle 1.9.x code &#039;&#039;&#039;has some enum defined in the database&#039;&#039;&#039;, you will need to create one upgrade block (in db/upgrade.php) to drop it (the enum, not the field! ;-) as part of the migration from Moodle 1.9 to 2.0 by using the new &#039;&#039;&#039;[[DB layer 2.0 examples#Dropping one enum from one field|drop_enum_from_field()]]&#039;&#039;&#039; method.&lt;br /&gt;
** Of course, if you don&#039;t use/like the XMLDB Editor, you can erase them manually with something like this:&lt;br /&gt;
 perl -p -e &#039;s/ENUM(VALUES)?=&amp;quot;.*?&amp;quot; //g&#039; &amp;lt; install.xml &amp;gt; install.xml.new&lt;br /&gt;
&lt;br /&gt;
* All upgrade.php scripts, within the main xxxx_upgrade function must have &#039;&#039;&#039;$DB&#039;&#039;&#039; (uppercase) in the globals declaration (along with others if needed). Example (from glossary module):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function xmldb_glossary_upgrade($oldversion=0) {&lt;br /&gt;
    &lt;br /&gt;
    global $CFG, $THEME, $DB;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
* All upgrade.php scripts, must NOT have &#039;&#039;&#039;$db&#039;&#039;&#039; (lowercase) in the globals declaration. Delete it if present.&lt;br /&gt;
* After the global declaration in the points above, this line must be present (we&#039;ll need it later):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$dbman = $DB-&amp;gt;get_manager(); /// loads ddl manager and xmldb classes&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
* All &#039;&#039;&#039;XMLDBTable&#039;&#039;&#039; instances in your upgrade code must be replaced by &#039;&#039;&#039;xmldb_table&#039;&#039;&#039; (no change in parameters)&lt;br /&gt;
* All &#039;&#039;&#039;XMLDBField&#039;&#039;&#039; instances in your upgrade code must be replaced by &#039;&#039;&#039;xmldb_field&#039;&#039;&#039; (with change in params, both enum and enumvalues are out from function declaration!)&lt;br /&gt;
* All &#039;&#039;&#039;XMLDBIndex&#039;&#039;&#039; instances in your upgrade code must be replaced by &#039;&#039;&#039;xmldb_index&#039;&#039;&#039; (no change in parameters)&lt;br /&gt;
* All &#039;&#039;&#039;XMLDBKey&#039;&#039;&#039; instances in your upgrade code must be replaced by &#039;&#039;&#039;xmldb_key&#039;&#039;&#039; (no change in parameters)&lt;br /&gt;
* All the &#039;&#039;&#039;addFieldInfo()&#039;&#039;&#039; methods must be replaced by &#039;&#039;&#039;add_field()&#039;&#039;&#039; (with change in params, both enum and enumvalues are out from function declaration!)&lt;br /&gt;
* All the &#039;&#039;&#039;addIndexInfo()&#039;&#039;&#039; methods must be replaced by &#039;&#039;&#039;add_index()&#039;&#039;&#039; (no change in parameters)&lt;br /&gt;
* All the &#039;&#039;&#039;addKeyInfo()&#039;&#039;&#039; methods must be replaced by &#039;&#039;&#039;add_key()&#039;&#039;&#039; (no change in parameters)&lt;br /&gt;
* All the &#039;&#039;&#039;setAttributes()&#039;&#039;&#039; methods must be replaced by &#039;&#039;&#039;set_attributes()&#039;&#039;&#039; (with change in params, both enum and enumvalues are out from function declaration!)&lt;br /&gt;
* All the DDL functions used in upgrade code, must be transformed as detailed below (it&#039;s only about to add &#039;&#039;&#039;&amp;quot;$dbman-&amp;gt;&amp;quot;&#039;&#039;&#039; - without the quotes - before each function call). No changes in parameters are required:&lt;br /&gt;
** table_exists ==&amp;gt; $dbman-&amp;gt;table_exists&lt;br /&gt;
** field_exists ==&amp;gt; $dbman-&amp;gt;field_exists&lt;br /&gt;
** index_exists ==&amp;gt; $dbman-&amp;gt;index_exists&lt;br /&gt;
** find_index_name ==&amp;gt; $dbman-&amp;gt;find_index_name&lt;br /&gt;
** find_check_constraint_name ==&amp;gt; $dbman-&amp;gt;find_check_constraint_name (&#039;&#039;&#039;DEPRECATED in 2.0. OUT in 2.1&#039;&#039;&#039;)&lt;br /&gt;
** check_constraint_exists ==&amp;gt; $dbman-&amp;gt;check_constraint_exists (&#039;&#039;&#039;DEPRECATED in 2.0. OUT in 2.1&#039;&#039;&#039;)&lt;br /&gt;
** find_sequence_name ==&amp;gt; &#039;&#039;&#039;OUT in 2.0&#039;&#039;&#039;, see MDL-20349&lt;br /&gt;
** create_table ==&amp;gt; $dbman-&amp;gt;create_table&lt;br /&gt;
** drop_table ==&amp;gt; $dbman-&amp;gt;drop_table&lt;br /&gt;
** rename_table ==&amp;gt; $dbman-&amp;gt;rename_table&lt;br /&gt;
** add_field ==&amp;gt; $dbman-&amp;gt;add_field&lt;br /&gt;
** drop_field ==&amp;gt; $dbman-&amp;gt;drop field&lt;br /&gt;
** rename_field ==&amp;gt; $dbman-&amp;gt;rename_field&lt;br /&gt;
** change_field_type ==&amp;gt; $dbman-&amp;gt;change_field_type&lt;br /&gt;
** change_field_precision =&amp;gt; $dbman-&amp;gt;change_field_precision&lt;br /&gt;
** change_field_unsigned ==&amp;gt; $dbman-&amp;gt;change_field_unsigned&lt;br /&gt;
** change_field_notnull ==&amp;gt; $dbman-&amp;gt;change_field_notnull&lt;br /&gt;
** change_field_enum ==&amp;gt; $dbman-&amp;gt;change_field_enum (&#039;&#039;&#039;OUT in 2.0&#039;&#039;&#039;, see &#039;&#039;&#039;[[DB layer 2.0 examples#Dropping one enum from one field|drop_enum_from_field()]]&#039;&#039;&#039; to get rid of remaining ENUMs in code).&lt;br /&gt;
** change_field_default ==&amp;gt; $dbman-&amp;gt;change_field_default&lt;br /&gt;
** add_key ==&amp;gt; $dbman-&amp;gt;add_key&lt;br /&gt;
** drop_key ==&amp;gt; $dbman-&amp;gt;drop_key&lt;br /&gt;
** add_index ==&amp;gt; $dbman-&amp;gt;add_index&lt;br /&gt;
** drop_index ==&amp;gt; $dbman-&amp;gt;drop_index&lt;br /&gt;
* Finally, and not less important, your code (module, block... plugin) must guarantee that it can be upgraded &#039;&#039;&#039;ONLY&#039;&#039;&#039; from Moodle 1.9, so any previous upgrade code can be safely deleted. &#039;&#039;&#039;Moodle 2.0 requires Moodle 1.9&#039;&#039;&#039; to be upgraded, so everybody will run the 1.9 =&amp;gt; 2.0 upgrade (with other paths like 1.8 =&amp;gt; 2.0 not being possible). One good time to clean-up a bit your upgrade code ;-). Don&#039;t forget to take a look to the [[XMLDB editor|XMLDB Editor]] and to core modules to see how [http://cvs.moodle.org/moodle/lib/db/upgrade.php?view=markup upgrade.php] files look like in Moodle 2.0.&lt;br /&gt;
&lt;br /&gt;
== DML changes ==&lt;br /&gt;
&lt;br /&gt;
=== Some comments ===&lt;br /&gt;
* The ENTIRE CODEBASE requires an update of ALL database query function calls. Expect most moodle files to be affected by this change.&lt;br /&gt;
&lt;br /&gt;
* This is the more complex part to migrate to have the code working under Moodle 2.0, not because of the complexity of the changes themselves (90% of them will be really easy), but because you&#039;ll need to triple-check everything works as expected after changes.&lt;br /&gt;
&lt;br /&gt;
* Along the changes below, you&#039;ll find links to some examples that will try to make things easier. Anyway, if you are blocked at any point, please ask in forums or tracker (see links at the beginning of the page). Sure it has a good enough solution.&lt;br /&gt;
&lt;br /&gt;
* Once more it&#039;s highly recommended to take a look to Moodle core code, searching for similar examples. Of course, new meaningful examples are welcome, and also any clarification in the list of changes below. Feel free to do it, this is a wiki!&lt;br /&gt;
&lt;br /&gt;
* Finally, one more explanation: The changes below have been split into three sections. First one, (called &#039;&#039;&#039;&amp;quot;The golden changes&amp;quot;&#039;&#039;&#039;) are modifications that must be applied to ALL the transformations defined in the second section (&#039;&#039;&#039;&amp;quot;The iron changes&amp;quot;&#039;&#039;&#039;). Sure you&#039;ll understand that after reading them (it&#039;s basically a matter of not repeating the golden ones within each iron one, just imagine they are everywhere). Finally other changes details can be found in the &#039;&#039;&#039;&amp;quot;The tin changes&amp;quot;&#039;&#039;&#039; section.&lt;br /&gt;
&lt;br /&gt;
=== The golden changes ===&lt;br /&gt;
&#039;&#039;PLEASE read the API before going crazy with search &amp;amp; replace&#039;&#039;! You can find all the new methods in lib/dml/moodle_database.php. This is essential because some method signatures have changed (params are different), and some method names have even changed (execute_sql() is now execute()).&lt;br /&gt;
&lt;br /&gt;
Each of the golden changes below is given one short name (G1, G2, G3...) for further reference in the rest of the documentation. Let&#039;s go:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span id=&amp;quot;g1&amp;quot;&amp;gt;&amp;lt;b&amp;gt;G1&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;: Wherever old functions are used (get_record*, get_field*, set_field, insert_record, update_record, count_records*, delete_records, record_exists), the global $DB must be used as the object on which these functions are called (e.g. get_record_select() becomes $DB-&amp;gt;get_record_select()).&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
// Old syntax&lt;br /&gt;
$sql = &amp;quot;WHERE id = 1&amp;quot;;&lt;br /&gt;
get_record_select($sql);&lt;br /&gt;
  &lt;br /&gt;
// New syntax&lt;br /&gt;
global $DB;&lt;br /&gt;
$sql = &amp;quot;WHERE id = 1&amp;quot;;&lt;br /&gt;
$DB-&amp;gt;get_record_select($sql);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
::Note: for some functions, the $params array is not the second function parameter. For example, set_field:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Old syntax&lt;br /&gt;
set_field(&#039;user&#039;, &#039;firstname&#039;, &#039;Peter&#039;, &#039;id&#039;, 1);&lt;br /&gt;
  &lt;br /&gt;
// New syntax&lt;br /&gt;
global $DB;&lt;br /&gt;
$DB-&amp;gt;set_field(&#039;user&#039;, &#039;firstname&#039;, &#039;Peter&#039;, array(&#039;id&#039; =&amp;gt; 1));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span id=&amp;quot;g2&amp;quot;&amp;gt;&amp;lt;b&amp;gt;G2&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;: All uses of addslashes() &#039;&#039;&#039;must be removed&#039;&#039;&#039;. They are no longer needed&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span id=&amp;quot;g3&amp;quot;&amp;gt;&amp;lt;b&amp;gt;G3&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;: All the functions that used to accept a list of string params in the form &amp;quot;param1, value1, param2, value2&amp;quot; now need to be given an array of key=&amp;gt;value pairs as a replacement for these params. Other params remain as before. Check the new API for any exceptions.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
// Old syntax:&lt;br /&gt;
$user = get_record(&amp;quot;user&amp;quot;, &amp;quot;firstname&amp;quot;, &amp;quot;Peter&amp;quot;, &amp;quot;lastname&amp;quot;, &amp;quot;Cantrophus&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// New syntax:&lt;br /&gt;
global $DB;&lt;br /&gt;
$conditions = array(&amp;quot;firstname&amp;quot; =&amp;gt; &amp;quot;Peter&amp;quot;, &amp;quot;lastname&amp;quot; =&amp;gt; &amp;quot;Cantrophus&amp;quot;);&lt;br /&gt;
$user = $DB-&amp;gt;get_record(&amp;quot;user&amp;quot;, $conditions);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
::Note: The example above has been written out in full for clarity. You can use the array() directly within the function call, without using a temporary variable, if you prefer:&#039;&#039;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
global $DB;&lt;br /&gt;
$user = $DB-&amp;gt;get_record(&amp;quot;user&amp;quot;, array(&amp;quot;firstname&amp;quot; =&amp;gt; &amp;quot;Peter&amp;quot;, &amp;quot;lastname&amp;quot; =&amp;gt; &amp;quot;Cantrophus&amp;quot;) );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span id=&amp;quot;g4&amp;quot;&amp;gt;&amp;lt;b&amp;gt;G4&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;: rs_fetch_next_record($rs) is deprecated, in favour of the simple foreach($rs as $var). Calls to rs_close() must be replaced by $rs-&amp;gt;close();&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
// Old syntax&lt;br /&gt;
while($result = rs_fetch_next_record($rs)) {&lt;br /&gt;
    ...&lt;br /&gt;
}&lt;br /&gt;
rs_close();&lt;br /&gt;
&lt;br /&gt;
// New syntax&lt;br /&gt;
foreach ($rs as $result) {&lt;br /&gt;
    ...&lt;br /&gt;
}&lt;br /&gt;
$rs-&amp;gt;close();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span id=&amp;quot;g5&amp;quot;&amp;gt;&amp;lt;b&amp;gt;G5&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;: Placeholders must be used for table names. Instead of {$CFG-&amp;gt;prefix}tablename, use {tablename}.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
// Old syntax&lt;br /&gt;
$sql = &amp;quot;SELECT * FROM {$CFG-&amp;gt;prefix}user&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// New syntax&lt;br /&gt;
$sql = &amp;quot;SELECT * FROM {user}&amp;quot;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span id=&amp;quot;g6&amp;quot;&amp;gt;&amp;lt;b&amp;gt;G6&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;: When PHP variables are used in SQL queries, they must be replaced by parameters. You have the choice between two approaches: ordered parameters, or named parameters.&lt;br /&gt;
** Ordered parameters use a simple array of values, which are given to the DML function as $params. The values in the SQL code are simply question marks (?) replacing the values. They are replaced by the DML code one by one, substituting each question mark (?) with the next value in the $params array.&lt;br /&gt;
** Named parameters use an associative array of name =&amp;gt; value pairs as the $params array. The values in the SQL code are replaced with a colon (:) followed by the key associated with the value, in the $params array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
// Old syntax&lt;br /&gt;
$sql = &amp;quot;SELECT id, firstname FROM {$CFG-&amp;gt;prefix}user WHERE firstname = &#039;Peter&#039; AND lastname = &#039;Cantrophus&#039;&amp;quot;;&lt;br /&gt;
$user = get_record_sql($sql);&lt;br /&gt;
  &lt;br /&gt;
// New syntax: ordered params&lt;br /&gt;
global $DB;&lt;br /&gt;
$params = array(&#039;Peter&#039;, &#039;Cantrophus&#039;);&lt;br /&gt;
$sql = &amp;quot;SELECT id, firstname FROM {user} WHERE firstname = ? AND lastname = ?&amp;quot;;&lt;br /&gt;
$user = $DB-&amp;gt;get_record_sql($sql, $params);&lt;br /&gt;
&lt;br /&gt;
// New syntax: named params&lt;br /&gt;
global $DB;&lt;br /&gt;
$params = array(&#039;firstname&#039; =&amp;gt; &#039;Peter&#039;, &#039;lastname&#039; =&amp;gt; &#039;Cantrophus&#039;);&lt;br /&gt;
$sql = &amp;quot;SELECT id, firstname FROM {user} WHERE firstname = :firstname AND lastname = :lastname&amp;quot;;&lt;br /&gt;
$user = $DB-&amp;gt;get_record_sql($sql, $params);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span id=&amp;quot;g7&amp;quot;&amp;gt;&amp;lt;b&amp;gt;G7&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;: Replacement of the IN(...) syntax: We no longer hard-code this in our SQL queries, we use a function which determines whether the IN() syntax is needed, or, if there is only one value to compare, the equal (=) sign can be used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
// Old syntax:&lt;br /&gt;
$depends_on = array(1, 43, 553);&lt;br /&gt;
$gis = implode(&#039;,&#039;, $depends_on);&lt;br /&gt;
$sql = &amp;quot;SELECT *&lt;br /&gt;
          FROM {$CFG-&amp;gt;prefix}grade_items&lt;br /&gt;
         WHERE id IN ($gis)&amp;quot;;&lt;br /&gt;
$items = $DB-&amp;gt;get_records_sql($sql);&lt;br /&gt;
  &lt;br /&gt;
// new syntax&lt;br /&gt;
global $DB;&lt;br /&gt;
$depends_on = array(1, 43, 553);&lt;br /&gt;
list($usql, $params) = $DB-&amp;gt;get_in_or_equal($depends_on);&lt;br /&gt;
$sql = &amp;quot;SELECT *&lt;br /&gt;
          FROM {grade_items}&lt;br /&gt;
         WHERE id $usql&amp;quot;;&lt;br /&gt;
$items = $DB-&amp;gt;get_records_sql($sql, $params);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; to combine the last two, do the G7 IN SQL stuff first to generate the params array, then do something like&lt;br /&gt;
  $param[&#039;firstname&#039;] = &#039;peter&#039;;&lt;br /&gt;
to add the stuff for G6&lt;br /&gt;
&lt;br /&gt;
=== The iron changes ===&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;span id=&amp;quot;I1&amp;quot;&amp;gt;&amp;lt;b&amp;gt;I1&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;: Originally the &#039;&#039;&#039;sql_substr()&#039;&#039;&#039; function was used without parameters and it returned only the name of the &amp;quot;substring&amp;quot; function to be used under each DB. In Moodle 2.0 and upwards, it has 3 parameters (2 being mandatory) and it returns the complete SQL text to be used when handling substrings. Note that positions in this function are 1-based (first char has index 1).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
// Old syntax&lt;br /&gt;
$records = get_records_sql(&amp;quot;SELECT &amp;quot; . sql_substr() . &amp;quot;(firstname, 1, 20)&amp;quot; . &amp;quot; FROM ... ...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// New syntax&lt;br /&gt;
$records = $DB-&amp;gt;get_records_sql(&amp;quot;SELECT &amp;quot; . $DB-&amp;gt;sql_substr(&#039;firstname&#039;, 1, 20) . &amp;quot; FROM ... ...&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The tin changes ===&lt;br /&gt;
List of minor changes&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span id=&amp;quot;g1&amp;quot;&amp;gt;&amp;lt;b&amp;gt;T1&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;: Originally get_records() and similar functions were returning false if no records found. All these methods are now always returning arrays, empty array in case of no records found. Please note that get_record() still returns false if specified record not found.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
// Old syntax&lt;br /&gt;
if (!$posts = get_records(&#039;forum_posts&#039;, &#039;parent&#039;, 666)) {&lt;br /&gt;
    $posts = array()&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// New syntax&lt;br /&gt;
global $DB;&lt;br /&gt;
$posts = $DB-&amp;gt;get_records(&#039;forum_posts&#039;, array(&#039;parent&#039;=&amp;gt;666));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;span id=&amp;quot;g1&amp;quot;&amp;gt;&amp;lt;b&amp;gt;T2&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;: Originally DML functions were returning &#039;&#039;false&#039;&#039; if error occurred - &#039;&#039;dml_exception&#039;&#039; is thrown now instead.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
// Old syntax&lt;br /&gt;
$record = new object();&lt;br /&gt;
$record-&amp;gt;course = 5;&lt;br /&gt;
if (!$id = insert_record(&#039;sometable&#039;, $record)) {&lt;br /&gt;
   error(&#039;can not insert new record&#039;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// New syntax&lt;br /&gt;
global $DB;&lt;br /&gt;
$record = new object();&lt;br /&gt;
$record-&amp;gt;course = 5;&lt;br /&gt;
$id = $DB-&amp;gt;insert_record(&#039;sometable&#039;, $record);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[XMLDB Documentation|XMLDB Documentation]]: where both xmldb and ddl stuff is explained.&lt;br /&gt;
* [[DDL functions|DDL functions]] - Documentation for all the Data Definition Language (DDL) functions available inside Moodle.&lt;br /&gt;
* [[DML functions|DML functions]] - Documentation for all the Data Manipulation Language (DML) functions available inside Moodle.&lt;br /&gt;
* [[DDL exceptions|DDL exceptions]] - DDL exceptions information.&lt;br /&gt;
* [[DML exceptions|DML exceptions]] - DML exceptions information.&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=SSH_key&amp;diff=8424</id>
		<title>SSH key</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=SSH_key&amp;diff=8424"/>
		<updated>2010-04-25T21:13:24Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* Mac OS X */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==What is a SSH key?==&lt;br /&gt;
&lt;br /&gt;
SSH keys are used for secure connections across a network.  They come in pairs, so you have a public key and a private key.&lt;br /&gt;
&lt;br /&gt;
The standard ssh2 file format (see&lt;br /&gt;
http://www.openssh.org/txt/draft-ietf-secsh-publickeyfile-02.txt)&lt;br /&gt;
looks like this:&lt;br /&gt;
&lt;br /&gt;
 ---- BEGIN SSH2 PUBLIC KEY ----&lt;br /&gt;
 Comment: &amp;quot;jtbell@Jon-Bells-Computer&amp;quot;&lt;br /&gt;
 AAAAB3NzaC1kc3MAAACBAPNgmidbM2rhYjUXunpnlXjHWfV+vc8/5YKrn8Y5P0Y6KwmG2G&lt;br /&gt;
 GMgNBon3LX3iJlBhtuU3FCBj3G1Kdt5vUhQHhUmHVrOasi47vawTrv7ZJCfiaSGwRsiBHt&lt;br /&gt;
 Jta5CAp7t0EnzX2q6BvPbFBBHNLyy6uNVpL2jOR06Pkx/vaqyScvAAAAFQDHvwmjWYwK9g&lt;br /&gt;
 K6Sp+pSvI7bwEUtwAAAIANMJDotMpfj89N+7+FJylSS+uFEQSS61PxENl/Mcj1jUREjJg2&lt;br /&gt;
 eNsJdAB9Ev99hWYS+7lFRtTJ2eh4Y9gpGe7BX3e2YGHOqp8cWCVCIKaMzwk9To+xnfThWq&lt;br /&gt;
 IfHT8I6CJxp/5ez02m6F2k/5iukvOwbGms6EAZK1DTBhDOHjEQwQAAAIAlz2/qBWkaMP+s&lt;br /&gt;
 W8FLmGKM+cCw5+asOaJGTwrFVuwJkDMvdEWxmG92A2dxuUske0d/AkN6zJp7HD0wlfesRM&lt;br /&gt;
 3+c+Res5qun9lFcdM4i03VoV5mXd+T7laS8yku6vZgvZZFnPvr2LOUnc7XThGFwMaQpFEW&lt;br /&gt;
 U8cvQbttO6QrT2CD2w==&lt;br /&gt;
 ---- END SSH2 PUBLIC KEY ----&lt;br /&gt;
&lt;br /&gt;
However, Moodle uses OpenSSH on its server and this key will not work with the OpenSSH server in this format; OpenSSH requires the key to be in OpenSSH format. Here is an example of a DSA public key in OpenSSH format (usually they are all in one line):&lt;br /&gt;
&lt;br /&gt;
 ssh-dss AAAAB3NzaC1kc3MAAACBAJ3hB5SAF6mBXPlZlRoJEZi0KSIN+NU2iGiaXZXi9CDrgVxTp6/&lt;br /&gt;
 sc56UcYCp4qjfrZ2G3+6PWbxYso4P4YyUC+61RU5KPy4EcTJske3O+aNvec/20cW7PT3TvH1+sxwGry&lt;br /&gt;
 mD50kTiXDgo5nXdqFvibgM61WW2DGTKlEUsZys0njRAAAAFQDs7ukaTGJlZdeznwFUAttTH9LrwwAAA&lt;br /&gt;
 IAMm4sLCdvvBx9WPkvWDX0OIXSteCYckiQxesOfPvz26FfYxuTG/2dljDlalC+kYG05C1NEcmZWSNES&lt;br /&gt;
 GBGfccSYSfI3Y5ahSVUhOC2LMO3JNjVyYUnOM/iyhzrnRfQoWO9GFMaugq0jBMlhZA4UO26yJqJ+BtX&lt;br /&gt;
 IyItaEEJdc/ghIwAAAIBFeCZynstlbBjP648+mDKIvzNSS+JYr5klGxS3q8A56NPcYhDMxGn7h1DKbb&lt;br /&gt;
 2AV4pO6y+6hDrWo3UT4dLVuzK01trwp PYp6JXTSZZ12ZaXNPz7sX9/z6pzMqhX4UEfjVsLcuF+ZS6a&lt;br /&gt;
 QCPO0ZZEa1z+EEIZSD/ykLQsDwPxGjPBqw== someone@somewhere.com&lt;br /&gt;
&lt;br /&gt;
In addition to OpenSSH and Standard SSH formats there are a variety of proprietary formats as well as SSH1 and SSH2 differences to account for, which can make this confusing. &lt;br /&gt;
&lt;br /&gt;
In the example above you will note that the key starts with &amp;quot;ssh-dss&amp;quot;. This is because this key was generated using DSA as opposed to RSA. A number of vendors in the SSH arena have argued, as per the PuTTY documentation that can be found at http://the.earth.li/~sgtatham/putty/0.55/htmldoc/Chapter8.html#S8.2.10 that users should employ RSA encryption because&lt;br /&gt;
&lt;br /&gt;
 DSA has an intrinsic weakness which makes it very easy to create a signature&lt;br /&gt;
 which contains enough information to give away the private key! This would &lt;br /&gt;
 allow an attacker to pretend to be you for any number of future sessions. &lt;br /&gt;
&lt;br /&gt;
An SSH2 public key in OpenSSH format will start with &amp;quot;ssh-rsa&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The idea behind all of this is that once you have keys on the remote server and your local host,  access will be simpler since the server will only grant access to someone who has the matching private key.&lt;br /&gt;
&lt;br /&gt;
==Why do I need a SSH key?==&lt;br /&gt;
&lt;br /&gt;
Our CVS server uses OpenSSH, so if you are a Moodle developer and you want to make your logins easier (by avoiding typing in your password all the time) then you will need to submit public key in Openssh format via the &amp;quot;Update my developer information&amp;quot; tab at http://moodle.org/cvs.&lt;br /&gt;
&lt;br /&gt;
==How do I create a SSH key pair?==&lt;br /&gt;
&lt;br /&gt;
===Platform Independent===&lt;br /&gt;
&lt;br /&gt;
Visit http://www.sshkeygen.com and simply follow the directions there.&lt;br /&gt;
&lt;br /&gt;
===Eclipse===&lt;br /&gt;
&lt;br /&gt;
If you plan to use Eclipse for development, please refer to the Eclipse document https://docs.moodle.org/en/Eclipse as Eclipse now has a plugin that allows you to manage all ssh key matters from within Eclipse.&lt;br /&gt;
&lt;br /&gt;
===Unix/Linux===&lt;br /&gt;
&lt;br /&gt;
You can use ssh-keygen at your system prompt.  Please consult the man page on your system for the options available to you.&lt;br /&gt;
&lt;br /&gt;
# Run:  &#039;&#039;&#039;ssh-keygen -t (rsa or dsa)&#039;&#039;&#039;. This will not include a passphrase. *&lt;br /&gt;
# Use of rsa or dsa above will result in rsa or dsa replacing each XXX below.&lt;br /&gt;
# Look in your ~/.ssh directory (or wherever you saved the output).  You&#039;ll find &#039;&#039;&#039;id_XXX&#039;&#039;&#039; (private) and &#039;&#039;&#039;id_XXX.pub&#039;&#039;&#039; (public).&lt;br /&gt;
# Cut and paste the contents of &#039;&#039;&#039;id_XXX.pub&#039;&#039;&#039; into your developer profile on http://moodle.org/cvs&lt;br /&gt;
# Put the private key wherever you will be calling CVS from (in your .ssh directory, for example).  Make sure it&#039;s secure!&lt;br /&gt;
&lt;br /&gt;
* This section initially recommended using &#039;&#039;ssh-keygen -d&#039;&#039; but it is unclear what the source of this -d option might be.&lt;br /&gt;
&lt;br /&gt;
===Windows===&lt;br /&gt;
Use puttygen and follow the instructions [http://the.earth.li/~sgtatham/putty/0.58/htmldoc/Chapter8.html here]. Make sure you choose the RSA2 key format and that when you copy the key data into the textbox on the site, that you have all of the characters on one line. If you have opened the key with word pad, it will have line breaks in it which will stop it from working.&lt;br /&gt;
&lt;br /&gt;
The box should look like this:&lt;br /&gt;
&lt;br /&gt;
 ssh-rsa&lt;br /&gt;
 AAAAWfg&amp;amp;jkf4D34H5@4svf..... (single very long line continues beyond edge of textbox)&lt;br /&gt;
&lt;br /&gt;
===Mac OS X===&lt;br /&gt;
If you have an existing key in Putty format, open it in puttygen on windows and then choose conversions and export as openssh format. You can then import the key into OS X using&lt;br /&gt;
  ssh-add -K filename&lt;br /&gt;
The -K flag is optional and stores your passphrase in the keychain [http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man1/ssh-add.1.html ssh-add documentation]&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=SSH_key&amp;diff=8423</id>
		<title>SSH key</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=SSH_key&amp;diff=8423"/>
		<updated>2010-04-25T21:10:48Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* Mac OS X */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==What is a SSH key?==&lt;br /&gt;
&lt;br /&gt;
SSH keys are used for secure connections across a network.  They come in pairs, so you have a public key and a private key.&lt;br /&gt;
&lt;br /&gt;
The standard ssh2 file format (see&lt;br /&gt;
http://www.openssh.org/txt/draft-ietf-secsh-publickeyfile-02.txt)&lt;br /&gt;
looks like this:&lt;br /&gt;
&lt;br /&gt;
 ---- BEGIN SSH2 PUBLIC KEY ----&lt;br /&gt;
 Comment: &amp;quot;jtbell@Jon-Bells-Computer&amp;quot;&lt;br /&gt;
 AAAAB3NzaC1kc3MAAACBAPNgmidbM2rhYjUXunpnlXjHWfV+vc8/5YKrn8Y5P0Y6KwmG2G&lt;br /&gt;
 GMgNBon3LX3iJlBhtuU3FCBj3G1Kdt5vUhQHhUmHVrOasi47vawTrv7ZJCfiaSGwRsiBHt&lt;br /&gt;
 Jta5CAp7t0EnzX2q6BvPbFBBHNLyy6uNVpL2jOR06Pkx/vaqyScvAAAAFQDHvwmjWYwK9g&lt;br /&gt;
 K6Sp+pSvI7bwEUtwAAAIANMJDotMpfj89N+7+FJylSS+uFEQSS61PxENl/Mcj1jUREjJg2&lt;br /&gt;
 eNsJdAB9Ev99hWYS+7lFRtTJ2eh4Y9gpGe7BX3e2YGHOqp8cWCVCIKaMzwk9To+xnfThWq&lt;br /&gt;
 IfHT8I6CJxp/5ez02m6F2k/5iukvOwbGms6EAZK1DTBhDOHjEQwQAAAIAlz2/qBWkaMP+s&lt;br /&gt;
 W8FLmGKM+cCw5+asOaJGTwrFVuwJkDMvdEWxmG92A2dxuUske0d/AkN6zJp7HD0wlfesRM&lt;br /&gt;
 3+c+Res5qun9lFcdM4i03VoV5mXd+T7laS8yku6vZgvZZFnPvr2LOUnc7XThGFwMaQpFEW&lt;br /&gt;
 U8cvQbttO6QrT2CD2w==&lt;br /&gt;
 ---- END SSH2 PUBLIC KEY ----&lt;br /&gt;
&lt;br /&gt;
However, Moodle uses OpenSSH on its server and this key will not work with the OpenSSH server in this format; OpenSSH requires the key to be in OpenSSH format. Here is an example of a DSA public key in OpenSSH format (usually they are all in one line):&lt;br /&gt;
&lt;br /&gt;
 ssh-dss AAAAB3NzaC1kc3MAAACBAJ3hB5SAF6mBXPlZlRoJEZi0KSIN+NU2iGiaXZXi9CDrgVxTp6/&lt;br /&gt;
 sc56UcYCp4qjfrZ2G3+6PWbxYso4P4YyUC+61RU5KPy4EcTJske3O+aNvec/20cW7PT3TvH1+sxwGry&lt;br /&gt;
 mD50kTiXDgo5nXdqFvibgM61WW2DGTKlEUsZys0njRAAAAFQDs7ukaTGJlZdeznwFUAttTH9LrwwAAA&lt;br /&gt;
 IAMm4sLCdvvBx9WPkvWDX0OIXSteCYckiQxesOfPvz26FfYxuTG/2dljDlalC+kYG05C1NEcmZWSNES&lt;br /&gt;
 GBGfccSYSfI3Y5ahSVUhOC2LMO3JNjVyYUnOM/iyhzrnRfQoWO9GFMaugq0jBMlhZA4UO26yJqJ+BtX&lt;br /&gt;
 IyItaEEJdc/ghIwAAAIBFeCZynstlbBjP648+mDKIvzNSS+JYr5klGxS3q8A56NPcYhDMxGn7h1DKbb&lt;br /&gt;
 2AV4pO6y+6hDrWo3UT4dLVuzK01trwp PYp6JXTSZZ12ZaXNPz7sX9/z6pzMqhX4UEfjVsLcuF+ZS6a&lt;br /&gt;
 QCPO0ZZEa1z+EEIZSD/ykLQsDwPxGjPBqw== someone@somewhere.com&lt;br /&gt;
&lt;br /&gt;
In addition to OpenSSH and Standard SSH formats there are a variety of proprietary formats as well as SSH1 and SSH2 differences to account for, which can make this confusing. &lt;br /&gt;
&lt;br /&gt;
In the example above you will note that the key starts with &amp;quot;ssh-dss&amp;quot;. This is because this key was generated using DSA as opposed to RSA. A number of vendors in the SSH arena have argued, as per the PuTTY documentation that can be found at http://the.earth.li/~sgtatham/putty/0.55/htmldoc/Chapter8.html#S8.2.10 that users should employ RSA encryption because&lt;br /&gt;
&lt;br /&gt;
 DSA has an intrinsic weakness which makes it very easy to create a signature&lt;br /&gt;
 which contains enough information to give away the private key! This would &lt;br /&gt;
 allow an attacker to pretend to be you for any number of future sessions. &lt;br /&gt;
&lt;br /&gt;
An SSH2 public key in OpenSSH format will start with &amp;quot;ssh-rsa&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The idea behind all of this is that once you have keys on the remote server and your local host,  access will be simpler since the server will only grant access to someone who has the matching private key.&lt;br /&gt;
&lt;br /&gt;
==Why do I need a SSH key?==&lt;br /&gt;
&lt;br /&gt;
Our CVS server uses OpenSSH, so if you are a Moodle developer and you want to make your logins easier (by avoiding typing in your password all the time) then you will need to submit public key in Openssh format via the &amp;quot;Update my developer information&amp;quot; tab at http://moodle.org/cvs.&lt;br /&gt;
&lt;br /&gt;
==How do I create a SSH key pair?==&lt;br /&gt;
&lt;br /&gt;
===Platform Independent===&lt;br /&gt;
&lt;br /&gt;
Visit http://www.sshkeygen.com and simply follow the directions there.&lt;br /&gt;
&lt;br /&gt;
===Eclipse===&lt;br /&gt;
&lt;br /&gt;
If you plan to use Eclipse for development, please refer to the Eclipse document https://docs.moodle.org/en/Eclipse as Eclipse now has a plugin that allows you to manage all ssh key matters from within Eclipse.&lt;br /&gt;
&lt;br /&gt;
===Unix/Linux===&lt;br /&gt;
&lt;br /&gt;
You can use ssh-keygen at your system prompt.  Please consult the man page on your system for the options available to you.&lt;br /&gt;
&lt;br /&gt;
# Run:  &#039;&#039;&#039;ssh-keygen -t (rsa or dsa)&#039;&#039;&#039;. This will not include a passphrase. *&lt;br /&gt;
# Use of rsa or dsa above will result in rsa or dsa replacing each XXX below.&lt;br /&gt;
# Look in your ~/.ssh directory (or wherever you saved the output).  You&#039;ll find &#039;&#039;&#039;id_XXX&#039;&#039;&#039; (private) and &#039;&#039;&#039;id_XXX.pub&#039;&#039;&#039; (public).&lt;br /&gt;
# Cut and paste the contents of &#039;&#039;&#039;id_XXX.pub&#039;&#039;&#039; into your developer profile on http://moodle.org/cvs&lt;br /&gt;
# Put the private key wherever you will be calling CVS from (in your .ssh directory, for example).  Make sure it&#039;s secure!&lt;br /&gt;
&lt;br /&gt;
* This section initially recommended using &#039;&#039;ssh-keygen -d&#039;&#039; but it is unclear what the source of this -d option might be.&lt;br /&gt;
&lt;br /&gt;
===Windows===&lt;br /&gt;
Use puttygen and follow the instructions [http://the.earth.li/~sgtatham/putty/0.58/htmldoc/Chapter8.html here]. Make sure you choose the RSA2 key format and that when you copy the key data into the textbox on the site, that you have all of the characters on one line. If you have opened the key with word pad, it will have line breaks in it which will stop it from working.&lt;br /&gt;
&lt;br /&gt;
The box should look like this:&lt;br /&gt;
&lt;br /&gt;
 ssh-rsa&lt;br /&gt;
 AAAAWfg&amp;amp;jkf4D34H5@4svf..... (single very long line continues beyond edge of textbox)&lt;br /&gt;
&lt;br /&gt;
===Mac OS X===&lt;br /&gt;
If you have an existing key in Putty format, open it in puttygen on windows and then choose conversions and export as openssh format. You can then import the key into OS X using&lt;br /&gt;
  ssh_add -K filename&lt;br /&gt;
The -K flag is optional and stores your passphrase in the keychain.&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Talk:Gradebook_improvements&amp;diff=27848</id>
		<title>Talk:Gradebook improvements</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Talk:Gradebook_improvements&amp;diff=27848"/>
		<updated>2010-03-12T21:27:24Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* Common frustrations */ Gradebook lateness&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Aggregation of hidden grades==&lt;br /&gt;
&lt;br /&gt;
Overlook problem partially solve after the database freeze - workaround was to recalculate the grades on the fly so that users that can the hidden grades are ignored. This approach is expensive and can not be used in conditional activities, grade exports, etc.&lt;br /&gt;
&lt;br /&gt;
Solution is to add new flag into grade categories - aggregate hidden grades. Having two values for each grade would be too complex, selective agrragation should solve most of the problems and should be reasonably backwards compatible.&lt;br /&gt;
&lt;br /&gt;
--[[User:Petr Škoda (škoďák)|Petr Škoda (škoďák)]] 11:56, 8 December 2008&lt;br /&gt;
&lt;br /&gt;
==Exports: more flexibility==&lt;br /&gt;
&lt;br /&gt;
Two aspects of the 1.9 export plugin have been criticised by some of Catalyst&#039;s clients:&lt;br /&gt;
&lt;br /&gt;
* the fact that grade exports are tied to a course&lt;br /&gt;
* the default user profile columns are not all needed and some custom ones would be necessary &lt;br /&gt;
&lt;br /&gt;
Therefore I propose the following changes:&lt;br /&gt;
&lt;br /&gt;
* removing the export plugin dependency on a single course by converting to an array of courses (see MDL-17420)&lt;br /&gt;
* making the user-related columns customisable (see MDL-17346)&lt;br /&gt;
&lt;br /&gt;
--[[User:Francois Marier|Francois Marier]] 06:42, 9 December 2008&lt;br /&gt;
&lt;br /&gt;
==Gradebook does not consider groupings functionality==&lt;br /&gt;
&lt;br /&gt;
Student in gradebook view all grade items, but must view only grade items thats belong to his groiping (see MDL-13868).&lt;br /&gt;
&lt;br /&gt;
--[[User:Artem Andreev|Artem Andreev]] 11:07, 9 December 2008&lt;br /&gt;
&lt;br /&gt;
==Common frustrations==&lt;br /&gt;
Below are some of the most often reported usability issues in the 1.9 gradebook, which we are trying to address. Several of these are grouped as sub-tasks under MDL-16913.&lt;br /&gt;
&lt;br /&gt;
===Assigning weights to categories and grade items===&lt;br /&gt;
This is the most common frustration. Weights are used extensively in many institutions, and were used in 1.8. However, they are difficult to understand in 1.9, and difficult to set up. This issue is discussed extensively in MDL-15680.&lt;br /&gt;
&lt;br /&gt;
===Moving items to categories===&lt;br /&gt;
Currently, the [[Edit categories and items]] page lets you move only one grade item or category at a time. It takes two page refreshes and two mouse clicks per move. This is very tedious and time-consuming when many items have to be moved around. MDL-13775 and MDL-12502 address this problem.&lt;br /&gt;
&lt;br /&gt;
===Removing the &#039;&#039;overridden&#039;&#039; attribute of individual grades===&lt;br /&gt;
When grades are imported into an existing gradebook, or when grades are manually edited in the grader report, these grades become [[Grade_editing#Overridden|overridden]], which prevents linked activity modules from updating this grade. Removing this attribute is very time-consuming, since one must enter the edit page of each individual grade, untick the checkbox and submit the form. This issue is discussed in [http://moodle.org/mod/forum/discuss.php?d=109636 this forum thread].&lt;br /&gt;
&lt;br /&gt;
===Viewing the overall contribution of each category and item to the course aggregation===&lt;br /&gt;
The tracker issue MDL-13777 reports the difficulty in seeing the contribution of each grade item and category to the course total. Calculations and weights may apply, which are not visible in any of the current reports except in each individual category or item&#039;s edit page.&lt;br /&gt;
&lt;br /&gt;
--[[User:Nicolas Connault|Nicolas Connault]] 12:41, 4 November 2008&lt;br /&gt;
&lt;br /&gt;
Some more that it would be great to see fixed:&lt;br /&gt;
===Setting grade to pass===&lt;br /&gt;
Takes a lot of clicks and the edit icon looks like it&#039;s part of the main mass of editing icons for the grades table itself, so it&#039;s hard to find. This is a very useful feature (at least once MDL-13830 is fixed) as it shows at a glance how many items a student has failed to pass. Seeing a row of red entries is a great way of quickly knowing who to target for extra attention in class. Quite obscure at the moment though, especially seeing as it cannot be done from the module itself. -[[User:Matt Gibson|Matt Gibson]] 07:36, 22 January 2009 (CST)&lt;br /&gt;
&lt;br /&gt;
===Its not possible to see whether or not a student has submitted work which has not been marked===&lt;br /&gt;
If the modules could send a special grade e.g. -1 to the gradebook as a placeholder that could be used to add either a css class to a cell, or display a special character to show that work is waiting. Then it would be possible to use the gradebook like a normal one, in order to evaluate students&#039; deadline-meeting for writing reports. At the moment, this is probably the biggest problem in our institution&#039;s use of the gradebook. - [[User:Matt Gibson|Matt Gibson]] 07:36, 22 January 2009 (CST)&lt;br /&gt;
&lt;br /&gt;
===Impossible to tell whether work was submitted on time or late===&lt;br /&gt;
This is vital for K-12 teachers who are writing reports on students and really needs to be added somehow. Gradebook database changes are needed, so it must be planned as part of a major release. MDL-12111&lt;br /&gt;
&lt;br /&gt;
==Patch for Edit Categories and Items page==&lt;br /&gt;
Following is a proposed patch to the &#039;&#039;&#039;Edit categories and items&#039;&#039;&#039; page in the 1.9 gradebook. It addresses many usability issues while remaining simple. The following features are currently implemented:&lt;br /&gt;
&lt;br /&gt;
===Simple features===&lt;br /&gt;
[[Image:gradebook_categories_simple.png|600px]]&lt;br /&gt;
*Items and categories are displayed in a table instead of a list. This improves readability and will make drag and drop easier to implement.&lt;br /&gt;
*All advanced features are hidden by default, so that the interface by default is almost identical to the original&lt;br /&gt;
*An additional column has checkboxes for grade items. All selected items can then be moved to one of the existing grade categories for the current course. Javascript &amp;quot;Select all/Select None&amp;quot; links replace these checkboxes for categories, to make it faster to select or de-select items.&lt;br /&gt;
&lt;br /&gt;
===Advanced features===&lt;br /&gt;
[[Image:gradebook_categories_advanced.png|600px]]&lt;br /&gt;
&lt;br /&gt;
*[[Category aggregation|Grade category aggregation type]]: changing this reloads the page, because the grade item weights/extra credits only apply to some of these aggregation types.&lt;br /&gt;
*Weight or extra credit: depending on the parent category&#039;s aggregation type, each category and grade item may have an input field or a checkbox for weight or extra credit. All these can be edited, then submitted with one click.&lt;br /&gt;
*Grade range is displayed for information purposes, but cannot be edited through this interface (it is most often controlled by the linked activity)&lt;br /&gt;
*[[Grade_categories#Aggregate_only_non-empty_grades|Aggregate only non-empty grades]]&lt;br /&gt;
*[[Grade_categories#Aggregate_including_sub-categories|Aggregate including sub-categories]]&lt;br /&gt;
*[[Grade_categories#Include_outcomes_in_aggregation|Include outcomes in aggregation]]&lt;br /&gt;
*[[Grade_categories#Drop_the_lowest|Drop the lowest]]&lt;br /&gt;
*[[Grade_categories#Keep_the_highest|Keep the highest]]&lt;br /&gt;
*[[Grade items|Multiplicator]]&lt;br /&gt;
*[[Grade_items|Offset]]&lt;br /&gt;
&lt;br /&gt;
All these settings can be changed then submitted with only one page reload. Just be mindful that changing a category&#039;s aggregation type will reload the page and you will lose any non-submitted changes you made to the other settings.&lt;br /&gt;
&lt;br /&gt;
--[[User:Nicolas Connault|Nicolas Connault]] 12:41, 4 November 2008&lt;br /&gt;
&lt;br /&gt;
==Further ideas for 2.0==&lt;br /&gt;
&lt;br /&gt;
The following list is from a gradebook planning meeting on 4 September 2009 between Martin, Nicolas, Petr and Helen:&lt;br /&gt;
* Replace hiding as an activity setting with automatic/manual/dated transfer of grades to gradebook&lt;br /&gt;
* Duplicate most of the grade item settings into the mod_edit form for each activity (controlled directly by gradebook)&lt;br /&gt;
* Implement grading interface centrally for wiki as a test in 2.0, not other modules yet&lt;br /&gt;
* Workflow of raw grades in activity -&amp;gt; proposed/hidden grades in gradebook -&amp;gt;  final grades released to students&lt;br /&gt;
What is the behaviour of hidden grades in calculated grades, exports, teacher view, student view, activity completion ... &lt;br /&gt;
* User overviews:&lt;br /&gt;
*# Overview of one user (have it now but need to review the capabilities, perhaps one overall is enough but really should check each course&lt;br /&gt;
*# Combine multiple gradebooks from one global group into one table of users vs courses, showing final grades for courses&lt;br /&gt;
* AJAX-based report to edit rows and columns at once, without reloads&lt;br /&gt;
* Adding more switches to turn off things (eg calculations)&lt;br /&gt;
* Improving documentation to make it clearer&lt;br /&gt;
* Gradebook tracker issues need some rationalisation, update all fix versions (perhaps move all 1.9.6 and 2.0 ones into subtasks like MDL-19131)&lt;br /&gt;
&lt;br /&gt;
--[[User:Helen Foster|Helen Foster]] 11:50, 10 September 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Tim&#039;s_Gradebook_thoughts|Tim&#039;s Gradebook thoughts]]&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Setting_up_Netbeans&amp;diff=8983</id>
		<title>Setting up Netbeans</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Setting_up_Netbeans&amp;diff=8983"/>
		<updated>2010-02-26T14:56:25Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: Added JIRA module bit&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.netbeans.org/features/php/index.html NetBeans] has got a good PHP support. You find a host of information on the website (tutorials, developer blog, screen casts, etc.).&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
* CVS integration: see all changes, lines deletion, diff in real time, show annotations, diff history...&lt;br /&gt;
* Ctrl+Click: Go to declaration&lt;br /&gt;
* Export/Import Diff Patch&lt;br /&gt;
* Easy navigation&lt;br /&gt;
* List of functions&lt;br /&gt;
* Code completion&lt;br /&gt;
* Instant rename&lt;br /&gt;
* HTML, CSS, JavaScript support&lt;br /&gt;
* MySQL manager&lt;br /&gt;
* Quick Search&lt;br /&gt;
* Very few bugs&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
* Download the latest [http://netbeans.org/community/releases/68/ 6.8 version] with PHP support, only 25 MB.&lt;br /&gt;
* Install and run it.&lt;br /&gt;
&lt;br /&gt;
== Set up for Moodle development ==&lt;br /&gt;
&lt;br /&gt;
* Checkout your Moodle project with a &#039;&#039;&#039;CVS client&#039;&#039;&#039; - see [[CVS for Administrators]] or [[CVS for developers|CVS for Developers]].&lt;br /&gt;
&lt;br /&gt;
* Open File &amp;gt; New Project &amp;gt; PHP &amp;gt; PHP Application &amp;gt; Next &lt;br /&gt;
: You&#039;re going to set the project now. &#039;&#039;Name&#039;&#039;, &#039;&#039;Location&#039;&#039; and &#039;&#039;Folder&#039;&#039; are used by NetBeans and are not related to the source code. So you can choose whatever you like, except your source folder. &#039;&#039;Sources&#039;&#039; has to be your checked out Moodle branch/head folder. The rest is clear enough. Don&#039;t forget to choose UTF-8 for &#039;&#039;Default Encoding&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
: Example:&lt;br /&gt;
&lt;br /&gt;
 Project Name:        Moodle 1.9 Stable&lt;br /&gt;
 Project Location:    C:\Users\jerome\Documents\NetBeansProjects&lt;br /&gt;
 Project Folder:      C:\Users\jerome\Documents\NetBeansProjects\Moodle 1.9 Stable&lt;br /&gt;
 Project Sources:     C:\Users\jerome\Projects\branch19_STABLE\moodle&lt;br /&gt;
 Project URL:         http://localhost/moodle19/&lt;br /&gt;
 Index File:          index.php&lt;br /&gt;
 Create:              unchecked&lt;br /&gt;
 Default Encoding:    UTF-8&lt;br /&gt;
 Set as Main Project: unchecked&lt;br /&gt;
&lt;br /&gt;
* Click on Finish.&lt;br /&gt;
&lt;br /&gt;
* Start coding!&lt;br /&gt;
&lt;br /&gt;
== CVS with NetBeans ==&lt;br /&gt;
&lt;br /&gt;
NetBeans comes with &#039;&#039;&#039;integrated CVS support&#039;&#039;&#039; which might be the easiest way to check out Moodle.&lt;br /&gt;
&lt;br /&gt;
=== Anonymous checkout ===&lt;br /&gt;
&lt;br /&gt;
# In NetBeans, select Window-&amp;gt;Versioning-&amp;gt;CVS-&amp;gt;Checkout&lt;br /&gt;
# Select Team-&amp;gt;CVS-&amp;gt;Checkout&lt;br /&gt;
# Enter into CVS Root: &#039;&#039;:pserver:anonymous@us.cvs.moodle.org:/cvsroot/moodle&#039;&#039;&lt;br /&gt;
: (Non-US-residents might use one of the other [https://docs.moodle.org/en/CVS_for_Administrators#CVS_Servers Moodle CVS servers] nearer to them.)&lt;br /&gt;
# Click &#039;&#039;Next&#039;&#039;&lt;br /&gt;
# Browse or enter into &#039;&#039;Module:&#039;&#039; moodle&lt;br /&gt;
# Browse or enter into &#039;&#039;Branch:&#039;&#039; MOODLE_19_STABLE&lt;br /&gt;
# Browse or enter into &#039;&#039;Local Folder:&#039;&#039; C:\xampp\htdocs&lt;br /&gt;
# Click &#039;&#039;Finish&#039;&#039; (and wait a few minutes for Moodle to be checked out)&lt;br /&gt;
# When you get the dialog box &amp;quot;Do you want to create an IDE project from the checked-out sources?&amp;quot;, Click &amp;quot;Create Project...&amp;quot;&lt;br /&gt;
# Select PHP Application with Existing Sources, and click Next&lt;br /&gt;
# Browse or enter into &#039;&#039;Sources Folder&#039;&#039; C:\xampp\htdocs\moodle&lt;br /&gt;
# Enter into &#039;&#039;Project Name:&#039;&#039; moodle&lt;br /&gt;
# Keep the other defaults and click next&lt;br /&gt;
# &#039;&#039;Run As:&#039;&#039; should have selected &#039;&#039;Local Web Site (running on local web server)&#039;&#039;&lt;br /&gt;
# Enter into Project URL http://localhost/moodle/&lt;br /&gt;
# Browse or enter into &#039;&#039;Index File:&#039;&#039; index.php&lt;br /&gt;
# Click &#039;&#039;Finish&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checkout for developers with write access ===&lt;br /&gt;
&lt;br /&gt;
IF you wish to use NetBeans CVS and have CVS write access, the procedure is as follows:&lt;br /&gt;
&lt;br /&gt;
# Follow the above instructions except for point 3&lt;br /&gt;
# At part 3, substitute &#039;&#039;:ext:yourusername&#039;&#039; for the part before the @ and remove the country code from after it, leaving it like this  &#039;&#039;&#039;&#039;&#039;:ext:yourusername&#039;&#039;&#039;@cvs.moodle.org/cvsroot/moodle&#039;&#039;&lt;br /&gt;
# Follow the rest of the instructions as above&lt;br /&gt;
&lt;br /&gt;
If you wish to work with a plugin, you will need to check this out separately and add it to the Moodle code project you have just made. This because for some reason, the &#039;Do you want to create a project&#039; option fails to show any of the files once you open it if you try to check out the plugin on its own (NetBeans 6.7.1 on a Mac).&lt;br /&gt;
&lt;br /&gt;
# Follow the above steps up to point 3, and again substitute &#039;&#039;:ext:yourusername&#039;&#039; and click &#039;next&#039;&lt;br /&gt;
# Click &#039;Browse...&#039; next to the &#039;Module&#039; dialogue&lt;br /&gt;
# Find the plugin you wish to work with in CONTRIB&lt;br /&gt;
# Click &#039;OK&#039;&lt;br /&gt;
# Proceed as before up to point 6, then press &#039;Close&#039; when asked if you want to create a new project.&lt;br /&gt;
# Now navigate to the folder you earlier specified in the &#039;local folder&#039; dialogue and you will find a folder marked &#039;contrib&#039;.&lt;br /&gt;
# navigate to the plugin folder, copy that folder, and then navigate to your main Moodle project folder and paste it where it belongs.&lt;br /&gt;
&lt;br /&gt;
===Adding a branch to your plugin===&lt;br /&gt;
Your plugin will likely start with just a HEAD tag and at some point, you will want to branch it so that you can have versions for different Moodles. To add a MOODLE_20_STABLE branch, for example, do the following.&lt;br /&gt;
&lt;br /&gt;
# Checkout as above, but use the MOODLE_20_STABLE branch instead of MOODLE_19_STABLE&lt;br /&gt;
# You will end up with an empty folder, which you copy into place as above.&lt;br /&gt;
# Find the folder in NetBeans, then right click and choose CVS-&amp;gt;Merge changes from branch...&lt;br /&gt;
# Choose to merge from whatever branch has all the current code, using the help link if not sure what to do.&lt;br /&gt;
&lt;br /&gt;
There is a small chance that the Merge link will not be there, in which case, you will have to copy the files into the directory by hand outside netbeans and then check them in. If you do this, make sure you don&#039;t copy over the &#039;CVS&#039; folders that will have been made when you checked out the MOODLE_19_STABLE code.&lt;br /&gt;
&lt;br /&gt;
=== A few warnings ===&lt;br /&gt;
&lt;br /&gt;
Some of these warnings could also apply to other IDEs:&lt;br /&gt;
&lt;br /&gt;
* If you want to delete a file from your computer but not from CVS, delete it from Windows Explorer/Nautilus/Finder. Otherwise your next commit could delete the file from CVS. &amp;lt;br/&amp;gt;In case you have already deleted a wrong file from NetBeans:  with Windows Explorer/Nautilus/Finder, delete all the folder content of this deleted file (including the CVS folder) and update the folder.&lt;br /&gt;
* If you rename files and that other people are working on them, NetBeans could end up to mess up your CVS folder (even though that is quite rare). Then NetBeans CVS will refuse to update your code displaying a no explicit error as &#039;&#039;&#039;Update Failed&#039;&#039;&#039;. In this case, delete the content of the damaged folder with Windows Explorer/Nautilus/Finder. Then update this folder.&lt;br /&gt;
* If you create a patch or a new PHP file with NetBeans on Microsoft Windows, please check that it&#039;s a Unix format file. You may want to use another software to create Unix format patch/php files.&lt;br /&gt;
&lt;br /&gt;
== Git with NetBeans ==&lt;br /&gt;
&lt;br /&gt;
=== NBGit | Git Support for NetBeans ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;NBGit is a module for the NetBeans IDE that adds support for working with the Git version control system. It uses the JGit library created as part of EGit to interact with Git repositories. Because the module is Java code all the way, it should work better cross-platform modulo platform specific differences, such as file system behavior. It is based on the NetBeans Mercurial module.&amp;quot; &lt;br /&gt;
(http://nbgit.org)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
Unfortunately, the key word in that quote is &#039;&#039;&#039;should&#039;&#039;&#039;. In reality, because JGit is a rewrite from scratch of the tried-and-tested git core C code, it is still buggy, incomplete and unreliable. Therefore, the NetBeans and Eclipse git plugins are still only beta quality, and pretty sucky. Well, they mostly work for browsing the contents of the repository, but there is a small chance that if you use them for update operations, they will corrupt your repository. Hence, I am still doing git from the command-line.--[[User:Tim Hunt|Tim Hunt]] 11:11, 19 January 2010 (UTC)&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Optimization ==&lt;br /&gt;
&lt;br /&gt;
1. You may want to run NetBeans with the Sun JDK. NetBeans seems to work a bit better with the [http://java.sun.com/javase/downloads/index.jsp Sun JDK]. You&#039;ll have to edit NetBeans config file. Open netbeans/etc/netbeans.conf. Then uncomment and edit: &lt;br /&gt;
&lt;br /&gt;
 netbeans_jdkhome=&amp;quot;your_JDK_path&amp;quot;&lt;br /&gt;
&lt;br /&gt;
2. To change the NetBeans look and feel run netbeans in the command line with this parameter:&lt;br /&gt;
 &amp;quot;netbeans&amp;quot;  --laf javax.swing.plaf.metal.MetalLookAndFeel &lt;br /&gt;
&lt;br /&gt;
3. If NetBeans starts to slow down, give it more memory&lt;br /&gt;
 &amp;quot;netbeans&amp;quot; -J-Xmx600m&lt;br /&gt;
See FAQ for more [http://wiki.netbeans.org/FaqSettingHeapSize details on memory optimisation].&lt;br /&gt;
&lt;br /&gt;
== Coding faster ==&lt;br /&gt;
&lt;br /&gt;
=== Keyboard shortcuts ===&lt;br /&gt;
(Note: Some shortcuts might not work for PHP development.)&lt;br /&gt;
* [http://www.phpmag.ru/2009/01/23/extremely-usefull-netbeans-shortcuts/ Extremely Useful NetBeans Shortcuts] &lt;br /&gt;
* [http://netbeanside61.blogspot.com/2008/04/top-10-netbeans-ide-keyboard-shortcuts.html Top 10 NetBeans IDE Keyboard Shortcuts I use the most]&lt;br /&gt;
* [http://wiki.netbeans.org/KeymapProfileFor60 NetBeans IDE 6.x Keyboard Shortcuts Specification]&lt;br /&gt;
&lt;br /&gt;
=== PHPUnit support ===&lt;br /&gt;
See [http://blogs.sun.com/netbeansphp/entry/recent_improvements_in_phpunit_support &amp;quot;Recent improvements in PHPUnit-support&amp;quot;] on how to use PHPUnit with NetBeans.&lt;br /&gt;
&lt;br /&gt;
===JIRA support===&lt;br /&gt;
You can install the optional JIRA module in order to be able to interact with the Moodle Tracker from within netbeans. This has the advantage of avoiding constantly switching back and forth from the browser and works quite well. Go to Tools-&amp;gt;plugins-&amp;gt;available plugins and search for JIRA. Once installed, right click &#039;issue trackers&#039; in the &#039;services&#039; pane to make a new tracker instance, then enter your details.&lt;br /&gt;
&lt;br /&gt;
== See also: ==&lt;br /&gt;
Moodle forums &lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=112972 NetBeans 6.5 for moodle/PHP/debugging is a better experience v.s Eclipse]&lt;br /&gt;
&lt;br /&gt;
Online resources&lt;br /&gt;
* [http://www.netbeans.org/kb/trails/php.html NetBeans PHP Learning Trail]&lt;br /&gt;
* [http://wiki.netbeans.org/PHP NetBeans PHP Wiki]&lt;br /&gt;
* Sun&#039;s [http://blogs.sun.com/netbeansphp/ NetBeans PHP Team Blog]&lt;br /&gt;
&lt;br /&gt;
Book&lt;br /&gt;
* [http://www.packtpub.com/netbeans-platform-6-8-developers-guide/book NetBeans Platform 6.8 Developer&#039;s Guide] by Jürgen Petri (March 2010), focus on Java and Swing &lt;br /&gt;
&lt;br /&gt;
[[Category:NetBeans]]&lt;br /&gt;
[[Category:Developer tools|NetBeans]]&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=AJAX_marking_block&amp;diff=17051</id>
		<title>AJAX marking block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=AJAX_marking_block&amp;diff=17051"/>
		<updated>2010-02-25T14:04:44Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* Constructor */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page outlines the internal architecture of the AJAX marking block and how to extend it for new types of assignment.&lt;br /&gt;
&lt;br /&gt;
=Architecture=&lt;br /&gt;
&lt;br /&gt;
The block has a server side section of code written in PHP and a client side in javascript. The client is based on the YUI treeview widget and sends asynchronous messages to the server to retrieve the data which becomes the nodes of the tree. Each time a node is clicked to expand it, a new message is sent, with the response data parsed and made into the new sub-nodes.&lt;br /&gt;
&lt;br /&gt;
==HTML fallback==&lt;br /&gt;
To aid accessibility, the block starts by loading a very basic HTML version so that if javascript is turned off either in the browser or the user&#039;s preferences, the block is still usable. This HTML version is normally not visible as the javascript acts to hide it immediately if possible.&lt;br /&gt;
&lt;br /&gt;
==File structure==&lt;br /&gt;
The main lib.php file provides a base class which holds most of the useful functions. This is extended through inheritance when either ajax.php is accessed (each time an asynchronous request is sent) or html_list.php is included when the page is initially set up, providing an object which automatically collects submitted POST data and outputs the desired code once instantiated. This file also has a base class, module_base which is extended by each of the modules with a modulename_functions classin the modulename_grading.php file. All of these files are included as needed at the start and the instantiated objects are added to the main library class object as e.g. $AMB_AJAX_response-&amp;gt;quiz so that their functions are available. The module objects will need to use many of the library functions, so a reference to the parent library object is passed in via the constructor and is used as $this-&amp;gt;mainobject-&amp;gt;useful_function().&lt;br /&gt;
&lt;br /&gt;
The javascript.js file contains a collection of functions which are placed within the YAHOO.ajax_marking_block namespace. Some are part of YAHOO.ajax_marking_block.tree_base which is an extended version of the YAHOO.widget.TreeView widget that gets instantiated once for the main tree and once for the configuration tree via a factory function.&lt;br /&gt;
&lt;br /&gt;
=Plugins=&lt;br /&gt;
The block is designed to allow new assessment types to be added dynamically. Rach new type will need to provide two files: modulename_grading.php and modulename_grading.js, whic can be placed either in the /block/ajax_marking folder or in the /mod/modulename folder.&lt;br /&gt;
&lt;br /&gt;
To see how these work, take the assignment_grading files as examples.&lt;br /&gt;
&lt;br /&gt;
==PHP==&lt;br /&gt;
The php file will need the following:&lt;br /&gt;
&lt;br /&gt;
The usual login check&lt;br /&gt;
  require_login(0, false);&lt;br /&gt;
&lt;br /&gt;
A class declaration for modulename_function which extends module_base&lt;br /&gt;
  class assignment_functions extends module_base {&lt;br /&gt;
&lt;br /&gt;
===Constructor===&lt;br /&gt;
A constructor which lays out the basic information about this module&lt;br /&gt;
  function assignment_functions(&amp;amp;$reference) {&lt;br /&gt;
&lt;br /&gt;
The library object (which this object will be attached to) passed in as a reference so that functions can be accessed&lt;br /&gt;
  $this-&amp;gt;mainobject = $reference;&lt;br /&gt;
&lt;br /&gt;
The type must be identical to the modulename stored in the database&lt;br /&gt;
  $this-&amp;gt;type = &#039;assignment&#039;;&lt;br /&gt;
&lt;br /&gt;
This is the capability that will need to be checked to see if the person has grading permission i.e. teachers should be able to do this whilst students should not.&lt;br /&gt;
  $this-&amp;gt;capability = &#039;mod/assignment:grade&#039;;&lt;br /&gt;
&lt;br /&gt;
This is the location of the icon to be displayed for this assessment type. It varies according to which theme setup you have. Smartpix was difficult to integrate, so there is a home-grown solution using this property, at least for 1.9.&lt;br /&gt;
  $this-&amp;gt;icon = &#039;mod/assignment/icon.gif&#039;;&lt;br /&gt;
&lt;br /&gt;
This array is used to match the types which are returned from the nodes being clicked in the ajax tree to the functions which return the next level of the tree. The initial course-&amp;gt;assessment node one is built in, so you just need to add the second and possibly third level connections. In this case, when a node of type &#039;assignment is clicked, the name of the function that will return the next layer of nodes (the individual student submissions) is &#039;submissions()&#039;. Groups nodes are dealt with automatically, so there is no need to put them here.&lt;br /&gt;
  $this-&amp;gt;functions  = array(&lt;br /&gt;
       &#039;assignment&#039; =&amp;gt; &#039;submissions&#039;&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
It is possible that your assessment may have only two levels e.g. the journal module. This would be because there is no screen that allows you to grade individual students&#039; work and you must have a pop up for the entire journal with all students. Alternatively, it may be that you can only grade a student&#039;s work for a subdivision of an assessment e.g. one question at a time in the quiz. In this case, you will have four levels: course, quiz, quiz question, student. Specify the number of levels here so that the nodes are constructed properly. 3 is the norm.&lt;br /&gt;
  $this-&amp;gt;levels = 3;&lt;br /&gt;
&lt;br /&gt;
==Javascript==&lt;br /&gt;
Using the assignment module as an example, the javascript file will need to use the YAHOO.ajax_marking_block.modulename namespace and will have to add the following features:&lt;br /&gt;
&lt;br /&gt;
Make a new namespace for the module:&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment = {};&lt;br /&gt;
The following functions (in no particular order) all use this namespace and must be included even if empty unless otherwise stated.&lt;br /&gt;
&lt;br /&gt;
Provide arguments for the pop up window that the grading will happen in. The main thing to change here is the height and width so that the grading interface is visible.&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment.pop_up_arguments  = function(clicked_node) {&lt;br /&gt;
      return &#039;menubar=0,location=0,scrollbars,resizable,width=780,height=630&#039;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
Provide the URL for the pop up window. This will usually involve some combination of the student&#039;s userid and the assessement id or coursemodule id. This data is saved in the data attribute of the clicked node and is passed through to this function. You will need to make sure it is passed through by the PHP code on the server.&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment.pop_up_opening_url = function (clicked_node) {&lt;br /&gt;
      return &#039;/mod/assignment/submissions.php?id=&#039;+clicked_node.data.aid+&#039;&amp;amp;userid=&#039;+clicked_node.data.sid+&#039;&amp;amp;mode=single&amp;amp;offset=0&#039;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
The pop up window needs to be closed after grading has finished, which a small piece of javascript carries out. It does this by checking to see if the URL has changed to the one signifying that your grades have been saved, so grade some work, press &#039;save&#039; and look to see the URL, which you put in this function.&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment.pop_up_closing_url = function (clicked_node) {&lt;br /&gt;
      return &#039;/mod/assignment/submissions.php&#039;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
There may be a need to send more than just the standard user id and assessment item id with the AJAX request in order to specify what&#039;s needed. See the quiz module for an example, where the quiz id and question id are needed as well as the user id. Leave it as below if not required.&lt;br /&gt;
&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment.extra_ajax_request_arguments = function (clicked_node) {&lt;br /&gt;
      return true;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
You then need to provide code that will alter the pop up&#039;s contents so that when the submit button is clicked, the tree nodes are updated. The function below will be run every second from the point at which the pop up is opened until it completes successfully. It aims to test the loaded portion of the DOM to see whether the buttons that need altering are present, then adds an onclick function which will update the tree.&lt;br /&gt;
&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment.alter_popup = function(node_id) {&lt;br /&gt;
  &lt;br /&gt;
      var els = &#039;&#039;;&lt;br /&gt;
  &lt;br /&gt;
      if (YAHOO.ajax_marking_block.pop_up_holder.document.getElementsByName) {&lt;br /&gt;
  &lt;br /&gt;
          els = YAHOO.ajax_marking_block.pop_up_holder.document.getElementsByName(&#039;submit&#039;);&lt;br /&gt;
          // the above line will not return anything until the pop up is fully loaded&lt;br /&gt;
  &lt;br /&gt;
          if (els.length &amp;gt; 0) {&lt;br /&gt;
              var functionText   = &amp;quot;return YAHOO.ajax_marking_block.main_instance.remove_node_from_tree(-1, &#039;&amp;quot;;&lt;br /&gt;
                   functionText += node_id+&amp;quot;&#039;, false); &amp;quot;;&lt;br /&gt;
  &lt;br /&gt;
              els[0][&amp;quot;onclick&amp;quot;] = new Function(functionText);&lt;br /&gt;
  &lt;br /&gt;
              // cancel the timer loop for this function&lt;br /&gt;
              window.clearInterval(YAHOO.ajax_marking_block.timerVar);&lt;br /&gt;
          }&lt;br /&gt;
      }    &lt;br /&gt;
  }&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=AJAX_marking_block&amp;diff=17050</id>
		<title>AJAX marking block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=AJAX_marking_block&amp;diff=17050"/>
		<updated>2010-02-25T14:04:27Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* Constructor */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page outlines the internal architecture of the AJAX marking block and how to extend it for new types of assignment.&lt;br /&gt;
&lt;br /&gt;
=Architecture=&lt;br /&gt;
&lt;br /&gt;
The block has a server side section of code written in PHP and a client side in javascript. The client is based on the YUI treeview widget and sends asynchronous messages to the server to retrieve the data which becomes the nodes of the tree. Each time a node is clicked to expand it, a new message is sent, with the response data parsed and made into the new sub-nodes.&lt;br /&gt;
&lt;br /&gt;
==HTML fallback==&lt;br /&gt;
To aid accessibility, the block starts by loading a very basic HTML version so that if javascript is turned off either in the browser or the user&#039;s preferences, the block is still usable. This HTML version is normally not visible as the javascript acts to hide it immediately if possible.&lt;br /&gt;
&lt;br /&gt;
==File structure==&lt;br /&gt;
The main lib.php file provides a base class which holds most of the useful functions. This is extended through inheritance when either ajax.php is accessed (each time an asynchronous request is sent) or html_list.php is included when the page is initially set up, providing an object which automatically collects submitted POST data and outputs the desired code once instantiated. This file also has a base class, module_base which is extended by each of the modules with a modulename_functions classin the modulename_grading.php file. All of these files are included as needed at the start and the instantiated objects are added to the main library class object as e.g. $AMB_AJAX_response-&amp;gt;quiz so that their functions are available. The module objects will need to use many of the library functions, so a reference to the parent library object is passed in via the constructor and is used as $this-&amp;gt;mainobject-&amp;gt;useful_function().&lt;br /&gt;
&lt;br /&gt;
The javascript.js file contains a collection of functions which are placed within the YAHOO.ajax_marking_block namespace. Some are part of YAHOO.ajax_marking_block.tree_base which is an extended version of the YAHOO.widget.TreeView widget that gets instantiated once for the main tree and once for the configuration tree via a factory function.&lt;br /&gt;
&lt;br /&gt;
=Plugins=&lt;br /&gt;
The block is designed to allow new assessment types to be added dynamically. Rach new type will need to provide two files: modulename_grading.php and modulename_grading.js, whic can be placed either in the /block/ajax_marking folder or in the /mod/modulename folder.&lt;br /&gt;
&lt;br /&gt;
To see how these work, take the assignment_grading files as examples.&lt;br /&gt;
&lt;br /&gt;
==PHP==&lt;br /&gt;
The php file will need the following:&lt;br /&gt;
&lt;br /&gt;
The usual login check&lt;br /&gt;
  require_login(0, false);&lt;br /&gt;
&lt;br /&gt;
A class declaration for modulename_function which extends module_base&lt;br /&gt;
  class assignment_functions extends module_base {&lt;br /&gt;
&lt;br /&gt;
===Constructor===&lt;br /&gt;
A constructor which lays out the basic information about this module&lt;br /&gt;
  function assignment_functions(&amp;amp;$reference) {&lt;br /&gt;
&lt;br /&gt;
The library object (which this object will be attached to) passed in as a reference so that functions can be accessed&lt;br /&gt;
  $this-&amp;gt;mainobject = $reference;&lt;br /&gt;
&lt;br /&gt;
The type must be identical to the modulename stored in the database&lt;br /&gt;
  $this-&amp;gt;type       = &#039;assignment&#039;;&lt;br /&gt;
&lt;br /&gt;
This is the capability that will need to be checked to see if the person has grading permission i.e. teachers should be able to do this whilst students should not.&lt;br /&gt;
  $this-&amp;gt;capability = &#039;mod/assignment:grade&#039;;&lt;br /&gt;
&lt;br /&gt;
This is the location of the icon to be displayed for this assessment type. It varies according to which theme setup you have. Smartpix was difficult to integrate, so there is a home-grown solution using this property, at least for 1.9.&lt;br /&gt;
  $this-&amp;gt;icon       = &#039;mod/assignment/icon.gif&#039;;&lt;br /&gt;
&lt;br /&gt;
This array is used to match the types which are returned from the nodes being clicked in the ajax tree to the functions which return the next level of the tree. The initial course-&amp;gt;assessment node one is built in, so you just need to add the second and possibly third level connections. In this case, when a node of type &#039;assignment is clicked, the name of the function that will return the next layer of nodes (the individual student submissions) is &#039;submissions()&#039;. Groups nodes are dealt with automatically, so there is no need to put them here.&lt;br /&gt;
  $this-&amp;gt;functions  = array(&lt;br /&gt;
       &#039;assignment&#039; =&amp;gt; &#039;submissions&#039;&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
It is possible that your assessment may have only two levels e.g. the journal module. This would be because there is no screen that allows you to grade individual students&#039; work and you must have a pop up for the entire journal with all students. Alternatively, it may be that you can only grade a student&#039;s work for a subdivision of an assessment e.g. one question at a time in the quiz. In this case, you will have four levels: course, quiz, quiz question, student. Specify the number of levels here so that the nodes are constructed properly. 3 is the norm.&lt;br /&gt;
  $this-&amp;gt;levels = 3;&lt;br /&gt;
&lt;br /&gt;
==Javascript==&lt;br /&gt;
Using the assignment module as an example, the javascript file will need to use the YAHOO.ajax_marking_block.modulename namespace and will have to add the following features:&lt;br /&gt;
&lt;br /&gt;
Make a new namespace for the module:&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment = {};&lt;br /&gt;
The following functions (in no particular order) all use this namespace and must be included even if empty unless otherwise stated.&lt;br /&gt;
&lt;br /&gt;
Provide arguments for the pop up window that the grading will happen in. The main thing to change here is the height and width so that the grading interface is visible.&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment.pop_up_arguments  = function(clicked_node) {&lt;br /&gt;
      return &#039;menubar=0,location=0,scrollbars,resizable,width=780,height=630&#039;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
Provide the URL for the pop up window. This will usually involve some combination of the student&#039;s userid and the assessement id or coursemodule id. This data is saved in the data attribute of the clicked node and is passed through to this function. You will need to make sure it is passed through by the PHP code on the server.&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment.pop_up_opening_url = function (clicked_node) {&lt;br /&gt;
      return &#039;/mod/assignment/submissions.php?id=&#039;+clicked_node.data.aid+&#039;&amp;amp;userid=&#039;+clicked_node.data.sid+&#039;&amp;amp;mode=single&amp;amp;offset=0&#039;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
The pop up window needs to be closed after grading has finished, which a small piece of javascript carries out. It does this by checking to see if the URL has changed to the one signifying that your grades have been saved, so grade some work, press &#039;save&#039; and look to see the URL, which you put in this function.&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment.pop_up_closing_url = function (clicked_node) {&lt;br /&gt;
      return &#039;/mod/assignment/submissions.php&#039;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
There may be a need to send more than just the standard user id and assessment item id with the AJAX request in order to specify what&#039;s needed. See the quiz module for an example, where the quiz id and question id are needed as well as the user id. Leave it as below if not required.&lt;br /&gt;
&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment.extra_ajax_request_arguments = function (clicked_node) {&lt;br /&gt;
      return true;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
You then need to provide code that will alter the pop up&#039;s contents so that when the submit button is clicked, the tree nodes are updated. The function below will be run every second from the point at which the pop up is opened until it completes successfully. It aims to test the loaded portion of the DOM to see whether the buttons that need altering are present, then adds an onclick function which will update the tree.&lt;br /&gt;
&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment.alter_popup = function(node_id) {&lt;br /&gt;
  &lt;br /&gt;
      var els = &#039;&#039;;&lt;br /&gt;
  &lt;br /&gt;
      if (YAHOO.ajax_marking_block.pop_up_holder.document.getElementsByName) {&lt;br /&gt;
  &lt;br /&gt;
          els = YAHOO.ajax_marking_block.pop_up_holder.document.getElementsByName(&#039;submit&#039;);&lt;br /&gt;
          // the above line will not return anything until the pop up is fully loaded&lt;br /&gt;
  &lt;br /&gt;
          if (els.length &amp;gt; 0) {&lt;br /&gt;
              var functionText   = &amp;quot;return YAHOO.ajax_marking_block.main_instance.remove_node_from_tree(-1, &#039;&amp;quot;;&lt;br /&gt;
                   functionText += node_id+&amp;quot;&#039;, false); &amp;quot;;&lt;br /&gt;
  &lt;br /&gt;
              els[0][&amp;quot;onclick&amp;quot;] = new Function(functionText);&lt;br /&gt;
  &lt;br /&gt;
              // cancel the timer loop for this function&lt;br /&gt;
              window.clearInterval(YAHOO.ajax_marking_block.timerVar);&lt;br /&gt;
          }&lt;br /&gt;
      }    &lt;br /&gt;
  }&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=AJAX_marking_block&amp;diff=17049</id>
		<title>AJAX marking block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=AJAX_marking_block&amp;diff=17049"/>
		<updated>2010-02-25T13:55:41Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* Javascript */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page outlines the internal architecture of the AJAX marking block and how to extend it for new types of assignment.&lt;br /&gt;
&lt;br /&gt;
=Architecture=&lt;br /&gt;
&lt;br /&gt;
The block has a server side section of code written in PHP and a client side in javascript. The client is based on the YUI treeview widget and sends asynchronous messages to the server to retrieve the data which becomes the nodes of the tree. Each time a node is clicked to expand it, a new message is sent, with the response data parsed and made into the new sub-nodes.&lt;br /&gt;
&lt;br /&gt;
==HTML fallback==&lt;br /&gt;
To aid accessibility, the block starts by loading a very basic HTML version so that if javascript is turned off either in the browser or the user&#039;s preferences, the block is still usable. This HTML version is normally not visible as the javascript acts to hide it immediately if possible.&lt;br /&gt;
&lt;br /&gt;
==File structure==&lt;br /&gt;
The main lib.php file provides a base class which holds most of the useful functions. This is extended through inheritance when either ajax.php is accessed (each time an asynchronous request is sent) or html_list.php is included when the page is initially set up, providing an object which automatically collects submitted POST data and outputs the desired code once instantiated. This file also has a base class, module_base which is extended by each of the modules with a modulename_functions classin the modulename_grading.php file. All of these files are included as needed at the start and the instantiated objects are added to the main library class object as e.g. $AMB_AJAX_response-&amp;gt;quiz so that their functions are available. The module objects will need to use many of the library functions, so a reference to the parent library object is passed in via the constructor and is used as $this-&amp;gt;mainobject-&amp;gt;useful_function().&lt;br /&gt;
&lt;br /&gt;
The javascript.js file contains a collection of functions which are placed within the YAHOO.ajax_marking_block namespace. Some are part of YAHOO.ajax_marking_block.tree_base which is an extended version of the YAHOO.widget.TreeView widget that gets instantiated once for the main tree and once for the configuration tree via a factory function.&lt;br /&gt;
&lt;br /&gt;
=Plugins=&lt;br /&gt;
The block is designed to allow new assessment types to be added dynamically. Rach new type will need to provide two files: modulename_grading.php and modulename_grading.js, whic can be placed either in the /block/ajax_marking folder or in the /mod/modulename folder.&lt;br /&gt;
&lt;br /&gt;
To see how these work, take the assignment_grading files as examples.&lt;br /&gt;
&lt;br /&gt;
==PHP==&lt;br /&gt;
The php file will need the following:&lt;br /&gt;
&lt;br /&gt;
The usual login check&lt;br /&gt;
  require_login(0, false);&lt;br /&gt;
&lt;br /&gt;
A class declaration for modulename_function which extends module_base&lt;br /&gt;
  class assignment_functions extends module_base {&lt;br /&gt;
&lt;br /&gt;
===Constructor===&lt;br /&gt;
A constructor which lays out the basic information about this module&lt;br /&gt;
  function assignment_functions(&amp;amp;$reference) {&lt;br /&gt;
&lt;br /&gt;
The library object (which this object will be attached to) passed in as a reference so that functions can be accessed&lt;br /&gt;
  $this-&amp;gt;mainobject = $reference;&lt;br /&gt;
&lt;br /&gt;
The type must be identical to the modulename stored in the database&lt;br /&gt;
  $this-&amp;gt;type       = &#039;assignment&#039;;&lt;br /&gt;
&lt;br /&gt;
This is the capability that will need to be checked to see if the person has grading permission i.e. teachers should be able to do this whilst students should not.&lt;br /&gt;
  $this-&amp;gt;capability = &#039;mod/assignment:grade&#039;;&lt;br /&gt;
&lt;br /&gt;
This is the location of the icon to be displayed for this assessment type. It varies according to which theme setup you have. Smartpix was difficult to integrate, so there is a home-grown solution using this property, at least for 1.9.&lt;br /&gt;
  $this-&amp;gt;icon       = &#039;mod/assignment/icon.gif&#039;;&lt;br /&gt;
&lt;br /&gt;
This array is used to match the types which are returned from the nodes being clicked in the ajax tree to the functions which return the next level of the tree. The initial course-&amp;gt;assessment node one is built in, so you just need to add the second and possibly third level connections. In this case, when a node of type &#039;assignment is clicked, the name of the function that will return the next layer of nodes (the individual student submissions) is &#039;submissions()&#039;. Groups nodes are dealt with automatically, so there is no need to put them here.&lt;br /&gt;
  $this-&amp;gt;functions  = array(&lt;br /&gt;
       &#039;assignment&#039; =&amp;gt; &#039;submissions&#039;&lt;br /&gt;
   );&lt;br /&gt;
&lt;br /&gt;
It is possible that your assessment may have only two levels e.g. the journal module. This would be because there is no screen that allows you to grade individual students&#039; work and you must have a pop up for the entire journal with all students. Alternatively, it may be that you can only grade a student&#039;s work for a subdivision of an assessment e.g. one question at a time in the quiz. In this case, you will have four levels: course, quiz, quiz question, student. Specify the number of levels here so that the nodes are constructed properly. 3 is the norm.&lt;br /&gt;
  $this-&amp;gt;levels = 3;&lt;br /&gt;
&lt;br /&gt;
==Javascript==&lt;br /&gt;
Using the assignment module as an example, the javascript file will need to use the YAHOO.ajax_marking_block.modulename namespace and will have to add the following features:&lt;br /&gt;
&lt;br /&gt;
Make a new namespace for the module:&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment = {};&lt;br /&gt;
The following functions (in no particular order) all use this namespace and must be included even if empty unless otherwise stated.&lt;br /&gt;
&lt;br /&gt;
Provide arguments for the pop up window that the grading will happen in. The main thing to change here is the height and width so that the grading interface is visible.&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment.pop_up_arguments  = function(clicked_node) {&lt;br /&gt;
      return &#039;menubar=0,location=0,scrollbars,resizable,width=780,height=630&#039;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
Provide the URL for the pop up window. This will usually involve some combination of the student&#039;s userid and the assessement id or coursemodule id. This data is saved in the data attribute of the clicked node and is passed through to this function. You will need to make sure it is passed through by the PHP code on the server.&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment.pop_up_opening_url = function (clicked_node) {&lt;br /&gt;
      return &#039;/mod/assignment/submissions.php?id=&#039;+clicked_node.data.aid+&#039;&amp;amp;userid=&#039;+clicked_node.data.sid+&#039;&amp;amp;mode=single&amp;amp;offset=0&#039;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
The pop up window needs to be closed after grading has finished, which a small piece of javascript carries out. It does this by checking to see if the URL has changed to the one signifying that your grades have been saved, so grade some work, press &#039;save&#039; and look to see the URL, which you put in this function.&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment.pop_up_closing_url = function (clicked_node) {&lt;br /&gt;
      return &#039;/mod/assignment/submissions.php&#039;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
There may be a need to send more than just the standard user id and assessment item id with the AJAX request in order to specify what&#039;s needed. See the quiz module for an example, where the quiz id and question id are needed as well as the user id. Leave it as below if not required.&lt;br /&gt;
&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment.extra_ajax_request_arguments = function (clicked_node) {&lt;br /&gt;
      return true;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
You then need to provide code that will alter the pop up&#039;s contents so that when the submit button is clicked, the tree nodes are updated. The function below will be run every second from the point at which the pop up is opened until it completes successfully. It aims to test the loaded portion of the DOM to see whether the buttons that need altering are present, then adds an onclick function which will update the tree.&lt;br /&gt;
&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment.alter_popup = function(node_id) {&lt;br /&gt;
  &lt;br /&gt;
      var els = &#039;&#039;;&lt;br /&gt;
  &lt;br /&gt;
      if (YAHOO.ajax_marking_block.pop_up_holder.document.getElementsByName) {&lt;br /&gt;
  &lt;br /&gt;
          els = YAHOO.ajax_marking_block.pop_up_holder.document.getElementsByName(&#039;submit&#039;);&lt;br /&gt;
          // the above line will not return anything until the pop up is fully loaded&lt;br /&gt;
  &lt;br /&gt;
          if (els.length &amp;gt; 0) {&lt;br /&gt;
              var functionText   = &amp;quot;return YAHOO.ajax_marking_block.main_instance.remove_node_from_tree(-1, &#039;&amp;quot;;&lt;br /&gt;
                   functionText += node_id+&amp;quot;&#039;, false); &amp;quot;;&lt;br /&gt;
  &lt;br /&gt;
              els[0][&amp;quot;onclick&amp;quot;] = new Function(functionText);&lt;br /&gt;
  &lt;br /&gt;
              // cancel the timer loop for this function&lt;br /&gt;
              window.clearInterval(YAHOO.ajax_marking_block.timerVar);&lt;br /&gt;
          }&lt;br /&gt;
      }    &lt;br /&gt;
  }&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=AJAX_marking_block&amp;diff=17048</id>
		<title>AJAX marking block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=AJAX_marking_block&amp;diff=17048"/>
		<updated>2010-02-25T13:40:58Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* PHP */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page outlines the internal architecture of the AJAX marking block and how to extend it for new types of assignment.&lt;br /&gt;
&lt;br /&gt;
=Architecture=&lt;br /&gt;
&lt;br /&gt;
The block has a server side section of code written in PHP and a client side in javascript. The client is based on the YUI treeview widget and sends asynchronous messages to the server to retrieve the data which becomes the nodes of the tree. Each time a node is clicked to expand it, a new message is sent, with the response data parsed and made into the new sub-nodes.&lt;br /&gt;
&lt;br /&gt;
==HTML fallback==&lt;br /&gt;
To aid accessibility, the block starts by loading a very basic HTML version so that if javascript is turned off either in the browser or the user&#039;s preferences, the block is still usable. This HTML version is normally not visible as the javascript acts to hide it immediately if possible.&lt;br /&gt;
&lt;br /&gt;
==File structure==&lt;br /&gt;
The main lib.php file provides a base class which holds most of the useful functions. This is extended through inheritance when either ajax.php is accessed (each time an asynchronous request is sent) or html_list.php is included when the page is initially set up, providing an object which automatically collects submitted POST data and outputs the desired code once instantiated. This file also has a base class, module_base which is extended by each of the modules with a modulename_functions classin the modulename_grading.php file. All of these files are included as needed at the start and the instantiated objects are added to the main library class object as e.g. $AMB_AJAX_response-&amp;gt;quiz so that their functions are available. The module objects will need to use many of the library functions, so a reference to the parent library object is passed in via the constructor and is used as $this-&amp;gt;mainobject-&amp;gt;useful_function().&lt;br /&gt;
&lt;br /&gt;
The javascript.js file contains a collection of functions which are placed within the YAHOO.ajax_marking_block namespace. Some are part of YAHOO.ajax_marking_block.tree_base which is an extended version of the YAHOO.widget.TreeView widget that gets instantiated once for the main tree and once for the configuration tree via a factory function.&lt;br /&gt;
&lt;br /&gt;
=Plugins=&lt;br /&gt;
The block is designed to allow new assessment types to be added dynamically. Rach new type will need to provide two files: modulename_grading.php and modulename_grading.js, whic can be placed either in the /block/ajax_marking folder or in the /mod/modulename folder.&lt;br /&gt;
&lt;br /&gt;
To see how these work, take the assignment_grading files as examples.&lt;br /&gt;
&lt;br /&gt;
==PHP==&lt;br /&gt;
The php file will need the following:&lt;br /&gt;
&lt;br /&gt;
The usual login check&lt;br /&gt;
  require_login(0, false);&lt;br /&gt;
&lt;br /&gt;
A class declaration for modulename_function which extends module_base&lt;br /&gt;
  class assignment_functions extends module_base {&lt;br /&gt;
&lt;br /&gt;
===Constructor===&lt;br /&gt;
A constructor which lays out the basic information about this module&lt;br /&gt;
  function assignment_functions(&amp;amp;$reference) {&lt;br /&gt;
&lt;br /&gt;
The library object (which this object will be attached to) passed in as a reference so that functions can be accessed&lt;br /&gt;
  $this-&amp;gt;mainobject = $reference;&lt;br /&gt;
&lt;br /&gt;
The type must be identical to the modulename stored in the database&lt;br /&gt;
  $this-&amp;gt;type       = &#039;assignment&#039;;&lt;br /&gt;
&lt;br /&gt;
This is the capability that will need to be checked to see if the person has grading permission i.e. teachers should be able to do this whilst students should not.&lt;br /&gt;
  $this-&amp;gt;capability = &#039;mod/assignment:grade&#039;;&lt;br /&gt;
&lt;br /&gt;
This is the location of the icon to be displayed for this assessment type. It varies according to which theme setup you have. Smartpix was difficult to integrate, so there is a home-grown solution using this property, at least for 1.9.&lt;br /&gt;
  $this-&amp;gt;icon       = &#039;mod/assignment/icon.gif&#039;;&lt;br /&gt;
&lt;br /&gt;
This array is used to match the types which are returned from the nodes being clicked in the ajax tree to the functions which return the next level of the tree. The initial course-&amp;gt;assessment node one is built in, so you just need to add the second and possibly third level connections. In this case, when a node of type &#039;assignment is clicked, the name of the function that will return the next layer of nodes (the individual student submissions) is &#039;submissions()&#039;. Groups nodes are dealt with automatically, so there is no need to put them here.&lt;br /&gt;
  $this-&amp;gt;functions  = array(&lt;br /&gt;
       &#039;assignment&#039; =&amp;gt; &#039;submissions&#039;&lt;br /&gt;
   );&lt;br /&gt;
&lt;br /&gt;
It is possible that your assessment may have only two levels e.g. the journal module. This would be because there is no screen that allows you to grade individual students&#039; work and you must have a pop up for the entire journal with all students. Alternatively, it may be that you can only grade a student&#039;s work for a subdivision of an assessment e.g. one question at a time in the quiz. In this case, you will have four levels: course, quiz, quiz question, student. Specify the number of levels here so that the nodes are constructed properly. 3 is the norm.&lt;br /&gt;
  $this-&amp;gt;levels = 3;&lt;br /&gt;
&lt;br /&gt;
==Javascript==&lt;br /&gt;
Using the assignment module as an example, the javascript file will need to use the YAHOO.ajax_marking_block.modulename namespace and will have to add the following features:&lt;br /&gt;
&lt;br /&gt;
Make a new namespace for the module:&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment = {};&lt;br /&gt;
The following functions (in no particular order) all use this namespace and must be included even if empty unless otherwise stated.&lt;br /&gt;
&lt;br /&gt;
Provide arguments for the pop up window that the grading will happen in. The main thing to change here is the height and width so that the grading interface is visible.&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment.pop_up_arguments  = function(clicked_node) {&lt;br /&gt;
      return &#039;menubar=0,location=0,scrollbars,resizable,width=780,height=630&#039;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
Provide the URL for the pop up window. This will usually involve some combination of the student&#039;s userid and the assessement id or coursemodule id. This data is saved in the data attribute of the clicked node and is passed through to this function. You will need to make sure it is passed through by the PHP code on the server.&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment.pop_up_opening_url = function (clicked_node) {&lt;br /&gt;
      return &#039;/mod/assignment/submissions.php?id=&#039;+clicked_node.data.aid+&#039;&amp;amp;userid=&#039;+clicked_node.data.sid+&#039;&amp;amp;mode=single&amp;amp;offset=0&#039;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
The pop up window needs to be closed after grading has finished, which a small piece of javascript carries out. It does this by checking to see if the URL has changed to the one signifying that your grades have been saved, so grade some work, press &#039;save&#039; and look to see the URL, which you put in this function.&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment.pop_up_closing_url = function (clicked_node) {&lt;br /&gt;
      return &#039;/mod/assignment/submissions.php&#039;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
There may be a need to send more than just the standard user id and assessment item id with the AJAX request in order to specify what&#039;s needed. See the quiz module for an example, where the quiz id and question id are needed as well as the user id. Leave it as below if not required.&lt;br /&gt;
&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment.extra_ajax_request_arguments = function (clicked_node) {&lt;br /&gt;
      return true;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
You then need to provide code that will alter the pop up&#039;s contents so that when the submit button is clicked, the tree nodes are updated. The function below will be run every second from the point at which the pop up is opened until it completes successfully. It aims to test the loaded portion of the DOM to see whether the buttons that need altering are present, then adds an onclick function which will update the tree.&lt;br /&gt;
&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment.alter_popup = function(node_id) {&lt;br /&gt;
  &lt;br /&gt;
      var els = &#039;&#039;;&lt;br /&gt;
  &lt;br /&gt;
      if (YAHOO.ajax_marking_block.pop_up_holder.document.getElementsByName) {&lt;br /&gt;
  &lt;br /&gt;
          els = YAHOO.ajax_marking_block.pop_up_holder.document.getElementsByName(&#039;submit&#039;);&lt;br /&gt;
          // the above line will not return anything until the pop up is fully loaded&lt;br /&gt;
  &lt;br /&gt;
          if (els.length &amp;gt; 0) {&lt;br /&gt;
              var functionText   = &amp;quot;return YAHOO.ajax_marking_block.main_instance.remove_node_from_tree(-1, &#039;&amp;quot;;&lt;br /&gt;
                    functionText += node_id+&amp;quot;&#039;, false); &amp;quot;;&lt;br /&gt;
  &lt;br /&gt;
              els[0][&amp;quot;onclick&amp;quot;] = new Function(functionText);&lt;br /&gt;
  &lt;br /&gt;
              // cancel the timer loop for this function&lt;br /&gt;
              window.clearInterval(YAHOO.ajax_marking_block.timerVar);&lt;br /&gt;
          }&lt;br /&gt;
      }    &lt;br /&gt;
  }&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=AJAX_marking_block&amp;diff=17047</id>
		<title>AJAX marking block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=AJAX_marking_block&amp;diff=17047"/>
		<updated>2010-02-25T13:00:18Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page outlines the internal architecture of the AJAX marking block and how to extend it for new types of assignment.&lt;br /&gt;
&lt;br /&gt;
=Architecture=&lt;br /&gt;
&lt;br /&gt;
The block has a server side section of code written in PHP and a client side in javascript. The client is based on the YUI treeview widget and sends asynchronous messages to the server to retrieve the data which becomes the nodes of the tree. Each time a node is clicked to expand it, a new message is sent, with the response data parsed and made into the new sub-nodes.&lt;br /&gt;
&lt;br /&gt;
==HTML fallback==&lt;br /&gt;
To aid accessibility, the block starts by loading a very basic HTML version so that if javascript is turned off either in the browser or the user&#039;s preferences, the block is still usable. This HTML version is normally not visible as the javascript acts to hide it immediately if possible.&lt;br /&gt;
&lt;br /&gt;
==File structure==&lt;br /&gt;
The main lib.php file provides a base class which holds most of the useful functions. This is extended through inheritance when either ajax.php is accessed (each time an asynchronous request is sent) or html_list.php is included when the page is initially set up, providing an object which automatically collects submitted POST data and outputs the desired code once instantiated. This file also has a base class, module_base which is extended by each of the modules with a modulename_functions classin the modulename_grading.php file. All of these files are included as needed at the start and the instantiated objects are added to the main library class object as e.g. $AMB_AJAX_response-&amp;gt;quiz so that their functions are available. The module objects will need to use many of the library functions, so a reference to the parent library object is passed in via the constructor and is used as $this-&amp;gt;mainobject-&amp;gt;useful_function().&lt;br /&gt;
&lt;br /&gt;
The javascript.js file contains a collection of functions which are placed within the YAHOO.ajax_marking_block namespace. Some are part of YAHOO.ajax_marking_block.tree_base which is an extended version of the YAHOO.widget.TreeView widget that gets instantiated once for the main tree and once for the configuration tree via a factory function.&lt;br /&gt;
&lt;br /&gt;
=Plugins=&lt;br /&gt;
The block is designed to allow new assessment types to be added dynamically. Rach new type will need to provide two files: modulename_grading.php and modulename_grading.js, whic can be placed either in the /block/ajax_marking folder or in the /mod/modulename folder.&lt;br /&gt;
&lt;br /&gt;
To see how these work, take the assignment_grading files as examples.&lt;br /&gt;
&lt;br /&gt;
==PHP==&lt;br /&gt;
The php file will need the following functions as a minimum:&lt;br /&gt;
&lt;br /&gt;
==Javascript==&lt;br /&gt;
Using the assignment module as an example, the javascript file will need to use the YAHOO.ajax_marking_block.modulename namespace and will have to add the following features:&lt;br /&gt;
&lt;br /&gt;
Make a new namespace for the module:&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment = {};&lt;br /&gt;
The following functions (in no particular order) all use this namespace and must be included even if empty unless otherwise stated.&lt;br /&gt;
&lt;br /&gt;
Provide arguments for the pop up window that the grading will happen in. The main thing to change here is the height and width so that the grading interface is visible.&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment.pop_up_arguments  = function(clicked_node) {&lt;br /&gt;
      return &#039;menubar=0,location=0,scrollbars,resizable,width=780,height=630&#039;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
Provide the URL for the pop up window. This will usually involve some combination of the student&#039;s userid and the assessement id or coursemodule id. This data is saved in the data attribute of the clicked node and is passed through to this function. You will need to make sure it is passed through by the PHP code on the server.&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment.pop_up_opening_url = function (clicked_node) {&lt;br /&gt;
      return &#039;/mod/assignment/submissions.php?id=&#039;+clicked_node.data.aid+&#039;&amp;amp;userid=&#039;+clicked_node.data.sid+&#039;&amp;amp;mode=single&amp;amp;offset=0&#039;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
The pop up window needs to be closed after grading has finished, which a small piece of javascript carries out. It does this by checking to see if the URL has changed to the one signifying that your grades have been saved, so grade some work, press &#039;save&#039; and look to see the URL, which you put in this function.&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment.pop_up_closing_url = function (clicked_node) {&lt;br /&gt;
      return &#039;/mod/assignment/submissions.php&#039;;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
There may be a need to send more than just the standard user id and assessment item id with the AJAX request in order to specify what&#039;s needed. See the quiz module for an example, where the quiz id and question id are needed as well as the user id. Leave it as below if not required.&lt;br /&gt;
&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment.extra_ajax_request_arguments = function (clicked_node) {&lt;br /&gt;
      return true;&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
You then need to provide code that will alter the pop up&#039;s contents so that when the submit button is clicked, the tree nodes are updated. The function below will be run every second from the point at which the pop up is opened until it completes successfully. It aims to test the loaded portion of the DOM to see whether the buttons that need altering are present, then adds an onclick function which will update the tree.&lt;br /&gt;
&lt;br /&gt;
  YAHOO.ajax_marking_block.assignment.alter_popup = function(node_id) {&lt;br /&gt;
  &lt;br /&gt;
      var els = &#039;&#039;;&lt;br /&gt;
  &lt;br /&gt;
      if (YAHOO.ajax_marking_block.pop_up_holder.document.getElementsByName) {&lt;br /&gt;
  &lt;br /&gt;
          els = YAHOO.ajax_marking_block.pop_up_holder.document.getElementsByName(&#039;submit&#039;);&lt;br /&gt;
          // the above line will not return anything until the pop up is fully loaded&lt;br /&gt;
  &lt;br /&gt;
          if (els.length &amp;gt; 0) {&lt;br /&gt;
              var functionText   = &amp;quot;return YAHOO.ajax_marking_block.main_instance.remove_node_from_tree(-1, &#039;&amp;quot;;&lt;br /&gt;
                    functionText += node_id+&amp;quot;&#039;, false); &amp;quot;;&lt;br /&gt;
  &lt;br /&gt;
              els[0][&amp;quot;onclick&amp;quot;] = new Function(functionText);&lt;br /&gt;
  &lt;br /&gt;
              // cancel the timer loop for this function&lt;br /&gt;
              window.clearInterval(YAHOO.ajax_marking_block.timerVar);&lt;br /&gt;
          }&lt;br /&gt;
      }    &lt;br /&gt;
  }&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=AJAX_marking_block&amp;diff=17046</id>
		<title>AJAX marking block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=AJAX_marking_block&amp;diff=17046"/>
		<updated>2010-02-25T09:14:36Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page outlines the internal architecture of the AJAX marking block and how to extend it for new types of assignment.&lt;br /&gt;
&lt;br /&gt;
=Architecture=&lt;br /&gt;
&lt;br /&gt;
The block has a server side section of code written in PHP and a client side in javascript. The client is based on the YUI treeview widget and sends asynchronous messages to the server to retrieve the data which becomes the nodes of the tree. Each time a node is clicked to expand it, a new message is sent, with the response data parsed and made into the new sub-nodes.&lt;br /&gt;
&lt;br /&gt;
==HTML fallback==&lt;br /&gt;
To aid accessibility, the block starts by loading a very basic HTML version so that if javascript is turned off either in the browser or the user&#039;s preferences, the block is still usable. This HTML version is normally not visible as the javascript acts to hide it immediately if possible.&lt;br /&gt;
&lt;br /&gt;
==File structure==&lt;br /&gt;
The main lib.php file provides a base class which holds most of the useful functions. This is extended through inheritance when either ajax.php is accessed (each time an asynchronous request is sent) or html_list.php is included when the page is initially set up, providing an object which automatically collects submitted POST data and outputs the desired code once instantiated. This file also has a base class, module_base which is extended by each of the modules with a modulename_functions classin the modulename_grading.php file. All of these files are included as needed at the start and the instantiated objects are added to the main library class object as e.g. $AMB_AJAX_response-&amp;gt;quiz so that their functions are available. The module objects will need to use many of the library functions, so a reference to the parent library object is passed in via the constructor and is used as $this-&amp;gt;mainobject-&amp;gt;useful_function().&lt;br /&gt;
&lt;br /&gt;
The javascript.js file contains a collection of functions which are placed within the YAHOO.ajax_marking_block namespace. Some are part of YAHOO.ajax_marking_block.tree_base which is an extended version of the YAHOO.widget.TreeView widget that gets instantiated once for the main tree and once for the configuration tree via a factory function.&lt;br /&gt;
&lt;br /&gt;
=Plugins=&lt;br /&gt;
The block is designed to allow new assessment types to be added dynamically. Rach new type will need to provide two files: modulename_grading.php and modulename_grading.js, whic can be placed either in the /block/ajax_marking folder or in the /mod/modulename folder.&lt;br /&gt;
&lt;br /&gt;
To see how these work, take the assignment_grading files as examples.&lt;br /&gt;
&lt;br /&gt;
==PHP==&lt;br /&gt;
The php file will need the following functions as a minimum:&lt;br /&gt;
&lt;br /&gt;
==Javascript==&lt;br /&gt;
The javascript file will need to use the YAHOO.ajax_marking_block.modulename namespace and will have to add the following functions:&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=AJAX_marking_block&amp;diff=17045</id>
		<title>AJAX marking block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=AJAX_marking_block&amp;diff=17045"/>
		<updated>2010-02-25T00:24:15Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: Began page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page outlines the internal architecture of the AJAX marking block and how to extend it for new types of assignment.&lt;br /&gt;
&lt;br /&gt;
=Architecture=&lt;br /&gt;
&lt;br /&gt;
The block has a server side section of code written in PHP and a client side in javascript. The client is based on the YUI treeview widget and sends asynchronous messages to the server to retrieve the data which becomes the nodes of the tree. Each time a node is clicked to expand it, a new message is sent, with the response data parsed and made into the new sub-nodes.&lt;br /&gt;
&lt;br /&gt;
==HTML fallback==&lt;br /&gt;
To aid accessibility, the block starts by loading a very basic HTML version so that if javascript is turned off either in the browser or the user&#039;s preferences, the block is still usable. This HTML version is normally not visible as the javascript acts to hide it immediately if possible.&lt;br /&gt;
&lt;br /&gt;
==File structure==&lt;br /&gt;
The main lib.php file acts as a base class which holds most of the useful functions. This is extended through inheritance when either ajax.php is accessed (each time an asynchronous request is sent) or html_list.php, providing an object which automatically collects submitted POST data and outputs the desired code once instantiated.&lt;br /&gt;
&lt;br /&gt;
The javascript.js file...&lt;br /&gt;
&lt;br /&gt;
=Plugins=&lt;br /&gt;
The block is designed to allow new assessment types to be added dynamically. Rach new type will need to provide two files: modulename_grading.php and modulename_grading.js, whic can be placed either in the /block/ajax_marking folder or in the /mod/modulename folder.&lt;br /&gt;
&lt;br /&gt;
To see how these work, take the assignment_grading files as examples.&lt;br /&gt;
&lt;br /&gt;
==PHP==&lt;br /&gt;
The php file will need the following functions as a minimum:&lt;br /&gt;
&lt;br /&gt;
==Javascript==&lt;br /&gt;
The javascript file will need to use the YAHOO.ajax_marking_block.modulename namespace and will have to add the following functions:&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Setting_up_Netbeans&amp;diff=8970</id>
		<title>Setting up Netbeans</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Setting_up_Netbeans&amp;diff=8970"/>
		<updated>2010-01-19T09:36:42Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: added memory optimisation link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.netbeans.org/features/php/index.html NetBeans] has got a good PHP support. You find a host of information on the website (tutorials, developer blog, screen casts, etc.).&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
* CVS integration: see all changes, lines deletion, diff in real time, show annotations, diff history...&lt;br /&gt;
* Ctrl+Click: Go to declaration&lt;br /&gt;
* Export/Import Diff Patch&lt;br /&gt;
* Easy navigation&lt;br /&gt;
* List of functions&lt;br /&gt;
* Code completion&lt;br /&gt;
* Instant rename&lt;br /&gt;
* HTML, CSS, JavaScript support&lt;br /&gt;
* MySQL manager&lt;br /&gt;
* Quick Search&lt;br /&gt;
* Very few bugs&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
* I recommend downloading the latest [http://www.netbeans.org/downloads/indexB.html 6.7.1 version with PHP support ]. It&#039;s only a 26 MB download.&lt;br /&gt;
* Install and run it.&lt;br /&gt;
&lt;br /&gt;
* There&#039;s also the brand new [http://netbeans.org/community/releases/68/ NetBeans 6.8 Beta release].&lt;br /&gt;
&lt;br /&gt;
== Set up for Moodle development ==&lt;br /&gt;
&lt;br /&gt;
* Checkout your Moodle project with a &#039;&#039;&#039;CVS client&#039;&#039;&#039; - see [[CVS for Administrators]] or [[CVS for developers|CVS for Developers]].&lt;br /&gt;
&lt;br /&gt;
* Open File &amp;gt; New Project &amp;gt; PHP &amp;gt; PHP Application &amp;gt; Next &lt;br /&gt;
: You&#039;re going to set the project now. &#039;&#039;Name&#039;&#039;, &#039;&#039;Location&#039;&#039; and &#039;&#039;Folder&#039;&#039; are used by NetBeans and are not related to the source code. So you can choose whatever you like, except your source folder. &#039;&#039;Sources&#039;&#039; has to be your checked out Moodle branch/head folder. The rest is clear enough. Don&#039;t forget to choose UTF-8 for &#039;&#039;Default Encoding&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
: Example:&lt;br /&gt;
&lt;br /&gt;
 Project Name:        Moodle 1.9 Stable&lt;br /&gt;
 Project Location:    C:\Users\jerome\Documents\NetBeansProjects&lt;br /&gt;
 Project Folder:      C:\Users\jerome\Documents\NetBeansProjects\Moodle 1.9 Stable&lt;br /&gt;
 Project Sources:     C:\Users\jerome\Projects\branch19_STABLE\moodle&lt;br /&gt;
 Project URL:         http://localhost/moodle19/&lt;br /&gt;
 Index File:          index.php&lt;br /&gt;
 Create:              unchecked&lt;br /&gt;
 Default Encoding:    UTF-8&lt;br /&gt;
 Set as Main Project: unchecked&lt;br /&gt;
&lt;br /&gt;
* Click on Finish.&lt;br /&gt;
&lt;br /&gt;
* Start coding!&lt;br /&gt;
&lt;br /&gt;
== CVS with NetBeans ==&lt;br /&gt;
&lt;br /&gt;
NetBeans comes with &#039;&#039;&#039;integrated CVS support&#039;&#039;&#039; which might be the easiest way to check out Moodle.&lt;br /&gt;
&lt;br /&gt;
=== Anonymous checkout ===&lt;br /&gt;
&lt;br /&gt;
# In NetBeans, select Window-&amp;gt;Versioning-&amp;gt;CVS-&amp;gt;Checkout&lt;br /&gt;
# Select Team-&amp;gt;CVS-&amp;gt;Checkout&lt;br /&gt;
# Enter into CVS Root: &#039;&#039;:pserver:anonymous@us.cvs.moodle.org:/cvsroot/moodle&#039;&#039;&lt;br /&gt;
: (Non-US-residents might use one of the other [https://docs.moodle.org/en/CVS_for_Administrators#CVS_Servers Moodle CVS servers] nearer to them.)&lt;br /&gt;
# Click &#039;&#039;Next&#039;&#039;&lt;br /&gt;
# Browse or enter into &#039;&#039;Module:&#039;&#039; moodle&lt;br /&gt;
# Browse or enter into &#039;&#039;Branch:&#039;&#039; MOODLE_19_STABLE&lt;br /&gt;
# Browse or enter into &#039;&#039;Local Folder:&#039;&#039; C:\xampp\htdocs&lt;br /&gt;
# Click &#039;&#039;Finish&#039;&#039; (and wait a few minutes for Moodle to be checked out)&lt;br /&gt;
# When you get the dialog box &amp;quot;Do you want to create an IDE project from the checked-out sources?&amp;quot;, Click &amp;quot;Create Project...&amp;quot;&lt;br /&gt;
# Select PHP Application with Existing Sources, and click Next&lt;br /&gt;
# Browse or enter into &#039;&#039;Sources Folder&#039;&#039; C:\xampp\htdocs\moodle&lt;br /&gt;
# Enter into &#039;&#039;Project Name:&#039;&#039; moodle&lt;br /&gt;
# Keep the other defaults and click next&lt;br /&gt;
# &#039;&#039;Run As:&#039;&#039; should have selected &#039;&#039;Local Web Site (running on local web server)&#039;&#039;&lt;br /&gt;
# Enter into Project URL http://localhost/moodle/&lt;br /&gt;
# Browse or enter into &#039;&#039;Index File:&#039;&#039; index.php&lt;br /&gt;
# Click &#039;&#039;Finish&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checkout for developers with write access ===&lt;br /&gt;
&lt;br /&gt;
IF you wish to use NetBeans CVS and have CVS write access, the procedure is as follows:&lt;br /&gt;
&lt;br /&gt;
# Follow the above instructions except for point 3&lt;br /&gt;
# At part 3, substitute &#039;&#039;:ext:yourusername&#039;&#039; for the part before the @ and remove the country code from after it, leaving it like this  &#039;&#039;&#039;&#039;&#039;:ext:yourusername&#039;&#039;&#039;@cvs.moodle.org/cvsroot/moodle&#039;&#039;&lt;br /&gt;
# Follow the rest of the instructions as above&lt;br /&gt;
&lt;br /&gt;
If you wish to work with a plugin, you will need to check this out separately and add it to the Moodle code project you have just made. This because for some reason, the &#039;Do you want to create a project&#039; option fails to show any of the files once you open it if you try to check out the plugin on its own (NetBeans 6.7.1 on a Mac).&lt;br /&gt;
&lt;br /&gt;
# Follow the above steps up to point 3, and again substitute &#039;&#039;:ext:yourusername&#039;&#039; and click &#039;next&#039;&lt;br /&gt;
# Click &#039;Browse...&#039; next to the &#039;Module&#039; dialogue&lt;br /&gt;
# Find the plugin you wish to work with in CONTRIB&lt;br /&gt;
# Click &#039;OK&#039;&lt;br /&gt;
# Proceed as before up to point 6, then press &#039;Close&#039; when asked if you want to create a new project.&lt;br /&gt;
# Now navigate to the folder you earlier specified in the &#039;local folder&#039; dialogue and you will find a folder marked &#039;contrib&#039;.&lt;br /&gt;
# navigate to the plugin folder, copy that folder, and then navigate to your main Moodle project folder and paste it where it belongs.&lt;br /&gt;
&lt;br /&gt;
===Adding a branch to your plugin===&lt;br /&gt;
Your plugin will likely start with just a HEAD tag and at some point, you will want to branch it so that you can have versions for different Moodles. To add a MOODLE_20_STABLE branch, for example, do the following.&lt;br /&gt;
&lt;br /&gt;
# Checkout as above, but use the MOODLE_20_STABLE branch instead of MOODLE_19_STABLE&lt;br /&gt;
# You will end up with an empty folder, which you copy into place as above.&lt;br /&gt;
# Find the folder in NetBeans, then right click and choose CVS-&amp;gt;Merge changes from branch...&lt;br /&gt;
# Choose to merge from whatever branch has all the current code, using the help link if not sure what to do.&lt;br /&gt;
&lt;br /&gt;
There is a small chance that the Merge link will not be there, in which case, you will have to copy the files into the directory by hand outside netbeans and then check them in. If you do this, make sure you don&#039;t copy over the &#039;CVS&#039; folders that will have been made when you checked out the MOODLE_19_STABLE code.&lt;br /&gt;
&lt;br /&gt;
=== A few warnings ===&lt;br /&gt;
&lt;br /&gt;
Some of these warnings could also apply to other IDEs:&lt;br /&gt;
&lt;br /&gt;
* If you want to delete a file from your computer but not from CVS, delete it from Windows Explorer/Nautilus/Finder. Otherwise your next commit could delete the file from CVS. &amp;lt;br/&amp;gt;In case you have already deleted a wrong file from NetBeans:  with Windows Explorer/Nautilus/Finder, delete all the folder content of this deleted file (including the CVS folder) and update the folder.&lt;br /&gt;
* If you rename files and that other people are working on them, NetBeans could end up to mess up your CVS folder (even though that is quite rare). Then NetBeans CVS will refuse to update your code displaying a no explicit error as &#039;&#039;&#039;Update Failed&#039;&#039;&#039;. In this case, delete the content of the damaged folder with Windows Explorer/Nautilus/Finder. Then update this folder.&lt;br /&gt;
* If you create a patch or a new PHP file with NetBeans on Microsoft Windows, please check that it&#039;s a Unix format file. You may want to use another software to create Unix format patch/php files.&lt;br /&gt;
&lt;br /&gt;
== Optimization ==&lt;br /&gt;
&lt;br /&gt;
1. You may want to run Netbeans with the Sun JDK. Netbeans seems to work a bit better with the Sun JDK. Download it from  [http://java.sun.com/javase/downloads/index.jsp]. You&#039;ll have to edit Netbeans config file. Open netbeans/etc/netbeans.conf. Then uncomment and edit: &lt;br /&gt;
&lt;br /&gt;
 netbeans_jdkhome=&amp;quot;your_JDK_path&amp;quot;&lt;br /&gt;
&lt;br /&gt;
2. To change the Netbeans look and feel run netbeans in the command line with this parameter:&lt;br /&gt;
 &amp;quot;netbeans&amp;quot;  --laf javax.swing.plaf.metal.MetalLookAndFeel &lt;br /&gt;
&lt;br /&gt;
3. If Netbeans starts to slow down, give it more memory&lt;br /&gt;
 &amp;quot;netbeans&amp;quot; -J-Xmx600m&lt;br /&gt;
See [http://wiki.netbeans.org/FaqSettingHeapSize here] for more details on memory optimisation.&lt;br /&gt;
&lt;br /&gt;
== Coding faster ==&lt;br /&gt;
&lt;br /&gt;
=== Keyboard shortcuts ===&lt;br /&gt;
(Note: Some shortcuts might not work for PHP development.)&lt;br /&gt;
* [http://www.phpmag.ru/2009/01/23/extremely-usefull-netbeans-shortcuts/ Extremely Useful NetBeans Shortcuts] &lt;br /&gt;
* [http://netbeanside61.blogspot.com/2008/04/top-10-netbeans-ide-keyboard-shortcuts.html Top 10 NetBeans IDE Keyboard Shortcuts I use the most]&lt;br /&gt;
* [http://wiki.netbeans.org/KeymapProfileFor60 NetBeans IDE 6.x Keyboard Shortcuts Specification]&lt;br /&gt;
&lt;br /&gt;
=== PHPUnit support ===&lt;br /&gt;
See [http://blogs.sun.com/netbeansphp/entry/recent_improvements_in_phpunit_support &amp;quot;Recent improvements in PHPUnit-support&amp;quot;] on how to use PHPUnit with NetBeans.&lt;br /&gt;
&lt;br /&gt;
== See also: ==&lt;br /&gt;
* Moodle forum: [http://moodle.org/mod/forum/discuss.php?d=112972 NetBeans 6.5 for moodle/PHP/debugging is a better experience v.s Eclipse]&lt;br /&gt;
* [http://www.netbeans.org/kb/trails/php.html NetBeans PHP Learning Trail]&lt;br /&gt;
* [http://wiki.netbeans.org/PHP NetBeans PHP Wiki]&lt;br /&gt;
* Sun&#039;s [http://blogs.sun.com/netbeansphp/ NetBeans PHP Team Blog]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:NetBeans]]&lt;br /&gt;
[[Category:Developer tools|NetBeans]]&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Setting_up_Netbeans&amp;diff=8969</id>
		<title>Setting up Netbeans</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Setting_up_Netbeans&amp;diff=8969"/>
		<updated>2009-11-19T14:31:02Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: Adding a branch to your plugin&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.netbeans.org/features/php/index.html NetBeans] has got a good PHP support. You find a host of information on the website (tutorials, developer blog, screen casts, etc.).&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
* CVS integration: see all changes, lines deletion, diff in real time, show annotations, diff history...&lt;br /&gt;
* Ctrl+Click: Go to declaration&lt;br /&gt;
* Export/Import Diff Patch&lt;br /&gt;
* Easy navigation&lt;br /&gt;
* List of functions&lt;br /&gt;
* Code completion&lt;br /&gt;
* Instant rename&lt;br /&gt;
* HTML, CSS, JavaScript support&lt;br /&gt;
* MySQL manager&lt;br /&gt;
* Quick Search&lt;br /&gt;
* Very few bugs&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
* I recommend downloading the latest [http://www.netbeans.org/downloads/indexB.html 6.7.1 version with PHP support ]. It&#039;s only a 26 MB download.&lt;br /&gt;
* Install and run it.&lt;br /&gt;
&lt;br /&gt;
* There&#039;s also the brand new [http://netbeans.org/community/releases/68/ NetBeans 6.8 Beta release].&lt;br /&gt;
&lt;br /&gt;
== Set up for Moodle development ==&lt;br /&gt;
&lt;br /&gt;
* Checkout your Moodle project with a &#039;&#039;&#039;CVS client&#039;&#039;&#039; - see [[CVS for Administrators]] or [[CVS for developers|CVS for Developers]].&lt;br /&gt;
&lt;br /&gt;
* Open File &amp;gt; New Project &amp;gt; PHP &amp;gt; PHP Application &amp;gt; Next &lt;br /&gt;
: You&#039;re going to set the project now. &#039;&#039;Name&#039;&#039;, &#039;&#039;Location&#039;&#039; and &#039;&#039;Folder&#039;&#039; are used by NetBeans and are not related to the source code. So you can choose whatever you like, except your source folder. &#039;&#039;Sources&#039;&#039; has to be your checked out Moodle branch/head folder. The rest is clear enough. Don&#039;t forget to choose UTF-8 for &#039;&#039;Default Encoding&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
: Example:&lt;br /&gt;
&lt;br /&gt;
 Project Name:        Moodle 1.9 Stable&lt;br /&gt;
 Project Location:    C:\Users\jerome\Documents\NetBeansProjects&lt;br /&gt;
 Project Folder:      C:\Users\jerome\Documents\NetBeansProjects\Moodle 1.9 Stable&lt;br /&gt;
 Project Sources:     C:\Users\jerome\Projects\branch19_STABLE\moodle&lt;br /&gt;
 Project URL:         http://localhost/moodle19/&lt;br /&gt;
 Index File:          index.php&lt;br /&gt;
 Create:              unchecked&lt;br /&gt;
 Default Encoding:    UTF-8&lt;br /&gt;
 Set as Main Project: unchecked&lt;br /&gt;
&lt;br /&gt;
* Click on Finish.&lt;br /&gt;
&lt;br /&gt;
* Start coding!&lt;br /&gt;
&lt;br /&gt;
== CVS with NetBeans ==&lt;br /&gt;
&lt;br /&gt;
NetBeans comes with &#039;&#039;&#039;integrated CVS support&#039;&#039;&#039; which might be the easiest way to check out Moodle.&lt;br /&gt;
&lt;br /&gt;
=== Anonymous checkout ===&lt;br /&gt;
&lt;br /&gt;
# In NetBeans, select Window-&amp;gt;Versioning-&amp;gt;CVS-&amp;gt;Checkout&lt;br /&gt;
# Select Team-&amp;gt;CVS-&amp;gt;Checkout&lt;br /&gt;
# Enter into CVS Root: &#039;&#039;:pserver:anonymous@us.cvs.moodle.org:/cvsroot/moodle&#039;&#039;&lt;br /&gt;
: (Non-US-residents might use one of the other [https://docs.moodle.org/en/CVS_for_Administrators#CVS_Servers Moodle CVS servers] nearer to them.)&lt;br /&gt;
# Click &#039;&#039;Next&#039;&#039;&lt;br /&gt;
# Browse or enter into &#039;&#039;Module:&#039;&#039; moodle&lt;br /&gt;
# Browse or enter into &#039;&#039;Branch:&#039;&#039; MOODLE_19_STABLE&lt;br /&gt;
# Browse or enter into &#039;&#039;Local Folder:&#039;&#039; C:\xampp\htdocs&lt;br /&gt;
# Click &#039;&#039;Finish&#039;&#039; (and wait a few minutes for Moodle to be checked out)&lt;br /&gt;
# When you get the dialog box &amp;quot;Do you want to create an IDE project from the checked-out sources?&amp;quot;, Click &amp;quot;Create Project...&amp;quot;&lt;br /&gt;
# Select PHP Application with Existing Sources, and click Next&lt;br /&gt;
# Browse or enter into &#039;&#039;Sources Folder&#039;&#039; C:\xampp\htdocs\moodle&lt;br /&gt;
# Enter into &#039;&#039;Project Name:&#039;&#039; moodle&lt;br /&gt;
# Keep the other defaults and click next&lt;br /&gt;
# &#039;&#039;Run As:&#039;&#039; should have selected &#039;&#039;Local Web Site (running on local web server)&#039;&#039;&lt;br /&gt;
# Enter into Project URL http://localhost/moodle/&lt;br /&gt;
# Browse or enter into &#039;&#039;Index File:&#039;&#039; index.php&lt;br /&gt;
# Click &#039;&#039;Finish&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Checkout for developers with write access ===&lt;br /&gt;
&lt;br /&gt;
IF you wish to use NetBeans CVS and have CVS write access, the procedure is as follows:&lt;br /&gt;
&lt;br /&gt;
# Follow the above instructions except for point 3&lt;br /&gt;
# At part 3, substitute &#039;&#039;:ext:yourusername&#039;&#039; for the part before the @ and remove the country code from after it, leaving it like this  &#039;&#039;&#039;&#039;&#039;:ext:yourusername&#039;&#039;&#039;@cvs.moodle.org/cvsroot/moodle&#039;&#039;&lt;br /&gt;
# Follow the rest of the instructions as above&lt;br /&gt;
&lt;br /&gt;
If you wish to work with a plugin, you will need to check this out separately and add it to the Moodle code project you have just made. This because for some reason, the &#039;Do you want to create a project&#039; option fails to show any of the files once you open it if you try to check out the plugin on its own (NetBeans 6.7.1 on a Mac).&lt;br /&gt;
&lt;br /&gt;
# Follow the above steps up to point 3, and again substitute &#039;&#039;:ext:yourusername&#039;&#039; and click &#039;next&#039;&lt;br /&gt;
# Click &#039;Browse...&#039; next to the &#039;Module&#039; dialogue&lt;br /&gt;
# Find the plugin you wish to work with in CONTRIB&lt;br /&gt;
# Click &#039;OK&#039;&lt;br /&gt;
# Proceed as before up to point 6, then press &#039;Close&#039; when asked if you want to create a new project.&lt;br /&gt;
# Now navigate to the folder you earlier specified in the &#039;local folder&#039; dialogue and you will find a folder marked &#039;contrib&#039;.&lt;br /&gt;
# navigate to the plugin folder, copy that folder, and then navigate to your main Moodle project folder and paste it where it belongs.&lt;br /&gt;
&lt;br /&gt;
===Adding a branch to your plugin===&lt;br /&gt;
Your plugin will likely start with just a HEAD tag and at some point, you will want to branch it so that you can have versions for different Moodles. To add a MOODLE_20_STABLE branch, for example, do the following.&lt;br /&gt;
&lt;br /&gt;
# Checkout as above, but use the MOODLE_20_STABLE branch instead of MOODLE_19_STABLE&lt;br /&gt;
# You will end up with an empty folder, which you copy into place as above.&lt;br /&gt;
# Find the folder in NetBeans, then right click and choose CVS-&amp;gt;Merge changes from branch...&lt;br /&gt;
# Choose to merge from whatever branch has all the current code, using the help link if not sure what to do.&lt;br /&gt;
&lt;br /&gt;
There is a small chance that the Merge link will not be there, in which case, you will have to copy the files into the directory by hand outside netbeans and then check them in. If you do this, make sure you don&#039;t copy over the &#039;CVS&#039; folders that will have been made when you checked out the MOODLE_19_STABLE code.&lt;br /&gt;
&lt;br /&gt;
=== A few warnings ===&lt;br /&gt;
&lt;br /&gt;
Some of these warnings could also apply to other IDEs:&lt;br /&gt;
&lt;br /&gt;
* If you want to delete a file from your computer but not from CVS, delete it from Windows Explorer/Nautilus/Finder. Otherwise your next commit could delete the file from CVS. &amp;lt;br/&amp;gt;In case you have already deleted a wrong file from NetBeans:  with Windows Explorer/Nautilus/Finder, delete all the folder content of this deleted file (including the CVS folder) and update the folder.&lt;br /&gt;
* If you rename files and that other people are working on them, NetBeans could end up to mess up your CVS folder (even though that is quite rare). Then NetBeans CVS will refuse to update your code displaying a no explicit error as &#039;&#039;&#039;Update Failed&#039;&#039;&#039;. In this case, delete the content of the damaged folder with Windows Explorer/Nautilus/Finder. Then update this folder.&lt;br /&gt;
* If you create a patch or a new PHP file with NetBeans on Microsoft Windows, please check that it&#039;s a Unix format file. You may want to use another software to create Unix format patch/php files.&lt;br /&gt;
&lt;br /&gt;
== Optimization ==&lt;br /&gt;
&lt;br /&gt;
1. You may want to run Netbeans with the Sun JDK. Netbeans seems to work a bit better with the Sun JDK. Download it from  [http://java.sun.com/javase/downloads/index.jsp]. You&#039;ll have to edit Netbeans config file. Open netbeans/etc/netbeans.conf. Then uncomment and edit: &lt;br /&gt;
&lt;br /&gt;
 netbeans_jdkhome=&amp;quot;your_JDK_path&amp;quot;&lt;br /&gt;
&lt;br /&gt;
2. To change the Netbeans look and feel run netbeans in the command line with this parameter:&lt;br /&gt;
 &amp;quot;netbeans&amp;quot;  --laf javax.swing.plaf.metal.MetalLookAndFeel &lt;br /&gt;
&lt;br /&gt;
3. If Netbeans starts to slow down, give it more memory&lt;br /&gt;
 &amp;quot;netbeans&amp;quot; -J-Xmx600m&lt;br /&gt;
&lt;br /&gt;
== Coding faster ==&lt;br /&gt;
&lt;br /&gt;
=== Keyboard shortcuts ===&lt;br /&gt;
(Note: Some shortcuts might not work for PHP development.)&lt;br /&gt;
* [http://www.phpmag.ru/2009/01/23/extremely-usefull-netbeans-shortcuts/ Extremely Useful NetBeans Shortcuts] &lt;br /&gt;
* [http://netbeanside61.blogspot.com/2008/04/top-10-netbeans-ide-keyboard-shortcuts.html Top 10 NetBeans IDE Keyboard Shortcuts I use the most]&lt;br /&gt;
* [http://wiki.netbeans.org/KeymapProfileFor60 NetBeans IDE 6.x Keyboard Shortcuts Specification]&lt;br /&gt;
&lt;br /&gt;
=== PHPUnit support ===&lt;br /&gt;
See [http://blogs.sun.com/netbeansphp/entry/recent_improvements_in_phpunit_support &amp;quot;Recent improvements in PHPUnit-support&amp;quot;] on how to use PHPUnit with NetBeans.&lt;br /&gt;
&lt;br /&gt;
== See also: ==&lt;br /&gt;
* Moodle forum: [http://moodle.org/mod/forum/discuss.php?d=112972 NetBeans 6.5 for moodle/PHP/debugging is a better experience v.s Eclipse]&lt;br /&gt;
* [http://www.netbeans.org/kb/trails/php.html NetBeans PHP Learning Trail]&lt;br /&gt;
* [http://wiki.netbeans.org/PHP NetBeans PHP Wiki]&lt;br /&gt;
* Sun&#039;s [http://blogs.sun.com/netbeansphp/ NetBeans PHP Team Blog]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:NetBeans]]&lt;br /&gt;
[[Category:Developer tools|NetBeans]]&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Setting_up_Netbeans&amp;diff=8963</id>
		<title>Setting up Netbeans</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Setting_up_Netbeans&amp;diff=8963"/>
		<updated>2009-11-10T23:41:19Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* CVS with NetBeans */ Added instructions for developers with write access&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.netbeans.org/features/php/index.html NetBeans] has got a good PHP support. You find a host of information on the website (tutorials, developer blog, screen casts, etc.).&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
* CVS integration: see all changes, lines deletion, diff in real time, show annotations, diff history...&lt;br /&gt;
* Ctrl+Click: Go to declaration&lt;br /&gt;
* Export/Import Diff Patch&lt;br /&gt;
* Easy navigation&lt;br /&gt;
* List of functions&lt;br /&gt;
* Code completion&lt;br /&gt;
* Instant rename&lt;br /&gt;
* HTML, CSS, JavaScript support&lt;br /&gt;
* MySQL manager&lt;br /&gt;
* Quick Search&lt;br /&gt;
* Very few bugs&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
* I recommend downloading the latest [http://www.netbeans.org/downloads/indexB.html 6.7.1 version with PHP support ]. It&#039;s only a 26 MB download.&lt;br /&gt;
* Install and run it.&lt;br /&gt;
&lt;br /&gt;
== Set up for Moodle development ==&lt;br /&gt;
&lt;br /&gt;
* Checkout your Moodle project with a &#039;&#039;&#039;CVS client&#039;&#039;&#039; - see [[CVS for Administrators]] or [[CVS for developers|CVS for Developers]].&lt;br /&gt;
&lt;br /&gt;
* Open File &amp;gt; New Project &amp;gt; PHP &amp;gt; PHP Application &amp;gt; Next &lt;br /&gt;
: You&#039;re going to set the project now. &#039;&#039;Name&#039;&#039;, &#039;&#039;Location&#039;&#039; and &#039;&#039;Folder&#039;&#039; are used by NetBeans and are not related to the source code. So you can choose whatever you like, except your source folder. &#039;&#039;Sources&#039;&#039; has to be your checked out Moodle branch/head folder. The rest is clear enough. Don&#039;t forget to choose UTF-8 for &#039;&#039;Default Encoding&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
: Example:&lt;br /&gt;
&lt;br /&gt;
 Project Name:        Moodle 1.9 Stable&lt;br /&gt;
 Project Location:    C:\Users\jerome\Documents\NetBeansProjects&lt;br /&gt;
 Project Folder:      C:\Users\jerome\Documents\NetBeansProjects\Moodle 1.9 Stable&lt;br /&gt;
 Project Sources:     C:\Users\jerome\Projects\branch19_STABLE\moodle&lt;br /&gt;
 Project URL:         http://localhost/moodle19/&lt;br /&gt;
 Index File:          index.php&lt;br /&gt;
 Create:              unchecked&lt;br /&gt;
 Default Encoding:    UTF-8&lt;br /&gt;
 Set as Main Project: unchecked&lt;br /&gt;
&lt;br /&gt;
* Click on Finish.&lt;br /&gt;
&lt;br /&gt;
* Start coding!&lt;br /&gt;
&lt;br /&gt;
== CVS with NetBeans ==&lt;br /&gt;
&lt;br /&gt;
NetBeans comes with &#039;&#039;&#039;integrated CVS support&#039;&#039;&#039; which might be the easiest way to check out Moodle.&lt;br /&gt;
&lt;br /&gt;
# In NetBeans, select Window-&amp;gt;Versioning-&amp;gt;CVS-&amp;gt;Checkout&lt;br /&gt;
# Select Team-&amp;gt;CVS-&amp;gt;Checkout&lt;br /&gt;
# Enter into CVS Root: &#039;&#039;:pserver:anonymous@us.cvs.moodle.org:/cvsroot/moodle&#039;&#039;&lt;br /&gt;
: (Non-US-residents might use one of the other [https://docs.moodle.org/en/CVS_for_Administrators#CVS_Servers Moodle CVS servers] nearer to them.)&lt;br /&gt;
# Click &#039;&#039;Next&#039;&#039;&lt;br /&gt;
# Browse or enter into &#039;&#039;Module:&#039;&#039; moodle&lt;br /&gt;
# Browse or enter into &#039;&#039;Branch:&#039;&#039; MOODLE_19_STABLE&lt;br /&gt;
# Browse or enter into &#039;&#039;Local Folder:&#039;&#039; C:\xampp\htdocs&lt;br /&gt;
# Click &#039;&#039;Finish&#039;&#039; (and wait a few minutes for Moodle to be checked out)&lt;br /&gt;
# When you get the dialog box &amp;quot;Do you want to create an IDE project from the checked-out sources?&amp;quot;, Click &amp;quot;Create Project...&amp;quot;&lt;br /&gt;
# Select PHP Application with Existing Sources, and click Next&lt;br /&gt;
# Browse or enter into &#039;&#039;Sources Folder&#039;&#039; C:\xampp\htdocs\moodle&lt;br /&gt;
# Enter into &#039;&#039;Project Name:&#039;&#039; moodle&lt;br /&gt;
# Keep the other defaults and click next&lt;br /&gt;
# &#039;&#039;Run As:&#039;&#039; should have selected &#039;&#039;Local Web Site (running on local web server)&#039;&#039;&lt;br /&gt;
# Enter into Project URL http://localhost/moodle/&lt;br /&gt;
# Browse or enter into &#039;&#039;Index File:&#039;&#039; index.php&lt;br /&gt;
# Click &#039;&#039;Finish&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
IF you wish to use Netbeans CVS and have CVS write access, the procedure is as follows:&lt;br /&gt;
&lt;br /&gt;
# Follow the above instructions except for point 3&lt;br /&gt;
# At part 3, substitute :ext:yourusername for the part before the @ and remove the country code from after it, leaving it like this  :ext:yourusername@cvs.moodle.org/cvsroot/moodle&lt;br /&gt;
# Follow the rest of the instructions as above&lt;br /&gt;
&lt;br /&gt;
If you wish to work with a plugin, you will need to check this out separately and add it to the Moodle code project you have just made. This because for some reason, the &#039;Do you want to create a project&#039; option fails to show any of the files once you open it if you try to check out the plugin on its own (Netbeans 6.7.1 on a mac).&lt;br /&gt;
&lt;br /&gt;
# Follow the above steps up to point 3, and again substitute :ext:yourusername and click &#039;next&#039;&lt;br /&gt;
# Click &#039;Browse...&#039; next to the &#039;Module&#039; dialogue&lt;br /&gt;
# Find the plugin you wish to work with in CONTRIB&lt;br /&gt;
# Click &#039;OK&#039;&lt;br /&gt;
# Proceed as before up to point 6, then press &#039;Close&#039; when asked if you want to create a new project.&lt;br /&gt;
# Now navigate to the folder you earlier specified in the &#039;local folder&#039; dialogue and you will find a folder marked &#039;contrib&#039;.&lt;br /&gt;
# navigate to the plugin folder, copy that folder, and then navigate to your main Moodle project folder and paste it where it belongs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Few warnings ===&lt;br /&gt;
Some of these warnings could also apply to other IDE:&lt;br /&gt;
* If you want to delete a file from your computer but not from CVS, delete it from Windows Explorer/Nautilus/Finder. Otherwise your next commit could delete the file from CVS. &amp;lt;br/&amp;gt;In case you have already deleted a wrong file from Netbeans:  with Windows Explorer/Nautilus/Finder, delete all the folder content of this deleted file (including the CVS folder) and update the folder.&lt;br /&gt;
* If you rename files and that other people are working on them, Netbeans could end up to mess up your CVS folder (even though that is quite rare). Then Netbeans CVS will refuse to update your code displaying a no explicit error as &#039;&#039;&#039;Update Failed&#039;&#039;&#039;. In this case, delete the content of the damaged folder with Windows Explorer/Nautilus/Finder. Then update this folder.&lt;br /&gt;
* If you create a patch or a new php file with Netbeans on Microsoft Windows, please check that it&#039;s a Unix format file. You may want to use another software to create Unix format patch/php file.&lt;br /&gt;
&lt;br /&gt;
== Optimization ==&lt;br /&gt;
&lt;br /&gt;
1. You may want to run Netbeans with the Sun JDK. Netbeans seems to work a bit better with the Sun JDK. Download it from  [http://java.sun.com/javase/downloads/index.jsp]. You&#039;ll have to edit Netbeans config file. Open netbeans/etc/netbeans.conf. Then uncomment and edit: &lt;br /&gt;
&lt;br /&gt;
 netbeans_jdkhome=&amp;quot;your_JDK_path&amp;quot;&lt;br /&gt;
&lt;br /&gt;
2. To change the Netbeans look and feel run netbeans in the command line with this parameter:&lt;br /&gt;
 &amp;quot;netbeans&amp;quot;  --laf javax.swing.plaf.metal.MetalLookAndFeel &lt;br /&gt;
&lt;br /&gt;
3. If Netbeans starts to slow down, give it more memory&lt;br /&gt;
 &amp;quot;netbeans&amp;quot; -J-Xmx600m&lt;br /&gt;
&lt;br /&gt;
== Coding faster ==&lt;br /&gt;
&lt;br /&gt;
=== Keyboard shortcuts ===&lt;br /&gt;
(Note: Some shortcuts might not work for PHP development.)&lt;br /&gt;
* [http://www.phpmag.ru/2009/01/23/extremely-usefull-netbeans-shortcuts/ Extremely Useful NetBeans Shortcuts] &lt;br /&gt;
* [http://netbeanside61.blogspot.com/2008/04/top-10-netbeans-ide-keyboard-shortcuts.html Top 10 NetBeans IDE Keyboard Shortcuts I use the most]&lt;br /&gt;
* [http://wiki.netbeans.org/KeymapProfileFor60 NetBeans IDE 6.x Keyboard Shortcuts Specification]&lt;br /&gt;
&lt;br /&gt;
== See also: ==&lt;br /&gt;
* Moodle forum: [http://moodle.org/mod/forum/discuss.php?d=112972 NetBeans 6.5 for moodle/PHP/debugging is a better experience v.s Eclipse]&lt;br /&gt;
* [http://www.netbeans.org/kb/trails/php.html NetBeans PHP Learning Trail]&lt;br /&gt;
* [http://wiki.netbeans.org/PHP NetBeans PHP Wiki]&lt;br /&gt;
* Sun&#039;s [http://blogs.sun.com/netbeansphp/ NetBeans PHP Team Blog]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:NetBeans]]&lt;br /&gt;
[[Category:Developer tools|NetBeans]]&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Setting_up_Netbeans&amp;diff=8962</id>
		<title>Setting up Netbeans</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Setting_up_Netbeans&amp;diff=8962"/>
		<updated>2009-11-06T12:48:03Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: small typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.netbeans.org/features/php/index.html NetBeans] has got a good PHP support. You find a host of information on the website (tutorials, developer blog, screen casts, etc.).&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
* CVS integration: see all changes, lines deletion, diff in real time, show annotations, diff history...&lt;br /&gt;
* Ctrl+Click: Go to declaration&lt;br /&gt;
* Export/Import Diff Patch&lt;br /&gt;
* Easy navigation&lt;br /&gt;
* List of functions&lt;br /&gt;
* Code completion&lt;br /&gt;
* Instant rename&lt;br /&gt;
* HTML, CSS, JavaScript support&lt;br /&gt;
* MySQL manager&lt;br /&gt;
* Quick Search&lt;br /&gt;
* Very few bugs&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
* I recommend downloading the latest [http://www.netbeans.org/downloads/indexB.html 6.7.1 version with PHP support ]. It&#039;s only a 26 MB download.&lt;br /&gt;
* Install and run it.&lt;br /&gt;
&lt;br /&gt;
== Set up for Moodle development ==&lt;br /&gt;
&lt;br /&gt;
* Checkout your Moodle project with a &#039;&#039;&#039;CVS client&#039;&#039;&#039; - see [[CVS for Administrators]] or [[CVS for developers|CVS for Developers]].&lt;br /&gt;
&lt;br /&gt;
* Open File &amp;gt; New Project &amp;gt; PHP &amp;gt; PHP Application &amp;gt; Next &lt;br /&gt;
: You&#039;re going to set the project now. &#039;&#039;Name&#039;&#039;, &#039;&#039;Location&#039;&#039; and &#039;&#039;Folder&#039;&#039; are used by NetBeans and are not related to the source code. So you can choose whatever you like, except your source folder. &#039;&#039;Sources&#039;&#039; has to be your checked out Moodle branch/head folder. The rest is clear enough. Don&#039;t forget to choose UTF-8 for &#039;&#039;Default Encoding&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
: Example:&lt;br /&gt;
&lt;br /&gt;
 Project Name:        Moodle 1.9 Stable&lt;br /&gt;
 Project Location:    C:\Users\jerome\Documents\NetBeansProjects&lt;br /&gt;
 Project Folder:      C:\Users\jerome\Documents\NetBeansProjects\Moodle 1.9 Stable&lt;br /&gt;
 Project Sources:     C:\Users\jerome\Projects\branch19_STABLE\moodle&lt;br /&gt;
 Project URL:         http://localhost/moodle19/&lt;br /&gt;
 Index File:          index.php&lt;br /&gt;
 Create:              unchecked&lt;br /&gt;
 Default Encoding:    UTF-8&lt;br /&gt;
 Set as Main Project: unchecked&lt;br /&gt;
&lt;br /&gt;
* Click on Finish.&lt;br /&gt;
&lt;br /&gt;
* Start coding!&lt;br /&gt;
&lt;br /&gt;
== CVS with NetBeans ==&lt;br /&gt;
&lt;br /&gt;
NetBeans comes with &#039;&#039;&#039;integrated CVS support&#039;&#039;&#039; which might be the easiest way to check out Moodle.&lt;br /&gt;
&lt;br /&gt;
* In NetBeans, select Window-&amp;gt;Versioning-&amp;gt;CVS-&amp;gt;Checkout&lt;br /&gt;
* Select Team-&amp;gt;CVS-&amp;gt;Checkout&lt;br /&gt;
* Enter into CVS Root: &#039;&#039;:pserver:anonymous@us.cvs.moodle.org:/cvsroot/moodle&#039;&#039;&lt;br /&gt;
: (Non-US-residents might use one of the other [https://docs.moodle.org/en/CVS_for_Administrators#CVS_Servers Moodle CVS servers] nearer to them.)&lt;br /&gt;
* Click &#039;&#039;Next&#039;&#039;&lt;br /&gt;
* Browse or enter into &#039;&#039;Module:&#039;&#039; moodle&lt;br /&gt;
* Browse or enter into &#039;&#039;Branch:&#039;&#039; MOODLE_19_STABLE&lt;br /&gt;
* Browse or enter into &#039;&#039;Local Folder:&#039;&#039; C:\xampp\htdocs&lt;br /&gt;
* Click &#039;&#039;Finish&#039;&#039; (and wait a few minutes for Moodle to be checked out)&lt;br /&gt;
* When you get the dialog box &amp;quot;Do you want to create an IDE project from the checked-out sources?&amp;quot;, Click &amp;quot;Create Project...&amp;quot;&lt;br /&gt;
* Select PHP Application with Existing Sources, and click Next&lt;br /&gt;
* Browse or enter into &#039;&#039;Sources Folder&#039;&#039; C:\xampp\htdocs\moodle&lt;br /&gt;
* Enter into &#039;&#039;Project Name:&#039;&#039; moodle&lt;br /&gt;
* Keep the other defaults and click next&lt;br /&gt;
* &#039;&#039;Run As:&#039;&#039; should have selected &#039;&#039;Local Web Site (running on local web server)&#039;&#039;&lt;br /&gt;
* Enter into Project URL http://localhost/moodle/&lt;br /&gt;
* Browse or enter into &#039;&#039;Index File:&#039;&#039; index.php&lt;br /&gt;
* Click &#039;&#039;Finish&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Few warnings ===&lt;br /&gt;
Some of these warnings could also apply to other IDE:&lt;br /&gt;
* If you want to delete a file from your computer but not from CVS, delete it from Windows Explorer/Nautilus/Finder. Otherwise your next commit could delete the file from CVS. &amp;lt;br/&amp;gt;In case you have already deleted a wrong file from Netbeans:  with Windows Explorer/Nautilus/Finder, delete all the folder content of this deleted file (including the CVS folder) and update the folder.&lt;br /&gt;
* If you rename files and that other people are working on them, Netbeans could end up to mess up your CVS folder (even though that is quite rare). Then Netbeans CVS will refuse to update your code displaying a no explicit error as &#039;&#039;&#039;Update Failed&#039;&#039;&#039;. In this case, delete the content of the damaged folder with Windows Explorer/Nautilus/Finder. Then update this folder.&lt;br /&gt;
* If you create a patch or a new php file with Netbeans on Microsoft Windows, please check that it&#039;s a Unix format file. You may want to use another software to create Unix format patch/php file.&lt;br /&gt;
&lt;br /&gt;
== Optimization ==&lt;br /&gt;
&lt;br /&gt;
1. You may want to run Netbeans with the Sun JDK. Netbeans seems to work a bit better with the Sun JDK. Download it from  [http://java.sun.com/javase/downloads/index.jsp]. You&#039;ll have to edit Netbeans config file. Open netbeans/etc/netbeans.conf. Then uncomment and edit: &lt;br /&gt;
&lt;br /&gt;
 netbeans_jdkhome=&amp;quot;your_JDK_path&amp;quot;&lt;br /&gt;
&lt;br /&gt;
2. To change the Netbeans look and feel run netbeans in the command line with this parameter:&lt;br /&gt;
 &amp;quot;netbeans&amp;quot;  --laf javax.swing.plaf.metal.MetalLookAndFeel &lt;br /&gt;
&lt;br /&gt;
3. If Netbeans starts to slow down, give it more memory&lt;br /&gt;
 &amp;quot;netbeans&amp;quot; -J-Xmx600m&lt;br /&gt;
&lt;br /&gt;
== Coding faster ==&lt;br /&gt;
&lt;br /&gt;
=== Keyboard shortcuts ===&lt;br /&gt;
(Note: Some shortcuts might not work for PHP development.)&lt;br /&gt;
* [http://www.phpmag.ru/2009/01/23/extremely-usefull-netbeans-shortcuts/ Extremely Useful NetBeans Shortcuts] &lt;br /&gt;
* [http://netbeanside61.blogspot.com/2008/04/top-10-netbeans-ide-keyboard-shortcuts.html Top 10 NetBeans IDE Keyboard Shortcuts I use the most]&lt;br /&gt;
* [http://wiki.netbeans.org/KeymapProfileFor60 NetBeans IDE 6.x Keyboard Shortcuts Specification]&lt;br /&gt;
&lt;br /&gt;
== See also: ==&lt;br /&gt;
* Moodle forum: [http://moodle.org/mod/forum/discuss.php?d=112972 NetBeans 6.5 for moodle/PHP/debugging is a better experience v.s Eclipse]&lt;br /&gt;
* [http://www.netbeans.org/kb/trails/php.html NetBeans PHP Learning Trail]&lt;br /&gt;
* [http://wiki.netbeans.org/PHP NetBeans PHP Wiki]&lt;br /&gt;
* Sun&#039;s [http://blogs.sun.com/netbeansphp/ NetBeans PHP Team Blog]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:NetBeans]]&lt;br /&gt;
[[Category:Developer tools|NetBeans]]&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Talk:Community_hub&amp;diff=27026</id>
		<title>Talk:Community hub</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Talk:Community_hub&amp;diff=27026"/>
		<updated>2009-07-06T11:37:01Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Regarding the course import for teachers to start from...&lt;br /&gt;
I can envisage a situation whereby the original course author finds new information/ideas and adds stuff to the master course after the teacher has downloaded it, which in the current model would not make it to the teacher as the download is a one off process which they will not repeat. I would prefer a model whereby a course can act as a master template which gets updated regularly so that new questions, resources, activities etc appear dynamically as hidden items within the teacher&#039;s downloaded course, ready to be reviewed and revealed if needed. This would be like maintaining your Moodle install using CVS - you get updates all the time as they are created. &lt;br /&gt;
&lt;br /&gt;
It would also be good to be able to track how many people are using a particular course and to have some sort of meta-forum for discussing changes and developemts. Many teachers will end up using the successful/well designed courses, so it would make a lot of sense to have a way of pooling their shared experience and getting that feedback back to the original creator. -- [[User:Matt Gibson|Matt Gibson]] 18:51, 25 June 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Harvesting courses regularly and a few other  comments ==&lt;br /&gt;
&lt;br /&gt;
I&#039;ve put this in the forum, but I&#039;ll say it here as well.  If a site has a lot of courses to share with a hub, perhaps because they are an OpenCourseWare provider, they might prefer to supply an RSS or OAI list rather than click &amp;quot;publish&amp;quot; on each individual course.  OCW Consortium members are already encouraged to offer an RSS feed (with DC metadata) of all their courses that is picked up by a number of OCW search tools.  I&#039;m sure Moodle users in that community would love the same approach to mean they could be included in the hubs as well.&lt;br /&gt;
&lt;br /&gt;
To aid course harvesting (but to make publishing easier anyway) I&#039;d like to see the DC metadata editing screen become part of the standard course settings screen, and the data pulled from here as part of the publish to hub functionality (and into any RSS or OAI service).&lt;br /&gt;
&lt;br /&gt;
Using LOM as well as (or instead of) DC would allow more flexible searching at the hub with relatively little extra cost of data inputting.  &lt;br /&gt;
&lt;br /&gt;
Finally, there is a great deal of discussion in the OCW community about asset-level re-use.  Anecdotal evidence from teachers suggests that the course-level is not fine-grained enough and they&#039;d prefer to pick a single resource/image/activity.  See http://opencontent.org/blog/archives/900 and related comments for example.  So I&#039;d like to see DC metadata added to resources and modules too, and the searching and import/export/enrol facility in the hub system work at this level also.&lt;br /&gt;
-- [[User:Jenny Gray|Jenny Gray]] 14:48, 30 June 2009 (GMT)&lt;br /&gt;
&lt;br /&gt;
I second the points Jenny made above. I can&#039;t see much call for importing a whole course, as it will be too much hassle to integrate with current stuff. Ideally, single activities and resources can be copied at once from a remote course. This is already possible within a single site using the contributed sharing cart block, and if this could be brought into core and made to work across sites, it would be a killer app. &lt;br /&gt;
&lt;br /&gt;
If that gets done, it brings up an issue of copyright - some courses will have things that are only licenced for site use and cannot be shared. If there was a switch that would set the item to &#039;can&#039;t copy/view over mnet&#039;, then it would be possible to allow access to courses with commercial resources and only share the parts which a teacher has made themselves.&lt;br /&gt;
&lt;br /&gt;
For me, this use case would be an absolute killer app and would make collaboration a breeze across whole countries at a time. -- [[User:Matt Gibson|Matt Gibson]] 11:37, 6 July 2009 (UTC)&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Talk:Community_hub&amp;diff=27023</id>
		<title>Talk:Community hub</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Talk:Community_hub&amp;diff=27023"/>
		<updated>2009-06-25T18:55:09Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Regarding the course import for teachers to start from...&lt;br /&gt;
I can envisage a situation whereby the original course author finds new information/ideas and adds stuff to the master course after the teacher has downloaded it, which in the current model would not make it to the teacher as the download is a one off process which they will not repeat. I would prefer a model whereby a course can act as a master template which gets updated regularly so that new questions, resources, activities etc appear dynamically as hidden items within the teacher&#039;s downloaded course, ready to be reviewed and revealed if needed. This would be like maintaining your Moodle install using CVS - you get updates all the time as they are created. &lt;br /&gt;
&lt;br /&gt;
It would also be good to be able to track how many people are using a particular course and to have some sort of meta-forum for discussing changes and developemts. Many teachers will end up using the successful/well designed courses, so it would make a lot of sense to have a way of pooling their shared experience and getting that feedback back to the original creator. -- [[User:Matt Gibson|Matt Gibson]] 18:51, 25 June 2009 (UTC)&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Talk:Community_hub&amp;diff=27022</id>
		<title>Talk:Community hub</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Talk:Community_hub&amp;diff=27022"/>
		<updated>2009-06-25T18:54:54Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Regarding the course import for teachers to start from...&lt;br /&gt;
I can envisage a situation whereby the original course author finds new information/ideas and adds stuff to the master course after the teacher has downloaded it, which in the current model would not make it to the teacher as the download is a one off process which they will not repeat. I would prefer a model whereby a course can act as a master template which gets updated regularly so that new questions, resources, activities etc appear dynamically as hidden items within the teacher&#039;s downloaded course, ready to be reviewed and revealed if needed. This would be like maintaining your Moodle install using CVS - you get updates all the time as they are created. &lt;br /&gt;
&lt;br /&gt;
It would also be good to be able to track how many people are using a particular course and to have some sort of meta-forum for discussing changes and developemts. Many teachers will end up using the successful/well designed courses, so it would make a lot of sense to have a way of pooling their shared experience and getting that feedback back to the original creator.[[User:Matt Gibson|Matt Gibson]] 18:51, 25 June 2009 (UTC)&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Talk:Community_hub&amp;diff=27021</id>
		<title>Talk:Community hub</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Talk:Community_hub&amp;diff=27021"/>
		<updated>2009-06-25T18:51:26Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Regarding the course import for teachers to start from...&lt;br /&gt;
I can envisage a situation whereby the original course author finds new information/ideas and adds stuff to the master course after the teacher has downloaded it, which in the current model would not make it to the teacher as the download is a one off process which they will not repeat. I would prefer a model whereby a course can act as a master template which gets updated regularly so that new questions, resources, activities etc appear dynamically as hidden items within the teacher&#039;s downloaded course, ready to be reviewed and revealed if needed. [[User:Matt Gibson|Matt Gibson]] 18:51, 25 June 2009 (UTC)&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Old_Events_API&amp;diff=6556</id>
		<title>Old Events API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Old_Events_API&amp;diff=6556"/>
		<updated>2009-05-26T11:27:26Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 1.9}}&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The Events API is a core system in Moodle to allow communication between modules.  &lt;br /&gt;
&lt;br /&gt;
An &#039;&#039;&#039;event&#039;&#039;&#039; is when something &amp;quot;interesting&amp;quot; happens in Moodle that is worth alerting the system about.&lt;br /&gt;
&lt;br /&gt;
Any Moodle modules can &#039;&#039;&#039;trigger&#039;&#039;&#039; new events (with attached data), and other modules can elect to &#039;&#039;&#039;handle&#039;&#039;&#039; those events with custom functions that operate on the given data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
Let&#039;s look at an example of how events are used to implement Messaging in Moodle 2.0.  In the messaging system, textual messages are generated for users by different modules, and the user can decide how certain types of messages are displayed.&lt;br /&gt;
&lt;br /&gt;
===Triggering an event===&lt;br /&gt;
&lt;br /&gt;
When a messaging event occurs, the module should trigger a &amp;quot;message_send&amp;quot; event.   In this example let&#039;s pretend someone just posted to a forum.&lt;br /&gt;
&lt;br /&gt;
The forum module needs to create an object with the data that this event needs.  This may vary completely for different types of events, it&#039;s just a data object.&lt;br /&gt;
&lt;br /&gt;
 $eventdata = new object();&lt;br /&gt;
 $eventdata-&amp;gt;component         = &#039;mod/forum&#039;;    // path in Moodle&lt;br /&gt;
 $eventdata-&amp;gt;name              = &#039;posts&#039;;        // type of message from that module (as module defines it)&lt;br /&gt;
 $eventdata-&amp;gt;userfrom          = $userfrom;      // user object&lt;br /&gt;
 $eventdata-&amp;gt;userto            = $userto;        // user object&lt;br /&gt;
 $eventdata-&amp;gt;subject           = &amp;quot;Hi there&amp;quot;;     // short one-line subject&lt;br /&gt;
 $eventdata-&amp;gt;fullmessage       = &amp;quot;Here is the full message&amp;quot;;      // raw text&lt;br /&gt;
 $eventdata-&amp;gt;fullmessageformat = FORMAT_PLAIN;   // text format&lt;br /&gt;
 $eventdata-&amp;gt;fullmessagehtml   = &amp;quot;Here is the &amp;amp;lt;b&amp;gt;full&amp;amp;lt;/b&amp;gt; message&amp;quot;;    // html rendered version   (optional)&lt;br /&gt;
 $eventdata-&amp;gt;smallmessage      = &amp;quot;Here is the truncated message&amp;quot;;      // useful for plugins like sms or twitter  (optional)&lt;br /&gt;
&lt;br /&gt;
Then we post the object as an event and forget about it:&lt;br /&gt;
&lt;br /&gt;
 events_trigger(&#039;message_send&#039;, $eventdata);&lt;br /&gt;
&lt;br /&gt;
===Handling an event===&lt;br /&gt;
&lt;br /&gt;
Modules or core code can define an events.php in the db directory which defines events they want to be notified about, and describes which of their functions or class methods should be notified.  For this case, there is this definition of a handler in lib/db/events.php&lt;br /&gt;
&lt;br /&gt;
 $handlers = array (&lt;br /&gt;
     &#039;message_send&#039; =&amp;gt; array (&lt;br /&gt;
          &#039;handlerfile&#039;      =&amp;gt; &#039;/lib/messagelib.php&#039;,&lt;br /&gt;
          &#039;handlerfunction&#039;  =&amp;gt; &#039;message_send_handler&#039;,&lt;br /&gt;
          &#039;schedule&#039;         =&amp;gt; &#039;instant&#039;&lt;br /&gt;
      )&lt;br /&gt;
 );&lt;br /&gt;
&lt;br /&gt;
These events.php files are parsed during install / upgrade and stored in a simple database table.&lt;br /&gt;
&lt;br /&gt;
Now, when a &#039;&#039;&#039;message_send&#039;&#039;&#039; event happens, all the registered handlers functions for that event will be called something like this (but with more error handling):&lt;br /&gt;
&lt;br /&gt;
          include_once($CFG-&amp;gt;dirroot.$handlers[&#039;message_send&#039;][&#039;handlerfile&#039;]);&lt;br /&gt;
          call_user_func($handlers[&#039;message_send&#039;][&#039;handlerfunction&#039;], $eventdata);&lt;br /&gt;
&lt;br /&gt;
Any code can hook into any events this way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Database structure==&lt;br /&gt;
&lt;br /&gt;
There are 3 core tables for events. Note that if a handler is queued, and yet to be processed or processing failed, then all subsequent calls on that handler must be queued.&lt;br /&gt;
&lt;br /&gt;
===events_handlers===&lt;br /&gt;
&lt;br /&gt;
This table is for storing which components requests what type of event, and the location of the responsible handler functions.&lt;br /&gt;
&lt;br /&gt;
These entries are created by parsing events.php files in all the modules, and can be rebuilt any time (during an upgrade, say).&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Info&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
|int(10)&lt;br /&gt;
|auto increment identifier&lt;br /&gt;
|-&lt;br /&gt;
|eventname&lt;br /&gt;
|varchar(255)&lt;br /&gt;
|name of the event, e.g. &#039;message_send&#039;&lt;br /&gt;
|-&lt;br /&gt;
|handlermodule&lt;br /&gt;
|varchar(255)&lt;br /&gt;
|e.g. moodle, mod/forum, block/rss_client&lt;br /&gt;
|-&lt;br /&gt;
|handlerfile&lt;br /&gt;
|varchar(255)&lt;br /&gt;
|path to the file of the function, eg /lib/messagelib.php&lt;br /&gt;
|-&lt;br /&gt;
|handlerfunction&lt;br /&gt;
|text&lt;br /&gt;
|serialized string or array describing function, suitable to be passed to &#039;&#039;&#039;call_user_func()&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|schedule 	&lt;br /&gt;
|varchar(255) 	&lt;br /&gt;
|&#039;cron&#039; or &#039;instant&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|status&lt;br /&gt;
|int(10)&lt;br /&gt;
|number of failed attempts to process this handler&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===events_queue===&lt;br /&gt;
&lt;br /&gt;
This table is for storing queued events. It stores only one copy of the eventdata here, and entries from this table are being references by the events_queue_handlers table.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Info&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
|int(10)&lt;br /&gt;
|auto increment identifier&lt;br /&gt;
|-&lt;br /&gt;
|eventdata 	&lt;br /&gt;
|longtext 	&lt;br /&gt;
|serialized version of the data object passed to the event handler.&lt;br /&gt;
|-&lt;br /&gt;
|stackdump&lt;br /&gt;
|text&lt;br /&gt;
|serialized debug_backtrace showing where the event was fired from&lt;br /&gt;
|-&lt;br /&gt;
|userid&lt;br /&gt;
|int(10)&lt;br /&gt;
|$USER-&amp;gt;id when the event was fired&lt;br /&gt;
|-&lt;br /&gt;
|timecreated&lt;br /&gt;
|int(10) 	&lt;br /&gt;
|time stamp of the first time this was added&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===events_queue_handlers===&lt;br /&gt;
&lt;br /&gt;
This is the list of queued handlers for processing. The event object is retrieved from the events_queue table. When no further reference is made to the events_queue table, the corresponding entry in the events_queue table should be deleted. Entry should get deleted (?) after a successful event processing by the specified handler.  The status field keeps track of failures, after it gets to a certain number (eg 10?) it should trigger an &amp;quot;event failed&amp;quot; event (that could result in admin being emailed etc, or perhaps even the originating module taking care of it or rolling something back etc).&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Info&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
|id&lt;br /&gt;
|int(10)&lt;br /&gt;
|auto increment identifier&lt;br /&gt;
|-&lt;br /&gt;
|queuedeventid&lt;br /&gt;
|int(10)&lt;br /&gt;
|foreign key id corresponding to the id of the event_queues table&lt;br /&gt;
|-&lt;br /&gt;
|handlerid&lt;br /&gt;
|int(10)&lt;br /&gt;
|foreign key id corresponding to the id of the event_handlers table&lt;br /&gt;
|-&lt;br /&gt;
|status&lt;br /&gt;
|int(10)&lt;br /&gt;
|number of failed attempts to process this handler&lt;br /&gt;
|-&lt;br /&gt;
|errormessage&lt;br /&gt;
|text&lt;br /&gt;
|if an error happened last time we tried to process this event, record it here.&lt;br /&gt;
|-&lt;br /&gt;
|timemodified&lt;br /&gt;
|int(10)&lt;br /&gt;
|time stamp of the last attempt to run this from the queue&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Standards for naming events==&lt;br /&gt;
&lt;br /&gt;
All event names should follow a consistent naming pattern, such as modulename_noun_verb&lt;br /&gt;
&lt;br /&gt;
==Events which exist==&lt;br /&gt;
&lt;br /&gt;
When we add new events to core we should always add them here too.&lt;br /&gt;
&lt;br /&gt;
Under each event, list the data sent as part of the event.&lt;br /&gt;
&lt;br /&gt;
===Users===&lt;br /&gt;
* user_created&lt;br /&gt;
** full new record from &#039;user&#039; table&lt;br /&gt;
* user_updated&lt;br /&gt;
** full new record from &#039;user&#039; table&lt;br /&gt;
&lt;br /&gt;
===Courses===&lt;br /&gt;
* course_created&lt;br /&gt;
** full course record&lt;br /&gt;
* course_updated&lt;br /&gt;
** full course record&lt;br /&gt;
* course_deleted&lt;br /&gt;
** full course record&lt;br /&gt;
* course_category_deleted&lt;br /&gt;
** full category record&lt;br /&gt;
&lt;br /&gt;
===Groups===&lt;br /&gt;
* groups_member_added&lt;br /&gt;
** groupid&lt;br /&gt;
** userid&lt;br /&gt;
* groups_member_removed&lt;br /&gt;
** groupid&lt;br /&gt;
** userid&lt;br /&gt;
* groups_group_created&lt;br /&gt;
** id&lt;br /&gt;
** courseid&lt;br /&gt;
** name&lt;br /&gt;
** description&lt;br /&gt;
** timecreated&lt;br /&gt;
** timemodified&lt;br /&gt;
** picture&lt;br /&gt;
* groups_group_updated&lt;br /&gt;
** id&lt;br /&gt;
** courseid&lt;br /&gt;
** name&lt;br /&gt;
** description&lt;br /&gt;
** timecreated&lt;br /&gt;
** timemodified&lt;br /&gt;
** picture&lt;br /&gt;
* groups_group_deleted&lt;br /&gt;
** id&lt;br /&gt;
** courseid&lt;br /&gt;
** name&lt;br /&gt;
** description&lt;br /&gt;
** timecreated&lt;br /&gt;
** timemodified&lt;br /&gt;
** picture&lt;br /&gt;
* groups_grouping_created&lt;br /&gt;
** id&lt;br /&gt;
** courseid&lt;br /&gt;
** name&lt;br /&gt;
** timecreated&lt;br /&gt;
** timemodified&lt;br /&gt;
* groups_grouping_updated&lt;br /&gt;
** id&lt;br /&gt;
** courseid&lt;br /&gt;
** name&lt;br /&gt;
** timecreated&lt;br /&gt;
** timemodified&lt;br /&gt;
* groups_grouping_deleted&lt;br /&gt;
** id&lt;br /&gt;
** courseid&lt;br /&gt;
** name&lt;br /&gt;
** timecreated&lt;br /&gt;
** timemodified&lt;br /&gt;
* groups_members_removed (user deleted from all groups in a course)&lt;br /&gt;
** courseid&lt;br /&gt;
** userid&lt;br /&gt;
* groups_groupings_groups_removed (remove all groups from all groupings in a course)&lt;br /&gt;
** courseid (as plain integer, not object)&lt;br /&gt;
* groups_groups_deleted (delete all groups in a course)&lt;br /&gt;
** courseid (as plain integer, not object)&lt;br /&gt;
* groups_groupings_deleted (delete all groupings in a course)&lt;br /&gt;
** courseid (as plain integer, not object)&lt;br /&gt;
&lt;br /&gt;
===Messaging===&lt;br /&gt;
* message_send&lt;br /&gt;
** component = &#039;mod/forum&#039;: path in Moodle&lt;br /&gt;
** name = &#039;posts&#039;: type of message from that module (as module defines it)&lt;br /&gt;
** userfrom = $userfrom: a user object to send from&lt;br /&gt;
** userto = $userto: a user object to send to&lt;br /&gt;
** subject = &#039;subject line&#039;: a short text line&lt;br /&gt;
** fullmessage = &#039;full plain text&#039;: raw text as entered by user&lt;br /&gt;
** fullmessageformat = FORMAT_PLAIN|FORMAT_HTML|FORMAT_MOODLE|FORMAT_MARKDOWN: the format of this text&lt;br /&gt;
** fullmessagehtml = &#039;long html text&#039;; html rendered version (optional)&lt;br /&gt;
** smallmessage = &#039;short text&#039;: useful for plugins like sms or twitter (optional)&lt;br /&gt;
&lt;br /&gt;
===Portfolio===&lt;br /&gt;
* portfolio_send&lt;br /&gt;
** id : recordid in portfolio_tempdata table, used for itemid in file storage&lt;br /&gt;
&lt;br /&gt;
==Events wishlist==&lt;br /&gt;
&lt;br /&gt;
List of events which it would be nice to have.  Please add to this list if what you want is not shown here.&lt;br /&gt;
&lt;br /&gt;
* user_assign_role&lt;br /&gt;
* user_unassign_role&lt;br /&gt;
* mform_print_form -- this for all types of form e.g. admin settings, user profile, module updating, + some sort of standard way of discriminiating between them e.g. if ($form-&amp;gt;name == &#039;user_profile&#039;) {}. This would be better triggered at the end of the form generation process so that new bits can be inserted at any point, or existing bits could be removed.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=69103 General Developer Forum thread for discussing this proposal]. &lt;br /&gt;
* [[Messaging_2.0]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Events]]&lt;br /&gt;
[[Category:Grades]]&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Resource_module_file_API_migration&amp;diff=13732</id>
		<title>Resource module file API migration</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Resource_module_file_API_migration&amp;diff=13732"/>
		<updated>2009-05-18T08:53:16Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* Current problems */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle_2.0}}&lt;br /&gt;
&lt;br /&gt;
=Current problems=&lt;br /&gt;
* text and html resource types separate&lt;br /&gt;
* embedded images and files in general are stored in course files without appropriate access control&lt;br /&gt;
* local files and Internet links mixed&lt;br /&gt;
* is IMS plug-in maintained?&lt;br /&gt;
* repository plug-in obsoleted&lt;br /&gt;
* embedded images are lost during backup &amp;amp; restore which moves the course to a new site. -- [[User:Matt Gibson|Matt Gibson]] 08:53, 18 May 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
=Types of resources=&lt;br /&gt;
* Directory of files&lt;br /&gt;
* Resource page - using new editor element&lt;br /&gt;
* External resource link - some file stored elsewhere&lt;br /&gt;
* Single uploaded images and files&lt;br /&gt;
* Packages and uploaded html files&lt;br /&gt;
* Other 3rd party plugins&lt;br /&gt;
&lt;br /&gt;
=Upgrade planning=&lt;br /&gt;
Each type requires different upgrade code.&lt;br /&gt;
&lt;br /&gt;
==Directory type==&lt;br /&gt;
# Recursively copy directory to resource area, skip backup and moddata contents &lt;br /&gt;
&lt;br /&gt;
==Text and web page==&lt;br /&gt;
# Convert to one plug-in using new editor forms element&lt;br /&gt;
# Copy directly linked files that may not contain other relative links to resource area&lt;br /&gt;
# PROBLEM: deal somehow with html, flash, and java; maybe just warn and manual migration button&lt;br /&gt;
&lt;br /&gt;
==Links to files==&lt;br /&gt;
# Links to external sites do not need any upgrade&lt;br /&gt;
# If link points to simple file (image, sound, pdf.) copy to resource area&lt;br /&gt;
# PROBLEM: links to different courses - already problem now, maybe just warn teachers&lt;br /&gt;
# PROBLEM: links to files that may contain other relative links (html, flash, java)&lt;br /&gt;
&lt;br /&gt;
==IMS type==&lt;br /&gt;
# copy files to resource area&lt;br /&gt;
&lt;br /&gt;
==hive==&lt;br /&gt;
# PROBLEM: remove from core completely?&lt;br /&gt;
&lt;br /&gt;
==3rd party==&lt;br /&gt;
# needs docs&lt;br /&gt;
&lt;br /&gt;
=Solution of caching problems=&lt;br /&gt;
Teachers often do not understand that files may be cached in browsers, se the same mechanism already implemented in SCORM module.&lt;br /&gt;
# Internally store all files as itemid=0&lt;br /&gt;
# Add new revision db field into resource table&lt;br /&gt;
# When serving files always construct links with itemid==revision&lt;br /&gt;
# Ignore itemid for resource files in pluginfile.php&lt;br /&gt;
&lt;br /&gt;
=Internal refactoring and UI changes=&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
=See also=&lt;br /&gt;
&lt;br /&gt;
* [[Using the file API]]&lt;br /&gt;
* [[Repository API]]&lt;br /&gt;
* [[Portfolio API]]&lt;br /&gt;
* [[File API]]&lt;br /&gt;
* MDL-14589 - File API Meta issue&lt;br /&gt;
* MDL-16089 - Resource module conversion&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=YUI&amp;diff=4270</id>
		<title>YUI</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=YUI&amp;diff=4270"/>
		<updated>2009-05-13T15:27:30Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Yahoo! User Interface (YUI) Library is a set of utilities and controls, written in JavaScript, for building richly interactive web applications using techniques such as DOM scripting, DHTML and AJAX. All components in the YUI Library have been released as open source under a BSD license and are free for all uses. Details of the YUI can be found at the [http://developer.yahoo.com/yui/index.html Yahoo Developer Website].&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
Broadly speaking, you find an example you&#039;d like to implement e.g. from [http://developer.yahoo.com/yui/examples/slider/index.html here], then add it to an existing page, then tweak it to do what you want. &lt;br /&gt;
&lt;br /&gt;
YUI works with a single global object called YAHOO, which all other functions are added to via namespacing. You then use them like this:&lt;br /&gt;
 YAHOO.util.Event.onDOMready(//do something );&lt;br /&gt;
&lt;br /&gt;
===Dependencies===&lt;br /&gt;
In order to make the onDOMready method available to you, you first include a .js file that sets up the global object, then the events library .js file that adds all of the events methods to it. Moodle&#039;s way of doing this is with the require_js() function:&lt;br /&gt;
 &amp;lt;?php require_js(array(&#039;yui_yahoo&#039;, &#039;yui_event&#039;)); ?&amp;gt;&lt;br /&gt;
You can see that you can use shortcuts for many of the libraries. the ajax_get_lib() function in /lib/ajax/ajaxlib.php has details. Otherwise, you use the full path like this:&lt;br /&gt;
 &amp;lt;?php require_js(array($CFG-&amp;gt;dirroot.&#039;/lib/yui/yahoo/yahoo-min.js&#039;, $CFG-&amp;gt;dirroot.&#039;/lib/yui/event/event-min.js&#039;)); ?&amp;gt;&lt;br /&gt;
You notice that the files are called xxx-min.js. This is because they have been minified to make them as small as possible for fast page loading. Every file comes in a non-minifed version too called xxx-debug.js, which will give you accurate error messages as well as letting you follow progress in the YUI logger console.&lt;br /&gt;
&lt;br /&gt;
Once you have included the various .js dependency files with require_js() as outlined above, then write your own source .js file and add that to the require_js array &#039;&#039;&#039;after&#039;&#039;&#039; the other YUI ones. Many of the YUI files have other dependencies, so you&#039;ll often need to include more than one and the order matters for them too. Just follow the examples. &lt;br /&gt;
&lt;br /&gt;
You can also inject libraries dynamically if you really want to using [http://developer.yahoo.com/yui/yuiloader/ YUI loader], which adds &amp;lt;script&amp;gt; and &amp;lt;link&amp;gt; tags on the fly and can keep initial page load lighter.&lt;br /&gt;
&lt;br /&gt;
===Skinning===&lt;br /&gt;
For CSS, you include the css dependency files in either your theme styles.php or module/block styles.php using the standard PHP include() function. You will often need to apply the yui-skin-sam style to the body tag to get the skins to work right, so add something near the top of your script like:&lt;br /&gt;
 document.body.className += &#039; yui-skin-sam&#039;;&lt;br /&gt;
As a caveat, the paths in the CSS files assume that yui is placed in the site&#039;s web root and have no reference to $CFG-&amp;gt;wwwroot, so none of the images work. The solution is to go through the CSS files, pulling out any that have&lt;br /&gt;
 background: url(../../whatever.png);&lt;br /&gt;
and paste them into your styles.php below the css include you&#039;ve added, but looking like this:&lt;br /&gt;
 background: url(&amp;lt;?php echo $CFG-&amp;gt;wwwroot ?&amp;gt;/lib/yui/whatever.png);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Performance==&lt;br /&gt;
Remember to use [http://developer.yahoo.com/yui/examples/event/event-delegation.html event bubbling] wherever possible so that instead of adding a drag-drop listener to every page element, you just add one to the content div which catches all of the events lower down the DOM tree and does what&#039;s needed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Debugging==&lt;br /&gt;
Ideally, you should use Firefox, with the [https://addons.mozilla.org/en-US/firefox/addon/60 webdeveloper], [https://addons.mozilla.org/en-US/firefox/addon/1843 Firebug] and [https://addons.mozilla.org/en-US/firefox/addon/5369 YSlow] extensions loaded. The YUI logger will need to be included as a dependency if you want to use the xxx-debug.js versions of the files, so you need to add it to require_js() before them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Documentation for specific libraries==&lt;br /&gt;
&lt;br /&gt;
*[[Yahoo Global Object]] (/lib/yui/yahoo/yahoo.js)&lt;br /&gt;
*[[YUI event utility|YUI event utility]] (/lib/yui/event/event.js)&lt;br /&gt;
*[[Yahoo DOM Manipulation ]] (/lib/yui/dom/dom.js)&lt;br /&gt;
*[[Yahoo Connection Manager]] (/lib/yui/connection/connection.js)&lt;br /&gt;
*[[Yahoo Drag and Drop Utility]] (/lib/yui/dragdrop/dragdrop.js)&lt;br /&gt;
*[[Yahoo Animation Utility]] (/lib/yui/animation/animation.js)&lt;br /&gt;
*[[YUI TreeView|YUI TreeView]] (/lib/yui/treeview/treeview.js)&lt;br /&gt;
*[[Yahoo logger]] (/lib/yui/logger/logger-min.js)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Javascript|YUI]]&lt;br /&gt;
[[Category:AJAX|YUI]]&lt;br /&gt;
&lt;br /&gt;
{{CategoryDeveloper}}&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=YUI&amp;diff=4269</id>
		<title>YUI</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=YUI&amp;diff=4269"/>
		<updated>2009-05-13T15:27:01Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Yahoo! User Interface (YUI) Library is a set of utilities and controls, written in JavaScript, for building richly interactive web applications using techniques such as DOM scripting, DHTML and AJAX. All components in the YUI Library have been released as open source under a BSD license and are free for all uses. Details of the YUI can be found at the [http://developer.yahoo.com/yui/index.html Yahoo Developer Website].&lt;br /&gt;
&lt;br /&gt;
==Getting started==&lt;br /&gt;
&lt;br /&gt;
Broadly speaking, you find an example you&#039;d like to implement e.g. from [http://developer.yahoo.com/yui/examples/slider/index.html here], then add it to an existing page, then tweak it to do what you want. &lt;br /&gt;
&lt;br /&gt;
YUI works with a single global object called YAHOO, which all other functions are added to via namespacing. You then use them like this:&lt;br /&gt;
 YAHOO.util.Event.onDOMready(//do something );&lt;br /&gt;
&lt;br /&gt;
===Dependencies===&lt;br /&gt;
In order to make the onDOMready method available to you, you first include a .j file that sets up the global object, then the events library .js file that adds all of the events methods to it. Moodle&#039;s way of doing this is with the require_js() function:&lt;br /&gt;
 &amp;lt;?php require_js(array(&#039;yui_yahoo&#039;, &#039;yui_event&#039;)); ?&amp;gt;&lt;br /&gt;
You can see that you can use shortcuts for many of the libraries. the ajax_get_lib() function in /lib/ajax/ajaxlib.php has details. Otherwise, you use the full path like this:&lt;br /&gt;
 &amp;lt;?php require_js(array($CFG-&amp;gt;dirroot.&#039;/lib/yui/yahoo/yahoo-min.js&#039;, $CFG-&amp;gt;dirroot.&#039;/lib/yui/event/event-min.js&#039;)); ?&amp;gt;&lt;br /&gt;
You notice that the files are called xxx-min.js. This is because they have been minified to make them as small as possible for fast page loading. Every file comes in a non-minifed version too called xxx-debug.js, which will give you accurate error messages as well as letting you follow progress in the YUI logger console.&lt;br /&gt;
&lt;br /&gt;
Once you have included the various .js dependency files with require_js() as outlined above, then write your own source .js file and add that to the require_js array &#039;&#039;&#039;after&#039;&#039;&#039; the other YUI ones. Many of the YUI files have other dependencies, so you&#039;ll often need to include more than one and the order matters for them too. Just follow the examples. &lt;br /&gt;
&lt;br /&gt;
You can also inject libraries dynamically if you really want to using [http://developer.yahoo.com/yui/yuiloader/ YUI loader], which adds &amp;lt;script&amp;gt; and &amp;lt;link&amp;gt; tags on the fly and can keep initial page load lighter.&lt;br /&gt;
&lt;br /&gt;
===Skinning===&lt;br /&gt;
For CSS, you include the css dependency files in either your theme styles.php or module/block styles.php using the standard PHP include() function. You will often need to apply the yui-skin-sam style to the body tag to get the skins to work right, so add something near the top of your script like:&lt;br /&gt;
 document.body.className += &#039; yui-skin-sam&#039;;&lt;br /&gt;
As a caveat, the paths in the CSS files assume that yui is placed in the site&#039;s web root and have no reference to $CFG-&amp;gt;wwwroot, so none of the images work. The solution is to go through the CSS files, pulling out any that have&lt;br /&gt;
 background: url(../../whatever.png);&lt;br /&gt;
and paste them into your styles.php below the css include you&#039;ve added, but looking like this:&lt;br /&gt;
 background: url(&amp;lt;?php echo $CFG-&amp;gt;wwwroot ?&amp;gt;/lib/yui/whatever.png);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Performance==&lt;br /&gt;
Remember to use [http://developer.yahoo.com/yui/examples/event/event-delegation.html event bubbling] wherever possible so that instead of adding a drag-drop listener to every page element, you just add one to the content div which catches all of the events lower down the DOM tree and does what&#039;s needed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Debugging==&lt;br /&gt;
Ideally, you should use Firefox, with the [https://addons.mozilla.org/en-US/firefox/addon/60 webdeveloper], [https://addons.mozilla.org/en-US/firefox/addon/1843 Firebug] and [https://addons.mozilla.org/en-US/firefox/addon/5369 YSlow] extensions loaded. The YUI logger will need to be included as a dependency if you want to use the xxx-debug.js versions of the files, so you need to add it to require_js() before them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Documentation for specific libraries==&lt;br /&gt;
&lt;br /&gt;
*[[Yahoo Global Object]] (/lib/yui/yahoo/yahoo.js)&lt;br /&gt;
*[[YUI event utility|YUI event utility]] (/lib/yui/event/event.js)&lt;br /&gt;
*[[Yahoo DOM Manipulation ]] (/lib/yui/dom/dom.js)&lt;br /&gt;
*[[Yahoo Connection Manager]] (/lib/yui/connection/connection.js)&lt;br /&gt;
*[[Yahoo Drag and Drop Utility]] (/lib/yui/dragdrop/dragdrop.js)&lt;br /&gt;
*[[Yahoo Animation Utility]] (/lib/yui/animation/animation.js)&lt;br /&gt;
*[[YUI TreeView|YUI TreeView]] (/lib/yui/treeview/treeview.js)&lt;br /&gt;
*[[Yahoo logger]] (/lib/yui/logger/logger-min.js)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Javascript|YUI]]&lt;br /&gt;
[[Category:AJAX|YUI]]&lt;br /&gt;
&lt;br /&gt;
{{CategoryDeveloper}}&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=SSH_key&amp;diff=8421</id>
		<title>SSH key</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=SSH_key&amp;diff=8421"/>
		<updated>2009-03-26T12:57:50Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* Windows */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==What is a SSH key?==&lt;br /&gt;
&lt;br /&gt;
SSH keys are used for secure connections across a network.  They come in pairs, so you have a public key and a private key.&lt;br /&gt;
&lt;br /&gt;
The standard ssh2 file format (see&lt;br /&gt;
http://www.openssh.org/txt/draft-ietf-secsh-publickeyfile-02.txt)&lt;br /&gt;
looks like this:&lt;br /&gt;
&lt;br /&gt;
 ---- BEGIN SSH2 PUBLIC KEY ----&lt;br /&gt;
 Comment: &amp;quot;jtbell@Jon-Bells-Computer&amp;quot;&lt;br /&gt;
 AAAAB3NzaC1kc3MAAACBAPNgmidbM2rhYjUXunpnlXjHWfV+vc8/5YKrn8Y5P0Y6KwmG2G&lt;br /&gt;
 GMgNBon3LX3iJlBhtuU3FCBj3G1Kdt5vUhQHhUmHVrOasi47vawTrv7ZJCfiaSGwRsiBHt&lt;br /&gt;
 Jta5CAp7t0EnzX2q6BvPbFBBHNLyy6uNVpL2jOR06Pkx/vaqyScvAAAAFQDHvwmjWYwK9g&lt;br /&gt;
 K6Sp+pSvI7bwEUtwAAAIANMJDotMpfj89N+7+FJylSS+uFEQSS61PxENl/Mcj1jUREjJg2&lt;br /&gt;
 eNsJdAB9Ev99hWYS+7lFRtTJ2eh4Y9gpGe7BX3e2YGHOqp8cWCVCIKaMzwk9To+xnfThWq&lt;br /&gt;
 IfHT8I6CJxp/5ez02m6F2k/5iukvOwbGms6EAZK1DTBhDOHjEQwQAAAIAlz2/qBWkaMP+s&lt;br /&gt;
 W8FLmGKM+cCw5+asOaJGTwrFVuwJkDMvdEWxmG92A2dxuUske0d/AkN6zJp7HD0wlfesRM&lt;br /&gt;
 3+c+Res5qun9lFcdM4i03VoV5mXd+T7laS8yku6vZgvZZFnPvr2LOUnc7XThGFwMaQpFEW&lt;br /&gt;
 U8cvQbttO6QrT2CD2w==&lt;br /&gt;
 ---- END SSH2 PUBLIC KEY ----&lt;br /&gt;
&lt;br /&gt;
However, Moodle uses OpenSSH on its server and this key will not work with the OpenSSH server in this format; OpenSSH requires the key to be in OpenSSH format. Here is an example of a DSA public key in OpenSSH format (usually they are all in one line):&lt;br /&gt;
&lt;br /&gt;
 ssh-dss AAAAB3NzaC1kc3MAAACBAJ3hB5SAF6mBXPlZlRoJEZi0KSIN+NU2iGiaXZXi9CDrgVxTp6/&lt;br /&gt;
 sc56UcYCp4qjfrZ2G3+6PWbxYso4P4YyUC+61RU5KPy4EcTJske3O+aNvec/20cW7PT3TvH1+sxwGry&lt;br /&gt;
 mD50kTiXDgo5nXdqFvibgM61WW2DGTKlEUsZys0njRAAAAFQDs7ukaTGJlZdeznwFUAttTH9LrwwAAA&lt;br /&gt;
 IAMm4sLCdvvBx9WPkvWDX0OIXSteCYckiQxesOfPvz26FfYxuTG/2dljDlalC+kYG05C1NEcmZWSNES&lt;br /&gt;
 GBGfccSYSfI3Y5ahSVUhOC2LMO3JNjVyYUnOM/iyhzrnRfQoWO9GFMaugq0jBMlhZA4UO26yJqJ+BtX&lt;br /&gt;
 IyItaEEJdc/ghIwAAAIBFeCZynstlbBjP648+mDKIvzNSS+JYr5klGxS3q8A56NPcYhDMxGn7h1DKbb&lt;br /&gt;
 2AV4pO6y+6hDrWo3UT4dLVuzK01trwp PYp6JXTSZZ12ZaXNPz7sX9/z6pzMqhX4UEfjVsLcuF+ZS6a&lt;br /&gt;
 QCPO0ZZEa1z+EEIZSD/ykLQsDwPxGjPBqw== someone@somewhere.com&lt;br /&gt;
&lt;br /&gt;
In addition to OpenSSH and Standard SSH formats there are a variety of proprietary formats as well as SSH1 and SSH2 differences to account for, which can make this confusing. &lt;br /&gt;
&lt;br /&gt;
In the example above you will note that the key starts with &amp;quot;ssh-dss&amp;quot;. This is because this key was generated using DSA as opposed to RSA. A number of vendors in the SSH arena have argued, as per the PuTTY documentation that can be found at http://the.earth.li/~sgtatham/putty/0.55/htmldoc/Chapter8.html#S8.2.10 that users should employ RSA encryption because&lt;br /&gt;
&lt;br /&gt;
 DSA has an intrinsic weakness which makes it very easy to create a signature&lt;br /&gt;
 which contains enough information to give away the private key! This would &lt;br /&gt;
 allow an attacker to pretend to be you for any number of future sessions. &lt;br /&gt;
&lt;br /&gt;
An SSH2 public key in OpenSSH format will start with &amp;quot;ssh-rsa&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The idea behind all of this is that once you have keys on the remote server and your local host,  access will be simpler since the server will only grant access to someone who has the matching private key.&lt;br /&gt;
&lt;br /&gt;
==Why do I need a SSH key?==&lt;br /&gt;
&lt;br /&gt;
Our CVS server uses OpenSSH, so if are a Moodle developer and you want to make your logins easier (by avoiding typing in your password all the time) then you will need to submit public key in Openssh format via the &amp;quot;Update my developer information&amp;quot; tab at http://moodle.org/cvs.&lt;br /&gt;
&lt;br /&gt;
==How do I create a SSH key pair?==&lt;br /&gt;
&lt;br /&gt;
===Platform Independent===&lt;br /&gt;
&lt;br /&gt;
Visit http://www.sshkeygen.com and simply follow the directions there.&lt;br /&gt;
&lt;br /&gt;
===Eclipse===&lt;br /&gt;
&lt;br /&gt;
If you plan to use Eclipse for development, please refer to the Eclipse document https://docs.moodle.org/en/Eclipse as Eclipse now has a plugin that allows you to manage all ssh key matters from within Eclipse.&lt;br /&gt;
&lt;br /&gt;
===Unix/Linux===&lt;br /&gt;
&lt;br /&gt;
You can use ssh-keygen at your system prompt.  Please consult the man page on your system for the options available to you.&lt;br /&gt;
&lt;br /&gt;
# Run:  &#039;&#039;&#039;ssh-keygen -t (rsa or dsa)&#039;&#039;&#039;. This will not include a passphrase. *&lt;br /&gt;
# Use of rsa or dsa above will result in rsa or dsa replacing each XXX below.&lt;br /&gt;
# Look in your ~/.ssh directory (or wherever you saved the output).  You&#039;ll find &#039;&#039;&#039;id_XXX&#039;&#039;&#039; (private) and &#039;&#039;&#039;id_XXX.pub&#039;&#039;&#039; (public).&lt;br /&gt;
# Cut and paste the contents of &#039;&#039;&#039;id_XXX.pub&#039;&#039;&#039; into your developer profile on http://moodle.org/cvs&lt;br /&gt;
# Put the private key wherever you will be calling CVS from (in your .ssh directory, for example).  Make sure it&#039;s secure!&lt;br /&gt;
&lt;br /&gt;
* This section initially recommended using &#039;&#039;ssh-keygen -d&#039;&#039; but it is unclear what the source of this -d option might be.&lt;br /&gt;
&lt;br /&gt;
===Windows===&lt;br /&gt;
Use puttygen and follow the instructions [http://the.earth.li/~sgtatham/putty/0.58/htmldoc/Chapter8.html here]. Make sure you choose the RSA2 key format and that when you copy the key data into the textbox on the site, that you have all of the characters on one line. If you have opened the key with word pad, it will have line breaks in it which will stop it from working.&lt;br /&gt;
&lt;br /&gt;
The box should look like this:&lt;br /&gt;
&lt;br /&gt;
 ssh-rsa&lt;br /&gt;
 AAAAWfg&amp;amp;jkf4D34H5@4svf..... (single very long line continues beyond edge of textbox)&lt;br /&gt;
&lt;br /&gt;
===Mac OS X===&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=SSH_key&amp;diff=8420</id>
		<title>SSH key</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=SSH_key&amp;diff=8420"/>
		<updated>2009-03-26T12:54:44Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* Windows */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==What is a SSH key?==&lt;br /&gt;
&lt;br /&gt;
SSH keys are used for secure connections across a network.  They come in pairs, so you have a public key and a private key.&lt;br /&gt;
&lt;br /&gt;
The standard ssh2 file format (see&lt;br /&gt;
http://www.openssh.org/txt/draft-ietf-secsh-publickeyfile-02.txt)&lt;br /&gt;
looks like this:&lt;br /&gt;
&lt;br /&gt;
 ---- BEGIN SSH2 PUBLIC KEY ----&lt;br /&gt;
 Comment: &amp;quot;jtbell@Jon-Bells-Computer&amp;quot;&lt;br /&gt;
 AAAAB3NzaC1kc3MAAACBAPNgmidbM2rhYjUXunpnlXjHWfV+vc8/5YKrn8Y5P0Y6KwmG2G&lt;br /&gt;
 GMgNBon3LX3iJlBhtuU3FCBj3G1Kdt5vUhQHhUmHVrOasi47vawTrv7ZJCfiaSGwRsiBHt&lt;br /&gt;
 Jta5CAp7t0EnzX2q6BvPbFBBHNLyy6uNVpL2jOR06Pkx/vaqyScvAAAAFQDHvwmjWYwK9g&lt;br /&gt;
 K6Sp+pSvI7bwEUtwAAAIANMJDotMpfj89N+7+FJylSS+uFEQSS61PxENl/Mcj1jUREjJg2&lt;br /&gt;
 eNsJdAB9Ev99hWYS+7lFRtTJ2eh4Y9gpGe7BX3e2YGHOqp8cWCVCIKaMzwk9To+xnfThWq&lt;br /&gt;
 IfHT8I6CJxp/5ez02m6F2k/5iukvOwbGms6EAZK1DTBhDOHjEQwQAAAIAlz2/qBWkaMP+s&lt;br /&gt;
 W8FLmGKM+cCw5+asOaJGTwrFVuwJkDMvdEWxmG92A2dxuUske0d/AkN6zJp7HD0wlfesRM&lt;br /&gt;
 3+c+Res5qun9lFcdM4i03VoV5mXd+T7laS8yku6vZgvZZFnPvr2LOUnc7XThGFwMaQpFEW&lt;br /&gt;
 U8cvQbttO6QrT2CD2w==&lt;br /&gt;
 ---- END SSH2 PUBLIC KEY ----&lt;br /&gt;
&lt;br /&gt;
However, Moodle uses OpenSSH on its server and this key will not work with the OpenSSH server in this format; OpenSSH requires the key to be in OpenSSH format. Here is an example of a DSA public key in OpenSSH format (usually they are all in one line):&lt;br /&gt;
&lt;br /&gt;
 ssh-dss AAAAB3NzaC1kc3MAAACBAJ3hB5SAF6mBXPlZlRoJEZi0KSIN+NU2iGiaXZXi9CDrgVxTp6/&lt;br /&gt;
 sc56UcYCp4qjfrZ2G3+6PWbxYso4P4YyUC+61RU5KPy4EcTJske3O+aNvec/20cW7PT3TvH1+sxwGry&lt;br /&gt;
 mD50kTiXDgo5nXdqFvibgM61WW2DGTKlEUsZys0njRAAAAFQDs7ukaTGJlZdeznwFUAttTH9LrwwAAA&lt;br /&gt;
 IAMm4sLCdvvBx9WPkvWDX0OIXSteCYckiQxesOfPvz26FfYxuTG/2dljDlalC+kYG05C1NEcmZWSNES&lt;br /&gt;
 GBGfccSYSfI3Y5ahSVUhOC2LMO3JNjVyYUnOM/iyhzrnRfQoWO9GFMaugq0jBMlhZA4UO26yJqJ+BtX&lt;br /&gt;
 IyItaEEJdc/ghIwAAAIBFeCZynstlbBjP648+mDKIvzNSS+JYr5klGxS3q8A56NPcYhDMxGn7h1DKbb&lt;br /&gt;
 2AV4pO6y+6hDrWo3UT4dLVuzK01trwp PYp6JXTSZZ12ZaXNPz7sX9/z6pzMqhX4UEfjVsLcuF+ZS6a&lt;br /&gt;
 QCPO0ZZEa1z+EEIZSD/ykLQsDwPxGjPBqw== someone@somewhere.com&lt;br /&gt;
&lt;br /&gt;
In addition to OpenSSH and Standard SSH formats there are a variety of proprietary formats as well as SSH1 and SSH2 differences to account for, which can make this confusing. &lt;br /&gt;
&lt;br /&gt;
In the example above you will note that the key starts with &amp;quot;ssh-dss&amp;quot;. This is because this key was generated using DSA as opposed to RSA. A number of vendors in the SSH arena have argued, as per the PuTTY documentation that can be found at http://the.earth.li/~sgtatham/putty/0.55/htmldoc/Chapter8.html#S8.2.10 that users should employ RSA encryption because&lt;br /&gt;
&lt;br /&gt;
 DSA has an intrinsic weakness which makes it very easy to create a signature&lt;br /&gt;
 which contains enough information to give away the private key! This would &lt;br /&gt;
 allow an attacker to pretend to be you for any number of future sessions. &lt;br /&gt;
&lt;br /&gt;
An SSH2 public key in OpenSSH format will start with &amp;quot;ssh-rsa&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The idea behind all of this is that once you have keys on the remote server and your local host,  access will be simpler since the server will only grant access to someone who has the matching private key.&lt;br /&gt;
&lt;br /&gt;
==Why do I need a SSH key?==&lt;br /&gt;
&lt;br /&gt;
Our CVS server uses OpenSSH, so if are a Moodle developer and you want to make your logins easier (by avoiding typing in your password all the time) then you will need to submit public key in Openssh format via the &amp;quot;Update my developer information&amp;quot; tab at http://moodle.org/cvs.&lt;br /&gt;
&lt;br /&gt;
==How do I create a SSH key pair?==&lt;br /&gt;
&lt;br /&gt;
===Platform Independent===&lt;br /&gt;
&lt;br /&gt;
Visit http://www.sshkeygen.com and simply follow the directions there.&lt;br /&gt;
&lt;br /&gt;
===Eclipse===&lt;br /&gt;
&lt;br /&gt;
If you plan to use Eclipse for development, please refer to the Eclipse document https://docs.moodle.org/en/Eclipse as Eclipse now has a plugin that allows you to manage all ssh key matters from within Eclipse.&lt;br /&gt;
&lt;br /&gt;
===Unix/Linux===&lt;br /&gt;
&lt;br /&gt;
You can use ssh-keygen at your system prompt.  Please consult the man page on your system for the options available to you.&lt;br /&gt;
&lt;br /&gt;
# Run:  &#039;&#039;&#039;ssh-keygen -t (rsa or dsa)&#039;&#039;&#039;. This will not include a passphrase. *&lt;br /&gt;
# Use of rsa or dsa above will result in rsa or dsa replacing each XXX below.&lt;br /&gt;
# Look in your ~/.ssh directory (or wherever you saved the output).  You&#039;ll find &#039;&#039;&#039;id_XXX&#039;&#039;&#039; (private) and &#039;&#039;&#039;id_XXX.pub&#039;&#039;&#039; (public).&lt;br /&gt;
# Cut and paste the contents of &#039;&#039;&#039;id_XXX.pub&#039;&#039;&#039; into your developer profile on http://moodle.org/cvs&lt;br /&gt;
# Put the private key wherever you will be calling CVS from (in your .ssh directory, for example).  Make sure it&#039;s secure!&lt;br /&gt;
&lt;br /&gt;
* This section initially recommended using &#039;&#039;ssh-keygen -d&#039;&#039; but it is unclear what the source of this -d option might be.&lt;br /&gt;
&lt;br /&gt;
===Windows===&lt;br /&gt;
Use puttygen and follow the instructions [http://the.earth.li/~sgtatham/putty/0.58/htmldoc/Chapter8.html here]. Make sure you choose the RSA2 key format and that when you copy the key data into the textbox on the site, that you have all of the characters on one line. If you have opened the key with word pad, it will have line breaks in it which will stop it from working.&lt;br /&gt;
&lt;br /&gt;
===Mac OS X===&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Tooltips&amp;diff=12528</id>
		<title>Tooltips</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Tooltips&amp;diff=12528"/>
		<updated>2009-03-19T13:45:49Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is aimed at listing all of the parts of Moodle that have inadequate or missing tooltips and providing suggestions for text to add to them.&lt;br /&gt;
&lt;br /&gt;
Each tooltip should have three things:&lt;br /&gt;
* The name of the item&lt;br /&gt;
* How it works&lt;br /&gt;
* Why you would want to use it &lt;br /&gt;
&lt;br /&gt;
Occasionally all 3 will not be necessary (e.g. Delete), but that should be a rare exception, not the rule.&lt;br /&gt;
&lt;br /&gt;
==Course page==&lt;br /&gt;
Editing icons:&lt;br /&gt;
{| border = &amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Icon&lt;br /&gt;
! Current tooltip&lt;br /&gt;
! Improved tooltip suggestion&lt;br /&gt;
|-&lt;br /&gt;
| Move || Move || Click here and drag to move this item to any other part of the center column&lt;br /&gt;
|-&lt;br /&gt;
| Right arrow || Move right || Click here to indent this item one level to the right. This can help you to structure your course by presenting items in nested lists&lt;br /&gt;
|-&lt;br /&gt;
| Edit icon || Update || Click here to update settings for this item such as its name or the instructions the students will see&lt;br /&gt;
|-&lt;br /&gt;
| Delete icon || Delete || Delete this item (you will be asked to confirm)&lt;br /&gt;
|-&lt;br /&gt;
| Open eye || Hide || This item is currently visible to students. Click here to hide it&lt;br /&gt;
|-&lt;br /&gt;
| Little person || No groups (click to change) || This item is currently set to &#039;No groups&#039; mode, meaning that it will ignore what group(s) a student is part of. Click here to switch it to separate groups and click again to switch it to visible groups.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Tooltips&amp;diff=12527</id>
		<title>Tooltips</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Tooltips&amp;diff=12527"/>
		<updated>2009-03-19T13:39:30Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: New page: This page is aimed at listing all of the parts of Moodle that have inadequate or missing tooltips and providing suggestions for text to add to them  ==Course page== Editing icons: {| borde...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is aimed at listing all of the parts of Moodle that have inadequate or missing tooltips and providing suggestions for text to add to them&lt;br /&gt;
&lt;br /&gt;
==Course page==&lt;br /&gt;
Editing icons:&lt;br /&gt;
{| border = &amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Icon&lt;br /&gt;
! Current tooltip&lt;br /&gt;
! Improved tooltip suggestion&lt;br /&gt;
|-&lt;br /&gt;
| Move || Move || Click here and drag to move this item to any other part of the center column&lt;br /&gt;
|-&lt;br /&gt;
| Right arrow || Move right || Click here to indent this item one level to the right. This can help you to structure your course by presenting items in nested lists&lt;br /&gt;
|-&lt;br /&gt;
| Edit icon || Update || Click here to update settings for this item such as its name or the instructions the students will see&lt;br /&gt;
|-&lt;br /&gt;
| Delete icon || Delete || Delete this item (you will be asked to confirm)&lt;br /&gt;
|-&lt;br /&gt;
| Open eye || Hide || This item is currently visible to students. Click here to hide it&lt;br /&gt;
|-&lt;br /&gt;
| Little person || No groups (click to change) || This item is currently set to &#039;No groups&#039; mode, meaning that it will ignore what group(s) a student is part of. Click here to switch it to separate groups and click again to switch it to visible groups.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Talk:Gradebook_improvements&amp;diff=27846</id>
		<title>Talk:Gradebook improvements</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Talk:Gradebook_improvements&amp;diff=27846"/>
		<updated>2009-01-22T13:36:37Z</updated>

		<summary type="html">&lt;p&gt;Mattgibson: /* Common frustrations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Aggregation of hidden grades==&lt;br /&gt;
&lt;br /&gt;
Overlook problem partially solve after the database freeze - workaround was to recalculate the grades on the fly so that users that can the hidden grades are ignored. This approach is expensive and can not be used in conditional activities, grade exports, etc.&lt;br /&gt;
&lt;br /&gt;
Solution is to add new flag into grade categories - aggregate hidden grades. Having two values for each grade would be too complex, selective agrragation should solve most of the problems and should be reasonably backwards compatible.&lt;br /&gt;
&lt;br /&gt;
--[[User:Petr Škoda (škoďák)|Petr Škoda (škoďák)]] 11:56, 8 December 2008&lt;br /&gt;
&lt;br /&gt;
==Exports: more flexibility==&lt;br /&gt;
&lt;br /&gt;
Two aspects of the 1.9 export plugin have been criticised by some of Catalyst&#039;s clients:&lt;br /&gt;
&lt;br /&gt;
* the fact that grade exports are tied to a course&lt;br /&gt;
* the default user profile columns are not all needed and some custom ones would be necessary &lt;br /&gt;
&lt;br /&gt;
Therefore I propose the following changes:&lt;br /&gt;
&lt;br /&gt;
* removing the export plugin dependency on a single course by converting to an array of courses (see MDL-17420)&lt;br /&gt;
* making the user-related columns customisable (see MDL-17346)&lt;br /&gt;
&lt;br /&gt;
--[[User:Francois Marier|Francois Marier]] 06:42, 9 December 2008&lt;br /&gt;
&lt;br /&gt;
==Gradebook does not consider groupings functionality==&lt;br /&gt;
&lt;br /&gt;
Student in gradebook view all grade items, but must view only grade items thats belong to his groiping (see MDL-13868).&lt;br /&gt;
&lt;br /&gt;
--[[User:Artem Andreev|Artem Andreev]] 11:07, 9 December 2008&lt;br /&gt;
&lt;br /&gt;
==Common frustrations==&lt;br /&gt;
Below are some of the most often reported usability issues in the 1.9 gradebook, which we are trying to address. Several of these are grouped as sub-tasks under MDL-16913.&lt;br /&gt;
&lt;br /&gt;
===Assigning weights to categories and grade items===&lt;br /&gt;
This is the most common frustration. Weights are used extensively in many institutions, and were used in 1.8. However, they are difficult to understand in 1.9, and difficult to set up. This issue is discussed extensively in MDL-15680.&lt;br /&gt;
&lt;br /&gt;
===Moving items to categories===&lt;br /&gt;
Currently, the [[Edit categories and items]] page lets you move only one grade item or category at a time. It takes two page refreshes and two mouse clicks per move. This is very tedious and time-consuming when many items have to be moved around. MDL-13775 and MDL-12502 address this problem.&lt;br /&gt;
&lt;br /&gt;
===Removing the &#039;&#039;overridden&#039;&#039; attribute of individual grades===&lt;br /&gt;
When grades are imported into an existing gradebook, or when grades are manually edited in the grader report, these grades become [[Grade_editing#Overridden|overridden]], which prevents linked activity modules from updating this grade. Removing this attribute is very time-consuming, since one must enter the edit page of each individual grade, untick the checkbox and submit the form. This issue is discussed in [http://moodle.org/mod/forum/discuss.php?d=109636 this forum thread].&lt;br /&gt;
&lt;br /&gt;
===Viewing the overall contribution of each category and item to the course aggregation===&lt;br /&gt;
The tracker issue MDL-13777 reports the difficulty in seeing the contribution of each grade item and category to the course total. Calculations and weights may apply, which are not visible in any of the current reports except in each individual category or item&#039;s edit page.&lt;br /&gt;
&lt;br /&gt;
--[[User:Nicolas Connault|Nicolas Connault]] 12:41, 4 November 2008&lt;br /&gt;
&lt;br /&gt;
Some more that it would be great to see fixed:&lt;br /&gt;
===Setting grade to pass===&lt;br /&gt;
Takes a lot of clicks and the edit icon looks like it&#039;s part of the main mass of editing icons for the grades table itself, so it&#039;s hard to find. This is a very useful feature (at least once MDL-13830 is fixed) as it shows at a glance how many items a student has failed to pass. Seeing a row of red entries is a great way of quickly knowing who to target for extra attention in class. Quite obscure at the moment though, especially seeing as it cannot be done from the module itself. -[[User:Matt Gibson|Matt Gibson]] 07:36, 22 January 2009 (CST)&lt;br /&gt;
&lt;br /&gt;
===Its not possible to see whether or not a student has submitted work which has not been marked===&lt;br /&gt;
If the modules could send a special grade e.g. -1 to the gradebook as a placeholder that could be used to add either a css class to a cell, or display a special character to show that work is waiting. Then it would be possible to use the gradebook like a normal one, in order to evaluate students&#039; deadline-meeting for writing reports. At the moment, this is probably the biggest problem in our institution&#039;s use of the gradebook. - [[User:Matt Gibson|Matt Gibson]] 07:36, 22 January 2009 (CST)&lt;br /&gt;
&lt;br /&gt;
==Patch for Edit Categories and Items page==&lt;br /&gt;
Following is a proposed patch to the &#039;&#039;&#039;Edit categories and items&#039;&#039;&#039; page in the 1.9 gradebook. It addresses many usability issues while remaining simple. The following features are currently implemented:&lt;br /&gt;
&lt;br /&gt;
===Simple features===&lt;br /&gt;
[[Image:gradebook_categories_simple.png|600px]]&lt;br /&gt;
*Items and categories are displayed in a table instead of a list. This improves readability and will make drag and drop easier to implement.&lt;br /&gt;
*All advanced features are hidden by default, so that the interface by default is almost identical to the original&lt;br /&gt;
*An additional column has checkboxes for grade items. All selected items can then be moved to one of the existing grade categories for the current course. Javascript &amp;quot;Select all/Select None&amp;quot; links replace these checkboxes for categories, to make it faster to select or de-select items.&lt;br /&gt;
&lt;br /&gt;
===Advanced features===&lt;br /&gt;
[[Image:gradebook_categories_advanced.png|600px]]&lt;br /&gt;
&lt;br /&gt;
*[[Category aggregation|Grade category aggregation type]]: changing this reloads the page, because the grade item weights/extra credits only apply to some of these aggregation types.&lt;br /&gt;
*Weight or extra credit: depending on the parent category&#039;s aggregation type, each category and grade item may have an input field or a checkbox for weight or extra credit. All these can be edited, then submitted with one click.&lt;br /&gt;
*Grade range is displayed for information purposes, but cannot be edited through this interface (it is most often controlled by the linked activity)&lt;br /&gt;
*[[Grade_categories#Aggregate_only_non-empty_grades|Aggregate only non-empty grades]]&lt;br /&gt;
*[[Grade_categories#Aggregate_including_sub-categories|Aggregate including sub-categories]]&lt;br /&gt;
*[[Grade_categories#Include_outcomes_in_aggregation|Include outcomes in aggregation]]&lt;br /&gt;
*[[Grade_categories#Drop_the_lowest|Drop the lowest]]&lt;br /&gt;
*[[Grade_categories#Keep_the_highest|Keep the highest]]&lt;br /&gt;
*[[Grade items|Multiplicator]]&lt;br /&gt;
*[[Grade_items|Offset]]&lt;br /&gt;
&lt;br /&gt;
All these settings can be changed then submitted with only one page reload. Just be mindful that changing a category&#039;s aggregation type will reload the page and you will lose any non-submitted changes you made to the other settings.&lt;br /&gt;
&lt;br /&gt;
--[[User:Nicolas Connault|Nicolas Connault]] 12:41, 4 November 2008&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Tim&#039;s_Gradebook_thoughts|Tim&#039;s Gradebook thoughts]]&lt;/div&gt;</summary>
		<author><name>Mattgibson</name></author>
	</entry>
</feed>