- Moodle 1.9 Extension Development
- Jonathan Moore Michael Churchward
- 1889字
- 2021-08-06 17:24:07
Building a filter
Now it's time to build our own filter. To begin with, let's come up with a requirement.
Let's assume that our organization, called "Learning is Fun", has a main website at http://2fun2learn.org. Now, we need any instance of the phrase learning is fun to be hyperlinked to the website URL every time it appears on the screen, as in the forum post shown in the following screenshots:


We can do this by implementing a policy with our content creators that forces them to create hyperlink tags around the phrase every time they write it. However, this will be difficult to enforce and will be fraught with errors. Instead, wouldn't it be easier if the system itself could recognize the phrase and create the hyperlink for us?
That's what our filter will do.
Getting started
We need a name for our filter. It is the name that will be used for the directory the filter will reside in. We want a name that will describe what our filter does and will be unlikely to conflict with any other filter name. Let's call it"learningisfunlink".
To start with, create a new subdirectory in the /filter
directory and call it learningisfunlink
. Next, create a new file called filter.php
. This is the only file required for a filter.
Open the new filter.php
file in your development environment. The filter only requires one function, which is named after the filter name and suffixed with _filter
. Add the PHP open and close tags (<?php
and ?>
), and an empty function called learningisfunlink_filter
that takes two arguments: a course ID and the text to filter. When completed, you should have a file that looks like this:
<?php function learningisfunlink_filter($courseid, $text) { return $text; } ?>
We now have the bare minimum required for the filter to be recognized by the system. It doesn't do what we want yet, but it will be present.
Creating the language file
Log in to the site (that makes use of your new filter) as an administrator. On the main page of your site, look for the Modules | Filters folder in the Site Administration block. Click on the Manage filters link. If you have the default filter setup, you will see your new filter near the bottom of the list, called Learningisfunlink, as shown in the following screenshot:

Now, even though the name is reasonably descriptive, it will be better if it were a phrase similar to the others in the list; something like Main website link.
To do this, we need to create a new directory in our /filter/learningisfunlink
directory called lang/en_utf8/
(the en_utf8
is the language specific part—English in this case). In this directory, we create a new file called filter_learningisfunlink.php
. This name is the concatenation of the phrase filter_
and the name of our filter.
In this file, we need to add the following line:
$string['filtername'] = "Main website link";
This language string defines the text that will be displayed as the name of our filter, replacing the phrase Learningisfunlink that we saw earlier with Main website link. This file will contain any other strings that we may output to the screen, specifically for this filter.
Once we have created this file, returning to the Manage filters page should now show our filter with the name that we provided for it in our language file.
Note
At the time of writing, a bug was found to exist within the plugin filter language directories that prevented the language string from being displayed in the filters table. Refer to http://tracker.moodle.org/browse/MDL-17684 for more information. If you really want this to work properly, copy the filter language file into your main language directory and remove the text filter_
from the filename.
Creating the filter code
We now have a filter that is recognized by the system and that displays the name we want it to. However, we haven't made it do anything. Let's create the code to add some functionality.
Remember, what we want this filter to do is to search the text and add a hyperlink pointing to our website for all occurrences of the phrase "learning is fun". We could simply perform a search and replace function on the text and return it, and that would be perfectly valid. However, for the sake of learning more about the Moodle API, we'll use some functions that are set up specifically for filters. To that end, we'll look at two code constructs: the filterobject
class and the filter_phrases
function, both of which are contained in the /lib/filterlib.php
file.
The filterobject
class defines an object that contains all of the information required by the filter_phrases
function to change the text to the way the filter wants it to be. It contains the phrase to be filtered, the tag to start the replacement with, the tag to end the replacement with, whether to match case, whether a full match is required, and any replacement text for the match.
An array of filterobjects
is sent to the filter_phrases
function, along with the text to search in. It's intended to be used when you have a number of phrases and replacements to apply at one time, but we'll use it anyway.
Let's initialize our filter strings:
$searchphrase = "learning is fun"; $starttag = "<a href=\"http://2fun2learn.org\">"; $endtag = "</a>";
Now, let's create our filterobject:
$filterobjects = array(); $filterobjects[] = new filterobject($searchphrase, $starttag, $endtag);
Lastly, let's pass the structure to the filter_phrases
function, along with the text to be filtered:
$text = filter_phrases($text, $filterobjects);
Our function now has the code to change any occurrence of the phrase "learning is fun" to a hyperlinked phrase. Let's go test it.
Activating the filter
In our test course, let's add some text containing the phrase "learning is fun" and see how the filter works. The easiest way to do this is to add a label. Turn on editing in your course and select Insert a label from the Add a resource... drop-down menu. Enter the text Don't you think learning is fun in this course? into the editor box and save the link. Our label should now be displayed with the text that we entered, but our phrase isn't hyperlinked.
The reason that our filter isn't working is that we first need to activate it. Navigate back to the main page of your site, open the Modules | Filters folder in the Site Administration block, and click on the Manage filters link. Look for the row with our filter in it, and click on the closed eye icon in the Disable/Enable column. This will change the icon to an open eye, indicating that our filter is now enabled, as shown in the following screenshot:

Return to the course where we added our label and see if the filter is now working. We should now see our phrase Don't you think learning is fun in this course? with the learning is fun part linked to our site. This is the active filter at work!
Adding configuration settings
Our filter now does what we want it to do. However, what if we want to link a different phrase, or change where the phrase is linked to? We'd need to recode the filter. Instead, let's add some configurable settings.
Navigate back to the Manage filters page via the Site Administration block. Notice that many of the filters have a Settings link in the last column. If you click on any one of the links, you will see a form that lets you enter configuration information for that filter. We need to create one for our filter that lets us specify a phrase to link and the URL to link to.
To create configuration settings for our filter, we need to add a file called filtersettings.php
to our filter directory. Create this file in our /filter/learningisfunlink
directory. Once you have created this file, if you go back to the Manage filters page you will see that our filter now has a Settings link. Moodle has noticed the file and created the link for us. Now we just need to make it do something useful.
Moodle provides a library specifically for these types of settings
files. These functions are contained in a number of class definitions in the /lib/adminlib.php
file. Look through the file to familiarize yourself with what's there.
Our settings
file will be included into a main function. We need to add our options to this function. We do this by adding what we need to a $settings
variable that Moodle has set up for us. This variable is an object of the class admin_settingpage
and is created in the /admin/settings/plugins.php
file, which is the file that includes our settings
file.
We need to add a couple of form text inputs that will allow us to configure our filter. We will do this using the admin_setting_configtext
class. Add the following lines to the filtersettings.php
file:
$settings->add(new admin_setting_configtext('filter_learningisfunlink_phrase', get_string('phrase','filter_learningisfunlink'), get_string('phraseconfig', 'filter_learningisfunlink'), get_string('phrasedefault', 'filter_learningisfunlink'))); $settings->add(new admin_setting_configtext('filter_learningisfunlink_link', get_string('link','filter_learningisfunlink'), get_string('linkconfig', 'filter_learningisfunlink'), get_string('linkdefault', 'filter_learningisfunlink')));
These functions define the text inputs, so that the values will be stored in the specified configuration variables: filter_learningisfunlink_phrase
and filter_learningisfunlink_link
.
We've also used some new language strings here, so add the following lines to the /filter/learningisfunlink/lang/en_utf8/filter_learningisfunlink.php
file:
$string['link'] = "URL"; $string['linkconfig'] = "URL to link phrase to"; $string['linkdefault'] = "http://2fun2learn.org"; $string['phrase'] = "Phrase"; $string['phraseconfig'] = "Phrase to hyperlink"; $string['phrasedefault'] = "learning is fun";
Now, navigate back and look at the settings
file by clicking on the Settings link for our filter on the Manage filters page. You should see a form, as shown in the following screenshot:

That's all we needed to do. We can now change these settings to anything we want, and save them. You can verify this by making changes, saving them, moving away from the page, and then going back to it. The settings should then reflect what you saved.
Using our settings
We have added functionality that allows us to configure our filter with our own phrase and link, but our code still has these settings hardcoded. In order for these to be useful, we need to use them in our code.
Open up our main filter file (/filter/learningisfunlink/filter.php
) and change the first three lines of code to the following:
global $CFG; if (!isset($CFG->filter_learningisfunlink_phrase)) { set_config( 'filter_learningisfunlink_phrase', get_string('phrasedefault', 'filter_learningisfunlink')); } if (!isset($CFG->filter_learningisfunlink_link)) { set_config( 'filter_learningisfunlink_link', get_string('linkdefault', 'filter_learningisfunlink')); } $searchphrase = $CFG->filter_learningisfunlink_phrase; $starttag = "<a href=\"{$CFG->filter_learningisfunlink_link}\">"; $endtag = "</a>";
Our saved settings are now part of Moodle's global $CFG
object variable. The name that we gave them in the settings
file is the property of the $CFG
object that we use. So for our use, we need to look at $CFG->filter_learningisfunlink_phrase
and $CFG->filter_learningisfunlink_link
.
The first two if
structures check to see if we have saved the configuration settings yet. If not, they are saved with the default values stored in our language file. The next two lines use these settings instead of the old hardcoded strings. Our filter should now work with our configured settings.
Try it out! Change the link value and then look at the label that we created in our test course. The link should now be whatever you specified in the settings. Change the phrase to something different, such as "fun in this course". Now look at the label and see which part of the phrase is linked.
You now have a flexible filter that can link any specified text to any specified URL!