WordPress钩子Hook的简要说明

最近在给主题添加评论 VIP 等级和评论者 UA 及地理位置的显示的时候,没办法像之前那样无脑拷贝粘贴别人的代码。其中本站摸索使用了插件机制来实现需要的功能。实际上也就是通常说的 Hook 了,即通俗讲就是钩子。

Wordpress 分为两种钩子,一个称为动作(action),一个称为过滤器(filter)。动作的理念是让你在一种情况或者一个特别的位置执行一些特定函数,比如发送一封邮件等;过滤器则是允许你修改 WordPress 核心需要用到的一个值,然后 WordPress 再用这些值做一些事情,比如函数的返回值等。

动作钩子

wp_head()函数就有一个很典型的 Hook 动作,大部分主题的 head 标签中都加入此函数。其中的钩子为:wp_head。插件和WordPress核心都通过给 wp_head 添加钩子函数来向网站的 head 标签中加入内容。例:

function my_wp_head() {
    echo '<meta name="keywords" content="WordPress" />';
}
add_action('wp_head', 'my_wp_head');

提交代码后,查看前台的网页源代码,就可以在 head 标签里看到刚刚添加的内容了。

这边只是是演示一个最简单的例子。利用这个钩子,我们还可以做一个发生访问 404 向管理员邮箱发送一封邮件的动作。

// 发生404 向管理员邮箱发送邮件
function HN_404_page_mail(){
  if( !is_404() ) return;//如果正常访问页面则退出该函数
  $to = get_option( 'admin_email' );//获取管理员地址
  $subject = '遇到 404 页面啦!';//邮件标题
  $message = '404 页面的地址:http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];//邮件内容
  wp_mail( $to, $subject, $message );//发送邮件
}
add_action( 'wp_head', 'HN_404_page_mail' );

挂钩函数可以选择接受从动作调用的参数,如果有任何要传递的话。在这个简单的例子中,echo_comment_id 函数需要 $comment_id 参数,该参数将在 comment_id_not_found 过滤钩子运行时通过 do_action() 传递。

function echo_comment_id( $comment_id ) // 注意$comment_id就是动作调用的参数传递过来的
{
   echo 'Comment ID ' . $comment_id . ' could not be found';
}
add_action( 'comment_id_not_found', 'echo_comment_id', 10, 1 );

过滤器钩子

过滤器钩子可以让你改一些东西的值,过滤器回调函数会接受一个参数,这就是当前的值。还记得那个用来调用文章内容的 the_content() 函数吧,这个函数就提供了一个 the_content 过滤器。

给 the_content 钩子添加一个函数,这个函数需要接收一个参数,这个参数就是当前的值。

//文章内容图片自动加ALT属性为文章标题
function kratos_auto_post_link($content)//$content 变量就是文章内容,因为其它过滤器也要过滤,所以这个内容可能是经过其它函数过滤的
 {
  global $post;
  $content = preg_replace('/<\s*img\s+[^>]*?src\s*=\s*(\'|\")(.*?)\\1[^>]*?\/?\s*>/i', "<img layer-src=\"$2\" src=\"$2\" alt=\"《".$post->post_title."》\" />", $content);
  return $content;//必须要把过滤后的内容返回回去,否则值就丢了
  }
add_filter ('the_content', 'kratos_auto_post_link',0);

其他

要找出一个动作的参数的ID和名称,只需搜索匹配 do_action() 调用的代码库。举例来说,如果你挂载到’save_post’,你会在 post.php 找到:

<?php do_action( 'save_post', $post_ID, $post ); ?>

你的 add_action 调用将是这样:

<?php add_action( 'save_post', 'my_save_post', 10, 2 ); ?>

而且你的函数将是这样:

function my_save_post( $post_ID, $post )
{
   // do stuff here
}

钩子原理

实际上,在调用 add_action() 和 add_filter() 的时候,只是向 $wp_filter 全局变量添加了一个数组元素,还要说的就是动作和过滤器是公用的一个全局变量,也就是说,过滤器和动作是不能重名的。

当调用 do_action() 的时候,会查找 $wp_filter 全局变量中都有哪些添加到此动作的函数,循环执行即可。

apply_filters() 比 do_action() 多了一个步奏,就是每次调用函数时还要接收这个函数的返回值,最后把经过多次过滤的值返回出去,供使用。

获取当前钩子列表
WordPress 的动作和过滤器是插件机制的核心部分,允许你在特定的地方主动添加自己需要执行的动作,一般使用 add_action() 和 add_filter() 函数挂载函数。

这些钩子被储存在 $wp_filter 全局变量里,所以,要获取钩子列表,可以直接获取 $wp_filter 全局变量。

<?php var_dump( $GLOBALS['wp_filter'] ); ?>

上边的代码会打印出钩子列表数组。

发表评论

电子邮件地址不会被公开。 必填项已用*标注