Drupal Input Filters Part 2: The Content Switch-a-roo

Where were we?

Ok, last time we looked at the ideas behind Input Filters in Drupal, so we covered Input Formats, how to configure them and what they can do for you. Now we get the real good stuff; how to make one.

Outline

Before we go any further, we need a reason to make an input filter. Do you play Xbox? I do. Wouldn't it be great if we could somehow allow members of our site to display their gamertag? Well, with Input Filters, you can.

Get your Coding Hat On

Open up your favorite text editor (mine is TextWrangler), and we'll create the .info file. The basic info file tells Drupal about your module. It gives it the name, the package it is part of, and many other things such as module dependencies. Ours is going to be very simple, just the name, a basic description, the required version of the Drupal Core, and a package.

name = Xbox Gamertag
description = Add your xbox Gamertag to your site
core = 6.x
package = cool modules

Save this in directory called 'xbox' under sites/all/modules/custom/xbox, and call it xbox.info.

Once this is done, you are ready to start the module proper.

The Main Event

The first function to define is the implementation of hook_filter. This hook defines the filter, and exposes it to Drupal for application in an Input Format.

It's a pretty simple hook, all it needs is a switch statement that switches on the value of the operation being performed. Before we create the code, lets talk about the different operators involved in this hook.

List

The list operation simply reveals your filter to the list of available filters for each Input Format. It is an array containing all the filters defined in this module (yes, you can define more than one).

Description

Gives a brief description to accompany the title in the list operation.

Settings

This stores the HTML Form for defining an administrative interface to control your Filter. We don't need it here, but it can be very useful to define extra settings. The values are stored in the Drupal Variables table, so the usual variable_set and variable_get rules apply.

No Cache

Is it OK to cache the output of this filter? If yes, this imply returns FALSE. This allows the input to be stored in the cache_filter table (more on caching in future articles). If you need the filter to be applied on every page load, return TRUE here, so the Input Format knows to run your filter on every request (remember, on a production server this may not be advisable).

Prepare

This operation is called before the actual work is dealt with, so you can use it to set up any variables needed here first

Process

The actual work is done here.

The default case simply returns the text.

Enough Talk.

Lets se the code, right? OK. Here is its.

  1.  
  2. function xbox_filter($op, $delta = 0, $format = -1, $text = ''){
  3. switch($op){
  4.                 case 'list':
  5.                         return array(
  6.                                 0 => t('Xbox Gamertag')
  7.                         );     
  8.                 case 'description':
  9.                         return t('Enables users to add your Xbox gamertag to any node by adding [xbox].');
  10.                 case 'settings':
  11.                         // No settings interface for this filter
  12.                         break;
  13.                 case 'no cache':
  14.                         // It's OK to cache this filter's output
  15.                         return FALSE;
  16.                 case 'prepare':
  17.                         // No preparation yet
  18.                         return $text;
  19.                 case 'process':
  20.                         return preg_replace_callback("|\[xbox\](.*)\[\/xbox\]|i",
  21.                         'xbox_expand', $text);
  22.                 default:
  23.                         return $text;
  24.         }
  25.  }

I thought you said three lines?

I know, I slightly exaggerated when I said three lines, but what I meant was that the process case was one line, and the callback function defined in the preg_callback is only another one line. So I was kinda telling the truth.

Preg...whaaaaa?

Before we get to the callback function, we better explain what on earth is going on in the process section of the above code.

We call the PHP function preg_replace_callback(); The arguments are the regular expression to find in the filtered text, the function to call, and the text to find the regular expression in. Now, this isn't a regular expression tutorial, but I will briefly explain what this does.

  1. \[xbox\] - this looks for the [xbox] tag in the text to begin the substitution. The backslashes are escape characters, meaning it is literally looking for the [ character.
  2. (.*) - This means 'find zero or more of any character'. The dot means 'any character', the asterisk means 'zero or more'. The round brackets mean 'group the matched elements'.
  3. \[\/xbox\] - This should be familiar by now, it is simply looking for the close of the [xbox] tag.

The matches that are found are passed into the callback function, so we can begin examining the callback.

The Callback

This function very simple; all it does is cleans up the input, and returns a string with the xbox gamertag in it, to replace the [xbox] tag.

  1. return '<iframe src="http://gamercard.xbox.com/'.$tag.'.card" scrolling="no" frameBorder="0" height="70" width="102">'.$tag.'</iframe>';

You don't need to worry about most of this code, all that's important is that the $tag variable comes from the array passed in to this function.

To sum Up

There you have it. That's all you need to get a basic input filter written. It would help to implement a few other hooks, for example I have implemented, hook_filter_tips, hook_help and hook_perm to make this a fully fledged module.

Taking It Further

You can take this further, for example, you can define the callback as an anonymous function, which as the PHP Site says 'doesn't clutter the namespace with one-time functions'. Also, you could add extra elements like a settings form and prepare routines. Please comment if you have taken this further.

You can download the final module here.

Anonymous
Thanks for the module. kate, Web Design Company
Submitted by Anonymous on Fri, 08/21/2009 - 11:11.
lev
No worries, hope you find it useful!
Submitted by lev on Fri, 08/21/2009 - 15:19.

Post new comment

The content of this field is kept private and will not be shown publicly.
CAPTCHA
Are you human? Prove it by typing in the two words below.
Top