<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ca">
	<id>https://docs.moodle.org/2x/ca/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Davidkazuhiro</id>
	<title>MoodleDocs - Contribucions de l&amp;#039;usuari [ca]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.moodle.org/2x/ca/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Davidkazuhiro"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/2x/ca/Especial:Contribucions/Davidkazuhiro"/>
	<updated>2026-04-21T02:45:05Z</updated>
	<subtitle>Contribucions de l&amp;#039;usuari</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/2x/ca/index.php?title=Moodle_in_education&amp;diff=52873</id>
		<title>Moodle in education</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/2x/ca/index.php?title=Moodle_in_education&amp;diff=52873"/>
		<updated>2009-03-16T16:18:07Z</updated>

		<summary type="html">&lt;p&gt;Davidkazuhiro: reverting to previous version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Teacher documentation}}&lt;br /&gt;
* &#039;&#039;&#039;[[Getting started for teachers|Getting started for teachers page link]]&#039;&#039;&#039; - New at this Moodle thing? The &amp;quot;Getting started&amp;quot; page gives a general overview of all the features of a course.  There are lots of internal links that will allow you to expand your knowledge.  Welcome !&lt;br /&gt;
&lt;br /&gt;
You can get back to this page by using the Teacher link in the Documentation menu on the left on most MoodleDoc pages.&lt;br /&gt;
&lt;br /&gt;
==Reference==&lt;br /&gt;
*[[:Category:Teacher]] - a list of links to &amp;quot;Teacher&amp;quot; related pages&lt;br /&gt;
*[[Moodle manuals]] - a list of links to manuals and books&lt;br /&gt;
*[[Using Moodle book]] - a real book you can reprint!&lt;br /&gt;
&lt;br /&gt;
==Guidelines==&lt;br /&gt;
*[[Blogs]] - blogs in Moodle&lt;br /&gt;
*[[Teaching with Moodle]] - inspiring links&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=66854 Moodle and elearning intro] - Written by Martin Langhoff&lt;br /&gt;
*[[Teaching do&#039;s and don&#039;ts|Teaching Do&#039;s and Don&#039;ts]] - hints&lt;br /&gt;
*[[Teaching FAQ]] - common questions&lt;br /&gt;
*[http://moodle.tokem.fi/mod/book/view.php?id=16397&amp;amp;chapterid=8258 Example of a course teaching checklist]&lt;br /&gt;
*[http://moodle.tokem.fi/mod/book/view.php?id=16397 Teacher&#039;s Moodle Manual] - site specific, done in Moodle with the book module&lt;br /&gt;
*[http://www.houseoftutorials.net/ Video Tutorials on how to use Moodle] (go to the learning Moodle section and login as guest)&lt;br /&gt;
*[[Teaching tips and tricks]]&lt;br /&gt;
*[[Student documentation examples]]&lt;br /&gt;
*[[Student FAQ]] - students have questions about technology?&lt;br /&gt;
*[[Trainer]] - links that might be useful to Trainers&lt;br /&gt;
*Non Internet Moodles - useful for course building and sandboxes&lt;br /&gt;
:[[Complete install packages]] design course on your desktop&lt;br /&gt;
:[[Installation guide - Moodle for Windows on a USB Memory Stick]]&lt;br /&gt;
:[[Development:Windows_Installer_anywhere]] &lt;br /&gt;
&lt;br /&gt;
[[Category:Teacher]]&lt;br /&gt;
[[cs:Rukověť učitele]]&lt;br /&gt;
[[de:Dokumentation für Trainer]]&lt;br /&gt;
[[es:Documentación para Profesores]]&lt;br /&gt;
[[eu:Irakasleentzako dokumentazioa]]&lt;br /&gt;
[[fi:Opettajan opas]]&lt;br /&gt;
[[fr:Documentation enseignant]]&lt;br /&gt;
[[it:Documentazione per Docenti]]&lt;br /&gt;
[[ja:教師ドキュメント]]&lt;br /&gt;
[[nl:Documentatie voor leraren]]&lt;br /&gt;
[[ru:Учителям]]&lt;br /&gt;
[[zh:教师文档]]&lt;/div&gt;</summary>
		<author><name>Davidkazuhiro</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/2x/ca/index.php?title=Broken/Blocks&amp;diff=48574</id>
		<title>Broken/Blocks</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/2x/ca/index.php?title=Broken/Blocks&amp;diff=48574"/>
		<updated>2009-01-04T00:37:27Z</updated>

		<summary type="html">&lt;p&gt;Davidkazuhiro: /* Configure That Out */ spelling&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039; A Step-by-step Guide To Creating Blocks &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Original Author: Jon Papaioannou (pj@moodle.org)&lt;br /&gt;
&lt;br /&gt;
The present document serves as a guide to developers who want to create their own blocks for use in Moodle. It applies to the 1.5 development version of Moodle (and any newer) &#039;&#039;&#039;only&#039;&#039;&#039;, as the blocks subsystem was rewritten and expanded for the 1.5 release. However, you can also find it useful if you want to modify blocks written for Moodle 1.3 and 1.4 to work with the latest versions (look at [[Blocks_Howto#appendix_b| Appendix B]]).&lt;br /&gt;
The guide is written as an interactive course which aims to develop a configurable, multi-purpose block that displays arbitrary HTML. It&#039;s targeted mainly at people with little experience with Moodle or programming in general and aims to show how easy it is to create new blocks for Moodle. A certain small amount of PHP programming knowledge is still required, though. Experienced developers and those who just want a reference text should refer to [[Blocks_Howto#appendix_a| Appendix A]] because the main guide has a rather low concentration of pure information in the text.&lt;br /&gt;
&lt;br /&gt;
== Basic Concepts ==&lt;br /&gt;
Through this guide, we will be following the creation of an &amp;quot;HTML&amp;quot; block from scratch in order to demonstrate most of the block features at our disposal. Our block will be named &amp;quot;SimpleHTML&amp;quot;. This does not constrain us regarding the name of the actual directory on the server where the files for our block will be stored, but for consistency we will follow the practice of using the lowercased form &amp;quot;simplehtml&amp;quot; in any case where such a name is required. Whenever we refer to a file or directory name which contains &amp;quot;simplehtml&amp;quot;, it&#039;s important to remember that &#039;&#039;only&#039;&#039; the &amp;quot;simplehtml&amp;quot; part is up to us to change; the rest is standardized and essential for Moodle to work correctly.&lt;br /&gt;
Whenever a file&#039;s path is mentioned in this guide, it will always start with a slash. This refers to the Moodle home directory; all files and directories will be referred to with respect to that directory.&lt;br /&gt;
&lt;br /&gt;
== Ready, Set, Go! ==&lt;br /&gt;
To define a &amp;quot;block&amp;quot; in Moodle, in the most basic case we need to provide just one source code file. We start by creating the directory &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/&amp;lt;/span&amp;gt; and creating a file named &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/block_simplehtml.php&amp;lt;/span&amp;gt; which will hold our code. We then begin coding the block:&lt;br /&gt;
     &amp;lt;?php&lt;br /&gt;
     class block_simplehtml extends block_base {&lt;br /&gt;
     function init() {&lt;br /&gt;
         $this-&amp;gt;title = get_string(&#039;simplehtml&#039;, &#039;block_simplehtml&#039;);&lt;br /&gt;
         $this-&amp;gt;version = 2004111200;&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
The first line is our block class definition; it must be named exactly in the manner shown. Again, only the &amp;quot;simplehtml&amp;quot; part can (and indeed must) change; everything else is standardized.&lt;br /&gt;
Our class is then given a small method: [[Blocks_Howto#method_init| init]]. This is essential for all blocks, and its purpose is to set the two class member variables listed inside it. But what do these values actually mean? Here&#039;s a more detailed description.&lt;br /&gt;
[[Blocks_Howto#variable_title| $this-&amp;gt;title]] is the title displayed in the header of our block. We can set it to whatever we like; in this case it&#039;s set to read the actual title from a language file we are presumably distributing together with the block. I &#039;ll skip ahead a bit here and say that if you want your block to display &#039;&#039;&#039;no&#039;&#039;&#039; title at all, then you should set this to any descriptive value you want (but &#039;&#039;&#039;not&#039;&#039;&#039; make it an empty string). We will later see [[Blocks_Howto#section_eye_candy| how to disable the title&#039;s display]].&lt;br /&gt;
[[Blocks_Howto#variable_version| $this-&amp;gt;version]] is the version of our block. This actually would only make a difference if your block wanted to keep its own data in special tables in the database (i.e. for very complex blocks). In that case the version number is used exactly as it&#039;s used in activities; an upgrade script uses it to incrementally upgrade an &amp;quot;old&amp;quot; version of the block&#039;s data to the latest. We will outline this process further ahead, since blocks tend to be relatively simple and not hold their own private data. In our example, &lt;br /&gt;
this is certainly the case so we just set [[Blocks_Howto#variable_version| $this-&amp;gt;version]] to &#039;&#039;&#039;YYYYMMDD00&#039;&#039;&#039; and forget about it.&lt;br /&gt;
&#039;&#039;&#039;UPDATING:&#039;&#039;&#039; Prior to version 1.5, the basic structure of each block class was slightly different. Refer to [[Blocks_Howto#appendix_b| Appendix B]] for more information on the changes that old blocks have to make to conform to the new standard.&lt;br /&gt;
&lt;br /&gt;
== I Just Hear Static ==&lt;br /&gt;
In order to get our block to actually display something on screen, we need to add one more method to our class (before the final closing brace in our file). The new code is:&lt;br /&gt;
 function get_content() {&lt;br /&gt;
     if ($this-&amp;gt;content !== NULL) {&lt;br /&gt;
         return $this-&amp;gt;content;&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     $this-&amp;gt;content = new stdClass;&lt;br /&gt;
     $this-&amp;gt;content-&amp;gt;text = &#039;The content of our SimpleHTML block!&#039;;&lt;br /&gt;
     $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
 &lt;br /&gt;
     return $this-&amp;gt;content;&lt;br /&gt;
 }&lt;br /&gt;
 }&lt;br /&gt;
 ?&amp;gt;&lt;br /&gt;
It can&#039;t get any simpler than that, can it? Let&#039;s dissect this method to see what&#039;s going on...&lt;br /&gt;
First of all, there is a check that returns the current value of [[Blocks_Howto#variable_content| $this-&amp;gt;content]] if it&#039;s not NULL; otherwise we proceed with &amp;quot;computing&amp;quot; it. Since the computation is potentially a time-consuming operation and it &#039;&#039;&#039;will&#039;&#039;&#039; be called several times for each block (Moodle works that way internally), we take a precaution and include this time-saver.&lt;br /&gt;
Supposing the content had not been computed before (it was NULL), we then define it from scratch. The code speaks for itself there, so there isn&#039;t much to say. Just keep in mind that we can use HTML both in the text &#039;&#039;&#039;and&#039;&#039;&#039; in the footer, if we want to.&lt;br /&gt;
At this point our block should be capable of being automatically installed in Moodle and added to courses; visit your administration page to install it and after seeing it in action come back to continue our tutorial.&lt;br /&gt;
&lt;br /&gt;
== Configure That Out ==&lt;br /&gt;
The current version of our block doesn&#039;t really do much; it just displays a fixed message, which is not very useful. What we &#039;d really like to do is allow the teachers to customize what goes into the block. This, in block-speak, is called &amp;quot;instance configuration&amp;quot;. So let&#039;s give our block some instance configuration...&lt;br /&gt;
First of all, we need to tell Moodle that we want it to provide instance-specific configuration amenities to our block. That&#039;s as simple as adding one more method to our block class:&lt;br /&gt;
 function instance_allow_config() {&lt;br /&gt;
     return true;&lt;br /&gt;
 }&lt;br /&gt;
This small change is enough to make Moodle display an &amp;quot;Edit...&amp;quot; icon in our block&#039;s header when we turn editing mode on in any course. However, if you try to click on that icon you will be presented with a notice that complains about the block&#039;s configuration not being implemented correctly. Try it, it&#039;s harmless.&lt;br /&gt;
Moodle&#039;s complaints do make sense. We told it that we want to have configuration, but we didn&#039;t say &#039;&#039;what&#039;&#039; kind of configuration we want, or how it should be displayed. To do that, we need to create one more file: &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/config_instance.html&amp;lt;/span&amp;gt; (which has to be named exactly like that). For the moment, copy paste the following into it and save:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;table cellpadding=&amp;quot;9&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&lt;br /&gt;
         &amp;lt;?php print_string(&#039;configcontent&#039;, &#039;block_simplehtml&#039;); ?&amp;gt;:&lt;br /&gt;
     &amp;lt;/td&amp;gt;&lt;br /&gt;
     &amp;lt;td&amp;gt;&lt;br /&gt;
         &amp;lt;?php print_textarea(true, 10, 50, 0, 0, &#039;text&#039;, $this-&amp;gt;config-&amp;gt;text); ?&amp;gt;&lt;br /&gt;
     &amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
     &amp;lt;td colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
         &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;&amp;lt;?php print_string(&#039;savechanges&#039;) ?&amp;gt;&amp;quot; /&amp;gt;&lt;br /&gt;
     &amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
 &amp;lt;?php use_html_editor(); ?&amp;gt;&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
It isn&#039;t difficult to see that the above code just provides us with a wysiwyg-editor-enabled textarea to write our block&#039;s desired content in and a submit button to save. But... what&#039;s $this-&amp;gt;config-&amp;gt;text? Well...&lt;br /&gt;
Moodle goes a long way to make things easier for block developers. Did you notice that the textarea is actually named &amp;quot;text&amp;quot;? When the submit button is pressed, Moodle saves each and every field it can find in our &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;config_instance.html&amp;lt;/span&amp;gt; file as instance configuration data. We can then access that data as &#039;&#039;&#039;$this-&amp;gt;config-&amp;gt;&#039;&#039;variablename&#039;&#039;&#039;&#039;&#039;, where &#039;&#039;variablename&#039;&#039; is the actual name we used for our field; in this case, &amp;quot;text&amp;quot;. So in essence, the above form just pre-populates the textarea with the current content of the block (as indeed it should) and then allows us to change it.&lt;br /&gt;
You also might be surprised by the presence of a submit button and the absence of any &amp;lt;form&amp;gt; element at the same time. But the truth is, we don&#039;t need to worry about that at all; Moodle goes a really long way to make things easier for developers! We just print the configuration options we want, in any format we want; include a submit button, and Moodle will handle all the rest itself. The instance configuration variables are automatically at our disposal to access from any of the class methods &#039;&#039;except&#039;&#039; [[Blocks_Howto#method_init| init]].&lt;br /&gt;
In the event where the default behavior is not satisfactory, we can still override it. However, this requires advanced modifications to our block class and will not be covered here; refer to [[Blocks_Howto#appendix_a| Appendix A]] for more details.&lt;br /&gt;
Having now the ability to refer to this instance configuration data through [[Blocks_Howto#variable_config| $this-&amp;gt;config]], the final twist is to tell our block to actually &#039;&#039;display&#039;&#039; what is saved in its configuration data. To do that, find this snippet in &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/block_simplehtml.php&amp;lt;/span&amp;gt;&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 $this-&amp;gt;content = new stdClass;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;text = &#039;The content of our SimpleHTML block!&#039;;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
and change it to:&lt;br /&gt;
 &lt;br /&gt;
 $this-&amp;gt;content = new stdClass;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;text = $this-&amp;gt;config-&amp;gt;text;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
Oh, and since the footer isn&#039;t really exciting at this point, we remove it from our block because it doesn&#039;t contribute anything. We could just as easily have decided to make the footer configurable in the above way, too. So for our latest code, the snippet becomes:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 $this-&amp;gt;content = new stdClass;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;text = $this-&amp;gt;config-&amp;gt;text;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;footer = &#039;&#039;;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
After this discussion, our block is ready for prime time! Indeed, if you now visit any course with a SimpleHTML block, you will see that modifying its contents is now a snap.&lt;br /&gt;
&lt;br /&gt;
== The Specialists ==&lt;br /&gt;
Implementing instance configuration for the block&#039;s contents was good enough to whet our appetite, but who wants to stop there? Why not customize the block&#039;s title, too?&lt;br /&gt;
Why not, indeed. Well, our first attempt to achieve this is natural enough: let&#039;s add another field to &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/config_instance.html&amp;lt;/span&amp;gt;. Here goes:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;p&amp;gt;&amp;lt;?php print_string(&#039;configtitle&#039;, &#039;block_simplehtml&#039;); ?&amp;gt;:&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
     &amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;title&amp;quot; size=&amp;quot;30&amp;quot; value=&amp;quot;&amp;lt;?php echo $this-&amp;gt;config-&amp;gt;title; ?&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
We save the edited file, go to a course, edit the title of the block and... nothing happens! The instance configuration is saved correctly, all right (editing it once more proves that) but it&#039;s not being displayed. All we get is just the simple &amp;quot;SimpleHTML&amp;quot; title.&lt;br /&gt;
That&#039;s not too wierd, if we think back a bit. Do you remember that [[Blocks_Howto#method_init| init]] method, where we set [[Blocks_Howto#variable_title| $this-&amp;gt;title]]? We didn&#039;t actually change its value from then, and [[Blocks_Howto#variable_title| $this-&amp;gt;title]] is definitely not the same as $this-&amp;gt;config-&amp;gt;title (to Moodle, at least). What we need is a way to update [[Blocks_Howto#variable_title| $this-&amp;gt;title]] with the value in the instance configuration. But as we said a bit earlier, we can use [[Blocks_Howto#variable_config| $this-&amp;gt;config]] in all methods &#039;&#039;except&#039;&#039; [[Blocks_Howto#method_init| init]]&amp;lt;nowiki&amp;gt;! So what can we do?&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Let&#039;s pull out another ace from our sleeve, and add this small method to our block class:&lt;br /&gt;
 &lt;br /&gt;
 function specialization() {&lt;br /&gt;
     if(!empty($this-&amp;gt;config-&amp;gt;title)){&lt;br /&gt;
         $this-&amp;gt;title = $this-&amp;gt;config-&amp;gt;title;&lt;br /&gt;
     }&lt;br /&gt;
     else{&lt;br /&gt;
         $this-&amp;gt;config-&amp;gt;title = &#039;&#039;&#039;&#039;&#039;&#039;&#039;;&lt;br /&gt;
     }&lt;br /&gt;
     if(empty($this-&amp;gt;config-&amp;gt;text)){&lt;br /&gt;
         $this-&amp;gt;config-&amp;gt;text = &#039;&#039;&#039;&#039;&#039;&#039;&#039;;&lt;br /&gt;
     }    &lt;br /&gt;
 }&lt;br /&gt;
Aha, here&#039;s what we wanted to do all along! But what&#039;s going on with the [[Blocks_Howto#method_specialization| specialization]] method?&lt;br /&gt;
This &amp;quot;magic&amp;quot; method has actually a very nice property: it&#039;s &#039;&#039;guaranteed&#039;&#039; to be automatically called by Moodle as soon as our instance configuration is loaded and available (that is, immediately after [[Blocks_Howto#method_init| init]] is called). That means before the block&#039;s content is computed for the first time, and indeed before &#039;&#039;anything&#039;&#039; else is done with the block. Thus, providing a [[Blocks_Howto#method_specialization| specialization]] method is the natural choice for any configuration data that needs to be acted upon &amp;quot;as soon as possible&amp;quot;, as in this case.&lt;br /&gt;
&lt;br /&gt;
== Now You See Me, Now You Don&#039;t ==&lt;br /&gt;
Now would be a good time to mention another nifty technique that can be used in blocks, and which comes in handy quite often. Specifically, it may be the case that our block will have something interesting to display some of the time; but in some other cases, it won&#039;t have anything useful to say. (An example here would be the &amp;quot;Recent Activity&amp;quot; block, in the case where no recent activity in fact exists. However in that case the block chooses to explicitly inform you of the lack of said activity, which is arguably useful). It would be nice, then, to be able to have our block &amp;quot;disappear&amp;quot; if it&#039;s not needed to display it.&lt;br /&gt;
This is indeed possible, and the way to do it is to make sure that after the [[Blocks_Howto#method_get_content| get_content]]&amp;lt;nowiki&amp;gt; method is called, the block is completely void of content. Specifically, &amp;quot;void of content&amp;quot; means that both $this-&amp;gt;content-&amp;gt;text and $this-&amp;gt;content-&amp;gt;footer are each equal to the empty string (&#039;&#039;). Moodle performs this check by calling the block&#039;s &amp;lt;/nowiki&amp;gt;[[Blocks_Howto#method_is_empty| is_empty()]] method, and if the block is indeed empty then it is not displayed at all.&lt;br /&gt;
Note that the exact value of the block&#039;s title and the presence or absence of a [[Blocks_Howto#method_hide_header| hide_header]] method do &#039;&#039;not&#039;&#039; affect this behavior. A block is considered empty if it has no content, irrespective of anything else.&lt;br /&gt;
== We Are Legion ==&lt;br /&gt;
Right now our block is fully configurable, both in title and content. It&#039;s so versatile, in fact, that we could make pretty much anything out of it. It would be really nice to be able to add multiple blocks of this type to a single course. And, as you might have guessed, doing that is as simple as adding another small method to our block class:&lt;br /&gt;
 &lt;br /&gt;
 function instance_allow_multiple() {&lt;br /&gt;
     return true;&lt;br /&gt;
 }&lt;br /&gt;
This tells Moodle that it should allow any number of instances of the SimpleHTML block in any course. After saving the changes to our file, Moodle immediately allows us to add multiple copies of the block without further ado!&lt;br /&gt;
There are a couple more of interesting points to note here. First of all, even if a block itself allows multiple instances in the same page, the administrator still has the option of disallowing such behavior. This setting can be set separately for each block from the Administration / Configuration / Blocks page.&lt;br /&gt;
And finally, a nice detail is that as soon as we defined an [[Blocks_Howto#method_instance_allow_multiple| instance_allow_multiple]] method, the method [[Blocks_Howto#method_instance_allow_config| instance_allow_config]] that was already defined became obsolete. Moodle assumes that if a block allows multiple instances of itself, those instances will want to be configured (what is the point of same multiple instances in the same page if they are identical?) and thus automatically provides an &amp;quot;Edit&amp;quot; icon. So, we can also remove the whole [[Blocks_Howto#method_instance_allow_config| instance_allow_config]] method now without harm. We had only needed it when multiple instances of the block were not allowed.&lt;br /&gt;
== The Effects of Globalization ==&lt;br /&gt;
Configuring each block instance with its own personal data is cool enough, but sometimes administrators need some way to &amp;quot;touch&amp;quot; all instances of a specific block at the same time. In the case of our SimpleHTML block, a few settings that would make sense to apply to all instances aren&#039;t that hard to come up with. For example, we might want to limit the contents of each block to only so many characters, or we might have a setting that filters HTML out of the block&#039;s contents, only allowing pure text in. Granted, such a feature wouldn&#039;t win us any awards for naming our block &amp;quot;SimpleHTML&amp;quot; but some tormented administrator somewhere might actually find it useful.&lt;br /&gt;
This kind of configuration is called &amp;quot;global configuration&amp;quot; and applies only to a specific block type (all instances of that block type are affected, however). Implementing such configuration for our block is quite similar to implementing the instance configuration. We will now see how to implement the second example, having a setting that only allows text and not HTML in the block&#039;s contents.&lt;br /&gt;
First of all, we need to tell Moodle that we want our block to provide global configuration by, what a surprise, adding a small method to our block class:&lt;br /&gt;
 &lt;br /&gt;
 function has_config() {&lt;br /&gt;
     return true;&lt;br /&gt;
 }&lt;br /&gt;
Then, we need to create a HTML file that actually prints out the configuration screen. In our case, we &#039;ll just print out a checkbox saying &amp;quot;Do not allow HTML in the content&amp;quot; and a &amp;quot;submit&amp;quot; button. Let&#039;s create the file &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/config_global.html&amp;lt;/span&amp;gt; which again must be named just so, and copy paste the following into it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;lt;div style=&amp;quot;text-align: center;&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;block_simplehtml_strict&amp;quot; value=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;block_simplehtml_strict&amp;quot; value=&amp;quot;1&amp;quot;&lt;br /&gt;
   &amp;lt;?php if(!empty($CFG-&amp;gt;block_simplehtml_strict)) echo &#039;checked=&amp;quot;checked&amp;quot;&#039;; ?&amp;gt; /&amp;gt;&lt;br /&gt;
 &amp;lt;?php print_string(&#039;donotallowhtml&#039;, &#039;block_simplehtml&#039;); ?&amp;gt;&lt;br /&gt;
 &amp;lt;p&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;&amp;lt;?php print_string(&#039;savechanges&#039;); ?&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
True to our block&#039;s name, this looks simple enough. What it does is that it displays a checkbox named &amp;quot;block_simplehtml_strict&amp;quot; and if the Moodle configuration variable with the same name (i.e., $CFG-&amp;gt;block_simplehtml_strict) is set and not empty (that means it&#039;s not equal to an empty string, to zero, or to boolean false) it displays the box as pre-checked (reflecting the current status). Why does it check the configuration setting with the same name? Because the default implementation of the global configuration saving code takes all the variables we have in our form and saves them as Moodle configuration options with the same name. Thus, it&#039;s good practice to use a descriptive name and also one that won&#039;t possibly conflict with the name of another setting. &amp;quot;block_simplehtml_strict&amp;quot; clearly satisfies both requirements.&lt;br /&gt;
The astute reader may have noticed that we actually have &#039;&#039;two&#039;&#039; input fields named &amp;quot;block_simplehtml_strict&amp;quot; in our configuration file. One is hidden and its value is always 0; the other is the checkbox and its value is 1. What gives? Why have them both there?&lt;br /&gt;
Actually, this is a small trick we use to make our job as simple as possible. HTML forms work this way: if a checkbox in a form is not checked, its name does not appear at all in the variables passed to PHP when the form is submitted. That effectively means that, when we uncheck the box and click submit, the variable is not passed to PHP at all. Thus, PHP does not know to update its value to &amp;quot;0&amp;quot;, and our &amp;quot;strict&amp;quot; setting cannot be turned off at all once we turn it on for the first time. Not the behavior we want, surely.&lt;br /&gt;
However, when PHP handles received variables from a form, the variables are processed in the order in which they appear in the form. If a variable comes up having the same name with an already-processed variable, the new value overwrites the old one. Taking advantage of this, our logic runs as follows: the variable &amp;quot;block_simplehtml_strict&amp;quot; is first unconditionally set to &amp;quot;0&amp;quot;. Then, &#039;&#039;if&#039;&#039; the box is checked, it is set to &amp;quot;1&amp;quot;, overwriting the previous value as discussed. The net result is that our configuration setting behaves as it should.&lt;br /&gt;
To round our bag of tricks up, notice that the use of if(!empty($CFG-&amp;gt;block_simplehtml_strict)) in the test for &amp;quot;should the box be checked by default?&amp;quot; is quite deliberate. The first time this script runs, the variable $CFG-&amp;gt;block_simplehtml_strict will not exist at all. After it&#039;s set for the first time, its value can be either &amp;quot;0&amp;quot; or &amp;quot;1&amp;quot;. Given that both &amp;quot;not set&amp;quot; and the string &amp;quot;0&amp;quot; evaluate as empty while the sting &amp;quot;1&amp;quot; does not, we manage to avoid any warnings from PHP regarding the variable not being set at all, &#039;&#039;and&#039;&#039; have a nice human-readable representation for its two possible values (&amp;quot;0&amp;quot; and &amp;quot;1&amp;quot;).&lt;br /&gt;
Now that we have managed to cram a respectable amount of tricks into a few lines of HTML, we might as well discuss the alternative in case that tricks are not enough for a specific configuration setup we have in mind. Saving the data is done in the method [[Blocks_Howto#method_config_save| config_save]], the default implementation of which is as follows:&lt;br /&gt;
 &lt;br /&gt;
 function config_save($data) {&lt;br /&gt;
     // Default behavior: save all variables as $CFG properties&lt;br /&gt;
     foreach ($data as $name =&amp;gt; $value) {&lt;br /&gt;
         set_config($name, $value);&lt;br /&gt;
     }&lt;br /&gt;
     return true;&lt;br /&gt;
 }&lt;br /&gt;
As can be clearly seen, Moodle passes this method an associative array $data which contains all the variables coming in from our configuration screen. If we wanted to do the job without the &amp;quot;hidden variable with the same name&amp;quot; trick we used above, one way to do it would be by overriding this method with the following:&lt;br /&gt;
 &lt;br /&gt;
 function config_save($data) {&lt;br /&gt;
     if(isset($data[&#039;block_simplehtml_strict&#039;])) {&lt;br /&gt;
         set_config(&#039;block_simplehtml_strict&#039;, &#039;1&#039;);&lt;br /&gt;
     }&lt;br /&gt;
     else {&lt;br /&gt;
         set_config(&#039;block_simplehtml_strict&#039;, &#039;0&#039;);&lt;br /&gt;
     }&lt;br /&gt;
     return true;&lt;br /&gt;
 }&lt;br /&gt;
Quite straightfoward: if the variable &amp;quot;block_simplehtml_strict&amp;quot; is passed to us, then it can only mean that the user has checked it, so set the configuration variable with the same name to &amp;quot;1&amp;quot;. Otherwise, set it to &amp;quot;0&amp;quot;. Of course, this version would need to be updated if we add more configuration options because it doesn&#039;t respond to them as the default implementation does. Still, it&#039;s useful to know how we can override the default implementation if it does not fit our needs (for example, we might not want to save the variable as part of the Moodle configuration but do something else with it).&lt;br /&gt;
So, we are now at the point where we know if the block should allow HTML tags in its content or not. How do we get the block to actually respect that setting?&lt;br /&gt;
We could decide to do one of two things: either have the block &amp;quot;clean&amp;quot; HTML out from the input before saving it in the instance configuration and then display it as-is (the &amp;quot;eager&amp;quot; approach); or have it save the data &amp;quot;as is&amp;quot; and then clean it up each time just before displaying it (the &amp;quot;lazy&amp;quot; approach). The eager approach involves doing work once when saving the configuration; the lazy approach means doing work each time the block is displayed and thus it promises to be worse performance-wise. We shall hence go with the eager approach.&lt;br /&gt;
Much as we did just before with overriding [[Blocks_Howto#method_config_save| config_save]], what is needed here is overriding the method [[Blocks_Howto#method_instance_config_save| instance_config_save]] which handles the instance configuration. The default implementation is as follows:&lt;br /&gt;
 &lt;br /&gt;
 function instance_config_save($data) {&lt;br /&gt;
     $data = stripslashes_recursive($data);&lt;br /&gt;
     $this-&amp;gt;config = $data;&lt;br /&gt;
     return set_field(&#039;block_instance&#039;, &#039;configdata&#039;, base64_encode(serialize($data)),&lt;br /&gt;
                      &#039;id&#039;, $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
 }&lt;br /&gt;
This may look intimidating at first (what&#039;s all this stripslashes_recursive() and base64_encode() and serialize() stuff?) but do not despair; we won&#039;t have to touch any of it. We will only add some extra validation code in the beginning and then instruct Moodle to additionally call this default implementation to do the actual storing of the data. Specifically, we will add a method to our class which goes like this:&lt;br /&gt;
 &lt;br /&gt;
 function instance_config_save($data) {&lt;br /&gt;
     // Clean the data if we have to&lt;br /&gt;
     global $CFG;&lt;br /&gt;
     if(!empty($CFG-&amp;gt;block_simplehtml_strict)) {&lt;br /&gt;
         $data-&amp;gt;text = strip_tags($data-&amp;gt;text);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     // And now forward to the default implementation defined in the parent class&lt;br /&gt;
     return parent::instance_config_save($data);&lt;br /&gt;
 }&lt;br /&gt;
At last! Now the administrator has absolute power of life and death over what type of content is allowed in our &amp;quot;SimpleHTML&amp;quot; block! Absolute? Well... not exactly. In fact, if we think about it for a while, it will become apparent that if at some point in time HTML is allowed and some blocks have saved their content with HTML included, and afterwards the administrator changes the setting to &amp;quot;off&amp;quot;, this will only prevent subsequent content changes from including HTML. Blocks which already had HTML in their content would continue to display it!&lt;br /&gt;
Following that train of thought, the next stop is realizing that we wouldn&#039;t have this problem if we had chosen the lazy approach a while back, because in that case we would &amp;quot;sanitize&amp;quot; each block&#039;s content just before it was displayed. The only thing we can do with the eager approach is strip all the tags from the content of all SimpleHTML instances as soon as the admin setting is changed to &amp;quot;HTML off&amp;quot;; but even then, turning the setting back to &amp;quot;HTML on&amp;quot; won&#039;t bring back the tags we stripped away. On the other hand, the lazy approach might be slower, but it&#039;s more versatile; we can choose whether to strip or keep the HTML before displaying the content, and we won&#039;t lose it at all if the admin toggles the setting off and on again. Isn&#039;t the life of a developer simple and wonderful?&lt;br /&gt;
We will let this part of the tutorial come to a close with the obligatory excercise for the reader: in order to have the SimpleHTML block work &amp;quot;correctly&amp;quot;, find out how to strengthen the eager approach to strip out all tags from the existing configuration of all instances of our block, &#039;&#039;&#039;or&#039;&#039;&#039; go back and implement the lazy approach instead. (Hint: do that in the [[Blocks_Howto#method_get_content| get_content]] method)&lt;br /&gt;
&#039;&#039;&#039;UPDATING&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;: Prior to version 1.5, the file &amp;lt;/nowiki&amp;gt;&amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;config_global.html&amp;lt;/span&amp;gt; was named simply &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;config.html&amp;lt;/span&amp;gt;. Also, the methods [[Blocks_Howto#method_config_save| config_save]] and [[Blocks_Howto#method_config_print| config_print]] were named &#039;&#039;&#039;handle_config&#039;&#039;&#039; and &#039;&#039;&#039;print_config&#039;&#039;&#039; respectively. Upgrading a block to work with Moodle 1.5 involves updating these aspects; refer to [[Blocks_Howto#appendix_b| Appendix B]] for more information.&lt;br /&gt;
&lt;br /&gt;
== Eye Candy ==&lt;br /&gt;
Our block is just about complete functionally, so now let&#039;s take a look at some of the tricks we can use to make its behavior customized in a few more useful ways.&lt;br /&gt;
First of all, there are a couple of ways we can adjust the visual aspects of our block. For starters, it might be useful to create a block that doesn&#039;t display a header (title) at all. You can see this effect in action in the Course Description block that comes with Moodle. This behavior is achieved by, you guessed it, adding one more method to our block class:&lt;br /&gt;
 &lt;br /&gt;
 function hide_header() {&lt;br /&gt;
     return true;&lt;br /&gt;
 }&lt;br /&gt;
One more note here: we cannot just set an empty title inside the block&#039;s [[Blocks_Howto#method_init| init]] method; it&#039;s necessary for each block to have a unique, non-empty title after [[Blocks_Howto#method_init| init]] is called so that Moodle can use those titles to differentiate between all of the installed blocks.&lt;br /&gt;
Another adjustment we might want to do is instruct our block to take up a certain amount of width on screen. Moodle handles this as a two-part process: first, it queries each block about its preferred width and takes the maximum number as the desired value. Then, the page that&#039;s being displayed can choose to use this value or, more probably, bring it within some specific range of values if it isn&#039;t already. That means that the width setting is a best-effort settlement; your block can &#039;&#039;request&#039;&#039; a certain width and Moodle will &#039;&#039;try&#039;&#039; to provide it, but there&#039;s no guarantee whatsoever about the end result. As a concrete example, all standard Moodle course formats will deliver any requested width between 180 and 210 pixels, inclusive.&lt;br /&gt;
To instruct Moodle about our block&#039;s preferred width, we add one more method to the block class:&lt;br /&gt;
 &lt;br /&gt;
 function preferred_width() {&lt;br /&gt;
     // The preferred value is in pixels&lt;br /&gt;
     return 200;&lt;br /&gt;
 }&lt;br /&gt;
This will make our block (and all the other blocks displayed at the same side of the page) a bit wider than standard.&lt;br /&gt;
Finally, we can also affect some properties of the actual HTML that will be used to print our block. Each block is fully contained within a &amp;amp;lt;table&amp;amp;gt; element, inside which all the HTML for that block is printed. We can instruct Moodle to add HTML attributes with specific values to that container. This would be done to either a) directly affect the end result (if we say, assign bgcolor=&amp;quot;black&amp;quot;), or b) give us freedom to customize the end result using CSS (this is in fact done by default as we &#039;ll see below).&lt;br /&gt;
The default behavior of this feature in our case will assign to our block&#039;s container the class HTML attribute with the value &amp;quot;sideblock block_simplehtml&amp;quot; (the prefix &amp;quot;block_&amp;quot; followed by the name of our block, lowercased). We can then use that class to make CSS selectors in our theme to alter this block&#039;s visual style (for example, &amp;quot;.sideblock.block_simplehtml { border: 1px black solid}&amp;quot;).&lt;br /&gt;
To change the default behavior, we will need to define a method which returns an associative array of attribute names and values. For example, the version&lt;br /&gt;
 &lt;br /&gt;
 function html_attributes() {&lt;br /&gt;
     return array(&lt;br /&gt;
         &#039;class&#039;       =&amp;gt; &#039;sideblock block_&#039;. $this-&amp;gt;name(),&lt;br /&gt;
         &#039;onmouseover&#039; =&amp;gt; &amp;quot;alert(&#039;Mouseover on our block!&#039;);&amp;quot;&lt;br /&gt;
     );&lt;br /&gt;
 }&lt;br /&gt;
will result in a mouseover event being added to our block using JavaScript, just as if we had written the onmouseover=&amp;quot;alert(...)&amp;quot; part ourselves in HTML. Note that we actually duplicate the part which sets the class attribute (we want to keep that, and since we override the default behavior it&#039;s our responsibility to emulate it if required). And the final elegant touch is that we don&#039;t set the class to the hard-coded value &amp;quot;block_simplehtml&amp;quot; but instead use the [[Blocks_Howto#method_name| name]] method to make it dynamically match our block&#039;s name.&lt;br /&gt;
&lt;br /&gt;
== Authorized Personnel Only ==&lt;br /&gt;
It&#039;s not difficult to imagine a block which is very useful in some circumstances but it simply cannot be made meaningful in others. An example of this would be the &amp;quot;Social Activities&amp;quot; block which is indeed useful in a course with the social format, but doesn&#039;t do anything useful in a course with the weeks format. There should be some way of allowing the use of such blocks only where they are indeed meaningful, and not letting them confuse users if they are not.&lt;br /&gt;
Moodle allows us to declare which course formats each block is allowed to be displayed in, and enforces these restrictions as set by the block developers at all times. The information is given to Moodle as a standard associative array, with each key corresponding to a page format and defining a boolean value (true/false) that declares whether the block should be allowed to appear in that page format.&lt;br /&gt;
Notice the deliberate use of the term &#039;&#039;page&#039;&#039; instead of &#039;&#039;course&#039;&#039; in the above paragraph. This is because in Moodle 1.5 and onwards, blocks can be displayed in any page that supports them. The best example of such pages are the course pages, but we are not restricted to them. For instance, the quiz view page (the first one we see when we click on the name of the quiz) also supports blocks.&lt;br /&gt;
The format names we can use for the pages derive from the name of the script which is actually used to display that page. For example, when we are looking at a course, the script is &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/course/view.php&amp;lt;/span&amp;gt; (this is evident from the browser&#039;s address line). Thus, the format name of that page is &#039;&#039;&#039;course-view&#039;&#039;&#039;. It follows easily that the format name for a quiz view page is &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039;. This rule of thumb does have a few exceptions, however:&lt;br /&gt;
#* The format name for the front page of Moodle is &#039;&#039;&#039;site-index&#039;&#039;&#039;.&lt;br /&gt;
#* The format name for courses is actually not just &#039;&#039;&#039;course-view&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; it is &amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;course-view-weeks&#039;&#039;&#039;, &#039;&#039;&#039;course-view-topics&#039;&#039;&#039;, etc.&lt;br /&gt;
#* Even though there is no such page, the format name &#039;&#039;&#039;all&#039;&#039;&#039; can be used as a catch-all option.&lt;br /&gt;
We can include as many format names as we want in our definition of the applicable formats. Each format can be allowed or disallowed, and there are also three more rules that help resolve the question &amp;quot;is this block allowed into this page or not?&amp;quot;:&lt;br /&gt;
#* Prefixes of a format name will match that format name; for example, &#039;&#039;&#039;mod&#039;&#039;&#039; will match all the activity modules. &#039;&#039;&#039;course-view&#039;&#039;&#039; will match any course, regardless of the course format. And finally, &#039;&#039;&#039;site&#039;&#039;&#039; will also match the front page (remember that its full format name is &#039;&#039;&#039;site-index&#039;&#039;&#039;).&lt;br /&gt;
#* The more specialized a format name that matches our page is, the higher precedence it has when deciding if the block will be allowed. For example, &#039;&#039;&#039;mod&#039;&#039;&#039;, &#039;&#039;&#039;mod-quiz&#039;&#039;&#039; and &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; all match the quiz view page. But if all three are present, &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; will take precedence over the other two because it is a better match.&lt;br /&gt;
#* The character &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; can be used in place of any word. For example, &#039;&#039;&#039;mod&#039;&#039;&#039; and &#039;&#039;&#039;mod-*&#039;&#039;&#039; are equivalent. At the time of this document&#039;s writing, there is no actual reason to utilize this &amp;quot;wildcard matching&amp;quot; feature, but it exists for future usage.&lt;br /&gt;
#* The order that the format names appear does not make any difference.&lt;br /&gt;
All of the above are enough to make the situation sound complex, so let&#039;s look at some specific examples. First of all, to have our block appear &#039;&#039;&#039;only&#039;&#039;&#039; in the site front page, we would use:&lt;br /&gt;
 &lt;br /&gt;
 function applicable_formats() {&lt;br /&gt;
     return array(&#039;site&#039; =&amp;gt; true);&lt;br /&gt;
 }&lt;br /&gt;
Since &#039;&#039;&#039;all&#039;&#039;&#039; is missing, the block is disallowed from appearing in &#039;&#039;any&#039;&#039; course format; but then &#039;&#039;&#039;site&#039;&#039;&#039; is set to true, so it&#039;s explicitly allowed to appear in the site front page (remember that &#039;&#039;&#039;site&#039;&#039;&#039; matches &#039;&#039;&#039;site-index&#039;&#039;&#039; because it&#039;s a prefix).&lt;br /&gt;
For another example, if we wanted to allow the block to appear in all course formats &#039;&#039;except&#039;&#039; social, and also to &#039;&#039;not&#039;&#039; be allowed anywhere but in courses, we would use:&lt;br /&gt;
 &lt;br /&gt;
 function applicable_formats() {&lt;br /&gt;
     return array(&#039;course-view&#039; =&amp;gt; true, &#039;course-view-social&#039; =&amp;gt; false);&lt;br /&gt;
 }&lt;br /&gt;
This time, we first allow the block to appear in all courses and then we explicitly disallow the social format.&lt;br /&gt;
For our final, most complicated example, suppose that a block can be displayed in the site front page, in courses (but not social courses) and also when we are viewing any activity module, &#039;&#039;except&#039;&#039; quiz. This would be:&lt;br /&gt;
 &lt;br /&gt;
 function applicable_formats() {&lt;br /&gt;
     return array(&#039;site-index&#039; =&amp;gt; true,&lt;br /&gt;
                  &#039;course-view&#039; =&amp;gt; true, &#039;course-view-social&#039; =&amp;gt; false,&lt;br /&gt;
                  &#039;mod&#039; =&amp;gt; true, &#039;mod-quiz&#039; =&amp;gt; false);&lt;br /&gt;
 }&lt;br /&gt;
It is not difficult to realize that the above accomplishes the objective if we remember that there is a &amp;quot;best match&amp;quot; policy to determine the end result.&lt;br /&gt;
&#039;&#039;&#039;UPDATING:&#039;&#039;&#039; Prior to version 1.5, blocks were only allowed in courses (and in Moodle 1.4, in the site front page). Also, the keywords used to describe the valid course formats at the time were slightly different and had to be changed in order to allow for a more open architecture. Refer to [[Blocks_Howto#appendix_b| Appendix B]] for more information on the changes that old blocks have to make to conform to the new standard.&lt;br /&gt;
== Lists and Icons ==&lt;br /&gt;
In this final part of the guide we will briefly discuss an additional capability of Moodle&#039;s block system, namely the ability to very easily create blocks that display a list of choices to the user. This list is displayed with one item per line, and an optional image (icon) next to the item. An example of such a &#039;&#039;list block&#039;&#039; is the standard Moodle &amp;quot;admin&amp;quot; block, which illustrates all the points discussed in this section.&lt;br /&gt;
As we have seen so far, blocks use two properties of [[Blocks_Howto#variable_content| $this-&amp;gt;content]]&amp;lt;nowiki&amp;gt;: &amp;quot;text&amp;quot; and &amp;quot;footer&amp;quot;. The text is displayed as-is as the block content, and the footer is displayed below the content in a smaller font size. List blocks use $this-&amp;gt;content-&amp;gt;footer in the exact same way, but they ignore $this-&amp;gt;content-&amp;gt;text.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Instead, Moodle expects such blocks to set two other properties when the [[Blocks_Howto#method_get_content| get_content]] method is called: $this-&amp;gt;content-&amp;gt;items and $this-&amp;gt;content-&amp;gt;icons. $this-&amp;gt;content-&amp;gt;items should be a numerically indexed array containing elements that represent the HTML for each item in the list that is going to be displayed. Usually these items will be HTML anchor tags which provide links to some page. $this-&amp;gt;content-&amp;gt;icons should also be a numerically indexed array, with exactly as many items as $this-&amp;gt;content-&amp;gt;items has. Each of these items should be a fully qualified HTML &amp;lt;img&amp;gt; tag, with &amp;quot;src&amp;quot;, &amp;quot;height&amp;quot;, &amp;quot;width&amp;quot; and &amp;quot;alt&amp;quot; attributes. Obviously, it makes sense to keep the images small and of a uniform size.&lt;br /&gt;
In order to tell Moodle that we want to have a list block instead of the standard text block, we need to make a small change to our block class declaration. Instead of extending class &#039;&#039;&#039;block_base&#039;&#039;&#039;, our block will extend class &#039;&#039;&#039;block_list&#039;&#039;&#039;. For example:&lt;br /&gt;
 &lt;br /&gt;
 class block_my_menu extends block_list {&lt;br /&gt;
     // The init() method does not need to change at all&lt;br /&gt;
 }&lt;br /&gt;
In addition to making this change, we must of course also modify the [[Blocks_Howto#method_get_content| get_content]] method to construct the [[Blocks_Howto#variable_content| $this-&amp;gt;content]] variable as discussed above:&lt;br /&gt;
 &lt;br /&gt;
 function get_content() {&lt;br /&gt;
     if ($this-&amp;gt;content !== NULL) {&lt;br /&gt;
         return $this-&amp;gt;content;&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     $this-&amp;gt;content = new stdClass;&lt;br /&gt;
     $this-&amp;gt;content-&amp;gt;items = array();&lt;br /&gt;
     $this-&amp;gt;content-&amp;gt;icons = array();&lt;br /&gt;
     $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
 &lt;br /&gt;
     $this-&amp;gt;content-&amp;gt;items[] = &#039;&amp;lt;a href=&amp;quot;some_file.php&amp;quot;&amp;gt;Menu Option 1&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
     $this-&amp;gt;content-&amp;gt;icons[] = &#039;&amp;lt;img src=&amp;quot;images/icons/1.gif&amp;quot; class=&amp;quot;icon&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;&#039;;&lt;br /&gt;
 &lt;br /&gt;
     // Add more list items here&lt;br /&gt;
 &lt;br /&gt;
     return $this-&amp;gt;content;&lt;br /&gt;
 }&lt;br /&gt;
To summarize, if we want to create a list block instead of a text block, we just need to change the block class declaration and the [[Blocks_Howto#method_get_content| get_content]] method. Adding the mandatory [[Blocks_Howto#method_init| init]] method as discussed earlier will then give us our first list block in no time!&lt;br /&gt;
&lt;br /&gt;
== Appendix A: Reference ==&lt;br /&gt;
&lt;br /&gt;
This Appendix will discuss the base class &#039;&#039;&#039;block_base&#039;&#039;&#039; from which all other block classes derive, and present each and every method that can be overridden by block developers in detail. Methods that should &#039;&#039;&#039;not&#039;&#039;&#039; be overridden are explicitly referred to as such. After reading this Appendix, you will have a clear understanding of every method which you should or could override to implement functionality for your block.&lt;br /&gt;
&lt;br /&gt;
The methods are divided into three categories: those you may use and override in your block, those that you may &#039;&#039;&#039;not&#039;&#039;&#039; override but might want to use, and those internal methods that should &#039;&#039;&#039;neither&#039;&#039;&#039; be used &#039;&#039;&#039;nor&#039;&#039;&#039; overridden. In each category, methods are presented in alphabetical order.&lt;br /&gt;
&lt;br /&gt;
=== Methods you can freely use and override: ===&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;after_install&amp;lt;/div&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 function after_install() {&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Available in Moodle 1.7 and later&lt;br /&gt;
&lt;br /&gt;
This method is designed to be overridden by block subclasses, and allows you to specify a set of tasks to be executed after the block is installed.  For example, you may wish to store the date on which the block was installed.  However, each database type has its own way of getting the current date, and when using XMLDB to install your block, these operations are also unsupported. So the best way to complete such a task while maintaining database abstraction is to use XMLDB to install the block, and then use the after_install() method to perform the insertion before the block is used.&lt;br /&gt;
&lt;br /&gt;
Please note that after_install() is called once per block, not once per instance.&lt;br /&gt;
&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;applicable_formats&amp;lt;/div&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 function applicable_formats() {&lt;br /&gt;
     // Default case: the block can be used in courses and site index, but not in activities&lt;br /&gt;
     return array(&#039;all&#039; =&amp;gt; true, &#039;mod&#039; =&amp;gt; false);&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to control which pages your block can be added to. Page formats are formulated from the full path of the script that is used to display that page. You should return an array with the keys being page format names and the values being booleans (true or false). Your block is only allowed to appear in those formats where the value is true.&lt;br /&gt;
Example format names are: &#039;&#039;&#039;course-view&#039;&#039;&#039;, &#039;&#039;&#039;site-index&#039;&#039;&#039; (this is an exception, referring front page of the Moodle site), &#039;&#039;&#039;course-format-weeks&#039;&#039;&#039; (referring to a specific course format), &#039;&#039;&#039;mod-quiz&#039;&#039;&#039; (referring to the quiz module) and &#039;&#039;&#039;all&#039;&#039;&#039; (this will be used for those formats you have not explicitly allowed or disallowed).&lt;br /&gt;
The full matching rules are:&lt;br /&gt;
*** Prefixes of a format name will match that format name; for example, &#039;&#039;&#039;mod&#039;&#039;&#039; will match all the activity modules. &#039;&#039;&#039;course-view&#039;&#039;&#039; will match any course, regardless of the course format. And finally, &#039;&#039;&#039;site&#039;&#039;&#039; will also match the front page (remember that its full format name is &#039;&#039;&#039;site-index&#039;&#039;&#039;).&lt;br /&gt;
*** The more specialized a format name that matches our page is, the higher precedence it has when deciding if the block will be allowed. For example, &#039;&#039;&#039;mod&#039;&#039;&#039;, &#039;&#039;&#039;mod-quiz&#039;&#039;&#039; and &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; all match the quiz view page. But if all three are present, &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; will take precedence over the other two because it is a better match.&lt;br /&gt;
*** The character &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; can be used in place of any word. For example, &#039;&#039;&#039;mod&#039;&#039;&#039; and &#039;&#039;&#039;mod-*&#039;&#039;&#039; are equivalent. At the time of this document&#039;s writing, there is no actual reason to utilize this &amp;quot;wildcard matching&amp;quot; feature, but it exists for future usage.&lt;br /&gt;
*** The order that the format names appear does not make any difference.&lt;br /&gt;
&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;before_delete&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 function before_delete() {&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Available in Moodle 1.7 and later&lt;br /&gt;
&lt;br /&gt;
This method is called when an administrator removes a block from the Moodle installation, immediately before the relevant database tables are deleted.  It allows block authors to perform any necessary cleanup - removing temporary files and so on - before the block is deleted.&lt;br /&gt;
&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;config_print&amp;lt;/div&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 function config_print() {&lt;br /&gt;
     // Default behavior: print the config_global.html file&lt;br /&gt;
     // You don&#039;t need to override this if you&#039;re satisfied with the above&lt;br /&gt;
     if (!$this-&amp;gt;has_config()) {&lt;br /&gt;
         return false;&lt;br /&gt;
     }&lt;br /&gt;
     global $CFG, $THEME;&lt;br /&gt;
     print_simple_box_start(&#039;center&#039;, &#039;&#039;, $THEME-&amp;gt;cellheading);&lt;br /&gt;
     include($CFG-&amp;gt;dirroot.&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_global.html&#039;);&lt;br /&gt;
     print_simple_box_end();&lt;br /&gt;
     return true;&lt;br /&gt;
 }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to choose how to display the global configuration screen for your block. This is the screen that the administrator is presented with when he chooses &amp;quot;Settings...&amp;quot; for a specific block. Override it if you need something much more complex than the default implementation allows you to do. However, keep these points in mind:&lt;br /&gt;
**# If you save your configuration options in $CFG, you will probably need to use global $CFG; before including any HTML configuration screens.&lt;br /&gt;
**# The HTML &amp;lt;input&amp;gt; elements that you include in your method&#039;s output will be automatically enclosed in a &amp;lt;form&amp;gt; element. You do not need to worry about where and how that form is submitted; however, you &#039;&#039;&#039;must&#039;&#039;&#039; provide a way to submit it (i.e., an &amp;lt;input type=&amp;quot;submit&amp;quot; /&amp;gt;.&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;config_save&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function config_save($data) {&lt;br /&gt;
     // Default behavior: save all variables as $CFG properties&lt;br /&gt;
     // You don&#039;t need to override this if you &#039;re satisfied with the above&lt;br /&gt;
     foreach ($data as $name =&amp;gt; $value) {&lt;br /&gt;
         set_config($name, $value);&lt;br /&gt;
     }&lt;br /&gt;
     return true;&lt;br /&gt;
 }&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to override the storage mechanism for your global configuration data. The received argument is an associative array, with the keys being setting names and the values being setting values. The default implementation saves everything as Moodle $CFG variables.&lt;br /&gt;
Note that $data does not hold all of the submitted POST data because Moodle adds some hidden fields to the form in order to be able to process it. However, before calling this method it strips the hidden fields from the received data and so when this method is called only the &amp;quot;real&amp;quot; configuration data remain.&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;get_content&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function get_content() {&lt;br /&gt;
     // This should be implemented by the derived class.&lt;br /&gt;
     return NULL;&lt;br /&gt;
 }&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should, when called, populate the [[Blocks_Howto#variable_content| $this-&amp;gt;content]] variable of your block. Populating the variable means:&lt;br /&gt;
&#039;&#039;&#039;EITHER&#039;&#039;&#039;&amp;lt;br /&amp;gt;defining $this-&amp;gt;content-&amp;gt;text and $this-&amp;gt;content-&amp;gt;footer if your block derives from &#039;&#039;&#039;block_base&#039;&#039;&#039;. Both of these should be strings, and can contain arbitrary HTML.&lt;br /&gt;
&#039;&#039;&#039;OR&#039;&#039;&#039;&amp;lt;br /&amp;gt;defining $this-&amp;gt;content-&amp;gt;items, $this-&amp;gt;content-&amp;gt;icons and $this-&amp;gt;content-&amp;gt;footer if your block derives from &#039;&#039;&#039;block_list&#039;&#039;&#039;. The first two should be numerically indexed arrays having the exact same number of elements. $this-&amp;gt;content-&amp;gt;items is an array of strings that can contain arbitrary HTML while $this-&amp;gt;content-&amp;gt;icons also contains should strings, but those must be fully-qualified HTML &amp;lt;img&amp;gt; tags &#039;&#039;&#039;and nothing else&#039;&#039;&#039;. $this-&amp;gt;content-&amp;gt;footer is a string, as above.&lt;br /&gt;
If you set &#039;&#039;all&#039;&#039; of these variables to their default &amp;quot;empty&amp;quot; values (empty arrays for the arrays and empty strings for the strings), the block will &#039;&#039;&#039;not&#039;&#039;&#039; be displayed at all except to editing users. This is a good way of having your block hide itself to unclutter the screen if there is no reason to have it displayed.&lt;br /&gt;
Before starting to populate [[Blocks_Howto#variable_content| $this-&amp;gt;content]], you should also include a simple caching check. If [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is exactly equal to NULL then proceed as normally, while if it is not, return the existing value instead of calculating it once more. If you fail to do this, Moodle will suffer a performance hit.&lt;br /&gt;
In any case, your method should return the fully constructed [[Blocks_Howto#variable_content| $this-&amp;gt;content]] variable.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;has_config&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function has_config() {&lt;br /&gt;
     return false;&lt;br /&gt;
 }&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value that denotes whether your block wants to present a configuration interface to site admins or not. The configuration that this interface offers will impact all instances of the block equally.&lt;br /&gt;
To actually implement the configuration interface, you will either need to rely on the default [[Blocks_Howto#method_instance_config_print| config_print]] method or override it. The full guide contains [[Blocks_Howto#section_effects_of_globalization| more information on this]].&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;hide_header&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function hide_header() {&lt;br /&gt;
     //Default, false--&amp;gt; the header is shown&lt;br /&gt;
     return false;&lt;br /&gt;
 }&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value that denotes whether your block wants to hide its header (or title). Thus, if you override it to return true, your block will not display a title unless the current user is in editing mode.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;html_attributes&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function html_attributes() {&lt;br /&gt;
     // Default case: an id with the instance and a class with our name in it&lt;br /&gt;
     return array(&#039;id&#039; =&amp;gt; &#039;inst&#039;.$this-&amp;gt;instance-&amp;gt;id, &#039;class&#039; =&amp;gt; &#039;block_&#039;. $this-&amp;gt;name());&lt;br /&gt;
 }&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return an associative array of HTML attributes that will be given to your block&#039;s container element when Moodle constructs the output HTML. No sanitization will be performed in these elements at all.&lt;br /&gt;
If you intend to override this method, you should return the default attributes as well as those you add yourself. The recommended way to do this is:&lt;br /&gt;
 &lt;br /&gt;
 function html_attributes() {&lt;br /&gt;
     $attrs = parent::html_attributes();&lt;br /&gt;
     // Add your own attributes here, e.g.&lt;br /&gt;
     // $attrs[&#039;width&#039;] = &#039;50%&#039;;&lt;br /&gt;
     return $attrs;&lt;br /&gt;
 }&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;init&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function init() {&lt;br /&gt;
     $this-&amp;gt;title = get_string(&#039;simplehtml&#039;, &#039;block_simplehtml&#039;);&lt;br /&gt;
     $this-&amp;gt;version = 2004111200;&lt;br /&gt;
 }&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method must be implemented for all blocks. It has to assign meaningful values to the object variables [[Blocks_Howto#variable_title| $this-&amp;gt;title]] and [[Blocks_Howto#variable_version| $this-&amp;gt;version]] (which is used by Moodle for performing automatic updates when available).&lt;br /&gt;
No return value is expected from this method.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;instance_allow_config&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function instance_allow_config() {&lt;br /&gt;
     return false;&lt;br /&gt;
 }&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value. True indicates that your block wants to have per-instance configuration, while false means it does not. If you do want to implement instance configuration, you will need to take some additional steps apart from overriding this method; refer to the full guide for [[Blocks_Howto#section_configure_that_out| more information]].&lt;br /&gt;
This method&#039;s return value is irrelevant if [[Blocks_Howto#method_instance_allow_multiple| instance_allow_multiple]] returns true; it is assumed that if you want multiple instances then each instance needs its own configuration.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;instance_allow_multiple&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function instance_allow_multiple() {&lt;br /&gt;
     // Are you going to allow multiple instances of each block?&lt;br /&gt;
     // If yes, then it is assumed that the block WILL USE per-instance configuration&lt;br /&gt;
     return false;&lt;br /&gt;
 }&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value, indicating whether you want to allow multiple instances of this block in the same page or not. If you do allow multiple instances, it is assumed that you will also be providing per-instance configuration for the block. Thus, you will need to take some additional steps apart from overriding this method; refer to the full guide for [[Blocks_Howto#section_configure_that_out| more information]].&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;instance_config_print&amp;lt;/div&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 function instance_config_print() {&lt;br /&gt;
     // Default behavior: print the config_instance.html file&lt;br /&gt;
     // You don&#039;t need to override this if you&#039;re satisfied with the above&lt;br /&gt;
     if (!$this-&amp;gt;instance_allow_multiple() &amp;amp;&amp;amp; !$this-&amp;gt;instance_allow_config()) {&lt;br /&gt;
         return false;&lt;br /&gt;
     }&lt;br /&gt;
     global $CFG, $THEME;&lt;br /&gt;
 &lt;br /&gt;
     if (is_file($CFG-&amp;gt;dirroot .&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_instance.html&#039;)) {&lt;br /&gt;
         print_simple_box_start(&#039;center&#039;, &#039;&#039;, $THEME-&amp;gt;cellheading);&lt;br /&gt;
         include($CFG-&amp;gt;dirroot .&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_instance.html&#039;);&lt;br /&gt;
         print_simple_box_end();&lt;br /&gt;
     } else {&lt;br /&gt;
         notice(get_string(&#039;blockconfigbad&#039;),&lt;br /&gt;
                str_replace(&#039;blockaction=&#039;, &#039;dummy=&#039;, qualified_me()));&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     return true;&lt;br /&gt;
 }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to choose how to display the instance configuration screen for your block. Override it if you need something much more complex than the default implementation allows you to do. Keep in mind that whatever you do output from [[Blocks_Howto#method_instance_config_print| config_print]], it will be enclosed in a HTML form automatically. You only need to provide a way to submit that form.&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;instance_config_save&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function instance_config_save($data) {&lt;br /&gt;
     $data = stripslashes_recursive($data);&lt;br /&gt;
     $this-&amp;gt;config = $data;&lt;br /&gt;
     return set_field(&#039;block_instance&#039;, &#039;configdata&#039;, base64_encode(serialize($data)),&lt;br /&gt;
                      &#039;id&#039;, $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
 }&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to override the storage mechanism for your instance configuration data. The received argument is an associative array, with the keys being setting names and the values being setting values.&lt;br /&gt;
The configuration must be stored in the &amp;quot;configdata&amp;quot; field of your instance record in the database so that Moodle can auto-load it when your block is constructed. However, you may still want to override this method if you need to take some additional action apart from saving the data. In that case, you really should do what data processing you want and then call parent::instance_config_save($data) with your new $data array. This will keep your block from becoming broken if the default implementation of instance_config_save changes in the future.&lt;br /&gt;
Note that $data does not hold all of the submitted POST data because Moodle adds some hidden fields to the form in order to be able to process it. However, before calling this method it strips the hidden fields from the received data and so when this method is called only the &amp;quot;real&amp;quot; configuration data remain.&lt;br /&gt;
If you want to update the stored copy of the configuration data at run time (for example to persist some changes you made programmatically), you should not use this method. The correct procedure for that purpose is to call [[Blocks_Howto#method_instance_config_commit| instance_config_commit]].&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;preferred_width&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function preferred_width() {&lt;br /&gt;
     // Default case: the block wants to be 180 pixels wide&lt;br /&gt;
     return 180;&lt;br /&gt;
 }&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return an integer value, which is the number of pixels of width your block wants to take up when displayed. Moodle will try to honor your request, but this is actually up to the implementation of the format of the page your block is being displayed in and therefore no guarantee is given. You might get exactly what you want or any other width the format decides to give you, although obviously an effort to accomodate your block will be made.&lt;br /&gt;
Most display logic at this point allocates the maximum width requested by the blocks that are going to be displayed, bounding it both downwards and upwards to avoid having a bad-behaving block break the format.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;refresh_content&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function refresh_content() {&lt;br /&gt;
     // Nothing special here, depends on content()&lt;br /&gt;
     $this-&amp;gt;content = NULL;&lt;br /&gt;
     return $this-&amp;gt;get_content();&lt;br /&gt;
 }&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should cause your block to recalculate its content immediately. If you follow the guidelines for [[Blocks_Howto#get_content| get_content]], which say to respect the current content value unless it is NULL, then the default implementation will do the job just fine.&lt;br /&gt;
You should return the new value of [[Blocks_Howto#variable_content| $this-&amp;gt;content]] after refreshing it.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;specialization&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function specialization() {&lt;br /&gt;
     // Just to make sure that this method exists.&lt;br /&gt;
 }&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method is automatically called by the framework immediately after your instance data (which includes the page type and id and all instance configuration data) is loaded from the database. If there is some action that you need to take as soon as this data becomes available and which cannot be taken earlier, you should override this method.&lt;br /&gt;
The instance data will be available in the variables [[Blocks_Howto#variable_instance| $this-&amp;gt;instance]] and [[Blocks_Howto#variable_config| $this-&amp;gt;config]].&lt;br /&gt;
This method should not return anything at all.&lt;br /&gt;
=== Methods which you should &#039;&#039;not&#039;&#039; override but may want to use: ===&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;instance_config_commit&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function instance_config_commit() {&lt;br /&gt;
     return set_field(&#039;block_instance&#039;,&lt;br /&gt;
                      &#039;configdata&#039;, base64_encode(serialize($this-&amp;gt;config)),&lt;br /&gt;
                      &#039;id&#039;, $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
 }&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method saves the current contents of [[Blocks_Howto#variable_config| $this-&amp;gt;config]] to the database. If you need to make a change to the configuration settings of a block instance at run time (and not through the usual avenue of letting the user change it), just make the changes you want to [[Blocks_Howto#variable_config| $this-&amp;gt;config]] and then call this method.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;get_content_type&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function get_content_type() {&lt;br /&gt;
     return $this-&amp;gt;content_type;&lt;br /&gt;
 }&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;get_title&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function get_title() {&lt;br /&gt;
     return $this-&amp;gt;title;&lt;br /&gt;
 }&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_title| $this-&amp;gt;title]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;get_version&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function get_version() {&lt;br /&gt;
     return $this-&amp;gt;version;&lt;br /&gt;
 }&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_version| $this-&amp;gt;version]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;is_empty&amp;lt;/div&amp;gt;&lt;br /&gt;
For blocks that extend class &#039;&#039;&#039;block_base&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function is_empty() {&lt;br /&gt;
     $this-&amp;gt;get_content();&lt;br /&gt;
     return(empty($this-&amp;gt;content-&amp;gt;text) &amp;amp;&amp;amp; empty($this-&amp;gt;content-&amp;gt;footer));&lt;br /&gt;
 }&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
For blocks that extend class &#039;&#039;&#039;block_list&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function is_empty() {&lt;br /&gt;
     $this-&amp;gt;get_content();&lt;br /&gt;
     return (empty($this-&amp;gt;content-&amp;gt;items) &amp;amp;&amp;amp; empty($this-&amp;gt;content-&amp;gt;footer));&lt;br /&gt;
 }&lt;br /&gt;
This method returns the a boolean true/false value, depending on whether the block has any content at all to display. Blocks without content are not displayed by the framework.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;name&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function name() {&lt;br /&gt;
     static $myname;&lt;br /&gt;
     if ($myname === NULL) {&lt;br /&gt;
         $myname = strtolower(get_class($this));&lt;br /&gt;
         $myname = substr($myname, strpos($myname, &#039;_&#039;) + 1);&lt;br /&gt;
     }&lt;br /&gt;
     return $myname;&lt;br /&gt;
 }&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the internal name of your block inside Moodle, without the &#039;&#039;&#039;block_&#039;&#039;&#039; prefix. Obtaining the name of a block object is sometimes useful because it can be used to write code that is agnostic to the actual block&#039;s name (and thus more generic and reusable). For an example of this technique, see the [[Blocks_Howto#method_config_print| config_print]] method.&lt;br /&gt;
=== Methods which you should &#039;&#039;not&#039;&#039; override and &#039;&#039;not&#039;&#039; use at all: ===&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;_self_test&amp;lt;/div&amp;gt;&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;_add_edit_controls&amp;lt;/div&amp;gt;&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;_load_instance&amp;lt;/div&amp;gt;&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;_print_block&amp;lt;/div&amp;gt;&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;_print_shadow&amp;lt;/div&amp;gt;&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
The class &#039;&#039;&#039;block_base&#039;&#039;&#039; also has a few standard member variables which its methods manipulate. These variables, the purpose of each and the type of data they are expected to hold is explained in the next section of this Appendix.&lt;br /&gt;
&lt;br /&gt;
=== Class variables: ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;div class=&amp;quot;variable_title&amp;quot;&amp;gt;$this-&amp;gt;config&amp;lt;/div&amp;gt;&lt;br /&gt;
This variable holds all the specialized instance configuration data that have been provided for this specific block instance (object). It is an object of type stdClass, with member variables directly corresponding to the HTML &amp;lt;input&amp;gt; elements in the block&#039;s &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;config_instance.html&amp;lt;/span&amp;gt; file.&lt;br /&gt;
The variable is initialized just after the block object is constructed, immediately before [[Blocks_Howto#method_specialization| specialization]] is called for the object. It is possible that the block has no instance configuration, in which case the variable will be NULL.&lt;br /&gt;
It is obvious that there is a direct relationship between this variable and the configdata field in the mdl_block_instance table. However, it is &#039;&#039;strongly&#039;&#039; advised that you refrain from accessing the configdata field yourself. If you absolutely must update its value at any time, it is recommended that you call the method [[Blocks_Howto#method_instance_config_commit| instance_config_commit]] to do the actual work.&lt;br /&gt;
* &amp;lt;div class=&amp;quot;variable_title&amp;quot;&amp;gt;$this-&amp;gt;content_type&amp;lt;/div&amp;gt;&lt;br /&gt;
This variable instructs Moodle on what type of content it should assume the block has, and is used to differentiate text blocks from list blocks. It is essential that it has a meaningful value, as Moodle depends on this for correctly displaying the block on screen. Consequently, this variable is closely tied with the variable [[Blocks_Howto#variable_content| $this-&amp;gt;content]]. The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each block.&lt;br /&gt;
The only valid values for this variable are the two named constants [[Blocks_Howto#constant_block_type_text| BLOCK_TYPE_TEXT]] and [[Blocks_Howto#constant_block_type_list| BLOCK_TYPE_LIST]].&lt;br /&gt;
* &amp;lt;div class=&amp;quot;variable_title&amp;quot;&amp;gt;$this-&amp;gt;content&amp;lt;/div&amp;gt;&lt;br /&gt;
This variable holds all the actual content that is displayed inside each block. Valid values for it are either NULL or an object of class stdClass, which must have specific member variables set as explained below. Normally, it begins life with a value of NULL and it becomes fully constructed (i.e., an object) when [[Blocks_Howto#method_get_content| get_content]] is called.&lt;br /&gt;
After it is fully constructed, this object is expected to have certain properties, depending on the value of [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]]. Specifically:&lt;br /&gt;
** If [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] is [[Blocks_Howto#constant_block_type_text| BLOCK_TYPE_TEXT]], then [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is expected to have the following member variables:&lt;br /&gt;
*** &amp;lt;div&amp;gt;&#039;&#039;&#039;text&#039;&#039;&#039;&amp;lt;/div&amp;gt;This is a string of arbitrary length and content. It is displayed inside the main area of the block, and can contain HTML.&lt;br /&gt;
*** &amp;lt;div&amp;gt;&#039;&#039;&#039;footer&#039;&#039;&#039;&amp;lt;/div&amp;gt;This is a string of arbitrary length and contents. It is displayed below the text, using a smaller font size. It can also contain HTML.&lt;br /&gt;
** If [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] is [[Blocks_Howto#constant_block_type_list| BLOCK_TYPE_LIST]], then [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is expected to have the following member variables:&lt;br /&gt;
*** &amp;lt;div&amp;gt;&#039;&#039;&#039;items&#039;&#039;&#039;&amp;lt;/div&amp;gt;This is a numerically indexed array of strings which holds the title for each item in the list that will be displayed in the block&#039;s area. Since usually such lists function like menus, the title for each item is normally a fully qualified HTML &amp;lt;a&amp;gt; tag.&lt;br /&gt;
*** &amp;lt;div&amp;gt;&#039;&#039;&#039;icons&#039;&#039;&#039;&amp;lt;/div&amp;gt;This is a numerically indexed array of strings which represent the images displayed before each item of the list. It therefore follows that it should have the exact number of elements as the items member variable. Each item in this array should be a fully qualified HTML &amp;lt;img&amp;gt; tag.&lt;br /&gt;
*** &amp;lt;div&amp;gt;&#039;&#039;&#039;footer&#039;&#039;&#039;&amp;lt;/div&amp;gt;This is a string of arbitrary length and contents. It is displayed below the text, using a smaller font size. It can also contain HTML.&lt;br /&gt;
* &amp;lt;div class=&amp;quot;variable_title&amp;quot;&amp;gt;$this-&amp;gt;instance&amp;lt;/div&amp;gt;&lt;br /&gt;
This member variable holds all the specific information that differentiates one block instance (i.e., the PHP object that embodies it) from another. It is an object of type stdClass retrieved by calling get_record on the table mdl_block_instance. Its member variables, then, directly correspond to the fields of that table. It is initialized immediately after the block object itself is constructed.&lt;br /&gt;
* &amp;lt;div class=&amp;quot;variable_title&amp;quot;&amp;gt;$this-&amp;gt;title&amp;lt;/div&amp;gt;&lt;br /&gt;
This variable is a string that contains the human-readable name of the block. It is used to refer to blocks of that type throughout Moodle, for example in the administrator&#039;s block configuration screen and in the editing teacher&#039;s add block menu. It is also the title that is printed when the block is displayed on screen, although blocks can specifically change this title to something else if they wish (see below). The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each object.&lt;br /&gt;
In the case of blocks which may want to configure their title dynamically through instance configuration, it is still essential to provide a valid title inside [[Blocks_Howto#method_init| init]]. This title may then be overridden when the [[Blocks_Howto#method_specialization| specialization]] method is called by the framework:&lt;br /&gt;
 &lt;br /&gt;
 function specialization() {&lt;br /&gt;
     // At this point, $this-&amp;gt;instance and $this-&amp;gt;config are available&lt;br /&gt;
     // for use. We can now change the title to whatever we want.&lt;br /&gt;
     $this-&amp;gt;title = $this-&amp;gt;config-&amp;gt;variable_holding_the_title;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
A lot of blocks seem to use &lt;br /&gt;
&lt;br /&gt;
 $this-&amp;gt;title = get_string(&#039;blockname&#039;, ... );&lt;br /&gt;
&lt;br /&gt;
to set the title of the block (and then put a more specific title inside the language file)&lt;br /&gt;
If there is no proper language string, the title of the block will then be set to &#039;&#039;blockname&#039;&#039;. If there is another block with the same generic title, then an error will show up: Naming conflict.&lt;br /&gt;
&lt;br /&gt;
To avoid this error on installations with missing language strings, use a more specific name when calling the language string...&lt;br /&gt;
&lt;br /&gt;
 $this-&amp;gt;title = get_string(&#039;simplehtml&#039;, ... );&lt;br /&gt;
&lt;br /&gt;
That way all blocks will show up with a unique title in the admin area, even if people have not yet succeeded in placing language files in the correct location&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;div class=&amp;quot;variable_title&amp;quot;&amp;gt;$this-&amp;gt;version&amp;lt;/div&amp;gt;&lt;br /&gt;
This variable should hold each block&#039;s version number in the form &#039;&#039;&#039;YYYYMMDDXX&#039;&#039;&#039;, as per the convention throughout Moodle. The version number is used by Moodle to detect when a block has been upgraded and it consequently needs to run the block&#039;s upgrade code to bring the &amp;quot;old&amp;quot; version of the block&#039;s data up to date. The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each block.&lt;br /&gt;
Most blocks do not keep complex data of their own in the database the way that modules do, so in most cases nothing actually happens during a block version upgrade. However, the version number is displayed in the administration interface for blocks. It is good practice therefore to change your block&#039;s version number when it gains new functionality or receives important bug fixes, to enable site administrators to easily identify the exact version of the block they are working with.&lt;br /&gt;
&lt;br /&gt;
Appearing throughout the code related to the Blocks API, there is a number of predefined constants that are utilized to avoid the use of &amp;quot;magic numbers&amp;quot; in the code. These constants are:&lt;br /&gt;
&lt;br /&gt;
=== Named constants: ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;div class=&amp;quot;named_constant&amp;quot;&amp;gt;BLOCK_TYPE_LIST&amp;lt;/div&amp;gt;&lt;br /&gt;
This is one of the two valid values for the [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] member variable of every block. Its value specifies the exact requirements that Moodle will then have for [[Blocks_Howto#variable_content| $this-&amp;gt;content]].&lt;br /&gt;
* &amp;lt;div class=&amp;quot;named_constant&amp;quot;&amp;gt;BLOCK_TYPE_TEXT&amp;lt;/div&amp;gt;&lt;br /&gt;
This is one of the two valid values for the [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] member variable of every block. Its value specifies the exact requirements that Moodle will then have for [[Blocks_Howto#variable_content| $this-&amp;gt;content]].&lt;br /&gt;
&lt;br /&gt;
== Appendix B: Differences in the Blocks API for Moodle versions prior to 1.5 ==&lt;br /&gt;
&lt;br /&gt;
This Appendix will discuss what changes in the Blocks API were introduced by Moodle 1.5 and what steps developers need to take to update their blocks to be fully compatible with Moodle 1.5. Unfortunately, with these changes backward compatibility is broken; this means that blocks from Moodle 1.4 will never work with 1.5 and vice versa.&lt;br /&gt;
&lt;br /&gt;
=== Class naming conventions changed ===&lt;br /&gt;
In Moodle 1.4, all block classes were required to have a name like &#039;&#039;&#039;CourseBlock_something&#039;&#039;&#039; and the base class from which the derived was &#039;&#039;&#039;MoodleBlock&#039;&#039;&#039;. This has changed in Moodle 1.5, to bring the naming conventions in line with other object-oriented aspects of Moodle (for example there are classes enrolment_base, resource_base etc). The new block classes should instead be named like &#039;&#039;&#039;block_something&#039;&#039;&#039; and derive from &#039;&#039;&#039;block_base&#039;&#039;&#039;. This means that in order to make a block compatible with Moodle 1.5, you need to change the class definition&lt;br /&gt;
 &lt;br /&gt;
 class CourseBlock_online_users extends MoodleBlock { ... }&lt;br /&gt;
to&lt;br /&gt;
 &lt;br /&gt;
 class block_online_users extends block_base { ... }&lt;br /&gt;
An exception to the above is the special case where the block is intended to display a list of items instead of arbitrary text; in this case the block class must derive from class &#039;&#039;&#039;block_list&#039;&#039;&#039; instead, like this:&lt;br /&gt;
 &lt;br /&gt;
 class block_admin extends block_list { ... }&lt;br /&gt;
&lt;br /&gt;
=== Constructor versus init() ===&lt;br /&gt;
&lt;br /&gt;
In Moodle 1.4, in each block class it was mandatory to define a constructor which accepted a course data record as an argument (the example is from the actual Online Users block):&lt;br /&gt;
 &lt;br /&gt;
     function CourseBlock_online_users ($course) {&lt;br /&gt;
         $this-&amp;gt;title = get_string(&#039;blockname&#039;,&#039;block_online_users&#039;);&lt;br /&gt;
         $this-&amp;gt;content_type = BLOCK_TYPE_TEXT;&lt;br /&gt;
         $this-&amp;gt;course = $course;&lt;br /&gt;
         $this-&amp;gt;version = 2004052700;&lt;br /&gt;
     }&lt;br /&gt;
In contrast, Moodle 1.5 does away with the constructor and instead requires you to define an init() method that takes no arguments:&lt;br /&gt;
 &lt;br /&gt;
     function init() {&lt;br /&gt;
         $this-&amp;gt;title = get_string(&#039;blockname&#039;,&#039;block_online_users&#039;);&lt;br /&gt;
         $this-&amp;gt;version = 2004111600;&lt;br /&gt;
     }&lt;br /&gt;
Of course, this leaves you without access to the $course object, which you might actually need. Since that&#039;s probably going to be needed inside [[Blocks_Howto#method_get_content| get_content]], the way to retrieve it is by using this code:&lt;br /&gt;
 &lt;br /&gt;
     $course = get_record(&#039;course&#039;, &#039;id&#039;, $this-&amp;gt;instance-&amp;gt;pageid);&lt;br /&gt;
If you are going to need access to $course from inside other methods in addition to [[Blocks_Howto#method_get_content| get_content]], you might fetch the $course object inside the [[Blocks_Howto#method_specialization| specialization]] method and save it as a class variable for later use, in order to avoid executing the same query multiple times:&lt;br /&gt;
 &lt;br /&gt;
     function specialization() {&lt;br /&gt;
         $this-&amp;gt;course = get_record(&#039;course&#039;, &#039;id&#039;, $this-&amp;gt;instance-&amp;gt;pageid);&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
=== Blocks with configuration ===&lt;br /&gt;
In Moodle 1.4, blocks could only have what are now (in Moodle 1.5) called &amp;quot;global configuration&amp;quot; options, to differentiate from the new &amp;quot;instance configuration&amp;quot; options. If your block has support for configuration, you will need to take these steps:&lt;br /&gt;
## Rename your &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;config.html&amp;lt;/span&amp;gt; file to &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;config_global.html&amp;lt;/span&amp;gt;.&lt;br /&gt;
## Edit the newly renamed file and completely remove the &amp;lt;form&amp;gt; tag (Moodle now wraps your configuration in a form automatically).&lt;br /&gt;
## If you are using any HTML &amp;lt;input&amp;gt; tags other than those that directly affect your configuration (for example, &amp;quot;sesskey&amp;quot;), REMOVE those too (Moodle will add them automatically as required).&lt;br /&gt;
## If you have overridden &#039;&#039;&#039;print_config&#039;&#039;&#039;, rename your method to &#039;&#039;&#039;config_print&#039;&#039;&#039;.&lt;br /&gt;
## If you have overridden &#039;&#039;&#039;handle_config&#039;&#039;&#039;, rename your method to &#039;&#039;&#039;config_save&#039;&#039;&#039;.&lt;br /&gt;
=== Blocks with customized applicable formats ===&lt;br /&gt;
The correct way to specify the formats you want to allow or disallow your block to exist has been reworked for Moodle 1.5 to take account of the fact that blocks are no longer restricted to just courses. To have a block retain its intended behavior, you must change these format names (array keys in the return value of [[Blocks_Howto#method_applicable_formats| applicable_formats]]) if they are used in your block:&lt;br /&gt;
#* &#039;&#039;&#039;social&#039;&#039;&#039; should become &#039;&#039;&#039;course-view-social&#039;&#039;&#039;&lt;br /&gt;
#* &#039;&#039;&#039;topics&#039;&#039;&#039; should become &#039;&#039;&#039;course-view-topics&#039;&#039;&#039;&lt;br /&gt;
#* &#039;&#039;&#039;weeks&#039;&#039;&#039; should become &#039;&#039;&#039;course-view-weeks&#039;&#039;&#039;&lt;br /&gt;
You should also keep in mind that there is now the possibility of blocks being displayed in other pages too, like the introductory page that users see when they enter an activity module. You might therefore need to make the specification for applicable formats more restrictive to keep your block out of pages it is not supposed to be shown in. Also, there are subtle changes to the way that the final decision to allow or disallow a block is made. For the technical details refer to the definition of [[Blocks_Howto#method_applicable_formats| applicable_formats]], and for a more extended example read [[Blocks_Howto#section_authorized_personnel_only| the section dedicated to this subject]].&lt;br /&gt;
That&#039;s everything; your block will now be ready for use in Moodle 1.5!&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer|Blocks]]&lt;br /&gt;
&lt;br /&gt;
[[es:Desarrollo de bloques]]&lt;br /&gt;
&lt;br /&gt;
== Creating Database Tables for Blocks ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The following describes what to do in Moodle &amp;lt;= 1.6. For Moodle &amp;gt;= 1.7, you need to use [[Development:XMLDB_Documentation|XMLDB]], that is, create an install.xml file, instead of *.sql files.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can easily create a database table for your block by adding&lt;br /&gt;
two files mysql.sql and postgres7.sql to a subdirectory db/ of&lt;br /&gt;
your block. The tables HAVE TO be named the same way as the&lt;br /&gt;
block (e.g. block_rss2_feeds) otherwise moodle will not be able&lt;br /&gt;
to drop the table upon removal of the block from the system.&lt;br /&gt;
Here is an example for mysql.sql:&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE prefix_rss2_feeds (&lt;br /&gt;
 `id` int(11) NOT NULL auto_increment,&lt;br /&gt;
 `userid` int(11) NOT NULL default &#039;0&#039;,&lt;br /&gt;
 `title` text NOT NULL default &#039;&#039;,&lt;br /&gt;
 `description` text NOT NULL default &#039;&#039;,&lt;br /&gt;
 `url` varchar(255) NOT NULL default &#039;&#039;,&lt;br /&gt;
 `pingbacktokenurl` varchar(255) NOT NULL default &#039;&#039;,&lt;br /&gt;
 PRIMARY KEY  (`id`)&lt;br /&gt;
) TYPE=MyISAM  COMMENT=&#039;Remote news feed information.&#039;;&lt;br /&gt;
&lt;br /&gt;
Pay attention that, furthermore, you might want to add a&lt;br /&gt;
mysql.php and postgres7.php page that contains update&lt;br /&gt;
routines for upgrading the database tables with evolving&lt;br /&gt;
version numbers of the block. In case you use that be sure&lt;br /&gt;
that you provide the necessary structure (again function&lt;br /&gt;
name should be like the block name + &amp;quot;_upgrade&amp;quot;!).&lt;br /&gt;
Here is an example:&lt;br /&gt;
&lt;br /&gt;
function rss_pingback_upgrade( $oldversion ) {&lt;br /&gt;
    global $CFG;&lt;br /&gt;
    if ($oldversion &amp;lt; 2003111500) {&lt;br /&gt;
       # Do something ...&lt;br /&gt;
    }&lt;br /&gt;
    return true;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Davidkazuhiro</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/2x/ca/index.php?title=Grader_report&amp;diff=43366</id>
		<title>Grader report</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/2x/ca/index.php?title=Grader_report&amp;diff=43366"/>
		<updated>2008-09-10T21:48:57Z</updated>

		<summary type="html">&lt;p&gt;Davidkazuhiro: /* Basics */ not =&amp;gt;note&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Grades}}The grader report page is the main teacher view of the new gradebook in Moodle 1.9. For versions prior to 1.9, look [[Grades_pre-1.9 | here]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Basics=&lt;br /&gt;
The gradebook collects [[Grade_items|items]] that have been graded from the various parts of Moodle that are assessed, and allows you to view and change them as well as sort them out into [[Grade_categories|categories]] and calculate totals in various ways. When you add an assessed item in a Moodle course, the gradebook automatically creates space for the grades it will produce and also adds the grades themselves as they are generated, either by the system or by you.&lt;br /&gt;
&lt;br /&gt;
The [[Grades|grades]] displayed are initially displayed as the raw marks from the assessments themselves, so will depend on how you set those up e.g. an essay out of 36 will appear as how ever many raw marks that student got, not a percentage (although this can be changed later, see below).&lt;br /&gt;
&lt;br /&gt;
Note that various default options for the gradebook are set at system level by the administrator and can be marked as being overridable by you, or fixed. This means that the options will not always be set up the same way for every user when they see the grader report for the first time.&lt;br /&gt;
&lt;br /&gt;
=Display=&lt;br /&gt;
==Layout==&lt;br /&gt;
[[Image:gradebook_normal_mode.png|right|thumb|Grader report in non-editing mode]]&lt;br /&gt;
Along the top are several rows: first the course, then the category, then the actual column (e.g. an essay or a category total). When you start off, every essay, quiz etc is in the &#039;&#039;&#039;uncategorised&#039;&#039;&#039; category, which is named after the course by default, but can be changed if needed.&lt;br /&gt;
&lt;br /&gt;
You can add a row showing the range of possible scores by going to [[Grade_preferences|My report preferences]] and selecting &#039;&#039;&#039;Show ranges&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
There are three ways that the categories can be displayed&lt;br /&gt;
&lt;br /&gt;
* Grades only - without the category totals column&lt;br /&gt;
* Collapsed - Category total column only&lt;br /&gt;
* Full view - grades and the aggregates (the totals column for the category) &lt;br /&gt;
&lt;br /&gt;
Each section has a small icon immediately to the right of its name. Clicking this will cycle through these display modes for that category. + goes to grades only view, o goes to full view and - goes to collapsed view.&lt;br /&gt;
&lt;br /&gt;
===Other layout options===&lt;br /&gt;
The defaults for these options can be set at site level by going to Administration-&amp;gt;Grades-&amp;gt;[[Gradebook_report_settings|Report settings]]-&amp;gt;Grader report.&lt;br /&gt;
&lt;br /&gt;
*You can add a row showing the range of possible scores by going to [[Grade_preferences|My report preferences]] and selecting &#039;&#039;&#039;Show ranges&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Highlighting rows and columns==&lt;br /&gt;
When your gradebook starts to grow, it can be hard to keep track of which student and which assignment a cell refers to. Highlighting solves that.&lt;br /&gt;
* Clicking on empty space in the cell that contains the students name will toggle the highlighting of that entire row&lt;br /&gt;
* Clicking on empty space in the cell at the top of each column will toggle highlighting of the entire column&lt;br /&gt;
(Note: this requires Javascript to be enabled in your browser.)&lt;br /&gt;
&lt;br /&gt;
==Highlighting scores that are either adequate or unacceptable in red and green==&lt;br /&gt;
Turn editing on and click on the edit icon in the controls cell at the top of the column. You can then (maybe need to click &#039;show advanced&#039;) see the option to enter a &#039;grade to pass&#039;. Once set, any grades falling above this will be highlighted in green and any below will be highlighted in red.&lt;br /&gt;
&lt;br /&gt;
==Categorising the grades==&lt;br /&gt;
The &#039;Choose an action...&#039; drop down on the upper left will let you switch to other views&lt;br /&gt;
* &#039;&#039;&#039;Edit categories and items&#039;&#039;&#039; will allow you to set up your assessments in different categories e.g. &#039;classwork&#039;, &#039;homework&#039; etc. &lt;br /&gt;
&lt;br /&gt;
Each category will then have its own &#039;&#039;&#039;Category total&#039;&#039;&#039; column.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Editing=&lt;br /&gt;
[[Image:gradebook_edit_mode.png|right|thumb|Grader report in editing mode]]&lt;br /&gt;
Note: Editing anything in the gradebook refers to editing the grades &#039;&#039;&#039;only&#039;&#039;&#039; and none of the available operations bear any relationship to editing the main course page i.e. the appearance of your course page cannot be influenced by anything you do in the gradebook. The &amp;quot;Turn editing on&amp;quot; button functions separately to the main course one, so editing can be on in the gradebook, but simultaneously off when you switch back to course view. This is because editing grades and editing the course page are separate capabilities and a role e.g. &#039;non-editing teacher&#039; may only have one or the other.&lt;br /&gt;
&lt;br /&gt;
==Altering the grades==&lt;br /&gt;
You can click &amp;quot;Turn editing on&amp;quot;  at the top right to show an edit icon next to each grade. Clicking on the icon will bring up the editing screen for that grade which will allow you to set the grade, its written feedback and a number of other attributes.&lt;br /&gt;
&lt;br /&gt;
Alternatively, you can click on &amp;quot;[[Grade_preferences|My report preferences]]&amp;quot;&#039; and choose &amp;quot;Quick grading&amp;quot; and &amp;quot;Quick feedback&amp;quot; to make the report appear with editable boxes containing each grade, so you can change many at once.&lt;br /&gt;
&lt;br /&gt;
Quick feedback is switched off by default, but you can easily switch it on or off using the &amp;quot;Show Quick Feedback&amp;quot; link above the grader report, when editing is on. Alternatively you can switch it on and off in the page &amp;quot;[[Grade_preferences|My report preferences]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Calculating totals==&lt;br /&gt;
Rather than a simple average or sum, Moodle can perform very complex calculations to produce the totals for each category and for the whole course. e.g. you want to take an average of 3 items from one category, double it, then add it to the average of another category.&lt;br /&gt;
&lt;br /&gt;
You can do this using calculations. Either turn on editing, then click &#039;&#039;&#039;Show calculations&#039;&#039;&#039;, or go to &#039;&#039;&#039;[[Grade_preferences|My report preferences]]&#039;&#039;&#039;, choose &#039;&#039;&#039;show calculations&#039;&#039;&#039;, then save and turn editing on. You will then see a small calculator icon next to each total column which, when you click on it, will take you to the page [[Edit grade calculation]] where there are instructions.&lt;br /&gt;
&lt;br /&gt;
To choose how the grades are aggregated for the totals within categories, you can turn editing on and click on the little editing icon for the category. You can then choose to have means, medians, modes etc. leave out empty grades and other settings.&lt;br /&gt;
&lt;br /&gt;
==Hiding columns or individual grades==&lt;br /&gt;
Turning on editing then clicking the &amp;quot;Show show/hide icons&amp;quot; link will give you the familiar show/hide eye icon next to each grade and at the top of each column. For more information, read about [[Grade_hiding|grade hiding]].&lt;br /&gt;
&lt;br /&gt;
==Recalculating==&lt;br /&gt;
If you change any part of an assesment e.g. alter the maximum grade for one of the questions in a quiz, you may find that the columns do not yet reflect the change you have made. Click &#039;Turn editing on&#039; twice to force the gradebook to re-check.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[[Edit grade calculation]]&lt;br /&gt;
*[[Grade preferences]]&lt;br /&gt;
*[http://www.youtube.com/watch?v=EB58W3KePBc Video showing the basic gradebook setup and use]&lt;br /&gt;
*[http://www.youtube.com/watch?v=jWPUEqdhI4A Video showing how to change the display of grades in the gradebook]&lt;br /&gt;
*[http://www.youtube.com/watch?v=5hrLNbifiGQ Video explaining the different gradebook reports]&lt;br /&gt;
*Using Moodle [http://moodle.org/mod/forum/discuss.php?d=87844 What happens in the 1.9 gradebook when students are unenrolled from a course] forum discussion&lt;br /&gt;
&lt;br /&gt;
[[ca:grade/report/grader/index]]&lt;br /&gt;
[[fr:Rapport de l&#039;évaluateur]]&lt;/div&gt;</summary>
		<author><name>Davidkazuhiro</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/2x/ca/index.php?title=XMLDB_introduction&amp;diff=41549</id>
		<title>XMLDB introduction</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/2x/ca/index.php?title=XMLDB_introduction&amp;diff=41549"/>
		<updated>2008-08-06T22:47:31Z</updated>

		<summary type="html">&lt;p&gt;Davidkazuhiro: a facelift for the article&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Development:XMLDB Documentation|XMLDB Documentation]] &amp;gt; Introduction&lt;br /&gt;
----&lt;br /&gt;
__NOTOC__&lt;br /&gt;
One of the main upcoming features in Moodle 1.7 will be its ability to work with some more [[wikipedia:RDBMS|RDBMS]] ([[wikipedia:MSSQL|MSSQL]] and [[wikipedia:Oracle database|Oracle]]) while maintaining everything working properly with both [[MySQL]] and [[PostgreSQL]]. As Moodle core uses [http://adodb.sourceforge.net/ ADOdb] internally, this possibility has been present since the beginning and, with the current maturity of the project (5 years old baby!), this can be a good moment to sort all this out.&lt;br /&gt;
&lt;br /&gt;
Initially, all our tests and preliminary work was to inspect how [http://adodb.sourceforge.net/ ADOdb] was doing its work, and how we could mix together all those 4 RDBMS, whose SQL dialects, although pretty similar, have some differences and idiosyncrasies that force us to do some important changes to our current database code (formerly &#039;&#039;&#039;datalib.php&#039;&#039;&#039;) and how it&#039;s used by the rest of Moodle.&lt;br /&gt;
&lt;br /&gt;
All the changes to be performed, which primary objective is to enable Moodle to work with more RDBMS, must be fulfilled by following these non-functional requirements: &lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Provide one layer (new) for DB creation/upgrade&#039;&#039;&#039; ([[wikipedia:Data_Definition_Language|DDL]]): With this, developers will create their structures in one neutral form, independent of the exact implementation to be used by each RDBMS.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Provide one layer (existing) for DB handling&#039;&#039;&#039; ([[wikipedia:Data_Manipulation_Language|DML]]): With this, developers will request/store information also in one neutral form, independent of the RDBMS being used.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Easy migration path from previous versions&#039;&#039;&#039;: The current installation/upgrade system will work until, at least, Moodle 2.0, allowing 3rd party developers to migrate to the new system.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Simple, usable and effective&#039;&#039;&#039;: Until now, the way to upgrade Moodle has been really cool and it has worked pretty fine since the beginning. However, it has forced developers to maintain at least two installation and two upgrade scripts for each module/plugin. The new alternative will have only one file to install and one file to upgrade (per module/plugin too), reducing the possibility of mistakes drastically.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Conditional code usage must be minimised&#039;&#039;&#039;: Database libraries must accept 99% of potential SQL sentences, building/transforming them as necessary to work properly under any RDBMS. The number of places using custom (per DB) code should be minimum.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Well documented&#039;&#039;&#039;: All the functions defined, both at DML and DDL level must be well documented, helping the developer to find and use the correct one in each situation.&lt;br /&gt;
&lt;br /&gt;
== The Stack ==&lt;br /&gt;
&lt;br /&gt;
The next stack shows how Moodle 1.7 code will interact with the underlying RDBMS. It will help us understand a bit more what we are trying to do and will explain some of the points related in the Roadmap (below in this page).&lt;br /&gt;
&lt;br /&gt;
[[Image:MoodleDBStack.png|center]]&lt;br /&gt;
&lt;br /&gt;
Moodle code will use two &#039;&#039;languages&#039;&#039; to perform its DB actions:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;XMLDB neutral description files&#039;&#039;&#039;: To create, modify and delete database objects (DDL: create/alter/drop tables, fields, indexes, constraints...). It consists of a collection of validated, standard, XML files. They will be used to define all the DB objects. New for 1.7.&lt;br /&gt;
* &#039;&#039;&#039;Moodle SQL neutral statements&#039;&#039;&#039;: To add, modify, delete and select database information (DML: insert/update/delete/select records). To modify for 1.7.&lt;br /&gt;
&lt;br /&gt;
Please note the &#039;&#039;&#039;neutral&#039;&#039;&#039; keyword used in the expressions above. It means that both &#039;&#039;&#039;languages&#039;&#039;&#039; will be 100% the same, independent of the underlying RDBMS being used. And this must be particularly true for the XMLDB part.&lt;br /&gt;
&lt;br /&gt;
Obviously it&#039;s possible that in the SQL part we found some specialised queries (using complex joins, regular expressions...) that will force us to do some &#039;&#039;&#039;Exceptions&#039;&#039;&#039;. Well, they can exist (in fact, they exist), but we always must try to provide an alternate path to minimise them using neutral statements and standard libraries.&lt;br /&gt;
&lt;br /&gt;
Each one of the &#039;&#039;&#039;languages&#039;&#039;&#039; above will use its own library to do the work:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Moodle DDL Library&#039;&#039;&#039; ([[Development:DDL functions|ddllib.php]]): Where all the functions needed to handle DB objects will exist. This library is new for 1.7 and will provide developers with an high level of abstraction. As input it will accept some well defined objects and actions and it will execute the proper commands for the RDBMS being used.&lt;br /&gt;
* &#039;&#039;&#039;Moodle DML Library&#039;&#039;&#039; ([[Development:DML functions|dmllib.php]]): Where all the functions needed to handle DB contents will exist. This library is new for 1.7, although its contents are, basically, functions currently present in &#039;&#039;&#039;datalib.php&#039;&#039;&#039; (moved from there). All those DML functions will offer cross-db support for insert/update/delete/select statements using a common behaviour.&lt;br /&gt;
&lt;br /&gt;
Also note that &#039;&#039;&#039;datalib.php&#039;&#039;&#039; is still present in the schema above. It will contain all the functions that haven&#039;t been moved to the new &#039;&#039;&#039;ddllib.php&#039;&#039;&#039; and &#039;&#039;&#039;dmllib.php&#039;&#039;&#039; libraries. Only some common functions will remain there, and these will disappear (it&#039;s considered a legacy library) in upcoming &#039;&#039;&#039;Moodle&#039;&#039;&#039; releases (after 1.7) by moving all those functions to their proper library (course/lib.php, user/lib.php....). &lt;br /&gt;
&lt;br /&gt;
Both of these libraries (plus the small &#039;&#039;&#039;Exceptions&#039;&#039;&#039; bar) will perform all their actions using the &#039;&#039;&#039;ADOdb Database Abstraction Library for PHP&#039;&#039;&#039; that will receive all the requests from them, communicate with the DB (&#039;&#039;&#039;MySQL&#039;&#039;&#039;, &#039;&#039;&#039;PostgreSQL&#039;&#039;&#039;, &#039;&#039;&#039;Oracle&#039;&#039;&#039; or &#039;&#039;&#039;SQL*Server&#039;&#039;&#039;), retrieve results and forward them back to originator library.&lt;br /&gt;
&lt;br /&gt;
== The process ==&lt;br /&gt;
&lt;br /&gt;
This section points to the main areas of information about the &#039;&#039;&#039;process of design and implementation&#039;&#039;&#039; of the new XMLDB layer:&lt;br /&gt;
&lt;br /&gt;
* [[XMLDB Roadmap|Roadmap]]: Where the whole process is defined. It has been split into small chunks to be performed and tested easily. Also, such documents should be used to track what&#039;s done and what&#039;s pending, while using easy nomenclature.&lt;br /&gt;
&lt;br /&gt;
* [[XMLDB Problems|Problems]]: A comprehensive list of issues that need to be determined/solved prior to incorporating them into the [[XMLDB Roadmap|roadmap]].&lt;br /&gt;
&lt;br /&gt;
== The documentation ==&lt;br /&gt;
&lt;br /&gt;
This section points to the &#039;&#039;&#039;main documentation index&#039;&#039;&#039; about the implemented XMLDB:&lt;br /&gt;
&lt;br /&gt;
* [[Development:XMLDB Documentation|Documentation]]: Where you&#039;ll find quick links to different parts of the XMLDB documentation.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
=== XMLDB related ===&lt;br /&gt;
&lt;br /&gt;
* [[Development:XMLDB preliminary links|XMLDB preliminary links]] - A collection of links about general info, searched and analysed at the initial stages of the project&lt;br /&gt;
* [[Development:XMLDB preliminary notes|XMLDB preliminary notes]] - A collection of notes collected in the early stages of this project, pointing both to some changes required and some problems to solve.&lt;br /&gt;
&lt;br /&gt;
=== Database related ===&lt;br /&gt;
&lt;br /&gt;
* [[Development:DDL functions|DDL functions]] - Documentation for all the Data Definition Language (DDL) functions available inside Moodle.&lt;br /&gt;
* [[Development:DML functions|DML functions]] - Documentation for all the Data Manipulation Language (DML) functions available inside Moodle.&lt;br /&gt;
&lt;br /&gt;
[[Category:XMLDB]]&lt;br /&gt;
&lt;br /&gt;
[[zh:开发:XML数据库计划]]&lt;/div&gt;</summary>
		<author><name>Davidkazuhiro</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/2x/ca/index.php?title=XMLDB_introduction&amp;diff=41548</id>
		<title>XMLDB introduction</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/2x/ca/index.php?title=XMLDB_introduction&amp;diff=41548"/>
		<updated>2008-08-06T21:49:27Z</updated>

		<summary type="html">&lt;p&gt;Davidkazuhiro: trying to make the sentence make more sense&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Development:XMLDB Documentation|XMLDB Documentation]] &amp;gt; Introduction&lt;br /&gt;
----&lt;br /&gt;
__NOTOC__&lt;br /&gt;
One of the main upcoming features in Moodle 1.7 will be its ability to work with some more [[wikipedia:RDBMS|RDBMS]] ([[wikipedia:MSSQL|MSSQL]] and [[wikipedia:Oracle database|Oracle]]) while maintaining everything working properly with both [[MySQL]] and [[PostgreSQL]]. As Moodle core uses [http://adodb.sourceforge.net/ ADOdb] internally, this possibility has been present since the beginning and, with the current maturity of the project (5 years old baby!), this can be a good moment to sort all this out.&lt;br /&gt;
&lt;br /&gt;
Initially, all our tests and preliminary work was to inspect how [http://adodb.sourceforge.net/ ADOdb] was doing its work, and how we could mix together all those 4 RDBMS, whose SQL dialects, although pretty similar, have some differences and idiosyncrasies that force us to do some important changes to our current database code (formerly &#039;&#039;&#039;datalib.php&#039;&#039;&#039;) and how it&#039;s used by the rest of Moodle.&lt;br /&gt;
&lt;br /&gt;
All the changes to be performed, which primary objective is to enable Moodle to work with more RDBMS, must be fulfilled by following these non-functional requirements: &lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Provide one layer (new) for DB creation/upgrade&#039;&#039;&#039; ([[wikipedia:Data_Definition_Language|DDL]]): With this, developers will create their structures in one neutral form, independent of the exact implementation to be used by each RDBMS.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Provide one layer (existing) for DB handling&#039;&#039;&#039; ([[wikipedia:Data_Manipulation_Language|DML]]): With this, developers will request/store information also in one neutral form, independent of the RDBMS being used.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Easy migration path from previous versions&#039;&#039;&#039;: The current installation/upgrade system will work until, at least, Moodle 2.0, allowing 3rd part developers to migrate along the time to the new system.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Simple, usable and effective&#039;&#039;&#039;: Until now, the way to upgrade Moodle has been really cool and it has worked pretty fine since the beginning, but it has forced developers to maintain at least two installation and two upgrade scripts for each module/plugin. The new alternative will have only one file to install and one file to upgrade (per module/plugin too), reducing the possibility of mistakes in an high degree.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Conditional code usage must be minimised&#039;&#039;&#039;: Database libraries must accept 99% of potential SQL sentences, building/transforming them as necessary to work properly under any RDBMS. The number of places using custom (per DB) code should be minimum.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Well documented&#039;&#039;&#039;: All the functions defined, both at DML and DDL level must be well documented, helping the developer to find and use the correct one in each situation.&lt;br /&gt;
&lt;br /&gt;
== The Stack ==&lt;br /&gt;
&lt;br /&gt;
The next stack shows how Moodle 1.7 code will interact with underlying RDBMS. It will help us to understand a bit more what we are trying to do and will explain some of the points related in the Roadmap (below in this page).&lt;br /&gt;
&lt;br /&gt;
[[Image:MoodleDBStack.png|center]]&lt;br /&gt;
&lt;br /&gt;
Moodle code will use two &#039;&#039;languages&#039;&#039; to perform its DB actions:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;XMLDB neutral description files&#039;&#039;&#039;: To create, modify and delete database objects (DDL: create/alter/drop tables, fields, indexes, constraints...). It consists in a collection of validated, standard, XML files. They will be used to define all the DB objects. New for 1.7.&lt;br /&gt;
* &#039;&#039;&#039;Moodle SQL neutral statements&#039;&#039;&#039;: To add, modify, delete and select database information (DML: insert/update/delete/select records). To modify for 1.7.&lt;br /&gt;
&lt;br /&gt;
Please note the &#039;&#039;&#039;neutral&#039;&#039;&#039; keyword used in the expressions above. It means that both &#039;&#039;&#039;languages&#039;&#039;&#039; will be 100% the same, independently  of the underlying RDBMS being used. And this must be particularly true for the XMLDB part. Point.&lt;br /&gt;
&lt;br /&gt;
Obviously it&#039;s possible that in the SQL part we found some specialised queries (using complex joins, regular expressions...) that will force us to do some &#039;&#039;&#039;Exceptions&#039;&#039;&#039;. Well, they can exist (in fact, they exist), but we always must try to provide an alternate path to minimise them using neutral statements and standard libraries.&lt;br /&gt;
&lt;br /&gt;
Each one of the &#039;&#039;&#039;languages&#039;&#039;&#039; above will use its own library to do the work:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Moodle DDL Library&#039;&#039;&#039; ([[Development:DDL functions|ddllib.php]]): Where all the functions needed to handle DB objects will exist. This library is new for 1.7 and will provide developers with an high level of abstraction. As input it will accept some well defined objects and actions and it will execute the proper commands for the RDBMS being used.&lt;br /&gt;
* &#039;&#039;&#039;Moodle DML Library&#039;&#039;&#039; ([[Development:DML functions|dmllib.php]]): Where all the functions needed to handle DB contents will exist. This library is new for 1.7, although its contents are, basically, functions currently present in &#039;&#039;&#039;datalib.php&#039;&#039;&#039; (moved from there). All those DML functions will offer cross-db support for insert/update/delete/select statements using a common behaviour.&lt;br /&gt;
&lt;br /&gt;
Also note that &#039;&#039;&#039;datalib.php&#039;&#039;&#039; continues present in the schema above. It will contain all the functions that haven&#039;t been moved to the new &#039;&#039;&#039;ddllib.php&#039;&#039;&#039; and &#039;&#039;&#039;dmllib.php&#039;&#039;&#039; libraries. Only some common functions will remain there, and this situation will disappear (it&#039;s considered a legacy library) in upcoming &#039;&#039;&#039;Moodle&#039;&#039;&#039; releases (after 1.7) by moving all those functions to their proper library (course/lib.php, user/lib.php....). &lt;br /&gt;
&lt;br /&gt;
Both these libraries (plus the small &#039;&#039;&#039;Exceptions&#039;&#039;&#039; bar) will perform all their actions using the &#039;&#039;&#039;ADOdb Database Abstraction Library for PHP&#039;&#039;&#039; that will receive all the requests from them, communicate with the DB (&#039;&#039;&#039;MySQL&#039;&#039;&#039;, &#039;&#039;&#039;PostgreSQL&#039;&#039;&#039;, &#039;&#039;&#039;Oracle&#039;&#039;&#039; or &#039;&#039;&#039;SQL*Server&#039;&#039;&#039;), retrieve results and forward them back to originator library.&lt;br /&gt;
&lt;br /&gt;
== The process ==&lt;br /&gt;
&lt;br /&gt;
This section points to the main areas of information about the &#039;&#039;&#039;process of design and implementation&#039;&#039;&#039; of the new XMLDB layer:&lt;br /&gt;
&lt;br /&gt;
* [[XMLDB Roadmap|Roadmap]]: Where the whole process is defined. It has been split into small chuncks to be performed and tested easily. Also, such documents should be used to track what&#039;s done and what&#039;s pending following some easy nomenclature.&lt;br /&gt;
&lt;br /&gt;
* [[XMLDB Problems|Problems]]: A comprensive list of issues that need to be determined/solved prior to incorporating them into the [[XMLDB Roadmap|roadmap]].&lt;br /&gt;
&lt;br /&gt;
== The documentation ==&lt;br /&gt;
&lt;br /&gt;
This section points to the &#039;&#039;&#039;main documentation index&#039;&#039;&#039; about the implemented XMLDB:&lt;br /&gt;
&lt;br /&gt;
* [[Development:XMLDB Documentation|Documentation]]: Where you&#039;ll find quick links to different parts of the XMLDB documentation.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
=== XMLDB related ===&lt;br /&gt;
&lt;br /&gt;
* [[Development:XMLDB preliminary links|XMLDB preliminary links]] - A collection of links about general info, searched and analysed at the initial stages of the project&lt;br /&gt;
* [[Development:XMLDB preliminary notes|XMLDB preliminary notes]] - A collection of notes collected in the early stages of this project, pointing both to some changes required and some problems to solve.&lt;br /&gt;
&lt;br /&gt;
=== Database related ===&lt;br /&gt;
&lt;br /&gt;
* [[Development:DDL functions|DDL functions]] - Documentation for all the Data Definition Language (DDL) functions available inside Moodle.&lt;br /&gt;
* [[Development:DML functions|DML functions]] - Documentation for all the Data Manipulation Language (DML) functions available inside Moodle.&lt;br /&gt;
&lt;br /&gt;
[[Category:XMLDB]]&lt;br /&gt;
&lt;br /&gt;
[[zh:开发:XML数据库计划]]&lt;/div&gt;</summary>
		<author><name>Davidkazuhiro</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/2x/ca/index.php?title=XMLDB_introduction&amp;diff=41547</id>
		<title>XMLDB introduction</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/2x/ca/index.php?title=XMLDB_introduction&amp;diff=41547"/>
		<updated>2008-08-06T18:50:07Z</updated>

		<summary type="html">&lt;p&gt;Davidkazuhiro: fixed typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Development:XMLDB Documentation|XMLDB Documentation]] &amp;gt; Introduction&lt;br /&gt;
----&lt;br /&gt;
__NOTOC__&lt;br /&gt;
One of the main upcoming features in Moodle 1.7 will be its ability to work with some more [[wikipedia:RDBMS|RDBMS]] ([[wikipedia:MSSQL|MSSQL]] and [[wikipedia:Oracle database|Oracle]]) while maintaining everything working properly with both [[MySQL]] and [[PostgreSQL]]. As Moodle core uses [http://adodb.sourceforge.net/ ADOdb] internally, this possibility has been present since the beginning and, with the current maturity of the project (5 years old baby!), this can be a good moment to sort all this out.&lt;br /&gt;
&lt;br /&gt;
Initially, all our tests and preliminary work was to inspect how [http://adodb.sourceforge.net/ ADOdb] was doing its work, and how we could mix together all those 4 RDBMS, whose SQL dialects, although pretty similar, have some differences and idiosyncrasies that force us to do some important changes to our current database code (formerly &#039;&#039;&#039;datalib.php&#039;&#039;&#039;) and how it&#039;s used by the rest of Moodle.&lt;br /&gt;
&lt;br /&gt;
All the changes to be performed, which primary objective is to enable Moodle to work with more RDBMS must be filled following the next non-functional requirements: &lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Provide one layer (new) for DB creation/upgrade&#039;&#039;&#039; ([[wikipedia:Data_Definition_Language|DDL]]): With this, developers will create their structures in one neutral form, independent of the exact implementation to be used by each RDBMS.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Provide one layer (existing) for DB handling&#039;&#039;&#039; ([[wikipedia:Data_Manipulation_Language|DML]]): With this, developers will request/store information also in one neutral form, independent of the RDBMS being used.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Easy migration path from previous versions&#039;&#039;&#039;: The current installation/upgrade system will work until, at least, Moodle 2.0, allowing 3rd part developers to migrate along the time to the new system.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Simple, usable and effective&#039;&#039;&#039;: Until now, the way to upgrade Moodle has been really cool and it has worked pretty fine since the beginning, but it has forced developers to maintain at least two installation and two upgrade scripts for each module/plugin. The new alternative will have only one file to install and one file to upgrade (per module/plugin too), reducing the possibility of mistakes in an high degree.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Conditional code usage must be minimised&#039;&#039;&#039;: Database libraries must accept 99% of potential SQL sentences, building/transforming them as necessary to work properly under any RDBMS. The number of places using custom (per DB) code should be minimum.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Well documented&#039;&#039;&#039;: All the functions defined, both at DML and DDL level must be well documented, helping the developer to find and use the correct one in each situation.&lt;br /&gt;
&lt;br /&gt;
== The Stack ==&lt;br /&gt;
&lt;br /&gt;
The next stack shows how Moodle 1.7 code will interact with underlying RDBMS. It will help us to understand a bit more what we are trying to do and will explain some of the points related in the Roadmap (below in this page).&lt;br /&gt;
&lt;br /&gt;
[[Image:MoodleDBStack.png|center]]&lt;br /&gt;
&lt;br /&gt;
Moodle code will use two &#039;&#039;languages&#039;&#039; to perform its DB actions:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;XMLDB neutral description files&#039;&#039;&#039;: To create, modify and delete database objects (DDL: create/alter/drop tables, fields, indexes, constraints...). It consists in a collection of validated, standard, XML files. They will be used to define all the DB objects. New for 1.7.&lt;br /&gt;
* &#039;&#039;&#039;Moodle SQL neutral statements&#039;&#039;&#039;: To add, modify, delete and select database information (DML: insert/update/delete/select records). To modify for 1.7.&lt;br /&gt;
&lt;br /&gt;
Please note the &#039;&#039;&#039;neutral&#039;&#039;&#039; keyword used in the expressions above. It means that both &#039;&#039;&#039;languages&#039;&#039;&#039; will be 100% the same, independently  of the underlying RDBMS being used. And this must be particularly true for the XMLDB part. Point.&lt;br /&gt;
&lt;br /&gt;
Obviously it&#039;s possible that in the SQL part we found some specialised queries (using complex joins, regular expressions...) that will force us to do some &#039;&#039;&#039;Exceptions&#039;&#039;&#039;. Well, they can exist (in fact, they exist), but we always must try to provide an alternate path to minimise them using neutral statements and standard libraries.&lt;br /&gt;
&lt;br /&gt;
Each one of the &#039;&#039;&#039;languages&#039;&#039;&#039; above will use its own library to do the work:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Moodle DDL Library&#039;&#039;&#039; ([[Development:DDL functions|ddllib.php]]): Where all the functions needed to handle DB objects will exist. This library is new for 1.7 and will provide developers with an high level of abstraction. As input it will accept some well defined objects and actions and it will execute the proper commands for the RDBMS being used.&lt;br /&gt;
* &#039;&#039;&#039;Moodle DML Library&#039;&#039;&#039; ([[Development:DML functions|dmllib.php]]): Where all the functions needed to handle DB contents will exist. This library is new for 1.7, although its contents are, basically, functions currently present in &#039;&#039;&#039;datalib.php&#039;&#039;&#039; (moved from there). All those DML functions will offer cross-db support for insert/update/delete/select statements using a common behaviour.&lt;br /&gt;
&lt;br /&gt;
Also note that &#039;&#039;&#039;datalib.php&#039;&#039;&#039; continues present in the schema above. It will contain all the functions that haven&#039;t been moved to the new &#039;&#039;&#039;ddllib.php&#039;&#039;&#039; and &#039;&#039;&#039;dmllib.php&#039;&#039;&#039; libraries. Only some common functions will remain there, and this situation will disappear (it&#039;s considered a legacy library) in upcoming &#039;&#039;&#039;Moodle&#039;&#039;&#039; releases (after 1.7) by moving all those functions to their proper library (course/lib.php, user/lib.php....). &lt;br /&gt;
&lt;br /&gt;
Both these libraries (plus the small &#039;&#039;&#039;Exceptions&#039;&#039;&#039; bar) will perform all their actions using the &#039;&#039;&#039;ADOdb Database Abstraction Library for PHP&#039;&#039;&#039; that will receive all the requests from them, communicate with the DB (&#039;&#039;&#039;MySQL&#039;&#039;&#039;, &#039;&#039;&#039;PostgreSQL&#039;&#039;&#039;, &#039;&#039;&#039;Oracle&#039;&#039;&#039; or &#039;&#039;&#039;SQL*Server&#039;&#039;&#039;), retrieve results and forward them back to originator library.&lt;br /&gt;
&lt;br /&gt;
== The process ==&lt;br /&gt;
&lt;br /&gt;
This section points to the main areas of information about the &#039;&#039;&#039;process of design and implementation&#039;&#039;&#039; of the new XMLDB layer:&lt;br /&gt;
&lt;br /&gt;
* [[XMLDB Roadmap|Roadmap]]: Where the whole process is defined. It has been split into small chuncks to be performed and tested easily. Also, such documents should be used to track what&#039;s done and what&#039;s pending following some easy nomenclature.&lt;br /&gt;
&lt;br /&gt;
* [[XMLDB Problems|Problems]]: A comprensive list of issues that need to be determined/solved prior to incorporating them into the [[XMLDB Roadmap|roadmap]].&lt;br /&gt;
&lt;br /&gt;
== The documentation ==&lt;br /&gt;
&lt;br /&gt;
This section points to the &#039;&#039;&#039;main documentation index&#039;&#039;&#039; about the implemented XMLDB:&lt;br /&gt;
&lt;br /&gt;
* [[Development:XMLDB Documentation|Documentation]]: Where you&#039;ll find quick links to different parts of the XMLDB documentation.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
=== XMLDB related ===&lt;br /&gt;
&lt;br /&gt;
* [[Development:XMLDB preliminary links|XMLDB preliminary links]] - A collection of links about general info, searched and analysed at the initial stages of the project&lt;br /&gt;
* [[Development:XMLDB preliminary notes|XMLDB preliminary notes]] - A collection of notes collected in the early stages of this project, pointing both to some changes required and some problems to solve.&lt;br /&gt;
&lt;br /&gt;
=== Database related ===&lt;br /&gt;
&lt;br /&gt;
* [[Development:DDL functions|DDL functions]] - Documentation for all the Data Definition Language (DDL) functions available inside Moodle.&lt;br /&gt;
* [[Development:DML functions|DML functions]] - Documentation for all the Data Manipulation Language (DML) functions available inside Moodle.&lt;br /&gt;
&lt;br /&gt;
[[Category:XMLDB]]&lt;br /&gt;
&lt;br /&gt;
[[zh:开发:XML数据库计划]]&lt;/div&gt;</summary>
		<author><name>Davidkazuhiro</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/2x/ca/index.php?title=Tracker&amp;diff=40090</id>
		<title>Tracker</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/2x/ca/index.php?title=Tracker&amp;diff=40090"/>
		<updated>2008-07-21T01:11:34Z</updated>

		<summary type="html">&lt;p&gt;Davidkazuhiro: /* Logging new issues or improvements */ fixed section header&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Image:Tracker.jpg]] &#039;&#039;&#039;is Moodle&#039;s&#039;&#039;&#039; [[Image:Issue Tracker MoodleOrg link.JPG]]&lt;br /&gt;
&lt;br /&gt;
Issue tracking is an important part of a continuous quality control process.  It involves the 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 &#039;&#039;&#039;[http://tracker.moodle.org Moodle Tracker]&#039;&#039;&#039;.  We welcome your requests for new features, improvements, or even constructive criticism of existing features.&lt;br /&gt;
&lt;br /&gt;
The beauty of open source is that anyone can participate and help to create a better product for all of us to enjoy. Please help us by using [http://tracker.moodle.org Moodle Tracker]!&lt;br /&gt;
&lt;br /&gt;
==Basics==&lt;br /&gt;
===Logging in to Tracker===&lt;br /&gt;
*If you&#039;re a new Tracker user, create a user account [http://tracker.moodle.org here].  It is strongly suggested your Tracker username is the same name you use at Moodle.org.  &lt;br /&gt;
*If you&#039;ve forgotten your password, go [http://tracker.moodle.org here] and select &#039;&amp;lt;u&amp;gt;forgot password&amp;lt;/u&amp;gt;&#039; which is just under the &#039;log in&#039; button.  Follow the prompts.&lt;br /&gt;
&lt;br /&gt;
=== Summary: How to report a bug, improvement, or new feature request ===&lt;br /&gt;
NB See the section &#039;Tracker fields&#039; below for a full description of every field.&lt;br /&gt;
*Login to [http://tracker.moodle.org Tracker]&lt;br /&gt;
*Select &amp;quot;Create New Issue&amp;quot; from the menu under the Moodle Tracker logo&lt;br /&gt;
*From the dropdown menu select the &amp;quot;Issue type&amp;quot;: Bug, New Feature, Task or Improvement&lt;br /&gt;
*You will see a series of dropdown and free text fields.  Complete as many as you can.  Some fields are required while others are optional.&lt;br /&gt;
*Press the &#039;Create&#039; button at the bottom of the page to create the bug.&lt;br /&gt;
&lt;br /&gt;
=== How to write a good Tracker entry===&lt;br /&gt;
A good report will include:&lt;br /&gt;
*Summary (describe the issue in 1 or 2 sentences)&lt;br /&gt;
*Description (a concise yet complete summary of the problem or improvement)&lt;br /&gt;
*Steps to Reproduce: A detailed, easy-to-follow sequence of steps a developer can follow to reproduce the problem.  If possible, provide a URL so a developer can see the problem with one click.&lt;br /&gt;
*Actual Results: What the application did after performing the above steps.    &lt;br /&gt;
*Expected Results: What the application should have done, were the bug not present.  Provide as much detail as possible. Your expectation might mean that help instructions need to be improved or interface changed.&lt;br /&gt;
&lt;br /&gt;
If possible, include additional information that may be helpful to the developer:&lt;br /&gt;
*Moodle version (there is a dropdown menu on the top of the form, if that does not have what you want, add it in the description)&lt;br /&gt;
* If you have an error message, or information in your PHP or web server logs, copy and paste it into the bug report. If you can, turn on &amp;quot;debug&amp;quot; in your Admin configuration page and reproduce the problem to get the best possible error message.&lt;br /&gt;
* Screen shots are very helpful for some bugs, but please write a textual description of the problem too.&lt;br /&gt;
* Provide details about your setup including operating system, database, etc. If you run out of room in the environment section, add more detail in the description. The full set of information that might be relevant is:&lt;br /&gt;
**Server operating system type and version number&lt;br /&gt;
**Web server type and version number&lt;br /&gt;
**PHP version number (and whether you are using an accelerator)&lt;br /&gt;
**Database type and version number&lt;br /&gt;
**Client-side operating system type and version number&lt;br /&gt;
**Web browser type and version number &lt;br /&gt;
&lt;br /&gt;
* You don&#039;t need to provide details all the time. For example, for a layout rendering problem, you need to give only the client-side OS and browser info, and if it is a server-side problem you only need to describe the setup there. Use your judgment. Here are some examples:&lt;br /&gt;
**I see this bug with the latest Moodle HEAD running on PHP5.1.2/Apache 2.2.3 on Linux. My database is Postgres 8.1. &lt;br /&gt;
**This rendering problem happens using Internet Explorer 6.0 on Windows XP. &lt;br /&gt;
&lt;br /&gt;
In summary stick with facts and present enough facts so someone else can duplicate the problem.&lt;br /&gt;
&lt;br /&gt;
Here are some examples of good bug reports: MDL-6030, MDL-5688, MDL-12505&lt;br /&gt;
&lt;br /&gt;
*A good external reference to help write a tracker entry can be found at [http://developer.mozilla.org/en/docs/Bug_writing_guidelines mozilla bug writing guidelines].&lt;br /&gt;
&lt;br /&gt;
&amp;quot;What’s the hardest thing about a bug report?&amp;quot;  Most of the time fixing the problem is the easy part, the hard part is reproducing the bug.  The developer needs to see how it is broke to be able to fix it.   If they can&#039;t reproduce the error you can be sure they won&#039;t be able to fix it!&lt;br /&gt;
&lt;br /&gt;
Good bug reports contain as much detail as possible and are specific.  Don&#039;t generalise or leap to conclusions.&lt;br /&gt;
&lt;br /&gt;
For example, a bug report that only says &amp;quot;The RSS feed doesn’t support UTF-8&amp;quot; is not helpful. The developer knows that UTF-8 and RSS feeds are compatible.  The developer has no idea of what the person sees and why they reported this bug.  In this case more time and effort needs to be expended to determine the problem.&lt;br /&gt;
&lt;br /&gt;
Consider a bug report which says that the descriptions for the specific RSS feed XYZ@abc shows unrecognisable characters rather than expected characters.&lt;br /&gt;
&lt;br /&gt;
==Tracker process==&lt;br /&gt;
===Logging new issues or improvements===&lt;br /&gt;
Anyone with a Tracker account can log issues.  See instructions above for writing good quality bug reports.  It is important that you search Tracker to determine if your problem or suggestion for improvement has already been reported.  If it has you are encouraged to add more information (use the &amp;quot;comment&amp;quot; function), vote for the issue, or watch it (more on this later).&lt;br /&gt;
&lt;br /&gt;
You will receive an email when you log a new bug or make updates to bugs you&#039;ve reported.  You&#039;ll also receive notification when updates are made to bugs you&#039;re watching.&lt;br /&gt;
&lt;br /&gt;
You can monitor, or &#039;&#039;&#039;watch&#039;&#039;&#039; issues reported by others. To do this, open the issue, then select &amp;quot;Watch it&amp;quot; from the left hand navigation panel. To add others to the watchlist for your issue, open the issue, select the option &amp;quot;Watching&amp;quot; from the left hand navigation panel. These people will receive email notification when the issue is updated.&lt;br /&gt;
&lt;br /&gt;
Tracker provides a facility to &#039;&#039;&#039;Link&#039;&#039;&#039; issues.  Any user logged onto Tracker may link issues.   Multiple link types are defined in the system; you will be required to select one when linking bugs.  See [insert section name] for detailed list of link types.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vote&#039;&#039;&#039; for bugs you want to see addressed in Moodle.  Any user can vote.  To vote for a specific bug, browse to the bug, then select &amp;quot;Vote for it&amp;quot; from the left-hand navigation panel.  Developers may consider the number of votes a bug has when weighing the merits of two or more bugs. &lt;br /&gt;
&lt;br /&gt;
The Tracker &#039;&#039;&#039;Dashboard&#039;&#039;&#039; is flexible and customisable depending on your area of interest.  For instructions on configuring the Tracker dashboard click  [http://www.atlassian.com/software/jira/docs/v3.6.3/dashboard.html here].&lt;br /&gt;
&lt;br /&gt;
The Tracker &#039;&#039;&#039;Issue Navigator&#039;&#039;&#039; is used to find and filter bugs.  For instructions on configuring the Issue Navigator click [http://www.atlassian.com/software/jira/docs/v3.6.4/navigatorcolumns.html here].&lt;br /&gt;
&lt;br /&gt;
Tracker&#039;s &#039;&#039;&#039;Quick Search&#039;&#039;&#039; function is explained [http://www.atlassian.com/software/jira/docs/v3.6.4/quicksearch.html here]&lt;br /&gt;
&lt;br /&gt;
===Resolving issues===&lt;br /&gt;
 (this section should be reviewed)&lt;br /&gt;
Issues are resolved in Tracker to show that they&#039;ve been actioned.  Only Moodle core developers and testers are permitted to change the status of bugs in Tracker to &amp;quot;resolved&amp;quot; or &amp;quot;closed&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This is the general process a developer will follow when actioning a Tracker issue:&lt;br /&gt;
&lt;br /&gt;
# Issues are automatically assigned at the time they&#039;re created based on component type; they may be reassigned by developers or Component Leads.&lt;br /&gt;
# Developers fix, modify or add code and check into CVS.  The Tracker issue number is included which automatically links the CVS change to Tracker.&lt;br /&gt;
# Patches are attached to Tracker issues so that they may be verified and possibly included in CVS.&lt;br /&gt;
# Appropriate comments should be added in Tracker describing the fix.  The bug&#039;s status is changed to &#039;&#039;&#039;Resolved&#039;&#039;&#039;. &lt;br /&gt;
# The developer should indicate which version of Moodle the change will be included in using the &#039;&#039;&#039;Fix Version/s&#039;&#039;&#039;. You should use this to indicate which branch(es) you checked the fix into (example below).&lt;br /&gt;
# The only exception to not moving a bug to Resolved is if a developer believes there is no value in testing the resolved issue, in which case the bug status can be changed to Closed.&lt;br /&gt;
&lt;br /&gt;
===Testing issues===&lt;br /&gt;
All users are encouraged to be active participants when it comes to testing Moodle.  Anyone with a Tracker user account can log, view, comment on, vote, and watch bugs.  If you find bugs or problems, have ideas for improvements, or want additional functionality added to Moodle, please log a bug in Tracker.  &lt;br /&gt;
&lt;br /&gt;
We&#039;ve formalised a group of testers in Tracker who are responsible for verifying the accuracy of changes made by developers.  These testers have responsibilities and authority in Tracker beyond that of standard users. Testers normally have a good understanding of Moodle, and are active in the Moodle community.  Obviously testers should have the skills and knowledge to sufficiently test the issue - experience is important - but don&#039;t forget there are others in the Moodle community who may be willing to lend a hand. If you are interested in becoming a member of the Moodle Testing team, make yourself known by logging a request through Tracker.  We&#039;d love to have you join the team!  Log your request at the [http://tracker.moodle.org/secure/project/ViewProject.jspa?pid=10020 Moodle.org Sites] Tracker project.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Testing a bug in Tracker&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NB This is the process members of the moodle-testers group should follow to move bugs from &#039;resolved&#039; to &#039;closed&#039;. &lt;br /&gt;
*Testers test bugs with Status=Resolved.  Global filters have been created based on upcoming releases (eg 1.7 Resolved) to make identification simple.  &lt;br /&gt;
*Use the &#039;&#039;&#039;QA Assignee&#039;&#039;&#039; field to identify yourself as the tester of a particular bug.  &lt;br /&gt;
 &lt;br /&gt;
*It&#039;s a good idea to add your name to the watch list for all bugs you test. (see &amp;quot;Tracker watch list&amp;quot;, below.)  &lt;br /&gt;
*If the bug passes testing, close the bug using the &amp;quot;Close Issue&amp;quot; button.  You must add appropriate &#039;&#039;&#039;comments&#039;&#039;&#039; describing your testing methods, any issues that were found, etc.&lt;br /&gt;
*If the bug fails testing or if you feel the fix is incomplete, &#039;&#039;&#039;reopen&#039;&#039;&#039; the bug using the &amp;quot;Reopen Issue&amp;quot; button.  Ensure the bug is assigned to the correct developer.  Work with the developer to find a mutually agreeable resolution to the bug. &lt;br /&gt;
*A release will be deemed ready when all bugs fixed for a particular version have been closed.&lt;br /&gt;
*All resolved bugs should be tested.  Bugs with a resolution code of &amp;quot;fixed&amp;quot; represent bugs where code has been updated, and probably represent more of a challenge than bugs with resoluton codes of  duplicate, won&#039;t fix, and not a bug, and can&#039;t reproduce.  Please ensure bugs have been closed with a proper resolution code.  Unfortunately it&#039;s not easy to change a resolution code in Tracker once the bug has been resolved (the only way is to reopen, then re-resolve).  &lt;br /&gt;
*Don&#039;t be afraid to discuss your testing with the developer assigned to the bug.  Simply adding a comment should get the attention of the developer as they are notified of all changes.&lt;br /&gt;
&lt;br /&gt;
==Detailed description of Tracker fields and groups ==&lt;br /&gt;
===Tracker fields===&lt;br /&gt;
NB A short explanation appears under each field in Tracker.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Project&#039;&#039;&#039; - Required field.  Tracker is a collection of multiple projects.  At present there are 3: &#039;moodle&#039;, &#039;moodle.org sites&#039; and &#039;Non-core contributed modules&#039;.  Specify &#039;moodle&#039; for issues/bugs related to moodle software; specify &#039;moodle.org sites&#039; for issues/bugs related to tracker.moodle.org, docs.moodle.org, demo.moodle.org, download.moodle.org, or moodle.org; specify &#039;Non-core contributed modules&#039; for issues/bugs related to contributed modules.  &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Issue Type&#039;&#039;&#039; - Required field.  Bugs are classified as 1 of the following:&lt;br /&gt;
:&#039;&#039;Bug&#039;&#039; - A problem which impairs or prevents Moodle from functioning correctly.&lt;br /&gt;
:&#039;&#039;Improvement&#039;&#039; - An enhancement to an existing Moodle feature.&lt;br /&gt;
:&#039;&#039;New Feature&#039;&#039; - A new Moodle feature which has yet to be developed.&lt;br /&gt;
:&#039;&#039;Task&#039;&#039; - A task that needs to be completed. Tasks usually refer to work that must be done outside the product.&lt;br /&gt;
:&#039;&#039;Sub-Task&#039;&#039; - Issues are sometimes broken into multiple sub-tasks.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Summary&#039;&#039;&#039; - Required field.  A brief, concise description of the problem.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Security Level&#039;&#039;&#039; - Optional field. Specify if this bug or change has security implications for Moodle. Bugs with serious security implications are restricted so that only members of the moodle-security group can see them.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Priority&#039;&#039;&#039; - Bugs are prioritised using one of the following:&lt;br /&gt;
:&#039;&#039;Blocker&#039;&#039; - Blocks development and/or testing work, production could not run.&lt;br /&gt;
:&#039;&#039;Critical&#039;&#039; - Crashes, loss of data, severe memory leak.&lt;br /&gt;
:&#039;&#039;Major&#039;&#039; - Major loss of function.&lt;br /&gt;
:&#039;&#039;Minor&#039;&#039; - Minor loss of function, or other problem where easy workaround is available.&lt;br /&gt;
:&#039;&#039;Trivial&#039;&#039; - Cosmetic problem like misspelled words or misaligned text.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Component/s&#039;&#039;&#039; - Required field.  Select the area in Moodle which is affected by this bug.  Select &#039;Unknown&#039; if you are unsure.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Affects Version/s&#039;&#039;&#039; - Required field.  This is the Moodle version in which the bug has been found.  It is entered by the person logging the bug, and typically only 1 version is specified.  Enter your current version when logging an &#039;improvement&#039;, &#039;task&#039;, or &#039;new feature&#039; as this will help assess the state of the product when the request was made.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Assigned To&#039;&#039;&#039; - This is the person who will fix (code) the issue.  Tracker automatically assigns issues to Component Leads.  Developers or QA Testers can reassign issues.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Reporter&#039;&#039;&#039; - The person who logs the bug.  This field is automatically filled by Tracker.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Environment&#039;&#039;&#039; - Specify the operating system, software platform and/or hardware specifications if applicable to this bug.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Description&#039;&#039;&#039; - A full and complete yet concise description of the problem or improvement.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Database&#039;&#039;&#039; - Optional field.  If applicable to the bug, identify the database type.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;URL&#039;&#039;&#039; - Optional field.  If possible, provide a URL address that demonstrates an example of this bug.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;QA Assignee&#039;&#039;&#039; - Used to designate the person who will test this issue.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Fixed Version/s&#039;&#039;&#039; - This is the Moodle version the bug was or will be fixed in.  Basically you should think &#039;&#039;&#039;Which release notes should this appear in?&#039;&#039;&#039; This field is normally completed by the developer when the bug has been resolved or by lead developers allocating bugs for a specific release.  Normally only one version is specified in this field.  It symbolises the &#039;&#039;first&#039;&#039; version of Moodle where the change will be seen.&lt;br /&gt;
:Example: after Moodle 1.9 has been released, if you fix a bug on the MOODLE_19_STABLE and HEAD branches, mark it as fixed in 1.9.1.  If you also backported to MOODLE_18_STABLE, then add the version of the next 1.8.x release too.&lt;br /&gt;
&lt;br /&gt;
:If you resolve the bug as anything but &amp;quot;Fixed&amp;quot; (Cannot Reproduce, Won&#039;t Fix, etc.) leave Fix Version/s blank.&lt;br /&gt;
:If you resolve the bug as Duplicate, then create a link to the duplicate issue.&lt;br /&gt;
:These Fix version/s are used to automatically build release notes (see the tabs on http://tracker.moodle.org/browse/MDL).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attachment&#039;&#039;&#039; - Optional.  Attach a file that will help developers and testers better understand the bug.  Maximum attachement size is 512Kb.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Comment&#039;&#039;&#039; - The comment field is a detailed register of all changes that relate to this bug.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Resolution&#039;&#039;&#039; - This field is only displayed when resolving or closing a bug.  Specify a code that best describes how this bug was resolved.&lt;br /&gt;
:&#039;&#039;Fixed&#039;&#039; - Bug has been fixed; a code change will be checked into CVS.  Use this resolution code only when actual changes were made to Moodle code.&lt;br /&gt;
:&#039;&#039;Won&#039;t Fix&#039;&#039; - The problem described is an issue which will never be fixed. 	&lt;br /&gt;
:&#039;&#039;Not a bug&#039;&#039; - This issue is not a bug; was logged in error.  Use this code if the bug was fixed by another bug report or in some earlier Moodle version.&lt;br /&gt;
:&#039;&#039;Duplicate&#039;&#039; - The problem is a duplicate of an existing issue.&lt;br /&gt;
:&#039;&#039;Incomplete&#039;&#039; - More information is needed to understand this bug.&lt;br /&gt;
:&#039;&#039;Can&#039;t Reproduce&#039;&#039; - All attempts at reproducing this issue failed, or not enough information was available to reproduce the issue.  Reading the code produces no clues as to why this behavior would occur. If more information appears later, please reopen the issue.&lt;br /&gt;
:&#039;&#039;Deferred&#039;&#039; - The resolution to this bug will be deferred to a later release.&lt;br /&gt;
&lt;br /&gt;
=== Tracker groups and permissions ===&lt;br /&gt;
&#039;&#039;&#039;Standard Users&#039;&#039;&#039; [groupname=jira-user] - This is the default group.  New user accounts are placed in this group at the time of creation, and users must be a member of this group in order to log into Tracker.  Members of this group can browse bugs, create new bugs, comment on bugs, create attachments, create sub-tasks, create filters, watch bugs, and vote for bugs.  Members of this group can also resolve bugs, which is primarily a way of closing bugs that are no longer relevant (eg duplicates, or logged in error).  Standard Users can configure their Tracker workspace by using the &amp;quot;Configure your Issue Navigator&amp;quot; button.  This feature allows users to view watch and voting lists and to manage preferences, profile, and password.&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;Developers&#039;&#039;&#039; [groupname=jira-developer] - Developers can do everything Standard Users can do.  In addition they can clone bugs, close bugs, edit bugs, link bugs, and assign bugs.  Members of this group can also use the Bulk Edit function which allows bulk updated to multiple bugs. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Testers&#039;&#039;&#039; [groupname=moodle-testers] - Testers can do everything a Developer can do.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Moodle Security groups&#039;&#039;&#039; [groupname=moodle-security] - Trusted developers and administrators who need to work on and learn about security issues.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Nobody&amp;quot; is a Tracker user created to alert users to the fact that an issue hasn&#039;t been assigned to a developer.  These issues are regularly reviewed by the team at Moodle HQ.  &lt;br /&gt;
&lt;br /&gt;
NB You can browse a project while not logged in to Tracker, however you will be unable change/edit/comment on bugs.&lt;br /&gt;
&lt;br /&gt;
=== Link types ===&lt;br /&gt;
The following link types are available:&lt;br /&gt;
::duplicates - duplicates are inevitable in a project the size of Moodle.  They occur when a logger is unaware of an existing bug that describes the same problem.  Use &#039;&#039;duplicates&#039;&#039; to link to the first or most comprehensively described instance of the problem.  All duplicates should be linked together.&lt;br /&gt;
::blockers - use this to identify bugs that block others from being fixed.&lt;br /&gt;
::cloners - in some instances a duplicate bug is intentionally created in order to track the fix in another branch of the code - this almost never is used in the Moodle project.&lt;br /&gt;
::dependency - often a fix is dependent on another bug being resolved first, on in a specific order.&lt;br /&gt;
::relates - used to identify a bug that is somehow related to another bug.&lt;br /&gt;
&#039;&#039;&#039;Don&#039;t be afraid to link bugs. &#039;&#039;&#039;  Links are bi-directional meaning that there&#039;s a concept of &#039;inward&#039; and &#039;outward&#039; - it affects how linked bugs are displayed.  This is why you&#039;ll see &amp;quot;blocks/is blocked by&amp;quot; or &amp;quot;duplicates/is duplicated by&amp;quot; in the drop down list of the &#039;&#039;Link Issue&#039;&#039; dialog.  Don&#039;t become too concerned about using the &amp;quot;correct&amp;quot; link type - all link types work similarly.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
*[[Development:Weekly Code Review]]&lt;br /&gt;
*[http://www.atlassian.com/software/jira/ Jira] Tracker is a slightly customised version of Atlassian&#039;s product  &lt;br /&gt;
*Using Moodle [http://moodle.org/mod/forum/discuss.php?d=43952 How to manipulate Moodle developers] forum discussion&lt;br /&gt;
*Wikipedia [http://en.wikipedia.org/wiki/Software_bug Definition of a bug]&lt;br /&gt;
&lt;br /&gt;
[[Category:Teacher]]&lt;br /&gt;
[[Category:Administrator]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Developer tools]]&lt;br /&gt;
&lt;br /&gt;
[[pt:Tracker]]&lt;br /&gt;
[[es:Sistema de bugs]]&lt;br /&gt;
[[fr:Traqueur de bogues]]&lt;/div&gt;</summary>
		<author><name>Davidkazuhiro</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/2x/ca/index.php?title=GIFT_format&amp;diff=36578</id>
		<title>GIFT format</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/2x/ca/index.php?title=GIFT_format&amp;diff=36578"/>
		<updated>2008-05-22T18:27:13Z</updated>

		<summary type="html">&lt;p&gt;Davidkazuhiro: removed german&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;With GIFT format you can write multiple-choice, true-false, short answer, matching and numerical questions in a text editor in a simple format. For large numbers of questions, GIFT is likely to provide the quickest way of bulk loading your questions.&lt;br /&gt;
[[Image:Gift.jpg|frame|left|screen shot from quiz help file documentation]]&amp;lt;br style=&amp;quot;clear:both;&amp;quot;&amp;gt; &lt;br /&gt;
&lt;br /&gt;
At least one blank line must be left between each question.&lt;br /&gt;
&lt;br /&gt;
Here is an [http://moodle.org/file.php/5/moddata/forum/121/236161/GIFT-examples.zip GIFT example] for quiz-import, easy to copy and change ...&lt;br /&gt;
&lt;br /&gt;
The file &#039;&#039;&#039;must&#039;&#039;&#039; be correctly encoded in [[UTF8]]. Beware of some of Microsoft&#039;s &amp;quot;fake&amp;quot; Unicode implementation which is not compatible and may result in strange characters appearing in your quizzes. &lt;br /&gt;
&lt;br /&gt;
Here is a 2-column GIFT format reference sheet I created for a training:&lt;br /&gt;
*[http://buypct.com/gift_reference.pdf GIFT Reference Sheet]&lt;br /&gt;
&lt;br /&gt;
===Hints and Tips===&lt;br /&gt;
&lt;br /&gt;
* Use the ::title:: at the beginning of every question to organize this for you (01 - testquestion), otherwise it would be difficult to find the right question for changes, moodle will take the beginning of every question as internal title.&lt;br /&gt;
* In the Lesson module, in a question page, correct answers jump by default to Next page and incorrect answers jump to This page (i.e. student has to &amp;quot;try again&amp;quot;). When importing from a GIFT format file, this is exactly the mechanism which is used.&lt;br /&gt;
* If you want a student to be taken directly from one question to the next irrespective of their answer being correct or incorrect: in the Lesson Settings, set Maximum number of attempts: to 1. Please note, however, that a message &amp;quot;correct / incorrect&amp;quot; will still be displayed to the student upon answering each question. If you do not want this (default) feedback message to be displayed then enter your own feedback message (i.e. &amp;quot;continue&amp;quot;, &amp;quot;---&amp;quot;, etc.) In case you want no visible message displayed then enter a non-breaking space as feedback, so you&#039;ll have to put a # after the answer which may be ~3 and &#039;&#039;&#039;write &amp;amp; n b s p ; after that.(without spaces between these characters)&#039;&#039;&#039;&lt;br /&gt;
* If you want to use curly braces, { or }, or equal sign, =, or # or ~ in a GIFT file (for example in a math question including TeX expressions) you must &amp;quot;escape&amp;quot; them by preceding them with a \ directly in front of each { or } or =. It is possible to use a replace program/macro/editor filter to do this conversion before importing to Moodle.&lt;br /&gt;
* There are Word macros available for easily creating GIFT files. See [http://www.soberit.hut.fi/sprg/resources/moodle/GiftConverter.html].&lt;br /&gt;
* Here&#039;s an Excel spreadsheet for generating multiple choice GIFT files [http://moodle.org/mod/forum/discuss.php?d=45245] and a newer version that supports other question formats (be sure to scroll down to the most recent version) [http://moodle.org/mod/forum/discuss.php?d=66660].&lt;br /&gt;
* Here&#039;s an Open Office template for generating GIFT files. [http://moodle.org/mod/forum/discuss.php?d=20705&amp;amp;parent=168385]&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
*[[Export questions]]&lt;br /&gt;
*[[Import questions]]&lt;br /&gt;
*[[Aiken Format]]&lt;br /&gt;
*[[Moodle XML format]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Questions]]&lt;/div&gt;</summary>
		<author><name>Davidkazuhiro</name></author>
	</entry>
</feed>