在这个由两部分组成的系列中,我们将了解 WordPress 挂钩系统。具体来说,我们正在仔细研究操作和过滤器以及它们在 WordPress 开发中所起的作用。
尽管它们都被定义为钩子,但每个都在 WordPress 开发中扮演着特定的角色。如果您想成为一名更有成就的 WordPress 开发人员,不仅要了解它们之间的区别,还要了解如何实现自定义钩子。
在该系列的第一篇文章中,我们定义了钩子是什么,了解了它们是如何在其他地方使用的,并且还回顾了包括如何定义我们自己的操作在内的操作。如果您还没有读到第一篇文章,我强烈建议您在继续本教程之前阅读它。
在开始使用钩子之前,我将快速回顾一下上一篇文章中讨论的内容,然后我们将从那里继续前进。
话虽如此,让我们开始吧。
快速刷新
在上一篇文章中,我们看到了钩子是如何实现事件驱动设计模式的。特别是,我们将其定义如下:
- 该软件具有某些点,它会在某些点广播发生某事的消息。
- 作为开发人员,我们能够编写侦听此消息的代码,然后使用自定义代码对其进行响应。
然后在整个内容中,我们准确地回顾了这种模式是如何在 WordPress 中实现的。我们讨论了如何利用它,然后我们讨论了如何实施我们自己的行动。
我们也发现了一个微妙的区别:
操作旨在与功能一起使用,过滤器旨在与数据一起使用。
虽然动作允许我们修改某些行为的方式,但过滤器将允许我们在数据被保存、检索或显示在屏幕上之前对其进行修改。在本教程中,我们将了解如何在将数据写入屏幕之前使用过滤器,例如如何将文本小写并从文本中删除元音。
归根结底,它是关于尝试通过我们正在做的工作获得乐趣并看到切实的成果,同时了解 WordPress 的这一强大方面。
在我们这样做之前,我们需要确保我们已经设置好本地开发环境并准备就绪。
入门
回想一下上一篇文章,我们的本地开发环境应该包括以下内容:
- WordPress 6.0.1
- 您首选的 IDE
- 网络服务器
- PHP的副本
- 一个数据库
对于许多人来说,可以轻松安装 Apache、PHP 和 MySQL。如果您更高级,那么您可能正在使用诸如Nginx和替代数据库之类的东西。如果是这种情况,那很好,但出于本教程的目的,我假设您拥有前者。
如果您没有任何设置,那么不用担心:我们已经为您提供了保障。链接的教程将为您提供在本地计算机上开始使用 WordPress 所需的一切。
设置完成后,我们将准备好继续。
了解 WordPress 过滤器
WordPress Codex 为那些希望了解所有过滤器的人提供了一套全面的资源。正如我们所说,它将过滤器定义如下:
自定义过滤器与自定义操作不同,因为自定义操作允许您在现有操作中添加或删除代码。而自定义过滤器允许您替换在现有操作中找到的特定数据(例如变量)。
但是,如果您正在寻找 WordPress 中可用过滤器的完整列表,请务必在 Codex中引用(并添加书签)此页面。它有大约 20 秒的过滤器,其中许多都链接到他们自己的文档页面。
这意味着如果您对是否存在特定过滤器感到好奇,那么您可以参考此页面。类似地,您可以访问该特定过滤器的页面以获取少量参数参数、示例函数定义以及如何使用它。
关于优先级和参数的一句话
在我们继续之前,我想确保我们在 WordPress 钩子的上下文中讨论它们时所指的优先级和参数数量都在同一页面上。
举个例子,下面这行代码:
1
2
|
<?php
add_filter( ‘author_edit_pre’, ‘filter_function_name’, 10, 2 );
|
这告诉我们四件事:
- 我们要连接的过滤器的名称
- 应该调用的函数的名称
- 何时调用函数的优先级
- 函数应该接受多少个参数
一般来说,前两点很快就明白了;但是,另外两个经常会绊倒新开发人员,但这并不是一个难以理解的概念。
首先,将优先级视为调用函数的时间。请记住,由于给定的钩子可以有多个与之关联的函数,因此优先级允许您定义函数的调用时间或延迟时间。数字越小,触发越早;数字越高,触发越晚。
其次,表示一个参数需要多少个参数的数字。如果您不指定数字,它将接受 none 或任何默认参数。如果您想传递与预期不同的数量,那么您将指定参数应该接受多少个参数。我们将在本教程后面更详细地看到这一点。
使用过滤器
要开始使用过滤器,让我们继续在二二十二目录的根目录中创建我们自己的文件。我们将调用文件tutsplus-filters.php. 然后,在 twentytwo’sfunctions.php中,我们将添加以下代码行:
1
2
|
<?php
include_once( get_template_directory() . ‘/tutsplus-filters.php’ );
|
这将确保我们所有的自定义代码都驻留在一个文件中,当我们不想使用它时可以将其排除。它还将它包含在自己的区域中,这样它就不会与主题中存在的任何代码混在一起。
过滤帖子标题和内容
在我们开始定义我们自己的自定义过滤器之前,了解过滤器的工作原理很重要。由于过滤器是用来修改数据的,而且帖子是博客的组成部分之一,让我们来看看如何在博客帖子的内容显示在屏幕上之前对其进行过滤。
在我们的案例中,博客文章将是一个简单的笑话。您可以通过从 WordPress 管理仪表板导航到“帖子”>“添加新”来创建新帖子。我自己的帖子是这样的:

帖子标题简单地说,“今日笑话”。帖子内容有实际的笑话。我们将对帖子进行两次修改。首先,我们将使用the_content过滤器钩子在笑话的结尾添加一个信用。然后,我们将使用the_title过滤器挂钩将今天的日期附加到标题。
在处理这个示例时,请注意它与我们使用 WordPress 操作的方式相似,但它不是修改行为,而是修改数据。
1. 注册我们的过滤器
要注册我们的过滤器,我们需要两条信息:
- 我们要将函数挂钩的过滤器的名称
- 负责过滤数据的函数
由于我们要修改帖子内容,我们可以利用the_content过滤器。该函数的要点如下:
- 它接受单个参数,即帖子内容,允许我们对其进行修改,然后将其返回给调用者
在这种情况下,WordPress 将帖子内容传递给函数,然后函数将在完成工作后返回数据。
让我们命名我们的自定义函数tutsplus_the_content,然后将其注册到 WordPress。
1
2
3
4
5
6
|
<?php
add_filter( ‘the_content’, ‘tutsplus_the_content’ );
function tutsplus_the_content( $content ) {
return $content;
}
|
在最基本的层面上,这就是函数的样子。当然,作用不大。它只是返回传递给它的内容。
2. 修改内容
让我们让这个函数稍微修改一下数据。具体来说,让我们这样做:
- 确保在单个帖子视图中查看帖子
- 在帖子底部添加一条消息,告诉观众帖子中的笑话来自哪里。
这不是过滤器最实际的用途,但它会让您了解如何修改函数。
这是代码的样子。还要注意代码注释:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
<?php
add_filter( ‘the_content’, ‘tutsplus_the_content’ );
function tutsplus_the_content( $content ) {
// Don’t proceed with this function if we’re not viewing a single post.
if ( ! is_single() ) {
return $content;
}
$credit = <<<SOURCE
<p>
This joke was taken from <a href=”https://www.rd.com/list/short-jokes/” target=”_blank”>rd.com</a>
</p>
SOURCE;
// Now append it to the content.
$content .= $credit;
return $content;
}
|
如果您在索引视图或博客的主视图中查看页面,那么您将看到与未经任何修改的标准帖子完全相同。但是,如果您现在访问该笑话帖子,您会在每个帖子的顶部看到一个新短语。具体来说,您会看到如下内容:

尝试访问其他页面,您会看到信用信息显示在所有帖子的末尾。这可能不是期望的行为
让我们对标题做一些更有针对性的事情。除了在内容底部添加信用信息之外,让我们更新帖子标题以显示今天的日期,然后再将其返回给 WordPress。
为此,我们将使用以下代码:
01
02
03
04
05
06
07
08
09
10
11
12
|
<?php
add_filter( ‘the_title’, ‘tutsplus_the_title’ );
function tutsplus_the_title( $title ) {
// Don’t proceed with this function if we’re not viewing the joke post.
if ( is_single() && get_the_ID() == 60 ) {
return $title.” — “.date(“F j, Y”);
} else {
return $title;
}
}
|
实现该代码,保存它,然后访问您的 WordPress 安装中的任何帖子。您会注意到日期仅附加在笑话帖子的标题上。

如果您想附加日期以及将帖子标题大写怎么办?您可以在以下代码的帮助下做到这一点:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
<?php
add_filter( ‘the_title’, ‘tutsplus_joke_title’, 10, 2);
function tutsplus_joke_title( $title ) {
$post_list = [60, 64];
if (is_single() && in_array(get_the_ID(), $post_list) ) {
$title = strtoupper($title);
return $title.” — “.date(“F j, Y”);
} else {
return $title;
}
}
|
这次我们创建了一个我想为其附加日期的帖子 ID 数组。这可能包括诸如每日行情、每日笑话等内容。代码基本上检查我们是否正在处理单个博客文章,其 ID 是否与我们想要的 ID 匹配。如果是这样,我们将标题大写并附加日期。
定义自定义过滤器
不过,利用预先存在的过滤器很容易。如前所述,调用add_filter,指定过滤器的名称,然后传递我们要调用的函数的名称来过滤数据,这实际上是一件简单的事情。
但是如果我们想创建自己的自定义过滤器怎么办?也许我们想创建一个过滤器,将帖子中的所有文本都小写?或者,也许我们想创建一个过滤器来替换帖子中的一些文本?
对于我们的示例,我创建了一篇关于我假设的加拿大之旅的简单博客文章,如下所示:

理解apply_filters
这是我们开始感兴趣的地方apply_filters。这个特殊的函数是一个接受两个参数的函数:
- 标识过滤器钩子名称的标签
- 引用应用过滤器的值的值
如果你看一个例子,比如说,get_the_content 在 WordPress corethe_content中,那么你会注意到它通过via传递了指定的值apply_filters。
这有助于理解,但是我们如何定义我们自己的自定义过滤器,以便其他人可以调用apply_filters我们开发的功能?
添加我们自己的过滤器
添加我们自己的过滤器很容易。我们需要指定上面列出的相同的四件事:
- 过滤器的名称
- 过滤器应该调用的函数
- 函数的优先级
- 它应该接受的参数数量
让我们从一个简单的例子开始。
小写一切
让我们首先确保整个帖子的内容是小写的。
首先,我们要定义优先级为 10 的过滤器。我们知道它只会接受一个参数,即内容,所以我们将在添加过滤器时传递数字 1:
1
2
|
<?php
add_filter( ‘tutsplus_lowercase_all’, ‘tutsplus_lowercase_all_callback’, 10, 1 );
|
接下来,我们将定义一个简单的函数体,它使用 PHP 的strtolower函数来小写任何传递给它的值,然后我们将返回它。
1
2
3
4
|
<?php
function tutsplus_lowercase_all_callback( $content ) {
return strtolower( $content );
}
|
代码的最终版本将如下所示:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
<?php
add_filter( ‘tutsplus_lowercase_all’, ‘tutsplus_lowercase_all_callback’, 10, 1 );
function tutsplus_lowercase_all_callback( $content ) {
return strtolower( $content );
}
add_filter( ‘the_content’, ‘tutsplus_the_content’ );
function tutsplus_the_content( $content ) {
// Proceed with this function only if we are viewing a particular post.
if ( is_single() && get_the_ID() == 66) {
return apply_filters( ‘tutsplus_lowercase_all’, $content );
} else {
return $content;
}
}
|
我们博客文章中上述过滤器的输出将产生如下内容:

很容易理解,对吧?让我们再看一个替换国家名称的示例。
更换国家
要替换国家,我们可以使用内置str_replace()函数。但是,我们需要更改过滤器注册到 WordPress 的方式,然后我们需要确保注册到 WordPress 的函数正确调用apply_filters.
由于我们已经了解了如何添加我们自己的过滤器、指定优先级、定义它应该接受的参数数量以及实现一个函数,因此我不会在琐碎的细节上浪费时间。
这是过滤器,它被单独调用:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
<?php
add_filter( ‘tutsplus_replace_country’, ‘tutsplus_replace_country_callback’, 10, 1 );
function tutsplus_replace_country_callback( $content ) {
return str_replace( ‘Canada’, ‘U.S.’, $content );
}
add_filter( ‘the_content’, ‘tutsplus_the_content’ );
function tutsplus_the_content( $content ) {
// Proceed with this function only if we are viewing a particular post.
if ( is_single() && get_the_ID() == 66) {
return apply_filters( ‘tutsplus_replace_country’, $content );
} else {
return $content;
}
}
|
带有上述过滤器的输出将如下图所示:

然后这就是您可以从初始挂钩中调用它的方式。
一起召唤他们
最后,可以apply_filters多次调用:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<?php
add_filter( ‘tutsplus_lowercase_all’, ‘tutsplus_lowercase_all_callback’, 10, 1 );
function tutsplus_lowercase_all_callback( $content ) {
return strtolower( $content );
}
add_filter( ‘tutsplus_replace_country’, ‘tutsplus_replace_country_callback’, 10, 1 );
function tutsplus_replace_country_callback( $content ) {
return str_replace( ‘Canada’, ‘U.S.’, $content );
}
add_filter( ‘the_content’, ‘tutsplus_the_content’ );
function tutsplus_the_content( $content ) {
// Proceed with this function only if we are viewing a particular post.
if ( is_single() && get_the_ID() == 66) {
return apply_filters(‘tutsplus_lowercase_all’, apply_filters( ‘tutsplus_replace_country’, $content ));
} else {
return $content;
}
}
|
这是同时应用两个过滤器的最终结果:

请注意,这实现了前面案例的组合结果,但它是通过将它们压缩成一行代码来实现的。还有其他方法可以编写,但本教程的目的是教育您如何编写自己的过滤器以及如何apply_filters在自己的工作中利用。
结论
本教程结束了我们对 WordPress 钩子的介绍。在整个系列中,我们回顾了如何利用现有的操作和过滤器,以及如何创建和实施我们自己的。
钩子系统对于开发人员来说是 WordPress 最强大的方面之一,因此熟悉它很重要。这样做,您不仅可以操作 WordPress 提供的行为和数据,还可以定义自己的钩子,其他开发人员可以在他们自己的代码中使用这些钩子。