<?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=Scyrma</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=Scyrma"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/Special:Contributions/Scyrma"/>
	<updated>2026-10-03T16:07:47Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Filters&amp;diff=46762</id>
		<title>Filters</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Filters&amp;diff=46762"/>
		<updated>2014-11-10T20:24:15Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: My mistake.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;&#039;&#039;&#039;Please note:&#039;&#039;&#039; This page contains information for developers. You may prefer to read the [[:en:Filters| information about filters for teachers and administrators]].&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Filters&#039;&#039;&#039; are a way to automatically transform content before it is output. For example&lt;br /&gt;
* render embedded equations to images (the TeX filter)&lt;br /&gt;
* Links to media files can be automatically converted to an embedded applet for playing the media.&lt;br /&gt;
* Mentions of glossary terms can be automatically converted to links.&lt;br /&gt;
The possibilities are endless. There are a number of standard filters included with Moodle, or you can create your own. Filters are one of the easiest types of plugin to create. This page explains how.&lt;br /&gt;
&lt;br /&gt;
==Before you start==&lt;br /&gt;
&lt;br /&gt;
Go to  Site administration ▶ Plugins ▶ Filters ▶ Common filter settings and set Text cache lifetime to 0 (&amp;quot;No&amp;quot;) while you do development. Otherwise, you will not be able to see the effects of your changes when you edit your filter&#039;s code. (You should also be using the other common developer settings, like developer debug, theme designer mode and so on.)&lt;br /&gt;
&lt;br /&gt;
==Creating a basic filter==&lt;br /&gt;
&lt;br /&gt;
During this tutorial, we will build a simple example filter. We will make one that adds the word &#039;hello&#039; before every occurrence of the word &#039;world&#039;.&lt;br /&gt;
&lt;br /&gt;
1. Since our filter is not part of a module, we should put it inside the &#039;filter&#039; folder. Therefore, we create a directory called &#039;filter/helloworld&#039;.&lt;br /&gt;
&lt;br /&gt;
2. Inside that folder, we create a file called &#039;filter.php&#039;.&lt;br /&gt;
&lt;br /&gt;
3. Inside that PHP file, we define a class called filter_helloworld, that extends the moodle_text_filter class.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
class filter_helloworld extends moodle_text_filter {&lt;br /&gt;
    // ...&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Inside that class, we have to define one method, called &#039;filter&#039;. This takes the HTML to be filtered as an argument. The method should then transform that, and return the processed text. Replace the &#039;// ...&#039; above with&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
class filter_helloworld extends moodle_text_filter {&lt;br /&gt;
    public function filter($text, array $options = array()) {&lt;br /&gt;
        return str_replace(&#039;world&#039;, &#039;hello world!&#039;, $text);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That is basically all there is to it!&lt;br /&gt;
&lt;br /&gt;
==Giving your filter a name==&lt;br /&gt;
&lt;br /&gt;
To try the new filter, you first have to log in as Administrator and enable it by going to the page Administration ► Plugins ► Filters ► Manage filters.&lt;br /&gt;
&lt;br /&gt;
When you do, you will find that your plugin does not have a name. We missed a step:&lt;br /&gt;
&lt;br /&gt;
5. Inside the &#039;filter/helloworld&#039; folder, create a folder called &#039;lang&#039;, and in there, create a folder called &#039;en&#039;.&lt;br /&gt;
&lt;br /&gt;
6. Inside there, create a file called &#039;filter_helloworld.php&#039;. That is, you have just created the file &#039;filter/helloworld/lang/en/filter_helloworld.php&#039;.&lt;br /&gt;
&lt;br /&gt;
7. In that file, put&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php // $Id$&lt;br /&gt;
// Language string for filter/helloworld.&lt;br /&gt;
&lt;br /&gt;
$string[&#039;filtername&#039;] = &#039;Hello world!&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That may seem a little involved, just to give your filter a name, but it is just [[Places_to_search_for_lang_strings|the standard way Moodle stores language strings for plugins]].&lt;br /&gt;
&lt;br /&gt;
==Trying out your filter==&lt;br /&gt;
&lt;br /&gt;
We had just got to the [[Filters|filters administration screen]]. If you reload that page now, it should now show your filter with its proper name. Turn your filter on now.&lt;br /&gt;
&lt;br /&gt;
Filters are applied to all text that is printed with the [[Output functions|output functions]] format_text(), and, if you have turned on that option, format_string(). So, to see your filter in action, add some content containing the word &#039;world&#039; somewhere, for example, create a test course, and use the word in the course description. When you look at that course in the course listing, you should see that your filter has transformed it.&lt;br /&gt;
&lt;br /&gt;
==Adding a global settings screen==&lt;br /&gt;
&lt;br /&gt;
Some filters can benefit from some settings to let the administrator control how they work. Suppose we want to greet something other than &#039;world&#039;. To add global settings to the filter you need to:&lt;br /&gt;
&lt;br /&gt;
8. Create a file called &#039;filtersettings.php&#039; inside the &#039;filter/helloworld&#039; folder. Use standard &#039;settings.php&#039; file in Moodle 2.6 and later.&lt;br /&gt;
&lt;br /&gt;
9. In the &#039;filtersettings.php&#039; file, put something like:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$settings-&amp;gt;add(new admin_setting_configtext(&#039;filter_helloworld_word&#039;,&lt;br /&gt;
        get_string(&#039;word&#039;, &#039;filter_helloworld&#039;),&lt;br /&gt;
        get_string(&#039;word_desc&#039;, &#039;filter_helloworld&#039;), &#039;world&#039;, PARAM_NOTAGS));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
10. In the language file &#039;filter/helloworld/lang/en/filter_helloworld.php&#039; add the necessary strings:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;word&#039;] = &#039;The thing to greet&#039;;&lt;br /&gt;
$string[&#039;word_desc&#039;] = &#039;The hello world filter will add the word \&#039;hello\&#039; in front of every occurrence of this word in any content.&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
11. Change the filter to use the new setting:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
class filter_helloworld extends moodle_text_filter {&lt;br /&gt;
    public function filter($text, array $options = array()) {&lt;br /&gt;
        global $CFG;&lt;br /&gt;
        return str_replace($CFG-&amp;gt;filter_helloworld_word,&lt;br /&gt;
                &amp;quot;hello $CFG-&amp;gt;filter_helloworld_word!&amp;quot;, $text);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In standard Moodle, the censor, mediaplugin and tex filters all provide good examples of of how filters use global configuration like this.&lt;br /&gt;
&lt;br /&gt;
==A note about performance==&lt;br /&gt;
&lt;br /&gt;
One important thing to remember when creating a filter is that the filter will be called to transform every bit of text output using format_text(), and possibly also format_string(). That means that you have to be careful, or you could cause big performance problems. If you have to get data out of the database, try to cache it so that you only do a fixed number of database queries per page load. The Glossary filter is an example of this. (I am not sure how good an example ;-))&lt;br /&gt;
&lt;br /&gt;
==Local configuration==&lt;br /&gt;
&lt;br /&gt;
In addition, in Moodle 2.0, filters can also have different configuration in each context. For example, the glossary could be changes so that in Forum A, you can choose to only link words from a particular glossary, sat Glossary A, while in Forum B you choose to link words from Glossary B.&lt;br /&gt;
&lt;br /&gt;
To do that sort of thing, you need to add a file called filterlocalsettings.php. In it, you must define a [[lib/formslib.php|Moodle form]] that is a subclass of filter_local_settings_form. In addition to the standard formslib methods, you also need to define a save_changes method. There is not a good example of this in the standard Moodle install yet. To continue our example:&lt;br /&gt;
&lt;br /&gt;
12. Create a file called &#039;filterlocalsettings.php&#039; inside the &#039;filter/helloworld&#039; folder.&lt;br /&gt;
&lt;br /&gt;
13. In the &#039;filterlocalsettings.php&#039; file, put:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
class helloworld_filter_local_settings_form extends filter_local_settings_form {&lt;br /&gt;
    protected function definition_inner($mform) {&lt;br /&gt;
        $mform-&amp;gt;addElement(&#039;text&#039;, &#039;word&#039;, get_string(&#039;word&#039;, &#039;filter_helloworld&#039;), array(&#039;size&#039; =&amp;gt; 20));&lt;br /&gt;
        $mform-&amp;gt;setType(&#039;word&#039;, PARAM_NOTAGS);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
14. Extend the filter to use the new setting, if it is present. The filter must be able to work if the setting is not set, for example by falling back to the global or default setting in this case&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
class filter_helloworld extends moodle_text_filter {&lt;br /&gt;
    public function filter($text, array $options = array()) {&lt;br /&gt;
        global $CFG;&lt;br /&gt;
        if (isset($this-&amp;gt;localconfig[&#039;word&#039;])) {&lt;br /&gt;
            $word = $this-&amp;gt;localconfig[&#039;word&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            $word = $CFG-&amp;gt;filter_helloworld_word;&lt;br /&gt;
        }&lt;br /&gt;
        return str_replace($word, &amp;quot;hello $word!&amp;quot;, $text);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Two types of filter==&lt;br /&gt;
&lt;br /&gt;
In the past, Moodle supported two different types of filter:&lt;br /&gt;
* Stand-alone filters like the one we created above. These live in a folder inside the &#039;filter&#039; folder. For example, in &#039;filter/myfilter&#039;. &#039;filter/tex&#039; is an example of a core filter of this type.&lt;br /&gt;
* Filters that were part of an activity module. In this case, the filter code lives inside the &#039;mod/mymod&#039; folder. &#039;mod/glossary&#039; used to be an example of a core module with a filter.&lt;br /&gt;
The second option no longer exists in Moodle 2.5 and later. All filters live in the filter folder. Of course, a filter may depend on an associated other plugin, like mod_glossary. If so, you should declare that in the [[version.php]] file.&lt;br /&gt;
&lt;br /&gt;
==Dynamic content==&lt;br /&gt;
&lt;br /&gt;
From Moodle 2.7:&lt;br /&gt;
On (very few) pages - it is possible that page content is loaded by ajax *after* the page is loaded (e.g. equations in a glossary popup). In certain filter types (e.g. MathJax) javascript is required to be run on the output of the filter in order to do the final markup. For these types of filters, a javascript event is triggered when new content is added to the page (the content will have already been processed by the filter in php). The javascript for a filter can listen for these event notifications and reprocess the affected dom nodes. &lt;br /&gt;
&lt;br /&gt;
To subscribe to the event:&lt;br /&gt;
&lt;br /&gt;
        // Listen for events triggered when new text is added to a page that needs                                                  &lt;br /&gt;
        // processing by a filter.                                                                                                  &lt;br /&gt;
        Y.on(M.core.event.FILTER_CONTENT_UPDATED, this.contentUpdated, this);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To handle the event:&lt;br /&gt;
&lt;br /&gt;
    /**                                                                                                                             &lt;br /&gt;
     * Handle content updated events - typeset the new content.                                                                     &lt;br /&gt;
     * @method contentUpdated                                                                                                       &lt;br /&gt;
     * @param Y.Event - Custom event with &amp;quot;nodes&amp;quot; indicating the root of the updated nodes.                                         &lt;br /&gt;
     */                                                                                                                             &lt;br /&gt;
    contentUpdated: function(event) {                                                                                               &lt;br /&gt;
        var self = this;                                                                                                            &lt;br /&gt;
        Y.use(&#039;mathjax&#039;, function() {                                                                                               &lt;br /&gt;
            self._setLocale();                                                                                                      &lt;br /&gt;
            event.nodes.each(function (node) {                                                                                      &lt;br /&gt;
                node.all(&#039;.filter_mathjaxloader_equation&#039;).each(function(node) {                                                    &lt;br /&gt;
                    MathJax.Hub.Queue([&amp;quot;Typeset&amp;quot;, MathJax.Hub, node.getDOMNode()]);                                                 &lt;br /&gt;
                });                                                                                                                 &lt;br /&gt;
            });                                                                                                                     &lt;br /&gt;
        });                                                                                                                         &lt;br /&gt;
    }                      &lt;br /&gt;
&lt;br /&gt;
See: filter/mathjaxloader/yui/src/loader/js/loader.js&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Filters schema]] - a page containing some ideas and thoughts about modifications to the filters system&lt;br /&gt;
* [[:en:Filters]] user documentation about filters.&lt;br /&gt;
* [https://moodle.org/plugins/browse.php?list=category&amp;amp;id=7 - List of filters in the Plugins database].&lt;br /&gt;
&lt;br /&gt;
[[Category:Filter]]&lt;br /&gt;
[[Category:Plugins]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Filters&amp;diff=46761</id>
		<title>Filters</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Filters&amp;diff=46761"/>
		<updated>2014-11-10T20:23:21Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;&#039;&#039;&#039;Please note:&#039;&#039;&#039; This page contains information for developers. You may prefer to read the [[:en:Filters| information about filters for teachers and administrators]].&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Filters&#039;&#039;&#039; are a way to automatically transform content before it is output. For example&lt;br /&gt;
* render embedded equations to images (the TeX filter)&lt;br /&gt;
* Links to media files can be automatically converted to an embedded applet for playing the media.&lt;br /&gt;
* Mentions of glossary terms can be automatically converted to links.&lt;br /&gt;
The possibilities are endless. There are a number of standard filters included with Moodle, or you can create your own. Filters are one of the easiest types of plugin to create. This page explains how.&lt;br /&gt;
&lt;br /&gt;
==Before you start==&lt;br /&gt;
&lt;br /&gt;
Go to  Site administration ▶ Plugins ▶ Filters ▶ Common filter settings and set Text cache lifetime to 0 (&amp;quot;No&amp;quot;) while you do development. Otherwise, you will not be able to see the effects of your changes when you edit your filter&#039;s code. (You should also be using the other common developer settings, like developer debug, theme designer mode and so on.)&lt;br /&gt;
&lt;br /&gt;
==Creating a basic filter==&lt;br /&gt;
&lt;br /&gt;
During this tutorial, we will build a simple example filter. We will make one that adds the word &#039;hello&#039; before every occurrence of the word &#039;world&#039;.&lt;br /&gt;
&lt;br /&gt;
1. Since our filter is not part of a module, we should put it inside the &#039;filter&#039; folder. Therefore, we create a directory called &#039;filter/helloworld&#039;.&lt;br /&gt;
&lt;br /&gt;
2. Inside that folder, we create a file called &#039;filter.php&#039;.&lt;br /&gt;
&lt;br /&gt;
3. Inside that PHP file, we define a class called filter_helloworld, that extends the moodle_text_filter class.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
class filter_helloworld extends moodle_text_filter {&lt;br /&gt;
    // ...&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Inside that class, we have to define one method, called &#039;filter&#039;. This takes the HTML to be filtered as an argument. The method should then transform that, and return the processed text. Replace the &#039;// ...&#039; above with&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
class filter_helloworld extends moodle_text_filter {&lt;br /&gt;
    public function filter($text, array $options = array()) {&lt;br /&gt;
        return str_replace(&#039;world&#039;, &#039;hello world!&#039;, $text);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That is basically all there is to it!&lt;br /&gt;
&lt;br /&gt;
==Giving your filter a name==&lt;br /&gt;
&lt;br /&gt;
To try the new filter, you first have to log in as Administrator and enable it by going to the page Administration ► Plugins ► Filters ► Manage filters.&lt;br /&gt;
&lt;br /&gt;
When you do, you will find that your plugin does not have a name. We missed a step:&lt;br /&gt;
&lt;br /&gt;
5. Inside the &#039;filter/helloworld&#039; folder, create a folder called &#039;lang&#039;, and in there, create a folder called &#039;en&#039;.&lt;br /&gt;
&lt;br /&gt;
6. Inside there, create a file called &#039;filter_helloworld.php&#039;. That is, you have just created the file &#039;filter/helloworld/lang/en/filter_helloworld.php&#039;.&lt;br /&gt;
&lt;br /&gt;
7. In that file, put&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php // $Id$&lt;br /&gt;
// Language string for filter/helloworld.&lt;br /&gt;
&lt;br /&gt;
$string[&#039;filtername&#039;] = &#039;Hello world!&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That may seem a little involved, just to give your filter a name, but it is just [[Places_to_search_for_lang_strings|the standard way Moodle stores language strings for plugins]].&lt;br /&gt;
&lt;br /&gt;
==Trying out your filter==&lt;br /&gt;
&lt;br /&gt;
We had just got to the [[Filters|filters administration screen]]. If you reload that page now, it should now show your filter with its proper name. Turn your filter on now.&lt;br /&gt;
&lt;br /&gt;
Filters are applied to all text that is printed with the [[Output functions|output functions]] format_text(), and, if you have turned on that option, format_string(). So, to see your filter in action, add some content containing the word &#039;world&#039; somewhere, for example, create a test course, and use the word in the course description. When you look at that course in the course listing, you should see that your filter has transformed it.&lt;br /&gt;
&lt;br /&gt;
==Adding a global settings screen==&lt;br /&gt;
&lt;br /&gt;
Some filters can benefit from some settings to let the administrator control how they work. Suppose we want to greet something other than &#039;world&#039;. To add global settings to the filter you need to:&lt;br /&gt;
&lt;br /&gt;
8. Create a file called &#039;filtersettings.php&#039; inside the &#039;filter/helloworld&#039; folder. Use standard &#039;settings.php&#039; file in Moodle 2.6 and later.&lt;br /&gt;
&lt;br /&gt;
9. In the &#039;filtersettings.php&#039; file, put something like:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$settings-&amp;gt;add(new admin_setting_configtext(&#039;filter_helloworld_word&#039;,&lt;br /&gt;
        get_string(&#039;word&#039;, &#039;filter_helloworld&#039;),&lt;br /&gt;
        get_string(&#039;word_desc&#039;, &#039;filter_helloworld&#039;), &#039;world&#039;, PARAM_NOTAGS));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
10. In the language file &#039;filter/helloworld/lang/en/filter_helloworld.php&#039; add the necessary strings:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;word&#039;] = &#039;The thing to greet&#039;;&lt;br /&gt;
$string[&#039;word_desc&#039;] = &#039;The hello world filter will add the word \&#039;hello\&#039; in front of every occurrence of this word in any content.&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
11. Change the filter to use the new setting:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
class filter_helloworld extends moodle_text_filter {&lt;br /&gt;
    public function filter($text, array $options = array()) {&lt;br /&gt;
        global $CFG;&lt;br /&gt;
        return str_replace($CFG-&amp;gt;filter_helloworld_word,&lt;br /&gt;
                &amp;quot;hello $CFG-&amp;gt;filter_helloworld_word!&amp;quot;, $text);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In standard Moodle, the censor, mediaplugin and tex filters all provide good examples of of how filters use global configuration like this.&lt;br /&gt;
&lt;br /&gt;
==A note about performance==&lt;br /&gt;
&lt;br /&gt;
One important thing to remember when creating a filter is that the filter will be called to transform every bit of text output using format_text(), and possibly also format_string(). That means that you have to be careful, or you could cause big performance problems. If you have to get data out of the database, try to cache it so that you only do a fixed number of database queries per page load. The Glossary filter is an example of this. (I am not sure how good an example ;-))&lt;br /&gt;
&lt;br /&gt;
==Local configuration==&lt;br /&gt;
&lt;br /&gt;
In addition, in Moodle 2.0, filters can also have different configuration in each context. For example, the glossary could be changes so that in Forum A, you can choose to only link words from a particular glossary, sat Glossary A, while in Forum B you choose to link words from Glossary B.&lt;br /&gt;
&lt;br /&gt;
To do that sort of thing, you need to add a file called filterlocalsettings.php. In it, you must define a [[lib/formslib.php|Moodle form]] that is a subclass of filter_local_settings_form. In addition to the standard formslib methods, you also need to define a save_changes method. There is not a good example of this in the standard Moodle install yet. To continue our example:&lt;br /&gt;
&lt;br /&gt;
12. Create a file called &#039;filterlocalsettings.php&#039; inside the &#039;filter/helloworld&#039; folder.&lt;br /&gt;
&lt;br /&gt;
13. In the &#039;filterlocalsettings.php&#039; file, put:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
class helloworld_filter_local_settings_form extends filter_local_settings_form {&lt;br /&gt;
    protected function definition_inner($mform) {&lt;br /&gt;
        $mform-&amp;gt;addElement(&#039;text&#039;, &#039;word&#039;, get_string(&#039;word&#039;, &#039;filter_helloworld&#039;), array(&#039;size&#039; =&amp;gt; 20));&lt;br /&gt;
        $mform-&amp;gt;setType(&#039;word&#039;, PARAM_NOTAGS);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
14. Extend the filter to use the new setting, if it is present. The filter must be able to work if the setting is not set, for example by falling back to the global or default setting in this case&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
class filter_helloworld extends moodle_text_filter {&lt;br /&gt;
    public function filter($text, array $options = array()) {&lt;br /&gt;
        global $CFG;&lt;br /&gt;
        if (isset($this-&amp;gt;localconfig[&#039;word&#039;])) {&lt;br /&gt;
            $word = $this-&amp;gt;localconfig[&#039;word&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            $word = $CFG-&amp;gt;filter_helloworld_word;&lt;br /&gt;
        }&lt;br /&gt;
        return str_replace($word, &amp;quot;hello $word!&amp;quot;, $text);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Two types of filter==&lt;br /&gt;
&lt;br /&gt;
In the past, Moodle supported two different types of filter:&lt;br /&gt;
* Stand-alone filters like the one we created above. These live in a folder inside the &#039;filter&#039; folder. For example, in &#039;filter/myfilter&#039;. &#039;filter/tex&#039; is an example of a core filter of this type.&lt;br /&gt;
* Filters that were part of an activity module. In this case, the filter code lives inside the &#039;mod/mymod&#039; folder. &#039;mod/glossary&#039; used to be an example of a core module with a filter.&lt;br /&gt;
The second option no longer exists in Moodle 2.5 and later. All filters live in the filter folder. Of course, a filter may depend on an associated other plugin, like mod_glossary. If so, you should declare that in the [[version.php]] file.&lt;br /&gt;
&lt;br /&gt;
==Dynamic content==&lt;br /&gt;
&lt;br /&gt;
From Moodle 2.7:&lt;br /&gt;
On (very few) pages - it is possible that page content is loaded by ajax *after* the page is loaded (e.g. equations in a glossary popup). In certain filter types (e.g. MathJax) javascript is required to be run on the output of the filter in order to do the final markup. For these types of filters, a javascript event is triggered when new content is added to the page (the content will have already been processed by the filter in php). The javascript for a filter can listen for these event notifications and reprocess the affected dom nodes. &lt;br /&gt;
&lt;br /&gt;
To subscribe to the event:&lt;br /&gt;
&lt;br /&gt;
        // Listen for events triggered when new text is added to a page that needs                                                  &lt;br /&gt;
        // processing by a filter.                                                                                                  &lt;br /&gt;
        Y.on(M.core.event.FILTER_CONTENT_UPDATED, this.contentUpdated, this);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To handle the event:&lt;br /&gt;
&lt;br /&gt;
    /**                                                                                                                             &lt;br /&gt;
     * Handle content updated events - typeset the new content.                                                                     &lt;br /&gt;
     * @method contentUpdated                                                                                                       &lt;br /&gt;
     * @param Y.Event - Custom event with &amp;quot;nodes&amp;quot; indicating the root of the updated nodes.                                         &lt;br /&gt;
     */                                                                                                                             &lt;br /&gt;
    contentUpdated: function(event) {                                                                                               &lt;br /&gt;
        var self = this;                                                                                                            &lt;br /&gt;
        Y.use(&#039;mathjax&#039;, function() {                                                                                               &lt;br /&gt;
            self._setLocale();                                                                                                      &lt;br /&gt;
            event.nodes.each(function (node) {                                                                                      &lt;br /&gt;
                node.all(&#039;.filter_mathjaxloader_equation&#039;).each(function(node) {                                                    &lt;br /&gt;
                    MathJax.Hub.Queue([&amp;quot;Typeset&amp;quot;, MathJax.Hub, node.getDOMNode()]);                                                 &lt;br /&gt;
                });                                                                                                                 &lt;br /&gt;
            });                                                                                                                     &lt;br /&gt;
        });                                                                                                                         &lt;br /&gt;
    }                      &lt;br /&gt;
&lt;br /&gt;
See: filter/mathjaxloader/yui/src/loader/js/loader.js&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Filters schema]] - a page containing some ideas and thoughts about modifications to the filters system&lt;br /&gt;
* [[:en:Filters]] user documentation about filters.&lt;br /&gt;
* [https://moodle.org/plugins/browse.php?list=category&amp;amp;id=7 - List of filters in the Plugins database].&lt;br /&gt;
&lt;br /&gt;
[[Category:Filter]]&lt;br /&gt;
[[Category:Plugins]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Filters&amp;diff=46760</id>
		<title>Filters</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Filters&amp;diff=46760"/>
		<updated>2014-11-10T20:23:02Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: Broken link - forgot to put language prefix&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;&#039;&#039;&#039;Please note:&#039;&#039;&#039; This page contains information for developers. You may prefer to read the [[:en:Filters| information about filters for teachers and administrators]].&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Filters&#039;&#039;&#039; are a way to automatically transform content before it is output. For example&lt;br /&gt;
* render embedded equations to images (the TeX filter)&lt;br /&gt;
* Links to media files can be automatically converted to an embedded applet for playing the media.&lt;br /&gt;
* Mentions of glossary terms can be automatically converted to links.&lt;br /&gt;
The possibilities are endless. There are a number of standard filters included with Moodle, or you can create your own. Filters are one of the easiest types of plugin to create. This page explains how.&lt;br /&gt;
&lt;br /&gt;
==Before you start==&lt;br /&gt;
&lt;br /&gt;
Go to  Site administration ▶ Plugins ▶ Filters ▶ Common filter settings and set Text cache lifetime to 0 (&amp;quot;No&amp;quot;) while you do development. Otherwise, you will not be able to see the effects of your changes when you edit your filter&#039;s code. (You should also be using the other common developer settings, like developer debug, theme designer mode and so on.)&lt;br /&gt;
&lt;br /&gt;
==Creating a basic filter==&lt;br /&gt;
&lt;br /&gt;
During this tutorial, we will build a simple example filter. We will make one that adds the word &#039;hello&#039; before every occurrence of the word &#039;world&#039;.&lt;br /&gt;
&lt;br /&gt;
1. Since our filter is not part of a module, we should put it inside the &#039;filter&#039; folder. Therefore, we create a directory called &#039;filter/helloworld&#039;.&lt;br /&gt;
&lt;br /&gt;
2. Inside that folder, we create a file called &#039;filter.php&#039;.&lt;br /&gt;
&lt;br /&gt;
3. Inside that PHP file, we define a class called filter_helloworld, that extends the moodle_text_filter class.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
class filter_helloworld extends moodle_text_filter {&lt;br /&gt;
    // ...&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Inside that class, we have to define one method, called &#039;filter&#039;. This takes the HTML to be filtered as an argument. The method should then transform that, and return the processed text. Replace the &#039;// ...&#039; above with&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
class filter_helloworld extends moodle_text_filter {&lt;br /&gt;
    public function filter($text, array $options = array()) {&lt;br /&gt;
        return str_replace(&#039;world&#039;, &#039;hello world!&#039;, $text);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That is basically all there is to it!&lt;br /&gt;
&lt;br /&gt;
==Giving your filter a name==&lt;br /&gt;
&lt;br /&gt;
To try the new filter, you first have to log in as Administrator and enable it by going to the page Administration ► Plugins ► Filters ► Manage filters.&lt;br /&gt;
&lt;br /&gt;
When you do, you will find that your plugin does not have a name. We missed a step:&lt;br /&gt;
&lt;br /&gt;
5. Inside the &#039;filter/helloworld&#039; folder, create a folder called &#039;lang&#039;, and in there, create a folder called &#039;en&#039;.&lt;br /&gt;
&lt;br /&gt;
6. Inside there, create a file called &#039;filter_helloworld.php&#039;. That is, you have just created the file &#039;filter/helloworld/lang/en/filter_helloworld.php&#039;.&lt;br /&gt;
&lt;br /&gt;
7. In that file, put&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php // $Id$&lt;br /&gt;
// Language string for filter/helloworld.&lt;br /&gt;
&lt;br /&gt;
$string[&#039;filtername&#039;] = &#039;Hello world!&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That may seem a little involved, just to give your filter a name, but it is just [[Places_to_search_for_lang_strings|the standard way Moodle stores language strings for plugins]].&lt;br /&gt;
&lt;br /&gt;
==Trying out your filter==&lt;br /&gt;
&lt;br /&gt;
We had just got to the [[Filters|filters administration screen]]. If you reload that page now, it should now show your filter with its proper name. Turn your filter on now.&lt;br /&gt;
&lt;br /&gt;
Filters are applied to all text that is printed with the [[Output functions|output functions]] format_text(), and, if you have turned on that option, format_string(). So, to see your filter in action, add some content containing the word &#039;world&#039; somewhere, for example, create a test course, and use the word in the course description. When you look at that course in the course listing, you should see that your filter has transformed it.&lt;br /&gt;
&lt;br /&gt;
==Adding a global settings screen==&lt;br /&gt;
&lt;br /&gt;
Some filters can benefit from some settings to let the administrator control how they work. Suppose we want to greet something other than &#039;world&#039;. To add global settings to the filter you need to:&lt;br /&gt;
&lt;br /&gt;
8. Create a file called &#039;filtersettings.php&#039; inside the &#039;filter/helloworld&#039; folder. Use standard &#039;settings.php&#039; file in Moodle 2.6 and later.&lt;br /&gt;
&lt;br /&gt;
9. In the &#039;filtersettings.php&#039; file, put something like:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$settings-&amp;gt;add(new admin_setting_configtext(&#039;filter_helloworld_word&#039;,&lt;br /&gt;
        get_string(&#039;word&#039;, &#039;filter_helloworld&#039;),&lt;br /&gt;
        get_string(&#039;word_desc&#039;, &#039;filter_helloworld&#039;), &#039;world&#039;, PARAM_NOTAGS));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
10. In the language file &#039;filter/helloworld/lang/en/filter_helloworld.php&#039; add the necessary strings:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;word&#039;] = &#039;The thing to greet&#039;;&lt;br /&gt;
$string[&#039;word_desc&#039;] = &#039;The hello world filter will add the word \&#039;hello\&#039; in front of every occurrence of this word in any content.&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
11. Change the filter to use the new setting:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
class filter_helloworld extends moodle_text_filter {&lt;br /&gt;
    public function filter($text, array $options = array()) {&lt;br /&gt;
        global $CFG;&lt;br /&gt;
        return str_replace($CFG-&amp;gt;filter_helloworld_word,&lt;br /&gt;
                &amp;quot;hello $CFG-&amp;gt;filter_helloworld_word!&amp;quot;, $text);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In standard Moodle, the censor, mediaplugin and tex filters all provide good examples of of how filters use global configuration like this.&lt;br /&gt;
&lt;br /&gt;
==A note about performance==&lt;br /&gt;
&lt;br /&gt;
One important thing to remember when creating a filter is that the filter will be called to transform every bit of text output using format_text(), and possibly also format_string(). That means that you have to be careful, or you could cause big performance problems. If you have to get data out of the database, try to cache it so that you only do a fixed number of database queries per page load. The Glossary filter is an example of this. (I am not sure how good an example ;-))&lt;br /&gt;
&lt;br /&gt;
==Local configuration==&lt;br /&gt;
&lt;br /&gt;
In addition, in Moodle 2.0, filters can also have different configuration in each context. For example, the glossary could be changes so that in Forum A, you can choose to only link words from a particular glossary, sat Glossary A, while in Forum B you choose to link words from Glossary B.&lt;br /&gt;
&lt;br /&gt;
To do that sort of thing, you need to add a file called filterlocalsettings.php. In it, you must define a [[lib/formslib.php|Moodle form]] that is a subclass of filter_local_settings_form. In addition to the standard formslib methods, you also need to define a save_changes method. There is not a good example of this in the standard Moodle install yet. To continue our example:&lt;br /&gt;
&lt;br /&gt;
12. Create a file called &#039;filterlocalsettings.php&#039; inside the &#039;filter/helloworld&#039; folder.&lt;br /&gt;
&lt;br /&gt;
13. In the &#039;filterlocalsettings.php&#039; file, put:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
class helloworld_filter_local_settings_form extends filter_local_settings_form {&lt;br /&gt;
    protected function definition_inner($mform) {&lt;br /&gt;
        $mform-&amp;gt;addElement(&#039;text&#039;, &#039;word&#039;, get_string(&#039;word&#039;, &#039;filter_helloworld&#039;), array(&#039;size&#039; =&amp;gt; 20));&lt;br /&gt;
        $mform-&amp;gt;setType(&#039;word&#039;, PARAM_NOTAGS);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
14. Extend the filter to use the new setting, if it is present. The filter must be able to work if the setting is not set, for example by falling back to the global or default setting in this case&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
class filter_helloworld extends moodle_text_filter {&lt;br /&gt;
    public function filter($text, array $options = array()) {&lt;br /&gt;
        global $CFG;&lt;br /&gt;
        if (isset($this-&amp;gt;localconfig[&#039;word&#039;])) {&lt;br /&gt;
            $word = $this-&amp;gt;localconfig[&#039;word&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            $word = $CFG-&amp;gt;filter_helloworld_word;&lt;br /&gt;
        }&lt;br /&gt;
        return str_replace($word, &amp;quot;hello $word!&amp;quot;, $text);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Two types of filter==&lt;br /&gt;
&lt;br /&gt;
In the past, Moodle supported two different types of filter:&lt;br /&gt;
* Stand-alone filters like the one we created above. These live in a folder inside the &#039;filter&#039; folder. For example, in &#039;filter/myfilter&#039;. &#039;filter/tex&#039; is an example of a core filter of this type.&lt;br /&gt;
* Filters that were part of an activity module. In this case, the filter code lives inside the &#039;mod/mymod&#039; folder. &#039;mod/glossary&#039; used to be an example of a core module with a filter.&lt;br /&gt;
The second option no longer exists in Moodle 2.5 and later. All filters live in the filter folder. Of course, a filter may depend on an associated other plugin, like mod_glossary. If so, you should declare that in the [[version.php]] file.&lt;br /&gt;
&lt;br /&gt;
==Dynamic content==&lt;br /&gt;
&lt;br /&gt;
From Moodle 2.7:&lt;br /&gt;
On (very few) pages - it is possible that page content is loaded by ajax *after* the page is loaded (e.g. equations in a glossary popup). In certain filter types (e.g. MathJax) javascript is required to be run on the output of the filter in order to do the final markup. For these types of filters, a javascript event is triggered when new content is added to the page (the content will have already been processed by the filter in php). The javascript for a filter can listen for these event notifications and reprocess the affected dom nodes. &lt;br /&gt;
&lt;br /&gt;
To subscribe to the event:&lt;br /&gt;
&lt;br /&gt;
        // Listen for events triggered when new text is added to a page that needs                                                  &lt;br /&gt;
        // processing by a filter.                                                                                                  &lt;br /&gt;
        Y.on(M.core.event.FILTER_CONTENT_UPDATED, this.contentUpdated, this);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To handle the event:&lt;br /&gt;
&lt;br /&gt;
    /**                                                                                                                             &lt;br /&gt;
     * Handle content updated events - typeset the new content.                                                                     &lt;br /&gt;
     * @method contentUpdated                                                                                                       &lt;br /&gt;
     * @param Y.Event - Custom event with &amp;quot;nodes&amp;quot; indicating the root of the updated nodes.                                         &lt;br /&gt;
     */                                                                                                                             &lt;br /&gt;
    contentUpdated: function(event) {                                                                                               &lt;br /&gt;
        var self = this;                                                                                                            &lt;br /&gt;
        Y.use(&#039;mathjax&#039;, function() {                                                                                               &lt;br /&gt;
            self._setLocale();                                                                                                      &lt;br /&gt;
            event.nodes.each(function (node) {                                                                                      &lt;br /&gt;
                node.all(&#039;.filter_mathjaxloader_equation&#039;).each(function(node) {                                                    &lt;br /&gt;
                    MathJax.Hub.Queue([&amp;quot;Typeset&amp;quot;, MathJax.Hub, node.getDOMNode()]);                                                 &lt;br /&gt;
                });                                                                                                                 &lt;br /&gt;
            });                                                                                                                     &lt;br /&gt;
        });                                                                                                                         &lt;br /&gt;
    }                      &lt;br /&gt;
&lt;br /&gt;
See: filter/mathjaxloader/yui/src/loader/js/loader.js&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Filters schema]] - a page containing some ideas and thoughts about modifications to the filters system&lt;br /&gt;
* [[:en:Filters]] user documentation about filters.&lt;br /&gt;
* [https://moodle.org/plugins/browse.php?list=category&amp;amp;id=7 - List of filters in the Plugins database].&lt;br /&gt;
&lt;br /&gt;
[[Category:Filter]]&lt;br /&gt;
[[Category:Plugins]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Filters&amp;diff=46759</id>
		<title>Filters</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Filters&amp;diff=46759"/>
		<updated>2014-11-10T20:20:46Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: /* See also */ Link sending user back to this same page. Probably meant for /Filters&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;&#039;&#039;&#039;Please note:&#039;&#039;&#039; This page contains information for developers. You may prefer to read the [[:en:Filters| information about filters for teachers and administrators]].&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Filters&#039;&#039;&#039; are a way to automatically transform content before it is output. For example&lt;br /&gt;
* render embedded equations to images (the TeX filter)&lt;br /&gt;
* Links to media files can be automatically converted to an embedded applet for playing the media.&lt;br /&gt;
* Mentions of glossary terms can be automatically converted to links.&lt;br /&gt;
The possibilities are endless. There are a number of standard filters included with Moodle, or you can create your own. Filters are one of the easiest types of plugin to create. This page explains how.&lt;br /&gt;
&lt;br /&gt;
==Before you start==&lt;br /&gt;
&lt;br /&gt;
Go to  Site administration ▶ Plugins ▶ Filters ▶ Common filter settings and set Text cache lifetime to 0 (&amp;quot;No&amp;quot;) while you do development. Otherwise, you will not be able to see the effects of your changes when you edit your filter&#039;s code. (You should also be using the other common developer settings, like developer debug, theme designer mode and so on.)&lt;br /&gt;
&lt;br /&gt;
==Creating a basic filter==&lt;br /&gt;
&lt;br /&gt;
During this tutorial, we will build a simple example filter. We will make one that adds the word &#039;hello&#039; before every occurrence of the word &#039;world&#039;.&lt;br /&gt;
&lt;br /&gt;
1. Since our filter is not part of a module, we should put it inside the &#039;filter&#039; folder. Therefore, we create a directory called &#039;filter/helloworld&#039;.&lt;br /&gt;
&lt;br /&gt;
2. Inside that folder, we create a file called &#039;filter.php&#039;.&lt;br /&gt;
&lt;br /&gt;
3. Inside that PHP file, we define a class called filter_helloworld, that extends the moodle_text_filter class.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
class filter_helloworld extends moodle_text_filter {&lt;br /&gt;
    // ...&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Inside that class, we have to define one method, called &#039;filter&#039;. This takes the HTML to be filtered as an argument. The method should then transform that, and return the processed text. Replace the &#039;// ...&#039; above with&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
class filter_helloworld extends moodle_text_filter {&lt;br /&gt;
    public function filter($text, array $options = array()) {&lt;br /&gt;
        return str_replace(&#039;world&#039;, &#039;hello world!&#039;, $text);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That is basically all there is to it!&lt;br /&gt;
&lt;br /&gt;
==Giving your filter a name==&lt;br /&gt;
&lt;br /&gt;
To try the new filter, you first have to log in as Administrator and enable it by going to the page Administration ► Plugins ► Filters ► Manage filters.&lt;br /&gt;
&lt;br /&gt;
When you do, you will find that your plugin does not have a name. We missed a step:&lt;br /&gt;
&lt;br /&gt;
5. Inside the &#039;filter/helloworld&#039; folder, create a folder called &#039;lang&#039;, and in there, create a folder called &#039;en&#039;.&lt;br /&gt;
&lt;br /&gt;
6. Inside there, create a file called &#039;filter_helloworld.php&#039;. That is, you have just created the file &#039;filter/helloworld/lang/en/filter_helloworld.php&#039;.&lt;br /&gt;
&lt;br /&gt;
7. In that file, put&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php // $Id$&lt;br /&gt;
// Language string for filter/helloworld.&lt;br /&gt;
&lt;br /&gt;
$string[&#039;filtername&#039;] = &#039;Hello world!&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That may seem a little involved, just to give your filter a name, but it is just [[Places_to_search_for_lang_strings|the standard way Moodle stores language strings for plugins]].&lt;br /&gt;
&lt;br /&gt;
==Trying out your filter==&lt;br /&gt;
&lt;br /&gt;
We had just got to the [[Filters|filters administration screen]]. If you reload that page now, it should now show your filter with its proper name. Turn your filter on now.&lt;br /&gt;
&lt;br /&gt;
Filters are applied to all text that is printed with the [[Output functions|output functions]] format_text(), and, if you have turned on that option, format_string(). So, to see your filter in action, add some content containing the word &#039;world&#039; somewhere, for example, create a test course, and use the word in the course description. When you look at that course in the course listing, you should see that your filter has transformed it.&lt;br /&gt;
&lt;br /&gt;
==Adding a global settings screen==&lt;br /&gt;
&lt;br /&gt;
Some filters can benefit from some settings to let the administrator control how they work. Suppose we want to greet something other than &#039;world&#039;. To add global settings to the filter you need to:&lt;br /&gt;
&lt;br /&gt;
8. Create a file called &#039;filtersettings.php&#039; inside the &#039;filter/helloworld&#039; folder. Use standard &#039;settings.php&#039; file in Moodle 2.6 and later.&lt;br /&gt;
&lt;br /&gt;
9. In the &#039;filtersettings.php&#039; file, put something like:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$settings-&amp;gt;add(new admin_setting_configtext(&#039;filter_helloworld_word&#039;,&lt;br /&gt;
        get_string(&#039;word&#039;, &#039;filter_helloworld&#039;),&lt;br /&gt;
        get_string(&#039;word_desc&#039;, &#039;filter_helloworld&#039;), &#039;world&#039;, PARAM_NOTAGS));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
10. In the language file &#039;filter/helloworld/lang/en/filter_helloworld.php&#039; add the necessary strings:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;word&#039;] = &#039;The thing to greet&#039;;&lt;br /&gt;
$string[&#039;word_desc&#039;] = &#039;The hello world filter will add the word \&#039;hello\&#039; in front of every occurrence of this word in any content.&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
11. Change the filter to use the new setting:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
class filter_helloworld extends moodle_text_filter {&lt;br /&gt;
    public function filter($text, array $options = array()) {&lt;br /&gt;
        global $CFG;&lt;br /&gt;
        return str_replace($CFG-&amp;gt;filter_helloworld_word,&lt;br /&gt;
                &amp;quot;hello $CFG-&amp;gt;filter_helloworld_word!&amp;quot;, $text);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In standard Moodle, the censor, mediaplugin and tex filters all provide good examples of of how filters use global configuration like this.&lt;br /&gt;
&lt;br /&gt;
==A note about performance==&lt;br /&gt;
&lt;br /&gt;
One important thing to remember when creating a filter is that the filter will be called to transform every bit of text output using format_text(), and possibly also format_string(). That means that you have to be careful, or you could cause big performance problems. If you have to get data out of the database, try to cache it so that you only do a fixed number of database queries per page load. The Glossary filter is an example of this. (I am not sure how good an example ;-))&lt;br /&gt;
&lt;br /&gt;
==Local configuration==&lt;br /&gt;
&lt;br /&gt;
In addition, in Moodle 2.0, filters can also have different configuration in each context. For example, the glossary could be changes so that in Forum A, you can choose to only link words from a particular glossary, sat Glossary A, while in Forum B you choose to link words from Glossary B.&lt;br /&gt;
&lt;br /&gt;
To do that sort of thing, you need to add a file called filterlocalsettings.php. In it, you must define a [[lib/formslib.php|Moodle form]] that is a subclass of filter_local_settings_form. In addition to the standard formslib methods, you also need to define a save_changes method. There is not a good example of this in the standard Moodle install yet. To continue our example:&lt;br /&gt;
&lt;br /&gt;
12. Create a file called &#039;filterlocalsettings.php&#039; inside the &#039;filter/helloworld&#039; folder.&lt;br /&gt;
&lt;br /&gt;
13. In the &#039;filterlocalsettings.php&#039; file, put:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
class helloworld_filter_local_settings_form extends filter_local_settings_form {&lt;br /&gt;
    protected function definition_inner($mform) {&lt;br /&gt;
        $mform-&amp;gt;addElement(&#039;text&#039;, &#039;word&#039;, get_string(&#039;word&#039;, &#039;filter_helloworld&#039;), array(&#039;size&#039; =&amp;gt; 20));&lt;br /&gt;
        $mform-&amp;gt;setType(&#039;word&#039;, PARAM_NOTAGS);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
14. Extend the filter to use the new setting, if it is present. The filter must be able to work if the setting is not set, for example by falling back to the global or default setting in this case&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
class filter_helloworld extends moodle_text_filter {&lt;br /&gt;
    public function filter($text, array $options = array()) {&lt;br /&gt;
        global $CFG;&lt;br /&gt;
        if (isset($this-&amp;gt;localconfig[&#039;word&#039;])) {&lt;br /&gt;
            $word = $this-&amp;gt;localconfig[&#039;word&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            $word = $CFG-&amp;gt;filter_helloworld_word;&lt;br /&gt;
        }&lt;br /&gt;
        return str_replace($word, &amp;quot;hello $word!&amp;quot;, $text);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Two types of filter==&lt;br /&gt;
&lt;br /&gt;
In the past, Moodle supported two different types of filter:&lt;br /&gt;
* Stand-alone filters like the one we created above. These live in a folder inside the &#039;filter&#039; folder. For example, in &#039;filter/myfilter&#039;. &#039;filter/tex&#039; is an example of a core filter of this type.&lt;br /&gt;
* Filters that were part of an activity module. In this case, the filter code lives inside the &#039;mod/mymod&#039; folder. &#039;mod/glossary&#039; used to be an example of a core module with a filter.&lt;br /&gt;
The second option no longer exists in Moodle 2.5 and later. All filters live in the filter folder. Of course, a filter may depend on an associated other plugin, like mod_glossary. If so, you should declare that in the [[version.php]] file.&lt;br /&gt;
&lt;br /&gt;
==Dynamic content==&lt;br /&gt;
&lt;br /&gt;
From Moodle 2.7:&lt;br /&gt;
On (very few) pages - it is possible that page content is loaded by ajax *after* the page is loaded (e.g. equations in a glossary popup). In certain filter types (e.g. MathJax) javascript is required to be run on the output of the filter in order to do the final markup. For these types of filters, a javascript event is triggered when new content is added to the page (the content will have already been processed by the filter in php). The javascript for a filter can listen for these event notifications and reprocess the affected dom nodes. &lt;br /&gt;
&lt;br /&gt;
To subscribe to the event:&lt;br /&gt;
&lt;br /&gt;
        // Listen for events triggered when new text is added to a page that needs                                                  &lt;br /&gt;
        // processing by a filter.                                                                                                  &lt;br /&gt;
        Y.on(M.core.event.FILTER_CONTENT_UPDATED, this.contentUpdated, this);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To handle the event:&lt;br /&gt;
&lt;br /&gt;
    /**                                                                                                                             &lt;br /&gt;
     * Handle content updated events - typeset the new content.                                                                     &lt;br /&gt;
     * @method contentUpdated                                                                                                       &lt;br /&gt;
     * @param Y.Event - Custom event with &amp;quot;nodes&amp;quot; indicating the root of the updated nodes.                                         &lt;br /&gt;
     */                                                                                                                             &lt;br /&gt;
    contentUpdated: function(event) {                                                                                               &lt;br /&gt;
        var self = this;                                                                                                            &lt;br /&gt;
        Y.use(&#039;mathjax&#039;, function() {                                                                                               &lt;br /&gt;
            self._setLocale();                                                                                                      &lt;br /&gt;
            event.nodes.each(function (node) {                                                                                      &lt;br /&gt;
                node.all(&#039;.filter_mathjaxloader_equation&#039;).each(function(node) {                                                    &lt;br /&gt;
                    MathJax.Hub.Queue([&amp;quot;Typeset&amp;quot;, MathJax.Hub, node.getDOMNode()]);                                                 &lt;br /&gt;
                });                                                                                                                 &lt;br /&gt;
            });                                                                                                                     &lt;br /&gt;
        });                                                                                                                         &lt;br /&gt;
    }                      &lt;br /&gt;
&lt;br /&gt;
See: filter/mathjaxloader/yui/src/loader/js/loader.js&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Filters]] how to write filters for Moodle 1.9 and before. Note that a Moodle 1.9 filter will still work in Moodle 2.0, but you should still update your code when you get the chance.&lt;br /&gt;
* [[Filters schema]] - a page containing some ideas and thoughts about modifications to the filters system&lt;br /&gt;
* [[Filters]] user documentation about filters.&lt;br /&gt;
* [https://moodle.org/plugins/browse.php?list=category&amp;amp;id=7 - List of filters in the Plugins database].&lt;br /&gt;
&lt;br /&gt;
[[Category:Filters]]&lt;br /&gt;
[[Category:Filter]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Plugins]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=PHPUnit_integration&amp;diff=46379</id>
		<title>PHPUnit integration</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=PHPUnit_integration&amp;diff=46379"/>
		<updated>2014-10-06T20:04:46Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Moodle PHPUnit integration was created to simplify using of PHPUnit framework in Moodle. It consists of specialised bootstrap script, utility scripts that initialise testing environment and highly optimised custom test case classes that handle automatic global state resetting after test that includes global variables, database rollback and purging of dataroot. We also try to bridge the gap between the design and coding style of Moodle and PHPUnit.&lt;br /&gt;
&lt;br /&gt;
Most of the documentation at http://www.phpunit.de/manual/3.6/en/index.html is relevant to Moodle PHPUnit integration, exceptions and additions are described below.&lt;br /&gt;
&lt;br /&gt;
=Definitions=&lt;br /&gt;
These definitions may differ in each testing framework or programming language. The definitions here should be valid for PHPUnit framework with our Moodle tweaks.&lt;br /&gt;
&lt;br /&gt;
;Test suite: is a collection of test cases or other suites usually related to one area of the product. It is defined in PHPUnit configuration files (phpunit.xml by default).&lt;br /&gt;
&lt;br /&gt;
;Test file: is a file with *_test.php name which contains a test case. (*_Test.php in PHPUnit)&lt;br /&gt;
&lt;br /&gt;
;Test case: is a class with test methods. Moodle tests extend basic_testcase or advanced_testcase. (PHPUnit_Framework_TestCase in PHPUnit)&lt;br /&gt;
&lt;br /&gt;
;Test: is a public method starting with &amp;quot;test_&amp;quot; prefix defined in test case class. It is the implementation of the test procedure.&lt;br /&gt;
&lt;br /&gt;
;Assertion: is the actual comparison of expected and actual behaviour of the tested code.&lt;br /&gt;
&lt;br /&gt;
=Organisation of test files=&lt;br /&gt;
All testing related files are stored in &amp;lt;code&amp;gt;/tests/&amp;lt;/code&amp;gt; subdirectories:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;.../tests/*_test.php&amp;lt;/code&amp;gt; are PHPUnit test files&lt;br /&gt;
* &amp;lt;code&amp;gt;.../tests/fixtures/&amp;lt;/code&amp;gt; contains auxiliary files used in tests&lt;br /&gt;
* &amp;lt;code&amp;gt;.../tests/performance/&amp;lt;/code&amp;gt; is reserved for performance testing scripts&lt;br /&gt;
* &amp;lt;code&amp;gt;.../tests/other/&amp;lt;/code&amp;gt; is used for everything else that does not fit&lt;br /&gt;
&lt;br /&gt;
==Class and file naming rules==&lt;br /&gt;
The class names of all testcases need to be unique, Frankenstyle prefix is used to guarantee this. Since 2.6 it is possible to use automatic class loader when executing individual unit tests.&lt;br /&gt;
&lt;br /&gt;
* All test case classes start with Frankenstyle prefix, for example: &#039;&#039;&#039;mod_forum_&#039;&#039;&#039;, &#039;&#039;&#039;block_html_&#039;&#039;&#039;, &#039;&#039;&#039;core_&#039;&#039;&#039;.&lt;br /&gt;
* All test case classes end with &#039;&#039;&#039;_testcase&#039;&#039;&#039; suffix.&lt;br /&gt;
* File names are constructed from the class names - the Frankenstyle prefix is removed, suffix &#039;&#039;&#039;_testcase&#039;&#039;&#039; is replaced with &#039;&#039;&#039;_test&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
* class &#039;&#039;&#039;mod_forum_lib_testcase&#039;&#039;&#039; is expected in file &#039;&#039;&#039;/mod/forum/tests/lib_test.php&#039;&#039;&#039;, executed as &amp;lt;code&amp;gt;vendor/bin/phpunit mod_forum_lib_testcase&amp;lt;/code&amp;gt;&lt;br /&gt;
* class &#039;&#039;&#039;core_text_testcase&#039;&#039;&#039; is expected in file &#039;&#039;&#039;/lib/texts/text_test.php&#039;&#039;&#039;, executed as &amp;lt;code&amp;gt;vendor/bin/phpunit core_text_testcase&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=basic_testcase=&lt;br /&gt;
&#039;&#039;basic_testcase&#039;&#039; is useful for simple tests that do not modify database or global variables. If something accidentally changes global state the test fails. This test case class is nearly identical to PHPUnit_Framework_TestCase used in PHPUnit documentation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
class mod_myplugin_sample_basic_testcase extends basic_testcase {&lt;br /&gt;
    public function test_equals() {&lt;br /&gt;
        $a = 1 + 2;&lt;br /&gt;
        $this-&amp;gt;assertEquals(3, $a);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are no extra methods that could be used in tests. The expected file name for this test case is &#039;&#039;&#039;/mod/myplugin/tests/sample_basic_test.php&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=advanced_testcase=&lt;br /&gt;
By default each test starts with fresh new moodle installation. Test may modify database content, files or global variables. It is possible to use data generators to create new course, categories, module instances and other objects, alternatively table data can be preloaded from XML or CSV files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
class mod_myplugin_some_permission_testcase extends advanced_testcase {&lt;br /&gt;
    public function test_isadmin() {&lt;br /&gt;
        global $DB;&lt;br /&gt;
&lt;br /&gt;
        $this-&amp;gt;resetAfterTest(true);          // reset all changes automatically after this test&lt;br /&gt;
&lt;br /&gt;
        $this-&amp;gt;assertFalse(is_siteadmin());   // by default no user is logged-in&lt;br /&gt;
        $this-&amp;gt;setUser(2);                    // switch $USER&lt;br /&gt;
        $this-&amp;gt;assertTrue(is_siteadmin());    // admin is logged-in now&lt;br /&gt;
&lt;br /&gt;
        $DB-&amp;gt;delete_records(&#039;user&#039;, array()); // lets do something crazy&lt;br /&gt;
&lt;br /&gt;
        $this-&amp;gt;resetAllData();                // that was not a good idea, let&#039;s go back&lt;br /&gt;
        $this-&amp;gt;assertTrue($admin = $DB-&amp;gt;record_exists(&#039;user&#039;, array(&#039;id&#039;=&amp;gt;2)));&lt;br /&gt;
        $this-&amp;gt;assertFalse(is_siteadmin());&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The expected file name for this test case is &#039;&#039;&#039;/mod/myplugin/tests/some_permission_test.php&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Extra methods==&lt;br /&gt;
; resetAfterTest(bool) : true means reset automatically after test, false means keep changes to next test method, default null means detect changes&lt;br /&gt;
; resetAllData() : reset global state in the middle of a test&lt;br /&gt;
; setAdminUser() : set current $USER as admin&lt;br /&gt;
; setGuestUser() : set current $USER as guest&lt;br /&gt;
; setUser() : set current $USER to a specific user - use getDataGenerator() to create one&lt;br /&gt;
; getDataGenerator() : returns data generator instance - use if you need to add new courses, users, etc.&lt;br /&gt;
; preventResetByRollback() : terminates active transactions, useful only when test contains own database transaction handling&lt;br /&gt;
; createXXXDataSet() : creates in memory structure of database table contents, used in loadDataSet() (eg: createXMLDataSet(), createCsvDataSet(), createFlatXMLDataSet())&lt;br /&gt;
; loadDataSet() : bulk loading of table contents&lt;br /&gt;
; getDebuggingMessages() : Return debugging messages from the current test. (Moodle 2.4 and upwards)&lt;br /&gt;
; resetDebugging() : Clear all previous debugging messages in current test. (Moodle 2.4 and upwards)&lt;br /&gt;
; assertDebuggingCalled() : Assert that exactly debugging was just called once. (Moodle 2.4 and upwards)&lt;br /&gt;
; assertDebuggingNotCalled() : Assert no debugging happened. (Moodle 2.4 and upwards)&lt;br /&gt;
; [[Writing PHPUnit tests#Testing sending of messages|redirectMessages()]]: Captures ongoing messages for later testing (Moodle 2.4 and upwards)&lt;br /&gt;
; [[Writing PHPUnit tests#Testing_sending_of_emails|redirectEmails()]]: Captures ongoing emails for later testing (Moodle 2.6 and upwards)&lt;br /&gt;
&lt;br /&gt;
==Restrictions==&lt;br /&gt;
* it is not possible to modify database structure such as create new table or drop columns from advanced_testcase.&lt;br /&gt;
&lt;br /&gt;
=Moodle specific features=&lt;br /&gt;
* detection of global state changes - helps with detection of unintended changes in database&lt;br /&gt;
* highly optimised global state reset&lt;br /&gt;
* dataset loading - this feature is copied from PHPUnit database testcases&lt;br /&gt;
* automatic generation of phpunit.xml - init script builds list of plugin testcases&lt;br /&gt;
* database driver testing class - used for functional DB tests&lt;br /&gt;
* SimpleTest emulation class - helps with migration of old tests&lt;br /&gt;
* debugging() interception - enables to control and test any expected debug output. (Moodle 2.4 and upwards)&lt;br /&gt;
&lt;br /&gt;
=Limitations=&lt;br /&gt;
* no Selenium support&lt;br /&gt;
* no support for PHPUnit_Extensions_Database_TestCase - it is possible to use data set loader only&lt;br /&gt;
&lt;br /&gt;
=See also=&lt;br /&gt;
* [[Writing PHPUnit tests]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Unit testing]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Enrolment_plugins&amp;diff=45327</id>
		<title>Enrolment plugins</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Enrolment_plugins&amp;diff=45327"/>
		<updated>2014-06-17T15:38:13Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Since Moodle 2.0 all enrolment plugins must extend [https://github.com/moodle/moodle/blob/master/lib/enrollib.php enrol_plugin] base class which is defined at the end of lib/enrollib.php. This base class contains all standard methods together with developer documentation.&lt;br /&gt;
&lt;br /&gt;
Course enrolment information is stored in tables &amp;lt;code&amp;gt;enrol&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;user_enrolments&amp;lt;/code&amp;gt; and optionally other custom database tables defined by individual enrolment plugins. Each plugin has complete total over own instance record and user enrolments, by defaults user enrolments are protected and can not be modified manually by teachers.&lt;br /&gt;
&lt;br /&gt;
Enrolment gives users following privileges:&lt;br /&gt;
* User with active enrolment may enter course, other users need either temporary guest access right or moodle/course:view capability.&lt;br /&gt;
* &amp;quot;My courses&amp;quot; shows list of active enrolments for current user.&lt;br /&gt;
* Course participation - some activities restrict participation to enrolled users only. The behaviour is defined independently by each activity, for example only enrolled users with submit capability may submit assignments, the capability alone is not enough.&lt;br /&gt;
* Only enrolled users may be members of groups.&lt;br /&gt;
* Gradebook tracks grades of all enrolled users, visibility of grades is controlled by role membership.&lt;br /&gt;
&lt;br /&gt;
Enrolments and role assignments are now separate concepts, you may be enrolled and not have any role and you may have a role in course and not be enrolled. Roles at course context level and below may be controlled by enrolment plugins.&lt;br /&gt;
&lt;br /&gt;
==User enrolment process==&lt;br /&gt;
&lt;br /&gt;
Manual enrolment plugins are the simplest way to handle user enrolments. This simplest plugin is enrol_manual, users with necessary permissions may enrol or unenrol users manually. enrol_flatfile plugin allows automation of enrolment and unernolment actions.&lt;br /&gt;
&lt;br /&gt;
Fully automatic plugins are configured at the system level, they synchronise user enrolments with information stored in external systems (ex.: enrol_ldap, enrol_database and enrol_category). Some non-interactive plugins may require configuration of enrolment instances (ex.: enrol_cohort and enrol_meta).&lt;br /&gt;
&lt;br /&gt;
Interactive enrolment plugins require user interaction during enrolment (ex.: enrol_self and enrol_paypal). These plugins need to override &amp;lt;code&amp;gt;enrol_plugin::show_enrolme_link()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;enrol_plugin::enrol_page_hook()&amp;lt;/code&amp;gt; and to implement adding and editing of enrol instance.&lt;br /&gt;
&lt;br /&gt;
==Enrolment expiration and suspending==&lt;br /&gt;
User has active enrolment if all following conditions are met:&lt;br /&gt;
* user has record in &amp;lt;code&amp;gt;user_enrolments&amp;lt;/code&amp;gt; table,&lt;br /&gt;
* user enrolment already started,&lt;br /&gt;
* user enrolment is not past timeend,&lt;br /&gt;
* user enrolment has active status,&lt;br /&gt;
* enrol instance has active status in &amp;lt;code&amp;gt;enrol&amp;lt;/code&amp;gt; table,&lt;br /&gt;
* enrol plugin is enabled.&lt;br /&gt;
&lt;br /&gt;
Most synchronisation plugins include a setting called &#039;&#039;External unenrol action&#039;&#039;. It is used to decide what happens when previously enrolled user is not supposed to be enrolled any more. Synchronisation is usually executed from cli/sync.php or as part of standard cron.&lt;br /&gt;
&lt;br /&gt;
Time based expiration was implemented in Moodle 2.5. Plugins that set timeend in user_enrolments table may want to specify expiration action and optional expiration notification, see &amp;lt;code&amp;gt;enrol_plugin::process_expirations()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;enrol_plugin::send_expiry_notifications()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Manual enrolment modifications==&lt;br /&gt;
&lt;br /&gt;
The standard user enrolment UI does not use the following methods directly, so developers need to describe all possible UI enrolments actions via &amp;lt;code&amp;gt;enrol_plugin::get_user_enrolment_actions()&amp;lt;/code&amp;gt;. It is very important to obey these restrictions in all externallib methods!&lt;br /&gt;
&lt;br /&gt;
The following methods describe the allowed modifications for each enrolment instance:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;enrol_plugin::roles_protected()&amp;lt;/code&amp;gt; - True means that protected roles (nonempty component+itemid) cannot be modified by any other plugin. Return false if you want to allow users to remove all roles assigned by this plugin. Since Moodle 2.5 it is allowed to assign roles with component+itemid even if roles are not protected.&lt;br /&gt;
* &amp;lt;code&amp;gt;enrol_plugin::allow_enrol()&amp;lt;/code&amp;gt; - True means other code may call &amp;lt;code&amp;gt;enrol_plugin::enrol_user()&amp;lt;/code&amp;gt;, false means only plugin may enrol users. Each plugin is responsible for implementing its own UI for enrolment. See &amp;lt;code&amp;gt;enrol_plugin::get_manual_enrol_link()&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;enrol_plugin::allow_unenrol()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;enrol_plugin::allow_unenrol_user()&amp;lt;/code&amp;gt; - Is other code allowed to unenrol everybody from one instance or one specific user? True is required for course reset and manual user unenrolment.&lt;br /&gt;
* &amp;lt;code&amp;gt;enrol_plugin:allow_manage()&amp;lt;/code&amp;gt; - Return true if plugin allows manual modification of user enrolments from other code. False is usually returned from plugins that synchronise data with external systems, otherwise the manual changes would be reverted immediately upon synchronisation.&lt;br /&gt;
&lt;br /&gt;
==Standard capabilities==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;enrol/xxx:enrol&#039;&#039;&#039; - Must be defined when &amp;lt;code&amp;gt;enrol_plugin::allow_enrol()&amp;lt;/code&amp;gt; returns true.&lt;br /&gt;
* &#039;&#039;&#039;enrol/xxx:unenrol&#039;&#039;&#039; - Must be implemented when &amp;lt;code&amp;gt;enrol_plugin::allow_unenrol()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;enrol_plugin::allow_unenrol_user()&amp;lt;/code&amp;gt; returns true.&lt;br /&gt;
* &#039;&#039;&#039;enrol/xxx:manage&#039;&#039;&#039; - Must be implemented when &amp;lt;code&amp;gt;enrol_plugin::allow_manage()&amp;lt;/code&amp;gt; returns true.&lt;br /&gt;
* &#039;&#039;&#039;enrol/xxx:unenrolself&#039;&#039;&#039; - Usually implemented when plugin support self-unenrolment.&lt;br /&gt;
* &#039;&#039;&#039;enrol/xxx:config&#039;&#039;&#039; - Implemented when plugin allows user to modify instance properties. Automatic synchronisation plugins do not usually need this capability.&lt;br /&gt;
&lt;br /&gt;
==Restore support==&lt;br /&gt;
&lt;br /&gt;
Enrolment and role restore is supported since Moodle 2.4, earlier versions can restore only manual and self enrolments.&lt;br /&gt;
&lt;br /&gt;
Plugins with automatic synchronisation may use &amp;lt;code&amp;gt;enrol_plugin:restore_sync_course()&amp;lt;/code&amp;gt; hook to synchronise enrolments in newly created courses. The restore process starts with instance restore which must set mapping information &amp;lt;code&amp;gt;enrol_plugin::restore_instance()&amp;lt;/code&amp;gt; (plugins may decide to map enrolments to other plugin type), then plugin must restore users enrolments &amp;lt;code&amp;gt;enrol_plugin::restore_user_enrolment()&amp;lt;/code&amp;gt;, protected roles &amp;lt;code&amp;gt;enrol_plugin::restore_role_assignment()&amp;lt;/code&amp;gt; and protected group membership &amp;lt;code&amp;gt;enrol_plugin::restore_group_member()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Enrolment API]]&lt;br /&gt;
* [[Enrolment usage overview]]&lt;br /&gt;
* [[New enrolments in 2.0]]&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]]&lt;br /&gt;
[[Category:Plugins]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Enrolment_plugins&amp;diff=45326</id>
		<title>Enrolment plugins</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Enrolment_plugins&amp;diff=45326"/>
		<updated>2014-06-17T13:28:30Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: /* Manual enrolment modifications */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Since Moodle 2.0 all enrolment plugins must extend [https://github.com/moodle/moodle/blob/master/lib/enrollib.php enrol_plugin] base class which is defined at the end of lib/enrollib.php. This base class contains all standard methods together with developer documentation.&lt;br /&gt;
&lt;br /&gt;
Course enrolment information is stored in tables &amp;lt;code&amp;gt;enrol&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;user_enrolments&amp;lt;/code&amp;gt; and optionally other custom database tables defined by individual enrolment plugins. Each plugin has complete total over own instance record and user enrolments, by defaults user enrolments are protected and can not be modified manually by teachers.&lt;br /&gt;
&lt;br /&gt;
Enrolment gives users following privileges:&lt;br /&gt;
* User with active enrolment may enter course, other users need either temporary guest access right or moodle/course:view capability.&lt;br /&gt;
* &amp;quot;My courses&amp;quot; shows list of active enrolments for current user.&lt;br /&gt;
* Course participation - some activities restrict participation to enrolled users only. The behaviour is defined independently by each activity, for example only enrolled users with submit capability may submit assignments, the capability alone is not enough.&lt;br /&gt;
* Only enrolled users may be members of groups.&lt;br /&gt;
* Gradebook tracks grades of all enrolled users, visibility of grades is controlled by role membership.&lt;br /&gt;
&lt;br /&gt;
Enrolments and role assignments are now separate concepts, you may be enrolled and not have any role and you may have a role in course and not be enrolled. Roles at course context level and bellow may be controlled by enrolment plugins.&lt;br /&gt;
&lt;br /&gt;
==User enrolment process==&lt;br /&gt;
&lt;br /&gt;
Manual enrolment plugins are the simplest way to handle user enrolments. This simplest plugin is enrol_manual, users with necessary permissions may enrol or unenrol users manually. enrol_flatfile plugin allows automation of enrolment and unernolment actions.&lt;br /&gt;
&lt;br /&gt;
Fully automatic plugins are configured at the system level, they synchronise user enrolments with information stored in external systems (ex.: enrol_ldap, enrol_database and enrol_category). Some non-interactive plugins may require configuration of enrolment instances (ex.: enrol_cohort and enrol_meta).&lt;br /&gt;
&lt;br /&gt;
Interactive enrolment plugins require user interaction during enrolment (ex.: enrol_self and enrol_paypal). These plugins need to override &amp;lt;code&amp;gt;enrol_plugin::show_enrolme_link()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;enrol_plugin::enrol_page_hook()&amp;lt;/code&amp;gt; and to implement adding and editing of enrol instance.&lt;br /&gt;
&lt;br /&gt;
==Enrolment expiration and suspending==&lt;br /&gt;
User has active enrolment if all following conditions are met:&lt;br /&gt;
* user has record in &amp;lt;code&amp;gt;user_enrolments&amp;lt;/code&amp;gt; table,&lt;br /&gt;
* user enrolment already started,&lt;br /&gt;
* user enrolment is not past timeend,&lt;br /&gt;
* user enrolment has active status,&lt;br /&gt;
* enrol instance has active status in &amp;lt;code&amp;gt;enrol&amp;lt;/code&amp;gt; table,&lt;br /&gt;
* enrol plugin is enabled.&lt;br /&gt;
&lt;br /&gt;
Most synchronisation plugins include a setting called &#039;&#039;External unenrol action&#039;&#039;. It is used to decide what happens when previously enrolled user is not supposed to be enrolled any more. Synchronisation is usually executed from cli/sync.php or as part of standard cron.&lt;br /&gt;
&lt;br /&gt;
Time based expiration was implemented in Moodle 2.5. Plugins that set timeend in user_enrolments table may want to specify expiration action and optional expiration notification, see &amp;lt;code&amp;gt;enrol_plugin::process_expirations()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;enrol_plugin::send_expiry_notifications()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Manual enrolment modifications==&lt;br /&gt;
&lt;br /&gt;
The standard user enrolment UI does not use the following methods directly, so developers need to describe all possible UI enrolments actions via &amp;lt;code&amp;gt;enrol_plugin::get_user_enrolment_actions()&amp;lt;/code&amp;gt;. It is very important to obey these restrictions in all externallib methods!&lt;br /&gt;
&lt;br /&gt;
The following methods describe the allowed modifications for each enrolment instance:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;enrol_plugin::roles_protected()&amp;lt;/code&amp;gt; - True means that protected roles (nonempty component+itemid) cannot be modified by any other plugin. Return false if you want to allow users to remove all roles assigned by this plugin. Since Moodle 2.5 it is allowed to assign roles with component+itemid even if roles are not protected.&lt;br /&gt;
* &amp;lt;code&amp;gt;enrol_plugin::allow_enrol()&amp;lt;/code&amp;gt; - True means other code may call &amp;lt;code&amp;gt;enrol_plugin::enrol_user()&amp;lt;/code&amp;gt;, false means only plugin may enrol users. Each plugin is responsible for implementing its own UI for enrolment. See &amp;lt;code&amp;gt;enrol_plugin::get_manual_enrol_link()&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;enrol_plugin::allow_unenrol()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;enrol_plugin::allow_unenrol_user()&amp;lt;/code&amp;gt; - Is other code allowed to unenrol everybody from one instance or one specific user? True is required for course reset and manual user unenrolment.&lt;br /&gt;
* &amp;lt;code&amp;gt;enrol_plugin:allow_manage()&amp;lt;/code&amp;gt; - Return true if plugin allows manual modification of user enrolments from other code. False is usually returned from plugins that synchronise data with external systems, otherwise the manual changes would be reverted immediately upon synchronisation.&lt;br /&gt;
&lt;br /&gt;
==Standard capabilities==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;enrol/xxx:enrol&#039;&#039;&#039; - Must be defined when &amp;lt;code&amp;gt;enrol_plugin::allow_enrol()&amp;lt;/code&amp;gt; returns true.&lt;br /&gt;
* &#039;&#039;&#039;enrol/xxx:unenrol&#039;&#039;&#039; - Must be implemented when &amp;lt;code&amp;gt;enrol_plugin::allow_unenrol()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;enrol_plugin::allow_unenrol_user()&amp;lt;/code&amp;gt; returns true.&lt;br /&gt;
* &#039;&#039;&#039;enrol/xxx:manage&#039;&#039;&#039; - Must be implemented when &amp;lt;code&amp;gt;enrol_plugin::allow_manage()&amp;lt;/code&amp;gt; returns true.&lt;br /&gt;
* &#039;&#039;&#039;enrol/xxx:unenrolself&#039;&#039;&#039; - Usually implemented when plugin support self-unenrolment.&lt;br /&gt;
* &#039;&#039;&#039;enrol/xxx:config&#039;&#039;&#039; - Implemented when plugin allows user to modify instance properties. Automatic synchronisation plugins do not usually need this capability.&lt;br /&gt;
&lt;br /&gt;
==Restore support==&lt;br /&gt;
&lt;br /&gt;
Enrolment and role restore is supported since Moodle 2.4, earlier versions can restore only manual and self enrolments.&lt;br /&gt;
&lt;br /&gt;
Plugins with automatic synchronisation may use &amp;lt;code&amp;gt;enrol_plugin:restore_sync_course()&amp;lt;/code&amp;gt; hook to synchronise enrolments in newly created courses. The restore process starts with instance restore which must set mapping information &amp;lt;code&amp;gt;enrol_plugin::restore_instance()&amp;lt;/code&amp;gt; (plugins may decide to map enrolments to other plugin type), then plugin must restore users enrolments &amp;lt;code&amp;gt;enrol_plugin::restore_user_enrolment()&amp;lt;/code&amp;gt;, protected roles &amp;lt;code&amp;gt;enrol_plugin::restore_role_assignment()&amp;lt;/code&amp;gt; and protected group membership &amp;lt;code&amp;gt;enrol_plugin::restore_group_member()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Enrolment API]]&lt;br /&gt;
* [[Enrolment usage overview]]&lt;br /&gt;
* [[New enrolments in 2.0]]&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]]&lt;br /&gt;
[[Category:Plugins]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Theme_changes_in_2.0&amp;diff=41203</id>
		<title>Theme changes in 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Theme_changes_in_2.0&amp;diff=41203"/>
		<updated>2013-07-05T18:01:32Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: /* Other API changes */ layouts are in base, not standard&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Infobox Project&lt;br /&gt;
|name = Theme changes&lt;br /&gt;
|state = Implementation&lt;br /&gt;
|tracker = MDL-20204&lt;br /&gt;
|discussion = [http://moodle.org/mod/forum/discuss.php?d=140089 HEADS UP: Major theme changes landing]&lt;br /&gt;
|assignee = [[User:Petr Škoda (škoďák)|Petr Škoda (škoďák)]] + feedback and ideas from other developers&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Goals=&lt;br /&gt;
The main goals are:&lt;br /&gt;
# easier theme customisations - both CSS and images&lt;br /&gt;
# simplify core and themes code&lt;br /&gt;
# significant performance improvements&lt;br /&gt;
# solve majority of browser caching problems&lt;br /&gt;
# use YUI CSS foundation&lt;br /&gt;
# allow themes to be stored in separate directory without www access (such as dataroot)&lt;br /&gt;
&lt;br /&gt;
It should be easy to upgrade simple older themes. I think it is better if old themes are completely disabled with reasonable fallback mechanism. Why should we display broken themes during upgrade? Imagine users or teachers can select &amp;quot;broken&amp;quot; themes in the course edit page or a profile, I think it is more professional to display only new and upgraded themes in selectors instead of pretending old themes will work 100%. We have to make sure old themes will not cause fatal white screen errors.&lt;br /&gt;
&lt;br /&gt;
=Design overview=&lt;br /&gt;
&lt;br /&gt;
All theme files are served through two files &#039;&#039;/theme/styles.php&#039;&#039; and &#039;&#039;/theme/image.php&#039;&#039;. More advanced themes may serve extra javascript files through the &#039;&#039;/theme/javascripts.php&#039;&#039; file and a new config option with list of JS files. This approach allows us to parse the resulting CSS and replace all image placeholders and theme settings with current values.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
All CSS style sheets (including YUI, plugin CSS and parent themes) are merged into a single large CSS file served via the /theme/styles.php file. This script accepts following parameters:&lt;br /&gt;
* &#039;&#039;&#039;theme&#039;&#039;&#039; (string) - name of the theme&lt;br /&gt;
* &#039;&#039;&#039;rev&#039;&#039;&#039; (int) - theme revision number stored in $CFG-&amp;gt;themerevision&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
All options and features are reviewed and optimised. Backwards compatibility is not a primary concern, future possibilities and easy maintenance are always favoured.&lt;br /&gt;
&lt;br /&gt;
==Theme directory structure==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &amp;lt;center&amp;gt;&#039;&#039;File/folder&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
! &amp;lt;center&amp;gt;&#039;&#039;&#039;Description&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| db/ (optional)&lt;br /&gt;
| Installation and upgrade hooks - use of db tables is not recommended.&lt;br /&gt;
|-&lt;br /&gt;
| lang/&lt;br /&gt;
| Folder with standard language files - name of theme, usage information, settings. Standard themes store lang files in /lang/ for now.&lt;br /&gt;
|-&lt;br /&gt;
| layout/*.php&lt;br /&gt;
| Folder with page layout templates&lt;br /&gt;
|-&lt;br /&gt;
| pix/&lt;br /&gt;
| Folder with theme pictures - used from CSS or layout only, not used from other plugins.&lt;br /&gt;
|-&lt;br /&gt;
| pix_core/ (optional)&lt;br /&gt;
| Folder with overridden core images and icons from /pix/ folder&lt;br /&gt;
|-&lt;br /&gt;
| pix_plugins/ (optional)&lt;br /&gt;
| Folder with overridden plugin icons - structure is typeofplugin/pluginname/ which maps to pix folder in plugins&lt;br /&gt;
|-&lt;br /&gt;
| style/*.css&lt;br /&gt;
| Style sheet files referenced from the config.php.&lt;br /&gt;
|-&lt;br /&gt;
| config.php&lt;br /&gt;
| Theme configuration - see bellow.&lt;br /&gt;
|-&lt;br /&gt;
| lib.php (optional)&lt;br /&gt;
| Library functions - custom css post-processing, custom render factory, theme init function&lt;br /&gt;
|-&lt;br /&gt;
| renderers.php (optional)&lt;br /&gt;
| Custom renderers used from custom renderer factories.&lt;br /&gt;
|-&lt;br /&gt;
| settings.php (optional)&lt;br /&gt;
| Custom theme settings - colours, logos, etc. Settings are applied in custom css post-processing function.&lt;br /&gt;
|-&lt;br /&gt;
| [[version.php]]&lt;br /&gt;
| Needed for install and upgrade hooks, states compatibility with specific Moodle versions. Used for triggering of cache purging.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Theme config.php==&lt;br /&gt;
&lt;br /&gt;
The theme config.php structure is simplified and a bit more flexible. The goal is to make overriding of parent themes simple and easy to understand. Please note global $THEME variable is not available any more, use theme property in current page instance instead.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;$THEME-&amp;gt;parents = array(&#039;standard&#039;, &#039;purple&#039;);&amp;lt;/code&amp;gt;&lt;br /&gt;
Lists all parents top-down, each theme contains the full list of parents, this is non-recursive and more flexible specification without any limits. Originally the number of parent levels was restricted.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;$THEME-&amp;gt;sheets = array(&#039;styles_layout&#039;, &#039;styles_fonts&#039;, &#039;styles_color&#039;);&amp;lt;/code&amp;gt;&lt;br /&gt;
The same as before, lists files from current theme directory.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;$THEME-&amp;gt;parents_exclude_sheets = array(&#039;standard&#039;=&amp;gt;array(&#039;styles_moz&#039;), &#039;purple&#039;=&amp;gt;array(&#039;styles_fonts&#039;));&amp;lt;/code&amp;gt;&lt;br /&gt;
It is also posssible to use &#039;&#039;true&#039;&#039; instead of array in order to specify &#039;&#039;all&#039;&#039; sheets or all sheets in all parents, if not specified the value from the parent theme is used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;$THEME-&amp;gt;editor_sheets = array(&#039;styles_tinymce&#039;);&amp;lt;/code&amp;gt;&lt;br /&gt;
We can not load the full CSS file into the HTML editor&#039;s content area, instead we load editor sheet from lib/editor/editorname/editor_sheets.css and also sheets specified in theme.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;$THEME-&amp;gt;plugins_exclude_sheets(&#039;mod_book&#039;, &#039;gradereport_grader&#039;);&amp;lt;/code&amp;gt;&lt;br /&gt;
Ideally all plugin specific CSS should be stored in styles.css file separately in each plugin. This option lists plugins that should be excluded from this theme, if not specified the value from the parent theme is used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;$THEME-&amp;gt;layouts = array(...);&amp;lt;/code&amp;gt;&lt;br /&gt;
The complete list of layouts is in theme/base/config.php. Page layouts are in fact high level templates that are using PHP syntax. The template files are stored in layout/ subdirectory. Each page layout has specification of block areas and link to template file. Themes may also reference layouts files from other themes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;$THEME-&amp;gt;resource_mp3player_colors, $THEME-&amp;gt;filter_mediaplugin_colors&amp;lt;/code&amp;gt;&lt;br /&gt;
Obsoleted. If not specified the value from the parent theme is used. All these should be moved to real theme settings.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;$THEME-&amp;gt;rendererfactory = &#039;standard_renderer_factory&#039;;&amp;lt;/code&amp;gt;&lt;br /&gt;
The same as before. It is the name of class that returns needed instances of core and plugin renderers. defined in core some library or theme/themename/lib.php or theme/themename/renderers.php&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;$THEME-&amp;gt;csspostprocess = &#039;csspostprocess&#039;;&amp;lt;/code&amp;gt;&lt;br /&gt;
Name of custom CSS post-processing function, this function is usually defined in theme/themename/lib.php.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$THEME-&amp;gt;javascripts = array(&#039;navigation&#039;);&lt;br /&gt;
$THEME-&amp;gt;javascripts_footer = array(&#039;someJSlibrary&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
List of extra javascript files that are included on each page. Themes can not include extra scripts from the theme folder because the folder may not be accessible via web.&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==One huge CSS sheet==&lt;br /&gt;
&lt;br /&gt;
Each page includes only one huge style sheet. All theme sheets are served by a /theme/styles.php script. Page parameters specify the theme name and revision.&lt;br /&gt;
&lt;br /&gt;
The CSS concatenation is done from the YUI CSS, styles.css from all plugins and theme style sheets starting with top most parent and current theme last, please note the order is very important. The algorithm is following:&lt;br /&gt;
# YUI2 CSS&lt;br /&gt;
## merge all YUI2 CSS into one file, respect correct order of files&lt;br /&gt;
# plugins CSS&lt;br /&gt;
## go through all plugins and search for styles.css - put the list into array, use component names as keys, locations as values&lt;br /&gt;
## filter out excluded sheets specified in current $THEME-&amp;gt;plugins_exclude_sheets&lt;br /&gt;
# theme CSS&lt;br /&gt;
## go through all sheets defined in all parents and store all $THEME-&amp;gt;sheets in array&lt;br /&gt;
## filter out excluded sheets specified in current $THEME-&amp;gt;parent_exclude_sheets&lt;br /&gt;
# resolve real image locations&lt;br /&gt;
## regex search for &amp;lt;nowiki&amp;gt;[[pix:componentname|imagewithsibdirnoext]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
## priority is: current theme, parent themes, then plugin or YUI fodlers&lt;br /&gt;
## images in web accessible areas are linked directly, images in dataroot would have to go through /theme/image.php?theme=xxx&amp;amp;file=/sub/img&amp;amp;component=moodle&amp;amp;rev=-1&lt;br /&gt;
# apply theme admin settings - values and image locations&lt;br /&gt;
&lt;br /&gt;
Please note that the current $PAGE-&amp;gt;requires-&amp;gt;css() is suitable mostly for user supplied CSS for data content such as the custom CSS used in mod/data/ module.&lt;br /&gt;
&lt;br /&gt;
The YUI3 reset CSS is loaded separated before this huge combined CSS stylesheet, YUI3 loader may load CSS on the fly from Javascript.&lt;br /&gt;
&lt;br /&gt;
==Theme caching==&lt;br /&gt;
&lt;br /&gt;
Potential problems are:&lt;br /&gt;
* server performance - the merging of all CSS, parent themes and image resolving is relatively expensive&lt;br /&gt;
* bandwidth - longer caching, fewer files and optional gzip compression&lt;br /&gt;
* stale data in browser caches - different file needs to be served when anything in CSS changes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The theme CSS content depends on:&lt;br /&gt;
* current theme&lt;br /&gt;
* theme revision&lt;br /&gt;
&lt;br /&gt;
The theme revision is stored in $CFG-&amp;gt;themerev, it is an integer counter incremented after installation/upgrade of any plugin or core. The revision value -1 is used in theme designer mode to prevent the caching completely.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
All images used both from PHP and CSS have to be cached too. This is handled automatically in /theme/image.php which accepts similar parameters like the styles.php script.&lt;br /&gt;
&lt;br /&gt;
==The theme designer mode==&lt;br /&gt;
&lt;br /&gt;
Administrator, theme designers and developers often need to tweak CSS or images. In previous versions users had to purge the browser caches manually.&lt;br /&gt;
&lt;br /&gt;
In theme designer mode no CSS is cached on server or in browser, each changes are immediately visible. The switching on of this mode immediately invalidates old caches, the caching is turned on again after switching it off. This mode causes higher server load.&lt;br /&gt;
&lt;br /&gt;
This mode also disables all CSS cleanup and compression, all comments are kept and extra debug information can be included in CSS.&lt;br /&gt;
&lt;br /&gt;
This setting is available from the Appearance settings page.&lt;br /&gt;
&lt;br /&gt;
==Performance improvements==&lt;br /&gt;
&lt;br /&gt;
There are several possibilities for more performance improvements:&lt;br /&gt;
* storing of final CSS files in dataroot - caches need to be deleted after each theme revision change; this could significantly reduce server load&lt;br /&gt;
* longer lifetimes - revision parameter eliminates the stale CSS in browser cache completely , lower bandwidth consumption&lt;br /&gt;
* gzip compression - faster page loading on first page&lt;br /&gt;
* remove comments and useless white space&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
==Browser hacks==&lt;br /&gt;
&lt;br /&gt;
Old meta.php was used mostly for conditional loading of IE specific hacks. Open University developed alternative solution which adds browser specific classes to body html element. This can be implemented in the pagelib method returning standard body tags.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;body class=&amp;quot;ie ie7&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 #mypage .whatever {&lt;br /&gt;
  /** normal rules */&lt;br /&gt;
 }&lt;br /&gt;
 .ie6#mypage .whatever {&lt;br /&gt;
  /** broken rules */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
OU used these hacks not only for IE ;-)&lt;br /&gt;
&lt;br /&gt;
==RTL support==&lt;br /&gt;
&lt;br /&gt;
Originally RTL tweaks were stored in separate files. Now we use the same body class tweaks as described above.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;body class=&amp;quot;dir-rtl&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 #mypage .whatever {&lt;br /&gt;
  /** normal rules */&lt;br /&gt;
 }&lt;br /&gt;
 .dir-rtl #mypage .whatever {&lt;br /&gt;
  /** RTL rules */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==YUI==&lt;br /&gt;
&lt;br /&gt;
Moodle started using YUI framework around 1.7, until 2.0dev we did not use any UI widgets that required CSS. The problem is that the YUI needs to be loaded before theme and plugin CSS, second problem is that standard YUI CSS requires reset CSS which greatly improves A-grade browser compatibility and helps theme designers.&lt;br /&gt;
&lt;br /&gt;
YUI3 implements new loaders both for CSS and JS, there is a complementing PHP dependency loader for YUI.&lt;br /&gt;
&lt;br /&gt;
===YUI CSS foundation===&lt;br /&gt;
&lt;br /&gt;
Moodle styles are based on YUI foundation? Why not? The benefits are:&lt;br /&gt;
* eliminates some different HTML defaults (margins, paddings, font sizes, etc.) [http://developer.yahoo.com/yui/reset/ (YUI CSS Reset)]&lt;br /&gt;
* consistent font sizing and better font-family degradation [http://developer.yahoo.com/yui/fonts/ (YUI CSS Fonts)]&lt;br /&gt;
* the standard YUI CSS is already built on top of this foundation &lt;br /&gt;
* incredibly simple table-less page layouts that include nesting [http://developer.yahoo.com/yui/fonts/ (YUI CSS Grids)] (optional, themes do not have to use it for layout)&lt;br /&gt;
&lt;br /&gt;
===YUI widgets customisation===&lt;br /&gt;
&lt;br /&gt;
The standard YUI CSS has to be loaded after YUI CSS Base (Reset+Fonts+Grids), but before our own CSS. Overriding of YUI stylesheets should not depend on the order of loading, we only guarantee that the YUI CSS foundation sheets are loaded before any other CSS, customisations of YUI skins has to use moodle class selectors.&lt;br /&gt;
&lt;br /&gt;
===YUI versioning===&lt;br /&gt;
&lt;br /&gt;
In 1.9 we store all YUI files in /lib/yui/ folder, this was a problem when upgrading to YUI version from upstream because the old files could be still cached in browsers.&lt;br /&gt;
&lt;br /&gt;
In 2.0 we are finally replicating the YAHOO directory structures, each new version is stored in separate directory.&lt;br /&gt;
&lt;br /&gt;
===Combination of YUI 2 and 3===&lt;br /&gt;
&lt;br /&gt;
YUI 3 uses JS autoloading which is a great step forward and simplification. Unfortunately we still need the YUI2 libraries around for some time, luckily YUI2 libraries may coexist with YUI3 code.&lt;br /&gt;
&lt;br /&gt;
==The image resolver==&lt;br /&gt;
&lt;br /&gt;
Images are used in html code and in CSS style sheets. The problem is easy to solve in PHP code, partial solution was already present in Moodle 1.9 - see $CFG-&amp;gt;pixpath&lt;br /&gt;
&lt;br /&gt;
In 2.0dev there was implemented a new icon_finder class, it can be replaced by much simpler rules, we could also add pix support into all plugins.&lt;br /&gt;
&lt;br /&gt;
Image locations:&lt;br /&gt;
* /mod/modulename/pix/, blocks/blockname/pix/ - in all plugins&lt;br /&gt;
* /theme/themename/pix/ - theme images&lt;br /&gt;
* /theme/themename/pix_core/ - overridden images from core /pix/ folder&lt;br /&gt;
* /theme/themename/pix_plugins/plugin/plugintype/ - overriding of plugin images in themes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The standard API is &amp;lt;code&amp;gt;$OUTPUT-&amp;gt;pix_url($componentname, $imagename, encoded)&amp;lt;/code&amp;gt; when used from PHP and &amp;lt;nowiki&amp;gt;[[pix:componentname|imagename]]&amp;lt;/nowiki&amp;gt; if used in CSS.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Image resolved allows us to serve images from dataroot via /theme/image.php script and also solves all browser caching issues.&lt;br /&gt;
&lt;br /&gt;
==Themes in extra directory==&lt;br /&gt;
&lt;br /&gt;
Themes in dataroot is a frequently requested feature. Some admins might not like this, it should be optional. Some really advanced themes with lots of custom files might not be compatible at first. In fact it does not have to be dataroot, this location is configurable via $CFG-&amp;gt;themedir.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the stable branch we have a strange mix of standard themes. Moodle 2.0 is expected to include following themes:&lt;br /&gt;
* base - bare bones minimal theming that most other themes build on&lt;br /&gt;
* standard - basic theme that can be used as base for really simple themes (the exact look of new standard theme is not decided yet)&lt;br /&gt;
* customcolor - standard with admin specified colour palette and custom logos (not confirmed)&lt;br /&gt;
* and many other fancy modern themes like anomaly ( optionally with multiple configuration settings)&lt;br /&gt;
&lt;br /&gt;
Other contrib themes could be available via web interface from Moodle configuration in some future Moodle version.&lt;br /&gt;
&lt;br /&gt;
==Admin theme settings==&lt;br /&gt;
&lt;br /&gt;
Very often users need to make small tweaks to standard themes such as different colour or logos. There should be a way to keep this settings in config_plugin and files separately in dataroot. Settings are placed in /theme/themename/settings.php. This new feature could significantly reduce known theme upgrade problems in the future.&lt;br /&gt;
&lt;br /&gt;
This feature replaces the original CSS constants and will probably use the same syntax. The original CSS constants required modifications in dirroot which was in some cases unacceptable. CSS constants would not be compatible with automatic updates vie web interface anyway.&lt;br /&gt;
&lt;br /&gt;
This feature requires advanced caching of CSS. These settings and files should be available in layouts and renderers too.&lt;br /&gt;
&lt;br /&gt;
The actual replacing of setting placeholders by setting values is performed in custom css post-processing function specified in config.php. Logos and other custom images would be specified as external URLs, later we could also add basic support for storage of these custom theme files in standard Moodle filesystem.&lt;br /&gt;
&lt;br /&gt;
==Page layout==&lt;br /&gt;
Each page may specify one of standard page layouts that are defined in theme/base/config.php. It is not possible to add custom layouts.&lt;br /&gt;
&lt;br /&gt;
Layout definition consists of:&lt;br /&gt;
* template file specification - template name + file name without extension&lt;br /&gt;
* definition of regions&lt;br /&gt;
* default region&lt;br /&gt;
&lt;br /&gt;
New layouts will not be added in the STABLE CVS branches.&lt;br /&gt;
&lt;br /&gt;
==Renderers==&lt;br /&gt;
&lt;br /&gt;
Renderers are small methods that render visual elements using functional programming - our old style PHP style.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Module may define own renderer class and use own renderer methods. Themes may override both core and plugin renderers however you need to have some more advanced understanding of PHP and Moodle design in general.&lt;br /&gt;
&lt;br /&gt;
==Templates (maybe in future)==&lt;br /&gt;
&lt;br /&gt;
Similar to page layouts but much smaller parts of UI that are embedded into pages. This is a new feature that is not used in Moodle core yet.&lt;br /&gt;
&lt;br /&gt;
Code developers may choose to use templates instead of renderers for some larger parts of UI, they may also use renderers from templates. The major difference is that templates accept just one $DATA object with all parameters, templates might be also much easier to use&amp;amp;understand for typical theme designers.&lt;br /&gt;
&lt;br /&gt;
The original emulated templates approach was replaced because it was designed for code developers, not designers. I think it is much easier to just copy templates from core or plugins into themes and tweak them, instead of the reverse engineering of the renderers.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Please note this does not mean that Moodle is switching to templates now, but technically we could, plugin developers would decide to do so independently. This topic should be revisited in Moodle 2.1dev.&lt;br /&gt;
&lt;br /&gt;
==Other API changes==&lt;br /&gt;
&lt;br /&gt;
* added &#039;&#039;course&#039;&#039; layout&lt;br /&gt;
* $PAGE-&amp;gt;set_generaltype() replaced by $PAGE-&amp;gt;set_pagelayout() because it really switches to one of the layouts from  the standard theme; also the complete list of layouts is given in theme/base/config.php - there is no way to add plugin layouts, the $PAGE-&amp;gt;set_pagelayout() is used from core and plugin code, not from themes, so it is not possible to add new layouts at all (and never was)&lt;br /&gt;
* name things &#039;&#039;moodle_*&#039;&#039; only if potential conflicts exist, everything plugin related should be named &#039;&#039;componentname_&#039;&#039; (mod_ is usually an exception)- this was discussed several times before; renamed &#039;&#039;moodle_core_renderer&#039; class to &#039;&#039;core_renderer&#039;&#039;, etc.&lt;br /&gt;
* themes are now real plugins with capabilities, lang packs, upgrade code, settings, upgrade code, etc. - it is not recommended to create new db table though&lt;br /&gt;
&lt;br /&gt;
=Backwards compatibility and upgrades=&lt;br /&gt;
&lt;br /&gt;
BC is very limited, all themes and modules need to be manually updated. Keeping old themes during the upgrade must not cause fatal PHP errors. Old themes can be detected by searching for /theme/oldtheme/styles.php, this file will not be present in the new themes any more. Moodle core would simply use the specified parent theme  or the standard theme.&lt;br /&gt;
&lt;br /&gt;
==Theme upgrade steps==&lt;br /&gt;
# delete styles.php&lt;br /&gt;
# redefine all config.php options - in majority of cases change parent value to parents array&lt;br /&gt;
# rename styles_ie6.css and styles_ie7.css to styles_layout_ie6.css and styles_layout_ie7.css - each normal sheet may have an extra sheet with _ieX suffix now, these are loaded automatically, excluding is applied based on $THEME-&amp;gt;parents_exclude_sheets() info from the current theme&lt;br /&gt;
# rename rtl.css to styles_layout_rtl.css - again each normal style sheet may have extra sheet with _rtl suffix similar to IE hacks sheets&lt;br /&gt;
# delete header.html, footer.html and meta.php - obsoleted by $THEME-&amp;gt;layouts option and new layout files&lt;br /&gt;
# add custom layouts and rendereds&lt;br /&gt;
&lt;br /&gt;
In order to minimize confusion during the upgrade, the old themes will be ignored and will be listed os &amp;quot;Incompatible&amp;quot; on the theme selection page - this page is probably the first place admins go in order to diagnose theme problems.&lt;br /&gt;
&lt;br /&gt;
==Module upgrade steps==&lt;br /&gt;
* rename mod/modname/styles.php to styles.css&lt;br /&gt;
* put all images into mod/modname/pix/&lt;br /&gt;
* replace $CFG-&amp;gt;pixpath with $OUTPUT-&amp;gt;pix_url(&#039;imagename&#039;, &#039;mod_modname&#039;)&lt;br /&gt;
&lt;br /&gt;
==Removed features==&lt;br /&gt;
# &#039;&#039;&#039;sometheme/meta.php&#039;&#039;&#039; - used mostly for IE6/7 hacks, custom layouts may be used instead&lt;br /&gt;
# &#039;&#039;&#039;smartpix&#039;&#039;&#039; - completely obsoleted by the new image location resolution algorithm&lt;br /&gt;
# &#039;&#039;&#039;styles.php&#039;&#039;&#039; replaced by styles.css, supported in all plugin types - the PHP syntax is not needed anymore because images are specified using &amp;lt;nowiki&amp;gt;[[pix:component|dir/image]]&amp;lt;/nowiki&amp;gt; syntax and we can also use custom css post-processors&lt;br /&gt;
# &#039;&#039;&#039;$CFG-&amp;gt;pixpath&#039;&#039;&#039; replaced by $OUTPUT-&amp;gt;pix_url()&lt;br /&gt;
# &#039;&#039;&#039;CSS constants&#039;&#039;&#039; replaced by the admin theme settings&lt;br /&gt;
# separate IE6 and IE7 sheets - replaced by body class attributes&lt;br /&gt;
# separate RTL sheets - replaced by body class attribute&lt;br /&gt;
&lt;br /&gt;
=Expected reactions=&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &amp;lt;center&amp;gt;&#039;&#039;&#039;User type&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
! &amp;lt;center&amp;gt;&#039;&#039;&#039;Negative&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
! &amp;lt;center&amp;gt;&#039;&#039;&#039;Positive&#039;&#039;&#039;&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Core developer&lt;br /&gt;
| none&lt;br /&gt;
| No backwards compatibility headaches. Powerful new features. More flexible API.&lt;br /&gt;
|-&lt;br /&gt;
| Contrib developer&lt;br /&gt;
| Has to learn new API and upgrade current code.&lt;br /&gt;
| New useful pix folder and standard styles.css in all plugins. $OUTPUT-&amp;gt;pix_url() more flexible then old pixpath.&lt;br /&gt;
|-&lt;br /&gt;
| Theme designer&lt;br /&gt;
| Has to learn new theme API. Old advanced themes has to be completely redesigned. Has to understand YUI CSS foundation.&lt;br /&gt;
| They can finally override core and plugin images. Easier distribution of custom themes. New income opportunity. Basic theme structure is simplified. No browser caching issues when designing themes.&lt;br /&gt;
|-&lt;br /&gt;
| Administrator&lt;br /&gt;
| All themes need to be updated. Old themes are ignored.&lt;br /&gt;
| Much easier installation (optionally in dataroot) and easy customisation without code modification (images and colours for example). Much safer upgrades. Possibility to upgrade theme via web interface. No browser caching issues when upgrading themes. Better performance and lower server load.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
Using Moodle forum discussions:&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=131219 Yet more theme changes proposal]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=140089 HEADS UP: Major theme changes landing]&lt;br /&gt;
* [[Output_renderers]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Themes]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_Engine_2:Overview&amp;diff=34439</id>
		<title>Question Engine 2:Overview</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_Engine_2:Overview&amp;diff=34439"/>
		<updated>2012-07-12T17:17:52Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: /* Brief digression: who controls the model, the quiz or the question? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Question_engine_2}}&lt;br /&gt;
This page outlines how I think the question engine should work in Moodle 2.0 or 2.1.&lt;br /&gt;
&lt;br /&gt;
Previous section: [[Question Engine 2:Rationale|Rationale]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Normalise the database structure==&lt;br /&gt;
&lt;br /&gt;
At the moment, the some parts of the question_sessions and question_states tables and their relations are not normalised. This is a technical term for describing database designs. Basically, if the tables are normalised, then each &#039;fact&#039; is stored in exactly one place. A normalised database is much less likely to get into an inconsistent state. Changing to a normalised structure should therefore increase robustness.&lt;br /&gt;
&lt;br /&gt;
In addition, I wish to change the tables, so the the responses received from the student are stored in a much more &#039;raw&#039; form. That will mean that the responses can be saved much earlier in the sequence of processing, which will again increase robustness. It will also allow the sequence of responses from the student to be replayed more easily, making it easier to continue after a server crash, to regrade, and to write automatic test scripts.&lt;br /&gt;
&lt;br /&gt;
The detailed design describes the new database structure.&lt;br /&gt;
&lt;br /&gt;
(+++Robustness, +Correctness)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==New concept: Question behaviours==&lt;br /&gt;
&lt;br /&gt;
At the moment, the various sequences of states that a question can move through in response to student input is hard-coded. It is controlled by a combination of the compare_responses and grade_responses methods of the question types, and tangled logic in the question_process_responses function. This makes it difficult to add new ways on interacting with questions, for example certainty based marking. Also, the current code is tricky to keep working.&lt;br /&gt;
&lt;br /&gt;
I would like to separate out the control of how a question moves through different states, into what I will call question behaviours. Currently, Moodle has three or four of these:&lt;br /&gt;
&lt;br /&gt;
===Deferred feedback===&lt;br /&gt;
&lt;br /&gt;
This is how the quiz currently work when adaptive mode is off. The student enters a response to each question, then does Submit all and finish at the end of their attempt. Only then do they get feedback and/or grades on each question, depending on the review settings.&lt;br /&gt;
&lt;br /&gt;
===Adaptive===&lt;br /&gt;
&lt;br /&gt;
In this mode there is a separate submit button beside each question, so the student can submit each question individually during the attempt, and if they are wrong, try to improve their answer, although for a reduced grade.&lt;br /&gt;
&lt;br /&gt;
Currently, the way adaptive mode works from the student point of view is not very good. I propose to replace it with a new Interactive mode. See below.&lt;br /&gt;
&lt;br /&gt;
===Manually graded===&lt;br /&gt;
&lt;br /&gt;
Essay questions need to be manually graded by the teacher, so you cannot really use them in adaptive mode (although currently there is nothing in the Quiz to stop you, which leads to confusing results). And it is not quite the same as Deferred feedback mode, because the student must wait for the teacher to grade their response after clicking submit all and finish.&lt;br /&gt;
&lt;br /&gt;
===Each attempt builds on last===&lt;br /&gt;
&lt;br /&gt;
This is very similary to the deferred feedback model, except that in subsequent attempts, each question does not start blank, but instead with the student&#039;s last response from the previous attempt.&lt;br /&gt;
&lt;br /&gt;
Currently in Moodle there is nothing to stop you trying to combine Each attempt builds on last with Adaptive mode, although that combination does not make any sense to me. I think it simplifies things to treat this as a separate mode, although, of course, it will share code with Deferred feedback mode.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are also some new modes that I propose to add, either immediately, or shortly after the main part of the work:&lt;br /&gt;
&lt;br /&gt;
===Interactive===&lt;br /&gt;
&lt;br /&gt;
This will replace adaptive mode. This is the model that has been used successfully for several years in the OU&#039;s [http://www.open.ac.uk/openmarkexamples/ OpenMark] system. The OU has also  modified Moodle to work like this, but because of the way the quiz core currently works, I was not happy just merging the OU changes into Moodle core. In a sense, this whole document grew out of my thoughts about how to implement the OU changes in Moodle core properly.&lt;br /&gt;
&lt;br /&gt;
In the existing adaptive mode, after the student has clicked submit, the question both shows the feedback for the last answer the student submitted, while also letting the student change their answer. This can lead to weird results. For example create a numerical question 2 + 2 = 4. Attempt it. Enter 4. Click Submit. Enter 5. Click Save. You will see a page that seems to say that your answer is 5 and it is correct!&lt;br /&gt;
&lt;br /&gt;
In Interactive mode, the question is either in a state for the student to enter their answer, with a Submit button; or it is showing feedback for the student&#039;s previous attempt, with a Try again button to get back to the first state.&lt;br /&gt;
&lt;br /&gt;
The other difference is that students are only allowed a limited number of tries at each question (typically three). When they submit their third try, or when they submit a correct answer, that question is finished and they must go onto the next one.&lt;br /&gt;
&lt;br /&gt;
(This is quite difficult to explain. Try [https://students.open.ac.uk/openmark/s205.ayrf/ this example] and you should see how it works.)&lt;br /&gt;
&lt;br /&gt;
===Immediate feedback===&lt;br /&gt;
&lt;br /&gt;
This would be like cross between Deferred feedback an Interactive. Each question has a submit button beside it, like in interactive mode, so the student can get the feedback immediately while they still remember their thought processes while answering the question. However, unlike the interactive model, there is no try again button. You only get one chance at each question.&lt;br /&gt;
&lt;br /&gt;
This is a necessary prerequisite for implementing MDL-11047, which is fairly frequently asked for in the quiz forum.&lt;br /&gt;
&lt;br /&gt;
===Certainty based marking with deferred feedback===&lt;br /&gt;
&lt;br /&gt;
This takes any question that can use the deferred feedback model, and adds three radio buttons to the UI (higher, medium, lower) for the student to use to indicate how certain they are that their answer is correct. If they are more certain, the get more marks if they are right, but lose marks if they are wrong. This encourages students to reflect about their level of knowledge.&lt;br /&gt;
&lt;br /&gt;
===Certainty based marking with immediate feedback===&lt;br /&gt;
&lt;br /&gt;
This is like immediate feedback mode with the certainty based marking feature.&lt;br /&gt;
&lt;br /&gt;
===Delegate to a remote system===&lt;br /&gt;
&lt;br /&gt;
The Opaque question type from contrib, which is used to run both OpenMark and [http://stack.bham.ac.uk/ STACK] questions inside a Moodle quiz was very difficult to implement within the current code. Since the remote system controls the flow of the question, it makes sense to use a custom behaviour for this question type, and that will be possible in the new code.&lt;br /&gt;
&lt;br /&gt;
===Information item===&lt;br /&gt;
&lt;br /&gt;
Used for descriptions. There is no grade. Item gets marked as complete after the student has seen it once. Displays general feedback after the attempt is over.&lt;br /&gt;
&lt;br /&gt;
===Missing===&lt;br /&gt;
&lt;br /&gt;
This is like the Missing question type. This behaviour is used in the situation:&lt;br /&gt;
# Admin installs some behaviour.&lt;br /&gt;
# Student attempts quiz using that model.&lt;br /&gt;
# Admin uninstalls that model.&lt;br /&gt;
# Teacher tries to review that student&#039;s attempt.&lt;br /&gt;
The missing question behaviour does the best job it can to allow the review of the attempt with the missing model, while displaying an on-screen warning.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So, what exactly does the behaviour control? Given the current state of the question, it limits the range of actions that are possible. For example, in adaptive mode, there is a submit button next to each question. In non-adaptive mode, the only option is to enter an answer and have it saved, until the submit all and finish button is pressed. That is, there will be a class in the PHP code for each model, and it will have methods that replace the old question_extract_responses, question_process_responses, question_process_comment and save_question_state functions in the current code.&lt;br /&gt;
&lt;br /&gt;
(+++Richness, ++Correctness, +Robustness)&lt;br /&gt;
&lt;br /&gt;
===Brief digression: who controls the model, the quiz or the question?===&lt;br /&gt;
&lt;br /&gt;
There is one design decisions that it took a long time for me to resolve, and I want to mention it here.&lt;br /&gt;
&lt;br /&gt;
The question is: Is the behaviour a property of the question, or the quiz?&lt;br /&gt;
&lt;br /&gt;
At the moment, there is a setting in the quiz that lets you change all the questions in the quiz from adaptive mode to non-adaptive mode at the flick of a switch. Or, at least, it allows you to re-use the same questions in both adaptive and non-adaptive mode. This suggest that the behaviour is a property of the quiz.&lt;br /&gt;
&lt;br /&gt;
On the other hand, suppose that you wanted to introduce the feature that, in adaptive mode, the student gets different amounts of feedback after each try at getting the question right. For example, the first time they get it wrong the only get a brief hint. If they are wrong the second time they get a more detailed comment, and so on. In order to do this, you need more data (the various hints) in order to define an adaptive question that is irrelevant to a non-adaptive question. Also, certain question types (e.g. Opaque, from contrib) have to, of necessity, ignore the adaptive, non-adaptive setting. And I suggested above that, manually graded question types like Essay should really be considered to have a separate behaviour. This suggests that the behaviour is a property of the individual question. (Although usability considerations suggest that a single quiz should probably be constructed from questions with similar behaviour.)&lt;br /&gt;
&lt;br /&gt;
I eventually concluded that both answers are right. That is, it is a good idea for the quiz to have a setting like adaptive/non-adaptive that sets out the teacher&#039;s intention of how each question in this quiz should behave. However, the exact choice of behaviour to use is up to the different question types. When a quiz attempts is started, each question type is asked something like &amp;quot;A quiz attempt is starting using &#039;adaptive mode&#039;. Exactly which behaviour should be used for questions of this type in this attempt?&amp;quot; This gives questions that can only work in a certain way (for example essay questions) a chance to override the quiz setting.&lt;br /&gt;
&lt;br /&gt;
==Clarifying question states==&lt;br /&gt;
&lt;br /&gt;
Although there is a database table called question_states, the column there that stores the type of state is called event, and the values stored there are active verbs like open, save, grade. The question_process_responses function is written in terms of these actions too. One nasty part is that during the processing, the event type can be changed several times, before it is finally stored in the database as a state.&lt;br /&gt;
&lt;br /&gt;
I would like to clearly separate the concept of the current state that a question is in, and the various actions that lead to a change of state. The actions will be handled by the behaviours, and the state will be stored in the database as a state.&lt;br /&gt;
&lt;br /&gt;
The list of available states will also be changed slightly to match the following diagram. This came from thinking about what information it was important to display in the quiz navigation block.&lt;br /&gt;
&lt;br /&gt;
[[Image:Question_state_diagram.png]]&lt;br /&gt;
&lt;br /&gt;
(+Correctness, +Richness).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==What are the parts of a question?==&lt;br /&gt;
&lt;br /&gt;
When we come to think of outputting a question on-screen, we can now see that there are several things that affect what it will look like:&lt;br /&gt;
# The question type (multichoice, shortanswer, essay, ...)&lt;br /&gt;
# The behaviour (deferred feedback, interactive, CBM, ...)&lt;br /&gt;
# What state the question is in (has the student answered yet, has it been graded, ...)&lt;br /&gt;
# The options from the particular activity (whether any marks are available for this question, are students allowed to see their grades, how many decimal places to use to display grades, does this user have permission to make a manual comment ...)&lt;br /&gt;
&lt;br /&gt;
Also, we want different question type and behaviours to have the freedom to display whatever they like to the students; but we also want all the questions in a quiz to look and behave consistently, so that the experience is not confusing.&lt;br /&gt;
&lt;br /&gt;
In the sketch below, I try to summarise the bits that may be present in a typical question. If all questions can have these bits in this order, then that is probably enough consistency. The flexibility comes from allowing the question type or behaviour to put whatever it likes inside those bits. &lt;br /&gt;
&lt;br /&gt;
We can divide what you see when looking at a question is into three main parts:&lt;br /&gt;
# Information (meta-data): Which question number this is, a summary of what state it is currently in, what grade you have got for it (or how many marks are available, if any), whether you have flagged it. This has a grey background in the sketch below.&lt;br /&gt;
# The question and the response to it. This has a blue background in the sketch.&lt;br /&gt;
# The outcome from submitting that response. This has a yellow background.&lt;br /&gt;
&lt;br /&gt;
[[Image:Parts of a question2.png]]&lt;br /&gt;
&lt;br /&gt;
The full list of options that control which of those bits are visible at any time are:&lt;br /&gt;
&lt;br /&gt;
; correctness : (hidden / visible) whether the student gets told whether their answer was (in/partially)correct in the status summary under the question number, or instead are told something vague like &#039;Finished&#039;.&lt;br /&gt;
; marks : (hidden / max only / actual mark and max / actual mark and max with explanation ) whether the student can see the number of marks available, and how many marks they got, and how much detail of the marking to display.&lt;br /&gt;
; marks d.p. : (0 .. 7) how many decimal places marks are displayed to.&lt;br /&gt;
; flags: (hidden / visible / visible and editable) this is the feature that lets students bookmark or flag a question in an attempt for later reference.&lt;br /&gt;
; read-only: Whether the question just shows the response was already entered, or whether it gives controls to the user enter/change their response.&lt;br /&gt;
; specific feedback: (hidden / visible) feedback that relates to the particular response the student entered.&lt;br /&gt;
; general feedback : (hidden / visible) whether the general feedback (same for all students) is visible.&lt;br /&gt;
; correct response : (hidden / visible) whether the automatically generated message or other indication of the correct answer is visible.&lt;br /&gt;
; manual comment: (hidden / visible / visible and editable) whether the comment manually added by the teacher is visible and editable by the current user.&lt;br /&gt;
; response history : (hidden / visible) whether the list of steps the student went through to answer the question is displayed.&lt;br /&gt;
&lt;br /&gt;
These options are initially set by whatever it is that is using the question (for example the quiz will initialise them from the quiz settings). Then these options are modified by the behaviour. For example it should ensure that no feedback is displayed until the student has actually submitted an answer, or that after they have submitted their final answer, the question only appears in read-only mode.&lt;br /&gt;
&lt;br /&gt;
==Reorganise the code==&lt;br /&gt;
&lt;br /&gt;
There will, of course, be a new class for each behaviour, that all inherit from the same base class.&lt;br /&gt;
&lt;br /&gt;
At the moment question type classes have multiple responsibilities.&lt;br /&gt;
# They is information about the question types, and loading and saving, importing and exporting, backing up and restoring questions of that type.&lt;br /&gt;
# Then there is the processing of student responses for a particular instances of that question type.&lt;br /&gt;
# And then there is displaying the question in its various states.&lt;br /&gt;
(Fortunately, 4. Displaying an editing form, is already in a separate class.)&lt;br /&gt;
&lt;br /&gt;
Moodle 2.0 introduces the [[Theme_engines_for_Moodle%3F|renderer concept]]. Introducing qtype renderers will move the output code (3) into separate classes. This change to the question engine is the appropriate time to introduce qtype renderes.&lt;br /&gt;
&lt;br /&gt;
I will also introduce a new set of classes to store the state of a question within a quiz attempt. That is basically the combination of the $question and $state objects that are passed around at the moment, but with a specific subclass for each question type. This moves all the processing logic (2) into a separate class. That leaves the question type class itself just responsible for (1).&lt;br /&gt;
&lt;br /&gt;
Of course the behaviour classes and the question_state classes need to work together, and this is clearly a situation for the [http://en.wikipedia.org/wiki/Strategy_pattern strategy pattern]. However, I have not yet decided whether the question type is the context, and the iteration model is the strategy, or vice versa. I will have to see which comes out better when I do the implementation.&lt;br /&gt;
&lt;br /&gt;
Finally, there will be a new class in questionlib.php for managing the set of questions in an attempt. Already, in the Moodle 2.0 quiz developments, I have changed the quiz code to create a quiz_attempt class. This keeps track of all the questions in the quiz attempt. However, this really needs to be split into two bits. The job of tracking a set of questions and what state they are in is exactly the job of the question engine. Therefore we should have a question_set_attempt class that does that job. That class will take over the job of a number of functions in questionlib.php, for example question_load_states. Then the quiz_attempt class can just focus on the quiz-specific things, and use the question_set_attempt class. This new class should make it easier to use questions in other modules.&lt;br /&gt;
&lt;br /&gt;
It should be possible to organise the code so that only the question_set_attempt class had to load or save data to or from the database. It will then pass that data on to wherever it is needed. That should be good for efficiency.&lt;br /&gt;
&lt;br /&gt;
(+Robustness, +Efficiency)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Simplified API for question types==&lt;br /&gt;
&lt;br /&gt;
In the summary of how the quiz currently works, I said, &amp;quot;The student enters an answer to each question which is saved. Then when they submit the quiz attempt, all the questions are graded.&amp;quot; In fact, that was a lie. Whenever a response is saved, the grade_responses method of the question type is called, even in the state is only being saved. This is confusing, to say the least, and very bad for performance in the case of a question type like JUnit (in contrib) which takes code submitted by the student, and compiles it in order to grade it.&lt;br /&gt;
&lt;br /&gt;
So some of the API will only change to the extent that certain functions will in future only be called when one would expect them to be. I think this can be done in a backwards-compatible way.&lt;br /&gt;
&lt;br /&gt;
Another change will be that, at the moment, question types have to implement tricky load/save_question_state methods that, basically, have to unserialise/serialise some of the state data in a custom way, so it can be stored in the answer column. This is silly design, and leads to extra, unnecessary database queries. The changes to the database structure will to eliminate the need for these methods.&lt;br /&gt;
&lt;br /&gt;
Hopefully the above changes to how the code is organised will make it mauch easier to write new question types.&lt;br /&gt;
&lt;br /&gt;
(+Richness, +Correctness, +Efficiency)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduce more automated testing==&lt;br /&gt;
&lt;br /&gt;
Since the question_set_attempt class keeps track of all the data that is needed when processing questions, it should be very easy to write automatic tests (unit tests) for all the other parts of the question engine. That should greatly help in eliminating bugs.&lt;br /&gt;
&lt;br /&gt;
I am intending to take a [http://en.wikipedia.org/wiki/Test-driven_development test-driven] approach to implementing this proposal.&lt;br /&gt;
&lt;br /&gt;
(+++Correctness, ++Robustness)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
In the next section, [[Question Engine 2:Design|Design]], gives the detailed design of the above solution.&lt;br /&gt;
&lt;br /&gt;
* Back to [[Question_Engine_2|Question Engine 2]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_Engine_2:Overview&amp;diff=34438</id>
		<title>Question Engine 2:Overview</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_Engine_2:Overview&amp;diff=34438"/>
		<updated>2012-07-12T17:16:33Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: /* Brief digression: who controls the model, the quiz or the question? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Question_engine_2}}&lt;br /&gt;
This page outlines how I think the question engine should work in Moodle 2.0 or 2.1.&lt;br /&gt;
&lt;br /&gt;
Previous section: [[Question Engine 2:Rationale|Rationale]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Normalise the database structure==&lt;br /&gt;
&lt;br /&gt;
At the moment, the some parts of the question_sessions and question_states tables and their relations are not normalised. This is a technical term for describing database designs. Basically, if the tables are normalised, then each &#039;fact&#039; is stored in exactly one place. A normalised database is much less likely to get into an inconsistent state. Changing to a normalised structure should therefore increase robustness.&lt;br /&gt;
&lt;br /&gt;
In addition, I wish to change the tables, so the the responses received from the student are stored in a much more &#039;raw&#039; form. That will mean that the responses can be saved much earlier in the sequence of processing, which will again increase robustness. It will also allow the sequence of responses from the student to be replayed more easily, making it easier to continue after a server crash, to regrade, and to write automatic test scripts.&lt;br /&gt;
&lt;br /&gt;
The detailed design describes the new database structure.&lt;br /&gt;
&lt;br /&gt;
(+++Robustness, +Correctness)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==New concept: Question behaviours==&lt;br /&gt;
&lt;br /&gt;
At the moment, the various sequences of states that a question can move through in response to student input is hard-coded. It is controlled by a combination of the compare_responses and grade_responses methods of the question types, and tangled logic in the question_process_responses function. This makes it difficult to add new ways on interacting with questions, for example certainty based marking. Also, the current code is tricky to keep working.&lt;br /&gt;
&lt;br /&gt;
I would like to separate out the control of how a question moves through different states, into what I will call question behaviours. Currently, Moodle has three or four of these:&lt;br /&gt;
&lt;br /&gt;
===Deferred feedback===&lt;br /&gt;
&lt;br /&gt;
This is how the quiz currently work when adaptive mode is off. The student enters a response to each question, then does Submit all and finish at the end of their attempt. Only then do they get feedback and/or grades on each question, depending on the review settings.&lt;br /&gt;
&lt;br /&gt;
===Adaptive===&lt;br /&gt;
&lt;br /&gt;
In this mode there is a separate submit button beside each question, so the student can submit each question individually during the attempt, and if they are wrong, try to improve their answer, although for a reduced grade.&lt;br /&gt;
&lt;br /&gt;
Currently, the way adaptive mode works from the student point of view is not very good. I propose to replace it with a new Interactive mode. See below.&lt;br /&gt;
&lt;br /&gt;
===Manually graded===&lt;br /&gt;
&lt;br /&gt;
Essay questions need to be manually graded by the teacher, so you cannot really use them in adaptive mode (although currently there is nothing in the Quiz to stop you, which leads to confusing results). And it is not quite the same as Deferred feedback mode, because the student must wait for the teacher to grade their response after clicking submit all and finish.&lt;br /&gt;
&lt;br /&gt;
===Each attempt builds on last===&lt;br /&gt;
&lt;br /&gt;
This is very similary to the deferred feedback model, except that in subsequent attempts, each question does not start blank, but instead with the student&#039;s last response from the previous attempt.&lt;br /&gt;
&lt;br /&gt;
Currently in Moodle there is nothing to stop you trying to combine Each attempt builds on last with Adaptive mode, although that combination does not make any sense to me. I think it simplifies things to treat this as a separate mode, although, of course, it will share code with Deferred feedback mode.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are also some new modes that I propose to add, either immediately, or shortly after the main part of the work:&lt;br /&gt;
&lt;br /&gt;
===Interactive===&lt;br /&gt;
&lt;br /&gt;
This will replace adaptive mode. This is the model that has been used successfully for several years in the OU&#039;s [http://www.open.ac.uk/openmarkexamples/ OpenMark] system. The OU has also  modified Moodle to work like this, but because of the way the quiz core currently works, I was not happy just merging the OU changes into Moodle core. In a sense, this whole document grew out of my thoughts about how to implement the OU changes in Moodle core properly.&lt;br /&gt;
&lt;br /&gt;
In the existing adaptive mode, after the student has clicked submit, the question both shows the feedback for the last answer the student submitted, while also letting the student change their answer. This can lead to weird results. For example create a numerical question 2 + 2 = 4. Attempt it. Enter 4. Click Submit. Enter 5. Click Save. You will see a page that seems to say that your answer is 5 and it is correct!&lt;br /&gt;
&lt;br /&gt;
In Interactive mode, the question is either in a state for the student to enter their answer, with a Submit button; or it is showing feedback for the student&#039;s previous attempt, with a Try again button to get back to the first state.&lt;br /&gt;
&lt;br /&gt;
The other difference is that students are only allowed a limited number of tries at each question (typically three). When they submit their third try, or when they submit a correct answer, that question is finished and they must go onto the next one.&lt;br /&gt;
&lt;br /&gt;
(This is quite difficult to explain. Try [https://students.open.ac.uk/openmark/s205.ayrf/ this example] and you should see how it works.)&lt;br /&gt;
&lt;br /&gt;
===Immediate feedback===&lt;br /&gt;
&lt;br /&gt;
This would be like cross between Deferred feedback an Interactive. Each question has a submit button beside it, like in interactive mode, so the student can get the feedback immediately while they still remember their thought processes while answering the question. However, unlike the interactive model, there is no try again button. You only get one chance at each question.&lt;br /&gt;
&lt;br /&gt;
This is a necessary prerequisite for implementing MDL-11047, which is fairly frequently asked for in the quiz forum.&lt;br /&gt;
&lt;br /&gt;
===Certainty based marking with deferred feedback===&lt;br /&gt;
&lt;br /&gt;
This takes any question that can use the deferred feedback model, and adds three radio buttons to the UI (higher, medium, lower) for the student to use to indicate how certain they are that their answer is correct. If they are more certain, the get more marks if they are right, but lose marks if they are wrong. This encourages students to reflect about their level of knowledge.&lt;br /&gt;
&lt;br /&gt;
===Certainty based marking with immediate feedback===&lt;br /&gt;
&lt;br /&gt;
This is like immediate feedback mode with the certainty based marking feature.&lt;br /&gt;
&lt;br /&gt;
===Delegate to a remote system===&lt;br /&gt;
&lt;br /&gt;
The Opaque question type from contrib, which is used to run both OpenMark and [http://stack.bham.ac.uk/ STACK] questions inside a Moodle quiz was very difficult to implement within the current code. Since the remote system controls the flow of the question, it makes sense to use a custom behaviour for this question type, and that will be possible in the new code.&lt;br /&gt;
&lt;br /&gt;
===Information item===&lt;br /&gt;
&lt;br /&gt;
Used for descriptions. There is no grade. Item gets marked as complete after the student has seen it once. Displays general feedback after the attempt is over.&lt;br /&gt;
&lt;br /&gt;
===Missing===&lt;br /&gt;
&lt;br /&gt;
This is like the Missing question type. This behaviour is used in the situation:&lt;br /&gt;
# Admin installs some behaviour.&lt;br /&gt;
# Student attempts quiz using that model.&lt;br /&gt;
# Admin uninstalls that model.&lt;br /&gt;
# Teacher tries to review that student&#039;s attempt.&lt;br /&gt;
The missing question behaviour does the best job it can to allow the review of the attempt with the missing model, while displaying an on-screen warning.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So, what exactly does the behaviour control? Given the current state of the question, it limits the range of actions that are possible. For example, in adaptive mode, there is a submit button next to each question. In non-adaptive mode, the only option is to enter an answer and have it saved, until the submit all and finish button is pressed. That is, there will be a class in the PHP code for each model, and it will have methods that replace the old question_extract_responses, question_process_responses, question_process_comment and save_question_state functions in the current code.&lt;br /&gt;
&lt;br /&gt;
(+++Richness, ++Correctness, +Robustness)&lt;br /&gt;
&lt;br /&gt;
===Brief digression: who controls the model, the quiz or the question?===&lt;br /&gt;
&lt;br /&gt;
There is one design decisions that it took a long time for me to resolve, and I want to mention it here.&lt;br /&gt;
&lt;br /&gt;
The question is: Is the behaviour a property of the question, or the quiz?&lt;br /&gt;
&lt;br /&gt;
At the moment, there is a setting in the quiz that lets you change all the questions in the quiz from adaptive mode to non-adaptive mode at the flick of a switch. Or, at least, it allows you to re-use the same questions in both adaptive and non-adaptive mode. This suggest that the behaviour is a property of the quiz.&lt;br /&gt;
&lt;br /&gt;
On the other hand, suppose that you wanted to introduce the feature that, in adaptive mode, the student gets different amounts of feedback after each try at getting the question right. For example, the first time they get it wrong the only get a brief hint. If they are wrong the second time they get a more detailed comment, and so on. In order to do this, you need more data (the various hints) in order to define an adaptive question that is irrelevant to a non-adaptive question. Also, certain question types (e.g. Opaque, from contrib) have to, of necessity, ignore the adaptive, non-adaptive setting. And I suggested above that, manually graded question types like Essay should really be considered to have a separate behaviour. This suggests that the behaviour is a properly of the individual question. (Although usability considerations suggest that a single quiz should probably be constructed from questions with similar behaviour.)&lt;br /&gt;
&lt;br /&gt;
I eventually concluded that both answers are right. That is, it is a good idea for the quiz to have a setting like adaptive/non-adaptive that sets out the teacher&#039;s intention of how each question in this quiz should behave. However, the exact choice of behaviour to use is up to the different question types. When a quiz attempts is started, each question type is asked something like &amp;quot;A quiz attempt is starting using &#039;adaptive mode&#039;. Exactly which behaviour should be used for questions of this type in this attempt?&amp;quot; This gives questions that can only work in a certain way (for example essay questions) a chance to override the quiz setting.&lt;br /&gt;
&lt;br /&gt;
==Clarifying question states==&lt;br /&gt;
&lt;br /&gt;
Although there is a database table called question_states, the column there that stores the type of state is called event, and the values stored there are active verbs like open, save, grade. The question_process_responses function is written in terms of these actions too. One nasty part is that during the processing, the event type can be changed several times, before it is finally stored in the database as a state.&lt;br /&gt;
&lt;br /&gt;
I would like to clearly separate the concept of the current state that a question is in, and the various actions that lead to a change of state. The actions will be handled by the behaviours, and the state will be stored in the database as a state.&lt;br /&gt;
&lt;br /&gt;
The list of available states will also be changed slightly to match the following diagram. This came from thinking about what information it was important to display in the quiz navigation block.&lt;br /&gt;
&lt;br /&gt;
[[Image:Question_state_diagram.png]]&lt;br /&gt;
&lt;br /&gt;
(+Correctness, +Richness).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==What are the parts of a question?==&lt;br /&gt;
&lt;br /&gt;
When we come to think of outputting a question on-screen, we can now see that there are several things that affect what it will look like:&lt;br /&gt;
# The question type (multichoice, shortanswer, essay, ...)&lt;br /&gt;
# The behaviour (deferred feedback, interactive, CBM, ...)&lt;br /&gt;
# What state the question is in (has the student answered yet, has it been graded, ...)&lt;br /&gt;
# The options from the particular activity (whether any marks are available for this question, are students allowed to see their grades, how many decimal places to use to display grades, does this user have permission to make a manual comment ...)&lt;br /&gt;
&lt;br /&gt;
Also, we want different question type and behaviours to have the freedom to display whatever they like to the students; but we also want all the questions in a quiz to look and behave consistently, so that the experience is not confusing.&lt;br /&gt;
&lt;br /&gt;
In the sketch below, I try to summarise the bits that may be present in a typical question. If all questions can have these bits in this order, then that is probably enough consistency. The flexibility comes from allowing the question type or behaviour to put whatever it likes inside those bits. &lt;br /&gt;
&lt;br /&gt;
We can divide what you see when looking at a question is into three main parts:&lt;br /&gt;
# Information (meta-data): Which question number this is, a summary of what state it is currently in, what grade you have got for it (or how many marks are available, if any), whether you have flagged it. This has a grey background in the sketch below.&lt;br /&gt;
# The question and the response to it. This has a blue background in the sketch.&lt;br /&gt;
# The outcome from submitting that response. This has a yellow background.&lt;br /&gt;
&lt;br /&gt;
[[Image:Parts of a question2.png]]&lt;br /&gt;
&lt;br /&gt;
The full list of options that control which of those bits are visible at any time are:&lt;br /&gt;
&lt;br /&gt;
; correctness : (hidden / visible) whether the student gets told whether their answer was (in/partially)correct in the status summary under the question number, or instead are told something vague like &#039;Finished&#039;.&lt;br /&gt;
; marks : (hidden / max only / actual mark and max / actual mark and max with explanation ) whether the student can see the number of marks available, and how many marks they got, and how much detail of the marking to display.&lt;br /&gt;
; marks d.p. : (0 .. 7) how many decimal places marks are displayed to.&lt;br /&gt;
; flags: (hidden / visible / visible and editable) this is the feature that lets students bookmark or flag a question in an attempt for later reference.&lt;br /&gt;
; read-only: Whether the question just shows the response was already entered, or whether it gives controls to the user enter/change their response.&lt;br /&gt;
; specific feedback: (hidden / visible) feedback that relates to the particular response the student entered.&lt;br /&gt;
; general feedback : (hidden / visible) whether the general feedback (same for all students) is visible.&lt;br /&gt;
; correct response : (hidden / visible) whether the automatically generated message or other indication of the correct answer is visible.&lt;br /&gt;
; manual comment: (hidden / visible / visible and editable) whether the comment manually added by the teacher is visible and editable by the current user.&lt;br /&gt;
; response history : (hidden / visible) whether the list of steps the student went through to answer the question is displayed.&lt;br /&gt;
&lt;br /&gt;
These options are initially set by whatever it is that is using the question (for example the quiz will initialise them from the quiz settings). Then these options are modified by the behaviour. For example it should ensure that no feedback is displayed until the student has actually submitted an answer, or that after they have submitted their final answer, the question only appears in read-only mode.&lt;br /&gt;
&lt;br /&gt;
==Reorganise the code==&lt;br /&gt;
&lt;br /&gt;
There will, of course, be a new class for each behaviour, that all inherit from the same base class.&lt;br /&gt;
&lt;br /&gt;
At the moment question type classes have multiple responsibilities.&lt;br /&gt;
# They is information about the question types, and loading and saving, importing and exporting, backing up and restoring questions of that type.&lt;br /&gt;
# Then there is the processing of student responses for a particular instances of that question type.&lt;br /&gt;
# And then there is displaying the question in its various states.&lt;br /&gt;
(Fortunately, 4. Displaying an editing form, is already in a separate class.)&lt;br /&gt;
&lt;br /&gt;
Moodle 2.0 introduces the [[Theme_engines_for_Moodle%3F|renderer concept]]. Introducing qtype renderers will move the output code (3) into separate classes. This change to the question engine is the appropriate time to introduce qtype renderes.&lt;br /&gt;
&lt;br /&gt;
I will also introduce a new set of classes to store the state of a question within a quiz attempt. That is basically the combination of the $question and $state objects that are passed around at the moment, but with a specific subclass for each question type. This moves all the processing logic (2) into a separate class. That leaves the question type class itself just responsible for (1).&lt;br /&gt;
&lt;br /&gt;
Of course the behaviour classes and the question_state classes need to work together, and this is clearly a situation for the [http://en.wikipedia.org/wiki/Strategy_pattern strategy pattern]. However, I have not yet decided whether the question type is the context, and the iteration model is the strategy, or vice versa. I will have to see which comes out better when I do the implementation.&lt;br /&gt;
&lt;br /&gt;
Finally, there will be a new class in questionlib.php for managing the set of questions in an attempt. Already, in the Moodle 2.0 quiz developments, I have changed the quiz code to create a quiz_attempt class. This keeps track of all the questions in the quiz attempt. However, this really needs to be split into two bits. The job of tracking a set of questions and what state they are in is exactly the job of the question engine. Therefore we should have a question_set_attempt class that does that job. That class will take over the job of a number of functions in questionlib.php, for example question_load_states. Then the quiz_attempt class can just focus on the quiz-specific things, and use the question_set_attempt class. This new class should make it easier to use questions in other modules.&lt;br /&gt;
&lt;br /&gt;
It should be possible to organise the code so that only the question_set_attempt class had to load or save data to or from the database. It will then pass that data on to wherever it is needed. That should be good for efficiency.&lt;br /&gt;
&lt;br /&gt;
(+Robustness, +Efficiency)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Simplified API for question types==&lt;br /&gt;
&lt;br /&gt;
In the summary of how the quiz currently works, I said, &amp;quot;The student enters an answer to each question which is saved. Then when they submit the quiz attempt, all the questions are graded.&amp;quot; In fact, that was a lie. Whenever a response is saved, the grade_responses method of the question type is called, even in the state is only being saved. This is confusing, to say the least, and very bad for performance in the case of a question type like JUnit (in contrib) which takes code submitted by the student, and compiles it in order to grade it.&lt;br /&gt;
&lt;br /&gt;
So some of the API will only change to the extent that certain functions will in future only be called when one would expect them to be. I think this can be done in a backwards-compatible way.&lt;br /&gt;
&lt;br /&gt;
Another change will be that, at the moment, question types have to implement tricky load/save_question_state methods that, basically, have to unserialise/serialise some of the state data in a custom way, so it can be stored in the answer column. This is silly design, and leads to extra, unnecessary database queries. The changes to the database structure will to eliminate the need for these methods.&lt;br /&gt;
&lt;br /&gt;
Hopefully the above changes to how the code is organised will make it mauch easier to write new question types.&lt;br /&gt;
&lt;br /&gt;
(+Richness, +Correctness, +Efficiency)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduce more automated testing==&lt;br /&gt;
&lt;br /&gt;
Since the question_set_attempt class keeps track of all the data that is needed when processing questions, it should be very easy to write automatic tests (unit tests) for all the other parts of the question engine. That should greatly help in eliminating bugs.&lt;br /&gt;
&lt;br /&gt;
I am intending to take a [http://en.wikipedia.org/wiki/Test-driven_development test-driven] approach to implementing this proposal.&lt;br /&gt;
&lt;br /&gt;
(+++Correctness, ++Robustness)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
In the next section, [[Question Engine 2:Design|Design]], gives the detailed design of the above solution.&lt;br /&gt;
&lt;br /&gt;
* Back to [[Question_Engine_2|Question Engine 2]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_Engine_2:Overview&amp;diff=34437</id>
		<title>Question Engine 2:Overview</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_Engine_2:Overview&amp;diff=34437"/>
		<updated>2012-07-12T17:15:51Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: missing [ to set link up&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Question_engine_2}}&lt;br /&gt;
This page outlines how I think the question engine should work in Moodle 2.0 or 2.1.&lt;br /&gt;
&lt;br /&gt;
Previous section: [[Question Engine 2:Rationale|Rationale]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Normalise the database structure==&lt;br /&gt;
&lt;br /&gt;
At the moment, the some parts of the question_sessions and question_states tables and their relations are not normalised. This is a technical term for describing database designs. Basically, if the tables are normalised, then each &#039;fact&#039; is stored in exactly one place. A normalised database is much less likely to get into an inconsistent state. Changing to a normalised structure should therefore increase robustness.&lt;br /&gt;
&lt;br /&gt;
In addition, I wish to change the tables, so the the responses received from the student are stored in a much more &#039;raw&#039; form. That will mean that the responses can be saved much earlier in the sequence of processing, which will again increase robustness. It will also allow the sequence of responses from the student to be replayed more easily, making it easier to continue after a server crash, to regrade, and to write automatic test scripts.&lt;br /&gt;
&lt;br /&gt;
The detailed design describes the new database structure.&lt;br /&gt;
&lt;br /&gt;
(+++Robustness, +Correctness)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==New concept: Question behaviours==&lt;br /&gt;
&lt;br /&gt;
At the moment, the various sequences of states that a question can move through in response to student input is hard-coded. It is controlled by a combination of the compare_responses and grade_responses methods of the question types, and tangled logic in the question_process_responses function. This makes it difficult to add new ways on interacting with questions, for example certainty based marking. Also, the current code is tricky to keep working.&lt;br /&gt;
&lt;br /&gt;
I would like to separate out the control of how a question moves through different states, into what I will call question behaviours. Currently, Moodle has three or four of these:&lt;br /&gt;
&lt;br /&gt;
===Deferred feedback===&lt;br /&gt;
&lt;br /&gt;
This is how the quiz currently work when adaptive mode is off. The student enters a response to each question, then does Submit all and finish at the end of their attempt. Only then do they get feedback and/or grades on each question, depending on the review settings.&lt;br /&gt;
&lt;br /&gt;
===Adaptive===&lt;br /&gt;
&lt;br /&gt;
In this mode there is a separate submit button beside each question, so the student can submit each question individually during the attempt, and if they are wrong, try to improve their answer, although for a reduced grade.&lt;br /&gt;
&lt;br /&gt;
Currently, the way adaptive mode works from the student point of view is not very good. I propose to replace it with a new Interactive mode. See below.&lt;br /&gt;
&lt;br /&gt;
===Manually graded===&lt;br /&gt;
&lt;br /&gt;
Essay questions need to be manually graded by the teacher, so you cannot really use them in adaptive mode (although currently there is nothing in the Quiz to stop you, which leads to confusing results). And it is not quite the same as Deferred feedback mode, because the student must wait for the teacher to grade their response after clicking submit all and finish.&lt;br /&gt;
&lt;br /&gt;
===Each attempt builds on last===&lt;br /&gt;
&lt;br /&gt;
This is very similary to the deferred feedback model, except that in subsequent attempts, each question does not start blank, but instead with the student&#039;s last response from the previous attempt.&lt;br /&gt;
&lt;br /&gt;
Currently in Moodle there is nothing to stop you trying to combine Each attempt builds on last with Adaptive mode, although that combination does not make any sense to me. I think it simplifies things to treat this as a separate mode, although, of course, it will share code with Deferred feedback mode.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are also some new modes that I propose to add, either immediately, or shortly after the main part of the work:&lt;br /&gt;
&lt;br /&gt;
===Interactive===&lt;br /&gt;
&lt;br /&gt;
This will replace adaptive mode. This is the model that has been used successfully for several years in the OU&#039;s [http://www.open.ac.uk/openmarkexamples/ OpenMark] system. The OU has also  modified Moodle to work like this, but because of the way the quiz core currently works, I was not happy just merging the OU changes into Moodle core. In a sense, this whole document grew out of my thoughts about how to implement the OU changes in Moodle core properly.&lt;br /&gt;
&lt;br /&gt;
In the existing adaptive mode, after the student has clicked submit, the question both shows the feedback for the last answer the student submitted, while also letting the student change their answer. This can lead to weird results. For example create a numerical question 2 + 2 = 4. Attempt it. Enter 4. Click Submit. Enter 5. Click Save. You will see a page that seems to say that your answer is 5 and it is correct!&lt;br /&gt;
&lt;br /&gt;
In Interactive mode, the question is either in a state for the student to enter their answer, with a Submit button; or it is showing feedback for the student&#039;s previous attempt, with a Try again button to get back to the first state.&lt;br /&gt;
&lt;br /&gt;
The other difference is that students are only allowed a limited number of tries at each question (typically three). When they submit their third try, or when they submit a correct answer, that question is finished and they must go onto the next one.&lt;br /&gt;
&lt;br /&gt;
(This is quite difficult to explain. Try [https://students.open.ac.uk/openmark/s205.ayrf/ this example] and you should see how it works.)&lt;br /&gt;
&lt;br /&gt;
===Immediate feedback===&lt;br /&gt;
&lt;br /&gt;
This would be like cross between Deferred feedback an Interactive. Each question has a submit button beside it, like in interactive mode, so the student can get the feedback immediately while they still remember their thought processes while answering the question. However, unlike the interactive model, there is no try again button. You only get one chance at each question.&lt;br /&gt;
&lt;br /&gt;
This is a necessary prerequisite for implementing MDL-11047, which is fairly frequently asked for in the quiz forum.&lt;br /&gt;
&lt;br /&gt;
===Certainty based marking with deferred feedback===&lt;br /&gt;
&lt;br /&gt;
This takes any question that can use the deferred feedback model, and adds three radio buttons to the UI (higher, medium, lower) for the student to use to indicate how certain they are that their answer is correct. If they are more certain, the get more marks if they are right, but lose marks if they are wrong. This encourages students to reflect about their level of knowledge.&lt;br /&gt;
&lt;br /&gt;
===Certainty based marking with immediate feedback===&lt;br /&gt;
&lt;br /&gt;
This is like immediate feedback mode with the certainty based marking feature.&lt;br /&gt;
&lt;br /&gt;
===Delegate to a remote system===&lt;br /&gt;
&lt;br /&gt;
The Opaque question type from contrib, which is used to run both OpenMark and [http://stack.bham.ac.uk/ STACK] questions inside a Moodle quiz was very difficult to implement within the current code. Since the remote system controls the flow of the question, it makes sense to use a custom behaviour for this question type, and that will be possible in the new code.&lt;br /&gt;
&lt;br /&gt;
===Information item===&lt;br /&gt;
&lt;br /&gt;
Used for descriptions. There is no grade. Item gets marked as complete after the student has seen it once. Displays general feedback after the attempt is over.&lt;br /&gt;
&lt;br /&gt;
===Missing===&lt;br /&gt;
&lt;br /&gt;
This is like the Missing question type. This behaviour is used in the situation:&lt;br /&gt;
# Admin installs some behaviour.&lt;br /&gt;
# Student attempts quiz using that model.&lt;br /&gt;
# Admin uninstalls that model.&lt;br /&gt;
# Teacher tries to review that student&#039;s attempt.&lt;br /&gt;
The missing question behaviour does the best job it can to allow the review of the attempt with the missing model, while displaying an on-screen warning.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So, what exactly does the behaviour control? Given the current state of the question, it limits the range of actions that are possible. For example, in adaptive mode, there is a submit button next to each question. In non-adaptive mode, the only option is to enter an answer and have it saved, until the submit all and finish button is pressed. That is, there will be a class in the PHP code for each model, and it will have methods that replace the old question_extract_responses, question_process_responses, question_process_comment and save_question_state functions in the current code.&lt;br /&gt;
&lt;br /&gt;
(+++Richness, ++Correctness, +Robustness)&lt;br /&gt;
&lt;br /&gt;
===Brief digression: who controls the model, the quiz or the question?===&lt;br /&gt;
&lt;br /&gt;
There is one design decisions that it took a long time for me to resolve, and I want to mention it here.&lt;br /&gt;
&lt;br /&gt;
The question is: Is the behaviour a property of the question, or the quiz?&lt;br /&gt;
&lt;br /&gt;
At the moment, there is a setting in the quiz that lets you change all the questions in the quiz from adaptive mode to non-adptive mode at the flick of a switch. Or, at least, it allows you to re-use the same questions in both adaptive and non-adaptive mode. This suggest that the behaviour is a property of the quiz.&lt;br /&gt;
&lt;br /&gt;
On the other hand, suppose that you wanted to introduce the feature that, in adaptive mode, the student gets different amounts of feedback after each try at getting the question right. For example, the first time they get it wrong the only get a brief hint. If they are wrong the second time they get a more detailed comment, and so on. In order to do this, you need more data (the various hints) in order to define an adaptive question that is irrelevant to a non-adaptive question. Also, certain question types (e.g. Opaque, from contrib) have to, of necessity, ignore the adaptive, non-adaptive setting. And I suggested above that, manually graded question types like Essay should really be considered to have a separate behaviour. This suggests that the behaviour is a properly of the individual question. (Although usability considerations suggest that a single quiz should probably be constructed from questions with similar behaviour.)&lt;br /&gt;
&lt;br /&gt;
I eventually concluded that both answers are right. That is, it is a good idea for the quiz to have a setting like adaptive/non-adaptive that sets out the teacher&#039;s intention of how each question in this quiz should behave. However, the exact choice of behaviour to use is up to the different question types. When a quiz attempts is started, each question type is asked something like &amp;quot;A quiz attempt is starting using &#039;adaptive mode&#039;. Exactly which behaviour should be used for questions of this type in this attempt?&amp;quot; This gives questions that can only work in a certain way (for example essay questions) a chance to override the quiz setting.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Clarifying question states==&lt;br /&gt;
&lt;br /&gt;
Although there is a database table called question_states, the column there that stores the type of state is called event, and the values stored there are active verbs like open, save, grade. The question_process_responses function is written in terms of these actions too. One nasty part is that during the processing, the event type can be changed several times, before it is finally stored in the database as a state.&lt;br /&gt;
&lt;br /&gt;
I would like to clearly separate the concept of the current state that a question is in, and the various actions that lead to a change of state. The actions will be handled by the behaviours, and the state will be stored in the database as a state.&lt;br /&gt;
&lt;br /&gt;
The list of available states will also be changed slightly to match the following diagram. This came from thinking about what information it was important to display in the quiz navigation block.&lt;br /&gt;
&lt;br /&gt;
[[Image:Question_state_diagram.png]]&lt;br /&gt;
&lt;br /&gt;
(+Correctness, +Richness).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==What are the parts of a question?==&lt;br /&gt;
&lt;br /&gt;
When we come to think of outputting a question on-screen, we can now see that there are several things that affect what it will look like:&lt;br /&gt;
# The question type (multichoice, shortanswer, essay, ...)&lt;br /&gt;
# The behaviour (deferred feedback, interactive, CBM, ...)&lt;br /&gt;
# What state the question is in (has the student answered yet, has it been graded, ...)&lt;br /&gt;
# The options from the particular activity (whether any marks are available for this question, are students allowed to see their grades, how many decimal places to use to display grades, does this user have permission to make a manual comment ...)&lt;br /&gt;
&lt;br /&gt;
Also, we want different question type and behaviours to have the freedom to display whatever they like to the students; but we also want all the questions in a quiz to look and behave consistently, so that the experience is not confusing.&lt;br /&gt;
&lt;br /&gt;
In the sketch below, I try to summarise the bits that may be present in a typical question. If all questions can have these bits in this order, then that is probably enough consistency. The flexibility comes from allowing the question type or behaviour to put whatever it likes inside those bits. &lt;br /&gt;
&lt;br /&gt;
We can divide what you see when looking at a question is into three main parts:&lt;br /&gt;
# Information (meta-data): Which question number this is, a summary of what state it is currently in, what grade you have got for it (or how many marks are available, if any), whether you have flagged it. This has a grey background in the sketch below.&lt;br /&gt;
# The question and the response to it. This has a blue background in the sketch.&lt;br /&gt;
# The outcome from submitting that response. This has a yellow background.&lt;br /&gt;
&lt;br /&gt;
[[Image:Parts of a question2.png]]&lt;br /&gt;
&lt;br /&gt;
The full list of options that control which of those bits are visible at any time are:&lt;br /&gt;
&lt;br /&gt;
; correctness : (hidden / visible) whether the student gets told whether their answer was (in/partially)correct in the status summary under the question number, or instead are told something vague like &#039;Finished&#039;.&lt;br /&gt;
; marks : (hidden / max only / actual mark and max / actual mark and max with explanation ) whether the student can see the number of marks available, and how many marks they got, and how much detail of the marking to display.&lt;br /&gt;
; marks d.p. : (0 .. 7) how many decimal places marks are displayed to.&lt;br /&gt;
; flags: (hidden / visible / visible and editable) this is the feature that lets students bookmark or flag a question in an attempt for later reference.&lt;br /&gt;
; read-only: Whether the question just shows the response was already entered, or whether it gives controls to the user enter/change their response.&lt;br /&gt;
; specific feedback: (hidden / visible) feedback that relates to the particular response the student entered.&lt;br /&gt;
; general feedback : (hidden / visible) whether the general feedback (same for all students) is visible.&lt;br /&gt;
; correct response : (hidden / visible) whether the automatically generated message or other indication of the correct answer is visible.&lt;br /&gt;
; manual comment: (hidden / visible / visible and editable) whether the comment manually added by the teacher is visible and editable by the current user.&lt;br /&gt;
; response history : (hidden / visible) whether the list of steps the student went through to answer the question is displayed.&lt;br /&gt;
&lt;br /&gt;
These options are initially set by whatever it is that is using the question (for example the quiz will initialise them from the quiz settings). Then these options are modified by the behaviour. For example it should ensure that no feedback is displayed until the student has actually submitted an answer, or that after they have submitted their final answer, the question only appears in read-only mode.&lt;br /&gt;
&lt;br /&gt;
==Reorganise the code==&lt;br /&gt;
&lt;br /&gt;
There will, of course, be a new class for each behaviour, that all inherit from the same base class.&lt;br /&gt;
&lt;br /&gt;
At the moment question type classes have multiple responsibilities.&lt;br /&gt;
# They is information about the question types, and loading and saving, importing and exporting, backing up and restoring questions of that type.&lt;br /&gt;
# Then there is the processing of student responses for a particular instances of that question type.&lt;br /&gt;
# And then there is displaying the question in its various states.&lt;br /&gt;
(Fortunately, 4. Displaying an editing form, is already in a separate class.)&lt;br /&gt;
&lt;br /&gt;
Moodle 2.0 introduces the [[Theme_engines_for_Moodle%3F|renderer concept]]. Introducing qtype renderers will move the output code (3) into separate classes. This change to the question engine is the appropriate time to introduce qtype renderes.&lt;br /&gt;
&lt;br /&gt;
I will also introduce a new set of classes to store the state of a question within a quiz attempt. That is basically the combination of the $question and $state objects that are passed around at the moment, but with a specific subclass for each question type. This moves all the processing logic (2) into a separate class. That leaves the question type class itself just responsible for (1).&lt;br /&gt;
&lt;br /&gt;
Of course the behaviour classes and the question_state classes need to work together, and this is clearly a situation for the [http://en.wikipedia.org/wiki/Strategy_pattern strategy pattern]. However, I have not yet decided whether the question type is the context, and the iteration model is the strategy, or vice versa. I will have to see which comes out better when I do the implementation.&lt;br /&gt;
&lt;br /&gt;
Finally, there will be a new class in questionlib.php for managing the set of questions in an attempt. Already, in the Moodle 2.0 quiz developments, I have changed the quiz code to create a quiz_attempt class. This keeps track of all the questions in the quiz attempt. However, this really needs to be split into two bits. The job of tracking a set of questions and what state they are in is exactly the job of the question engine. Therefore we should have a question_set_attempt class that does that job. That class will take over the job of a number of functions in questionlib.php, for example question_load_states. Then the quiz_attempt class can just focus on the quiz-specific things, and use the question_set_attempt class. This new class should make it easier to use questions in other modules.&lt;br /&gt;
&lt;br /&gt;
It should be possible to organise the code so that only the question_set_attempt class had to load or save data to or from the database. It will then pass that data on to wherever it is needed. That should be good for efficiency.&lt;br /&gt;
&lt;br /&gt;
(+Robustness, +Efficiency)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Simplified API for question types==&lt;br /&gt;
&lt;br /&gt;
In the summary of how the quiz currently works, I said, &amp;quot;The student enters an answer to each question which is saved. Then when they submit the quiz attempt, all the questions are graded.&amp;quot; In fact, that was a lie. Whenever a response is saved, the grade_responses method of the question type is called, even in the state is only being saved. This is confusing, to say the least, and very bad for performance in the case of a question type like JUnit (in contrib) which takes code submitted by the student, and compiles it in order to grade it.&lt;br /&gt;
&lt;br /&gt;
So some of the API will only change to the extent that certain functions will in future only be called when one would expect them to be. I think this can be done in a backwards-compatible way.&lt;br /&gt;
&lt;br /&gt;
Another change will be that, at the moment, question types have to implement tricky load/save_question_state methods that, basically, have to unserialise/serialise some of the state data in a custom way, so it can be stored in the answer column. This is silly design, and leads to extra, unnecessary database queries. The changes to the database structure will to eliminate the need for these methods.&lt;br /&gt;
&lt;br /&gt;
Hopefully the above changes to how the code is organised will make it mauch easier to write new question types.&lt;br /&gt;
&lt;br /&gt;
(+Richness, +Correctness, +Efficiency)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduce more automated testing==&lt;br /&gt;
&lt;br /&gt;
Since the question_set_attempt class keeps track of all the data that is needed when processing questions, it should be very easy to write automatic tests (unit tests) for all the other parts of the question engine. That should greatly help in eliminating bugs.&lt;br /&gt;
&lt;br /&gt;
I am intending to take a [http://en.wikipedia.org/wiki/Test-driven_development test-driven] approach to implementing this proposal.&lt;br /&gt;
&lt;br /&gt;
(+++Correctness, ++Robustness)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
In the next section, [[Question Engine 2:Design|Design]], gives the detailed design of the above solution.&lt;br /&gt;
&lt;br /&gt;
* Back to [[Question_Engine_2|Question Engine 2]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=How_to_create_a_patch&amp;diff=6778</id>
		<title>How to create a patch</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=How_to_create_a_patch&amp;diff=6778"/>
		<updated>2008-07-01T08:00:40Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: /* Creating a patch using CVS (command line) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you have made some changes to the code that you would like to share with the community, particularly if you want to send them to one of the core developers for possible inclusion in Moodle Core, it is very helpful if you can provide them as a patch file. Sometimes also called a diff file.&lt;br /&gt;
&lt;br /&gt;
This page explains how you can make a patch file. Patch is a standard format, and there are many options for how to create one. Pick the one that is easiest for you.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note, I have not been able to test most of these instructions. They are about right, but I am hoping that as people use them, they will fill in any gaps, correct any details, and so on.[[User:Tim Hunt|Tim Hunt]] 08:40, 25 June 2007 (CDT)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Introduction: what does a patch file look like==&lt;br /&gt;
&lt;br /&gt;
This is a simple example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Index: lang/en_utf8/quiz.php&lt;br /&gt;
===================================================================&lt;br /&gt;
RCS file: /cvsroot/moodle/moodle/lang/en_utf8/quiz.php,v&lt;br /&gt;
retrieving revision 1.57.2.10&lt;br /&gt;
diff -u -r1.57.2.10 quiz.php&lt;br /&gt;
--- lang/en_utf8/quiz.php	29 May 2007 17:47:25 -0000	1.57.2.10&lt;br /&gt;
+++ lang/en_utf8/quiz.php	25 Jun 2007 12:58:34 -0000&lt;br /&gt;
@@ -252,7 +255,6 @@&lt;br /&gt;
 $string[&#039;indivresp&#039;] = &#039;Responses of Individuals to Each Item&#039;;&lt;br /&gt;
 $string[&#039;info&#039;] = &#039;Info&#039;;&lt;br /&gt;
 $string[&#039;introduction&#039;] = &#039;Introduction&#039;;&lt;br /&gt;
-$string[&#039;invalidcategory&#039;] = &#039;Category ID is invalid&#039;;&lt;br /&gt;
 $string[&#039;invalidnumericanswer&#039;] = &#039;One of the answers you entered was not a valid number.&#039;;&lt;br /&gt;
 $string[&#039;invalidnumerictolerance&#039;] = &#039;One of the tolerances you entered was not a valid number.&#039;;&lt;br /&gt;
 $string[&#039;invalidsource&#039;] = &#039;The source is not accepted as valid.&#039;;&lt;br /&gt;
@@ -375,8 +377,10 @@&lt;br /&gt;
 $string[&#039;questiontypesetupoptions&#039;] = &#039;Setup options for question types:&#039;;&lt;br /&gt;
 $string[&#039;quiz:attempt&#039;] = &#039;Attempt quizzes&#039;;&lt;br /&gt;
 $string[&#039;quiz:deleteattempts&#039;] = &#039;Delete quiz attempts&#039;;&lt;br /&gt;
+$string[&#039;quiz:emailconfirmsubmission&#039;] = &#039;Receive own quiz submission notification&#039;;&lt;br /&gt;
+$string[&#039;quiz:emailnotifysubmission&#039;] = &#039;Receive student quiz submission notifications&#039;;&lt;br /&gt;
 $string[&#039;quiz:grade&#039;] = &#039;Grade quizzes manually&#039;;&lt;br /&gt;
-$string[&#039;quiz:ignoretimelimits&#039;] = &#039;Ignores time limit on quizzes&#039;;&lt;br /&gt;
+$string[&#039;quiz:ignoretimelimits&#039;] = &#039;Ignores time limit on quizs&#039;;&lt;br /&gt;
 $string[&#039;quiz:manage&#039;] = &#039;Manage quizzes&#039;;&lt;br /&gt;
 $string[&#039;quiz:preview&#039;] = &#039;Preview quizzes&#039;;&lt;br /&gt;
 $string[&#039;quiz:view&#039;] = &#039;View quiz information&#039;;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At the top it says which file is being affected. Changes to several files can be included in one patch. Lines added are shown with a &#039;+&#039;, lines removed are shown with a &#039;-&#039;, lines changed are shown as the old line being removed and the new one added.&lt;br /&gt;
&lt;br /&gt;
Patch files are good because they only show the changed parts of the file. This has two advantages: it easy to understand the change; and if other parts of the same files change between the patch being made an being used, there is no problem, the patch will still apply.&lt;br /&gt;
&lt;br /&gt;
==Creating a patch using diff==&lt;br /&gt;
&lt;br /&gt;
diff is the a linux command line program, and is where patch files originated. It requires that you have two copies of the code, one with your changes, and one without. Suppose these two copies are in folders called &#039;standard_moodle&#039; and &#039;my_moodle&#039; which are subdirectories of the current folder. Then to create the patch, type:&lt;br /&gt;
&lt;br /&gt;
 diff -ur standard_moodle my_moodle &amp;gt; patch.txt&lt;br /&gt;
&lt;br /&gt;
==Creating a patch using CVS (command line)==&lt;br /&gt;
&lt;br /&gt;
It is easier if you are using CVS to manage your development, because you don&#039;t need to keep the copy of &#039;standard_moodle&#039;. CVS takes care of that for you. In you workspace (sandbox) type:&lt;br /&gt;
&lt;br /&gt;
 cvs diff -uN &amp;gt; patch.txt&lt;br /&gt;
&lt;br /&gt;
If you have unversioned files to include in your patch, you will notice that the above command simply adds the file&#039;s name to the top of your patch, prefixed with a question mark. This is because your new file is not tagged for adding to the repository. Just do&lt;br /&gt;
&lt;br /&gt;
 cvs add newfile&lt;br /&gt;
&lt;br /&gt;
Then &lt;br /&gt;
&lt;br /&gt;
 cvs diff -uNa &amp;gt; patch.txt&lt;br /&gt;
&lt;br /&gt;
This should add the correct code to the patch, so that someone applying the patch to their working copy will have a new file created at the right place (hopefully!).&lt;br /&gt;
&lt;br /&gt;
If your patch, for some reason, contains a lot of white space changes in many files, you might want to add -Bbw to the diff call. Make sure these changes are really not significant (like adding or removing a space at the end of a line - editors like Eclipse sometimes do this automatically). This can make a patch a lot smaller, and thus easier to review. The complete call would then be &lt;br /&gt;
&lt;br /&gt;
 cvs diff -uNawbB &amp;gt; patch.txt&lt;br /&gt;
&lt;br /&gt;
==Creating a patch using Tortoise CVS==&lt;br /&gt;
&lt;br /&gt;
[http://www.tortoisecvs.org/ Tortoise CVS] is a Windows GUI front end for CVS. To create a patch, right-click on a folder in CVS, and choose &#039;&#039;&#039;CVS -&amp;gt; Make patch ...&#039;&#039;&#039; from the context menu.&lt;br /&gt;
&lt;br /&gt;
==Creating a patch using Eclipse==&lt;br /&gt;
&lt;br /&gt;
See [[Setting_up_Eclipse#Creating_a_patch]]. Eclipse makes creating patches really easy, once you have got it set up correctly.&lt;br /&gt;
&lt;br /&gt;
==Creating a patch using WinMerge==&lt;br /&gt;
&lt;br /&gt;
[http://winmerge.org/ WinMerge] is a nice windows GUI for comparing folders. In this sense it is like the original command-line &#039;diff&#039; program. You need a copy of &#039;standard_moodle&#039; and &#039;my_moodle&#039;. Use &#039;&#039;&#039;File -&amp;gt; Open...&#039;&#039;&#039; to open the two versions for comparison. This will give you a nice view of what you have changed. Then do &#039;&#039;&#039;Tools -&amp;gt; Generate patch ...&#039;&#039;&#039;. In the dialogue box, make sure you select Style: Unified in the Format box.&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Talk:Setting_up_Eclipse&amp;diff=27065</id>
		<title>Talk:Setting up Eclipse</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Talk:Setting_up_Eclipse&amp;diff=27065"/>
		<updated>2008-06-26T01:28:32Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: New section: Eclipse and whitespace&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Really nice work, Tim, thanks!   I&#039;ve been through and I&#039;m trying it out.    [[User:Martin Dougiamas|Martin Dougiamas]] 09:05, 5 September 2006 (CDT)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
The stuff about changing editors under General -&amp;gt; Editors -&amp;gt; File Associations doesn&#039;t work any more if an Eclipse plugin has &#039;locked&#039; a file type or content type. Not sure how to fix this&lt;br /&gt;
--[[User:Andy Baker|Andy Baker]] 06:40, 28 November 2006 (CST)&lt;br /&gt;
&lt;br /&gt;
Hopefully it will be the PHP plugin, and it will have locked *.php to the setting you want anyway. If not, can you tell us exactly what you are seeing.[[User:Tim Hunt|Tim Hunt]] 04:24, 29 November 2006 (CST)&lt;br /&gt;
&lt;br /&gt;
== Problems with Ubuntu 6.10... ==&lt;br /&gt;
&lt;br /&gt;
I&#039;d really like to switch completely to Linux and Eclipse on my Moodle developments. However, I can&#039;t get the PHPEclipse plug-in to work with Eclipse 3.2 that came with Ubuntu 6.10. After the Eclipse restart required by the &amp;quot;add . to the include path&amp;quot; tweak, the &amp;quot;PHPEclipse stuff&amp;quot; is gone from the menus (forgot what it said), and when I try to open a PHP file in Eclipse I get:&lt;br /&gt;
&amp;quot;Failed to execute runnable (java.lang.NoClassDefFoundError: net.sourceforge.phpeclipse.phpeditor.PHPUnitEditor)&amp;quot; and &amp;quot;Unhandled event loop exception&amp;quot;... Going to Google around a bit, but there seems to be a lot of other issues with the JVM also: Eclipse crashed when I tried to search the help, for example. --[[User:Samuli Karevaara|Samuli Karevaara]] 04:07, 20 December 2006 (CST)&lt;br /&gt;
:Just reporting that now the error message has changed to &amp;quot;Problems occurred when invoking code from plug-in: &amp;quot;org.eclipse.jface&amp;quot;.&amp;quot; or I was reading the wrong part of the error log before... --[[User:Samuli Karevaara|Samuli Karevaara]] 04:11, 20 December 2006 (CST)&lt;br /&gt;
:One headache later I was able to get Eclipse to open the PHP files. Apparently it was about the Java Runtime Environment version after all. I had &amp;quot;sun-java5-bin : Sun Java(TM) Runtime Environment (JRE) 5.0&amp;quot; package installed but it didn&#039;t help. After completely removing everything &amp;quot;Java 1.4&amp;quot; (&amp;quot;j2re1.4&amp;quot; and friends) and upgrading &amp;quot;libgjc&amp;quot; packages I got it to work. I reeeeally not a friend of Java versioning and library packaging! --[[User:Samuli Karevaara|Samuli Karevaara]] 06:05, 20 December 2006 (CST)&lt;br /&gt;
&lt;br /&gt;
== Ubuntu Eclipse Improvements ==&lt;br /&gt;
&lt;br /&gt;
Just found this:&lt;br /&gt;
http://wiki.liferay.com/index.php/Liferay_Development_Environment:_Ubuntu_Linux#Eclipse_IDE&lt;br /&gt;
&lt;br /&gt;
It may help a bit.&lt;br /&gt;
&lt;br /&gt;
There is a problem wiht the different java VM. If you set that the vm is the one of sun it must be like this everywere&lt;br /&gt;
I did that:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   $ sudo aptitude install eclipse-sdk&lt;br /&gt;
&lt;br /&gt;
Remove any reference to gcj in &lt;br /&gt;
     /etc/eclipse/java_home.&lt;br /&gt;
&lt;br /&gt;
edit the file /usr/bin/eclipse and comment&lt;br /&gt;
&lt;br /&gt;
    -Dgnu.gcj.precompiled.db.path=/var/lib/gcj-4.1/classmap.db et &lt;br /&gt;
   -Dgnu.gcj.runtime.VMClassLoader.library_control=never.&lt;br /&gt;
&lt;br /&gt;
For me now eclipse runs with no problem&lt;br /&gt;
&lt;br /&gt;
== Prefs file missing? ==&lt;br /&gt;
&lt;br /&gt;
Working through this bit:&lt;br /&gt;
&lt;br /&gt;
  Open the file net.sourceforge.phpeclipse.ui.prefs that is in the directory (your&lt;br /&gt;
  workspace)/.metadata/.plugins/org.eclipse.core.runtime/.settings in a text editor.&lt;br /&gt;
&lt;br /&gt;
the file is not there. net.sourceforge.phpeclipse.prefs is present, but does not have the line described.&lt;br /&gt;
&lt;br /&gt;
Also,&lt;br /&gt;
&lt;br /&gt;
  Under Team -&amp;gt; CVS -&amp;gt; SSH2 Connection Method,&lt;br /&gt;
&lt;br /&gt;
this path does not exist (working on Xandros with linux eclipse)&lt;br /&gt;
&lt;br /&gt;
[[User:Matt Gibson|Matt Gibson]] 16:48, 17 January 2008 (CST)&lt;br /&gt;
&lt;br /&gt;
== net.sourcegorge.phpeclipse.ui.prefs ==&lt;br /&gt;
&lt;br /&gt;
Note that in the documentation is:&lt;br /&gt;
- Look for a line in the file that starts _php_include_paths= &#039;&#039;&#039;If it is not there, add it at the end&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
In my case, it was nothing there, so I add the line &lt;br /&gt;
_php_include_paths=.&lt;br /&gt;
and work.&lt;br /&gt;
&lt;br /&gt;
== Under Team -&amp;gt; CVS -&amp;gt; SSH2 Connection Method ==&lt;br /&gt;
&lt;br /&gt;
I found this to be &#039;&#039;&#039;General -&amp;gt; Network Connections -&amp;gt; SSH2 -&amp;gt; Key Management&#039;&#039;&#039; (the documentation is updated).&lt;br /&gt;
&lt;br /&gt;
After generating a DSA key, and following the rest of the instructions, I finally finish setting up Eclipse.&lt;br /&gt;
&lt;br /&gt;
== Eclipse and whitespace ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(Moving this out of main page, so as not to confuse people with discussion...) I suggested ... Under &#039;&#039;&#039;General -&amp;gt; Compare/Patch&#039;&#039;&#039;, turn on &#039;&#039;&#039;Ignore white space&#039;&#039;&#039; if you plan to exchange patches with other developers or send patches on the tracker. This will make patches smaller and easier to compare. [[User:Mathieu Petit-Clair|Mathieu Petit-Clair]] 20:28, 25 June 2008 (CDT)&lt;br /&gt;
&lt;br /&gt;
Tim replied: but that is a very bad idea. Whitespace is important, you should not change it unnecessarily, and so whitespace changes should be included in patches.&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
You&#039;ve got good point there, whitespace is significant. But Eclipse seems to remove trailing space (eg. at the end of lines) by itself, and this makes patches I receive from Eclipse users impossible to apply after a few days of hacking in cvs head. :(  Is there a way to tell Eclipse not to remove whitespace by itself? I really like to work with patches, but when they&#039;re twice as big as they should be and don&#039;t apply, it makes it a nightmare... [[User:Mathieu Petit-Clair|Mathieu Petit-Clair]] 20:28, 25 June 2008 (CDT)&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Setting_up_Eclipse&amp;diff=4970</id>
		<title>Setting up Eclipse</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Setting_up_Eclipse&amp;diff=4970"/>
		<updated>2008-06-26T01:23:33Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: /* General settings */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.eclipse.org/ Eclipse] is an IDE originally designed for Java, but now with plugins for many languages including PHP. It has lots of very powerful features, and it is the editor that some Moodle developers like to use. Other (more) popular choices are vim and emacs.&lt;br /&gt;
&lt;br /&gt;
However, Eclipse is not the easiest program in the world to get started with, so I&#039;m going to take you through it step by step. These instructions assume Eclipse 3.2, the current version at the time of writing. It should not change much between releases.&lt;br /&gt;
&lt;br /&gt;
This article started off as a brain-dump by [[User:Tim Hunt|Tim Hunt]]. Since then, several other people have worked through it and made corrections, so the information here should be pretty accurate.&lt;br /&gt;
&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
&lt;br /&gt;
Eclipse is written in Java, so I recommend getting the latest Java runtime environment from http://java.com/ for maximum speed and reliability.&lt;br /&gt;
&lt;br /&gt;
Eclipse is quite big, so I recommend lots of memory in your computer. I have used it on Windows, MacOS X and Linux, in each case with 1GB of memory, and that is plenty.&lt;br /&gt;
&lt;br /&gt;
==Installing Eclipse==&lt;br /&gt;
&lt;br /&gt;
Go to http://www.eclipse.org/downloads/. Click on the link corresponding to your operating system where it says &#039;&#039;&#039;Eclipse Classic&#039;&#039;&#039;. Choose a Mirror, and wait for the ~100MB download.&lt;br /&gt;
&lt;br /&gt;
You will notice that what you have got is a zip file (unless your system automatically decompresses it for you).&lt;br /&gt;
&lt;br /&gt;
On Windows, unzip it into &#039;&#039;&#039;C:\Program Files&#039;&#039;&#039; (all the files go into an &#039;&#039;&#039;Eclipse&#039;&#039;&#039; folder there). Then look in the Eclipse folder and drag Eclipse.exe to the Start menu/Desktop/Quicklaunch bar to make a shortcut for starting it.&lt;br /&gt;
&lt;br /&gt;
On MacOS, unzip and copy the Eclipse folder into Applications. Go into the Eclipse folder and drag the Eclipse app to the Dock for ease of launching.&lt;br /&gt;
&lt;br /&gt;
On Linux, unzip somewhere suitable, and make an easy way to launch it.&lt;br /&gt;
&lt;br /&gt;
==The first time you run Eclipse==&lt;br /&gt;
&lt;br /&gt;
The first time you launch Eclipse it does a bit of setup stuff, for instance, it create a &#039;&#039;&#039;workspace&#039;&#039;&#039;. This is where it stores the things you are working on. The default location is sensible on all platforms, so use that. &lt;br /&gt;
&lt;br /&gt;
For some reason, every time you start Eclipse, it asks you which workspace you want to use. I have never seen the need to have more than one, so I recommend turning on the checkbox that says &amp;quot;Use this as the default and do not ask again&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Another thing that happens the first time you run Eclipse is that you arrive at a welcome screen. This has links to various bits of help, which you can read if you like, but you probably don&#039;t need to if you are following these instructions. So find the button on the welcome page that closes it and gets you to the main Eclipse screen.&lt;br /&gt;
&lt;br /&gt;
==Installing the necessary plugins==&lt;br /&gt;
&lt;br /&gt;
By default, Eclipse comes with the Java tools. For everything else you will need to install some plugins.&lt;br /&gt;
&lt;br /&gt;
If you are sitting behind a web proxy, from the &#039;&#039;&#039;Window&#039;&#039;&#039; menu choose &#039;&#039;&#039;Preferences ...&#039;&#039;&#039;. Choose &#039;&#039;&#039;Install/Update&#039;&#039;&#039; from the tree view on the left, and enter the proxy information in the boxes on the right. If you aren&#039;t behind a proxy, ignore this step.&lt;br /&gt;
&lt;br /&gt;
From the &#039;&#039;&#039;Help&#039;&#039;&#039; menu choose &#039;&#039;&#039;Software Updates -&amp;gt; Find and Install&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
On the first screen of the wizard, make sure that &amp;quot;Search for new features to install&amp;quot; is selected, then click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The next screen is a list of upgrade sites to check. You need to add one to the list, so click the &#039;&#039;&#039;New Remote Site ...&#039;&#039;&#039; Button.&lt;br /&gt;
&lt;br /&gt;
In the pop-up dialog, give the remote site a name like &#039;&#039;&#039;PHPeclipse Update Site&#039;&#039;&#039;; set the URL to http://phpeclipse.sourceforge.net/update/releases/; then click &#039;&#039;&#039;OK&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note, there is now also another PHP editor for Eclipse. The update URL ishttp://download.eclipse.org/tools/pdt/updates/. I am just trying it--[[User:Tim Hunt|Tim Hunt]] 11:39, 7 November 2007 (CST)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Back in the wizard, turn on just two things in the box &amp;quot;Sites to include in search&amp;quot;:&lt;br /&gt;
* Your newly created &#039;&#039;&#039;Phpeclipse Update Site&#039;&#039;&#039;; and&lt;br /&gt;
* the one called &#039;&#039;&#039;Europa Discovery Site&#039;&#039;&#039; (or possibly &#039;&#039;&#039;Callisto Discovery Site&#039;&#039;&#039;.&lt;br /&gt;
Then click &#039;&#039;&#039;Finish&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
It goes off sees what updates are available at those sites. As it does so, it may occasionally pop up a dialog asking you to choose a mirror. Each time, select a sensible one.&lt;br /&gt;
&lt;br /&gt;
Eventually, you get to a new wizard for selecting and installing the updates you want. The ones you want (you may have to search the tree structure) are, &#039;&#039;&#039;PHPeclipse&#039;&#039;&#039; (from your newly created PHPEclipse Update Site) and all the &#039;&#039;&#039;Web Standard Tools (WST)&#039;&#039;&#039; (usually under Callisto Discovery Site --&amp;gt; Web and J2EE Development).&lt;br /&gt;
&lt;br /&gt;
Next, and very importantly, you must click the &#039;&#039;&#039;Select Required&#039;&#039;&#039; button which should resolve dependencies and remove the warning message you are probably worrying about. Then you can click the &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
Read and agree to all the license agreements. Then click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Finish&#039;&#039;&#039;, and wait for the plugins to download.&lt;br /&gt;
&lt;br /&gt;
Once the downloads have finished, a warning will pop-up telling you that all the plugins you downloaded are not digitally signed. The Eclipse Foundation build digital signing of plugins into their architecture as a security measure, and then did not sign any of their own plugins! Anyway, click the &#039;&#039;&#039;Install All&#039;&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
Finally, a window will pop up asking you to restart Eclipse. Do so.&lt;br /&gt;
&lt;br /&gt;
==Setting the preferences for Moodle development==&lt;br /&gt;
&lt;br /&gt;
Now go to the &#039;&#039;&#039;Window&#039;&#039;&#039; menu, and choose &#039;&#039;&#039;Preferences ...&#039;&#039;&#039; (&#039;&#039;&#039;Eclipse&#039;&#039;&#039; menu on Mac OS X).&lt;br /&gt;
&lt;br /&gt;
The Eclipse preferences are immense, with a tree view on the left, which selects which screen to display on the right. Don&#039;t panic, we&#039;ll guide you through it.&lt;br /&gt;
&lt;br /&gt;
===General settings===&lt;br /&gt;
&lt;br /&gt;
If you have strong feelings about fonts (I would hate to edit code an anything except Andale Mono), choose &#039;&#039;&#039;General -&amp;gt; Appearance -&amp;gt; Colors and Fonts&#039;&#039;&#039; from the tree on the left. Then on the right look under &#039;&#039;&#039;Basic&#039;&#039;&#039; and change &#039;&#039;&#039;Text Font&#039;&#039;&#039;. All the other editor font settings will inherit from this, so this is probably the only one you have to change.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;General -&amp;gt; Content Types&#039;&#039;&#039;, select PHP Source File, and add &#039;&#039;&#039;*.html&#039;&#039;&#039; to the box at the bottom.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;General -&amp;gt; Editors -&amp;gt; File Associations&#039;&#039;&#039;, if it is not already there, add &#039;&#039;&#039;*.php&#039;&#039;&#039; to the top box. With &#039;&#039;&#039;*.php&#039;&#039;&#039; selected in the top box, make sure &#039;&#039;&#039;PHP Editor&#039;&#039;&#039; is set to default in the bottom box. With &#039;&#039;&#039;*.html&#039;&#039;&#039; selected in the top box, select &#039;&#039;&#039;PHP Editor&#039;&#039;&#039; in the bottom box and click the &#039;&#039;&#039;Default&#039;&#039;&#039; button to change it, because in Moodle, most HTML files actually contain PHP code.&lt;br /&gt;
&lt;br /&gt;
If you use a web proxy, enter the details under &#039;&#039;&#039;Internet -&amp;gt; Proxy Settings&#039;&#039;&#039;. (Yes, I know you have entered them somewhere else before. Now you have to enter them again here. I don&#039;t know why. You just do.)&lt;br /&gt;
&lt;br /&gt;
===PHP Settings===&lt;br /&gt;
&lt;br /&gt;
These are all hidden under the &#039;&#039;&#039;PHPeclipse Web Development&#039;&#039;&#039; bit of the tree.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;PHPeclipse Web Development -&amp;gt; Browser Preview Defaults&#039;&#039;&#039;, turn off both checkboxes.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;PHPeclipse Web Development -&amp;gt; PHP&#039;&#039;&#039;, on the &#039;&#039;&#039;Appearance&#039;&#039;&#039; tab, set &#039;&#039;&#039;Displayed tab width&#039;&#039;&#039; to 4.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;PHPeclipse Web Development -&amp;gt; PHP&#039;&#039;&#039;, on the &#039;&#039;&#039;Appearance&#039;&#039;&#039; tab, check &#039;&#039;&#039;Show line numbers&#039;&#039;&#039; to display line numbers in the left margin (optional). NOTE.- When you are editing a PHP file, you could left-click in the left margin and tick the &#039;&#039;&#039;Show Line Numbers&#039;&#039;&#039; line in the contextual menu. However, this toggle only applies to plain text files, &#039;&#039;not&#039;&#039; to HTML or PHP files. The only place where you can toggle line numbers on/off for such files is in the PHP/Appearance menu.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;PHPeclipse Web Development -&amp;gt; PHP&#039;&#039;&#039;, on the &#039;&#039;&#039;Typing&#039;&#039;&#039; tab, turn off all the options except &#039;&#039;&#039;Pasting for correct indentation&#039;&#039;&#039;, &#039;&#039;&#039;Insert spaces for tab&#039;&#039;&#039; and &#039;&#039;&#039;Close PHPdocs and comments&#039;&#039;&#039; and &#039;&#039;&#039;Remove trailing spaces on editor save&#039;&#039;&#039;. It would be nice to turn on more of these options, but most of the rest don&#039;t work very well.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;PHPeclipse Web Development -&amp;gt; PHP -&amp;gt; Formatter&#039;&#039;&#039;, on the &#039;&#039;&#039;New Lines&#039;&#039;&#039; tab, turn on &#039;&#039;&#039;Clear all blank lines&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;PHPeclipse Web Development -&amp;gt; PHP -&amp;gt; Formatter&#039;&#039;&#039;, on the &#039;&#039;&#039;Style&#039;&#039;&#039; tab, turn off &#039;&#039;&#039;Indentation is represented by a tab&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;PHPeclipse Web Development -&amp;gt; PHP -&amp;gt; Templates&#039;&#039;&#039;, I like to define a new template to help with debugging:&lt;br /&gt;
;Name&lt;br /&gt;
:dump &lt;br /&gt;
;Description&lt;br /&gt;
:Dump a PHP variable&lt;br /&gt;
;Pattern&lt;br /&gt;
&amp;lt;pre&amp;gt;print_object(${word_selection}${cursor}); // DONOTCOMMIT&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can do other useful things with templates too. Here are two more I use:&lt;br /&gt;
&amp;lt;pre&amp;gt;debugging(&amp;quot;&#039;${word_selection}${cursor}&#039;&amp;quot;); // DONOTCOMMIT&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;$$string[&#039;${word_selection}${cursor}&#039;] = &#039;.&#039;;&amp;lt;/pre&amp;gt;&lt;br /&gt;
That is, a simple debug message with a stack trace, and a new language string.&lt;br /&gt;
&lt;br /&gt;
There is a really stupid bug. Under &#039;&#039;&#039;PHPeclipse Web Development -&amp;gt; Project Defaults&#039;&#039;&#039;, you would like to add &amp;quot;.&amp;quot; to the &#039;&#039;&#039;Include Paths&#039;&#039;&#039;, but you can&#039;t using the GUI. You will have to edit one of the Eclipse config files by hand. So&lt;br /&gt;
# Note down the path to your Eclipse profile. On Windows it will be something like &#039;&#039;&#039;C:/Documents and settings/XXXX/workspace&#039;&#039;&#039;, and on Unixy systems something like &#039;&#039;&#039;~/workspace&#039;&#039;&#039;.&lt;br /&gt;
# Close Eclipse. &lt;br /&gt;
# Open the file &#039;&#039;&#039;net.sourceforge.phpeclipse.ui.prefs&#039;&#039;&#039; that is in the directory &#039;&#039;&#039;(your workspace)/.metadata/.plugins/org.eclipse.core.runtime/.settings&#039;&#039;&#039; in a text editor.&lt;br /&gt;
# Look for a line in the file that starts &#039;&#039;&#039;_php_include_paths=&#039;&#039;&#039; If it is not there, add it at the end.&lt;br /&gt;
# Change this line to say &#039;&#039;&#039;_php_include_paths=.&#039;&#039;&#039;&lt;br /&gt;
# Run Eclipse again.&lt;br /&gt;
&lt;br /&gt;
===SSH2===&lt;br /&gt;
Information about generating SSH2 keys for the purpose of connecting to cvs.moodle.org can be found here at https://docs.moodle.org/en/Development:SSH_key , but please finish reading this section before reading that material.&lt;br /&gt;
&lt;br /&gt;
The Eclipse installation has its own SSH client plugin so you do not have to use a separate ssh client in connection with your use of Eclipse (this is one reason you will be using extssh below,  instead of just ext,  however,  if you wish you may alter the configuration to use an external client but please post news of your success and configuration). See, http://www.jcraft.com/eclipse-cvsssh2/ , for additional information on this plugin.  &lt;br /&gt;
&lt;br /&gt;
&#039;&#039; Since Eclipse 3.0M6 the CVSSSH plugin is incorporated into Eclipse, [http://www.jroller.com/prane/entry/eclipse_3_0_cvs_support as &amp;quot;extssh&amp;quot; instead of &amp;quot;extssh2&amp;quot;] - --[[User:Olli Savolainen|Olli Savolainen]] 07:54, 23  June 2008 (CDT)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Please note that Eclipse is fully equipped to generate ssh2 rsa and dsa keys as well as import keys.  You may encounter issues with passphrases that are too long (a bug reportedly fixed but which may still in fact be present) and some issues with using keypairs generated by other applications have been seen, so it may be best to generate a key pair with Eclipse. Additional details on how to do this will be added.&lt;br /&gt;
&lt;br /&gt;
Sourceforge, at http://sourceforge.net/docs/F02/ , provides instructions on how to create a SSH key for it&#039;s CVS (remember,  Moodle does not use sourceforge for its CVS now and you will need to generate keys for cvs.moodle.org, not sourceforge). This is mentioned by way of general explanation, not for the purposes of providing instructions on how to generate your keys for Eclipse. To make use of the public key, login to Moodle.org and add it via the Update My Developer Information tab under CVS Developers (http://moodle.org/cvs). Remember,  public keys provided to Moodle must be in the Openssh format.&lt;br /&gt;
&lt;br /&gt;
===CVS Settings===&lt;br /&gt;
&lt;br /&gt;
These are almost all hidden under the &#039;&#039;&#039;Team&#039;&#039;&#039; bit of the tree.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;General -&amp;gt; Network Connections -&amp;gt; SSH2 -&amp;gt; Key Management&#039;&#039;&#039;, you can set up a public/private key pair. If you do this, you won&#039;t have to keep typing your password when doing CVS operations. &lt;br /&gt;
&lt;br /&gt;
The rest of the ones in this section are personal preferences, but I recommend them because the default settings are very irritating.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;Team&#039;&#039;&#039;, set &#039;&#039;&#039;Perspectives&#039;&#039;&#039; to &#039;&#039;&#039;None&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;Team -&amp;gt; CVS -&amp;gt; Annotate&#039;&#039;&#039; set &#039;&#039;&#039;Use Quick Diff annotate mode for local file annotations&#039;&#039;&#039; to &#039;&#039;&#039;Yes&#039;&#039;&#039;, and &#039;&#039;&#039;Open perspective after a &#039;Show Annotations&#039; operation&#039;&#039;&#039; to &#039;&#039;&#039;No&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;Team -&amp;gt; CVS -&amp;gt; Label Decorations&#039;&#039;&#039;, switch to the &#039;&#039;&#039;Icon Decorations&#039;&#039;&#039; tab and turn on all the settings, and then on the &#039;&#039;&#039;Text Decorations&#039;&#039;&#039; tab change both &#039;&#039;&#039;File Decoration&#039;&#039;&#039; and &#039;&#039;&#039;Folder Decoration&#039;&#039;&#039; to be just &#039;&#039;&#039;{name}&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===Web and XML settings===&lt;br /&gt;
&lt;br /&gt;
Foreach XXX in CSS, HTML, Javascript, XML:&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;Web and XML -&amp;gt; XXX Files -&amp;gt;XXX Source&#039;&#039;&#039;, choose &#039;&#039;&#039;Indent using spaces&#039;&#039;&#039; and &#039;&#039;&#039;indentation size&#039;&#039;&#039; 4.&lt;br /&gt;
&lt;br /&gt;
==Checking out the Moodle code==&lt;br /&gt;
&lt;br /&gt;
From the &#039;&#039;&#039;File&#039;&#039;&#039; menu, choose &#039;&#039;&#039;New -&amp;gt; Project ...&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In the wizard that pops up, choose &#039;&#039;&#039;CVS -&amp;gt; Projects from CVS&#039;&#039;&#039;, then click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Select &#039;&#039;&#039;Create a new repository location&#039;&#039;&#039;, then click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Fill in&lt;br /&gt;
&amp;lt;div style=&amp;quot;float: right; border: 1px solid orange; padding: 0 1em;&amp;quot;&amp;gt;&lt;br /&gt;
For anonymous CVS access use&lt;br /&gt;
;Host&lt;br /&gt;
:XX.cvs.moodle.org&lt;br /&gt;
where XX.cvs.moodle.org is one of [[CVS_for_Administrators#CVS_Servers|these mirrors]]&lt;br /&gt;
;Repository path&lt;br /&gt;
:/cvsroot/moodle&lt;br /&gt;
;User&lt;br /&gt;
:anonymous&lt;br /&gt;
;Password&lt;br /&gt;
:(leave blank)&lt;br /&gt;
;Connection type&lt;br /&gt;
:pserver&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
;Host&lt;br /&gt;
:cvs.moodle.org&lt;br /&gt;
;Repository path&lt;br /&gt;
:/cvsroot/moodle&lt;br /&gt;
;User&lt;br /&gt;
:(your Moodle CVS username)&lt;br /&gt;
;Password&lt;br /&gt;
:(if you set up the SSH2 key thing in preferences, leave this blank, otherwise, type in your Moodle CVS password.)&lt;br /&gt;
;Connection type&lt;br /&gt;
:extssh&lt;br /&gt;
(CVS experts, if you are confused by that last one, know it is an Eclipse-specific thing.) Then click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
On the next screen of the Wizard, choose &#039;&#039;&#039;Use an existing module&#039;&#039;&#039;. Wait a moment, then select &#039;&#039;&#039;moodle&#039;&#039;&#039; from the list. Click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
On the next screen, make sure the option &#039;&#039;&#039;Check out as a project configured using the New Project Wizard&#039;&#039;&#039; is selected, then click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Refresh Tags&#039;&#039;&#039;, then choose the branch you want. For now leave it set to &#039;&#039;&#039;HEAD&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Finish&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now you  will find yourself back at the start of the &#039;&#039;&#039;New Project&#039;&#039;&#039; Wizard. This is because of the option you chose three paragraphs ago. This time you should select &#039;&#039;&#039;PHP -&amp;gt; PHP Project&#039;&#039;&#039;, then click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Make up a project name. &#039;&#039;&#039;moodle&#039;&#039;&#039; would be sensible.&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Finish&#039;&#039;&#039;, and wait while all the moodle files are checked out of CVS.&lt;br /&gt;
&lt;br /&gt;
Once it has finished, it will probably ask you if you want to switch to the PHP perspective. Answer &#039;&#039;&#039;Yes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you also need another branch (1.6, 1.7, 1.8, ...) repeat all the other steps with a few changes:&lt;br /&gt;
* This time you can choose &#039;&#039;&#039;Use an existing repository location&#039;&#039;&#039; instead of typing all the sourceforge CVS details again.&lt;br /&gt;
* Select the appropriate branch. If you don&#039;t see the branch you want, see [https://docs.moodle.org/en/Development:Setting_up_Eclipse#Resetting_the_branch_information this Troubleshooting tip].&lt;br /&gt;
* Use a different project name (e.g. moodle16, moodle17, etc.).&lt;br /&gt;
&lt;br /&gt;
==Let your development web server know where your files are==&lt;br /&gt;
&lt;br /&gt;
Either by editing you web server&#039;s config files, or using a symbolic link. Make sure your webserver can see your new working set of files at a sensible URL, so you can test the code you are working on.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Quick tour of some cool features, and remaining configuration changes==&lt;br /&gt;
&lt;br /&gt;
I find the default workbench setup is pretty good. Here is a quick guide to some of the bits.&lt;br /&gt;
&lt;br /&gt;
===Navigator===&lt;br /&gt;
&lt;br /&gt;
To the left is the &#039;&#039;&#039;Navigator&#039;&#039;&#039;. This is a tree view of all your files. If you double-click on a file, it opens in the editor in the middle. Try opening &#039;&#039;&#039;course/lib.php&#039;&#039;&#039; now. You will notice that it comes up nicely syntax-hightlighted.&lt;br /&gt;
&lt;br /&gt;
===Error highlighting===&lt;br /&gt;
&lt;br /&gt;
In the middle of the file, just type any old text, for example &amp;quot;I like Eclipse&amp;quot;. Obviously, this is not valid PHP syntax, and Eclipse will notice this, and put a red underline under it. Also, by the scrollbar is a ruler with a red mark in it to show the error.&lt;br /&gt;
&lt;br /&gt;
You will see some yellow marks lower down the ruler. There are warnings. Click on one, and you will be taken to where that warning is in the file. Hover your mouse over the warning, and you will get a tooltip explaining what the problem might be.&lt;br /&gt;
&lt;br /&gt;
Save the edited file. (Don&#039;t worry that it is broken, we&#039;ll clean up the mess later.) Notice that a red error marker is added to the file in the navigator, so you can see that there is a problem. Also, error markers are added to the course folder, and the whole project, so you could see there was an error even if the navigator tree was collapsed.&lt;br /&gt;
&lt;br /&gt;
You will probably find lots of warnings that the config.php file can&#039;t be found. In the navigator, find the file &#039;&#039;&#039;config-dist.php&#039;&#039;&#039;. Do &#039;&#039;&#039;Copy&#039;&#039;&#039; then &#039;&#039;&#039;Paste&#039;&#039;&#039; and choose to call the new file &#039;&#039;&#039;config.php&#039;&#039;&#039;. Edit this new config.php as normal. You should fine that most of the include file warnings have gone now.&lt;br /&gt;
&lt;br /&gt;
Notice also that there is another marker on each file icon. A little yellow cylinder on most files, but a white-on-brown star on the one you have edited. This is telling you the CVS status of each file. The brown stars are changes you have made but not checked in yet.&lt;br /&gt;
&lt;br /&gt;
===Outline===&lt;br /&gt;
&lt;br /&gt;
Over to the right is the Outline view. This shows a list of functions and classes defined in this file. By default, they are listed in the same order as in the file, but if you click on the &#039;&#039;&#039;az&#039;&#039;&#039; toolbar button, they are sorted into alphabetical order.&lt;br /&gt;
&lt;br /&gt;
Click on the function name &#039;&#039;&#039;add_course_module&#039;&#039;&#039; in the Outline. You will see that the editor scrolls to the definition of that function.&lt;br /&gt;
&lt;br /&gt;
===Code navigation===&lt;br /&gt;
&lt;br /&gt;
In that function, hover the mouse pointer over the function name &#039;&#039;&#039;insert_record&#039;&#039;&#039;. After a while, the documentation for that function will appear in a big tooltip.&lt;br /&gt;
&lt;br /&gt;
Hold down CTRL, move the mouse pointer over the function name &#039;&#039;&#039;insert_record&#039;&#039;&#039;, then click. Eclipse should load &#039;&#039;&#039;dmllib.php&#039;&#039;&#039;, and scroll you to where this function is defined.&lt;br /&gt;
&lt;br /&gt;
In the main Eclipse toolbar, there are forward and back arrows like in a web browser. Click back now to get back to &#039;&#039;&#039;course/lib.php&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===Open resource===&lt;br /&gt;
&lt;br /&gt;
From the &#039;&#039;&#039;Navigate&#039;&#039;&#039; menu, choose &#039;&#039;&#039;Open Resource...&#039;&#039;&#039;. In the dialog that pops up, start typing a filename for instance type &#039;&#039;&#039;moodlel&#039;&#039;&#039;. In the box in the middle of the dialog, you will see it list all the files in the project whose names start that way. At the bottom is a box which lists the different folders that contain a file with that name. This can be a very quick way of opening files with fairly unique names like moodlelib.php, without having to click through the levels of the navigator tree. Of course, it is not so useful for an index.php file! Click OK now to open moodlelib.php. (It would actually work if you just did CTRL + Shift + R, moodlel, Enter.)&lt;br /&gt;
&lt;br /&gt;
===Multi-file search===&lt;br /&gt;
&lt;br /&gt;
Scroll down moodlelib a little bit, and double click on the name of the constant &#039;&#039;&#039;MOODLE_INTERNAL&#039;&#039;&#039; where it is defined, so that the text is selected. Then, from the &#039;&#039;&#039;Search&#039;&#039;&#039; menu, choose &#039;&#039;&#039;Search...&#039;&#039;&#039;. Notice that the &#039;&#039;&#039;Containing text&#039;&#039;&#039; box has already been filled in for you with the text you just selected. Of course you can just type text into this box without selecting it first. Notice that you can do regular expression searches, but leave that turned off for now. In the &#039;&#039;&#039;File name patterns&#039;&#039;&#039; box type &#039;&#039;&#039;*.css, *.html, *.inc, *.js, *.php, *.xml&#039;&#039;&#039;. (This is the most useful general setting for working on moodle. Eclipse will remember this setting, so you only have to enter it once.) Click &#039;&#039;&#039;Search&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The search results will appear in a new view underneath the editor. That view has a toolbar with yellow up and down arrows. Click the down arrow a few times and it will take you to the first few matches in the code, opening the relevant files as necessary.&lt;br /&gt;
&lt;br /&gt;
===Synchronize view===&lt;br /&gt;
&lt;br /&gt;
I think this is my favorite feature. From the &#039;&#039;&#039;Window&#039;&#039;&#039; menu, select &#039;&#039;&#039;Show View -&amp;gt; Other...&#039;&#039;&#039;. In the dialog that pops up, select &#039;&#039;&#039;Team -&amp;gt; Synchronize&#039;&#039;&#039;, then click &#039;&#039;&#039;OK&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This opens the Synchronize view below the editor. The view has a toolbar. Click on the first toolbar button, which pops up the Synchronize wizard.&lt;br /&gt;
&lt;br /&gt;
On the first screen, there will probably only be one option: &#039;&#039;&#039;CVS&#039;&#039;&#039;. Make sure that is selected, then click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;Scope&#039;&#039;&#039;, choose &#039;&#039;&#039;Workspace&#039;&#039;&#039;, then click &#039;&#039;&#039;Finish&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Wait while it talks to the CVS server. After a while, you will see that the Synchronize view lists course/lib.php, and something called &#039;&#039;&#039;.project.... That is, it is listing just the files you have edited, but not checked in yet.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;.project&#039;&#039;&#039; is something that belongs to Eclipse that we don&#039;t care about. So select it and bring up the context menu, and choose &#039;&#039;&#039;Add to .cvsignore...&#039;&#039;&#039;. In the dialog that pops up, choose the top option, then click &#039;&#039;&#039;OK&#039;&#039;&#039;. Then you will find the Synchronize view shows you a &#039;&#039;&#039;.cvsignore&#039;&#039;&#039; file that you aren&#039;t interested in, so add that to .cvsignore too!&lt;br /&gt;
&lt;br /&gt;
If you double-click on &#039;&#039;&#039;course/lib.php&#039;&#039;&#039; here, you will see that it opens the compare editor, which is a nice graphical display of the changes in this file.&lt;br /&gt;
&lt;br /&gt;
If you select a file or files here, then bring up the context menu, you will see the option to &#039;&#039;&#039;Commit...&#039;&#039;&#039; the changes. (But don&#039;t do that now!). This is the easiest way to commit things in Eclipse.&lt;br /&gt;
&lt;br /&gt;
However, our changes were rubbish, so we want to undo them. So open the context menu again, and choose &#039;&#039;&#039;Override and Update&#039;&#039;&#039;. This checks a clean copy of the file out of CVS, removing our changes.&lt;br /&gt;
&lt;br /&gt;
Note that the easiest way to do an ordinary CVS Update is to select the top-level project-folder in the Navigator view on the left, open the context menu, and choose &#039;&#039;&#039;Team -&amp;gt; Update&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
That&#039;s all the really important features. I sure you can learn everything else on your own. An you could always read the built in help!&lt;br /&gt;
&lt;br /&gt;
===Creating a patch===&lt;br /&gt;
&lt;br /&gt;
In the synchronise view, right click on an item (file or folder) and choose &#039;&#039;&#039;Create Patch...&#039;&#039;&#039;. Or in the navigator, right click on an item and choose &#039;&#039;&#039;Team -&amp;gt; Create Patch...&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This brings up a two-page wizard. On the first page you can select where you want the patch made. For small patches it can be useful to create them on the clipboard, but normally you will want to save them in a file.&lt;br /&gt;
&lt;br /&gt;
On the second page, you can set some options, but normally you don&#039;t need to change the defaults which are &#039;&#039;&#039;Unified&#039;&#039;&#039; diff format, and Patch root set to &#039;&#039;&#039;Workspace&#039;&#039;&#039;. Well, sometimes it is helpful to change the second one to &#039;&#039;&#039;Project&#039;&#039;&#039; but it is not important.&lt;br /&gt;
&lt;br /&gt;
There is a corresponding apply patch wizard that you can use to apply a patch to a project.&lt;br /&gt;
&lt;br /&gt;
===Switching to another branch or version===&lt;br /&gt;
&lt;br /&gt;
Suppose you have been using a check-out of HEAD from CVS, and then as the 1.9 release approaches, the MOODLE_19_STABLE branch is created, and you want to start following that instead.&lt;br /&gt;
# Right click on the moodle project in the navigator view, and select &#039;&#039;&#039;Team -&amp;gt; Switch to Another Branch or Version ...&#039;&#039;&#039;.&lt;br /&gt;
# choose the second radio button: &#039;&#039;&#039;Select the tag from the following list&#039;&#039;&#039;.&lt;br /&gt;
# If the branch you want is not in the &#039;&#039;&#039;Matching tags&#039;&#039;&#039; box, see [[Setting_up_Eclipse#Resetting the branch information|Resetting the branch information]] below.&lt;br /&gt;
# Select the branch you want and click &#039;&#039;&#039;Finish&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
Some tips on how to solve common problems that may crop up.&lt;br /&gt;
&lt;br /&gt;
===Resetting the branch information===&lt;br /&gt;
&lt;br /&gt;
Every now and then, Eclipse may lose information on the branch tags it knows about. Hitting refresh tags may fix it, but if not, try the following:&lt;br /&gt;
&lt;br /&gt;
#Bring up the tag dialogue (example using &amp;quot;Team / Switch to Another Branch or Version&amp;quot;).&lt;br /&gt;
#Click on Configure tags ... (not Refresh tags).&lt;br /&gt;
#Select config-dist.php in the top left box (if this is a Moodle checkout).&lt;br /&gt;
#Click Add Checked tags.&lt;br /&gt;
#Click OK.&lt;br /&gt;
#Then you will have all tags.&lt;br /&gt;
&lt;br /&gt;
(thanks to Tim Hunt)&lt;br /&gt;
&lt;br /&gt;
This info saved my day to find all branches:&lt;br /&gt;
   1. Window-&amp;gt;Show View-&amp;gt;Other. Select CVS-&amp;gt;CVS Repositories.&lt;br /&gt;
   2. Context Menu-&amp;gt;New-&amp;gt;Repository Location...&lt;br /&gt;
   3. Fill in the location information identifying your repository and click Finish.&lt;br /&gt;
   4. Expand the newly-created repository location.&lt;br /&gt;
   5. Add the branch:&lt;br /&gt;
         1. right click on it and expand configure branches and versions&lt;br /&gt;
         2. Expand HEAD and select the project moodle.&lt;br /&gt;
         3. Context Menu-&amp;gt;Configure Branches and Versions...&lt;br /&gt;
         4. In the &amp;quot;Browse files for tags&amp;quot; table, select one or more files &lt;br /&gt;
            that contain tags you would like to see (for example scroll down &lt;br /&gt;
            to find config.php).&lt;br /&gt;
         5. On the right the existing tags will appear.&lt;br /&gt;
         6. select the tags: for example MOODLE_15_STABLE&lt;br /&gt;
         7. Click &amp;quot;Add Selected Tags&amp;quot;.&lt;br /&gt;
         8. Click &amp;quot;OK&amp;quot;.&lt;br /&gt;
   6. locate branches, MOODLE_19_STABLE, moodle MOODLE_19_STABLE.&lt;br /&gt;
   7. Context Menu-&amp;gt;Check Out As Project.&lt;br /&gt;
(&amp;quot;stolen&amp;quot; from  Joan Codina Filba	&lt;br /&gt;
General developer forum -&amp;gt; Moodle floating &amp;quot;block&amp;quot;/toolbar released -&amp;gt; Re: Moodle floating &amp;quot;block--PATCH FOR GRADES &amp;amp; ASIGNMENT --PROBLEM)&lt;br /&gt;
&lt;br /&gt;
===Error loading php files after Ubuntu 7.04 Install===&lt;br /&gt;
&lt;br /&gt;
A java issue with Ubuntu 7.04 may cause an error when you attempt to load php pages. Refer to:&lt;br /&gt;
http://www.plog4u.org/index.php/Using_PHPEclipse_:_Installation_:_Installing_PHPEclipse for details about how to fix this in Ubuntu 7.04.&lt;br /&gt;
&lt;br /&gt;
After upgrading from Ubuntu 7.04 to 7.10, I had to go in and re-edit the /etc/eclipse/java_home file in order to get the CVS functions to work and be able to open PHP files. When I tried to do a CVS update I initially received an error about org.eclipse.team.internal.ccvs.ui.wizards.CheckoutWizard). Everything seemed to work again after reapplying the fix for the aforementioned 7.04 java issue.&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
&lt;br /&gt;
There is an excellent series of articles published by IBM on using Eclipse for Drupal developement here : [http://www-128.ibm.com/developerworks/ibm/osource/index.html Using open source software to design, develop, and deploy a collaborative Web site Tools and techniques for getting relatively complicated Web sites up and running quickly].&lt;br /&gt;
&lt;br /&gt;
[[Category:Setting up Eclipse]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Setting_up_Eclipse&amp;diff=4968</id>
		<title>Setting up Eclipse</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Setting_up_Eclipse&amp;diff=4968"/>
		<updated>2008-06-25T07:10:39Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: /* General settings */ ignore whitespace in patches&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.eclipse.org/ Eclipse] is an IDE originally designed for Java, but now with plugins for many languages including PHP. It has lots of very powerful features, and it is the editor that some Moodle developers like to use. Other (more) popular choices are vim and emacs.&lt;br /&gt;
&lt;br /&gt;
However, Eclipse is not the easiest program in the world to get started with, so I&#039;m going to take you through it step by step. These instructions assume Eclipse 3.2, the current version at the time of writing. It should not change much between releases.&lt;br /&gt;
&lt;br /&gt;
This article started off as a brain-dump by [[User:Tim Hunt|Tim Hunt]]. Since then, several other people have worked through it and made corrections, so the information here should be pretty accurate.&lt;br /&gt;
&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
&lt;br /&gt;
Eclipse is written in Java, so I recommend getting the latest Java runtime environment from http://java.com/ for maximum speed and reliability.&lt;br /&gt;
&lt;br /&gt;
Eclipse is quite big, so I recommend lots of memory in your computer. I have used it on Windows, MacOS X and Linux, in each case with 1GB of memory, and that is plenty.&lt;br /&gt;
&lt;br /&gt;
==Installing Eclipse==&lt;br /&gt;
&lt;br /&gt;
Go to http://www.eclipse.org/downloads/. Click on the link corresponding to your operating system where it says &#039;&#039;&#039;Eclipse Classic&#039;&#039;&#039;. Choose a Mirror, and wait for the ~100MB download.&lt;br /&gt;
&lt;br /&gt;
You will notice that what you have got is a zip file (unless your system automatically decompresses it for you).&lt;br /&gt;
&lt;br /&gt;
On Windows, unzip it into &#039;&#039;&#039;C:\Program Files&#039;&#039;&#039; (all the files go into an &#039;&#039;&#039;Eclipse&#039;&#039;&#039; folder there). Then look in the Eclipse folder and drag Eclipse.exe to the Start menu/Desktop/Quicklaunch bar to make a shortcut for starting it.&lt;br /&gt;
&lt;br /&gt;
On MacOS, unzip and copy the Eclipse folder into Applications. Go into the Eclipse folder and drag the Eclipse app to the Dock for ease of launching.&lt;br /&gt;
&lt;br /&gt;
On Linux, unzip somewhere suitable, and make an easy way to launch it.&lt;br /&gt;
&lt;br /&gt;
==The first time you run Eclipse==&lt;br /&gt;
&lt;br /&gt;
The first time you launch Eclipse it does a bit of setup stuff, for instance, it create a &#039;&#039;&#039;workspace&#039;&#039;&#039;. This is where it stores the things you are working on. The default location is sensible on all platforms, so use that. &lt;br /&gt;
&lt;br /&gt;
For some reason, every time you start Eclipse, it asks you which workspace you want to use. I have never seen the need to have more than one, so I recommend turning on the checkbox that says &amp;quot;Use this as the default and do not ask again&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Another thing that happens the first time you run Eclipse is that you arrive at a welcome screen. This has links to various bits of help, which you can read if you like, but you probably don&#039;t need to if you are following these instructions. So find the button on the welcome page that closes it and gets you to the main Eclipse screen.&lt;br /&gt;
&lt;br /&gt;
==Installing the necessary plugins==&lt;br /&gt;
&lt;br /&gt;
By default, Eclipse comes with the Java tools. For everything else you will need to install some plugins.&lt;br /&gt;
&lt;br /&gt;
If you are sitting behind a web proxy, from the &#039;&#039;&#039;Window&#039;&#039;&#039; menu choose &#039;&#039;&#039;Preferences ...&#039;&#039;&#039;. Choose &#039;&#039;&#039;Install/Update&#039;&#039;&#039; from the tree view on the left, and enter the proxy information in the boxes on the right. If you aren&#039;t behind a proxy, ignore this step.&lt;br /&gt;
&lt;br /&gt;
From the &#039;&#039;&#039;Help&#039;&#039;&#039; menu choose &#039;&#039;&#039;Software Updates -&amp;gt; Find and Install&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
On the first screen of the wizard, make sure that &amp;quot;Search for new features to install&amp;quot; is selected, then click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The next screen is a list of upgrade sites to check. You need to add one to the list, so click the &#039;&#039;&#039;New Remote Site ...&#039;&#039;&#039; Button.&lt;br /&gt;
&lt;br /&gt;
In the pop-up dialog, give the remote site a name like &#039;&#039;&#039;PHPeclipse Update Site&#039;&#039;&#039;; set the URL to http://phpeclipse.sourceforge.net/update/releases/; then click &#039;&#039;&#039;OK&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note, there is now also another PHP editor for Eclipse. The update URL ishttp://download.eclipse.org/tools/pdt/updates/. I am just trying it--[[User:Tim Hunt|Tim Hunt]] 11:39, 7 November 2007 (CST)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Back in the wizard, turn on just two things in the box &amp;quot;Sites to include in search&amp;quot;:&lt;br /&gt;
* Your newly created &#039;&#039;&#039;Phpeclipse Update Site&#039;&#039;&#039;; and&lt;br /&gt;
* the one called &#039;&#039;&#039;Europa Discovery Site&#039;&#039;&#039; (or possibly &#039;&#039;&#039;Callisto Discovery Site&#039;&#039;&#039;.&lt;br /&gt;
Then click &#039;&#039;&#039;Finish&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
It goes off sees what updates are available at those sites. As it does so, it may occasionally pop up a dialog asking you to choose a mirror. Each time, select a sensible one.&lt;br /&gt;
&lt;br /&gt;
Eventually, you get to a new wizard for selecting and installing the updates you want. The ones you want (you may have to search the tree structure) are, &#039;&#039;&#039;PHPeclipse&#039;&#039;&#039; (from your newly created PHPEclipse Update Site) and all the &#039;&#039;&#039;Web Standard Tools (WST)&#039;&#039;&#039; (usually under Callisto Discovery Site --&amp;gt; Web and J2EE Development).&lt;br /&gt;
&lt;br /&gt;
Next, and very importantly, you must click the &#039;&#039;&#039;Select Required&#039;&#039;&#039; button which should resolve dependencies and remove the warning message you are probably worrying about. Then you can click the &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
Read and agree to all the license agreements. Then click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Finish&#039;&#039;&#039;, and wait for the plugins to download.&lt;br /&gt;
&lt;br /&gt;
Once the downloads have finished, a warning will pop-up telling you that all the plugins you downloaded are not digitally signed. The Eclipse Foundation build digital signing of plugins into their architecture as a security measure, and then did not sign any of their own plugins! Anyway, click the &#039;&#039;&#039;Install All&#039;&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
Finally, a window will pop up asking you to restart Eclipse. Do so.&lt;br /&gt;
&lt;br /&gt;
==Setting the preferences for Moodle development==&lt;br /&gt;
&lt;br /&gt;
Now go to the &#039;&#039;&#039;Window&#039;&#039;&#039; menu, and choose &#039;&#039;&#039;Preferences ...&#039;&#039;&#039; (&#039;&#039;&#039;Eclipse&#039;&#039;&#039; menu on Mac OS X).&lt;br /&gt;
&lt;br /&gt;
The Eclipse preferences are immense, with a tree view on the left, which selects which screen to display on the right. Don&#039;t panic, we&#039;ll guide you through it.&lt;br /&gt;
&lt;br /&gt;
===General settings===&lt;br /&gt;
&lt;br /&gt;
If you have strong feelings about fonts (I would hate to edit code an anything except Andale Mono), choose &#039;&#039;&#039;General -&amp;gt; Appearance -&amp;gt; Colors and Fonts&#039;&#039;&#039; from the tree on the left. Then on the right look under &#039;&#039;&#039;Basic&#039;&#039;&#039; and change &#039;&#039;&#039;Text Font&#039;&#039;&#039;. All the other editor font settings will inherit from this, so this is probably the only one you have to change.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;General -&amp;gt; Compare/Patch&#039;&#039;&#039;, turn on &#039;&#039;&#039;Ignore white space&#039;&#039;&#039; if you plan to exchange patches with other developers or send patches on the tracker. This will make patches smaller and easier to compare.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;General -&amp;gt; Content Types&#039;&#039;&#039;, select PHP Source File, and add &#039;&#039;&#039;*.html&#039;&#039;&#039; to the box at the bottom.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;General -&amp;gt; Editors -&amp;gt; File Associations&#039;&#039;&#039;, if it is not already there, add &#039;&#039;&#039;*.php&#039;&#039;&#039; to the top box. With &#039;&#039;&#039;*.php&#039;&#039;&#039; selected in the top box, make sure &#039;&#039;&#039;PHP Editor&#039;&#039;&#039; is set to default in the bottom box. With &#039;&#039;&#039;*.html&#039;&#039;&#039; selected in the top box, select &#039;&#039;&#039;PHP Editor&#039;&#039;&#039; in the bottom box and click the &#039;&#039;&#039;Default&#039;&#039;&#039; button to change it, because in Moodle, most HTML files actually contain PHP code.&lt;br /&gt;
&lt;br /&gt;
If you use a web proxy, enter the details under &#039;&#039;&#039;Internet -&amp;gt; Proxy Settings&#039;&#039;&#039;. (Yes, I know you have entered them somewhere else before. Now you have to enter them again here. I don&#039;t know why. You just do.)&lt;br /&gt;
&lt;br /&gt;
===PHP Settings===&lt;br /&gt;
&lt;br /&gt;
These are all hidden under the &#039;&#039;&#039;PHPeclipse Web Development&#039;&#039;&#039; bit of the tree.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;PHPeclipse Web Development -&amp;gt; Browser Preview Defaults&#039;&#039;&#039;, turn off both checkboxes.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;PHPeclipse Web Development -&amp;gt; PHP&#039;&#039;&#039;, on the &#039;&#039;&#039;Appearance&#039;&#039;&#039; tab, set &#039;&#039;&#039;Displayed tab width&#039;&#039;&#039; to 4.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;PHPeclipse Web Development -&amp;gt; PHP&#039;&#039;&#039;, on the &#039;&#039;&#039;Appearance&#039;&#039;&#039; tab, check &#039;&#039;&#039;Show line numbers&#039;&#039;&#039; to display line numbers in the left margin (optional). NOTE.- When you are editing a PHP file, you could left-click in the left margin and tick the &#039;&#039;&#039;Show Line Numbers&#039;&#039;&#039; line in the contextual menu. However, this toggle only applies to plain text files, &#039;&#039;not&#039;&#039; to HTML or PHP files. The only place where you can toggle line numbers on/off for such files is in the PHP/Appearance menu.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;PHPeclipse Web Development -&amp;gt; PHP&#039;&#039;&#039;, on the &#039;&#039;&#039;Typing&#039;&#039;&#039; tab, turn off all the options except &#039;&#039;&#039;Pasting for correct indentation&#039;&#039;&#039;, &#039;&#039;&#039;Insert spaces for tab&#039;&#039;&#039; and &#039;&#039;&#039;Close PHPdocs and comments&#039;&#039;&#039; and &#039;&#039;&#039;Remove trailing spaces on editor save&#039;&#039;&#039;. It would be nice to turn on more of these options, but most of the rest don&#039;t work very well.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;PHPeclipse Web Development -&amp;gt; PHP -&amp;gt; Formatter&#039;&#039;&#039;, on the &#039;&#039;&#039;New Lines&#039;&#039;&#039; tab, turn on &#039;&#039;&#039;Clear all blank lines&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;PHPeclipse Web Development -&amp;gt; PHP -&amp;gt; Formatter&#039;&#039;&#039;, on the &#039;&#039;&#039;Style&#039;&#039;&#039; tab, turn off &#039;&#039;&#039;Indentation is represented by a tab&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;PHPeclipse Web Development -&amp;gt; PHP -&amp;gt; Templates&#039;&#039;&#039;, I like to define a new template to help with debugging:&lt;br /&gt;
;Name&lt;br /&gt;
:dump &lt;br /&gt;
;Description&lt;br /&gt;
:Dump a PHP variable&lt;br /&gt;
;Pattern&lt;br /&gt;
&amp;lt;pre&amp;gt;print_object(${word_selection}${cursor}); // DONOTCOMMIT&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can do other useful things with templates too. Here are two more I use:&lt;br /&gt;
&amp;lt;pre&amp;gt;debugging(&amp;quot;&#039;${word_selection}${cursor}&#039;&amp;quot;); // DONOTCOMMIT&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;$$string[&#039;${word_selection}${cursor}&#039;] = &#039;.&#039;;&amp;lt;/pre&amp;gt;&lt;br /&gt;
That is, a simple debug message with a stack trace, and a new language string.&lt;br /&gt;
&lt;br /&gt;
There is a really stupid bug. Under &#039;&#039;&#039;PHPeclipse Web Development -&amp;gt; Project Defaults&#039;&#039;&#039;, you would like to add &amp;quot;.&amp;quot; to the &#039;&#039;&#039;Include Paths&#039;&#039;&#039;, but you can&#039;t using the GUI. You will have to edit one of the Eclipse config files by hand. So&lt;br /&gt;
# Note down the path to your Eclipse profile. On Windows it will be something like &#039;&#039;&#039;C:/Documents and settings/XXXX/workspace&#039;&#039;&#039;, and on Unixy systems something like &#039;&#039;&#039;~/workspace&#039;&#039;&#039;.&lt;br /&gt;
# Close Eclipse. &lt;br /&gt;
# Open the file &#039;&#039;&#039;net.sourceforge.phpeclipse.ui.prefs&#039;&#039;&#039; that is in the directory &#039;&#039;&#039;(your workspace)/.metadata/.plugins/org.eclipse.core.runtime/.settings&#039;&#039;&#039; in a text editor.&lt;br /&gt;
# Look for a line in the file that starts &#039;&#039;&#039;_php_include_paths=&#039;&#039;&#039; If it is not there, add it at the end.&lt;br /&gt;
# Change this line to say &#039;&#039;&#039;_php_include_paths=.&#039;&#039;&#039;&lt;br /&gt;
# Run Eclipse again.&lt;br /&gt;
&lt;br /&gt;
===SSH2===&lt;br /&gt;
Information about generating SSH2 keys for the purpose of connecting to cvs.moodle.org can be found here at https://docs.moodle.org/en/Development:SSH_key , but please finish reading this section before reading that material.&lt;br /&gt;
&lt;br /&gt;
The Eclipse installation has its own SSH client plugin so you do not have to use a separate ssh client in connection with your use of Eclipse (this is one reason you will be using extssh below,  instead of just ext,  however,  if you wish you may alter the configuration to use an external client but please post news of your success and configuration). See, http://www.jcraft.com/eclipse-cvsssh2/ , for additional information on this plugin.  &lt;br /&gt;
&lt;br /&gt;
&#039;&#039; Since Eclipse 3.0M6 the CVSSSH plugin is incorporated into Eclipse, [http://www.jroller.com/prane/entry/eclipse_3_0_cvs_support as &amp;quot;extssh&amp;quot; instead of &amp;quot;extssh2&amp;quot;] - --[[User:Olli Savolainen|Olli Savolainen]] 07:54, 23  June 2008 (CDT)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Please note that Eclipse is fully equipped to generate ssh2 rsa and dsa keys as well as import keys.  You may encounter issues with passphrases that are too long (a bug reportedly fixed but which may still in fact be present) and some issues with using keypairs generated by other applications have been seen, so it may be best to generate a key pair with Eclipse. Additional details on how to do this will be added.&lt;br /&gt;
&lt;br /&gt;
Sourceforge, at http://sourceforge.net/docs/F02/ , provides instructions on how to create a SSH key for it&#039;s CVS (remember,  Moodle does not use sourceforge for its CVS now and you will need to generate keys for cvs.moodle.org, not sourceforge). This is mentioned by way of general explanation, not for the purposes of providing instructions on how to generate your keys for Eclipse. To make use of the public key, login to Moodle.org and add it via the Update My Developer Information tab under CVS Developers (http://moodle.org/cvs). Remember,  public keys provided to Moodle must be in the Openssh format.&lt;br /&gt;
&lt;br /&gt;
===CVS Settings===&lt;br /&gt;
&lt;br /&gt;
These are almost all hidden under the &#039;&#039;&#039;Team&#039;&#039;&#039; bit of the tree.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;General -&amp;gt; Network Connections -&amp;gt; SSH2 -&amp;gt; Key Management&#039;&#039;&#039;, you can set up a public/private key pair. If you do this, you won&#039;t have to keep typing your password when doing CVS operations. &lt;br /&gt;
&lt;br /&gt;
The rest of the ones in this section are personal preferences, but I recommend them because the default settings are very irritating.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;Team&#039;&#039;&#039;, set &#039;&#039;&#039;Perspectives&#039;&#039;&#039; to &#039;&#039;&#039;None&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;Team -&amp;gt; CVS -&amp;gt; Annotate&#039;&#039;&#039; set &#039;&#039;&#039;Use Quick Diff annotate mode for local file annotations&#039;&#039;&#039; to &#039;&#039;&#039;Yes&#039;&#039;&#039;, and &#039;&#039;&#039;Open perspective after a &#039;Show Annotations&#039; operation&#039;&#039;&#039; to &#039;&#039;&#039;No&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;Team -&amp;gt; CVS -&amp;gt; Label Decorations&#039;&#039;&#039;, switch to the &#039;&#039;&#039;Icon Decorations&#039;&#039;&#039; tab and turn on all the settings, and then on the &#039;&#039;&#039;Text Decorations&#039;&#039;&#039; tab change both &#039;&#039;&#039;File Decoration&#039;&#039;&#039; and &#039;&#039;&#039;Folder Decoration&#039;&#039;&#039; to be just &#039;&#039;&#039;{name}&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===Web and XML settings===&lt;br /&gt;
&lt;br /&gt;
Foreach XXX in CSS, HTML, Javascript, XML:&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;Web and XML -&amp;gt; XXX Files -&amp;gt;XXX Source&#039;&#039;&#039;, choose &#039;&#039;&#039;Indent using spaces&#039;&#039;&#039; and &#039;&#039;&#039;indentation size&#039;&#039;&#039; 4.&lt;br /&gt;
&lt;br /&gt;
==Checking out the Moodle code==&lt;br /&gt;
&lt;br /&gt;
From the &#039;&#039;&#039;File&#039;&#039;&#039; menu, choose &#039;&#039;&#039;New -&amp;gt; Project ...&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In the wizard that pops up, choose &#039;&#039;&#039;CVS -&amp;gt; Projects from CVS&#039;&#039;&#039;, then click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Select &#039;&#039;&#039;Create a new repository location&#039;&#039;&#039;, then click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Fill in&lt;br /&gt;
&amp;lt;div style=&amp;quot;float: right; border: 1px solid orange; padding: 0 1em;&amp;quot;&amp;gt;&lt;br /&gt;
For anonymous CVS access use&lt;br /&gt;
;Host&lt;br /&gt;
:XX.cvs.moodle.org&lt;br /&gt;
where XX.cvs.moodle.org is one of [[CVS_for_Administrators#CVS_Servers|these mirrors]]&lt;br /&gt;
;Repository path&lt;br /&gt;
:/cvsroot/moodle&lt;br /&gt;
;User&lt;br /&gt;
:anonymous&lt;br /&gt;
;Password&lt;br /&gt;
:(leave blank)&lt;br /&gt;
;Connection type&lt;br /&gt;
:pserver&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
;Host&lt;br /&gt;
:cvs.moodle.org&lt;br /&gt;
;Repository path&lt;br /&gt;
:/cvsroot/moodle&lt;br /&gt;
;User&lt;br /&gt;
:(your Moodle CVS username)&lt;br /&gt;
;Password&lt;br /&gt;
:(if you set up the SSH2 key thing in preferences, leave this blank, otherwise, type in your Moodle CVS password.)&lt;br /&gt;
;Connection type&lt;br /&gt;
:extssh&lt;br /&gt;
(CVS experts, if you are confused by that last one, know it is an Eclipse-specific thing.) Then click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
On the next screen of the Wizard, choose &#039;&#039;&#039;Use an existing module&#039;&#039;&#039;. Wait a moment, then select &#039;&#039;&#039;moodle&#039;&#039;&#039; from the list. Click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
On the next screen, make sure the option &#039;&#039;&#039;Check out as a project configured using the New Project Wizard&#039;&#039;&#039; is selected, then click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Refresh Tags&#039;&#039;&#039;, then choose the branch you want. For now leave it set to &#039;&#039;&#039;HEAD&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Finish&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now you  will find yourself back at the start of the &#039;&#039;&#039;New Project&#039;&#039;&#039; Wizard. This is because of the option you chose three paragraphs ago. This time you should select &#039;&#039;&#039;PHP -&amp;gt; PHP Project&#039;&#039;&#039;, then click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Make up a project name. &#039;&#039;&#039;moodle&#039;&#039;&#039; would be sensible.&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Finish&#039;&#039;&#039;, and wait while all the moodle files are checked out of CVS.&lt;br /&gt;
&lt;br /&gt;
Once it has finished, it will probably ask you if you want to switch to the PHP perspective. Answer &#039;&#039;&#039;Yes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you also need another branch (1.6, 1.7, 1.8, ...) repeat all the other steps with a few changes:&lt;br /&gt;
* This time you can choose &#039;&#039;&#039;Use an existing repository location&#039;&#039;&#039; instead of typing all the sourceforge CVS details again.&lt;br /&gt;
* Select the appropriate branch. If you don&#039;t see the branch you want, see [https://docs.moodle.org/en/Development:Setting_up_Eclipse#Resetting_the_branch_information this Troubleshooting tip].&lt;br /&gt;
* Use a different project name (e.g. moodle16, moodle17, etc.).&lt;br /&gt;
&lt;br /&gt;
==Let your development web server know where your files are==&lt;br /&gt;
&lt;br /&gt;
Either by editing you web server&#039;s config files, or using a symbolic link. Make sure your webserver can see your new working set of files at a sensible URL, so you can test the code you are working on.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Quick tour of some cool features, and remaining configuration changes==&lt;br /&gt;
&lt;br /&gt;
I find the default workbench setup is pretty good. Here is a quick guide to some of the bits.&lt;br /&gt;
&lt;br /&gt;
===Navigator===&lt;br /&gt;
&lt;br /&gt;
To the left is the &#039;&#039;&#039;Navigator&#039;&#039;&#039;. This is a tree view of all your files. If you double-click on a file, it opens in the editor in the middle. Try opening &#039;&#039;&#039;course/lib.php&#039;&#039;&#039; now. You will notice that it comes up nicely syntax-hightlighted.&lt;br /&gt;
&lt;br /&gt;
===Error highlighting===&lt;br /&gt;
&lt;br /&gt;
In the middle of the file, just type any old text, for example &amp;quot;I like Eclipse&amp;quot;. Obviously, this is not valid PHP syntax, and Eclipse will notice this, and put a red underline under it. Also, by the scrollbar is a ruler with a red mark in it to show the error.&lt;br /&gt;
&lt;br /&gt;
You will see some yellow marks lower down the ruler. There are warnings. Click on one, and you will be taken to where that warning is in the file. Hover your mouse over the warning, and you will get a tooltip explaining what the problem might be.&lt;br /&gt;
&lt;br /&gt;
Save the edited file. (Don&#039;t worry that it is broken, we&#039;ll clean up the mess later.) Notice that a red error marker is added to the file in the navigator, so you can see that there is a problem. Also, error markers are added to the course folder, and the whole project, so you could see there was an error even if the navigator tree was collapsed.&lt;br /&gt;
&lt;br /&gt;
You will probably find lots of warnings that the config.php file can&#039;t be found. In the navigator, find the file &#039;&#039;&#039;config-dist.php&#039;&#039;&#039;. Do &#039;&#039;&#039;Copy&#039;&#039;&#039; then &#039;&#039;&#039;Paste&#039;&#039;&#039; and choose to call the new file &#039;&#039;&#039;config.php&#039;&#039;&#039;. Edit this new config.php as normal. You should fine that most of the include file warnings have gone now.&lt;br /&gt;
&lt;br /&gt;
Notice also that there is another marker on each file icon. A little yellow cylinder on most files, but a white-on-brown star on the one you have edited. This is telling you the CVS status of each file. The brown stars are changes you have made but not checked in yet.&lt;br /&gt;
&lt;br /&gt;
===Outline===&lt;br /&gt;
&lt;br /&gt;
Over to the right is the Outline view. This shows a list of functions and classes defined in this file. By default, they are listed in the same order as in the file, but if you click on the &#039;&#039;&#039;az&#039;&#039;&#039; toolbar button, they are sorted into alphabetical order.&lt;br /&gt;
&lt;br /&gt;
Click on the function name &#039;&#039;&#039;add_course_module&#039;&#039;&#039; in the Outline. You will see that the editor scrolls to the definition of that function.&lt;br /&gt;
&lt;br /&gt;
===Code navigation===&lt;br /&gt;
&lt;br /&gt;
In that function, hover the mouse pointer over the function name &#039;&#039;&#039;insert_record&#039;&#039;&#039;. After a while, the documentation for that function will appear in a big tooltip.&lt;br /&gt;
&lt;br /&gt;
Hold down CTRL, move the mouse pointer over the function name &#039;&#039;&#039;insert_record&#039;&#039;&#039;, then click. Eclipse should load &#039;&#039;&#039;dmllib.php&#039;&#039;&#039;, and scroll you to where this function is defined.&lt;br /&gt;
&lt;br /&gt;
In the main Eclipse toolbar, there are forward and back arrows like in a web browser. Click back now to get back to &#039;&#039;&#039;course/lib.php&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===Open resource===&lt;br /&gt;
&lt;br /&gt;
From the &#039;&#039;&#039;Navigate&#039;&#039;&#039; menu, choose &#039;&#039;&#039;Open Resource...&#039;&#039;&#039;. In the dialog that pops up, start typing a filename for instance type &#039;&#039;&#039;moodlel&#039;&#039;&#039;. In the box in the middle of the dialog, you will see it list all the files in the project whose names start that way. At the bottom is a box which lists the different folders that contain a file with that name. This can be a very quick way of opening files with fairly unique names like moodlelib.php, without having to click through the levels of the navigator tree. Of course, it is not so useful for an index.php file! Click OK now to open moodlelib.php. (It would actually work if you just did CTRL + Shift + R, moodlel, Enter.)&lt;br /&gt;
&lt;br /&gt;
===Multi-file search===&lt;br /&gt;
&lt;br /&gt;
Scroll down moodlelib a little bit, and double click on the name of the constant &#039;&#039;&#039;MOODLE_INTERNAL&#039;&#039;&#039; where it is defined, so that the text is selected. Then, from the &#039;&#039;&#039;Search&#039;&#039;&#039; menu, choose &#039;&#039;&#039;Search...&#039;&#039;&#039;. Notice that the &#039;&#039;&#039;Containing text&#039;&#039;&#039; box has already been filled in for you with the text you just selected. Of course you can just type text into this box without selecting it first. Notice that you can do regular expression searches, but leave that turned off for now. In the &#039;&#039;&#039;File name patterns&#039;&#039;&#039; box type &#039;&#039;&#039;*.css, *.html, *.inc, *.js, *.php, *.xml&#039;&#039;&#039;. (This is the most useful general setting for working on moodle. Eclipse will remember this setting, so you only have to enter it once.) Click &#039;&#039;&#039;Search&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The search results will appear in a new view underneath the editor. That view has a toolbar with yellow up and down arrows. Click the down arrow a few times and it will take you to the first few matches in the code, opening the relevant files as necessary.&lt;br /&gt;
&lt;br /&gt;
===Synchronize view===&lt;br /&gt;
&lt;br /&gt;
I think this is my favorite feature. From the &#039;&#039;&#039;Window&#039;&#039;&#039; menu, select &#039;&#039;&#039;Show View -&amp;gt; Other...&#039;&#039;&#039;. In the dialog that pops up, select &#039;&#039;&#039;Team -&amp;gt; Synchronize&#039;&#039;&#039;, then click &#039;&#039;&#039;OK&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This opens the Synchronize view below the editor. The view has a toolbar. Click on the first toolbar button, which pops up the Synchronize wizard.&lt;br /&gt;
&lt;br /&gt;
On the first screen, there will probably only be one option: &#039;&#039;&#039;CVS&#039;&#039;&#039;. Make sure that is selected, then click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;Scope&#039;&#039;&#039;, choose &#039;&#039;&#039;Workspace&#039;&#039;&#039;, then click &#039;&#039;&#039;Finish&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Wait while it talks to the CVS server. After a while, you will see that the Synchronize view lists course/lib.php, and something called &#039;&#039;&#039;.project.... That is, it is listing just the files you have edited, but not checked in yet.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;.project&#039;&#039;&#039; is something that belongs to Eclipse that we don&#039;t care about. So select it and bring up the context menu, and choose &#039;&#039;&#039;Add to .cvsignore...&#039;&#039;&#039;. In the dialog that pops up, choose the top option, then click &#039;&#039;&#039;OK&#039;&#039;&#039;. Then you will find the Synchronize view shows you a &#039;&#039;&#039;.cvsignore&#039;&#039;&#039; file that you aren&#039;t interested in, so add that to .cvsignore too!&lt;br /&gt;
&lt;br /&gt;
If you double-click on &#039;&#039;&#039;course/lib.php&#039;&#039;&#039; here, you will see that it opens the compare editor, which is a nice graphical display of the changes in this file.&lt;br /&gt;
&lt;br /&gt;
If you select a file or files here, then bring up the context menu, you will see the option to &#039;&#039;&#039;Commit...&#039;&#039;&#039; the changes. (But don&#039;t do that now!). This is the easiest way to commit things in Eclipse.&lt;br /&gt;
&lt;br /&gt;
However, our changes were rubbish, so we want to undo them. So open the context menu again, and choose &#039;&#039;&#039;Override and Update&#039;&#039;&#039;. This checks a clean copy of the file out of CVS, removing our changes.&lt;br /&gt;
&lt;br /&gt;
Note that the easiest way to do an ordinary CVS Update is to select the top-level project-folder in the Navigator view on the left, open the context menu, and choose &#039;&#039;&#039;Team -&amp;gt; Update&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
That&#039;s all the really important features. I sure you can learn everything else on your own. An you could always read the built in help!&lt;br /&gt;
&lt;br /&gt;
===Creating a patch===&lt;br /&gt;
&lt;br /&gt;
In the synchronise view, right click on an item (file or folder) and choose &#039;&#039;&#039;Create Patch...&#039;&#039;&#039;. Or in the navigator, right click on an item and choose &#039;&#039;&#039;Team -&amp;gt; Create Patch...&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This brings up a two-page wizard. On the first page you can select where you want the patch made. For small patches it can be useful to create them on the clipboard, but normally you will want to save them in a file.&lt;br /&gt;
&lt;br /&gt;
On the second page, you can set some options, but normally you don&#039;t need to change the defaults which are &#039;&#039;&#039;Unified&#039;&#039;&#039; diff format, and Patch root set to &#039;&#039;&#039;Workspace&#039;&#039;&#039;. Well, sometimes it is helpful to change the second one to &#039;&#039;&#039;Project&#039;&#039;&#039; but it is not important.&lt;br /&gt;
&lt;br /&gt;
There is a corresponding apply patch wizard that you can use to apply a patch to a project.&lt;br /&gt;
&lt;br /&gt;
===Switching to another branch or version===&lt;br /&gt;
&lt;br /&gt;
Suppose you have been using a check-out of HEAD from CVS, and then as the 1.9 release approaches, the MOODLE_19_STABLE branch is created, and you want to start following that instead.&lt;br /&gt;
# Right click on the moodle project in the navigator view, and select &#039;&#039;&#039;Team -&amp;gt; Switch to Another Branch or Version ...&#039;&#039;&#039;.&lt;br /&gt;
# choose the second radio button: &#039;&#039;&#039;Select the tag from the following list&#039;&#039;&#039;.&lt;br /&gt;
# If the branch you want is not in the &#039;&#039;&#039;Matching tags&#039;&#039;&#039; box, see [[Setting_up_Eclipse#Resetting the branch information|Resetting the branch information]] below.&lt;br /&gt;
# Select the branch you want and click &#039;&#039;&#039;Finish&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
Some tips on how to solve common problems that may crop up.&lt;br /&gt;
&lt;br /&gt;
===Resetting the branch information===&lt;br /&gt;
&lt;br /&gt;
Every now and then, Eclipse may lose information on the branch tags it knows about. Hitting refresh tags may fix it, but if not, try the following:&lt;br /&gt;
&lt;br /&gt;
#Bring up the tag dialogue (example using &amp;quot;Team / Switch to Another Branch or Version&amp;quot;).&lt;br /&gt;
#Click on Configure tags ... (not Refresh tags).&lt;br /&gt;
#Select config-dist.php in the top left box (if this is a Moodle checkout).&lt;br /&gt;
#Click Add Checked tags.&lt;br /&gt;
#Click OK.&lt;br /&gt;
#Then you will have all tags.&lt;br /&gt;
&lt;br /&gt;
(thanks to Tim Hunt)&lt;br /&gt;
&lt;br /&gt;
This info saved my day to find all branches:&lt;br /&gt;
   1. Window-&amp;gt;Show View-&amp;gt;Other. Select CVS-&amp;gt;CVS Repositories.&lt;br /&gt;
   2. Context Menu-&amp;gt;New-&amp;gt;Repository Location...&lt;br /&gt;
   3. Fill in the location information identifying your repository and click Finish.&lt;br /&gt;
   4. Expand the newly-created repository location.&lt;br /&gt;
   5. Add the branch:&lt;br /&gt;
         1. right click on it and expand configure branches and versions&lt;br /&gt;
         2. Expand HEAD and select the project moodle.&lt;br /&gt;
         3. Context Menu-&amp;gt;Configure Branches and Versions...&lt;br /&gt;
         4. In the &amp;quot;Browse files for tags&amp;quot; table, select one or more files &lt;br /&gt;
            that contain tags you would like to see (for example scroll down &lt;br /&gt;
            to find config.php).&lt;br /&gt;
         5. On the right the existing tags will appear.&lt;br /&gt;
         6. select the tags: for example MOODLE_15_STABLE&lt;br /&gt;
         7. Click &amp;quot;Add Selected Tags&amp;quot;.&lt;br /&gt;
         8. Click &amp;quot;OK&amp;quot;.&lt;br /&gt;
   6. locate branches, MOODLE_19_STABLE, moodle MOODLE_19_STABLE.&lt;br /&gt;
   7. Context Menu-&amp;gt;Check Out As Project.&lt;br /&gt;
(&amp;quot;stolen&amp;quot; from  Joan Codina Filba	&lt;br /&gt;
General developer forum -&amp;gt; Moodle floating &amp;quot;block&amp;quot;/toolbar released -&amp;gt; Re: Moodle floating &amp;quot;block--PATCH FOR GRADES &amp;amp; ASIGNMENT --PROBLEM)&lt;br /&gt;
&lt;br /&gt;
===Error loading php files after Ubuntu 7.04 Install===&lt;br /&gt;
&lt;br /&gt;
A java issue with Ubuntu 7.04 may cause an error when you attempt to load php pages. Refer to:&lt;br /&gt;
http://www.plog4u.org/index.php/Using_PHPEclipse_:_Installation_:_Installing_PHPEclipse for details about how to fix this in Ubuntu 7.04.&lt;br /&gt;
&lt;br /&gt;
After upgrading from Ubuntu 7.04 to 7.10, I had to go in and re-edit the /etc/eclipse/java_home file in order to get the CVS functions to work and be able to open PHP files. When I tried to do a CVS update I initially received an error about org.eclipse.team.internal.ccvs.ui.wizards.CheckoutWizard). Everything seemed to work again after reapplying the fix for the aforementioned 7.04 java issue.&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
&lt;br /&gt;
There is an excellent series of articles published by IBM on using Eclipse for Drupal developement here : [http://www-128.ibm.com/developerworks/ibm/osource/index.html Using open source software to design, develop, and deploy a collaborative Web site Tools and techniques for getting relatively complicated Web sites up and running quickly].&lt;br /&gt;
&lt;br /&gt;
[[Category:Setting up Eclipse]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=XMLDB_defining_an_XML_structure&amp;diff=4765</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=4765"/>
		<updated>2008-06-24T01:36:45Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: moving out of sourceforge&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 edition 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 [[Coding#Database_structures| 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.&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 &amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt; 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;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Moodle_Wishlist&amp;diff=9685</id>
		<title>Moodle Wishlist</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Moodle_Wishlist&amp;diff=9685"/>
		<updated>2008-06-20T01:56:09Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is a brainstorm about a complete rewrite/refactor for Moodle 3.0.&lt;br /&gt;
&lt;br /&gt;
Please add your ideas!   They don&#039;t need to be consistent yet, just make sure your ideas are here to be boiled down later on.&lt;br /&gt;
&lt;br /&gt;
Think Big!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===One type of plugin===&lt;br /&gt;
&lt;br /&gt;
All plugins/modules could be subclassed from one plugin class, making installation easier and simplifying the API a lot.&lt;br /&gt;
&lt;br /&gt;
===Look at new framework===&lt;br /&gt;
&lt;br /&gt;
Possibly base Moodle 3.0 on new existing frameworks?  Ruby on Rails?  Drupal?&lt;br /&gt;
&lt;br /&gt;
=== Moodlets===&lt;br /&gt;
&lt;br /&gt;
Individual-independent-activities backup/restore + metadata  - Eloy&lt;br /&gt;
&lt;br /&gt;
=== Support for alternate interfaces ===&lt;br /&gt;
&lt;br /&gt;
Completely flash-based interface?  Designed for offline clients?&lt;br /&gt;
&lt;br /&gt;
=== Integrated category/taxonomy system ===&lt;br /&gt;
&lt;br /&gt;
Putting together the &amp;quot;course categories&amp;quot;, &amp;quot;tags&amp;quot; into a generic taxonomy system.&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8404</id>
		<title>HTML editor 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8404"/>
		<updated>2008-06-04T08:59:10Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: /* Plan of action */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page details the specification of the HTML editor in Moodle 2.0.&lt;br /&gt;
== What we want ==&lt;br /&gt;
Ticket MDL-11113 discusses most issues.&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Integration - With Moodle (smileys, different formats, etc.) with a minimum of changes, cleaning up current code as much as possible&lt;br /&gt;
* Compatibility - With web browsers (mostly FF, IE, Safari, Opera)&lt;br /&gt;
* Standard - Outputs valid XHTML code&lt;br /&gt;
* Accessibility - Is it 100% keyboard accessible? Is it usable in JAWS? Etc.&lt;br /&gt;
* Configurability - Possibility to make it show different options and buttons according to the user, the context, etc.&lt;br /&gt;
* Support - Developed by an active community that will support it for a long time.&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
Some features that should be evaluated:&lt;br /&gt;
* Handling of Word documents&lt;br /&gt;
* HTML code direct editing&lt;br /&gt;
* Highlighting (not text background color, with &amp;quot;set-on&amp;quot; operation--Word style)&lt;br /&gt;
* Image uploading&lt;br /&gt;
* Mathematical formulas/equation editing&lt;br /&gt;
* Possible to turn it on and off on demand (on the page) without losing (possibly modified) content (see [http://wiki.moxiecode.com/examples/tinymce/installation_example_07.php this TinyMCE example of this])&lt;br /&gt;
* Right-to-left text input&lt;br /&gt;
* Smileys (has to be possible to use the Moodle list of smileys)&lt;br /&gt;
* Special characters&lt;br /&gt;
* Tables&lt;br /&gt;
* Themeable (possible to make a theme that fits with Moodle&#039;s)&lt;br /&gt;
&lt;br /&gt;
=== Wishes ===&lt;br /&gt;
* Make it possible to change to a different editor (provided someone comes up with the necessary code to &amp;quot;plug it&amp;quot; in Moodle)&lt;br /&gt;
* Possible to run many instances on the same page (see MDL-11101 in tracker)&lt;br /&gt;
* Fix [http://tracker.moodle.org/secure/IssueNavigator.jspa?reset=true&amp;amp;pid=10011&amp;amp;resolution=-1&amp;amp;component=10070&amp;amp;sorter/field=summary&amp;amp;sorter/order=ASC&amp;amp;sorter/field=resolution&amp;amp;sorter/order=ASC&amp;amp;sorter/field=status&amp;amp;sorter/order=ASC&amp;amp;sorter/field=priority&amp;amp;sorter/order=DESC all the bugs] related to the HTML editor&lt;br /&gt;
* Submit drafts in the background, using ajax.&lt;br /&gt;
&lt;br /&gt;
== Possibilities and evaluation ==&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Comparison_of_WYSIWYG_HTML_editors Comparison of WYSIWYG HTML editors on Wikipedia]&lt;br /&gt;
* [http://tinymce.moxiecode.com/ TinyMCE]: [http://wiki.moxiecode.com/index.php/TinyMCE:Compatibility Compatibility], [http://wiki.moxiecode.com/index.php/TinyMCE:Index Documentation], [http://tinymce.moxiecode.com/example_full.php?example=true Demo]&lt;br /&gt;
* [http://www.fckeditor.net/ FCKeditor]: [http://docs.fckeditor.net/FCKeditor_3.x/Design_and_Architecture/Browsers_Compatibility Compatibility] [http://docs.fckeditor.net/ Documentation], [http://www.fckeditor.net/demo Demo]&lt;br /&gt;
* [http://xinha.webfactional.com/ Xinha]: [http://xinha.webfactional.com/wiki/Documentation Documentation], [http://xinha.webfactional.com/wiki/Examples Demo]&lt;br /&gt;
* [http://developer.yahoo.com/yui/editor/ Yahoo RTE]: [http://developer.yahoo.com/yui/docs/module_editor.html Documentation], [http://developer.yahoo.com/yui/examples/editor/index.html Demo], &lt;br /&gt;
As of 16 April 2008, the preference goes to TinyMCE.&lt;br /&gt;
&lt;br /&gt;
== Plan of action ==&lt;br /&gt;
&lt;br /&gt;
See: MDL-11113 and MDL-14739&lt;br /&gt;
&lt;br /&gt;
* Get latest TinyMCE in HEAD before 13 May 2008 so that work can be done there (done, MDL-14739)&lt;br /&gt;
* Have the XHTML profile active by default in TinyMCE (done)&lt;br /&gt;
* Attack each Moodle plugin in turn, keeping modifications to TinyMCE code base as modular and minimal as possible&lt;br /&gt;
&lt;br /&gt;
=== Plugins to write ===&lt;br /&gt;
Some plugins will have to be written for each editor to make integration with Moodle possible.  These should be as abstracted as possible, to make as much code as possible common between each.  Since editors will be located under /lib/editor, let&#039;s store this common code under /lib/editormod.&lt;br /&gt;
&lt;br /&gt;
* File browser: the file browser (especially with the [[File API]]) will be Moodle specific&lt;br /&gt;
* Emoticons (smileys): Moodle defines its own list of emoticons, we need to make sure the editors use these consistently&lt;br /&gt;
* Language files: Moodle has a lot more languages than any editors, and some strings will be Moodle-specific.  We need a way to make for each editor to use Moodle strings, reusing as many existing strings as possible, and using lang/xx/editor.php for the rest.&lt;br /&gt;
* Equation editor: there is [[DragMath_equation_editor| ongoing work]] to get [http://www.dragmath.bham.ac.uk/ Dragmath] working in Moodle, making a common plugin could be a nice improvement&lt;br /&gt;
* Multilang:  all editors need to support multilang properly.&lt;br /&gt;
&lt;br /&gt;
It also may be possible to use Moodle&#039;s CSS files to define editors themes/skins, this needs investigation&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Editor-specific information:&#039;&#039;&#039;&lt;br /&gt;
* TinyMCE makes it possible to have [http://tinymce.moxiecode.com/punbb/viewtopic.php?pid=9317#p9317 self-registering plugins], that don&#039;t need to be under it&#039;s /plugins folder (and so could be in a moodle-specific folder).&lt;br /&gt;
* FCKeditor [http://docs.fckeditor.net/FCKeditor_2.x/Developers_Guide/Customization/Plug-ins needs to have its plugins in a specific place].&lt;br /&gt;
&lt;br /&gt;
=== Change in formats ===&lt;br /&gt;
&lt;br /&gt;
There is a bug (MDL-4868) about Markdown not being converted to HTML when using the HTML editor (after creating a post with Markdown). &lt;br /&gt;
&lt;br /&gt;
This really applies to all non-HTML formats.&lt;br /&gt;
&lt;br /&gt;
Proposal: whenever the HTML editor is used to edit existing non-HTML text, we convert the text to HTML for use in the editor.  Saving the changes will save the text (and format) as HTML.&lt;br /&gt;
&lt;br /&gt;
Although we are losing some information, we feel it&#039;s an acceptable tradeoff against overall usability, particularly as the HTML editor works on a wider range of browsers and we make XHTML compliance a requirement.&lt;br /&gt;
&lt;br /&gt;
== Links to forum discussions, tracker, docs, etc. ==&lt;br /&gt;
* [http://tracker.moodle.org/browse/MDL-11113 MDL-11113 - Get a fully working HTML editor in Moodle]&lt;br /&gt;
* [[Moodle-specific customisations to the HTML editor]]&lt;br /&gt;
&lt;br /&gt;
Using Moodle General developer forum discussions:&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=88382 TinyMCE3 Integration]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=93475 XINHA has started to support Opera and Safari]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=76912 What is the current position with the HTML editor?]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=96160 The most important decision on editor integration]&lt;br /&gt;
&lt;br /&gt;
[[Category:HTML editor]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8403</id>
		<title>HTML editor 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8403"/>
		<updated>2008-06-04T08:57:17Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: /* Plugins to write */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page details the specification of the HTML editor in Moodle 2.0.&lt;br /&gt;
== What we want ==&lt;br /&gt;
Ticket MDL-11113 discusses most issues.&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Integration - With Moodle (smileys, different formats, etc.) with a minimum of changes, cleaning up current code as much as possible&lt;br /&gt;
* Compatibility - With web browsers (mostly FF, IE, Safari, Opera)&lt;br /&gt;
* Standard - Outputs valid XHTML code&lt;br /&gt;
* Accessibility - Is it 100% keyboard accessible? Is it usable in JAWS? Etc.&lt;br /&gt;
* Configurability - Possibility to make it show different options and buttons according to the user, the context, etc.&lt;br /&gt;
* Support - Developed by an active community that will support it for a long time.&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
Some features that should be evaluated:&lt;br /&gt;
* Handling of Word documents&lt;br /&gt;
* HTML code direct editing&lt;br /&gt;
* Highlighting (not text background color, with &amp;quot;set-on&amp;quot; operation--Word style)&lt;br /&gt;
* Image uploading&lt;br /&gt;
* Mathematical formulas/equation editing&lt;br /&gt;
* Possible to turn it on and off on demand (on the page) without losing (possibly modified) content (see [http://wiki.moxiecode.com/examples/tinymce/installation_example_07.php this TinyMCE example of this])&lt;br /&gt;
* Right-to-left text input&lt;br /&gt;
* Smileys (has to be possible to use the Moodle list of smileys)&lt;br /&gt;
* Special characters&lt;br /&gt;
* Tables&lt;br /&gt;
* Themeable (possible to make a theme that fits with Moodle&#039;s)&lt;br /&gt;
&lt;br /&gt;
=== Wishes ===&lt;br /&gt;
* Make it possible to change to a different editor (provided someone comes up with the necessary code to &amp;quot;plug it&amp;quot; in Moodle)&lt;br /&gt;
* Possible to run many instances on the same page (see MDL-11101 in tracker)&lt;br /&gt;
* Fix [http://tracker.moodle.org/secure/IssueNavigator.jspa?reset=true&amp;amp;pid=10011&amp;amp;resolution=-1&amp;amp;component=10070&amp;amp;sorter/field=summary&amp;amp;sorter/order=ASC&amp;amp;sorter/field=resolution&amp;amp;sorter/order=ASC&amp;amp;sorter/field=status&amp;amp;sorter/order=ASC&amp;amp;sorter/field=priority&amp;amp;sorter/order=DESC all the bugs] related to the HTML editor&lt;br /&gt;
* Submit drafts in the background, using ajax.&lt;br /&gt;
&lt;br /&gt;
== Possibilities and evaluation ==&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Comparison_of_WYSIWYG_HTML_editors Comparison of WYSIWYG HTML editors on Wikipedia]&lt;br /&gt;
* [http://tinymce.moxiecode.com/ TinyMCE]: [http://wiki.moxiecode.com/index.php/TinyMCE:Compatibility Compatibility], [http://wiki.moxiecode.com/index.php/TinyMCE:Index Documentation], [http://tinymce.moxiecode.com/example_full.php?example=true Demo]&lt;br /&gt;
* [http://www.fckeditor.net/ FCKeditor]: [http://docs.fckeditor.net/FCKeditor_3.x/Design_and_Architecture/Browsers_Compatibility Compatibility] [http://docs.fckeditor.net/ Documentation], [http://www.fckeditor.net/demo Demo]&lt;br /&gt;
* [http://xinha.webfactional.com/ Xinha]: [http://xinha.webfactional.com/wiki/Documentation Documentation], [http://xinha.webfactional.com/wiki/Examples Demo]&lt;br /&gt;
* [http://developer.yahoo.com/yui/editor/ Yahoo RTE]: [http://developer.yahoo.com/yui/docs/module_editor.html Documentation], [http://developer.yahoo.com/yui/examples/editor/index.html Demo], &lt;br /&gt;
As of 16 April 2008, the preference goes to TinyMCE.&lt;br /&gt;
&lt;br /&gt;
== Plan of action ==&lt;br /&gt;
&lt;br /&gt;
See: MDL-xxxx&lt;br /&gt;
&lt;br /&gt;
* Get latest TinyMCE in HEAD before 13 May 2008 so that work can be done there&lt;br /&gt;
* Have the XHTML profile active by default in TinyMCE&lt;br /&gt;
* Attack each Moodle plugin in turn, keeping modifications to TinyMCE code base as modular and minimal as possible&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Plugins to write ===&lt;br /&gt;
Some plugins will have to be written for each editor to make integration with Moodle possible.  These should be as abstracted as possible, to make as much code as possible common between each.  Since editors will be located under /lib/editor, let&#039;s store this common code under /lib/editormod.&lt;br /&gt;
&lt;br /&gt;
* File browser: the file browser (especially with the [[File API]]) will be Moodle specific&lt;br /&gt;
* Emoticons (smileys): Moodle defines its own list of emoticons, we need to make sure the editors use these consistently&lt;br /&gt;
* Language files: Moodle has a lot more languages than any editors, and some strings will be Moodle-specific.  We need a way to make for each editor to use Moodle strings, reusing as many existing strings as possible, and using lang/xx/editor.php for the rest.&lt;br /&gt;
* Equation editor: there is [[DragMath_equation_editor| ongoing work]] to get [http://www.dragmath.bham.ac.uk/ Dragmath] working in Moodle, making a common plugin could be a nice improvement&lt;br /&gt;
* Multilang:  all editors need to support multilang properly.&lt;br /&gt;
&lt;br /&gt;
It also may be possible to use Moodle&#039;s CSS files to define editors themes/skins, this needs investigation&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Editor-specific information:&#039;&#039;&#039;&lt;br /&gt;
* TinyMCE makes it possible to have [http://tinymce.moxiecode.com/punbb/viewtopic.php?pid=9317#p9317 self-registering plugins], that don&#039;t need to be under it&#039;s /plugins folder (and so could be in a moodle-specific folder).&lt;br /&gt;
* FCKeditor [http://docs.fckeditor.net/FCKeditor_2.x/Developers_Guide/Customization/Plug-ins needs to have its plugins in a specific place].&lt;br /&gt;
&lt;br /&gt;
=== Change in formats ===&lt;br /&gt;
&lt;br /&gt;
There is a bug (MDL-4868) about Markdown not being converted to HTML when using the HTML editor (after creating a post with Markdown). &lt;br /&gt;
&lt;br /&gt;
This really applies to all non-HTML formats.&lt;br /&gt;
&lt;br /&gt;
Proposal: whenever the HTML editor is used to edit existing non-HTML text, we convert the text to HTML for use in the editor.  Saving the changes will save the text (and format) as HTML.&lt;br /&gt;
&lt;br /&gt;
Although we are losing some information, we feel it&#039;s an acceptable tradeoff against overall usability, particularly as the HTML editor works on a wider range of browsers and we make XHTML compliance a requirement.&lt;br /&gt;
&lt;br /&gt;
== Links to forum discussions, tracker, docs, etc. ==&lt;br /&gt;
* [http://tracker.moodle.org/browse/MDL-11113 MDL-11113 - Get a fully working HTML editor in Moodle]&lt;br /&gt;
* [[Moodle-specific customisations to the HTML editor]]&lt;br /&gt;
&lt;br /&gt;
Using Moodle General developer forum discussions:&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=88382 TinyMCE3 Integration]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=93475 XINHA has started to support Opera and Safari]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=76912 What is the current position with the HTML editor?]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=96160 The most important decision on editor integration]&lt;br /&gt;
&lt;br /&gt;
[[Category:HTML editor]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8402</id>
		<title>HTML editor 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8402"/>
		<updated>2008-06-04T08:53:44Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: /* Plugins to write */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page details the specification of the HTML editor in Moodle 2.0.&lt;br /&gt;
== What we want ==&lt;br /&gt;
Ticket MDL-11113 discusses most issues.&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Integration - With Moodle (smileys, different formats, etc.) with a minimum of changes, cleaning up current code as much as possible&lt;br /&gt;
* Compatibility - With web browsers (mostly FF, IE, Safari, Opera)&lt;br /&gt;
* Standard - Outputs valid XHTML code&lt;br /&gt;
* Accessibility - Is it 100% keyboard accessible? Is it usable in JAWS? Etc.&lt;br /&gt;
* Configurability - Possibility to make it show different options and buttons according to the user, the context, etc.&lt;br /&gt;
* Support - Developed by an active community that will support it for a long time.&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
Some features that should be evaluated:&lt;br /&gt;
* Handling of Word documents&lt;br /&gt;
* HTML code direct editing&lt;br /&gt;
* Highlighting (not text background color, with &amp;quot;set-on&amp;quot; operation--Word style)&lt;br /&gt;
* Image uploading&lt;br /&gt;
* Mathematical formulas/equation editing&lt;br /&gt;
* Possible to turn it on and off on demand (on the page) without losing (possibly modified) content (see [http://wiki.moxiecode.com/examples/tinymce/installation_example_07.php this TinyMCE example of this])&lt;br /&gt;
* Right-to-left text input&lt;br /&gt;
* Smileys (has to be possible to use the Moodle list of smileys)&lt;br /&gt;
* Special characters&lt;br /&gt;
* Tables&lt;br /&gt;
* Themeable (possible to make a theme that fits with Moodle&#039;s)&lt;br /&gt;
&lt;br /&gt;
=== Wishes ===&lt;br /&gt;
* Make it possible to change to a different editor (provided someone comes up with the necessary code to &amp;quot;plug it&amp;quot; in Moodle)&lt;br /&gt;
* Possible to run many instances on the same page (see MDL-11101 in tracker)&lt;br /&gt;
* Fix [http://tracker.moodle.org/secure/IssueNavigator.jspa?reset=true&amp;amp;pid=10011&amp;amp;resolution=-1&amp;amp;component=10070&amp;amp;sorter/field=summary&amp;amp;sorter/order=ASC&amp;amp;sorter/field=resolution&amp;amp;sorter/order=ASC&amp;amp;sorter/field=status&amp;amp;sorter/order=ASC&amp;amp;sorter/field=priority&amp;amp;sorter/order=DESC all the bugs] related to the HTML editor&lt;br /&gt;
* Submit drafts in the background, using ajax.&lt;br /&gt;
&lt;br /&gt;
== Possibilities and evaluation ==&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Comparison_of_WYSIWYG_HTML_editors Comparison of WYSIWYG HTML editors on Wikipedia]&lt;br /&gt;
* [http://tinymce.moxiecode.com/ TinyMCE]: [http://wiki.moxiecode.com/index.php/TinyMCE:Compatibility Compatibility], [http://wiki.moxiecode.com/index.php/TinyMCE:Index Documentation], [http://tinymce.moxiecode.com/example_full.php?example=true Demo]&lt;br /&gt;
* [http://www.fckeditor.net/ FCKeditor]: [http://docs.fckeditor.net/FCKeditor_3.x/Design_and_Architecture/Browsers_Compatibility Compatibility] [http://docs.fckeditor.net/ Documentation], [http://www.fckeditor.net/demo Demo]&lt;br /&gt;
* [http://xinha.webfactional.com/ Xinha]: [http://xinha.webfactional.com/wiki/Documentation Documentation], [http://xinha.webfactional.com/wiki/Examples Demo]&lt;br /&gt;
* [http://developer.yahoo.com/yui/editor/ Yahoo RTE]: [http://developer.yahoo.com/yui/docs/module_editor.html Documentation], [http://developer.yahoo.com/yui/examples/editor/index.html Demo], &lt;br /&gt;
As of 16 April 2008, the preference goes to TinyMCE.&lt;br /&gt;
&lt;br /&gt;
== Plan of action ==&lt;br /&gt;
&lt;br /&gt;
See: MDL-xxxx&lt;br /&gt;
&lt;br /&gt;
* Get latest TinyMCE in HEAD before 13 May 2008 so that work can be done there&lt;br /&gt;
* Have the XHTML profile active by default in TinyMCE&lt;br /&gt;
* Attack each Moodle plugin in turn, keeping modifications to TinyMCE code base as modular and minimal as possible&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Plugins to write ===&lt;br /&gt;
Some plugins will have to be written for each editor to make integration with Moodle possible.  These should be as abstracted as possible, to make as much code as possible common between each.  Since editors will be located under /lib/editor, let&#039;s store this common code under /lib/editormod.&lt;br /&gt;
&lt;br /&gt;
* File browser: the file browser (especially with the [[File API]]) will be Moodle specific&lt;br /&gt;
* Emoticons (smileys): Moodle defines its own list of emoticons, we need to make sure the editors use these consistently&lt;br /&gt;
* Language files: Moodle has a lot more languages than any editors, and some strings will be Moodle-specific.  We need a way to make for each editor to use Moodle strings, reusing as many existing strings as possible, and using lang/xx/editor.php for the rest.&lt;br /&gt;
* Equation editor: there is [[DragMath_equation_editor| ongoing work]] to get [http://www.dragmath.bham.ac.uk/ Dragmath] working in Moodle, making a common plugin could be a nice improvement&lt;br /&gt;
* Multilang:  all editors need to support multilang properly.&lt;br /&gt;
&lt;br /&gt;
It also may be possible to use Moodle&#039;s CSS files to define editors themes/skins, this needs investigation&lt;br /&gt;
&lt;br /&gt;
Editor-specific information:&lt;br /&gt;
* TinyMCE makes it possible to have [http://tinymce.moxiecode.com/punbb/viewtopic.php?pid=9317#p9317 self-registering plugins], that don&#039;t need to be under it&#039;s /plugins folder (and so could be in a moodle-specific folder).&lt;br /&gt;
* FCKeditor [http://docs.fckeditor.net/FCKeditor_2.x/Developers_Guide/Customization/Plug-ins needs to have its plugins in a specific place].&lt;br /&gt;
&lt;br /&gt;
=== Change in formats ===&lt;br /&gt;
&lt;br /&gt;
There is a bug (MDL-4868) about Markdown not being converted to HTML when using the HTML editor (after creating a post with Markdown). &lt;br /&gt;
&lt;br /&gt;
This really applies to all non-HTML formats.&lt;br /&gt;
&lt;br /&gt;
Proposal: whenever the HTML editor is used to edit existing non-HTML text, we convert the text to HTML for use in the editor.  Saving the changes will save the text (and format) as HTML.&lt;br /&gt;
&lt;br /&gt;
Although we are losing some information, we feel it&#039;s an acceptable tradeoff against overall usability, particularly as the HTML editor works on a wider range of browsers and we make XHTML compliance a requirement.&lt;br /&gt;
&lt;br /&gt;
== Links to forum discussions, tracker, docs, etc. ==&lt;br /&gt;
* [http://tracker.moodle.org/browse/MDL-11113 MDL-11113 - Get a fully working HTML editor in Moodle]&lt;br /&gt;
* [[Moodle-specific customisations to the HTML editor]]&lt;br /&gt;
&lt;br /&gt;
Using Moodle General developer forum discussions:&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=88382 TinyMCE3 Integration]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=93475 XINHA has started to support Opera and Safari]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=76912 What is the current position with the HTML editor?]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=96160 The most important decision on editor integration]&lt;br /&gt;
&lt;br /&gt;
[[Category:HTML editor]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8401</id>
		<title>HTML editor 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8401"/>
		<updated>2008-06-04T08:48:57Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: /* Plugins to write */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page details the specification of the HTML editor in Moodle 2.0.&lt;br /&gt;
== What we want ==&lt;br /&gt;
Ticket MDL-11113 discusses most issues.&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Integration - With Moodle (smileys, different formats, etc.) with a minimum of changes, cleaning up current code as much as possible&lt;br /&gt;
* Compatibility - With web browsers (mostly FF, IE, Safari, Opera)&lt;br /&gt;
* Standard - Outputs valid XHTML code&lt;br /&gt;
* Accessibility - Is it 100% keyboard accessible? Is it usable in JAWS? Etc.&lt;br /&gt;
* Configurability - Possibility to make it show different options and buttons according to the user, the context, etc.&lt;br /&gt;
* Support - Developed by an active community that will support it for a long time.&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
Some features that should be evaluated:&lt;br /&gt;
* Handling of Word documents&lt;br /&gt;
* HTML code direct editing&lt;br /&gt;
* Highlighting (not text background color, with &amp;quot;set-on&amp;quot; operation--Word style)&lt;br /&gt;
* Image uploading&lt;br /&gt;
* Mathematical formulas/equation editing&lt;br /&gt;
* Possible to turn it on and off on demand (on the page) without losing (possibly modified) content (see [http://wiki.moxiecode.com/examples/tinymce/installation_example_07.php this TinyMCE example of this])&lt;br /&gt;
* Right-to-left text input&lt;br /&gt;
* Smileys (has to be possible to use the Moodle list of smileys)&lt;br /&gt;
* Special characters&lt;br /&gt;
* Tables&lt;br /&gt;
* Themeable (possible to make a theme that fits with Moodle&#039;s)&lt;br /&gt;
&lt;br /&gt;
=== Wishes ===&lt;br /&gt;
* Make it possible to change to a different editor (provided someone comes up with the necessary code to &amp;quot;plug it&amp;quot; in Moodle)&lt;br /&gt;
* Possible to run many instances on the same page (see MDL-11101 in tracker)&lt;br /&gt;
* Fix [http://tracker.moodle.org/secure/IssueNavigator.jspa?reset=true&amp;amp;pid=10011&amp;amp;resolution=-1&amp;amp;component=10070&amp;amp;sorter/field=summary&amp;amp;sorter/order=ASC&amp;amp;sorter/field=resolution&amp;amp;sorter/order=ASC&amp;amp;sorter/field=status&amp;amp;sorter/order=ASC&amp;amp;sorter/field=priority&amp;amp;sorter/order=DESC all the bugs] related to the HTML editor&lt;br /&gt;
* Submit drafts in the background, using ajax.&lt;br /&gt;
&lt;br /&gt;
== Possibilities and evaluation ==&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Comparison_of_WYSIWYG_HTML_editors Comparison of WYSIWYG HTML editors on Wikipedia]&lt;br /&gt;
* [http://tinymce.moxiecode.com/ TinyMCE]: [http://wiki.moxiecode.com/index.php/TinyMCE:Compatibility Compatibility], [http://wiki.moxiecode.com/index.php/TinyMCE:Index Documentation], [http://tinymce.moxiecode.com/example_full.php?example=true Demo]&lt;br /&gt;
* [http://www.fckeditor.net/ FCKeditor]: [http://docs.fckeditor.net/FCKeditor_3.x/Design_and_Architecture/Browsers_Compatibility Compatibility] [http://docs.fckeditor.net/ Documentation], [http://www.fckeditor.net/demo Demo]&lt;br /&gt;
* [http://xinha.webfactional.com/ Xinha]: [http://xinha.webfactional.com/wiki/Documentation Documentation], [http://xinha.webfactional.com/wiki/Examples Demo]&lt;br /&gt;
* [http://developer.yahoo.com/yui/editor/ Yahoo RTE]: [http://developer.yahoo.com/yui/docs/module_editor.html Documentation], [http://developer.yahoo.com/yui/examples/editor/index.html Demo], &lt;br /&gt;
As of 16 April 2008, the preference goes to TinyMCE.&lt;br /&gt;
&lt;br /&gt;
== Plan of action ==&lt;br /&gt;
&lt;br /&gt;
See: MDL-xxxx&lt;br /&gt;
&lt;br /&gt;
* Get latest TinyMCE in HEAD before 13 May 2008 so that work can be done there&lt;br /&gt;
* Have the XHTML profile active by default in TinyMCE&lt;br /&gt;
* Attack each Moodle plugin in turn, keeping modifications to TinyMCE code base as modular and minimal as possible&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Plugins to write ===&lt;br /&gt;
Some plugins will have to be written for each editor to make integration with Moodle possible.  These should be as abstracted as possible, to make as much code as possible common between each.  Since editors will be located under /lib/editor, let&#039;s store this common code under /lib/editormod.&lt;br /&gt;
&lt;br /&gt;
* File browser: the file browser (especially with the [[File API]]) will be Moodle specific&lt;br /&gt;
* Emoticons (smileys): Moodle defines its own list of emoticons, we need to make sure the editors use these consistently&lt;br /&gt;
* Language files: Moodle has a lot more languages than any editors, and some strings will be Moodle-specific.  We need a way to make for each editor to use Moodle strings, reusing as many existing strings as possible, and using lang/xx/editor.php for the rest.&lt;br /&gt;
* Equation editor: there is [[DragMath_equation_editor| ongoing work]] to get [http://www.dragmath.bham.ac.uk/ Dragmath] working in Moodle, making a common plugin could be a nice improvement&lt;br /&gt;
* Multilang:  all editors need to support multilang properly.&lt;br /&gt;
&lt;br /&gt;
It also may be possible to use Moodle&#039;s CSS files to define editors themes/skins, this needs investigation&lt;br /&gt;
&lt;br /&gt;
Editor-specific information:&lt;br /&gt;
* tinymce makes it possible to have [http://tinymce.moxiecode.com/punbb/viewtopic.php?pid=9317#p9317 self-registering plugins], that don&#039;t need to be under it&#039;s /plugins folder (and so could be in a moodle-specific folder).&lt;br /&gt;
&lt;br /&gt;
=== Change in formats ===&lt;br /&gt;
&lt;br /&gt;
There is a bug (MDL-4868) about Markdown not being converted to HTML when using the HTML editor (after creating a post with Markdown). &lt;br /&gt;
&lt;br /&gt;
This really applies to all non-HTML formats.&lt;br /&gt;
&lt;br /&gt;
Proposal: whenever the HTML editor is used to edit existing non-HTML text, we convert the text to HTML for use in the editor.  Saving the changes will save the text (and format) as HTML.&lt;br /&gt;
&lt;br /&gt;
Although we are losing some information, we feel it&#039;s an acceptable tradeoff against overall usability, particularly as the HTML editor works on a wider range of browsers and we make XHTML compliance a requirement.&lt;br /&gt;
&lt;br /&gt;
== Links to forum discussions, tracker, docs, etc. ==&lt;br /&gt;
* [http://tracker.moodle.org/browse/MDL-11113 MDL-11113 - Get a fully working HTML editor in Moodle]&lt;br /&gt;
* [[Moodle-specific customisations to the HTML editor]]&lt;br /&gt;
&lt;br /&gt;
Using Moodle General developer forum discussions:&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=88382 TinyMCE3 Integration]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=93475 XINHA has started to support Opera and Safari]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=76912 What is the current position with the HTML editor?]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=96160 The most important decision on editor integration]&lt;br /&gt;
&lt;br /&gt;
[[Category:HTML editor]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=User:Mathieu_Petit-Clair&amp;diff=20470</id>
		<title>User:Mathieu Petit-Clair</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=User:Mathieu_Petit-Clair&amp;diff=20470"/>
		<updated>2008-05-08T05:11:01Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See http://moodle.org/user/view.php?id=423027&amp;amp;course=1 for details.&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Overview&amp;diff=7020</id>
		<title>Overview</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Overview&amp;diff=7020"/>
		<updated>2008-05-07T06:44:32Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: /* The key players */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A lot of people ask how the development of Moodle operates.  This page should give you a working overview that should help in understanding a lot of other developer documentation.&lt;br /&gt;
&lt;br /&gt;
==The key players==&lt;br /&gt;
&lt;br /&gt;
;Martin Dougiamas: Martin is the lead developer of Moodle. Generally he tries to facilitate democracy and meritocracy but occasionally has to make executive decisions on things.&lt;br /&gt;
&lt;br /&gt;
;Moodle HQ: The mostly-Australian team of developers who are directly funded by the Moodle project to work full-time on core developments.  Developers include Martin Dougiamas (moodler), Eloy Lafuente (stronk7), Petr Skoda (skodak), Mathieu Petit-Clair (scyrma), Nicolas Connault, Donsheng Cai, Jérôme Mouneyrac, Helen Foster (wildgirl) and occasionally Jamie Pratt (jamiesensei). Pictures of everyone can be found here: http://moodle.com/hq/.&lt;br /&gt;
&lt;br /&gt;
;Catalyst: The team of developers working for Moodle clients via Catalyst Ltd in New Zealand, resulting in a lot of core development.  Developers include Martin Langhoff, Penny Leach (mjollnir), Matt Clarkson, and Donal McMullan.&lt;br /&gt;
&lt;br /&gt;
;Open University: The team of developers working on Moodle implementations at Open University in the UK.  Developers include Tim Hunt, Sam Marshall, Nick Freear, Thanh Le and Jenny Gray.&lt;br /&gt;
&lt;br /&gt;
There are many other people contributing to Moodle in many ways, these are just the main groups currently working on core development.  See [http://moodle.org/cvs the full list of people with write access to Moodle]&lt;br /&gt;
&lt;br /&gt;
==Moodle versions==&lt;br /&gt;
&lt;br /&gt;
Moodle major releases occur roughly 6 months or more apart, on no fixed schedule.  Each major release increments the version number by 0.1.  Minor releases (no new features, just fixes) on each stable branch can occur at any time, whenever enough bug fixes have been made to justify them.  The full details can be seen in the [[Release notes]].&lt;br /&gt;
&lt;br /&gt;
The current development version is always on the trunk of CVS (i.e. HEAD), while stable branches are split off for every major version (e.g. MOODLE_18_STABLE).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Release cycles==&lt;br /&gt;
&lt;br /&gt;
Generally a cycle works like this:&lt;br /&gt;
;Rapid Development:Long period of several months adding code to the HEAD version of Moodle.  At the same time, all fixes that don&#039;t involve database changes or radical core changes are backported to the last two or three stable branches.&lt;br /&gt;
;Head Freeze:At some point Martin Dougiamas declares a freeze on new work for a while to stabilise the core.  All database changes and all major core changes need to have explicit permission from Martin.  All developers should be wrapping up work on new features and fixing bugs in new code.  This period may be 1 or 2 weeks.&lt;br /&gt;
;Beta period:Once the HEAD version becomes fairly stable, Martin declares a BETA version and this point is marked on HEAD as MOODLE_XX_BETA (e.g. MOODLE_19_BETA).  Install packages are generated daily from the latest version for wider testing and feedback via the tracker.  The freeze continues, testing and bug fixing continues.  This testing period may be anywhere from 2 to 6 weeks.&lt;br /&gt;
;Major release:When the core code passes all the testing we can throw at it, the MOODLE_XX_BETA flag is moved up to mark the current point as a branch point, and a new stable branch named MOODLE_XX_STABLE is created.  Packages are created, and the release is announced.&lt;br /&gt;
&lt;br /&gt;
Then it all starts again!&lt;br /&gt;
&lt;br /&gt;
==Quality control==&lt;br /&gt;
&lt;br /&gt;
Issue tracking is an important part of a continuous quality control process. It involves reporting of problems (bugs), ideas for improvement and new features. Unlike most proprietary software programs, Moodle issue reporting and tracking information is open to everyone. Moodle&#039;s issue tracking system is called the [[Tracker]].&lt;br /&gt;
&lt;br /&gt;
All Moodle users are encouraged to be active participants when it comes to testing. Anyone with a Tracker user account can create, view, comment on, vote, and watch bugs.&lt;br /&gt;
&lt;br /&gt;
===Testers===&lt;br /&gt;
&lt;br /&gt;
Testers are responsible for verifying the accuracy of changes made by developers. Testers choose which bugs they want to test, according to their area of expertise, and use the QA Assignee field to identify themselves as the tester.&lt;br /&gt;
&lt;br /&gt;
If the bug passes testing, then the tester changes the status of the bug from &#039;resolved&#039; to &#039;closed&#039;. If the bug fails testing, or if the fix is incomplete, then the tester reopens the bug.&lt;br /&gt;
&lt;br /&gt;
A Moodle release will be deemed ready when all &amp;quot;blocker&amp;quot; bugs fixed for a particular version have been closed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Weekly Code Review===&lt;br /&gt;
&lt;br /&gt;
Every Tuesday (all time zones), testers and core developers stop developing new code and focus on reviewing changes made to the stable releases in the past week (both at a code level and an interface level).&lt;br /&gt;
&lt;br /&gt;
This process is intended to improve the quality of the latest download packages and to catch any new bugs that might have been created while fixing old ones.&lt;br /&gt;
&lt;br /&gt;
The latest stable packages are tagged as MOODLE_19_WEEKLY (these tags are updated after the weekly review is over).&lt;br /&gt;
&lt;br /&gt;
See [[Weekly Code Review]] for more details.&lt;br /&gt;
&lt;br /&gt;
==Coding Standards==&lt;br /&gt;
&lt;br /&gt;
The full [[Coding|Coding Guide]] gives all the details, but here are some of the major things  your code needs to hit:&lt;br /&gt;
&lt;br /&gt;
===XMLDB===&lt;br /&gt;
&lt;br /&gt;
All our database schema are created using the XML &#039;&#039;install.php&#039;&#039; files, and upgraded using database-agnostic commands in &#039;&#039;upgrade.php&#039;&#039; files.  Any version of any part of Moodle can be smoothly upgraded to any later version in this fashion (on a wide variety of supported databases).&lt;br /&gt;
&lt;br /&gt;
===XHTML===&lt;br /&gt;
&lt;br /&gt;
All output from Moodle must be compliant with XHTML Strict 1.0, and also compliant with all common accessibility guidelines (such as W3C WAG).  &lt;br /&gt;
&lt;br /&gt;
===Forms===&lt;br /&gt;
&lt;br /&gt;
All forms should use the Moodleforms library if possible.  This results in a standardised accessible output that designers can style consistently and well.&lt;br /&gt;
&lt;br /&gt;
===Parameters===&lt;br /&gt;
&lt;br /&gt;
All parameters should be checked using require_param() and optional_param() which will safely clean all incoming data for use and provide defaults to your code.  Moodleforms will do this automatically for you.&lt;br /&gt;
&lt;br /&gt;
===Output===&lt;br /&gt;
&lt;br /&gt;
All textual output should be output using the format_text or format_string functions.  This will ensure that text is cleaned and filtered appropriately.&lt;br /&gt;
&lt;br /&gt;
===Access===&lt;br /&gt;
&lt;br /&gt;
All permissions-checking should use the &amp;quot;Access library&amp;quot; to check against current capabilities.  The most common function you&#039;ll use is has_capability() which checks the permissions of the current user in an efficient way to see if they are allowed to do this specific operation.   Do not check for specific roles in your code (e.g. teacher/student) as that will make your code useless.&lt;br /&gt;
&lt;br /&gt;
===Other core libraries===&lt;br /&gt;
&lt;br /&gt;
The other major libraries you should get familiar with are:&lt;br /&gt;
# &#039;&#039;moodlelib.php&#039;&#039; - a useful bin of all kinds of useful functions and constants&lt;br /&gt;
# &#039;&#039;datalib.php&#039;&#039; - all the functions you need to interface with the database &lt;br /&gt;
# &#039;&#039;weblib.php&#039;&#039; - all the functions you&#039;ll need to create and output XHTML &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Plugins===&lt;br /&gt;
&lt;br /&gt;
Moodle has about 22 different types of plugins last time I counted.  Plugins can generally be self-contained in a single directory containing scripts, images, stylesheets and language files all in one package that can be dropped into the Moodle script directory in the right place.  After that the admin just needs to visit the admin page to install them.&lt;br /&gt;
&lt;br /&gt;
Most plugins work in one of two ways, they either provide a &#039;&#039;lib.php&#039;&#039; filled with common functions and some scripts with standard names, or they subclass a proto-plugin and override a few method functions to achieve their goals.  &lt;br /&gt;
&lt;br /&gt;
The best way to learn is to pick an example from the core code that is similar to what you want to do and start playing with it.   There are also some template plugins to help get you started.&lt;br /&gt;
&lt;br /&gt;
==Development processes==&lt;br /&gt;
Not all Moodle development happens exactly like this, but it really should. :-)&lt;br /&gt;
&lt;br /&gt;
===Major Development===&lt;br /&gt;
A major development is a significant piece of new code, adding new functionality to Moodle.&lt;br /&gt;
&lt;br /&gt;
====Make sure it&#039;s a good idea====&lt;br /&gt;
Firstly, you should look at the roadmap and talk the idea over with some Moodle developers to see if someone else is working on it already and whether others think the general idea has merit.  Use the forums if you wish, or whatever means you have.  If you have a client, you may need to work with them to work out what they REALLY want (perhaps it isn&#039;t actually a new development for Moodle).&lt;br /&gt;
&lt;br /&gt;
====Create a specification in Moodle Docs====&lt;br /&gt;
Start a new page in the Moodle Docs wiki, similar to [[Grades]].  Your page should outline the database table design, the GUI, the hows and whys etc.  Include as much detail as you need (even mock screenshots) but try to keep it clear and logically organised.&lt;br /&gt;
&lt;br /&gt;
====Seek and absorb community feedback====&lt;br /&gt;
Post about the new page in the appropriate forums on [http://moodle.org/course/view.php?id=5 Using Moodle] to help draw attention to it and to stimulate some discussion around your development.  The more feedback you have the better, especially if it includes a wide variety of users (developers, teachers, students etc).&lt;br /&gt;
&lt;br /&gt;
Edit your page in response to the feedback, or invite people to do so themselves.  try to evolve the specification into something that all users are happy with.   Sometimes it&#039;s worth working harder to find the &amp;quot;best&amp;quot; way to do something without adding Yet Another Option.&lt;br /&gt;
&lt;br /&gt;
====Set up tasks in the Moodle Tracker====&lt;br /&gt;
Once the specification has settled down, it&#039;s time to start work.  Create a new task for yourself in the Moodle Tracker, and add sub-tasks in roughly chronological order for all the different parts of the job.   This not only helps you keep track of where you are, but allows the community to &amp;quot;watch you&amp;quot; develop and to help you where they can.  If there are different people working on different parts, you can assign subtasks to different people.  It&#039;s really very convenient to use once you get the hang of it.&lt;br /&gt;
&lt;br /&gt;
====Use CVS and link commits to Tracker====&lt;br /&gt;
If possible, develop the code in an open code repository (and preferably Moodle CVS!).  If you need CVS write access to the core code or the contrib repository, contact support@moodle.com with details.   Gaining access to the main core code is quite difficult, but we are generally very free with access to the contrib area.&lt;br /&gt;
&lt;br /&gt;
Every time you make a commit, include a detailed message about the new code and always include a Moodle Tracker bug number (e.g. MDL-7777).  This will ensure that the Moodle Tracker is able to detect your commit and attach it to the relevant bug report.&lt;br /&gt;
&lt;br /&gt;
====Comment on milestones in forums and tracker====&lt;br /&gt;
If you hit a major milestone, or want testers to try something, feel free to post about it in the relevant forum on Using Moodle.  The more people you can attract to look and try out your code the better it will be, trust me.&lt;br /&gt;
&lt;br /&gt;
====Respond to bug reports====&lt;br /&gt;
Of course you need to listen to your users (well, most of them :-)).  Encourage people to file bugs, and fix them.  If you need help setting up a project category in the Tracker contact support@moodle.com.  This will ensure that all your bugs are easy to find and to track.&lt;br /&gt;
&lt;br /&gt;
===Minor Development=== &lt;br /&gt;
&lt;br /&gt;
For smaller modules, fixes, improvements and other issues.&lt;br /&gt;
&lt;br /&gt;
====Create a new issue in the tracker====&lt;br /&gt;
&lt;br /&gt;
You should definitely create an issue in the tracker to describe your development and to act as a focus point for all discussion.  You can reference the bug number from forum discussions and in commit messages etc.  This way everyone can easily find out exactly what they are talking about.&lt;br /&gt;
&lt;br /&gt;
====Attach a patch====&lt;br /&gt;
&lt;br /&gt;
If you have some code, please attach it to the tracker issue, or if it&#039;s on your own site then link to it from the tracker issue.  Don&#039;t attach code in the Moodle forums ... it will &amp;quot;rot&amp;quot; quickly there and just clogs up moodle.org with useless old code.&lt;br /&gt;
&lt;br /&gt;
====Promote the patch====&lt;br /&gt;
&lt;br /&gt;
By all means draw attention to your work in the Moodle forums (mentioning the bug number) or email developers directly to help make them aware of it.  You can also add developers as &amp;quot;watchers&amp;quot; to the tracker issue if you want, this means they will get email for every change on the issue.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Finding your way into the Moodle code]]&lt;br /&gt;
* [[Working with the Community]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Overview]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8396</id>
		<title>HTML editor 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8396"/>
		<updated>2008-05-06T09:40:20Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page details the specification of the HTML editor in Moodle 2.0.&lt;br /&gt;
== What we want ==&lt;br /&gt;
Ticket MDL-11113 discusses most issues.&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Integration - With Moodle (smileys, different formats, etc.) with a minimum of changes, cleaning up current code as much as possible&lt;br /&gt;
* Compatibility - With web browsers (mostly FF, IE, Safari, Opera)&lt;br /&gt;
* Standard - Outputs valid XHTML code&lt;br /&gt;
* Accessibility - Is it 100% keyboard accessible? Is it usable in JAWS? Etc.&lt;br /&gt;
* Configurability - Possibility to make it show different options and buttons according to the user, the context, etc.&lt;br /&gt;
* Support - Developed by an active community that will support it for a long time.&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
Some features that should be evaluated:&lt;br /&gt;
* Handling of Word documents&lt;br /&gt;
* HTML code direct editing&lt;br /&gt;
* Highlighting (not text background color, with &amp;quot;set-on&amp;quot; operation--Word style)&lt;br /&gt;
* Image uploading&lt;br /&gt;
* Mathematical formulas/equation editing&lt;br /&gt;
* Possible to turn it on and off on demand (on the page) without losing (possibly modified) content (see [http://wiki.moxiecode.com/examples/tinymce/installation_example_07.php this TinyMCE example of this])&lt;br /&gt;
* Right-to-left text input&lt;br /&gt;
* Smileys (has to be possible to use the Moodle list of smileys)&lt;br /&gt;
* Special characters&lt;br /&gt;
* Tables&lt;br /&gt;
* Themeable (possible to make a theme that fits with Moodle&#039;s)&lt;br /&gt;
&lt;br /&gt;
=== Wishes ===&lt;br /&gt;
* Make it possible to change to a different editor (provided someone comes up with the necessary code to &amp;quot;plug it&amp;quot; in Moodle)&lt;br /&gt;
* Possible to run many instances on the same page (see MDL-11101 in tracker)&lt;br /&gt;
* Fix [http://tracker.moodle.org/secure/IssueNavigator.jspa?reset=true&amp;amp;pid=10011&amp;amp;resolution=-1&amp;amp;component=10070&amp;amp;sorter/field=summary&amp;amp;sorter/order=ASC&amp;amp;sorter/field=resolution&amp;amp;sorter/order=ASC&amp;amp;sorter/field=status&amp;amp;sorter/order=ASC&amp;amp;sorter/field=priority&amp;amp;sorter/order=DESC all the bugs] related to the HTML editor&lt;br /&gt;
* Submit drafts in the background, using ajax.&lt;br /&gt;
&lt;br /&gt;
== Possibilities and evaluation ==&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Comparison_of_WYSIWYG_HTML_editors Comparison of WYSIWYG HTML editors on Wikipedia]&lt;br /&gt;
* [http://tinymce.moxiecode.com/ TinyMCE]: [http://wiki.moxiecode.com/index.php/TinyMCE:Compatibility Compatibility], [http://wiki.moxiecode.com/index.php/TinyMCE:Index Documentation], [http://tinymce.moxiecode.com/example_full.php?example=true Demo]&lt;br /&gt;
* [http://www.fckeditor.net/ FCKeditor]: [http://docs.fckeditor.net/FCKeditor_3.x/Design_and_Architecture/Browsers_Compatibility Compatibility] [http://docs.fckeditor.net/ Documentation], [http://www.fckeditor.net/demo Demo]&lt;br /&gt;
* [http://xinha.webfactional.com/ Xinha]: [http://xinha.webfactional.com/wiki/Documentation Documentation], [http://xinha.webfactional.com/wiki/Examples Demo]&lt;br /&gt;
* [http://developer.yahoo.com/yui/editor/ Yahoo RTE]: [http://developer.yahoo.com/yui/docs/module_editor.html Documentation], [http://developer.yahoo.com/yui/examples/editor/index.html Demo], &lt;br /&gt;
As of 16 April 2008, the preference goes to TinyMCE.&lt;br /&gt;
&lt;br /&gt;
== Plan of action ==&lt;br /&gt;
* Get code in HEAD before 13 May 2008 so that work can be done there&lt;br /&gt;
* Have the XHTML profile active by default in TinyMCE&lt;br /&gt;
&lt;br /&gt;
=== Change in formats ===&lt;br /&gt;
&lt;br /&gt;
This is actually more a related issue... There is a [[http://tracker.moodle.org/browse/MDL-4868 | long-standing bug]] about Markdown not being converted to HTML when using the HTML editor (after creating a post with Markdown). As the HTML editor becomes available on more browsers (and being more stable), most people will probably want to use it instead of Markdown, so we should solve this bug, by properly converting the Markdown text to HTML, the first time it is displayed in the editor.&lt;br /&gt;
&lt;br /&gt;
=== Plugins to write ===&lt;br /&gt;
Some plugins will have to be written for each editor to make integration with Moodle possible.  These should be as abstracted as possible, to make as much code as possible common between each&lt;br /&gt;
* Language files: Moodle has a lot more languages than any editors, and some strings will be Moodle-specific.  We need a way to make the editors use Moodle strings&lt;br /&gt;
* File browser: the file browser (especially with the [[Repository API]]) will be Moodle specific&lt;br /&gt;
* Emoticons (smileys): Moodle defines it&#039;s own list of emoticons, we need to make a plugin to use them&lt;br /&gt;
* Equation editor: there is [[DragMath_equation_editor| ongoing work]] to get [http://www.dragmath.bham.ac.uk/ Dragmath] working in Moodle, making a common plugin could be a nice improvement&lt;br /&gt;
* It may be possible to use Moodle&#039;s CSS files to define editors themes/skins, this needs investigation&lt;br /&gt;
&lt;br /&gt;
== Links to forum discussions, tracker, docs, etc. ==&lt;br /&gt;
* [http://tracker.moodle.org/browse/MDL-11113 MDL-11113 - Get a fully working HTML editor in Moodle]&lt;br /&gt;
* [[Moodle-specific customisations to the HTML editor]]&lt;br /&gt;
&lt;br /&gt;
Using Moodle General developer forum discussions:&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=88382 TinyMCE3 Integration]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=93475 XINHA has started to support Opera and Safari]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=76912 What is the current position with the HTML editor?]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=96160 The most important decision on editor integration]&lt;br /&gt;
&lt;br /&gt;
[[Category:HTML editor]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8395</id>
		<title>HTML editor 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8395"/>
		<updated>2008-05-06T09:08:45Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page details the specification of the HTML editor in Moodle 2.0.&lt;br /&gt;
== What we want ==&lt;br /&gt;
Ticket MDL-11113 discusses most issues.&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Integration - With Moodle (smileys, different formats, etc.) with a minimum of changes, cleaning up current code as much as possible&lt;br /&gt;
* Compatibility - With web browsers (mostly FF, IE, Safari, Opera)&lt;br /&gt;
* Standard - Outputs valid XHTML code&lt;br /&gt;
* Accessibility - Is it 100% keyboard accessible? Is it usable in JAWS? Etc.&lt;br /&gt;
* Configurability - Possibility to make it show different options and buttons according to the user, the context, etc.&lt;br /&gt;
* Support - Developed by an active community that will support it for a long time.&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
Some features that should be evaluated:&lt;br /&gt;
* Handling of Word documents&lt;br /&gt;
* HTML code direct editing&lt;br /&gt;
* Highlighting (not text background color, with &amp;quot;set-on&amp;quot; operation--Word style)&lt;br /&gt;
* Image uploading&lt;br /&gt;
* Mathematical formulas/equation editing&lt;br /&gt;
* Possible to turn it on and off on demand (on the page) without losing (possibly modified) content (see [http://wiki.moxiecode.com/examples/tinymce/installation_example_07.php this TinyMCE example of this])&lt;br /&gt;
* Right-to-left text input&lt;br /&gt;
* Smileys (has to be possible to use the Moodle list of smileys)&lt;br /&gt;
* Special characters&lt;br /&gt;
* Tables&lt;br /&gt;
* Themeable (possible to make a theme that fits with Moodle&#039;s)&lt;br /&gt;
&lt;br /&gt;
=== Wishes ===&lt;br /&gt;
* Make it possible to change to a different editor (provided someone comes up with the necessary code to &amp;quot;plug it&amp;quot; in Moodle)&lt;br /&gt;
* Possible to run many instances on the same page (see MDL-11101 in tracker)&lt;br /&gt;
* Fix [http://tracker.moodle.org/secure/IssueNavigator.jspa?reset=true&amp;amp;pid=10011&amp;amp;resolution=-1&amp;amp;component=10070&amp;amp;sorter/field=summary&amp;amp;sorter/order=ASC&amp;amp;sorter/field=resolution&amp;amp;sorter/order=ASC&amp;amp;sorter/field=status&amp;amp;sorter/order=ASC&amp;amp;sorter/field=priority&amp;amp;sorter/order=DESC all the bugs] related to the HTML editor&lt;br /&gt;
* Submit drafts in the background, using ajax.&lt;br /&gt;
&lt;br /&gt;
== Possibilities and evaluation ==&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Comparison_of_WYSIWYG_HTML_editors Comparison of WYSIWYG HTML editors on Wikipedia]&lt;br /&gt;
* [http://tinymce.moxiecode.com/ TinyMCE]: [http://wiki.moxiecode.com/index.php/TinyMCE:Compatibility Compatibility], [http://wiki.moxiecode.com/index.php/TinyMCE:Index Documentation], [http://tinymce.moxiecode.com/example_full.php?example=true Demo]&lt;br /&gt;
* [http://www.fckeditor.net/ FCKeditor]: [http://docs.fckeditor.net/FCKeditor_3.x/Design_and_Architecture/Browsers_Compatibility Compatibility] [http://docs.fckeditor.net/ Documentation], [http://www.fckeditor.net/demo Demo]&lt;br /&gt;
* [http://xinha.webfactional.com/ Xinha]: [http://xinha.webfactional.com/wiki/Documentation Documentation], [http://xinha.webfactional.com/wiki/Examples Demo]&lt;br /&gt;
* [http://developer.yahoo.com/yui/editor/ Yahoo RTE]: [http://developer.yahoo.com/yui/docs/module_editor.html Documentation], [http://developer.yahoo.com/yui/examples/editor/index.html Demo], &lt;br /&gt;
As of 16 April 2008, the preference goes to TinyMCE.&lt;br /&gt;
&lt;br /&gt;
== Plan of action ==&lt;br /&gt;
* Get code in HEAD before 13 May 2008 so that work can be done there&lt;br /&gt;
* Have the XHTML profile active by default in TinyMCE&lt;br /&gt;
&lt;br /&gt;
=== Problems &amp;amp; Solutions ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Plugins to write ===&lt;br /&gt;
Some plugins will have to be written for each editor to make integration with Moodle possible.  These should be as abstracted as possible, to make as much code as possible common between each&lt;br /&gt;
* Language files: Moodle has a lot more languages than any editors, and some strings will be Moodle-specific.  We need a way to make the editors use Moodle strings&lt;br /&gt;
* File browser: the file browser (especially with the [[Repository API]]) will be Moodle specific&lt;br /&gt;
* Emoticons (smileys): Moodle defines it&#039;s own list of emoticons, we need to make a plugin to use them&lt;br /&gt;
* Equation editor: there is [[DragMath_equation_editor| ongoing work]] to get [http://www.dragmath.bham.ac.uk/ Dragmath] working in Moodle, making a common plugin could be a nice improvement&lt;br /&gt;
* It may be possible to use Moodle&#039;s CSS files to define editors themes/skins, this needs investigation&lt;br /&gt;
&lt;br /&gt;
== Links to forum discussions, tracker, docs, etc. ==&lt;br /&gt;
* [http://tracker.moodle.org/browse/MDL-11113 MDL-11113 - Get a fully working HTML editor in Moodle]&lt;br /&gt;
* [[Moodle-specific customisations to the HTML editor]]&lt;br /&gt;
&lt;br /&gt;
Using Moodle General developer forum discussions:&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=88382 TinyMCE3 Integration]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=93475 XINHA has started to support Opera and Safari]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=76912 What is the current position with the HTML editor?]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=96160 The most important decision on editor integration]&lt;br /&gt;
&lt;br /&gt;
[[Category:HTML editor]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8394</id>
		<title>HTML editor 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8394"/>
		<updated>2008-05-05T08:26:08Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: /* Wishes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page details the specification of the HTML editor in Moodle 2.0.&lt;br /&gt;
== What we want ==&lt;br /&gt;
Ticket MDL-11113 discusses most issues.&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Integration - With Moodle (smileys, different formats, etc.) with a minimum of changes, cleaning up current code as much as possible&lt;br /&gt;
* Compatibility - With web browsers (mostly FF, IE, Safari, Opera)&lt;br /&gt;
* Standard - Outputs valid XHTML code&lt;br /&gt;
* Accessibility - Is it 100% keyboard accessible? Is it usable in JAWS? Etc.&lt;br /&gt;
* Configurability - Possibility to make it show different options and buttons according to the user, the context, etc.&lt;br /&gt;
* Support - Developed by an active community that will support it for a long time.&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
Some features that should be evaluated:&lt;br /&gt;
* Handling of Word documents&lt;br /&gt;
* HTML code direct editing&lt;br /&gt;
* Highlighting (not text background color, with &amp;quot;set-on&amp;quot; operation--Word style)&lt;br /&gt;
* Image uploading&lt;br /&gt;
* Mathematical formulas/equation editing&lt;br /&gt;
* Possible to turn it on and off on demand (on the page) without losing (modified) content&lt;br /&gt;
* Right-to-left text input&lt;br /&gt;
* Smileys (has to be possible to use the Moodle list of smileys)&lt;br /&gt;
* Special characters&lt;br /&gt;
* Tables&lt;br /&gt;
* Themeable (possible to make a theme that fits with Moodle&#039;s)&lt;br /&gt;
&lt;br /&gt;
=== Wishes ===&lt;br /&gt;
* Make it possible to change to a different editor (provided someone comes up with the necessary code to &amp;quot;plug it&amp;quot; in Moodle)&lt;br /&gt;
* Possible to run many instances on the same page (see MDL-11101 in tracker)&lt;br /&gt;
* Fix [http://tracker.moodle.org/secure/IssueNavigator.jspa?reset=true&amp;amp;pid=10011&amp;amp;resolution=-1&amp;amp;component=10070&amp;amp;sorter/field=summary&amp;amp;sorter/order=ASC&amp;amp;sorter/field=resolution&amp;amp;sorter/order=ASC&amp;amp;sorter/field=status&amp;amp;sorter/order=ASC&amp;amp;sorter/field=priority&amp;amp;sorter/order=DESC all the bugs] related to the HTML editor&lt;br /&gt;
* Submit drafts in the background, using ajax.&lt;br /&gt;
&lt;br /&gt;
== Possibilities and evaluation ==&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Comparison_of_WYSIWYG_HTML_editors Comparison of WYSIWYG HTML editors on Wikipedia]&lt;br /&gt;
* [http://tinymce.moxiecode.com/ TinyMCE]: [http://wiki.moxiecode.com/index.php/TinyMCE:Compatibility Compatibility], [http://wiki.moxiecode.com/index.php/TinyMCE:Index Documentation], [http://tinymce.moxiecode.com/example_full.php?example=true Demo]&lt;br /&gt;
* [http://www.fckeditor.net/ FCKeditor]: [http://docs.fckeditor.net/FCKeditor_3.x/Design_and_Architecture/Browsers_Compatibility Compatibility] [http://docs.fckeditor.net/ Documentation], [http://www.fckeditor.net/demo Demo]&lt;br /&gt;
* [http://xinha.webfactional.com/ Xinha]: [http://xinha.webfactional.com/wiki/Documentation Documentation], [http://xinha.webfactional.com/wiki/Examples Demo]&lt;br /&gt;
* [http://developer.yahoo.com/yui/editor/ Yahoo RTE]: [http://developer.yahoo.com/yui/docs/module_editor.html Documentation], [http://developer.yahoo.com/yui/examples/editor/index.html Demo], &lt;br /&gt;
As of 16 April 2008, the preference goes to TinyMCE.&lt;br /&gt;
&lt;br /&gt;
== Links to forum discussions, tracker, docs, etc. ==&lt;br /&gt;
&lt;br /&gt;
* [http://tracker.moodle.org/browse/MDL-11113 MDL-11113 - Get a fully working HTML editor in Moodle]&lt;br /&gt;
* [[Moodle-specific customisations to the HTML editor]]&lt;br /&gt;
&lt;br /&gt;
Using Moodle General developer forum discussions:&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=88382 TinyMCE3 Integration]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=93475 XINHA has started to support Opera and Safari]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=76912 What is the current position with the HTML editor?]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=96160 The most important decision on editor integration]&lt;br /&gt;
&lt;br /&gt;
[[Category:HTML editor]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8392</id>
		<title>HTML editor 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8392"/>
		<updated>2008-04-24T03:42:31Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: /* Requirements */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page details the specification of the HTML editor in Moodle 2.0.&lt;br /&gt;
== What we want ==&lt;br /&gt;
Ticket MDL-11113 discusses most issues.&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Integration - With Moodle (smileys, different formats, etc.) with a minimum of changes, cleaning up current code as much as possible&lt;br /&gt;
* Compatibility - With web browsers (mostly FF, IE, Safari, Opera)&lt;br /&gt;
* Standard - Outputs valid XHTML code&lt;br /&gt;
* Accessibility - Is it 100% keyboard accessible? Is it usable in JAWS? Etc.&lt;br /&gt;
* Configurability - Possibility to make it show different options and buttons according to the user, the context, etc.&lt;br /&gt;
* Support - Developed by an active community that will support it for a long time.&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
Some features that should be evaluated:&lt;br /&gt;
* Handling of Word documents&lt;br /&gt;
* HTML code direct editing&lt;br /&gt;
* Highlighting (not text background color, with &amp;quot;set-on&amp;quot; operation--Word style)&lt;br /&gt;
* Image uploading&lt;br /&gt;
* Mathematical formulas/equation editing&lt;br /&gt;
* Possible to turn it on and off on demand (on the page) without losing (modified) content&lt;br /&gt;
* Right-to-left text input&lt;br /&gt;
* Smileys (has to be possible to use the Moodle list of smileys)&lt;br /&gt;
* Special characters&lt;br /&gt;
* Tables&lt;br /&gt;
* Themeable (possible to make a theme that fits with Moodle&#039;s)&lt;br /&gt;
&lt;br /&gt;
=== Wishes ===&lt;br /&gt;
* Make it possible to change to a different editor (provided someone comes up with the necessary code to &amp;quot;plug it&amp;quot; in Moodle)&lt;br /&gt;
* Possible to run many instances on the same page (see MDL-11101 in tracker)&lt;br /&gt;
* Fix [http://tracker.moodle.org/secure/IssueNavigator.jspa?reset=true&amp;amp;pid=10011&amp;amp;resolution=-1&amp;amp;component=10070&amp;amp;sorter/field=summary&amp;amp;sorter/order=ASC&amp;amp;sorter/field=resolution&amp;amp;sorter/order=ASC&amp;amp;sorter/field=status&amp;amp;sorter/order=ASC&amp;amp;sorter/field=priority&amp;amp;sorter/order=DESC all the bugs] related to the HTML editor&lt;br /&gt;
== Possibilities and evaluation ==&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Comparison_of_WYSIWYG_HTML_editors Comparison of WYSIWYG HTML editors on Wikipedia]&lt;br /&gt;
* [http://tinymce.moxiecode.com/ TinyMCE]: [http://wiki.moxiecode.com/index.php/TinyMCE:Compatibility Compatibility], [http://wiki.moxiecode.com/index.php/TinyMCE:Index Documentation], [http://tinymce.moxiecode.com/example_full.php?example=true Demo]&lt;br /&gt;
* [http://www.fckeditor.net/ FCKeditor]: [http://docs.fckeditor.net/FCKeditor_3.x/Design_and_Architecture/Browsers_Compatibility Compatibility] [http://docs.fckeditor.net/ Documentation], [http://www.fckeditor.net/demo Demo]&lt;br /&gt;
* [http://xinha.webfactional.com/ Xinha]: [http://xinha.webfactional.com/wiki/Documentation Documentation], [http://xinha.webfactional.com/wiki/Examples Demo]&lt;br /&gt;
* [http://developer.yahoo.com/yui/editor/ Yahoo RTE]: [http://developer.yahoo.com/yui/docs/module_editor.html Documentation], [http://developer.yahoo.com/yui/examples/editor/index.html Demo], &lt;br /&gt;
As of 16 April 2008, the preference goes to TinyMCE.&lt;br /&gt;
== Links to forum discussions, tracker, docs, etc. ==&lt;br /&gt;
* [http://tracker.moodle.org/browse/MDL-11113 MDL-11113 - Get a fully working HTML editor in Moodle]&lt;br /&gt;
* [[Moodle-specific_customisations_to_the_HTML_editor]]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=88382 Using Moodle - General developer forum: TinyMCE3 Integration]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=93475 Using Moodle - General developer forum: XINHA has started to support Opera and Safari]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=76912 Using Moodle - General developer forum: What is the current position with the HTML editor?]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8389</id>
		<title>HTML editor 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8389"/>
		<updated>2008-04-16T06:21:06Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: /* Requirements */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page details the specification of the HTML editor in Moodle 2.0.&lt;br /&gt;
== What we want ==&lt;br /&gt;
Ticket MDL-11113 discusses most issues.&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Integration - With Moodle (smileys, different formats, etc.) with a minimum of changes, cleaning up current code as much as possible&lt;br /&gt;
* Compatibility - With web browsers (mostly FF, IE, Safari, Opera)&lt;br /&gt;
* Standard - Outputs valid XHTML code&lt;br /&gt;
* Accessibility - Is it 100% keyboard accessible? Is it usable in JAWS? Etc.&lt;br /&gt;
* Configurability - Possibility to make it show different options and buttons according to the user, the context, etc.&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
Some features that should be evaluated:&lt;br /&gt;
* Handling of Word documents&lt;br /&gt;
* HTML code direct editing&lt;br /&gt;
* Image uploading&lt;br /&gt;
* Mathematical formulas/equation editing&lt;br /&gt;
* Possible to turn it on and off on demand (on the page) without losing (modified) content&lt;br /&gt;
* Right-to-left text input&lt;br /&gt;
* Smileys (has to be possible to use the Moodle list of smileys)&lt;br /&gt;
* Special characters&lt;br /&gt;
* Tables&lt;br /&gt;
* Themeable (possible to make a theme that fits with Moodle&#039;s)&lt;br /&gt;
=== Wishes ===&lt;br /&gt;
* Make it possible to change to a different editor (provided someone comes up with the necessary code to &amp;quot;plug it&amp;quot; in Moodle)&lt;br /&gt;
* Possible to run many instances on the same page (see MDL-11101 in tracker)&lt;br /&gt;
* Fix [http://tracker.moodle.org/secure/IssueNavigator.jspa?reset=true&amp;amp;pid=10011&amp;amp;resolution=-1&amp;amp;component=10070&amp;amp;sorter/field=summary&amp;amp;sorter/order=ASC&amp;amp;sorter/field=resolution&amp;amp;sorter/order=ASC&amp;amp;sorter/field=status&amp;amp;sorter/order=ASC&amp;amp;sorter/field=priority&amp;amp;sorter/order=DESC all the bugs] related to the HTML editor&lt;br /&gt;
== Possibilities and evaluation ==&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Comparison_of_WYSIWYG_HTML_editors Comparison of WYSIWYG HTML editors on Wikipedia]&lt;br /&gt;
* [http://tinymce.moxiecode.com/ TinyMCE]: [http://wiki.moxiecode.com/index.php/TinyMCE:Compatibility Compatibility], [http://wiki.moxiecode.com/index.php/TinyMCE:Index Documentation], [http://tinymce.moxiecode.com/example_full.php?example=true Demo]&lt;br /&gt;
* [http://www.fckeditor.net/ FCKeditor]: [http://docs.fckeditor.net/FCKeditor_3.x/Design_and_Architecture/Browsers_Compatibility Compatibility] [http://docs.fckeditor.net/ Documentation], [http://www.fckeditor.net/demo Demo]&lt;br /&gt;
* [http://xinha.webfactional.com/ Xinha]: [http://xinha.webfactional.com/wiki/Documentation Documentation], [http://xinha.webfactional.com/wiki/Examples Demo]&lt;br /&gt;
* [http://developer.yahoo.com/yui/editor/ Yahoo RTE]: [http://developer.yahoo.com/yui/docs/module_editor.html Documentation], [http://developer.yahoo.com/yui/examples/editor/index.html Demo], &lt;br /&gt;
As of 16 April 2008, the preference goes to TinyMCE.&lt;br /&gt;
== Links to forum discussions, tracker, docs, etc. ==&lt;br /&gt;
* [http://tracker.moodle.org/browse/MDL-11113 MDL-11113 - Get a fully working HTML editor in Moodle]&lt;br /&gt;
* [[Moodle-specific_customisations_to_the_HTML_editor]]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=88382 Using Moodle - General developer forum: TinyMCE3 Integration]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=93475 Using Moodle - General developer forum: XINHA has started to support Opera and Safari]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=76912 Using Moodle - General developer forum: What is the current position with the HTML editor?]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8388</id>
		<title>HTML editor 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8388"/>
		<updated>2008-04-16T06:19:03Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page details the specification of the HTML editor in Moodle 2.0.&lt;br /&gt;
== What we want ==&lt;br /&gt;
Ticket MDL-11113 discusses most issues.&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Integration - With Moodle (smileys, different formats, etc.) with a minimum of changes&lt;br /&gt;
* Compatibility - With web browsers (mostly FF, IE, Safari, Opera)&lt;br /&gt;
* Standard - Outputs valid XHTML code&lt;br /&gt;
* Accessibility - Is it 100% keyboard accessible? Is it usable in JAWS? Etc.&lt;br /&gt;
* Configurability - Possibility to make it show different options and buttons according to the user, the context, etc.&lt;br /&gt;
=== Features ===&lt;br /&gt;
Some features that should be evaluated:&lt;br /&gt;
* Handling of Word documents&lt;br /&gt;
* HTML code direct editing&lt;br /&gt;
* Image uploading&lt;br /&gt;
* Mathematical formulas/equation editing&lt;br /&gt;
* Possible to turn it on and off on demand (on the page) without losing (modified) content&lt;br /&gt;
* Right-to-left text input&lt;br /&gt;
* Smileys (has to be possible to use the Moodle list of smileys)&lt;br /&gt;
* Special characters&lt;br /&gt;
* Tables&lt;br /&gt;
* Themeable (possible to make a theme that fits with Moodle&#039;s)&lt;br /&gt;
=== Wishes ===&lt;br /&gt;
* Make it possible to change to a different editor (provided someone comes up with the necessary code to &amp;quot;plug it&amp;quot; in Moodle)&lt;br /&gt;
* Possible to run many instances on the same page (see MDL-11101 in tracker)&lt;br /&gt;
* Fix [http://tracker.moodle.org/secure/IssueNavigator.jspa?reset=true&amp;amp;pid=10011&amp;amp;resolution=-1&amp;amp;component=10070&amp;amp;sorter/field=summary&amp;amp;sorter/order=ASC&amp;amp;sorter/field=resolution&amp;amp;sorter/order=ASC&amp;amp;sorter/field=status&amp;amp;sorter/order=ASC&amp;amp;sorter/field=priority&amp;amp;sorter/order=DESC all the bugs] related to the HTML editor&lt;br /&gt;
== Possibilities and evaluation ==&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Comparison_of_WYSIWYG_HTML_editors Comparison of WYSIWYG HTML editors on Wikipedia]&lt;br /&gt;
* [http://tinymce.moxiecode.com/ TinyMCE]: [http://wiki.moxiecode.com/index.php/TinyMCE:Compatibility Compatibility], [http://wiki.moxiecode.com/index.php/TinyMCE:Index Documentation], [http://tinymce.moxiecode.com/example_full.php?example=true Demo]&lt;br /&gt;
* [http://www.fckeditor.net/ FCKeditor]: [http://docs.fckeditor.net/FCKeditor_3.x/Design_and_Architecture/Browsers_Compatibility Compatibility] [http://docs.fckeditor.net/ Documentation], [http://www.fckeditor.net/demo Demo]&lt;br /&gt;
* [http://xinha.webfactional.com/ Xinha]: [http://xinha.webfactional.com/wiki/Documentation Documentation], [http://xinha.webfactional.com/wiki/Examples Demo]&lt;br /&gt;
* [http://developer.yahoo.com/yui/editor/ Yahoo RTE]: [http://developer.yahoo.com/yui/docs/module_editor.html Documentation], [http://developer.yahoo.com/yui/examples/editor/index.html Demo], &lt;br /&gt;
As of 16 April 2008, the preference goes to TinyMCE.&lt;br /&gt;
== Links to forum discussions, tracker, docs, etc. ==&lt;br /&gt;
* [http://tracker.moodle.org/browse/MDL-11113 MDL-11113 - Get a fully working HTML editor in Moodle]&lt;br /&gt;
* [[Moodle-specific_customisations_to_the_HTML_editor]]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=88382 Using Moodle - General developer forum: TinyMCE3 Integration]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=93475 Using Moodle - General developer forum: XINHA has started to support Opera and Safari]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=76912 Using Moodle - General developer forum: What is the current position with the HTML editor?]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8387</id>
		<title>HTML editor 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8387"/>
		<updated>2008-04-16T05:44:32Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: /* Links to forum discussions, tracker, docs, etc. */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page details the specification of the HTML editor in Moodle 2.0.&lt;br /&gt;
&lt;br /&gt;
== What we want ==&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Integration - With Moodle (smileys, different formats, etc.) with a minimum of changes&lt;br /&gt;
* Compatibility - With web browsers (mostly FF, IE, Safari, Opera)&lt;br /&gt;
* Standard - Outputs valid XHTML code&lt;br /&gt;
* Accessibility - Is it 100% keyboard accessible? Is it usable in JAWS? Etc.&lt;br /&gt;
* Configurability - Possibility to make it show different options and buttons according to the user, the context, etc.&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
Some features that should be evaluated:&lt;br /&gt;
* Handling of Word documents&lt;br /&gt;
* HTML code direct editing&lt;br /&gt;
* Image uploading&lt;br /&gt;
* Mathematical formulas editing&lt;br /&gt;
* Possible to turn it on and off on demand (on the page) without losing (modified) content&lt;br /&gt;
* Right-to-left text input&lt;br /&gt;
* Smileys (has to be possible to use the Moodle list of smileys)&lt;br /&gt;
* Special characters&lt;br /&gt;
* Tables&lt;br /&gt;
* Themeable (possible to make a theme that fits with Moodle&#039;s)&lt;br /&gt;
&lt;br /&gt;
Ticket MDL-11113 discusses most issues.&lt;br /&gt;
&lt;br /&gt;
== Possibilities and evaluation ==&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Comparison_of_WYSIWYG_HTML_editors Comparison of WYSIWYG HTML editors on Wikipedia]&lt;br /&gt;
* [http://tinymce.moxiecode.com/ TinyMCE]: [http://wiki.moxiecode.com/index.php/TinyMCE:Compatibility Compatibility], [http://wiki.moxiecode.com/index.php/TinyMCE:Index Documentation], [http://tinymce.moxiecode.com/example_full.php?example=true Demo]&lt;br /&gt;
* [http://www.fckeditor.net/ FCKeditor]: [http://docs.fckeditor.net/FCKeditor_3.x/Design_and_Architecture/Browsers_Compatibility Compatibility] [http://docs.fckeditor.net/ Documentation], [http://www.fckeditor.net/demo Demo]&lt;br /&gt;
* [http://xinha.webfactional.com/ Xinha]: [http://xinha.webfactional.com/wiki/Documentation Documentation], [http://xinha.webfactional.com/wiki/Examples Demo]&lt;br /&gt;
* [http://developer.yahoo.com/yui/editor/ Yahoo RTE]: [http://developer.yahoo.com/yui/docs/module_editor.html Documentation], [http://developer.yahoo.com/yui/examples/editor/index.html Demo], &lt;br /&gt;
&lt;br /&gt;
As of 16 April 2008, the preference goes to TinyMCE.&lt;br /&gt;
&lt;br /&gt;
== Links to forum discussions, tracker, docs, etc. ==&lt;br /&gt;
* [http://tracker.moodle.org/browse/MDL-11113 MDL-11113 - Get a fully working HTML editor in Moodle]&lt;br /&gt;
* [[Moodle-specific_customisations_to_the_HTML_editor]]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=76912 Using Moodle - General developer forum: What is the current position with the HTML editor?]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=93475 Using Moodle - General developer forum: XINHA has started to support Opera and Safari]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=88382 Using Moodle - General developer forum: TinyMCE3 Integration]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8386</id>
		<title>HTML editor 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8386"/>
		<updated>2008-04-16T04:34:29Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page details the specification of the HTML editor in Moodle 2.0.&lt;br /&gt;
&lt;br /&gt;
== What we want ==&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Integration - With Moodle (smileys, different formats, etc.) with a minimum of changes&lt;br /&gt;
* Compatibility - With web browsers (mostly FF, IE, Safari, Opera)&lt;br /&gt;
* Standard - Outputs valid XHTML code&lt;br /&gt;
* Accessibility - Is it 100% keyboard accessible? Is it usable in JAWS? Etc.&lt;br /&gt;
* Configurability - Possibility to make it show different options and buttons according to the user, the context, etc.&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
Some features that should be evaluated:&lt;br /&gt;
* Handling of Word documents&lt;br /&gt;
* HTML code direct editing&lt;br /&gt;
* Image uploading&lt;br /&gt;
* Mathematical formulas editing&lt;br /&gt;
* Possible to turn it on and off on demand (on the page) without losing (modified) content&lt;br /&gt;
* Right-to-left text input&lt;br /&gt;
* Smileys (has to be possible to use the Moodle list of smileys)&lt;br /&gt;
* Special characters&lt;br /&gt;
* Tables&lt;br /&gt;
* Themeable (possible to make a theme that fits with Moodle&#039;s)&lt;br /&gt;
&lt;br /&gt;
Ticket MDL-11113 discusses most issues.&lt;br /&gt;
&lt;br /&gt;
== Possibilities and evaluation ==&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Comparison_of_WYSIWYG_HTML_editors Comparison of WYSIWYG HTML editors on Wikipedia]&lt;br /&gt;
* [http://tinymce.moxiecode.com/ TinyMCE]: [http://wiki.moxiecode.com/index.php/TinyMCE:Compatibility Compatibility], [http://wiki.moxiecode.com/index.php/TinyMCE:Index Documentation], [http://tinymce.moxiecode.com/example_full.php?example=true Demo]&lt;br /&gt;
* [http://www.fckeditor.net/ FCKeditor]: [http://docs.fckeditor.net/FCKeditor_3.x/Design_and_Architecture/Browsers_Compatibility Compatibility] [http://docs.fckeditor.net/ Documentation], [http://www.fckeditor.net/demo Demo]&lt;br /&gt;
* [http://xinha.webfactional.com/ Xinha]: [http://xinha.webfactional.com/wiki/Documentation Documentation], [http://xinha.webfactional.com/wiki/Examples Demo]&lt;br /&gt;
* [http://developer.yahoo.com/yui/editor/ Yahoo RTE]: [http://developer.yahoo.com/yui/docs/module_editor.html Documentation], [http://developer.yahoo.com/yui/examples/editor/index.html Demo], &lt;br /&gt;
&lt;br /&gt;
As of 16 April 2008, the preference goes to TinyMCE.&lt;br /&gt;
&lt;br /&gt;
== Links to forum discussions, tracker, docs, etc. ==&lt;br /&gt;
* [http://tracker.moodle.org/browse/MDL-11113 MDL-11113 - Get a fully working HTML editor in Moodle]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=76912 Using Moodle: What is the current position with the HTML editor?]&lt;br /&gt;
* [[Moodle-specific_customisations_to_the_HTML_editor]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8385</id>
		<title>HTML editor 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML_editor_2.0&amp;diff=8385"/>
		<updated>2008-04-16T04:33:17Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page details the specification of the HTML editor in Moodle 2.0.&lt;br /&gt;
&lt;br /&gt;
== What we want ==&lt;br /&gt;
&lt;br /&gt;
* Integration - With Moodle (smileys, different formats, etc.) with a minimum of changes&lt;br /&gt;
* Compatibility - With web browsers (mostly FF, IE, Safari, Opera)&lt;br /&gt;
* Standard - Outputs valid XHTML code&lt;br /&gt;
* Accessibility - Is it 100% keyboard accessible? Is it usable in JAWS? Etc.&lt;br /&gt;
* Configurability - Possibility to make it show different options and buttons according to the user, the context, etc.&lt;br /&gt;
&lt;br /&gt;
Some features that should be evaluated:&lt;br /&gt;
* Handling of Word documents&lt;br /&gt;
* HTML code direct editing&lt;br /&gt;
* Image uploading&lt;br /&gt;
* Mathematical formulas editing&lt;br /&gt;
* Possible to turn it on and off on demand (on the page) without losing (modified) content&lt;br /&gt;
* Right-to-left text input&lt;br /&gt;
* Smileys (has to be possible to use the Moodle list of smileys)&lt;br /&gt;
* Special characters&lt;br /&gt;
* Tables&lt;br /&gt;
* Themeable (possible to make a theme that fits with Moodle&#039;s)&lt;br /&gt;
&lt;br /&gt;
Ticket MDL-11113 discusses most issues.&lt;br /&gt;
&lt;br /&gt;
== Possibilities and evaluation ==&lt;br /&gt;
&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Comparison_of_WYSIWYG_HTML_editors Comparison of WYSIWYG HTML editors on Wikipedia]&lt;br /&gt;
* [http://tinymce.moxiecode.com/ TinyMCE]: [http://wiki.moxiecode.com/index.php/TinyMCE:Compatibility Compatibility], [http://wiki.moxiecode.com/index.php/TinyMCE:Index Documentation], [http://tinymce.moxiecode.com/example_full.php?example=true Demo]&lt;br /&gt;
* [http://www.fckeditor.net/ FCKeditor]: [http://docs.fckeditor.net/FCKeditor_3.x/Design_and_Architecture/Browsers_Compatibility Compatibility] [http://docs.fckeditor.net/ Documentation], [http://www.fckeditor.net/demo Demo]&lt;br /&gt;
* [http://xinha.webfactional.com/ Xinha]: [http://xinha.webfactional.com/wiki/Documentation Documentation], [http://xinha.webfactional.com/wiki/Examples Demo]&lt;br /&gt;
* [http://developer.yahoo.com/yui/editor/ Yahoo RTE]: [http://developer.yahoo.com/yui/docs/module_editor.html Documentation], [http://developer.yahoo.com/yui/examples/editor/index.html Demo], &lt;br /&gt;
&lt;br /&gt;
As of 16 April 2008, the preference goes to TinyMCE.&lt;br /&gt;
&lt;br /&gt;
== Links to forum discussions, tracker, docs, etc. ==&lt;br /&gt;
* [http://tracker.moodle.org/browse/MDL-11113 MDL-11113 - Get a fully working HTML editor in Moodle]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=76912 Using Moodle: What is the current position with the HTML editor?]&lt;br /&gt;
* [[Moodle-specific_customisations_to_the_HTML_editor]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Setting_up_Eclipse&amp;diff=4957</id>
		<title>Setting up Eclipse</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Setting_up_Eclipse&amp;diff=4957"/>
		<updated>2008-04-14T04:09:51Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: /* Checking out the Moodle code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.eclipse.org/ Eclipse] is an IDE originally designed for Java, but now with plugins for many languages including PHP. It has lots of very powerful features, and it is the editor that some Moodle developers like to use. Other (more) popular choices are vim and emacs.&lt;br /&gt;
&lt;br /&gt;
However, Eclipse is not the easiest program in the world to get started with, so I&#039;m going to take you through it step by step. These instructions assume Eclipse 3.2, the current version at the time of writing. It should not change much between releases.&lt;br /&gt;
&lt;br /&gt;
This article started off as a brain-dump by [[User:Tim Hunt|Tim Hunt]]. Since then, several other people have worked through it and made corrections, so the information here should be pretty accurate.&lt;br /&gt;
&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
&lt;br /&gt;
Eclipse is written in Java, so I recommend getting the latest Java runtime environment from http://java.com/ for maximum speed and reliability.&lt;br /&gt;
&lt;br /&gt;
Eclipse is quite big, so I recommend lots of memory in your computer. I have used it on Windows, MacOS X and Linux, in each case with 1GB of memory, and that is plenty.&lt;br /&gt;
&lt;br /&gt;
==Installing Eclipse==&lt;br /&gt;
&lt;br /&gt;
Go to http://www.eclipse.org/downloads/. Click on the link corresponding to your operating system where it says &#039;&#039;&#039;Eclipse Classic&#039;&#039;&#039;. Choose a Mirror, and wait for the ~100MB download.&lt;br /&gt;
&lt;br /&gt;
You will notice that what you have got is a zip file (unless your system automatically decompresses it for you).&lt;br /&gt;
&lt;br /&gt;
On Windows, unzip it into &#039;&#039;&#039;C:\Program Files&#039;&#039;&#039; (all the files go into an &#039;&#039;&#039;Eclipse&#039;&#039;&#039; folder there). Then look in the Eclipse folder and drag Eclipse.exe to the Start menu/Desktop/Quicklaunch bar to make a shortcut for starting it.&lt;br /&gt;
&lt;br /&gt;
On MacOS, unzip and copy the Eclipse folder into Applications. Go into the Eclipse folder and drag the Eclipse app to the Dock for ease of launching.&lt;br /&gt;
&lt;br /&gt;
On Linux, unzip somewhere suitable, and make an easy way to launch it.&lt;br /&gt;
&lt;br /&gt;
==The first time you run Eclipse==&lt;br /&gt;
&lt;br /&gt;
The first time you launch Eclipse it does a bit of setup stuff, for instance, it create a &#039;&#039;&#039;workspace&#039;&#039;&#039;. This is where it stores the things you are working on. The default location is sensible on all platforms, so use that. &lt;br /&gt;
&lt;br /&gt;
For some reason, every time you start Eclipse, it asks you which workspace you want to use. I have never seen the need to have more than one, so I recommend turning on the checkbox that says &amp;quot;Use this as the default and do not ask again&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Another thing that happens the first time you run Eclipse is that you arrive at a welcome screen. This has links to various bits of help, which you can read if you like, but you probably don&#039;t need to if you are following these instructions. So find the button on the welcome page that closes it and gets you to the main Eclipse screen.&lt;br /&gt;
&lt;br /&gt;
==Installing the necessary plugins==&lt;br /&gt;
&lt;br /&gt;
By default, Eclipse comes with the Java tools. For everything else you will need to install some plugins.&lt;br /&gt;
&lt;br /&gt;
If you are sitting behind a web proxy, from the &#039;&#039;&#039;Window&#039;&#039;&#039; menu choose &#039;&#039;&#039;Preferences ...&#039;&#039;&#039;. Choose &#039;&#039;&#039;Install/Update&#039;&#039;&#039; from the tree view on the left, and enter the proxy information in the boxes on the right. If you aren&#039;t behind a proxy, ignore this step.&lt;br /&gt;
&lt;br /&gt;
From the &#039;&#039;&#039;Help&#039;&#039;&#039; menu choose &#039;&#039;&#039;Software Updates -&amp;gt; Find and Install&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
On the first screen of the wizard, make sure that &amp;quot;Search for new features to install&amp;quot; is selected, then click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The next screen is a list of upgrade sites to check. You need to add one to the list, so click the &#039;&#039;&#039;New Remote Site ...&#039;&#039;&#039; Button.&lt;br /&gt;
&lt;br /&gt;
In the pop-up dialog, give the remote site a name like &#039;&#039;&#039;PHPeclipse Update Site&#039;&#039;&#039;; set the URL to http://phpeclipse.sourceforge.net/update/releases/; then click &#039;&#039;&#039;OK&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note, there is now also another PHP editor for Eclipse. The update URL ishttp://download.eclipse.org/tools/pdt/updates/. I am just trying it--[[User:Tim Hunt|Tim Hunt]] 11:39, 7 November 2007 (CST)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Back in the wizard, turn on just two things in the box &amp;quot;Sites to include in search&amp;quot;:&lt;br /&gt;
* Your newly created &#039;&#039;&#039;Phpeclipse Update Site&#039;&#039;&#039;; and&lt;br /&gt;
* the one called &#039;&#039;&#039;Europa Discovery Site&#039;&#039;&#039; (or possibly &#039;&#039;&#039;Callisto Discovery Site&#039;&#039;&#039;.&lt;br /&gt;
Then click &#039;&#039;&#039;Finish&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
It goes off sees what updates are available at those sites. As it does so, it may occasionally pop up a dialog asking you to choose a mirror. Each time, select a sensible one.&lt;br /&gt;
&lt;br /&gt;
Eventually, you get to a new wizard for selecting and installing the updates you want. The ones you want (you may have to search the tree structure) are, &#039;&#039;&#039;PHPeclipse&#039;&#039;&#039; (from your newly created PHPEclipse Update Site) and all the &#039;&#039;&#039;Web Standard Tools (WST)&#039;&#039;&#039; (usually under Callisto Discovery Site --&amp;gt; Web and J2EE Development).&lt;br /&gt;
&lt;br /&gt;
Next, and very importantly, you must click the &#039;&#039;&#039;Select Required&#039;&#039;&#039; button which should resolve dependencies and remove the warning message you are probably worrying about. Then you can click the &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
Read and agree to all the license agreements. Then click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Finish&#039;&#039;&#039;, and wait for the plugins to download.&lt;br /&gt;
&lt;br /&gt;
Once the downloads have finished, a warning will pop-up telling you that all the plugins you downloaded are not digitally signed. The Eclipse Foundation build digital signing of plugins into their architecture as a security measure, and then did not sign any of their own plugins! Anyway, click the &#039;&#039;&#039;Install All&#039;&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
Finally, a window will pop up asking you to restart Eclipse. Do so.&lt;br /&gt;
&lt;br /&gt;
==Setting the preferences for Moodle development==&lt;br /&gt;
&lt;br /&gt;
Now go to the &#039;&#039;&#039;Window&#039;&#039;&#039; menu, and choose &#039;&#039;&#039;Preferences ...&#039;&#039;&#039; (&#039;&#039;&#039;Eclipse&#039;&#039;&#039; menu on Mac OS X).&lt;br /&gt;
&lt;br /&gt;
The Eclipse preferences are immense, with a tree view on the left, which selects which screen to display on the right. Don&#039;t panic, we&#039;ll guide you through it.&lt;br /&gt;
&lt;br /&gt;
===General settings===&lt;br /&gt;
&lt;br /&gt;
If you have strong feelings about fonts (I would hate to edit code an anything except Andale Mono), choose &#039;&#039;&#039;General -&amp;gt; Appearance -&amp;gt; Colors and Fonts&#039;&#039;&#039; from the tree on the left. Then on the right look under &#039;&#039;&#039;Basic&#039;&#039;&#039; and change &#039;&#039;&#039;Text Font&#039;&#039;&#039;. All the other editor font settings will inherit from this, so this is probably the only one you have to change.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;General -&amp;gt; Content Types&#039;&#039;&#039;, select PHP Source File, and add &#039;&#039;&#039;*.html&#039;&#039;&#039; to the box at the bottom.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;General -&amp;gt; Editors -&amp;gt; File Associations&#039;&#039;&#039;, if it is not already there, add &#039;&#039;&#039;*.php&#039;&#039;&#039; to the top box. With &#039;&#039;&#039;*.php&#039;&#039;&#039; selected in the top box, make sure &#039;&#039;&#039;PHP Editor&#039;&#039;&#039; is set to default in the bottom box. With &#039;&#039;&#039;*.html&#039;&#039;&#039; selected in the top box, select &#039;&#039;&#039;PHP Editor&#039;&#039;&#039; in the bottom box and click the &#039;&#039;&#039;Default&#039;&#039;&#039; button to change it, because in Moodle, most HTML files actually contain PHP code.&lt;br /&gt;
&lt;br /&gt;
If you use a web proxy, enter the details under &#039;&#039;&#039;Internet -&amp;gt; Proxy Settings&#039;&#039;&#039;. (Yes, I know you have entered them somewhere else before. Now you have to enter them again here. I don&#039;t know why. You just do.)&lt;br /&gt;
&lt;br /&gt;
===PHP Settings===&lt;br /&gt;
&lt;br /&gt;
These are all hidden under the &#039;&#039;&#039;PHPeclipse Web Development&#039;&#039;&#039; bit of the tree.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;PHPeclipse Web Development -&amp;gt; Browser Preview Defaults&#039;&#039;&#039;, turn off both checkboxes.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;PHPeclipse Web Development -&amp;gt; PHP&#039;&#039;&#039;, on the &#039;&#039;&#039;Appearance&#039;&#039;&#039; tab, set &#039;&#039;&#039;Displayed tab width&#039;&#039;&#039; to 4.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;PHPeclipse Web Development -&amp;gt; PHP&#039;&#039;&#039;, on the &#039;&#039;&#039;Appearance&#039;&#039;&#039; tab, check &#039;&#039;&#039;Show line numbers&#039;&#039;&#039; to display line numbers in the left margin (optional). NOTE.- When you are editing a PHP file, you could left-click in the left margin and tick the &#039;&#039;&#039;Show Line Numbers&#039;&#039;&#039; line in the contextual menu. However, this toggle only applies to plain text files, &#039;&#039;not&#039;&#039; to HTML or PHP files. The only place where you can toggle line numbers on/off for such files is in the PHP/Appearance menu.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;PHPeclipse Web Development -&amp;gt; PHP&#039;&#039;&#039;, on the &#039;&#039;&#039;Typing&#039;&#039;&#039; tab, turn off all the options except &#039;&#039;&#039;Pasting for correct indentation&#039;&#039;&#039;, &#039;&#039;&#039;Insert spaces for tab&#039;&#039;&#039; and &#039;&#039;&#039;Close PHPdocs and comments&#039;&#039;&#039; and &#039;&#039;&#039;Remove trailing spaces on editor save&#039;&#039;&#039;. It would be nice to turn on more of these options, but most of the rest don&#039;t work very well.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;PHPeclipse Web Development -&amp;gt; PHP -&amp;gt; Formatter&#039;&#039;&#039;, on the &#039;&#039;&#039;New Lines&#039;&#039;&#039; tab, turn on &#039;&#039;&#039;Clear all blank lines&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;PHPeclipse Web Development -&amp;gt; PHP -&amp;gt; Formatter&#039;&#039;&#039;, on the &#039;&#039;&#039;Style&#039;&#039;&#039; tab, turn off &#039;&#039;&#039;Indentation is represented by a tab&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;PHPeclipse Web Development -&amp;gt; PHP -&amp;gt; Templates&#039;&#039;&#039;, I like to define a new template to help with debugging:&lt;br /&gt;
;Name&lt;br /&gt;
:dump &lt;br /&gt;
;Description&lt;br /&gt;
:Dump a PHP variable&lt;br /&gt;
;Pattern&lt;br /&gt;
&amp;lt;pre&amp;gt;print_object(${word_selection}${cursor}); // DONOTCOMMIT&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can do other useful things with templates too. Here are two more I use:&lt;br /&gt;
&amp;lt;pre&amp;gt;debugging(&amp;quot;&#039;${word_selection}${cursor}&#039;&amp;quot;); // DONOTCOMMIT&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;$$string[&#039;${word_selection}${cursor}&#039;] = &#039;.&#039;;&amp;lt;/pre&amp;gt;&lt;br /&gt;
That is, a simple debug message with a stack trace, and a new language string.&lt;br /&gt;
&lt;br /&gt;
There is a really stupid bug. Under &#039;&#039;&#039;PHPeclipse Web Development -&amp;gt; Project Defaults&#039;&#039;&#039;, you would like to add &amp;quot;.&amp;quot; to the &#039;&#039;&#039;Include Paths&#039;&#039;&#039;, but you can&#039;t using the GUI. You will have to edit one of the Eclipse config files by hand. So&lt;br /&gt;
# Note down the path to your Eclipse profile. On Windows it will be something like &#039;&#039;&#039;C:/Documents and settings/XXXX/workspace&#039;&#039;&#039;, and on Unixy systems something like &#039;&#039;&#039;~/workspace&#039;&#039;&#039;.&lt;br /&gt;
# Close Eclipse. &lt;br /&gt;
# Open the file &#039;&#039;&#039;net.sourceforge.phpeclipse.ui.prefs&#039;&#039;&#039; that is in the directory &#039;&#039;&#039;(your workspace)/.metadata/.plugins/org.eclipse.core.runtime/.settings&#039;&#039;&#039; in a text editor.&lt;br /&gt;
# Look for a line in the file that starts &#039;&#039;&#039;_php_include_paths=&#039;&#039;&#039; If it is not there, add it at the end.&lt;br /&gt;
# Change this line to say &#039;&#039;&#039;_php_include_paths=.&#039;&#039;&#039;&lt;br /&gt;
# Run Eclipse again.&lt;br /&gt;
&lt;br /&gt;
===CVS Settings===&lt;br /&gt;
&lt;br /&gt;
These are all hidden under the &#039;&#039;&#039;Team&#039;&#039;&#039; bit of the tree.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;Team -&amp;gt; CVS -&amp;gt; SSH2 Connection Method&#039;&#039;&#039;, you can set up a public/private key pair. If you do this, you won&#039;t have to keep typing your Sourceforge password when doing CVS operations. See http://sourceforge.net/docs/F02/ for the instructions on what people used to do when the CVS was at Sourceforge. However, If you follow the Sourceforge instructions now you will spend a good deal of time trying to add a public key to your sourceforge profile to no purpose; the key generated is for cvs.moodle.org, NOT, sourceforge,  and you add it via the Update My Developer Information tab on the moodle developers page at http://moodle.org/mod/cvsadmin/view.php?id=7134. Once you have uploaded your public key you can then try to fgure out how to make Eclipse use this keyset. &lt;br /&gt;
&lt;br /&gt;
The rest of the ones in this section are personal preferences, but I recommend them because the default settings are very irritating.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;Team&#039;&#039;&#039;, set &#039;&#039;&#039;Perspectives&#039;&#039;&#039; to &#039;&#039;&#039;None&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;Team -&amp;gt; CVS -&amp;gt; Annotate&#039;&#039;&#039; set &#039;&#039;&#039;Use Quick Diff annotate mode for local file annotations&#039;&#039;&#039; to &#039;&#039;&#039;Yes&#039;&#039;&#039;, and &#039;&#039;&#039;Open perspective after a &#039;Show Annotations&#039; operation&#039;&#039;&#039; to &#039;&#039;&#039;No&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;Team -&amp;gt; CVS -&amp;gt; Label Decorations&#039;&#039;&#039;, switch to the &#039;&#039;&#039;Icon Decorations&#039;&#039;&#039; tab and turn on all the settings, and then on the &#039;&#039;&#039;Text Decorations&#039;&#039;&#039; tab change both &#039;&#039;&#039;File Decoration&#039;&#039;&#039; and &#039;&#039;&#039;Folder Decoration&#039;&#039;&#039; to be just &#039;&#039;&#039;{name}&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===Web and XML settings===&lt;br /&gt;
&lt;br /&gt;
Foreach XXX in CSS, HTML, Javascript, XML:&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;Web and XML -&amp;gt; XXX Files -&amp;gt;XXX Source&#039;&#039;&#039;, choose &#039;&#039;&#039;Indent using spaces&#039;&#039;&#039; and &#039;&#039;&#039;indentation size&#039;&#039;&#039; 4.&lt;br /&gt;
&lt;br /&gt;
==Checking out the Moodle code==&lt;br /&gt;
&lt;br /&gt;
From the &#039;&#039;&#039;File&#039;&#039;&#039; menu, choose &#039;&#039;&#039;New -&amp;gt; Project ...&#039;&#039;&#039;, then click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In the wizard that pops up, choose &#039;&#039;&#039;CVS -&amp;gt; Projects from CVS&#039;&#039;&#039;, then click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Select &#039;&#039;&#039;Create a new repository location&#039;&#039;&#039;, then click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Fill in&lt;br /&gt;
&amp;lt;div style=&amp;quot;float: right; border: 1px solid orange; padding: 0 1em;&amp;quot;&amp;gt;&lt;br /&gt;
For anonymous CVS access use&lt;br /&gt;
;Host&lt;br /&gt;
:XX.cvs.moodle.org&lt;br /&gt;
where XX.cvs.moodle.org is one of [[CVS_for_Administrators#CVS_Servers|these mirrors]]&lt;br /&gt;
;Repository path&lt;br /&gt;
:/cvsroot/moodle&lt;br /&gt;
;User&lt;br /&gt;
:anonymous&lt;br /&gt;
;Password&lt;br /&gt;
:(leave blank)&lt;br /&gt;
;Connection type&lt;br /&gt;
:pserver&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
;Host&lt;br /&gt;
:cvs.moodle.org&lt;br /&gt;
;Repository path&lt;br /&gt;
:/cvsroot/moodle&lt;br /&gt;
;User&lt;br /&gt;
:(your Moodle CVS username)&lt;br /&gt;
;Password&lt;br /&gt;
:(if you set up the SSH2 key thing in preferences, leave this blank, otherwise, type in your Moodle CVS password.)&lt;br /&gt;
;Connection type&lt;br /&gt;
:extssh&lt;br /&gt;
(CVS experts, if you are confused by that last one, know it is an Eclipse-specific thing.) Then click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
On the next screen of the Wizard, choose &#039;&#039;&#039;Use an existing module&#039;&#039;&#039;. Wait a moment, then select &#039;&#039;&#039;moodle&#039;&#039;&#039; from the list. Click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
On the next screen, make sure the option &#039;&#039;&#039;Check out as a project configured using the New Project Wizard&#039;&#039;&#039; is selected, then click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Refresh Tags&#039;&#039;&#039;, then choose the branch you want. For now leave it set to &#039;&#039;&#039;HEAD&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Finish&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now you  will find yourself back at the start of the &#039;&#039;&#039;New Project&#039;&#039;&#039; Wizard. This is because of the option you chose three paragraphs ago. This time you should select &#039;&#039;&#039;PHP -&amp;gt; PHP Project&#039;&#039;&#039;, then click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Make up a project name. &#039;&#039;&#039;moodle&#039;&#039;&#039; would be sensible.&lt;br /&gt;
&lt;br /&gt;
Click &#039;&#039;&#039;Finish&#039;&#039;&#039;, and wait while all the moodle files are checked out of CVS.&lt;br /&gt;
&lt;br /&gt;
Once it has finished, it will probably ask you if you want to switch to the PHP perspective. Answer &#039;&#039;&#039;Yes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you also need another branch (1.6, 1.7, 1.8, ...) repeat all the other steps with a few changes:&lt;br /&gt;
* This time you can choose &#039;&#039;&#039;Use an existing repository location&#039;&#039;&#039; instead of typing all the sourceforge CVS details again.&lt;br /&gt;
* Select the appropriate branch. If you don&#039;t see the branch you want, see [https://docs.moodle.org/en/Development:Setting_up_Eclipse#Resetting_the_branch_information this Troubleshooting tip].&lt;br /&gt;
* Use a different project name (e.g. moodle16, moodle17, etc.).&lt;br /&gt;
&lt;br /&gt;
==Let your development web server know where your files are==&lt;br /&gt;
&lt;br /&gt;
Either by editing you web server&#039;s config files, or using a symbolic link. Make sure your webserver can see your new working set of files at a sensible URL, so you can test the code you are working on.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Quick tour of some cool features, and remaining configuration changes==&lt;br /&gt;
&lt;br /&gt;
I find the default workbench setup is pretty good. Here is a quick guide to some of the bits.&lt;br /&gt;
&lt;br /&gt;
===Navigator===&lt;br /&gt;
&lt;br /&gt;
To the left is the &#039;&#039;&#039;Navigator&#039;&#039;&#039;. This is a tree view of all your files. If you double-click on a file, it opens in the editor in the middle. Try opening &#039;&#039;&#039;course/lib.php&#039;&#039;&#039; now. You will notice that it comes up nicely syntax-hightlighted.&lt;br /&gt;
&lt;br /&gt;
===Error highlighting===&lt;br /&gt;
&lt;br /&gt;
In the middle of the file, just type any old text, for example &amp;quot;I like Eclipse&amp;quot;. Obviously, this is not valid PHP syntax, and Eclipse will notice this, and put a red underline under it. Also, by the scrollbar is a ruler with a red mark in it to show the error.&lt;br /&gt;
&lt;br /&gt;
You will see some yellow marks lower down the ruler. There are warnings. Click on one, and you will be taken to where that warning is in the file. Hover your mouse over the warning, and you will get a tooltip explaining what the problem might be.&lt;br /&gt;
&lt;br /&gt;
Save the edited file. (Don&#039;t worry that it is broken, we&#039;ll clean up the mess later.) Notice that a red error marker is added to the file in the navigator, so you can see that there is a problem. Also, error markers are added to the course folder, and the whole project, so you could see there was an error even if the navigator tree was collapsed.&lt;br /&gt;
&lt;br /&gt;
You will probably find lots of warnings that the config.php file can&#039;t be found. In the navigator, find the file &#039;&#039;&#039;config-dist.php&#039;&#039;&#039;. Do &#039;&#039;&#039;Copy&#039;&#039;&#039; then &#039;&#039;&#039;Paste&#039;&#039;&#039; and choose to call the new file &#039;&#039;&#039;config.php&#039;&#039;&#039;. Edit this new config.php as normal. You should fine that most of the include file warnings have gone now.&lt;br /&gt;
&lt;br /&gt;
Notice also that there is another marker on each file icon. A little yellow cylinder on most files, but a white-on-brown star on the one you have edited. This is telling you the CVS status of each file. The brown stars are changes you have made but not checked in yet.&lt;br /&gt;
&lt;br /&gt;
===Outline===&lt;br /&gt;
&lt;br /&gt;
Over to the right is the Outline view. This shows a list of functions and classes defined in this file. By default, they are listed in the same order as in the file, but if you click on the &#039;&#039;&#039;az&#039;&#039;&#039; toolbar button, they are sorted into alphabetical order.&lt;br /&gt;
&lt;br /&gt;
Click on the function name &#039;&#039;&#039;add_course_module&#039;&#039;&#039; in the Outline. You will see that the editor scrolls to the definition of that function.&lt;br /&gt;
&lt;br /&gt;
===Code navigation===&lt;br /&gt;
&lt;br /&gt;
In that function, hover the mouse pointer over the function name &#039;&#039;&#039;insert_record&#039;&#039;&#039;. After a while, the documentation for that function will appear in a big tooltip.&lt;br /&gt;
&lt;br /&gt;
Hold down CTRL, move the mouse pointer over the function name &#039;&#039;&#039;insert_record&#039;&#039;&#039;, then click. Eclipse should load &#039;&#039;&#039;dmllib.php&#039;&#039;&#039;, and scroll you to where this function is defined.&lt;br /&gt;
&lt;br /&gt;
In the main Eclipse toolbar, there are forward and back arrows like in a web browser. Click back now to get back to &#039;&#039;&#039;course/lib.php&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===Open resource===&lt;br /&gt;
&lt;br /&gt;
From the &#039;&#039;&#039;Navigate&#039;&#039;&#039; menu, choose &#039;&#039;&#039;Open Resource...&#039;&#039;&#039;. In the dialog that pops up, start typing a filename for instance type &#039;&#039;&#039;moodlel&#039;&#039;&#039;. In the box in the middle of the dialog, you will see it list all the files in the project whose names start that way. At the bottom is a box which lists the different folders that contain a file with that name. This can be a very quick way of opening files with fairly unique names like moodlelib.php, without having to click through the levels of the navigator tree. Of course, it is not so useful for an index.php file! Click OK now to open moodlelib.php. (It would actually work if you just did CTRL + Shift + R, moodlel, Enter.)&lt;br /&gt;
&lt;br /&gt;
===Multi-file search===&lt;br /&gt;
&lt;br /&gt;
Scroll down moodlelib a little bit, and double click on the name of the constant &#039;&#039;&#039;MOODLE_INTERNAL&#039;&#039;&#039; where it is defined, so that the text is selected. Then, from the &#039;&#039;&#039;Search&#039;&#039;&#039; menu, choose &#039;&#039;&#039;Search...&#039;&#039;&#039;. Notice that the &#039;&#039;&#039;Containing text&#039;&#039;&#039; box has already been filled in for you with the text you just selected. Of course you can just type text into this box without selecting it first. Notice that you can do regular expression searches, but leave that turned off for now. In the &#039;&#039;&#039;File name patterns&#039;&#039;&#039; box type &#039;&#039;&#039;*.css, *.html, *.inc, *.js, *.php, *.xml&#039;&#039;&#039;. (This is the most useful general setting for working on moodle. Eclipse will remember this setting, so you only have to enter it once.) Click &#039;&#039;&#039;Search&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The search results will appear in a new view underneath the editor. That view has a toolbar with yellow up and down arrows. Click the down arrow a few times and it will take you to the first few matches in the code, opening the relevant files as necessary.&lt;br /&gt;
&lt;br /&gt;
===Synchronize view===&lt;br /&gt;
&lt;br /&gt;
I think this is my favorite feature. From the &#039;&#039;&#039;Window&#039;&#039;&#039; menu, select &#039;&#039;&#039;Show View -&amp;gt; Other...&#039;&#039;&#039;. In the dialog that pops up, select &#039;&#039;&#039;Team -&amp;gt; Synchronize&#039;&#039;&#039;, then click &#039;&#039;&#039;OK&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This opens the Synchronize view below the editor. The view has a toolbar. Click on the first toolbar button, which pops up the Synchronize wizard.&lt;br /&gt;
&lt;br /&gt;
On the first screen, there will probably only be one option: &#039;&#039;&#039;CVS&#039;&#039;&#039;. Make sure that is selected, then click &#039;&#039;&#039;Next &amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Under &#039;&#039;&#039;Scope&#039;&#039;&#039;, choose &#039;&#039;&#039;Workspace&#039;&#039;&#039;, then click &#039;&#039;&#039;Finish&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Wait while it talks to the CVS server. After a while, you will see that the Synchronize view lists course/lib.php, and something called &#039;&#039;&#039;.project.... That is, it is listing just the files you have edited, but not checked in yet.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;.project&#039;&#039;&#039; is something that belongs to Eclipse that we don&#039;t care about. So select it and bring up the context menu, and choose &#039;&#039;&#039;Add to .cvsignore...&#039;&#039;&#039;. In the dialog that pops up, choose the top option, then click &#039;&#039;&#039;OK&#039;&#039;&#039;. Then you will find the Synchronize view shows you a &#039;&#039;&#039;.cvsignore&#039;&#039;&#039; file that you aren&#039;t interested in, so add that to .cvsignore too!&lt;br /&gt;
&lt;br /&gt;
If you double-click on &#039;&#039;&#039;course/lib.php&#039;&#039;&#039; here, you will see that it opens the compare editor, which is a nice graphical display of the changes in this file.&lt;br /&gt;
&lt;br /&gt;
If you select a file or files here, then bring up the context menu, you will see the option to &#039;&#039;&#039;Commit...&#039;&#039;&#039; the changes. (But don&#039;t do that now!). This is the easiest way to commit things in Eclipse.&lt;br /&gt;
&lt;br /&gt;
However, our changes were rubbish, so we want to undo them. So open the context menu again, and choose &#039;&#039;&#039;Override and Update&#039;&#039;&#039;. This checks a clean copy of the file out of CVS, removing our changes.&lt;br /&gt;
&lt;br /&gt;
Note that the easiest way to do an ordinary CVS Update is to select the top-level project-folder in the Navigator view on the left, open the context menu, and choose &#039;&#039;&#039;Team -&amp;gt; Update&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
That&#039;s all the really important features. I sure you can learn everything else on your own. An you could always read the built in help!&lt;br /&gt;
&lt;br /&gt;
===Creating a patch===&lt;br /&gt;
&lt;br /&gt;
In the synchronise view, right click on an item (file or folder) and choose &#039;&#039;&#039;Create Patch...&#039;&#039;&#039;. Or in the navigator, right click on an item and choose &#039;&#039;&#039;Team -&amp;gt; Create Patch...&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This brings up a two-page wizard. On the first page you can select where you want the patch made. For small patches it can be useful to create them on the clipboard, but normally you will want to save them in a file.&lt;br /&gt;
&lt;br /&gt;
On the second page, you can set some options, but normally you don&#039;t need to change the defaults which are &#039;&#039;&#039;Unified&#039;&#039;&#039; diff format, and Patch root set to &#039;&#039;&#039;Workspace&#039;&#039;&#039;. Well, sometimes it is helpful to change the second one to &#039;&#039;&#039;Project&#039;&#039;&#039; but it is not important.&lt;br /&gt;
&lt;br /&gt;
There is a corresponding apply patch wizard that you can use to apply a patch to a project.&lt;br /&gt;
&lt;br /&gt;
===Switching to another branch or version===&lt;br /&gt;
&lt;br /&gt;
Suppose you have been using a check-out of HEAD from CVS, and then as the 1.9 release approaches, the MOODLE_19_STABLE branch is created, and you want to start following that instead.&lt;br /&gt;
# Right click on the moodle project in the navigator view, and select &#039;&#039;&#039;Team -&amp;gt; Switch to Another Branch or Version ...&#039;&#039;&#039;.&lt;br /&gt;
# choose the second radio button: &#039;&#039;&#039;Select the tag from the following list&#039;&#039;&#039;.&lt;br /&gt;
# If the branch you want is not in the &#039;&#039;&#039;Matching tags&#039;&#039;&#039; box, see [[Setting_up_Eclipse#Resetting the branch information|Resetting the branch information]] below.&lt;br /&gt;
# Select the branch you want and click &#039;&#039;&#039;Finish&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
Some tips on how to solve common problems that may crop up.&lt;br /&gt;
&lt;br /&gt;
===Resetting the branch information===&lt;br /&gt;
&lt;br /&gt;
Every now and then, Eclipse may lose information on the branch tags it knows about. Hitting refresh tags may fix it, but if not, try the following:&lt;br /&gt;
&lt;br /&gt;
#Bring up the tag dialogue (example using &amp;quot;Team / Switch to Another Branch or Version&amp;quot;).&lt;br /&gt;
#Click on Configure tags ... (not Refresh tags).&lt;br /&gt;
#Select config-dist.php in the top left box (if this is a Moodle checkout).&lt;br /&gt;
#Click Add Checked tags.&lt;br /&gt;
#Click OK.&lt;br /&gt;
#Then you will have all tags.&lt;br /&gt;
&lt;br /&gt;
(thanks to Tim Hunt)&lt;br /&gt;
&lt;br /&gt;
===Error loading php files after Ubuntu 7.04 Install===&lt;br /&gt;
&lt;br /&gt;
A java issue with Ubuntu 7.04 may cause an error when you attempt to load php pages. Refer to:&lt;br /&gt;
http://www.plog4u.org/index.php/Using_PHPEclipse_:_Installation_:_Installing_PHPEclipse for details about how to fix this in Ubuntu 7.04.&lt;br /&gt;
&lt;br /&gt;
After upgrading from Ubuntu 7.04 to 7.10, I had to go in and re-edit the /etc/eclipse/java_home file in order to get the CVS functions to work and be able to open PHP files. When I tried to do a CVS update I initially received an error about org.eclipse.team.internal.ccvs.ui.wizards.CheckoutWizard). Everything seemed to work again after reapplying the fix for the aforementioned 7.04 java issue.&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
&lt;br /&gt;
There is an excellent series of articles published by IBM on using Eclipse for Drupal developement here : [http://www-128.ibm.com/developerworks/ibm/osource/index.html Using open source software to design, develop, and deploy a collaborative Web site Tools and techniques for getting relatively complicated Web sites up and running quickly].&lt;br /&gt;
&lt;br /&gt;
[[Category:Setting up Eclipse]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Weekly_Code_Review&amp;diff=8187</id>
		<title>Weekly Code Review</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Weekly_Code_Review&amp;diff=8187"/>
		<updated>2008-04-01T03:42:23Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: /* Test the fix */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Moodle has a weekly process of code review in the stable branches to help improve the quality of stable packages and to help detect any regressions that may have occurred in stable code.&lt;br /&gt;
&lt;br /&gt;
Here is the process for testers and developers:&lt;br /&gt;
&lt;br /&gt;
==Every Tuesday==&lt;br /&gt;
&lt;br /&gt;
===Find bugs to test===&lt;br /&gt;
&lt;br /&gt;
All developers and testers should be looking at:&lt;br /&gt;
&lt;br /&gt;
  Moodle 1.9 stable:  [http://tracker.moodle.org/secure/IssueNavigator.jspa?mode=hide&amp;amp;requestId=10565 1.9.x Needs QA review]&lt;br /&gt;
&lt;br /&gt;
(Make sure you can see the QA Assigned column)&lt;br /&gt;
&lt;br /&gt;
Grab any bug that:&lt;br /&gt;
&lt;br /&gt;
* is from the last week&lt;br /&gt;
* you did not fix&lt;br /&gt;
* does not have a QA assignee yet &lt;br /&gt;
&lt;br /&gt;
and claim it by editing the bug to add your name as QA Assignee.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Test the fix===&lt;br /&gt;
&lt;br /&gt;
* Read the comments &lt;br /&gt;
* Look at the patch attached to the tracker&lt;br /&gt;
* Try the feature out to make sure it works as advertised&lt;br /&gt;
* Post new comments (or talk on Moodle HQ) if you need clarification&lt;br /&gt;
&lt;br /&gt;
===If you find a problem===&lt;br /&gt;
&lt;br /&gt;
* Post a comment on the bug with details (preferably including patch!)&lt;br /&gt;
* Reopen the bug&lt;br /&gt;
* If it looks like the original developer isn&#039;t seeing it, reassign to Eloy Lafuente for triage.&lt;br /&gt;
* If the fix is obvious and you have CVS access, fix it yourself.&lt;br /&gt;
&lt;br /&gt;
===Mark the fix as reviewed===&lt;br /&gt;
&lt;br /&gt;
* When you are satisfied the bug is correctly fixed, simply change the status from Resolved to Closed&lt;br /&gt;
&lt;br /&gt;
==Every Wednesday==&lt;br /&gt;
&lt;br /&gt;
* The download site will automatically tag the whole current stable codebase (eg MOODLE_19_WEEKLY) and then build download packages&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Repository_API&amp;diff=5997</id>
		<title>Repository API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Repository_API&amp;diff=5997"/>
		<updated>2008-03-31T09:09:09Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: /* Repository plugins */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the specification for a future feature, currently being worked on for Moodle 2.0.  This spec is STILL UNDER CONSTRUCTION.&lt;br /&gt;
&lt;br /&gt;
See MDL-13766 to track the status of the implementation.&lt;br /&gt;
&lt;br /&gt;
The page is open for everyone so everyone can help correct mistakes and help evolution of this document.  However, if you have questions, problems or major changes to suggest please add them to the [[Development_talk:Repository_API|page comments]], or start a discussion in the [http://moodle.org/mod/forum/view.php?id=1807 Repositories forum].  We&#039;ll endeavour to merge all such suggestions into the main spec before we start development.&lt;br /&gt;
&lt;br /&gt;
==Objectives==&lt;br /&gt;
&lt;br /&gt;
# Allow files to be added directly into Moodle (as we do now)&lt;br /&gt;
# Allow all Moodle users to easily bring content into Moodle from external repositories&lt;br /&gt;
# Allow content to be used in multiple Moodle contexts securely and simply via capabilities&lt;br /&gt;
# Consistency and simplicity for ALL file handling&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The Repository API is a core set of interfaces that all Moodle code will use to:&lt;br /&gt;
# copy files from external servers&lt;br /&gt;
# store files within Moodle&lt;br /&gt;
# display files to Moodle users&lt;br /&gt;
&lt;br /&gt;
It&#039;s important to remember that a repository will generally be treated as READ-ONLY.  Management of the files will normally be done through the native interface provided by the repository.  Publishing of Moodle content TO a repository is handled by the [[Portfolio API|Portfolio API]].&lt;br /&gt;
&lt;br /&gt;
==Use cases==&lt;br /&gt;
&lt;br /&gt;
===Teacher adding an external file as a new resource===&lt;br /&gt;
&lt;br /&gt;
# Teacher wants to add a new resource to a course &lt;br /&gt;
# Teacher clicks the &amp;quot;Choose a resource&amp;quot; button&lt;br /&gt;
# Teacher is able to choose from a list of configured repositories (this step will be skipped if there&#039;s only one).&lt;br /&gt;
# Teacher is presented with a simple file picker to choose a file&lt;br /&gt;
# Teacher chooses a file&lt;br /&gt;
# File is COPIED into Moodle and included in the course.&lt;br /&gt;
# File is marked as owned by that user&lt;br /&gt;
# Access controls are automatically added for that file so that only those with privileges to see that course can see that file (the owner can change those permissions anytime)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Student submitting an assignment===&lt;br /&gt;
# Student needs to submit an assignment and presses the &amp;quot;Choose files&amp;quot; button&lt;br /&gt;
# Student sees a &amp;quot;file picker&amp;quot; where they can see files listed on any of several configured repositories&lt;br /&gt;
# Student chooses MySpace from the list&lt;br /&gt;
# Student is prompted to enter MySpace username/password (a checkbox could be there to &amp;quot;remember this for next time&amp;quot; but for security perhaps not)&lt;br /&gt;
# Student sees their files in MySpace and chooses one or more&lt;br /&gt;
# Files are copied from MySpace to Moodle &lt;br /&gt;
# Assignment module gives the files permissions so that only the Student and assignment graders can see the file (other students would not have permission).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Student attaching an image to a forum===&lt;br /&gt;
# Student needs to attach an image and presses the &amp;quot;Choose files&amp;quot; button in the posting screen&lt;br /&gt;
# Student sees a &amp;quot;file picker&amp;quot; where they can see files listed on any of several configured repositories&lt;br /&gt;
# Student chooses Mahara from the list&lt;br /&gt;
# Student is prompted to enter MySpace username/password (a checkbox could be there to &amp;quot;remember this for next time&amp;quot; but for security perhaps not)&lt;br /&gt;
# Student sees their files in Mahara and chooses one image&lt;br /&gt;
# Image is copied to Moodle &lt;br /&gt;
# Image file is attached to forum post by Forum module (by reference)&lt;br /&gt;
# Forum module gives permissions so that anyone who can read that forum can see that file&lt;br /&gt;
&lt;br /&gt;
===Student attaching the same image in another forum===&lt;br /&gt;
&lt;br /&gt;
# Student needs to submit an assignment and presses the &amp;quot;Choose files&amp;quot; button&lt;br /&gt;
# Student sees a &amp;quot;file picker&amp;quot; where they can see files listed on any of several configured repositories&lt;br /&gt;
# Student chooses Mahara from the list&lt;br /&gt;
# Student is prompted to enter MySpace username/password (a checkbox could be there to &amp;quot;remember this for next time&amp;quot; but for security perhaps not)&lt;br /&gt;
# Student sees their files in Mahara and chooses one image&lt;br /&gt;
# Moodle detects that the image already exists in Moodle so it it not copied again (or it&#039;s just updated)&lt;br /&gt;
# Image file is attached to forum post by Forum module (by reference)&lt;br /&gt;
# Forum module adds some permissions so that anyone who can read the current forum can also see that file&lt;br /&gt;
&lt;br /&gt;
===User managing their files===&lt;br /&gt;
# User goes to the &amp;quot;Files&amp;quot; area (similar to current Moodle, but for all users)&lt;br /&gt;
# User sees two tabs&lt;br /&gt;
# First tab shows listing of current files belonging to self, with buttons to manage them, including buttons to modify the permissions (eg &amp;quot;Allow all people in Course X to see this&amp;quot;).  You can also see what repository it came from, including the foreign path, and choose to &amp;quot;update from repository&amp;quot; and get a new copy of the file.&lt;br /&gt;
# Second tab shows listing of files belonging to others that you are able to see.&lt;br /&gt;
&lt;br /&gt;
Please add more use cases in this same format&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==General Architecture==&lt;br /&gt;
&lt;br /&gt;
All file-handling areas in Moodle (eg adding a new resource, adding attachments to a forum post, uploading assignments) will be rewritten to talk to the standard API class methods in a standard way.&lt;br /&gt;
&lt;br /&gt;
Each repository plugin (a standard Moodle plugin stored under /repository/xxx) will subclass the standard API and override methods specific to that repository.&lt;br /&gt;
&lt;br /&gt;
As is usual in Moodle, there will be admin settings to disable/enable certain repository plugins as standard, as well as user settings so that users can add their own personal repositories to the standard list (eg [http://briefcase.yahoo.com Yahoo Briefcase] or [http://docs.google.com Google Docs]) and to select their default repository.&lt;br /&gt;
&lt;br /&gt;
Once a repository has been used the file will usually be copied into Moodle there and then.  However there will also be options to:&lt;br /&gt;
* only return the URL to the file if it&#039;s desired to keep it external (but this does present security and integrity risks), or&lt;br /&gt;
* refresh the local file copy regularly and automatically&lt;br /&gt;
&lt;br /&gt;
All files in Moodle will be listed in a table (see below) allowing us to store various metadata about each file.  The file contents will not be the database (though we could easily offer that option if we want to), they will be on disk with a name related to the id rather than the &amp;quot;human&amp;quot; name (this avoids a lot of OS Unicode problems).&lt;br /&gt;
&lt;br /&gt;
The current &amp;quot;course file manager&amp;quot; will be replaced by a personal file manager, which basically is a user&#039;s view of the internal Moodle repository, showing the files that are available to you in that context (which may include files from other people, repositories etc) and a nice browse/search interface.&lt;br /&gt;
&lt;br /&gt;
Finally, normal Moodle modules will have easy functions it can use to add/remove permissions to particular files, according to module rules.   For example, the assignment plugin may, after allowing a student to select a file to be submitted, add permissions so that people who have grade permissions in that assignment can read it.&lt;br /&gt;
&lt;br /&gt;
All files will be served via a single control script in Moodle, located at $CFG-&amp;gt;fileroot.  This could be the same as $CFG-&amp;gt;wwwroot by default, but will be recommended (for security and avoiding XSS) that Moodle admins set up a second DNS name pointing to this script eg the main site could be at http://moodle.domain.edu but files would be served via http://moodlefiles.domain.edu/file.php.  (We&#039;ll have to set session cookies on both domains and keep them in sync somehow).&lt;br /&gt;
&lt;br /&gt;
The file.php will serve files using slasharguments almost as now.  We just need to replace the courseid with a fileid:  file.php/fileid/dir/dir/file.jpg  (where dir/dir/file.jpg is the virtual path in Moodle).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Repository requirements==&lt;br /&gt;
&lt;br /&gt;
From the Moodle point of view, each repository is just a hierarchy of nodes.&lt;br /&gt;
&lt;br /&gt;
The repository MUST provide:&lt;br /&gt;
# A URL to download each node (eg file).&lt;br /&gt;
# A list of the nodes (eg files and directories) under a given node (eg directory).  This allows Moodle to construct a standard browse interface (much like a standard OS file picker).  However some repository plugins may choose to completely override the repository_browse() method and implement their own interface, that&#039;s OK, as long as they end up with a URL for the file.&lt;br /&gt;
&lt;br /&gt;
The repository can OPTIONALLY:&lt;br /&gt;
# Require some authentication credentials &lt;br /&gt;
# Provide more metadata about each node (mime type, size, dates, related files, dublin core stuff, etc)&lt;br /&gt;
# Describe a search facility (so that Moodle can construct a search form)&lt;br /&gt;
# Provide copyright and usage rules (or just information about the rules)&lt;br /&gt;
&lt;br /&gt;
==Repository plugins==&lt;br /&gt;
&lt;br /&gt;
Some plugins I&#039;d like to see developed for the first version are:&lt;br /&gt;
* local - very similar to the current course-based file manager, except user-based&lt;br /&gt;
* moodle - an interface to another Moodle site, accessed over a secure mnet connection&lt;br /&gt;
* jsr170 - an interface that can talk to anything that supports jsr170 (eg [http://www.alfresco.com/ Alfresco])&lt;br /&gt;
* oki - an OKI emulator allowing us to access things with OKI interfaces,like [http://www.fedora.info/ Fedora]&lt;br /&gt;
* briefcase - an interface to [http://briefcase.yahoo.com/ Yahoo Briefcase]&lt;br /&gt;
* myspace - an interface to MySpace files (perhaps via [http://www.programmableweb.com/api/myspace this MySpace API])&lt;br /&gt;
* googledocs - an interface to [http://docs.google.com Google Docs]&lt;br /&gt;
* skydrive - an interface to Microsoft&#039;s [http://skydrive.live.com/ SkyDrive] files&lt;br /&gt;
* facebook - an interface to Facebook files&lt;br /&gt;
* merlot - an interface to the learning materials in [http://www.merlot.org/merlot/materials.htm Merlot.org]&lt;br /&gt;
* flickr - an interface to [http://flickr.com flickr]&lt;br /&gt;
* youtube - an interface to [http://youtube.com YouTube]&lt;br /&gt;
* mahara - an interface to a Mahara installation&lt;br /&gt;
&lt;br /&gt;
==Local Files==&lt;br /&gt;
&lt;br /&gt;
In general, all external files will be copied locally and stored in Moodle.  This section describes the storage of the files and how we define ACLs (access control lists) for them.  All existing files in the Moodle dataroot course areas will be moved into this new system during the upgrade.&lt;br /&gt;
&lt;br /&gt;
The files will not be stored as they have been in the past.  The new file system is &amp;quot;flat&amp;quot; with each file stored as an id.  The name and path are stored in tables.  To avoid running out of nodes we&#039;ll use a hash-like structure like the users directory does, ie:&lt;br /&gt;
&lt;br /&gt;
 dataroot &lt;br /&gt;
    /files&lt;br /&gt;
       /0&lt;br /&gt;
       /10000&lt;br /&gt;
       /20000&lt;br /&gt;
       /30000&lt;br /&gt;
           /3076.jpg&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Tables==&lt;br /&gt;
&lt;br /&gt;
=== repository ===&lt;br /&gt;
&lt;br /&gt;
This table contains one entry for every configured external repository instance.&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;Default&#039;&#039;&#039; &lt;br /&gt;
|&#039;&#039;&#039;Info&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;id&#039;&#039;&#039; &lt;br /&gt;
|int(10)  &lt;br /&gt;
|&lt;br /&gt;
|autoincrementing &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|repositoryname&lt;br /&gt;
|varchar&lt;br /&gt;
|&lt;br /&gt;
|A custom name for this reopsitory (non-unique)&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;repositorytype&#039;&#039;&#039; &lt;br /&gt;
|varchar&lt;br /&gt;
| &lt;br /&gt;
|The name of the plugin being used&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;userid&#039;&#039;&#039; &lt;br /&gt;
|int(10)&lt;br /&gt;
| &lt;br /&gt;
|The person who created this repository instance&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;contextid&#039;&#039;&#039; &lt;br /&gt;
|int(10)&lt;br /&gt;
| &lt;br /&gt;
|The context that this repository is available to ( = system context for site-wide ones)&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|username&lt;br /&gt;
|varchar&lt;br /&gt;
| &lt;br /&gt;
|username to log in with, if required&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|password&lt;br /&gt;
|varchar&lt;br /&gt;
| &lt;br /&gt;
|password to log in with, if required&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|option1&lt;br /&gt;
|varchar&lt;br /&gt;
| &lt;br /&gt;
|Other information useful to the plugin&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|option2&lt;br /&gt;
|varchar&lt;br /&gt;
| &lt;br /&gt;
|Other information useful to the plugin&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|option3&lt;br /&gt;
|varchar&lt;br /&gt;
| &lt;br /&gt;
|Other information useful to the plugin&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|option4&lt;br /&gt;
|varchar&lt;br /&gt;
| &lt;br /&gt;
|Other information useful to the plugin&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|option5&lt;br /&gt;
|varchar&lt;br /&gt;
| &lt;br /&gt;
|Other information useful to the plugin&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|timecreated&lt;br /&gt;
|int(10)&lt;br /&gt;
|&lt;br /&gt;
|The time this repository was created&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|timemodified&lt;br /&gt;
|int(10)&lt;br /&gt;
|&lt;br /&gt;
|The last time the repository was modified&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== file ===&lt;br /&gt;
&lt;br /&gt;
This table contains one entry for every file.  Enough information is kept here so that the file can be fully identified and retrieved again if necessary.&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;Default&#039;&#039;&#039; &lt;br /&gt;
|&#039;&#039;&#039;Info&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;id&#039;&#039;&#039; &lt;br /&gt;
|int(10)  &lt;br /&gt;
|&lt;br /&gt;
|autoincrementing &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;userid&#039;&#039;&#039; &lt;br /&gt;
|int(10)  &lt;br /&gt;
| &lt;br /&gt;
|The owner of the file (person who created this entry)&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|filename&lt;br /&gt;
|varchar&lt;br /&gt;
|&lt;br /&gt;
|The full Unicode name of this file&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;repositoryid&#039;&#039;&#039;&lt;br /&gt;
|int(10)&lt;br /&gt;
|&lt;br /&gt;
|The repository instance this is associated with&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|updates&lt;br /&gt;
|int(10)&lt;br /&gt;
|&lt;br /&gt;
|Specifies the update schedule (0 = none, 1 = on demand, other = some period in seconds)&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|cachetime&lt;br /&gt;
|int(10)&lt;br /&gt;
|&lt;br /&gt;
|Specifies how long this file can be cached by browsers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|moodlepath&lt;br /&gt;
|text&lt;br /&gt;
|&lt;br /&gt;
|The virtual path to the file locally (so we can still have apparent subdirectories etc)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|repositorypath&lt;br /&gt;
|text&lt;br /&gt;
|&lt;br /&gt;
|The full path to the original file on the repository&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|timeimportfirst&lt;br /&gt;
|int(10)&lt;br /&gt;
|&lt;br /&gt;
|The first time this file was imported into Moodle&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|timeimportlast&lt;br /&gt;
|int(10)&lt;br /&gt;
|&lt;br /&gt;
|The most recent time that this file was imported into Moodle&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|timecreated&lt;br /&gt;
|int(10)&lt;br /&gt;
|&lt;br /&gt;
|The time this file was created (if known), otherwise same as time imported&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|timemodified&lt;br /&gt;
|int(10)&lt;br /&gt;
|&lt;br /&gt;
|The last time the file was modified&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|timeaccessed&lt;br /&gt;
|int(10)&lt;br /&gt;
|&lt;br /&gt;
|The last time this file was accessed for any reason&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== file_instances ===&lt;br /&gt;
&lt;br /&gt;
This table contains one entry for every &amp;quot;place&amp;quot; a file is published to.  For example, one file might appear in an assignment but also in a forum attachment, so there would be two entries here.&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;Default&#039;&#039;&#039; &lt;br /&gt;
|&#039;&#039;&#039;Info&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;id&#039;&#039;&#039; &lt;br /&gt;
|int(10)  &lt;br /&gt;
|&lt;br /&gt;
|autoincrementing &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;fileid&#039;&#039;&#039; &lt;br /&gt;
|int(10)  &lt;br /&gt;
| &lt;br /&gt;
|The file we are defining access for&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|instancetype&lt;br /&gt;
|varchar&lt;br /&gt;
|&lt;br /&gt;
|This defines the table in Moodle that this instance is associated with (eg &#039;forum_posts&#039;, &#039;assignment_submissions&#039; etc&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;instanceid&#039;&#039;&#039;&lt;br /&gt;
|int(10)&lt;br /&gt;
|&lt;br /&gt;
|The id in the foreign table (of name instancetype) that this instance is associated with&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== file_access ===&lt;br /&gt;
&lt;br /&gt;
This table describes the ACL for each file, so that checks can easily be made on whether someone can see this file or not.  Note there can be multiple entries per file.  Users can ALWAYS see their own files, so there are no entries here for that.&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;Default&#039;&#039;&#039; &lt;br /&gt;
|&#039;&#039;&#039;Info&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;id&#039;&#039;&#039; &lt;br /&gt;
|int(10)  &lt;br /&gt;
|&lt;br /&gt;
|autoincrementing &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;fileid&#039;&#039;&#039; &lt;br /&gt;
|int(10)  &lt;br /&gt;
| &lt;br /&gt;
|The file we are defining access for&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;contextid&#039;&#039;&#039;&lt;br /&gt;
|int(10)&lt;br /&gt;
|&lt;br /&gt;
|The context where this file is being published&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;capability&#039;&#039;&#039;&lt;br /&gt;
|text &lt;br /&gt;
|&lt;br /&gt;
|The capability that is required to see this file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Class methods==&lt;br /&gt;
&lt;br /&gt;
===Repository class===&lt;br /&gt;
&lt;br /&gt;
This class implements the interface to a particular repository, for browsing, selecting and updating files.&lt;br /&gt;
&lt;br /&gt;
====get_file($path)====&lt;br /&gt;
&lt;br /&gt;
====get_listing($parent=&#039;/&#039;, $search=&#039;&#039;&#039;&#039;&#039;&#039;&#039;&#039;)====&lt;br /&gt;
&lt;br /&gt;
====cron()====&lt;br /&gt;
&lt;br /&gt;
====etc====&lt;br /&gt;
&lt;br /&gt;
===File class===&lt;br /&gt;
&lt;br /&gt;
This class implements the display and management of files from local storage, with full access checking.  Some of the functions are for single files, while some are optimised for bulk display and searching (eg in the personal files interface).&lt;br /&gt;
&lt;br /&gt;
====display_file()====&lt;br /&gt;
&lt;br /&gt;
sort of like file.php is now, except smarter&lt;br /&gt;
&lt;br /&gt;
====set_access($fileid, $accessstuff)====&lt;br /&gt;
&lt;br /&gt;
Grant some access to people to a file&lt;br /&gt;
&lt;br /&gt;
====has_access($fileid, $userid=NULL)====&lt;br /&gt;
&lt;br /&gt;
Returns true or false depending on access to a file&lt;br /&gt;
&lt;br /&gt;
==Areas in Moodle that need re-writing==&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Activity_modules&amp;diff=720</id>
		<title>Activity modules</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Activity_modules&amp;diff=720"/>
		<updated>2007-12-20T06:34:15Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: /* See also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Activity modules&#039;&#039;&#039; reside in the &#039;mod&#039; directory. Each module is in a separate subdirectory and consists of the following mandatory elements (plus extra scripts unique to each module):&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;mod.html&#039;&#039; - a form to set up or update an instance of this module&lt;br /&gt;
* &#039;&#039;version.php&#039;&#039; - defines some meta-info and provides upgrading code&lt;br /&gt;
* &#039;&#039;icon.gif&#039;&#039; - a 16x16 icon for the module&lt;br /&gt;
* &#039;&#039;db/&#039;&#039; - SQL dumps of all the required db tables and data (for each database type)&lt;br /&gt;
* &#039;&#039;index.php&#039;&#039; - a page to list all instances in a course&lt;br /&gt;
* &#039;&#039;view.php&#039;&#039; - a page to view a particular instance&lt;br /&gt;
* &#039;&#039;lib.php&#039;&#039; - any/all functions defined by the module should be in here. If the modulename is called widget, then the required functions include:&lt;br /&gt;
:* widget_install() - will be called during the installation of the module&lt;br /&gt;
:* widget_add_instance() - code to add a new instance of widget&lt;br /&gt;
:* widget_update_instance() - code to update an existing instance&lt;br /&gt;
:* widget_delete_instance() - code to delete an instance&lt;br /&gt;
:* widget_user_outline() - given an instance, return a summary of a user&#039;s contribution&lt;br /&gt;
:* widget_user_complete() - given an instance, print details of a user&#039;s contribution&lt;br /&gt;
:* Other functions available but not required are:&lt;br /&gt;
:** widget_delete_course() - code to clean up anything that would be leftover after all instances are deleted&lt;br /&gt;
:** widget_process_options() - code to pre-process the form data from module settings&lt;br /&gt;
:** [[Implementing Reset course functionality in a module|widget_reset_course_form() and widget_delete_userdata()]] - used to implement [[Reset course]] feature.&lt;br /&gt;
:* To avoid possible conflict, any module functions should be named starting with widget_ and any constants you define should start with WIDGET_&lt;br /&gt;
* &#039;&#039;config.html&#039;&#039; - (optional) a form to set up or update global settings of this module&lt;br /&gt;
* &#039;&#039;lang/en_utf8/resource_widget.php&#039;&#039; - (optional) Lastly, each module will have some language files that contain strings for that module.&lt;br /&gt;
&lt;br /&gt;
IMPORTANT: When creating a new module, the new name of the module must not contain numbers or other special characters! &lt;br /&gt;
&lt;br /&gt;
You should also make sure that your activity module provides appropriate support for groups and metacourses. &lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* Tracker issue [http://tracker.moodle.org/browse/CONTRIB-52 CONTRIB-52 Improvements to make NEWMODULE really useful] - including download link for new module template supporting roles, formslib etc. (unfinished) &lt;br /&gt;
* http://download.moodle.org/plugins16/mod/NEWMODULE.zip - new module template for versions of Moodle prior to 1.7. Please follow the README instructions inside the zip.&lt;br /&gt;
* Using Moodle [http://moodle.org/course/view.php?id=5 Activity modules] forum&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/discuss.php?d=66165 A new resource type: where do I put the language strings?] forum discussion&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/discuss.php?d=65986 New Module Template Code for Moodle 1.7] forum discussion&lt;br /&gt;
&lt;br /&gt;
[[Category:Modules]]&lt;br /&gt;
[[Category:Modules]]&lt;br /&gt;
&lt;br /&gt;
[[es:Módulos de actividades (desarrollador)]]&lt;br /&gt;
[[fr:Modules (développeur)]]&lt;br /&gt;
[[ja:モジュール (開発者)]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Releases&amp;diff=26017</id>
		<title>Releases</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Releases&amp;diff=26017"/>
		<updated>2007-12-12T05:04:52Z</updated>

		<summary type="html">&lt;p&gt;Scyrma: /* Moodle 1.9 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Release History==&lt;br /&gt;
&lt;br /&gt;
See [[Release_Notes|Release Notes]] for more details.&lt;br /&gt;
&lt;br /&gt;
==Moodle 1.0==&lt;br /&gt;
*Moodle 1.0 - 20 August 2002&lt;br /&gt;
*Moodle 1.0.1 - 26 August 2002&lt;br /&gt;
*Moodle 1.0.2 - 2 September 2002&lt;br /&gt;
*Moodle 1.0.3 - 5 September 2002&lt;br /&gt;
*Moodle 1.0.4 - 10 September 2002&lt;br /&gt;
*Moodle 1.0.5 - 27 September 2002&lt;br /&gt;
*Moodle 1.0.6 - 26 October 2002&lt;br /&gt;
:: 1.0.6.1 - 6 Nov&lt;br /&gt;
:: 1.0.6.2 - 11 Nov&lt;br /&gt;
:: 1.0.6.3 - 14 Nov&lt;br /&gt;
:: 1.0.6.4 - 25 Nov&lt;br /&gt;
*Moodle 1.0.7 - 9 December 2002&lt;br /&gt;
*Moodle 1.0.8 - 7 January 2003&lt;br /&gt;
*Moodle 1.0.9 - 30 May 2003&lt;br /&gt;
&lt;br /&gt;
==Moodle 1.1==&lt;br /&gt;
*Moodle 1.1 - 29 August 2003&lt;br /&gt;
*Moodle 1.1.1 - 11 September 2003&lt;br /&gt;
&lt;br /&gt;
==Moodle 1.2==&lt;br /&gt;
*Moodle 1.2 - 20 March 2004&lt;br /&gt;
*Moodle 1.2.1 - 25 March 2004&lt;br /&gt;
&lt;br /&gt;
==Moodle 1.3==&lt;br /&gt;
*Moodle 1.3 - 25 May 2004&lt;br /&gt;
*Moodle 1.3.1 - 4 June 2004&lt;br /&gt;
*Moodle 1.3.2 - 9 July 2004&lt;br /&gt;
*Moodle 1.3.3 - 16 July 2004&lt;br /&gt;
*Moodle 1.3.4 - 11 August 2004&lt;br /&gt;
&lt;br /&gt;
==Moodle 1.4==&lt;br /&gt;
*Moodle 1.4 - 31 August 2004&lt;br /&gt;
*Moodle 1.4.1 - 12 September 2004&lt;br /&gt;
*Moodle 1.4.2 - 5 November 2004&lt;br /&gt;
*Moodle 1.4.3 - 21 December 2004&lt;br /&gt;
*Moodle 1.4.4 - 7 March 2005 &lt;br /&gt;
*Moodle 1.4.5 - 7 May 2005&lt;br /&gt;
&lt;br /&gt;
==Moodle 1.5==&lt;br /&gt;
*Moodle 1.5   - 5 June 2005&lt;br /&gt;
*Moodle 1.5.1 - 8 July 2005&lt;br /&gt;
*Moodle 1.5.2 - 16 July 2005&lt;br /&gt;
*Moodle 1.5.3 - 11 November 2005&lt;br /&gt;
*Moodle 1.5.4 - 21 May 2006&lt;br /&gt;
&lt;br /&gt;
==Moodle 1.6==&lt;br /&gt;
*Moodle 1.6   - 20 June 2006&lt;br /&gt;
*Moodle 1.6.1 - 20 July 2006&lt;br /&gt;
*Moodle 1.6.2 - 12 September 2006&lt;br /&gt;
*Moodle 1.6.3 - 10 October 2006&lt;br /&gt;
*Moodle 1.6.4 - 17 January 2007&lt;br /&gt;
*Moodle 1.6.5 - 30 March 2007&lt;br /&gt;
&lt;br /&gt;
==Moodle 1.7==&lt;br /&gt;
*Moodle 1.7 - 7 November 2006&lt;br /&gt;
*Moodle 1.7.1 - 17 January 2007&lt;br /&gt;
*Moodle 1.7.2 - 30 March 2007&lt;br /&gt;
*Moodle 1.7.3 - 11 October 2007&lt;br /&gt;
&lt;br /&gt;
==Moodle 1.8==&lt;br /&gt;
*Moodle 1.8 - 30 March 2007&lt;br /&gt;
*Moodle 1.8.1 - 14 June 2007&lt;br /&gt;
*Moodle 1.8.2 - 8 July 2007&lt;br /&gt;
*Moodle 1.8.3 - 11 October 2007&lt;br /&gt;
&lt;br /&gt;
==Moodle 1.9==&lt;br /&gt;
*Moodle 1.9 beta 2 - 11 October 2007&lt;br /&gt;
*Moodle 1.9 beta 3 - 6 December 2007&lt;br /&gt;
&lt;br /&gt;
[[Category:Administrator]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
&lt;br /&gt;
[[fr:Historique des versions]]&lt;br /&gt;
[[es:Historia de las versiones]]&lt;/div&gt;</summary>
		<author><name>Scyrma</name></author>
	</entry>
</feed>