Revision as of 23:03, 6 March 2011 by Michalis Kamburelis (talk | contribs) (The correct class name is filter_helloworld, not helloworld_filter)

Jump to: navigation, search

Please note: This page contains information for developers. You may prefer to read the information about filters for teachers and administrators. Once Moodle 2.0 is released, Filters will be renamed to 'Development:Filters 1.9 and before' and this page will be renamed to 'Development:Filters'.

Filters are a way to automatically transform content before it is output. For example

  • render embedded equations to images (the TeX filter)
  • Links to media files can be automatically converted to an embedded applet for playing the media.
  • Mentions of glossary terms can be automatically converted to links.

The possibilities are endless. There are a number of standard filters included with Moodle, or you can create your own. Filters are one of the easiest types of plugin to create. This page explains how.

Two types of filter

Moodle supports two types of filter:

  • Stand-alone filters. These live in a folder inside the 'filter' folder. For example, in 'filter/myfilter'. 'filter/tex' is an example of a core filter of this type.
  • Filters that are part of an activity module. In this case, the filter code lives inside the 'mod/mymod' folder. 'mod/glossary' is an example of a core module with a filter.

The two types of filter work in exactly the same way, and to create one, you put your code in files with the same name, just in different places in the code base.

Creating a basic filter

During this tutorial, we will build a simple example filter. We will make one that adds the word 'hello' before every occurrence of the word 'world'.

1. Since our filter is not part of a module, we should put it inside the 'filter' folder. Therefore, we create a directory called 'filter/helloworld'.

2. Inside that folder, we create a file called 'filter.php'.

3. Inside that PHP file, we define a class called filter_helloworld, that extends the moodle_text_filter class.

class filter_helloworld extends moodle_text_filter {
    // ...

4. Inside that class, we have to define one method, called 'filter'. This takes the HTML to be filtered as an argument. The method should then transform that, and return the processed text. Replace the '// ...' above with

class filter_helloworld extends moodle_text_filter {
    public function filter($text, array $options = array()) {
        return str_replace('world', 'hello world!', $text);

That is basically all there is to it!

Giving your filter a name

To try the new filter, you first have to log in as Administrator and enable it by going to the page Administration ► Plugins ► Filters ► Manage filters.

When you do, you will find that your plugin does not have a name. We missed a step:

5. Inside the 'filter/helloworld' folder, create a folder called 'lang', and in there, create a folder called 'en'.

6. Inside there, create a file called 'filter_helloworld.php'. That is, you have just created the file 'filter/helloworld/lang/en/filter_helloworld.php'.

7. In that file, put

<?php // $Id$
// Language string for filter/helloworld.
$string['filtername'] = 'Hello world!';

That may seem a little involved, just to give your filter a name, but it is just the standard way Moodle stores language strings for plugins.

Trying out your filter

We had just got to the filters administration screen. If you reload that page now, it should now show your filter with its proper name. Turn your filter on now.

Filters are applied to all text that is printed with the output functions format_text(), and, if you have turned on that option, format_string(). So, to see your filter in action, add some content containing the work 'world' somewhere, for example, create a test course, and use the work in the course description. When you look at that course in the course listing, you should see that your filter has transformed it.

Adding a global settings screen

Some filters can benefit from some settings to let the administrator control how they work. Suppose we want to greet something other than 'world'. To add global settings to the filter you need to:

8. Create a file called 'filtersettings.php' inside the 'filter/helloworld' folder.

9. In the 'filtersettings.php' file, put something like:

$settings->add(new admin_setting_configtext('filter_helloworld_word',
        get_string('word', 'filter_helloworld'),
        get_string('configword', 'filter_helloworld'), 'world', PARAM_NOTAG));

10. In the language file 'filter/helloworld/lang/en/filter_helloworld.php' add the necessary strings:

$string['word'] = 'The thing to greet';
$string['configword'] = 'The hello world filter will add the word \'hello\' in front of every occurrence of this word in any content.';

11. Change the filter to use the new setting:

class filter_helloworld extends moodle_text_filter {
    public function filter($text, array $options = array()) {
        global $CFG;
        return str_replace($CFG->filter_helloworld_word,
                "hello $CFG->filter_helloworld_word!", $text);

In standard Moodle, the censor, mediaplugin and tex filters all provide good examples of of how filters use global configuration like this.

A note about performance

One important thing to remember when creating a filter is that the filter will be called to transform every bit of text output using format_text(), and possibly also format_string(). That means that you have to be careful, or you could cause big performance problems. If you have to get data out of the database, try to cache it so that you only do a fixed number of database queries per page load. The Glossary filter is an example of this. (I am not sure how good an example ;-))

Local configuration

In addition, in Moodle 2.0, filters can also have different configuration in each context. For example, the glossary could be changes so that in Forum A, you can choose to only link words from a particular glossary, sat Glossary A, while in Forum B you choose to link words from Glossary B.

To do that sort of thing, you need to add a file called filterlocalsettings.php. In it, you must define a Moodle form that is a subclass of filter_local_settings_form. In addition to the standard formslib methods, you also need to define a save_changes method. There is not a good example of this in the standard Moodle install yet. To continue our example:

12. Create a file called 'filterlocalsettings.php' inside the 'filter/helloworld' folder.

13. In the 'filterlocalsettings.php' file, put:

class helloworld_filter_local_settings_form extends filter_local_settings_form {
    protected function definition_inner($mform) {
        $mform->addElement('text', 'word', get_string('word', 'filter_helloworld'), array('size' => 20));
        $mform->setType('word', PARAM_NOTAGS);

14. Extend the filter to use the new setting, if it is present. The filter must be able to work if the setting is not set, for example by falling back to the global or default setting in this case

class filter_helloworld extends moodle_text_filter {
    public function filter($text, array $options = array()) {
        global $CFG;
        if (isset($this->localconfig['word'])) {
            $word = $this->localconfig['word'];
        } else {
            $word = $CFG->filter_helloworld_word;
        return str_replace($word, "hello $word!", $text);

See also

  • The example filter built here is in contrib CVS at
  • Filters how to write filters for Moodle 1.9 and before. Note that a Moodle 1.9 filter will still work in Moodle 2.0, but you should still update your code when you get the chance.
  • Filters schema - a page containing some ideas and thoughts about modifications to the filters system
  • Filters 2.0 - user documentation about filters.