IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    WordPress 基础开发 – 一探 WordPress Hook 机制及示例应用

    PCDotFan发表于 2017-01-24 10:48:51
    love 0

     

       本文行文思路及示例代码来自 WPMUDEV 同名文章,感谢原作者。禁止转载。

       Hook 机制是 事件驱动型架构 中相当举足轻重的一部分。总的来说,Hook 机制实际上为我们深度定制「 WordPress 」提供了一条捷径。

       简言之,「事件驱动型架构」是一种「通过监听事件状态并作出反应」的设计。发布文章、编辑主题、安装插件……任何一个动作实质上都对应着一个「事件」的发生。而 Hook 就如同刚刚所描述的那样——在代码和实际操作中修出一条捷径,令我们可以根据自己所想而不断丰富和拓展 WordPress。

       来举个简单的例子,「发布文章」就是一个再常见不过的示例——

    publish_post
     除此之外当然还有对应的
    delete_post
      等等(可在 WordPress Codex 上详阅各种 Hook 的具体作用)。可别小看 WordPress 所定义的这几个小「短语」,它们就是 WordPress 可被拓展的重要基础。毫不夸张地说,正是 Hook 让 WordPress 拥有了这么完备的生态圈(Ecosystem),以及数以万计的插件及主题。

       再来说说为什么我们非用 Hook 不可?

       还记得我们是怎么更新 WordPress 的吗?通常只需要点击仪表盘上的「立即更新」按钮,喝杯茶的功夫一切就搞定了。开发者们甚至不需要过多考虑为新版 WordPress 做出适配和调整——很多时候,连一行代码都不需要修改。这就是 Hook 的魅力所在,正因如此,WordPress 团队才能够通过仅更新一份代码,就让世界上近 10% 的网站不用担心程序本身所带来的安全风险。

    钩子(Hooks),动作(Actions),过滤器(Filters)?这尼玛都是啥? 

       究其本质,钩子(Hooks)是 WordPress 各种主题/插件 中的一些公有事件。

       可我们为什么要叫它……「钩子」呢?

       来看看这些场景:在发布文章的同时通知百度来爬下网站,或是在保存草稿后自动帮我获取第一张图片作为特色图像等等……开发者们总想着让自己的代码能够伴随着某个操作一起执行,正如一个「钩子」一样。 

       钩子总共分为两种类型:

    • 动作 Actions
    • 过滤器 Filters

    我们在之后会介绍它们之间的区别。

    Action Hooks 和 Filter Hooks 之间的区别

       Actions 和 Filters 基本上可以互换着用——它们都是通过一定的「参数」来获取数据的,只是实现的逻辑和写法略有不同(如果你详细读过 WordPress 的核心代码,即会发现 Action Hooks 实际上就是由 Filter Hooks 实现的 )。

       不过它们还有一项非常关键的区别:Filter hooks 必须返回一个实际值(value),Action Hooks 则不需要。

       在实际场景中,Filter Hooks 通常更专注于「内容」方面。例如说,Filter Hook 

    title_save_pre
     是作用于文章标题的, 
    content_save_pre
     就是作用于文章内容的。另一方面,Action Hooks 顾名思义,它偏向于「在 WordPress 做某件事时执行相应的动作」,还是拿 
    publish_post
     为例,这个 Action Hook 就是在「任意一篇文章被发表时」被触发。

    我该怎么用 Action Hook 呢?

       基本语句如下:

    add_action( $hook, $function_to_add, $priority, $accepted_args );

       其中的

    $hook
     就是你所指定的钩子,
    $function_to_add
     就是在「钩子满足条件被触发时」所执行的相关函数。后面的
    $priority, $accepted_args
     先不管,我们以后再说。

       稍安勿躁,等会我会介绍怎么把 Action Hook 用于具体的场景中。

    我该怎么用 Filter Hook 呢?

       Filter Hook 就是在「我只想获取/修改某个内容」时所使用。

       基本语句如下:

    add_filter( $hook, $function_to_add, $priority, $accepted_args );

       和之前的

    add_action
     超像对吧?同样地,
    $hook
     就是你所指定的钩子,
    $function_to_add
     就是在「钩子满足条件被触发时」所执行的相关函数。

    怎么删除钩子?

       诶等等,我干嘛要没事干删除掉好不容易定义的钩子?可别忘了 WordPress 许多核心功能就是由一个一个钩子所建立联系的。删除钩子好比带走了队伍中的某几个人,即使他们不在了——也不会影响到整个队伍的连续性。

    remove_action( $hook, $function_to_remove, $priority);
    remove_filter( $hook, $function_to_remove, $priority);
    

    应用实例

    注:所有 Filter Hooks 及 Action Hooks 都可以在 WordPress Codex 中被找到。Hookr.io 上收录了不少 Hooks 的使用示例,有时比官方还全哦。

    Interested in learning more? The WordPress Codex provides a comprehensive guide to hooks, including a code reference for developers.

       在写完这篇文章时,WordPress 已有超过 1900 个可被使用的钩子……只有你搜不到,没有它做不到。

    Number of WordPress hooks vs version

     

    Filter Hook 示例 #1

    使用场景:给每篇文章后面加一条链接。

    实现过程:

       从 WordPress Codex 中了解到, 

    content_save_pre
     可以实现「动态更改内容」的目的(Allow you to sanitize content prior to saving it in the database)。

    代码示例:

    function add_attribution_backlink( $content ) {
      // Process content here and add the backlink
      
      $backlink = ‘<div class=”attribution”>This article first appeared on <a href=”http://premium.wpmudev.org/blog”>WPMU Dev Blog</a></div>’;
    
      $content = $content . $backlink;
      return $content;
    }
    
    add_filter( 'content_save_pre', ‘add_attribution_backlink’, 10, 1 ); 

       大功告成啦!

       等等!那

    add_filter
     后面多出的
    10,1
     是什么?这就是之前我们没介绍到的
    $priority
     和 
    $accepted_args
     。

    $priority – 优先级

       设想:如果有很多个地方都添加同一个 Hook ,他们会怎么决定执行的先后顺序呢?这时

    $priority
      即起到作用。所设定的数值越小,则越靠前被执行;反之则越延后。这也就是为什么许多代码片段会给
    $priority
      设定出莫名其妙的 
    9999
     ——实际上就是令其最后一个被执行。

    $accepted_args – 传参

       这个应该很好理解,就是所被 Hook 的函数中所需要传递的参数。例如本例子的参数就是

    $content
     ,在 
    add_filter
      被设置为 1。

     

    Filter Hook 示例 #2

    使用场景:实现 SEO 插件中的「更改网站标题」功能

    实现过程:

       例如我的网站:「WP酷 – 最前沿的 WordPress 资源聚合平台」,如果我想更改其中的分隔符「 – 」呢?

       通过查阅文档得知,

    title_save_pre
    可以实现「动态更改标题」的目的。大同小异,仿照 「示例 #1」即可写出相应代码。不过需要注意的是:Filter Hook 必须返回一个有效的值哦!

    代码示例: 

    add_filter( ‘title_save_pre’, ‘add_sitename_to_title’, 10, 2 );
    
    add_sitename_to_title( $title, $sep ) {
    
    // You might want to check whether the title has been added already before appending the title (again)
    
    /* Retrieve site name. */
    $name = get_bloginfo( ‘name’ );
    
    /* Append site name to $title. */
    $title .= $sep . ‘ ‘ . $name;
    
    /* Return the title. */
    return $title;
    
    }

     

    Action Hook 示例 #1

    使用场景:在发布文章后自动发布微博、说说……

    使用过程:

       还是 

    publish_post
     ……猜都可以知道这个钩子是在 WordPress 后台点击「发布」按钮时所执行的(An action triggered whenever a post is published, or if it is edited and the status is changed to publish.)。

    function publish_post_to_social_media($post_ID) {
      global $post;
      // 发条说说
      blabla...
      // 发个微博
      blabla...
    }
    add_action('publish_post', 'publish_post_to_social_media');

       就这么简单。

     

    Action Hook 示例 #2

    使用场景:在用户完成注册后发送一条欢迎邮件

    使用过程:

       

    after_signup_user
     是「在用户注册之后」所触发的动作,不再赘述。

    代码示例:

    function send_welcome_email( $user_data ) 
    {
        global $service_locator;
        
        $firstName   = $user_data['first_name'];
        $lastName    = $user_data['last_name'];
      
        $email_content = "
    Hello $firstName,欢迎来到 WP酷。 "\r\n"
    这是一封欢迎邮件。
    …"
    
    }
    
    add_action(‘after_signup_user’, ‘send_welcome_email’, 10, get_userdata( $user_id ) );

       注意到了吗?

    add_action
     所指定的函数并没有像之前那样需要返回一个固定值。 

     

    还有什么是 WordPress Hooks 可以做的?

       如果你细心观察,许多的主题中都会出现 

    <?php wp_head(); ?>
     或是 
    <?php wp_footer(); ?>
     此类的身影。在看完本文后或许就能明白:这两个函数是为主题的可定制性所准备的——开发者们可以通过 Functions.php 直接将函数 Hook 到
    wp_head
     等之类的位置上。包括各类 SEO 插件、编辑器插件等等等等,它们都是通过 Hooks 达到「不修改主题本身」却实现了许多新功能的效果。

     

    WordPress 基础开发 – 一探 WordPress Hook 机制及示例应用,首发于WP酷。



沪ICP备19023445号-2号
友情链接