Drupal专业开发指南 第11章 Drupal过滤器系统(filter)(2)创建一个定制的过滤器

创建一个定制的过滤器

译者:老葛       Eskalate科技公司

当然,Drupal过滤器可以添加超链接,格式化你的内容,将文本转化为空中的pirate-speak,但是它能够聪明的帮我们写日志么,或者至少能够帮我们把我们创造性的火花碰撞出来么?当然,它也可以做到这一点!让我们创建一个带有过滤器的模块,用来向日志中插入随机的句子。我们将启用这一模块,这样当你在编写文章毫无灵感需要一些火花时,你可以简单的键入[juice!],当你保存文章时,它将会被替换为一个随机生成的句子。如果你需要更多的智慧火花时,你可以在一个页面中多次插入[juice!]标签。

 

sites/all/modules/custom/下面创建一个名为creativejuice的文件夹。首先,向creativejuice文件夹下面添加creativejuice.info文件:

 

; $Id$

name = Creative Juice

description = Adds a random sentence filter to content.

version = $Name$

 

接着,创建creativejuice.module文件并也将其添加到creativejuice文件夹下:

<?php

// $Id$

/**

* @file

* A silly module to assist whizbang novelists who are in a rut by providing a

* random sentence generator for their posts.

*/

 

hook_filter()

现在我们已经为创建模块做好了铺垫,让我们在creativejuice.module中添加hook_filter()的实现:

/**

* Implementation of hook_filter().

*/

function creativejuice_filter($op, $delta = 0, $format = -1, $text = '') {

switch ($op) {

case 'list':

return array(0 => t('Creative Juices filter'));

case 'description':

return t('Enables users to insert random sentences into their posts.');

case 'settings':

// No settings user interface for this filter.

break;

case 'no cache':

return FALSE;

case 'prepare':

return $text;

case 'process':

return preg_replace_callback("|/[juice!/]|i",

'creativejuice_sentence', $text);

default:

return $text;

}

}

 

过滤器API将穿过多个阶段,从收集过滤器的名称,到缓存,再到进行真实操作的处理阶段。通过检查creativejuice_filter(),让我们看一下这些阶段或者操作。下面是对这个钩子函数中的参数的分解:

 

$op:要进行的操作。在接下来的部分我们将详细的讨论它。

$delta: hook_filter()中可实现多个过滤器。你可以使用它来追踪当前执行的过滤器的ID。$delta是一个整数。

$format:一个整数,表示使用的哪一个输入格式。

$text:将被过滤的内容。

根据$op参数的不同,可进行不同的操作。

 

列表操作(The list $op)

列表操作(list)返回的是一个关联数组,其中以数字为键以过滤器名称为值,这是由于单个hook_filter()钩子实例中可以声明多个过滤器的缘故。这些键可在接下来的操作中使用,我们使用$delta参数来将它们传递给钩子。

case 'list':

return array(

0 => t('Creative Juices filter'),

1 => t('The name of my second filter'),

);

描述操作(The description $op)

 

该操作返回了一个关于过滤器能做什么的简单描述。只有具有管理过滤器权限的用户才可看到这些描述。

case 'description':

switch ($delta) {

case 0:

return t('Enables users to insert random sentences into their posts.');

case 1:

return t('If this module provided a second filter, the description

for that second filter would go here.');

// Should never reach here as value of $delta never exceeds

// the last index of the 'list' array.

default:

return;

}

设置操作(The settings $op)

当过滤器需要一个用于配置的表单接口时,使用该操作。它返回用于控制的HTML表单,当表单提交时,将会使用variable_set()自动的将数据保存起来。这意味在取回数据时使用variable_get()。使用该操作的实例,可参看modules/filter/filter.module中的filter_filter()。

 

禁用缓存操作(The no cache $op)

 

过滤器系统应该绕过对已过滤文本进行缓存操作么?如果要禁用缓存,那么返回的代码应该为TRUE。当你开发过滤器时,你需要禁用缓存,这样调试起来就会很容易。如果你修改禁用缓存操作所返回的布尔值,在生效以前你需要对使用到了你的过滤器的输入格式进行编辑。

 

警告 禁用单个过滤器的缓存,会把任何使用了该过滤器的输入格式的缓存清空。

 

 

准备操作(The prepare $op)

对内容的实际过滤流程包含两步。首先,允许过滤器准备用于处理的文本。该步的主要目的是将HTML转化为相应的实体。例如,有这样一个过滤器,它可让用户粘贴代码片段。在准备阶段会将代码转化为HTML实体,这样就可以阻止接下来的过滤器对这些进行操作了。例如,如果没有这一步的话,HTML过滤器将会清除掉里面的所有HTML标签。下面是codefilter.module中使用准备阶段的例子,该模块用于处理<code></code> <?php ?> 标签,从而允许用户发布代码而不用担心过滤它内部的HTML实体:

case 'prepare':

// Note: we use the bytes 0xFE and 0xFF to replace < > during the

// filtering process.

// These bytes are not valid in UTF-8 data and thus least likely to

// cause problems.

$text = preg_replace('@<code>(.+?)</code>@se', "'/xFEcode/xFF'.

codefilter_escape('//1') .'/xFE/code/xFF'", $text);

$text = preg_replace('@[/[<](/?php|%)(.+?)(/?|%)[/]>]@se',

"'/xFEphp/xFF'. codefilter_escape('//2') .'/xFE/php/xFF'", $text);

return $text;

 

处理操作(The process $op)

从准备操作阶段里面返回的结果将被传递到hook_filter()中来。在这里进行实际的本文处理:为URL添加超链接,删除恶意数据,添加单词定义,等等。在准备操作和处理操作阶段返回的都应该为$text

 

默认操作(The default $op)

包含默认操作情况非常重要。如果你的模块没有实现一些操作时,将调用该操作,要保证在这里返回的是$text(你的模块要过滤的文本)。

 

助手函数

$op 为“process”时,每次遇到[juice!]标签你都要执行一个名为creativejuice_sentence()的助手函数。将该函数也添加到creativejuice.module中。

/**

* Generate a random sentence.

*/

function creativejuice_sentence() {

$phrase[0][] = t('A majority of us believe');

$phrase[0][] = t('Generally speaking,');

$phrase[0][] = t('As times carry on');

$phrase[0][] = t('Barren in intellect,');

$phrase[0][] = t('Deficient in insight,');

$phrase[0][] = t('As blazing blue sky poured down torrents of light,');

$phrase[0][] = t('Aloof from the motley throng,');

$phrase[1][] = t('life flowed in its accustomed stream');

$phrase[1][] = t('he ransacked the vocabulary');

$phrase[1][] = t('the grimaces and caperings of buffoonery');

$phrase[1][] = t('the mind freezes at the thought');

$phrase[1][] = t('she reverted to another matter');

$phrase[1][] = t('he lived as modestly as a hermit');

$phrase[2][] = t('through the red tape of officialdom.');

$phrase[2][] = t('as it set anew in some fresh and appealing form.');

$phrase[2][] = t('supported by evidence.');

$phrase[2][] = t('as fatal as the fang of the most venomous snake.');

$phrase[2][] = t('as full of spirit as a gray squirrel.');

$phrase[2][] = t('as dumb as a fish.');

$phrase[2][] = t('like a damp-handed auctioneer.');

$phrase[2][] = t('like a bald ferret.');

foreach ($phrase as $key => $value) {

$rand_key = array_rand($phrase[$key]);

$sentence[] = $phrase[$key][$rand_key];

}

return implode(' ', $sentence);

}

 

hook_filter_tips()

你使用creativejuice_filter_tips()来向终端用户显示帮助信息。默认情况下,展示一个短的消息并带有一个指向http://example.com/?q=filter/tips的链接,链接页面包含了所有过滤器的详细说明。

/**

* Implementation of hook_filter_tips().

*/

function creativejuice_filter_tips($delta, $format, $long = FALSE) {

return t('Insert a random sentence into your post with the [juice!] tag.');

}

在前面的代码中,无论是简洁的帮助文本还是详细的帮助文本,都是用相同的文本信息,如果你想返回一个更详细的解释信息时,你需要使用$long进行切换,如下所示:

/**

* Implementation of hook_filter_tips().

*/

function creativejuice_filter_tips($delta, $format, $long = FALSE) {

if ($long) {

// Detailed explanation for example.com/?q=filter/tips page.

return t('The Creative Juices filter is for those times when your

brain is incapable of being creative. These time comes for everyone,

when even strong coffee and a barrel of jelly beans does not

create the desired effect. When that happens, you can simply enter

the [juice!] tag into your posts...'

);

}

else {

// Short explanation for underneath a post's textarea.

return t('Insert a random sentence into your post with the [juice!] tag.');

}

}

 

 

一旦在模块列表页面启用了这个模块,那么就可以使用 creativejuice过滤器了,你可以将它用在一个已存在的输入格式中,也可以用到新建的输入格式中。你可以使用合适的输入格式创建一个日志,然后提交包含[juice!]标签的文本:

 

Today was a crazy day. [juice!] Even if that sounds a little odd,

it still doesn't beat what I heard on the radio. [juice!]

 

提交的内容将会转化为如下所示的内容:

Today was a crazy day! Generally speaking, life flowed in its accustomed stream

through the red tape of officialdom. Even if that sounds a little odd, it still

doesn't beat what I heard on the radio. Barren in intellect, she reverted to another

matter like a damp-handed auctioneer.

 

 

防止恶意数据

如果你想防止恶意HTML,可以使用Filtered HTML过滤器对内容进行过滤,从而阻止XSS攻击。如果在一些情况下,你不能使用Filtered HTML过滤器时,你可以使用下面的方式手工的过滤XSS:

function mymodule_filter($op, $delta = 0, $format = -1, $text = '') {

switch ($op) {

case 'process':

// Decide which tags are allowed.

$allowed_tags = '<a> <em> <strong> <cite> <code> <ul> <ol> <li>';

return filter_xss($text, $allowed_tags);

default:

return $text;

break;

}

}

总结

读完本章后,你应该可以:

• 理解什么是过滤器,什么是输入格式,以及如何使用它们转化文本

• 理解为什么过滤器系统比使用其它钩子直接操纵文本更加有效

• 理解输入格式和过滤器的工作原理

• 创建一个定制的过滤器

• 理解过滤器中的各种操作函数

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值