]> git.mjollnir.org Git - moodle.git/commitdiff
Latest updated guide. The Appendixes need more work but up till there
authordefacer <defacer>
Fri, 31 Dec 2004 16:35:29 +0000 (16:35 +0000)
committerdefacer <defacer>
Fri, 31 Dec 2004 16:35:29 +0000 (16:35 +0000)
it's pretty much final.

blocks/HOWTO.html

index 832a6cfafe148a7558a18c7d290c9dc034b8e3c3..c45b09274afd85cbe758db5e5092ec16cd30ff02 100644 (file)
         display: inline;
         font-size: 0.9em;
     }
-    .function_title {
-        font-size: 1.1em;
+    .function_title, .variable_title, .named_constant {
         font-weight: bold;
+    }
+    div.function_title, div.variable_title, div.named_constant {
+        font-size: 1.1em;
         margin: 10px;
     }
+    a.function_title, a.variable_title, a.named_constant {
+        cursor: help;
+    }
+    a, a:visited, a:active {
+        text-decoration: none;
+        color: #009;
+    }
+    a:hover {
+        text-decoration: underline;
+    }
+    .updating {
+        padding: 10px;
+        border: 1px #999 dotted;
+        background-color: #FFD991;
+    }
 </style>
 </head>
 <body>
 
     <h3>Summary</h3>
 
-    <p>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) ONLY, 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 <a href="#appendix_b">Appendix B</a>).</p>
+    <p>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) <strong>only</strong>, 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 <a href="#appendix_b">Appendix B</a>).</p>
 
     <p>The guide is written as an interactive course which aims to develop a configurable, multi-purpose block that displays arbitrary HTML. It'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 <a href="#appendix_a">Appendix A</a> because the main guide has a rather low concentration of pure information in the text.</p>
 
 
     <h3>Basic Concepts</h3>
 
-    <p>Through this guide, we will be following the creation of an "HTML" block from scratch in order to demonstrate most of the block features at our disposal. Our block will be named "SimpleHTML". 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 "simplehtml" in any case where such a name is required. Whenever we refer to a file or directory name which contains "simplehtml", it's important to remember that ONLY the "simplehtml" part is up to us to change; the rest is standardized and essential for Moodle to work correctly.</p>
+    <p>Through this guide, we will be following the creation of an "HTML" block from scratch in order to demonstrate most of the block features at our disposal. Our block will be named "SimpleHTML". 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 "simplehtml" in any case where such a name is required. Whenever we refer to a file or directory name which contains "simplehtml", it's important to remember that <em>only</em> the "simplehtml" part is up to us to change; the rest is standardized and essential for Moodle to work correctly.</p>
 
     <p>Whenever a file'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.</p>
 
 </li>
 
-<li>
+<li id="ready_set_go">
 
     <h3>Ready, Set, Go!</h3>
 
 
     <p>Our class is then given a small method: <a class="function_title" href="#method_init">init</a>. This is essential for all blocks, and its function is to set the three class member variables listed inside it. But what do these values actually mean? Here's a more detailed description.</p>
 
-    <p>$this->title is the title displayed in the header of our block. We can set it to whatever we like; in this case it's set to read the actual title from a language file we are presumably distributing together with the block. I 'll skip ahead a bit here and say that if you want your block to display NO title at all, then you should set this to any descriptive value you want (but NOT make it empty). We will later see <a href="#section_eye_candy">how to disable the title's display</a>.</p>
+    <p><a class="variable_title" href="#variable_title">$this->title</a> is the title displayed in the header of our block. We can set it to whatever we like; in this case it's set to read the actual title from a language file we are presumably distributing together with the block. I 'll skip ahead a bit here and say that if you want your block to display <strong>no</strong> title at all, then you should set this to any descriptive value you want (but <strong>not</strong> make it an empty string). We will later see <a href="#section_eye_candy">how to disable the title's display</a>.</p>
 
-    <p>$this->content_type tells Moodle what kind of content to expect from this block. Here we have two simple choices. Either we set content_type to BLOCK_TYPE_TEXT, which tells Moodle to just take our content and display it on screen as-is; or we set it to BLOCK_TYPE_LIST, which tells Moodle that we want our block to display a nicely formatted list of items with optional icons next to each one. We can use BLOCK_TYPE_TEXT to manually create any content we want (do not be fooled by the name; HTML is allowed in the block's content without restriction) or use BLOCK_TYPE_LIST to easily create a simple menu.</p>
+    <p><a class="variable_title" href="#variable_content_type">$this->content_type</a> tells Moodle what kind of content to expect from this block. Here we have two simple choices. Either we set it to <a class="named_constant" href="#constant_block_type_text">BLOCK_TYPE_TEXT</a>, which tells Moodle to just take our content and display it on screen as-is; or we set it to <a class="named_constant" href="#constant_block_type_list">BLOCK_TYPE_LIST</a>, which tells Moodle that we want our block to display a nicely formatted list of items with optional icons next to each one. We can use <a class="named_constant" href="#constant_block_type_text">BLOCK_TYPE_TEXT</a> to manually create any content we want (do not be fooled by the name; HTML is allowed in the block's content without restriction) or use <a class="named_constant" href="#constant_block_type_list">BLOCK_TYPE_LIST</a> to easily create a simple menu.</p>
 
-    <p>$this->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's used in activities; an upgrade script uses it to incrementally upgrade an "old" version of the block'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, this is certainly the case so we just set $this->version to YYYYMMDD00 and forget about it.</p>
+    <p><a class="variable_title" href="#variable_version">$this->version</a> 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's used in activities; an upgrade script uses it to incrementally upgrade an "old" version of the block'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, this is certainly the case so we just set <a class="variable_title" href="#variable_version">$this->version</a> to YYYYMMDD00 and forget about it.</p>
 
-    <p>UPDATING: Prior to version 1.5, the basic structure of each block class was slightly different. Refer to <a href="#appendix_b">Appendix B</a> for more information on the changes that old blocks have to make to conform to the new standard.</p>
+    <p class="updating"><strong>UPDATING:</strong> Prior to version 1.5, the basic structure of each block class was slightly different. Refer to <a href="#appendix_b">Appendix B</a> for more information on the changes that old blocks have to make to conform to the new standard.</p>
 
 </li>
 
 
     <h3>I Just Hear Static</h3>
 
-    <p>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). All together now:</p>
+    <p>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:</p>
 
     <pre class="code">function get_content() {
     if ($this->content !== NULL) {
 
     <p>It can't get any simpler than that, can it? Let's dissect this method to see what's going on...</p>
 
-    <p>First of all, there is a check that returns the current value of $this->content if it's not NULL; otherwise we proceed with "computing" it. Since the computation is potentially a time-consuming operation and it WILL be called several times for each block (Moodle works that way internally), we take a precaution and include this time-saver.</p>
+    <p>First of all, there is a check that returns the current value of <a class="variable_title" href="#variable_content">$this->content</a> if it's not NULL; otherwise we proceed with "computing" it. Since the computation is potentially a time-consuming operation and it <strong>will</strong> be called several times for each block (Moodle works that way internally), we take a precaution and include this time-saver.</p>
 
-    <p>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't much to say. Just keep in mind that we can use HTML both in the text AND in the footer, if we want to.</p>
+    <p>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't much to say. Just keep in mind that we can use HTML both in the text <strong>and</strong> in the footer, if we want to.</p>
 
     <p>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.</p>
 
 
     <h3>Configure That Out</h3>
 
-    <p>The current version of our block doesn't really do much; it just displays a fixed message. Not very useful. What we 'd really like to do is allow the teachers to customize what goes into the block. This, in block-speak, is called "instance configuration". So let's give our block instance configuration...</p>
+    <p>The current version of our block doesn't really do much; it just displays a fixed message, which is not very useful. What we 'd really like to do is allow the teachers to customize what goes into the block. This, in block-speak, is called "instance configuration". So let's give our block some instance configuration...</p>
 
     <p>First of all, we need to tell Moodle that we want it to provide instance-specific configuration amenities to our block. That's as simple as adding one more method to our block class:</p>
 
 
     <p>This small change is enough to make Moodle display an "Edit..." icon in our block'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's configuration not being implemented correctly. Try it, it's harmless.</p>
 
-    <p>Well, that makes sense. We told Moodle that we want to have configuration, but we didn't tell it WHAT kind of configuration. To do that, we need to create one more file: <span class="filename">/blocks/simplehtml/config_instance.html</span> which as you see has to be named just so. For the moment, copy paste the following into it and save:</p>
+    <p>Moodle's complaints do makes sense. We told it that we want to have configuration, but we didn't say <em>what</em> kind of configuration we want, or how it should be displayed. To do that, we need to create one more file: <span class="filename">/blocks/simplehtml/config_instance.html</span> (which has to be named exactly like that). For the moment, copy paste the following into it and save:</p>
 
 <pre class="code">
 &lt;table cellpadding="9" cellspacing="0"&gt;
 
     <p>It isn't difficult to see that the above code just provides us with a wysiwyg-editor-enabled textarea to write our block's desired content in and a submit button to save. But... what's $this->config->text? Well...</p>
 
-    <p>Moodle goes a long way to make things easier for block developers. Did you notice that the textarea is actually named "text"? When the submit button is pressed, Moodle saves each and every field it can find in our config_instance.html file as instance configuration data. We can then access that data as $this->config->variablename, where variablename is the actual name we used for our field; in this case, "text". 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.</p>
+    <p>Moodle goes a long way to make things easier for block developers. Did you notice that the textarea is actually named "text"? When the submit button is pressed, Moodle saves each and every field it can find in our config_instance.html file as instance configuration data. We can then access that data as <strong>$this->config-><em>variablename</em></strong>, where <em>variablename</em> is the actual name we used for our field; in this case, "text". 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.</p>
 
-    <p>You also might be surprised by the presence of a submit button and the absence of any &lt;form&gt; element at the same time. But the truth is, we don'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 EXCEPT init().</p>
+    <p>You also might be surprised by the presence of a submit button and the absence of any &lt;form&gt; element at the same time. But the truth is, we don'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 <em>except</em> <a class="function_title" href="#method_init">init</a>.</p>
 
     <p>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 <a href="#appendix_a">Appendix A</a> for more details.</p>
 
-    <p>Having now the ability to refer to this instance configuration data through $this->config, the final twist is to tell our block to actually DISPLAY what is saved in is configuration data. To do that, find this snippet in <span class="filename">/blocks/simplehtml/block_simplehtml.php</span>:</p>
+    <p>Having now the ability to refer to this instance configuration data through <a class="variable_title" href="#variable_config">$this->config</a>, the final twist is to tell our block to actually <em>display</em> what is saved in is configuration data. To do that, find this snippet in <span class="filename">/blocks/simplehtml/block_simplehtml.php</span>:</p>
 
     <pre class="code">
 $this->content = new stdClass;
@@ -233,7 +250,7 @@ $this->content->footer = '';</pre>
 
     <p>Implementing instance configuration for the block's contents was good enough to whet our apetite, but who wants to stop there? Why not customize the block's title, too?</p>
 
-    <p>Why not, indeed. Well, our first attempt is natural enough: let's add another field to /blocks/simplehtml/config_instance.html. Here goes:</p>
+    <p>Why not, indeed. Well, our first attempt is natural enough: let's add another field to <span class="filename">/blocks/simplehtml/config_instance.html</span>. Here goes:</p>
 
     <pre class="code">
 &lt;tr valign="top"&gt;
@@ -244,7 +261,7 @@ $this->content->footer = '';</pre>
 
     <p>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's not being displayed. All we get is just the simple "SimpleHTML" title.</p>
 
-    <p>That's not too wierd, if we think back a bit. Do you remember that init() method, where we set $this->title? We didn't actually change its value from then, and $this->title is definitely not the same as $this->config->title (to Moodle, at least). What we need is a way to update $this->title with the value in the instance configuration. But as we said a bit earlier, you can use $this->config in all methods EXCEPT init()! So what can we do?</p>
+    <p>That's not too wierd, if we think back a bit. Do you remember that <a class="function_title" href="#method_init">init</a> method, where we set <a class="variable_title" href="#variable_title">$this->title</a>? We didn't actually change its value from then, and <a class="variable_title" href="#variable_title">$this->title</a> is definitely not the same as $this->config->title (to Moodle, at least). What we need is a way to update <a class="variable_title" href="#variable_title">$this->title</a> with the value in the instance configuration. But as we said a bit earlier, you can use <a class="variable_title" href="#variable_config">$this->config</a> in all methods <em>except</em> <a class="function_title" href="#method_init">init</a>! So what can we do?</p>
 
     <p>Let's pull out another ace from our sleeve, and add this small method to our block class:</p>
 
@@ -253,9 +270,9 @@ function specialization() {
     $this->title = $this->config->title;
 }</pre>
 
-    <p>Aha, here's what we wanted to do all along! But what's with the specialization() method?</p>
+    <p>Aha, here's what we wanted to do all along! But what's with the <a class="function_title" href="#method_specialization">specialization</a> method?</p>
 
-    <p>This "magic" method has actually a very nice property: it's GUARANTEED to be automatically called by Moodle as soon as our instance configuration is loaded and available (that is, a bit after init() is called). That means before the block's content is computed for the first time, and indeed before ANYTHING is else done with the block. Thus, providing a specialization() method is the natural choice for any configuration data that needs to be acted upon "as soon as possible", as in this case.</p>
+    <p>This "magic" method has actually a very nice property: it's <em>guaranteed</em> to be automatically called by Moodle as soon as our instance configuration is loaded and available (that is, a bit after <a class="function_title" href="#method_init">init</a> is called). That means before the block's content is computed for the first time, and indeed before <em>anything</em> is else done with the block. Thus, providing a <a class="function_title" href="#method_specialization">specialization</a> method is the natural choice for any configuration data that needs to be acted upon "as soon as possible", as in this case.</p>
 
     <p>Unrelated to the above discussion, we also remove the footer from our block because it doesn'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</p>
 
@@ -279,17 +296,17 @@ $this->content->footer = '';</pre>
 
     <p>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't have anything useful to say. (An example here would be the "Recent Activity" 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 "disappear" if it's not needed to display it.</p>
 
-    <p>This is indeed possible, and the way to do it is to make sure that after the get_content() method is called, the block is completely void of content. Specifically:</p>
+    <p>This is indeed possible, and the way to do it is to make sure that after the <a class="function_title" href="#method_get_content">get_content</a> method is called, the block is completely void of content. Specifically:</p>
 
     <ul>
 
-    <li>If $this->content_type equals BLOCK_TYPE_TEXT, then "void of content" means that both $this->content->text and $this->content->footer are each equal to the empty string ('').</li>
+    <li>If <a class="variable_title" href="#variable_content_type">$this->content_type</a> equals <a class="named_constant" href="#constant_block_type_text">BLOCK_TYPE_TEXT</a>, then "void of content" means that both $this->content->text and $this->content->footer are each equal to the empty string ('').</li>
 
-    <li>If $this->content_type equals BLOCK_TYPE_LIST, then "void of content" means that $this->content->items is an empty array and $this->content->footer is equal to the empty string ('').</li>
+    <li>If <a class="variable_title" href="#variable_content_type">$this->content_type</a> equals <a class="named_constant" href="#constant_block_type_list">BLOCK_TYPE_LIST</a>, then "void of content" means that $this->content->items is an empty array and $this->content->footer is equal to the empty string ('').</li>
     
     </ul>
 
-    <p>Refer to <a href="#">Part 3</a> which explains the init() function for more information on $this->content_type and its significance. Note that the exact value of the block's title and the presence or absence of a hide_header() method do NOT affect this behavior. A block is considered empty if it has no content, irrespective of anything else.</p>
+    <p>Refer to <a href="#ready_set_go">Part 3</a> which explains the <a class="function_title" href="#method_init">init</a> function for more information on <a class="variable_title" href="#variable_content_type">$this->content_type</a> and its significance. Note that the exact value of the block's title and the presence or absence of a <a class="function_title" href="#method_hide_header">hide_header</a> method do <em>not</em> affect this behavior. A block is considered empty if it has no content, irrespective of anything else.</p>
 
 </li>
 
@@ -308,7 +325,7 @@ function instance_allow_multiple() {
 
     <p>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.</p>
 
-    <p>And finally, a nice detail is that as soon as we defined an instance_allow_config() method, the method 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 "Edit" icon. So, you can also remove the whole instance_allow_config() method now without harm. We had only needed it when multiple instances of the block had not been allowed.</p>
+    <p>And finally, a nice detail is that as soon as we defined an <a class="function_title" href="#method_instance_allow_multiple">instance_allow_multiple</a> method, the method <a class="function_title" href="#method_instance_allow_config">instance_allow_config</a> 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 "Edit" icon. So, we can also remove the whole <a class="function_title" href="#method_instance_allow_config">instance_allow_config</a> method now without harm. We had only needed it when multiple instances of the block had not been allowed.</p>
 
 </li>
 
@@ -339,17 +356,17 @@ function has_config() {
 &lt;/div&gt;
 </pre>
 
-    <p>True to our block's name, this looks simple enough. What it does is that it displays a checkbox named "block_simplehtml_strict" and if the Moodle configuration variable with the same name is set and not empty (that means it'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's good practice to use a descriptive name and also one that won't possibly conflict with the name of another setting. "block_simplehtml_strict" clearly satisfies both requirements.</p>
+    <p>True to our block's name, this looks simple enough. What it does is that it displays a checkbox named "block_simplehtml_strict" and if the Moodle configuration variable with the same name (i.e., $CFG->block_simplehtml_strict) is set and not empty (that means it'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's good practice to use a descriptive name and also one that won't possibly conflict with the name of another setting. "block_simplehtml_strict" clearly satisfies both requirements.</p>
 
-    <p>The astute reader may have noticed that we actually have TWO input fields named "block_simplehtml_strict" 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?</p>
+    <p>The astute reader may have noticed that we actually have <em>two</em> input fields named "block_simplehtml_strict" 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?</p>
 
     <p>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 "0", and our "strict" setting cannot be turned off at all once we turn it on for the first time. Not the behavior we want, surely.</p>
 
-    <p>However, PHP handles received variables from a form this way: 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 "block_simplehtml_strict" is first unconditionally set to "0". Then, IF the box is checked, it is set to "1", overwriting the previous value as discussed. The net result is that our configuration setting behaves as it should.</p>
+    <p>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 "block_simplehtml_strict" is first unconditionally set to "0". Then, <em>if</em> the box is checked, it is set to "1", overwriting the previous value as discussed. The net result is that our configuration setting behaves as it should.</p>
 
-    <p>To round our bag of tricks up, notice that the use of if(!empty($CFG->block_simplehtml_strict)) in the test for "should the box be checked by default?" is quite deliberate. The first time this script runs, the variable $CFG->block_simplehtml_strict will not exist at all. After it's set for the first time, its value can be either "0" or "1". Given that both "not set" and the string "0" evaluate as empty while the sting "1" does not, we manage to avoid any warnings from PHP regarding the variable not being set at all, AND have a nice human-readable representation for its two possible values ("0" and "1").</p>
+    <p>To round our bag of tricks up, notice that the use of if(!empty($CFG->block_simplehtml_strict)) in the test for "should the box be checked by default?" is quite deliberate. The first time this script runs, the variable $CFG->block_simplehtml_strict will not exist at all. After it's set for the first time, its value can be either "0" or "1". Given that both "not set" and the string "0" evaluate as empty while the sting "1" does not, we manage to avoid any warnings from PHP regarding the variable not being set at all, <em>and</em> have a nice human-readable representation for its two possible values ("0" and "1").</p>
 
-    <p>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 config_save(), the default implementation of which is as follows:</p>
+    <p>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 <a class="function_title" href="#method_config_save">config_save</a>, the default implementation of which is as follows:</p>
 
     <pre class="code">
 function config_save($data) {
@@ -379,7 +396,7 @@ function config_save($data) {
 
     <p>We could decide to do one of two things: either have the block "clean" HTML out from the input before saving it in the instance configuration and then display it as-is (the "eager" approach); or have it save the data "as is" and then clean it up each time just before displaying it (the "lazy" 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.</p>
 
-    <p>Much as we did just before with overriding config_save(), what is needed here is overriding the method instance_config_save() which handles the instance configuration. The default implementation is as follows:</p>
+    <p>Much as we did just before with overriding <a class="function_title" href="#method_config_save">config_save</a>, what is needed here is overriding the method <a class="function_title" href="#method_instance_config_save">instance_config_save</a> which handles the instance configuration. The default implementation is as follows:</p>
 
     <pre class="code">
 function instance_config_save($data) {
@@ -389,7 +406,7 @@ function instance_config_save($data) {
                      'id', $this->instance->id);
 }</pre>
 
-    <p>This may look intimidating at first (what's all this stripslashes_recursive() and base64_encode() and serialize() stuff?) but do not despair; we won'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 will go like this:</p>
+    <p>This may look intimidating at first (what's all this stripslashes_recursive() and base64_encode() and serialize() stuff?) but do not despair; we won'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:</p>
 
     <pre class="code">
 function instance_config_save($data) {
@@ -403,13 +420,13 @@ function instance_config_save($data) {
     return parent::instance_config_save($data);
 }</pre>
 
-    <p>At last! Now the administrator has absolute power of life and death over what type of content is allowed in our "SimpleHTML" 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 in, and then the administrator changes the setting to "off", this will only prevent subsequent content changes from having HTML included. Blocks which already have HTML in their content won't lose it!</p>
+    <p>At last! Now the administrator has absolute power of life and death over what type of content is allowed in our "SimpleHTML" 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 "off", this will only prevent subsequent content changes from including HTML. Blocks which already had HTML in their content would continue to display it!</p>
 
-    <p>Following that train of thought, the next stop is realizing that we wouldn't have this problem if we had chosen the lazy approach a while back, because in that case we would "sanitize" each block'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 "HTML off"; but even then, turning the setting back to "HTML on" won't bring back the tags we stripped away. On the other hand, the lazy approach might be slower, but it's more versatile; we can choose whether to strip or keep the HTML before displaying the content, and we won't lose them at all if the admin toggles the setting off and on again. Isn't the life of a developer simple and wonderful?</p>
+    <p>Following that train of thought, the next stop is realizing that we wouldn't have this problem if we had chosen the lazy approach a while back, because in that case we would "sanitize" each block'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 "HTML off"; but even then, turning the setting back to "HTML on" won't bring back the tags we stripped away. On the other hand, the lazy approach might be slower, but it's more versatile; we can choose whether to strip or keep the HTML before displaying the content, and we won't lose them at all if the admin toggles the setting off and on again. Isn't the life of a developer simple and wonderful?</p>
 
-    <p>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 "correctly", find out how to strengthen the eager approach to strip out all tags from the existing configuration of all instances of our block, OR go back and implement the lazy approach instead. (Hint: do that in the get_content() method)</p>
+    <p>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 "correctly", find out how to strengthen the eager approach to strip out all tags from the existing configuration of all instances of our block, <strong>or</strong> go back and implement the lazy approach instead. (Hint: do that in the <a class="function_title" href="#method_get_content">get_content</a> method)</p>
 
-    <p class="updating">UPDATING: Prior to version 1.5, the file "config_global.html" was named simply "config.hmtl". Also, the methods config_save() and config_print() were named handle_config() and print_config() respectively. Upgrading a block to work with Moodle 1.5 involves updating these aspects; refer to <a href="#appendix_b">Appendix B</a> for more information.</p>
+    <p class="updating"><strong>UPDATING</strong>: Prior to version 1.5, the file "config_global.html" was named simply "config.hmtl". Also, the methods <a class="function_title" href="#method_config_save">config_save</a> and <a class="function_title" href="#method_config_print">config_print</a> were named <strong>handle_config</strong> and <strong>print_config</strong> respectively. Upgrading a block to work with Moodle 1.5 involves updating these aspects; refer to <a href="#appendix_b">Appendix B</a> for more information.</p>
 
 </li>
 
@@ -426,9 +443,9 @@ function hide_header() {
     return true;
 }</pre>
 
-    <p>As you see, hiding the title is quite straightforward. One more note here: you cannot just set an empty title inside the block's init() method; it's necessary for each block to have a unique, non-empty title after init() is called so that Moodle can use those titles to differentiate between all of the installed blocks.</p>
+    <p>As you see, hiding the title is quite straightforward. One more note here: you cannot just set an empty title inside the block's <a class="function_title" href="#method_init">init</a> method; it's necessary for each block to have a unique, non-empty title after <a class="function_title" href="#method_init">init</a> is called so that Moodle can use those titles to differentiate between all of the installed blocks.</p>
 
-    <p>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's being displayed can choose to use this value or, more probably, bring it within some specific range of values if it isn't already. That means that the width setting is a best-effort settlement; your block can REQUEST a certain width and Moodle will TRY to provide it, but there'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.</p>
+    <p>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's being displayed can choose to use this value or, more probably, bring it within some specific range of values if it isn't already. That means that the width setting is a best-effort settlement; your block can <em>request</em> a certain width and Moodle will <em>try</em> to provide it, but there'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.</p>
 
     <p>To instruct Moodle about our block's preferred width, we add one more method to the block class:</p>
 
@@ -440,7 +457,7 @@ function preferred_width() {
 
     <p>This will make our block (and all the other blocks displayed at the same side of the page) a bit wider than standard.</p>
 
-    <p>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 TABLE 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="black"), or b) give us freedom to customize the end result using CSS (this is in fact done by default as we 'll see below).</p>
+    <p>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 &lt;table&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="black"), or b) give us freedom to customize the end result using CSS (this is in fact done by default as we 'll see below).</p>
 
     <p>The default behavior of this feature in our case will assign to our block's container the id HTML attribute with the value "block_simplehtml" (the prefix "block_" followed by the name of our block, lowercased). We can then use that id to make CSS selectors in our theme to alter this block's visual style (for example, "#block_simplehtml { border: 1px black solid}").</p>
 
@@ -454,7 +471,7 @@ function html_attributes() {
     );
 }</pre>
 
-    <p>will result in a mouseover event being added to our block using JavaScript, just as if we had written the onmouseover="alert(...)" part ourselves in HTML. Note that we actually duplicate the part which sets the id attribute (we want to keep that, and since we override the default behavior it's our responsibility to emulate it if required). And the final elegant touch is that we don't set the id to the hard-coded value "block_simplehtml" but instead use the name() method to make it dynamically match our block's name.</p>
+    <p>will result in a mouseover event being added to our block using JavaScript, just as if we had written the onmouseover="alert(...)" part ourselves in HTML. Note that we actually duplicate the part which sets the id attribute (we want to keep that, and since we override the default behavior it's our responsibility to emulate it if required). And the final elegant touch is that we don't set the id to the hard-coded value "block_simplehtml" but instead use the <a class="function_title" href="#method_name">name</a> method to make it dynamically match our block's name.</p>
 
 </li>
 
@@ -468,14 +485,14 @@ function html_attributes() {
 
     <p>The format names we can use are: "weeks", "topics", and "social", which correspond to the three standard course format in Moodle; "site", which refers specifically to the front page of our Moodle installation; and "all", which is a fallback case and applies to everything. We can mix and match between these to create the desired effect. If a name is not present at all as a key in the array, it is assumed to be "false".</p>
 
-    <p>For example, to have our block appear ONLY in the site front page, we would use:</p>
+    <p>For example, to have our block appear <strong>only</strong> in the site front page, we would use:</p>
 
     <pre class="code">
 function applicable_formats() {
     return array('site' => true);
 }</pre>
 
-    <p>Since "all" is missing, the block is disallowed from appearing in ANY course format; but then "site" is set to true, so it's explicitly allowed to appear in the site front page. For another example, if we wanted to allow the block to appear in all course formats EXCEPT social, and also to NOT be allowed at the front page, we would use:</p>
+    <p>Since "all" is missing, the block is disallowed from appearing in <em>any</em> course format; but then "site" is set to true, so it's explicitly allowed to appear in the site front page. For another example, if we wanted to allow the block to appear in all course formats <em>except</em> social, and also to <em>not</em> be allowed at the front page, we would use:</p>
 
     <pre class="code">
 function applicable_formats() {
@@ -490,13 +507,13 @@ function applicable_formats() {
 
     <h3>Lists and Icons</h3>
 
-    <p>In this final part of the guide, we will briefly discuss what the differences between blocks of BLOCK_TYPE_TEXT and those of BLOCK_TYPE_LIST are. The vast majority of the techniques and options discussed before apply to any block; the only difference is in the handling of the $this->content variable.</p>
+    <p>In this final part of the guide, we will briefly discuss what the differences between blocks of <a class="named_constant" href="#constant_block_type_text">BLOCK_TYPE_TEXT</a> and those of <a class="named_constant" href="#constant_block_type_list">BLOCK_TYPE_LIST</a> are. The vast majority of the techniques and options discussed before apply to any block; the only difference is in the handling of the <a class="variable_title" href="#variable_content">$this->content</a> variable.</p>
 
-    <p>As we have seen, blocks of BLOCK_TYPE_TEXT use two properties of $this->content: "text" and "footer". The text is displayed as-is as the block content, and the footer goes below in smaller font size. Blocks of BLOCK_TYPE_LIST use $this->content->footer in the exact same way, but they ignore $this->content->text.</p>
+    <p>As we have seen, blocks of <a class="named_constant" href="#constant_block_type_text">BLOCK_TYPE_TEXT</a> use two properties of <a class="variable_title" href="#variable_content">$this->content</a>: "text" and "footer". The text is displayed as-is as the block content, and the footer goes below in smaller font size. Blocks of <a class="named_constant" href="#constant_block_type_list">BLOCK_TYPE_LIST</a> use $this->content->footer in the exact same way, but they ignore $this->content->text.</p>
 
-    <p>Instead, Moodle expects such blocks to set two other properties when the get_content() method is called. $this->content->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 links, so being free to write HTML allows us to provide anchor tags as list items. $this->content->icons should also be a numerically indexed array, with exactly as many items as $this->content->items has. Each of these items should be a fully qualified HTML &lt;img&gt; tag, with "src", "height", "width" and "alt" attributes. Obviously, it makes sense to keep the images small and of a uniform size.</p>
+    <p>Instead, Moodle expects such blocks to set two other properties when the <a class="function_title" href="#method_get_content">get_content</a> method is called. $this->content->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 links, so being free to write HTML allows us to provide anchor tags as list items. $this->content->icons should also be a numerically indexed array, with exactly as many items as $this->content->items has. Each of these items should be a fully qualified HTML &lt;img&gt; tag, with "src", "height", "width" and "alt" attributes. Obviously, it makes sense to keep the images small and of a uniform size.</p>
 
-    <p>Thus, if we were to create a list block, our get_content() method might read:</p>
+    <p>Thus, if we were to create a list block, our <a class="function_title" href="#method_get_content">get_content</a> method might read:</p>
 
     <pre class="code">
 function get_content() {
@@ -535,7 +552,7 @@ function get_content() {
 
 <ul>
 
-<li id="applicable_formats">
+<li id="method_applicable_formats">
 
     <div class="function_title">applicable_formats</div>
 
@@ -551,7 +568,7 @@ function applicable_formats() {
 
 </li>
 
-<li id="config_print">
+<li id="method_config_print">
 
     <div class="function_title">config_print</div>
 
@@ -573,14 +590,14 @@ function config_print() {
 
     <ol>
     <li>If you save your configuration options in $CFG, you will probably need to use global $CFG; before including any HTML configuration screens.</li>
-    <li>Whatever you do output from config_print(), it will be enclosed in a HTML form automatically. You only need to provide a way to submit that form.</li>
+    <li>Whatever you do output from <a class="function_title" href="#method_config_print">config_print</a>, it will be enclosed in a HTML form automatically. You only need to provide a way to submit that form.</li>
     </ol>
 
     <p>You should return a boolean value denoting the success or failure of your method's actions.</p>
 
 </li>
 
-<li id="config_save">
+<li id="method_config_save">
 
     <div class="function_title">config_save</div>
 
@@ -602,7 +619,7 @@ function config_save($data) {
 
 </li>
 
-<li id="get_content">
+<li id="method_get_content">
 
     <div class="function_title">get_content</div>
 
@@ -612,19 +629,19 @@ function get_content() {
     return NULL;
 }</pre>
 
-    <p>This method should, when called, populate the $this->content variable of your block. Populating the variable means:
+    <p>This method should, when called, populate the <a class="variable_title" href="#variable_content">$this->content</a> variable of your block. Populating the variable means:
 
-    <p><strong>EITHER</strong><br />defining $this->content->text and $this->content->footer if your block is of type BLOCK_TYPE_TEXT. Both of these should be strings which can contain arbitrary HTML.</p>
+    <p><strong>EITHER</strong><br />defining $this->content->text and $this->content->footer if your block is of type <a class="named_constant" href="#constant_block_type_text">BLOCK_TYPE_TEXT</a>. Both of these should be strings which can contain arbitrary HTML.</p>
 
-    <p><strong>OR</strong><br />defining $this->content->items, $this->content->icons and $this->content->footer if your block is of type BLOCK_TYPE_LIST. The first two should be numerically indexed arrays with the same number of elements. $this->content->items can contain arbitrary HTML while $this->content->icons should only contain fully-qualified HTML img tags. $this->content->footer is a string, as above.</p>
+    <p><strong>OR</strong><br />defining $this->content->items, $this->content->icons and $this->content->footer if your block is of type <a class="named_constant" href="#constant_block_type_list">BLOCK_TYPE_LIST</a>. The first two should be numerically indexed arrays with the same number of elements. $this->content->items can contain arbitrary HTML while $this->content->icons should only contain fully-qualified HTML img tags. $this->content->footer is a string, as above.</p>
 
     <p>If you set ALL of these variables to their default "empty" values (empty arrays for the arrays and empty strings for the strings), the block will NOT be displayed at all except to editing users. This is a good way of having your block NOT displayed if there is no reason for it.</p>
 
-    <p>Your function should return the fully constructed $this->content variable. You should also include a check that, if this variable is not exactly equal to NULL, returns the existing value instead of calculating it once more. If you fail to do this, Moodle will suffer a performance hit.</p>
+    <p>Your function should return the fully constructed <a class="variable_title" href="#variable_content">$this->content</a> variable. You should also include a check that, if this variable is not exactly equal to NULL, returns the existing value instead of calculating it once more. If you fail to do this, Moodle will suffer a performance hit.</p>
 
 </li>
 
-<li id="has_config">
+<li id="method_has_config">
 
     <div class="function_title">has_config</div>
 
@@ -637,7 +654,7 @@ function has_config() {
 
 </li>
 
-<li id="hide_header">
+<li id="method_hide_header">
 
     <div class="function_title">hide_header</div>
 
@@ -651,7 +668,7 @@ function hide_header() {
 
 </li>
 
-<li id="html_attributes">
+<li id="method_html_attributes">
 
     <div class="function_title">html_attributes</div>
 
@@ -665,7 +682,22 @@ function html_attributes() {
 
 </li>
 
-<li id="instance_allow_config">
+<li id="method_init">
+
+    <div class="function_title">init</div>
+
+    <pre class="code">
+function init() {
+    $this->title = get_string('simplehtml', 'block_simplehtml');
+    $this->content_type = BLOCK_TYPE_TEXT;
+    $this->version = 2004111200;
+}</pre>
+
+    <p>This method must be implemented for all blocks. It has to assign meaningful values to the object variables <a class="variable_title" href="#variable_title">$this->title</a>, <a class="variable_title" href="#variable_content_type">$this->content_type</a> (which must be either <a class="named_constant" href="#constant_block_type_text">BLOCK_TYPE_TEXT</a> or <a class="named_constant" href="#constant_block_type_list">BLOCK_TYPE_LIST</a>) and <a class="variable_title" href="#variable_version">$this->version</a> (which is used by Moodle for performing automatic updates when available). No return value is expected.</p>
+
+</li>
+
+<li id="method_instance_allow_config">
 
     <div class="function_title">instance_allow_config</div>
 
@@ -680,7 +712,7 @@ function instance_allow_config() {
 
 </li>
 
-<li id="instance_allow_multiple">
+<li id="method_instance_allow_multiple">
 
     <div class="function_title">instance_allow_multiple</div>
 
@@ -695,7 +727,7 @@ function instance_allow_multiple() {
 
 </li>
 
-<li id="instance_config_print">
+<li id="method_instance_config_print">
 
     <div class="function_title">instance_config_print</div>
 
@@ -719,11 +751,11 @@ function instance_config_print() {
     return true;
 }</pre>
 
-    <p>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 config_print(), it will be enclosed in a HTML form automatically. You only need to provide a way to submit that form.</p>
+    <p>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 <a class="function_title" href="#method_instance_config_print">config_print</a>, it will be enclosed in a HTML form automatically. You only need to provide a way to submit that form.</p>
 
     <p>You should return a boolean value denoting the success or failure of your method's actions.</p>
 
-<li id="instance_config_save">
+<li id="method_instance_config_save">
 
     <div class="function_title">instance_config_save</div>
 
@@ -739,13 +771,13 @@ function instance_config_save($data) {
 
     <p>The configuration must be stored in the "configdata" 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.</p>
 
-    <p>Note that what you receive as an argument will NOT be all of the POST data; Moodle will automatically strip out some bits it added itself (such as "sesskey"), so it's quite safe to save everything you receive.</p>
+    <p>Note that what you receive as an argument will <em>not</em> be all of the POST data; Moodle will automatically strip out some bits it added itself (such as "sesskey"), so it's quite safe to save everything you receive.</p>
 
     <p>You should return a boolean value denoting the success or failure of your method's actions.</p>
 
 </li>
 
-<li id="preferred_width">
+<li id="method_preferred_width">
 
     <div class="function_title">preferred_width</div>
 
@@ -761,7 +793,7 @@ function preferred_width() {
 
 </li>
 
-<li id="refresh_content">
+<li id="method_refresh_content">
 
     <div class="function_title">refresh_content</div>
 
@@ -774,11 +806,11 @@ function refresh_content() {
 
     <p>This method should cause your block to recalculate its content immediately. If you follow the guidelines for get_content, which say to respect the current content value unless it is NULL, then the default implementation will do the job just fine.</p>
 
-    <p>You should return the new value of $this->content after refreshing it.</p>
+    <p>You should return the new value of <a class="variable_title" href="#variable_content">$this->content</a> after refreshing it.</p>
 
 </li>
 
-<li id="specialization">
+<li id="method_specialization">
 
     <div class="function_title">specialization</div>
 
@@ -799,16 +831,16 @@ function specialization() {
 
 <ul>
 
-<li id="get_content_type">
+<li id="method_get_content_type">
     <div class="function_title">get_content_type</div>
 </li>
-<li id="get_title">
+<li id="method_get_title">
     <div class="function_title">get_title</div>
 </li>
-<li id="get_version">
+<li id="method_get_version">
     <div class="function_title">get_version</div>
 </li>
-<li id="name">
+<li id="method_name">
     <div class="function_title">name</div>
 </li>
 
@@ -817,27 +849,67 @@ function specialization() {
 </li>
 
 <li>Methods which you should NOT override and NOT use at all:
-
-<ul>
-<li id="_self_test">
+  <ul>
+  <li id="method__self_test">
     <div class="function_title">_self_test</div>
-</li>
-<li id="add_edit_controls">
+  </li>
+  <li id="method_add_edit_controls">
     <div class="function_title">add_edit_controls</div>
-</li>
-<li id="load_instance">
+  </li>
+  <li id="method_load_instance">
     <div class="function_title">load_instance</div>
-</li>
-<li id="print_block">
+  </li>
+  <li id="method_print_block">
     <div class="function_title">print_block</div>
-</li>
-<li id="print_shadow">
+  </li>
+  <li id="method_print_shadow">
     <div class="function_title">print_shadow</div>
+  </li>
+  </ul>
 </li>
+
 </ul>
 
-</li>
+<p>The class block_base also has a few standard member variables which its methods manipulate. These variables and their uses are explained hereafter:</p>
+
+<ul>
+  <li id="variable_title">
+    <div class="variable_title">$this->title</div>
+    <p>This variable should be a string that contains the human-readable name of the block. It is used to refer to blocks of that type everywhere, for example in the administrator's block configuration screen. The variable is expected to have a valid value after the framework calls the <a class="function_title" href="#method_init">init</a> method for each block.</p>
+    <p>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 <a class="function_title" href="#method_init">init</a>. This title may then be overridden when the <a class="function_title" href="#method_specialization">specialization</a> method is called by the framework.</p>
+  </li>
+  <li id="variable_content_type">
+    <div class="variable_title">$this->content_type</div>
+    <p>This variable instructs Moodle on what type of content it should assume the block provides. 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 varaible <a class="variable_title" href="#variable_content">$this->content</a>. The variable is expected to have a valid value after the framework calls the <a class="function_title" href="#method_init">init</a> method for each block.</p>
+    <p>The only valid values for this variable are the two named constants <a class="named_constant" href="#constant_block_type_text">BLOCK_TYPE_TEXT</a> and <a class="named_constant" href="#constant_block_type_list">BLOCK_TYPE_LIST</a>.</p>
+  </li>
+  <li id="variable_content">
+    <div class="variable_title">$this->content</div>
+    <p>!!!UNFINISHED!!! This variable instructs Moodle on what type of content it should assume the block provides. 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 varaible <a class="variable_title" href="#variable_content">$this->content</a>. The variable is expected to have a valid value after the framework calls the <a class="function_title" href="#method_init">init</a> method for each block.</p>
+    <p>The only valid values for this variable are the two named constants <a class="named_constant" href="#constant_block_type_text">BLOCK_TYPE_TEXT</a> and <a class="named_constant" href="#constant_block_type_list">BLOCK_TYPE_LIST</a>.</p>
+  </li>
+  <li id="variable_version">
+    <div class="variable_title">$this->version</div>
+    <p>This variable should hold each block's version number in the form YYYYMMDDXX, 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's upgrade code to bring the "old" version of the block's data up to date. The variable is expected to have a valid value after the framework calls the <a class="function_title" href="#method_init">init</a> method for each block.</p>
+    <p>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's version number when it gains new functionality or receives important bug fixes, to enable site administrators to easily see if they have the latest version or they need to upgrade.</p>
+  </li>
+  <li id="variable_config">
+    <div class="variable_title">$this->config</div>
+    <p>UNFINISHED!!!</p>
+  </li>
+</ul>
 
+<p>Appearing throughout the code related to the Blocks API, there is a number of predefined constants that are utilized to avoid the use of "magic numbers" in the code. These constants are:</p>
+
+<ul>
+  <li id="constant_block_type_list">
+    <div class="named_constant">BLOCK_TYPE_LIST</div>
+    <p>This variable should be a string that contains the human-readable name of the block. It is used to refer to blocks of that type everywhere, for example in the administrator's block configuration screen. The variable is expected to have a valid value after the framework calls the <a class="function_title" href="#method_init">init</a> method for each block.</p>
+  </li>
+  <li id="constant_block_type_text">
+    <div class="named_constant">BLOCK_TYPE_TEXT</div>
+    <p>This variable should be a string that contains the human-readable name of the block. It is used to refer to blocks of that type everywhere, for example in the administrator's block configuration screen. The variable is expected to have a valid value after the framework calls the <a class="function_title" href="#method_init">init</a> method for each block.</p>
+  </li>
 </ul>
 
 <h2 id="appendix_b">Appendix B: Differences in the Blocks API for Moodle versions prior to 1.5</h2>
@@ -889,13 +961,13 @@ class block_online_users extends block_base { ... }
     }
 </pre>
 
-    <p>Of course, this leaves you without access to the $course object, which you might actually need. Since that's probably going to be needed inside get_content(), the way to retrieve it is by using this code:</p>
+    <p>Of course, this leaves you without access to the $course object, which you might actually need. Since that's probably going to be needed inside <a class="function_title" href="#method_get_content">get_content</a>, the way to retrieve it is by using this code:</p>
 
     <pre class="code">
     $course = get_record('course', 'id', $this->instance->pageid);
 </pre>
 
-    <p>If you are going to need access to $course from inside other methods in addition to get_content(), you might fetch the $course object inside the specialization() method and save it as a class variable for later use, in order to avoid executing the same query multiple times:</p>
+    <p>If you are going to need access to $course from inside other methods in addition to <a class="function_title" href="#method_get_content">get_content</a>, you might fetch the $course object inside the <a class="function_title" href="#method_specialization">specialization</a> method and save it as a class variable for later use, in order to avoid executing the same query multiple times:</p>
 
     <pre class="code">
     function specialization() {