Genesis框架从入门到精通(6):过滤器

2019-03-13 10:23:08 浏览数 (1)

原文地址

Genesis Explained Filters

Once again, I encourage anyone joining in the middle of this series to start at the beginning as each article builds on previous information. The tag archive for the Genesis Explained series is con…

Designs By Nick the Geek


译文开始

欢迎阅读本系列教程,如果你是中间开始的,建议从头看起,因为每篇文章都基于之前的内容。Genesis Explained 这个tag可以方便地按顺序查看。本文开始一个新的子系列,重点关注Genesis中的Filters(过滤器)。与关于动作的子系列一样,第一篇旨在解释实际的过滤器函数,因为过滤器函数本身与动作函数并没有明显的不同,本文会将大幅引用什么是动作?里的内容 。

废话完了,让我们开始吧。

什么是过滤器?

过滤器是用来改变其他函数的函数。它们就像“巫毒娃娃”一样对我像是有某种魔力,即使我很清楚的知道它们的工作原理,并且越来越频繁地使用它们。现在我有机会能向 Genesis 团队直接提出一些建议,我发现我还是在建议他们添加更多的过滤器,因为它们通常比动作更高效更方便。

再拿乐高做个类比,如果有一个动作的意图是说:“将这些积木装到这里”,那么过滤器就接话说:“稍等,在执行此操作之前,先把这块换一下,好了,愉快的玩耍吧。”要使用动作进行达到相同的效果的话,你必须提供删除的命令,然后在提供另一条添加的指令,并提供新更改的代码。你会想“我就改了一点东西就能做这么多事?”

我相信你可以看出为什么我说这就像“巫毒娃娃”或作弊了吧。你会觉得这也太简单了吧。当然不会那么简单,内中自由玄机。过滤器只能用来修改已被执行了过滤器的内容。

执行过滤器

许多人常犯的错误是认为可以任何函数都可以被过滤。这是因为常常会有一个与“过滤器的名称”匹配的函数。程序员们这样写就是因为懒,好记而且可以少打字有经验的人会去查看函数来判断他们是否可以使用过滤器,现在你也可以,因为我把这个大秘密暴露出来了。 apply_filters() 函数包括几个重要的部分。

代码语言:javascript复制
apply_filters( $tag, $value, $var1, $var2, ... );

$tag 是过滤器的名称。我们稍后会详细讨论它。$value 是可以被编辑或被替换的值。变量$var1$var2 …可以用于传递一些附加信息,这对于条件语句很有用,比如('blue'== $ var1)为真时返回’color’,或者用 str_replace()进行搜索替换时,还有很多其他有用的用途。但是,你无法直接更改$var的值。

简而言之,如果你想要改变一个函数的值,那么你可以走捷径而不必费事地使用动作。在Genesis框架和WordPress中有大量的过滤器。Genesis也使用了一些WordPress过滤器,所以我们来谈谈怎么使用过滤器。

添加过滤器

add_filter()函数与add_action() 的用法完全,我在之前的教程中已经解释过,如果你没有看过我之前的文章什么是动作,请让我带你快速过一下,详细信息请参阅看看什么是动作这篇文章。首先,要有一条用来添加或删除过滤器的指令,然后要指定一个过滤器的名称。接下来是回调函数,也就是要被修改值的函数,后面是相对于其他过滤器的优先级,是运行过滤器的顺序,以及能接受的参数的数量。

最后一部分需要更多解释,所以让我们看一个一般性的过滤器。

代码语言:javascript复制
add_action( 'hook', 'hook_function' );
/**generic function with a filter*/
function hook_function() {
    echo apply_filters( 'hook_filter', 'foo', 'var 1', 'var 2', 'var 3' );
}

add_filter( 'hook_filter', 'filter_function', 10, 2 );
/**Changes the value of hook_filter if $var1 == 'var 1' */
function filter_function( $value, $var1 ){
    if( 'var 1' == $var1 )
        return 'bar';

    return $value;
}

让我来解释一下你应该已经对动作很熟悉了,这里就是将代码加载到名为“hook”的一个钩子上。它做的是将“foo”打印出来,钩子放在哪里就在哪里打印。但是在打印之前,它可以使用任何过滤器。换句话说,它会查找任何针对这条指令的修改。add_filter这一行就是为其添了一个加过滤器。我已经给它指定了一个需要运行的函数,而且告诉它我只需要2个参数,所以它将使用 $value 和第一个参数 $var。如果我告诉它我需要3个参数,它将使用$value和前两个参数$var1$var2。因此,如果我需要第3个$var,我必须告诉它我想要4个参数,即使我在代码中用不到前两个(有点捆绑销售的意思?),而且它们也必须有值,我想要的那个参数才能被加载进去用以获得我想要的值。

在我的例子中,我让过滤器检查参数$var是否与特定字符串匹配,如果匹配就让它返回一个字符串“bar”,在不同的场景中可能会用到动态匹配。这样,$value的值 foo 就被替换为 bar并打印出来。

这是过滤器和动作函数之间非常重要的区别。过滤器必须要有一个最终值返回出来,而不是打印出来。有些开发者在编写时将用过滤器把内容修改了并把修改过内容打印出来而不是返回出来,这一次次的让我感到恼火。如果没有返回该值,那么其他过滤器都无法使用。那样就是一坨屎样的编程风格,而且很不友好。始终要返回 $value!顺便说一句,最后一行也返回了$value。这样的话,如果值没有被修改就会原样返回。更好的方法是这样写:

代码语言:javascript复制
add_filter( 'hook_filter', 'filter_function', 10, 2 );
/**Changes the value of hook_filter if $var1 == 'var 1' */
function filter_function( $value, $var1 ){
    if( 'var 1' != $var1 )
        return $value;

    return 'bar';
}

这样做更好,因为如果在条件为假的时候修改 $value,很可能会在我不想修改的情况下也会意外返回一个被修改过的值,而上面的这种方式可以在对 $value 进行任何其他操作之前返回。两种方式都可以返回同样的结果,但是在一开始就返回你的 $value是一个好习惯,会更容易让你记住处理完之后要有返回值,因为如果不需要进行处理的话,你已经在一开始就把它返回了。

删除过滤器

remove_filter() 函数与 remove_action() 函数的使用方式相同。它需要完全匹配 add_filter() ,而且并且必须在过滤器添加过之后才可以删除。

如果你觉得是在看天书,那我也同意。接下来的部分,我将使用Genesis中的一些示例来展示如何在不使用动作的情况下进行主题更改,为了好玩,我将首先演示如何使用动作来修改,再演示用过滤器的方式,这样就能看出哪种方式更高效。


Bonus Time

说到 filter 呢,我就想到大学时候最喜欢的一首歌:Filter乐队的 Take a Picture,算了不说了,直接开花吧

0 人点赞