<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ryankohn</id>
	<title>MoodleDocs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ryankohn"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/Special:Contributions/Ryankohn"/>
	<updated>2026-09-16T01:07:47Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Blocks&amp;diff=2747</id>
		<title>Blocks</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Blocks&amp;diff=2747"/>
		<updated>2009-04-27T17:39:07Z</updated>

		<summary type="html">&lt;p&gt;Ryankohn: changed true/false to TRUE/FALSE, to match coding guidelines (this is the opposite of my previous edit)&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/Appendix_B| Appendix B]]).&lt;br /&gt;
&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. &lt;br /&gt;
&lt;br /&gt;
Experienced developers and those who just want a reference text should refer to [[Blocks/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;
&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. &lt;br /&gt;
&lt;br /&gt;
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;
&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;
&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 &#039;&#039;/blocks/simplehtml/&#039;&#039; and creating a file named &#039;&#039;/blocks/simplehtml/&#039;&#039;&#039;&#039;&#039;block_simplehtml.php&#039;&#039;&#039; which will hold our code. We then begin coding the block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&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;
  // The PHP tag and the curly bracket for the class definition &lt;br /&gt;
  // will only be closed after there is another function added in the next section.&lt;br /&gt;
&amp;lt;/code&amp;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;
&lt;br /&gt;
Our class is then given a small method: [[Blocks/Appendix_A#init.28.29| 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;
&lt;br /&gt;
[[Blocks/Appendix_A#.24this-.3Etitle| $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#Eye_Candy| how to disable the title&#039;s display]].&lt;br /&gt;
&lt;br /&gt;
[[Blocks/Appendix_A#.24this-.3Eversion| $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. &lt;br /&gt;
&lt;br /&gt;
In our example, this is certainly the case so we just set [[Blocks/Appendix_A#.24this-.3Eversion| $this-&amp;gt;version]] to &#039;&#039;&#039;YYYYMMDD00&#039;&#039;&#039; and forget about it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;UPDATING:&#039;&#039;&#039;&amp;lt;br /&amp;gt; &lt;br /&gt;
Prior to version 1.5, the basic structure of each block class was slightly different. Refer to [[Blocks/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;
&lt;br /&gt;
&amp;lt;code php&amp;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;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;
}   // Here&#039;s the closing curly bracket for the class definition&lt;br /&gt;
    // and here&#039;s the closing PHP tag from the section above.&lt;br /&gt;
?&amp;gt;  &amp;lt;/code&amp;gt;&lt;br /&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;
&lt;br /&gt;
First of all, there is a check that returns the current value of [[Blocks/Appendix_A#.24this-.3Econtent| $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;
&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 (Click &amp;quot;Notifications&amp;quot; under the Site Administration Block) and after seeing it in action come back to continue our tutorial.&lt;br /&gt;
&lt;br /&gt;
== Configure That Out ==&lt;br /&gt;
&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;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_config() {&lt;br /&gt;
  return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&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/&#039;&#039;&#039;config_instance.html&#039;&#039;&#039;&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;
 &lt;br /&gt;
&amp;lt;code php&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;
&lt;br /&gt;
&amp;lt;?php use_html_editor(); ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&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 &#039;&#039;&#039;config_instance.html&#039;&#039;&#039; file as instance configuration data. &lt;br /&gt;
&lt;br /&gt;
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;
&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/Appendix_A#init.28.29| init()]].&lt;br /&gt;
&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/Appendix_A| Appendix A]] for more details.&lt;br /&gt;
Having now the ability to refer to this instance configuration data through [[Blocks/Appendix_A#.24this-.3Econfig| $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 &#039;&#039;/blocks/simplehtml/block_simplehtml.php&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;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;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and change it to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&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;Footer here...&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&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;
&lt;br /&gt;
&amp;lt;code php&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;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&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;
[[#top|Back to top of page]]&lt;br /&gt;
&lt;br /&gt;
== The Specialists ==&lt;br /&gt;
&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;
&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;
&lt;br /&gt;
&amp;lt;code php&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;&lt;br /&gt;
    &amp;lt;?php print_string(&#039;configtitle&#039;, &#039;block_simplehtml&#039;); ?&amp;gt;:&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&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;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&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;
&lt;br /&gt;
That&#039;s not too weird, if we think back a bit. Do you remember that [[Blocks/Appendix_A#init.28.29|init()]] method, where we set [[Blocks/Appendix_A#.24this-.3Etitle|$this-&amp;gt;title]]? We didn&#039;t actually change its value from then, and [[Blocks/Appendix_A#.24this-.3Etitle|$this-&amp;gt;title]] is definitely not the same as &#039;&#039;&#039;$this-&amp;gt;config-&amp;gt;title&#039;&#039;&#039; (to Moodle, at least). What we need is a way to update [[Blocks/Appendix_A#.24this-.3Etitle|$this-&amp;gt;title]] with the value in the instance configuration. But as we said a bit earlier, we can use [[Blocks/Appendix_A#.24this-.3Econfig| $this-&amp;gt;config]] in all methods &#039;&#039;except&#039;&#039; [[Blocks/Appendix_A#init.28.29|init()]]! So what can we do?&lt;br /&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;
&amp;lt;code php&amp;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;
  }else{&lt;br /&gt;
    $this-&amp;gt;config-&amp;gt;title = &#039;Some title ...&#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;Some text ...&#039;;&lt;br /&gt;
  }    &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;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/Appendix_A#specialization.28.29| specialization()]] method?&lt;br /&gt;
&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/Appendix_A#init.28.29|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/Appendix_A#specialization.28.29| 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;
&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. &lt;br /&gt;
&lt;br /&gt;
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;
&lt;br /&gt;
This is indeed possible, and the way to do it is to make sure that after the [[Blocks/Appendix_A#get_content.28.29| get_content()]] 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 (&amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt;). Moodle performs this check by calling the block&#039;s [[Blocks/Appendix_A#is_empty.28.29| is_empty()]] method, and if the block is indeed empty then it is not displayed at all.&lt;br /&gt;
&lt;br /&gt;
Note that the exact value of the block&#039;s title and the presence or absence of a [[Blocks/Appendix_A#hide_header.28.29| 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;
&lt;br /&gt;
== We Are Legion ==&lt;br /&gt;
&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;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_multiple() {&lt;br /&gt;
  return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&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;
&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;
&lt;br /&gt;
And finally, a nice detail is that as soon as we defined an [[Blocks/Appendix_A#instance_allow_multiple.28.29| instance_allow_multiple()]] method, the method [[Blocks/Appendix_A#instance_allow_config.28.29| instance_allow_config()]] that was already defined became obsolete. &lt;br /&gt;
&lt;br /&gt;
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/Appendix_A#instance_allow_config.28.29| instance_allow_config()]] method now without harm. We had only needed it when multiple instances of the block were not allowed.&lt;br /&gt;
&lt;br /&gt;
[[#top|Back to top of page]]&lt;br /&gt;
&lt;br /&gt;
== The Effects of Globalization ==&lt;br /&gt;
&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. &lt;br /&gt;
&lt;br /&gt;
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;
&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;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function has_config() {&lt;br /&gt;
  return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&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;
[[Development_talk:Blocks|TODO: New settings.php method]] &lt;br /&gt;
: Just to note that general documentation about admin settings is at [[Admin_settings#Individual_settings]]. In the absence of documentation, you can look at blocks/course_list, blocks/online_users and blocks/rss_client. They all use a settings.php file.--[[User:Tim Hunt|Tim Hunt]] 19:38, 28 January 2009 (CST)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&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)) &lt;br /&gt;
             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;&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;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&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). &lt;br /&gt;
&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;block_simplehtml_strict&amp;quot; clearly satisfies both requirements.&lt;br /&gt;
&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;
&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;
&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;
&lt;br /&gt;
To round our bag of tricks up, notice that the use of &#039;&#039;if(!empty($CFG-&amp;gt;block_simplehtml_strict))&#039;&#039; 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 &#039;&#039;&#039;$CFG-&amp;gt;block_simplehtml_strict&#039;&#039;&#039; 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;
&lt;br /&gt;
=== config_save() ===&lt;br /&gt;
&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/Appendix_A#config_save.28.29| config_save()]], the default implementation of which is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;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;
&amp;lt;/code&amp;gt;&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;
&amp;lt;code php&amp;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;
  }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;
&amp;lt;/code&amp;gt;&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;
&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;
&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;
&lt;br /&gt;
[[#top|Back to top of page]]&lt;br /&gt;
&lt;br /&gt;
=== instance_config_save() ===&lt;br /&gt;
&lt;br /&gt;
Much as we did just before with overriding [[Blocks/Appendix_A#config_save.28.29| config_save()]], what is needed here is overriding the method [[Blocks/Appendix_A#instance_config_save.28.29| instance_config_save()]] which handles the instance configuration. The default implementation is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;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;, &lt;br /&gt;
                   &#039;configdata&#039;,&lt;br /&gt;
                    base64_encode(serialize($data)),&lt;br /&gt;
                   &#039;id&#039;, &lt;br /&gt;
                   $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&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;
&amp;lt;code php&amp;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;
&amp;lt;/code&amp;gt;&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;
&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. &lt;br /&gt;
&lt;br /&gt;
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;
&lt;br /&gt;
=== Exercise === &lt;br /&gt;
We will let this part of the tutorial come to a close with the obligatory exercise for the reader: &lt;br /&gt;
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. &lt;br /&gt;
(Hint: Do that in the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method.)&lt;br /&gt;
&lt;br /&gt;
=== UPDATING: === &lt;br /&gt;
Prior to version 1.5, the file &#039;&#039;config_global.html&#039;&#039; was named simply &#039;&#039;config.html&#039;&#039;. 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;
&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;
&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;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function hide_header() {&lt;br /&gt;
  return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One more note here: we cannot just set an empty title inside the block&#039;s [[Blocks/Appendix_A#init.28.29| init()]] method; it&#039;s necessary for each block to have a unique, non-empty title after [[Blocks/Appendix_A#init.28.29| init()]] is called so that Moodle can use those titles to differentiate between all of the installed blocks.&lt;br /&gt;
&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;
&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;
&amp;lt;code php&amp;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;
&amp;lt;/code&amp;gt;&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;
&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;
&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;
&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;
&amp;lt;code php&amp;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;
&amp;lt;/code&amp;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). &lt;br /&gt;
&lt;br /&gt;
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/Appendix_A#name.28.29| name()]] method to make it dynamically match our block&#039;s name.&lt;br /&gt;
&lt;br /&gt;
== Authorized Personnel Only ==&lt;br /&gt;
&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;
&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;
&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;
&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;
&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;
&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;
&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;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  return array(&#039;site&#039; =&amp;gt; TRUE);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&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;
&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;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  return array(&lt;br /&gt;
           &#039;course-view&#039; =&amp;gt; TRUE, &lt;br /&gt;
    &#039;course-view-social&#039; =&amp;gt; FALSE);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&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;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  return array(&lt;br /&gt;
           &#039;site-index&#039; =&amp;gt; TRUE,&lt;br /&gt;
          &#039;course-view&#039; =&amp;gt; TRUE, &lt;br /&gt;
   &#039;course-view-social&#039; =&amp;gt; FALSE,&lt;br /&gt;
                  &#039;mod&#039; =&amp;gt; TRUE, &lt;br /&gt;
             &#039;mod-quiz&#039; =&amp;gt; FALSE&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&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;
&lt;br /&gt;
&#039;&#039;&#039;UPDATING:&#039;&#039;&#039; &amp;lt;br /&amp;gt;&lt;br /&gt;
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/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;
== Lists and Icons ==&lt;br /&gt;
&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;
&lt;br /&gt;
As we have seen so far, blocks use two properties of [[Blocks/Appendix_A#.24this-.3Econtent| $this-&amp;gt;content]]: &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.&lt;br /&gt;
&lt;br /&gt;
Instead, Moodle expects such blocks to set two other properties when the [[Blocks/Appendix_A#get_content.28.29| 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;
&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;
&amp;lt;code php&amp;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;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to making this change, we must of course also modify the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method to construct the [[Blocks/Appendix_A#.24this-.3Econtent| $this-&amp;gt;content]] variable as discussed above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;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;
&amp;lt;/code&amp;gt;&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/Appendix_A#get_content.28.29| get_content()]] method. Adding the mandatory [[Blocks/Appendix_A#init.28.29| init()]] method as discussed earlier will then give us our first list block in no time!&lt;br /&gt;
&lt;br /&gt;
[[#top|Back to top of page]]&lt;br /&gt;
&lt;br /&gt;
== Appendices ==&lt;br /&gt;
&lt;br /&gt;
The appendices have been moved to separate pages:&lt;br /&gt;
&lt;br /&gt;
* Appendix A: [[Blocks/Appendix A|&#039;&#039;block_base&#039;&#039; Reference]] &lt;br /&gt;
* Appendix B: [[Blocks/Appendix B|Differences in the Blocks API for Moodle Versions prior to 1.5]]&lt;br /&gt;
* Appendix C: [[Blocks/Appendix C|Creating Database Tables for Blocks (prior to 1.7)]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Blocks]]&lt;br /&gt;
[[Category:Tutorial]]&lt;br /&gt;
&lt;br /&gt;
[[es:Desarrollo de bloques]]&lt;/div&gt;</summary>
		<author><name>Ryankohn</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Blocks&amp;diff=2746</id>
		<title>Blocks</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Blocks&amp;diff=2746"/>
		<updated>2009-04-27T17:36:35Z</updated>

		<summary type="html">&lt;p&gt;Ryankohn: changed TRUE to true, to match coding conventions&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/Appendix_B| Appendix B]]).&lt;br /&gt;
&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. &lt;br /&gt;
&lt;br /&gt;
Experienced developers and those who just want a reference text should refer to [[Blocks/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;
&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. &lt;br /&gt;
&lt;br /&gt;
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;
&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;
&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 &#039;&#039;/blocks/simplehtml/&#039;&#039; and creating a file named &#039;&#039;/blocks/simplehtml/&#039;&#039;&#039;&#039;&#039;block_simplehtml.php&#039;&#039;&#039; which will hold our code. We then begin coding the block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&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;
  // The PHP tag and the curly bracket for the class definition &lt;br /&gt;
  // will only be closed after there is another function added in the next section.&lt;br /&gt;
&amp;lt;/code&amp;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;
&lt;br /&gt;
Our class is then given a small method: [[Blocks/Appendix_A#init.28.29| 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;
&lt;br /&gt;
[[Blocks/Appendix_A#.24this-.3Etitle| $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#Eye_Candy| how to disable the title&#039;s display]].&lt;br /&gt;
&lt;br /&gt;
[[Blocks/Appendix_A#.24this-.3Eversion| $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. &lt;br /&gt;
&lt;br /&gt;
In our example, this is certainly the case so we just set [[Blocks/Appendix_A#.24this-.3Eversion| $this-&amp;gt;version]] to &#039;&#039;&#039;YYYYMMDD00&#039;&#039;&#039; and forget about it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;UPDATING:&#039;&#039;&#039;&amp;lt;br /&amp;gt; &lt;br /&gt;
Prior to version 1.5, the basic structure of each block class was slightly different. Refer to [[Blocks/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;
&lt;br /&gt;
&amp;lt;code php&amp;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;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;
}   // Here&#039;s the closing curly bracket for the class definition&lt;br /&gt;
    // and here&#039;s the closing PHP tag from the section above.&lt;br /&gt;
?&amp;gt;  &amp;lt;/code&amp;gt;&lt;br /&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;
&lt;br /&gt;
First of all, there is a check that returns the current value of [[Blocks/Appendix_A#.24this-.3Econtent| $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;
&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 (Click &amp;quot;Notifications&amp;quot; under the Site Administration Block) and after seeing it in action come back to continue our tutorial.&lt;br /&gt;
&lt;br /&gt;
== Configure That Out ==&lt;br /&gt;
&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;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_config() {&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&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/&#039;&#039;&#039;config_instance.html&#039;&#039;&#039;&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;
 &lt;br /&gt;
&amp;lt;code php&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;
&lt;br /&gt;
&amp;lt;?php use_html_editor(); ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&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 &#039;&#039;&#039;config_instance.html&#039;&#039;&#039; file as instance configuration data. &lt;br /&gt;
&lt;br /&gt;
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;
&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/Appendix_A#init.28.29| init()]].&lt;br /&gt;
&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/Appendix_A| Appendix A]] for more details.&lt;br /&gt;
Having now the ability to refer to this instance configuration data through [[Blocks/Appendix_A#.24this-.3Econfig| $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 &#039;&#039;/blocks/simplehtml/block_simplehtml.php&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;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;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and change it to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&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;Footer here...&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&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;
&lt;br /&gt;
&amp;lt;code php&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;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&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;
[[#top|Back to top of page]]&lt;br /&gt;
&lt;br /&gt;
== The Specialists ==&lt;br /&gt;
&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;
&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;
&lt;br /&gt;
&amp;lt;code php&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;&lt;br /&gt;
    &amp;lt;?php print_string(&#039;configtitle&#039;, &#039;block_simplehtml&#039;); ?&amp;gt;:&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&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;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&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;
&lt;br /&gt;
That&#039;s not too weird, if we think back a bit. Do you remember that [[Blocks/Appendix_A#init.28.29|init()]] method, where we set [[Blocks/Appendix_A#.24this-.3Etitle|$this-&amp;gt;title]]? We didn&#039;t actually change its value from then, and [[Blocks/Appendix_A#.24this-.3Etitle|$this-&amp;gt;title]] is definitely not the same as &#039;&#039;&#039;$this-&amp;gt;config-&amp;gt;title&#039;&#039;&#039; (to Moodle, at least). What we need is a way to update [[Blocks/Appendix_A#.24this-.3Etitle|$this-&amp;gt;title]] with the value in the instance configuration. But as we said a bit earlier, we can use [[Blocks/Appendix_A#.24this-.3Econfig| $this-&amp;gt;config]] in all methods &#039;&#039;except&#039;&#039; [[Blocks/Appendix_A#init.28.29|init()]]! So what can we do?&lt;br /&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;
&amp;lt;code php&amp;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;
  }else{&lt;br /&gt;
    $this-&amp;gt;config-&amp;gt;title = &#039;Some title ...&#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;Some text ...&#039;;&lt;br /&gt;
  }    &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;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/Appendix_A#specialization.28.29| specialization()]] method?&lt;br /&gt;
&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/Appendix_A#init.28.29|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/Appendix_A#specialization.28.29| 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;
&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. &lt;br /&gt;
&lt;br /&gt;
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;
&lt;br /&gt;
This is indeed possible, and the way to do it is to make sure that after the [[Blocks/Appendix_A#get_content.28.29| get_content()]] 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 (&amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt;). Moodle performs this check by calling the block&#039;s [[Blocks/Appendix_A#is_empty.28.29| is_empty()]] method, and if the block is indeed empty then it is not displayed at all.&lt;br /&gt;
&lt;br /&gt;
Note that the exact value of the block&#039;s title and the presence or absence of a [[Blocks/Appendix_A#hide_header.28.29| 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;
&lt;br /&gt;
== We Are Legion ==&lt;br /&gt;
&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;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_multiple() {&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&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;
&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;
&lt;br /&gt;
And finally, a nice detail is that as soon as we defined an [[Blocks/Appendix_A#instance_allow_multiple.28.29| instance_allow_multiple()]] method, the method [[Blocks/Appendix_A#instance_allow_config.28.29| instance_allow_config()]] that was already defined became obsolete. &lt;br /&gt;
&lt;br /&gt;
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/Appendix_A#instance_allow_config.28.29| instance_allow_config()]] method now without harm. We had only needed it when multiple instances of the block were not allowed.&lt;br /&gt;
&lt;br /&gt;
[[#top|Back to top of page]]&lt;br /&gt;
&lt;br /&gt;
== The Effects of Globalization ==&lt;br /&gt;
&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. &lt;br /&gt;
&lt;br /&gt;
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;
&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;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function has_config() {&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&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;
[[Development_talk:Blocks|TODO: New settings.php method]] &lt;br /&gt;
: Just to note that general documentation about admin settings is at [[Admin_settings#Individual_settings]]. In the absence of documentation, you can look at blocks/course_list, blocks/online_users and blocks/rss_client. They all use a settings.php file.--[[User:Tim Hunt|Tim Hunt]] 19:38, 28 January 2009 (CST)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&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)) &lt;br /&gt;
             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;&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;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&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). &lt;br /&gt;
&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;block_simplehtml_strict&amp;quot; clearly satisfies both requirements.&lt;br /&gt;
&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;
&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;
&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;
&lt;br /&gt;
To round our bag of tricks up, notice that the use of &#039;&#039;if(!empty($CFG-&amp;gt;block_simplehtml_strict))&#039;&#039; 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 &#039;&#039;&#039;$CFG-&amp;gt;block_simplehtml_strict&#039;&#039;&#039; 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;
&lt;br /&gt;
=== config_save() ===&lt;br /&gt;
&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/Appendix_A#config_save.28.29| config_save()]], the default implementation of which is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;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;
&amp;lt;/code&amp;gt;&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;
&amp;lt;code php&amp;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;
  }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;
&amp;lt;/code&amp;gt;&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;
&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;
&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;
&lt;br /&gt;
[[#top|Back to top of page]]&lt;br /&gt;
&lt;br /&gt;
=== instance_config_save() ===&lt;br /&gt;
&lt;br /&gt;
Much as we did just before with overriding [[Blocks/Appendix_A#config_save.28.29| config_save()]], what is needed here is overriding the method [[Blocks/Appendix_A#instance_config_save.28.29| instance_config_save()]] which handles the instance configuration. The default implementation is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;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;, &lt;br /&gt;
                   &#039;configdata&#039;,&lt;br /&gt;
                    base64_encode(serialize($data)),&lt;br /&gt;
                   &#039;id&#039;, &lt;br /&gt;
                   $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&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;
&amp;lt;code php&amp;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;
&amp;lt;/code&amp;gt;&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;
&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. &lt;br /&gt;
&lt;br /&gt;
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;
&lt;br /&gt;
=== Exercise === &lt;br /&gt;
We will let this part of the tutorial come to a close with the obligatory exercise for the reader: &lt;br /&gt;
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. &lt;br /&gt;
(Hint: Do that in the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method.)&lt;br /&gt;
&lt;br /&gt;
=== UPDATING: === &lt;br /&gt;
Prior to version 1.5, the file &#039;&#039;config_global.html&#039;&#039; was named simply &#039;&#039;config.html&#039;&#039;. 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;
&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;
&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;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function hide_header() {&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One more note here: we cannot just set an empty title inside the block&#039;s [[Blocks/Appendix_A#init.28.29| init()]] method; it&#039;s necessary for each block to have a unique, non-empty title after [[Blocks/Appendix_A#init.28.29| init()]] is called so that Moodle can use those titles to differentiate between all of the installed blocks.&lt;br /&gt;
&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;
&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;
&amp;lt;code php&amp;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;
&amp;lt;/code&amp;gt;&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;
&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;
&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;
&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;
&amp;lt;code php&amp;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;
&amp;lt;/code&amp;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). &lt;br /&gt;
&lt;br /&gt;
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/Appendix_A#name.28.29| name()]] method to make it dynamically match our block&#039;s name.&lt;br /&gt;
&lt;br /&gt;
== Authorized Personnel Only ==&lt;br /&gt;
&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;
&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;
&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;
&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;
&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;
&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;
&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;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  return array(&#039;site&#039; =&amp;gt; true);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&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;
&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;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  return array(&lt;br /&gt;
           &#039;course-view&#039; =&amp;gt; true, &lt;br /&gt;
    &#039;course-view-social&#039; =&amp;gt; false);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&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;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  return array(&lt;br /&gt;
           &#039;site-index&#039; =&amp;gt; true,&lt;br /&gt;
          &#039;course-view&#039; =&amp;gt; true, &lt;br /&gt;
   &#039;course-view-social&#039; =&amp;gt; false,&lt;br /&gt;
                  &#039;mod&#039; =&amp;gt; true, &lt;br /&gt;
             &#039;mod-quiz&#039; =&amp;gt; false&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&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;
&lt;br /&gt;
&#039;&#039;&#039;UPDATING:&#039;&#039;&#039; &amp;lt;br /&amp;gt;&lt;br /&gt;
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/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;
== Lists and Icons ==&lt;br /&gt;
&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;
&lt;br /&gt;
As we have seen so far, blocks use two properties of [[Blocks/Appendix_A#.24this-.3Econtent| $this-&amp;gt;content]]: &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.&lt;br /&gt;
&lt;br /&gt;
Instead, Moodle expects such blocks to set two other properties when the [[Blocks/Appendix_A#get_content.28.29| 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;
&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;
&amp;lt;code php&amp;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;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to making this change, we must of course also modify the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method to construct the [[Blocks/Appendix_A#.24this-.3Econtent| $this-&amp;gt;content]] variable as discussed above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;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;
&amp;lt;/code&amp;gt;&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/Appendix_A#get_content.28.29| get_content()]] method. Adding the mandatory [[Blocks/Appendix_A#init.28.29| init()]] method as discussed earlier will then give us our first list block in no time!&lt;br /&gt;
&lt;br /&gt;
[[#top|Back to top of page]]&lt;br /&gt;
&lt;br /&gt;
== Appendices ==&lt;br /&gt;
&lt;br /&gt;
The appendices have been moved to separate pages:&lt;br /&gt;
&lt;br /&gt;
* Appendix A: [[Blocks/Appendix A|&#039;&#039;block_base&#039;&#039; Reference]] &lt;br /&gt;
* Appendix B: [[Blocks/Appendix B|Differences in the Blocks API for Moodle Versions prior to 1.5]]&lt;br /&gt;
* Appendix C: [[Blocks/Appendix C|Creating Database Tables for Blocks (prior to 1.7)]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Blocks]]&lt;br /&gt;
[[Category:Tutorial]]&lt;br /&gt;
&lt;br /&gt;
[[es:Desarrollo de bloques]]&lt;/div&gt;</summary>
		<author><name>Ryankohn</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Setting_up_Eclipse&amp;diff=4981</id>
		<title>Setting up Eclipse</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Setting_up_Eclipse&amp;diff=4981"/>
		<updated>2009-04-27T02:24:22Z</updated>

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