使用钩子

除了知道如何向钩子注册回调函数外,在使用 WordPress 钩子时,你还需要了解一些其他事项。

在本课中,你将学习钩子优先级、钩子参数和钩子顺序。

钩子优先级

我们先从钩子优先级开始。

如果你查看 add_action 的文档,你会看到在钩子名称和回调函数之后,还有两个额外的函数参数。

第三个参数是钩子优先级,它是一个整数,默认值为 10。这意味着如果你在代码中注册一个动作时没有指定优先级,它将以优先级 10 被注册。

add_filter 函数也有一个优先级参数,其工作方式相同。

钩子优先级允许你确定你的钩子回调相对于可能注册在给定钩子上的其他钩子回调(无论是 WordPress 核心、其他主题还是插件)的执行顺序。

钩子按优先级数字顺序执行,从 1 开始。通常将优先级保留为默认值 10 是安全的,除非你特别想改变回调函数的执行顺序。

例如,在动作课程中的 after_setup_theme 示例中,你可能希望确保注册的回调函数仅在 WordPress 核心注册的任何回调之后运行。

因为 WordPress 核心以默认优先级 10 注册所有钩子回调,如果你指定优先级为 11,就可以确保你的回调函数在所有核心回调完成后运行。

add_action( 'after_setup_theme', 'wp_learn_setup_theme', 11 );

或者,如果你想确保回调在 WordPress 核心之前运行,你可以设置一个较低的优先级,比如 9。

add_action( 'after_setup_theme', 'wp_learn_setup_theme', 9 );

你经常会看到回调以高优先级注册,比如 99 或 9999。

add_action( 'after_setup_theme', 'wp_learn_setup_theme', 9999 );

这是因为插件或主题开发者希望确保这个回调在所有其他回调函数之后运行。然而,你永远无法知道其他第三方插件或主题可能以什么优先级注册它们的回调。

钩子参数

现在让我们看看钩子参数。

add_actionadd_filter 函数中的第四个参数是回调函数可以接受的参数数量。

为了更好地理解这是如何工作的,让我们看看一个与内容相关的过滤器钩子 get_the_excerpt

该过滤器定义在 wp-includes/post-template.php 文件的第 436 行。

return apply_filters( 'get_the_excerpt', $post->post_excerpt, $post );

这个过滤器定义在 get_the_excerpt 函数中,而该函数又从 the_excerpt 函数中调用。

这个函数通常用于显示搜索结果时,此时显示文章摘要而不是文章内容很有用。

apply_filters 函数注册了一个过滤器钩子,并带有两个与该过滤器相关的变量:$post_excerpt 字符串变量和 $post 对象。

在定义动作或过滤器钩子时,可以添加任意数量的可能参数。然而,传递给接受参数参数的数字决定了其中有多少个被传递给钩子回调函数。

如果你查看 add_filter 的文档,你会看到接受参数数量的默认值是 1,这意味着如果你不为此参数指定值,第一个参数将可用于传递给回调函数。

get_the_excerpt 过滤器中,有两个可能的变量可以被接受。

如果你在不设置参数数量的情况下注册回调,那么只有第一个参数(在本例中是 post_excerpt)会在回调函数中可用。

add_filter( 'get_the_excerpt', 'wp_learn_amend_the_excerpt', 10 );
function wp_learn_amend_the_excerpt( $post_excerpt ) {
    // 对 $post_excerpt 进行处理
}

为了接受更多可用的参数,你需要指定要接受的参数数量。

add_filter( 'get_the_excerpt', 'wp_learn_amend_the_excerpt', 10, 2 );

然后你可以在回调函数中使用这些参数。

function wp_learn_amend_the_excerpt( $post_excerpt, $post ) {

}

能够确定回调函数需要哪些参数,并在注册钩子时正确设置参数数量,是一项非常有价值的技能。

例如,假设你只想在摘要后面添加一段简单的文字。在这种情况下,你只需要 $post_excerpt 参数,因此可以省略接受参数的设置。

add_filter( 'get_the_excerpt', 'wp_learn_amend_the_excerpt', 11 );
function wp_learn_amend_the_excerpt( $post_excerpt ) {
    $additional_content = '<p>由搜索引擎验证</p>';
    $post_excerpt       = $post_excerpt . $additional_content;

    return $post_excerpt;
}

注意,优先级也做了调整。这样做是为了确保这段文字在核心过滤器回调函数(已分配给该过滤器)执行完毕后再被添加。

让我们在搜索结果中看看效果。

但是,如果你想包含文章中的某些内容,比如文章标题,该怎么办呢?

在这种情况下,你需要更新回调函数,使其接受钩子中的两个参数,以便从 $post 对象中获取文章标题。

add_filter( 'get_the_excerpt', 'wp_learn_amend_the_excerpt', 11, 2 );
function wp_learn_amend_the_excerpt( $post_excerpt, $post ) {
    $additional_content = '<p>'. $post->post_title . ' 由搜索引擎验证</p>';
    $post_excerpt       = $post_excerpt . $additional_content;

    return $post_excerpt;
}

让我们看看更新后的搜索结果是什么样子。

你会注意到,这段代码对传递给回调函数的参数使用了相同的变量名,即 $post_excerpt$post

这并不是强制要求,在注册回调函数时,你可以为它们任意命名。但使用相同的名称有助于记住每个变量的用途。

钩子顺序

根据你的具体需求,你可能首先需要确定使用哪个操作或过滤器是正确的。

幸运的是,WordPress 开发者文档中有一个“常见 API”部分的钩子页面,其中列出了所有操作和过滤器钩子,并按照它们在 WordPress 站点不同请求中的执行顺序排列。

你可以使用这个列表来检查你想使用的钩子何时执行,然后根据这些信息判断它是否满足你的需求。