WordPress 钩子指南

已发表: 2021-07-19

钩子系统对于初学者来说似乎令人生畏,但它们是 WordPress 最好的东西之一。 本指南将帮助您了解钩子的基础知识以及如何使用它们,提供示例用法和进一步的建议。

为什么要使用钩子?

如果您还没有意识到,更改 WordPress (WP) 中的核心文件是一个非常糟糕的主意。 抛开安全风险不谈,每次更新 WP 时,您的更改都会被覆盖! 插件和主题也是如此。

当然,您可以跟踪每个更新并重新实施您的更改。 可以穿过蜂箱来取蜂蜜。 这看起来很方便,但你迟早会被蜇到。

简而言之,您应该使用钩子,因为它们抵消了更改核心功能的风险

从这个意义上说,钩子的重要性怎么强调都不为过 它们是 WP 可扩展性的关键,也是其插件和主题生态系统的基石。 通过学习基础知识并很好地利用它们,您将为自己省去很多麻烦。

这些是什么?

您可以将钩子视为在整个 WP 加载序列中发生的事件 当 WP 遇到一个钩子时,它会在继续之前触发所有附加到该钩子的函数。

因此,您可以利用钩子在 WP 中添加功能或更改变量 您可以使用现有的钩子并添加新的钩子。 您可以移除不需要的挂钩。 您可以多次击中同一个钩子,按您认为合适的方式对每个功能进行优先级排序。 这是一个非常灵活的系统,仅受可用的钩子和它们公开的数据的限制。

它们是如何工作的?

您向钩子添加一个或多个函数。 其他功能也可能由您的主题、插件或 WP 本身添加。 当 WP 加载时,它会遇到钩子。 它检查与钩子关联的所有函数的列表。 WP按优先顺序运行所有这些功能 完成后,它会在钩子之后继续加载所有内容。

他们看起来怎么样?

向钩子添加函数如下所示:

add_action( $hook_name, $function_name, $priority, $arguments );

$hook_name是您要定位的钩子的名称

$function_name是要添加到该钩子的函数的名称

$priority是一个整数,表示$function_name$hook_name的队列中的优先级 数字越小,优先级越高。 从 1 开始,此数字可以随您的需要而增加(在系统限制内),但您不太可能看到它高于 40。默认值为 10。

$arguments是一个整数,表示您在函数中使用的参数数量。 必须与传递给函数的参数数量相匹配。 默认值为 1。

从钩子中删除一个函数几乎是一样的:

remove_action( $hook_name, $function_name, $priority );

$函数名$必须优先原始值从相应的ADD_ACTION功能匹配,否则将不会被删除!

钩子的种类

有两种主要类型的钩子:动作钩子和过滤器钩子。 它们在很多方面都很相似—— add_action()和它的对应物add_filter()都以相同的方式调用。 不同之处在于您传递的函数:


// 运行一些代码
add_action('where_to_do_the_thing', 'do_the_thing');
函数 do_the_thing() {
// 执行某些操作所需的操作
}

// 改变一个变量
add_filter('the_thing', 'change_the_thing');
函数 change_the_thing( $thing ) {
// 过滤 $thing 并更改为您需要的任何内容,然后...

返回 $thing;
}

注意,在第二示例中,第一个参数传递给函数的n为被修正的值。 任何附加参数仅用于实用程序,不会通过钩子传回。

您可能已经注意到我省略了$priority$arguments 这是因为默认值很好。 如果有帮助,上面的内容与以下内容基本相同:


// 运行一些代码
add_action( 'where_to_do_the_thing', 'do_the_thing', 10, 1 );
// 改变一个变量
add_filter( 'the_thing', 'change_the_thing', 10, 1 );

这些当然是人为的例子,但它们说明了两者之间的主要区别:过滤器用于更改变量,操作用于添加代码。

不那么做作的例子

假设您想让 WP 在新用户在您的网站上注册时发送电子邮件通知。 参考 WP codex,您可以找到user_register操作挂钩。 这为您提供了一个$user_id变量,您可以使用它来获取用户的详细信息。 wp_mail()处理其余的:


add_action('user_register', 'notify_on_user_registration');
函数 notify_on_user_registration( $user_id ) {

// 获取用户
$user = get_user_by('id', $user_id);

// 准备邮件主题和正文
$subject = “新用户注册”;
$message = “一个新用户 {$user->first_name} {$user->last_name} 已经注册。”;

// 发送电子邮件
wp_mail('[email protected]', $subject, $message );
}

如果您想在登录时将用户重定向到您的首页怎么办? 您可以使用login_redirect钩子轻松实现这一点,该钩子提供默认情况下用户重定向到的 URL:


add_filter('login_redirect', 'redirect_user_on_login');
函数redirect_user_on_login( $redirect_to ) {
返回 home_url();
}

添加此内容后不久,您很快就会意识到,作为管理员,您希望直接进入 WP 仪表板而不是主页。 没问题——您只需修改钩子,使其仅适用于管理员:


add_filter( 'login_redirect', 'redirect_user_on_login', 10, 3 );
函数redirect_user_on_login( $redirect_to, $request, $user ) {
// 除非用户是管理员,否则更改登录 URL
if ( isset( $user->roles ) && is_array( $user->roles ) ) {
if ( in_array( '管理员', $user->roles ) ) {
返回 $redirect_to; // 将管理员重定向到默认(管理区域)
}
}

返回 $redirect_to;
}

请注意, $priority$arguments开始发挥作用了!

由于需要访问钩子的第三个参数来检查用户的级别,所以需要显示3个参数; 你传递了一个 3 的值。

当然, $priority值 10 与默认值相同,但指定它是为了达到您上面需要$arguments值。

创建自己的钩子

创建自定义挂钩的能力在您的手中! WP 提供的功能如下所示:

do_action( $hook_name, $arg_1, $arg_2 ... $arg_n );

apply_filters( $hook_name, $arg_1, $arg_2 ... $arg_n );

再说一次,它们有点相似。 这两个函数都接受一个名称——这是你命名钩子的地方。 以下所有参数都是可用于添加到该钩子的函数的相同参数。 apply_filters()必须至少有一个附加参数(被过滤的参数),但所有其他参数都是可选的。

例如,如果你想在打开 body 标签之前注入一个分析脚本,但又不想把header.php弄得一团糟:


<?php do_action( 'before_body_tag' ); ?;>
</头>
<身体>

然后,您可以根据需要添加任意数量的脚本:


add_action('before_body_tag', 'add_analytics_custom');
函数 add_analytics_custom() {
// <script> 标签和分析代码放在这里
}

apply_filters() 的工作方式略有不同。 如上所述,过滤器用于修改值。 由于过滤器返回一个值,您将apply_filters()调用分配给一个变量:


<?php $text = apply_filters( 'call_to_action_text', '关于我们' ); ?>
<a href="<?php echo get_permalink('about'); ?>” class="button cta">
<?php echo $text; ?>
</a>

// 或者,您可以直接回显 apply_filters() 的结果
<a href="<?php echo get_permalink('about'); ?>” class="button cta">
<?php echo apply_filters('call_to_action_text', '关于我们'); ?>
</a>

然后您可以根据需要修改过滤后的变量:


add_filter('call_to_action_text', 'change_call_to_action_text');
函数 change_call_to_action_text( $text ) {
如果(is_front_page()){
$text = '发现更多';
}

返回 $text;
}

缺点

没有系统是完美的,钩子也不例外。 当涉及到核心钩子时,您通常必须使用所提供的东西。 偶尔你会遇到钩子不在你最方便的地方的情况。 发生这种情况时无能为力,因此请将其视为寻找创造性解决方案的机会!

此外,由于挂钩可以存在于 WP 目录结构中的任何位置,因此有时很难找到某些逻辑发生的位置。 这可以通过将函数挂钩分离到它们自己的文件中来抵消。

进一步建议

  • 为钩子创建函数时,请确保名称唯一,否则会发生冲突。 您的自定义钩子和过滤器名称也是如此!
  • 使用钩子保持模板整洁。 在整个模板中插入一些通用的do_action()挂钩可以帮助使逻辑远离标记(几乎总是一个好主意)。
  • 当你安装一个新插件时,检查它提供了哪些钩子并考虑如何使用它们。 这对于插件无法完全按照您的要求执行的不可避免的时间特别有用
  • 添加操作或过滤器时,您可以将函数名称替换为函数本身。 这有助于保持操作和过滤器自包含。 不能使用remove_action()remove_filter()删除以这种方式添加的函数,所以要小心!

add_action('where_to_do_the_thing', function() {
echo '事情完成了。';
}, 10, 1 );
  • 查看其他可用的钩子相关函数,例如did_action()has_action() 你永远不知道什么时候意识到它们会有用。

概括

使用钩子是一个习惯问题。 每当您处理 WP 项目时,尝试问自己两个简单的问题:

  1. “有没有钩子可以让我更轻松?”
  2. “我可以添加一个钩子,让未来的我更容易吗?”

一旦您以这种态度接近 WP 开发,您会发现许多大门打开了。

本指南中的示例只是冰山一角。 仅 WP 核心就有数百个钩子,更不用说庞大的插件和主题库了。 查看 WP操作参考过滤器参考以获取核心 WP 挂钩的完整列表。


如果您在 Web 开发方面需要帮助,请随时与我们联系。