一、背景

WordPress深受广大用户/企业喜欢的一大原因就是它对于二次开发的灵活支持。它允许二次开发人员自定义/修改其各种方法,从展现到数据输出,从内部管理到外部接口,程序员可以发挥自己的想象力,最大程度地实现自己个性化定制Wordpress应用。


当然,WordPress之所以能提供这样灵活的二次开发能力,很大程度上得益于其基于插件的架构设计。Wordpress里面内涵了各种各样的action/filter,通过这些action/filter,你可以在Wordpress运行的各个环节来修改缺省的Wordpress行为、表现和事件。


但是,这里面存在一个很大问题。就是:构建插件和主题时,我们经常需要参考WordPress钩子的优先顺序。搞清这个问题,将非常有助于确保仅在需要时和正确的时间加载各种组件。


同时,使用Wordpress各种钩子资源时还有一个问题:需要确定在前端、后端(仅限管理员)、AJAX和Cron上将触发哪些Action/Filter。下面是一个备忘单,将有助于理清上述两个方面的问题。


二、WordPress Action钩子

第一阶段 : Loading

前端页面

管理员页面

​muplugins_loaded​

​muplugins_loaded​

​registered_taxonomy​

​registered_taxonomy​

registered_post_type

registered_post_type

​plugins_loaded​

​plugins_loaded​

​sanitize_comment_cookies​

​sanitize_comment_cookies​

​setup_theme​

​setup_theme​

​load_textdomain​

​load_textdomain​

​after_setup_theme​

​after_setup_theme​

​auth_cookie_malformed​

 

​auth_cookie_valid​

​auth_cookie_valid​

​set_current_user​

​set_current_user​

​init​

​init​

​widgets_init *​

​widgets_init *​

​register_sidebar​

​register_sidebar​

​wp_register_sidebar_widget​

​wp_register_sidebar_widget​

​wp_default_scripts​

 ​​wp_default_scripts​

​wp_default_styles​

 ​​wp_default_styles​

​admin_bar_init​

 ​​admin_bar_init​

​add_admin_bar_menus​

 ​​add_admin_bar_menus​

​wp_loaded​

 ​​wp_loaded​


对插件开发者来说,plugins_loaded 动作钩子也许是最重要的动作钩子了。它在大多数 WordPress 文件加载完成之后,并在pluggable 函数和 WordPress 开始执行任何东西之前触发。在大多数的插件中,在这个钩子触发之前,不应该执行其他的代码。plugins_loaded 在所有用户启用的插件都被 WordPress 加载之后执行。这也是在加载过程中插件开发这最早能用到的钩子。

WordPress 的插件应该在这个钩子中执行安装。其他动作也应该添加到这个钩子的回调函数中。


init 钩子在大多数的 WordPress 都建立之后。WordPress 同样添加许多内部的功能到这个钩子中,例如 post types 和 taxonomies 以及默认 widgets 的初始化。因为这时几乎 WordPress 中的所有内容都就绪了,当 WordPress 的所有信息都可用时,你的插件使用这个钩子差不多可以做任何需要的事情了。



[注意]

​widgets_init​​ 是在init这个Action中触发的,此Action触发的优先级别为1(priority: 1)。

第二阶段:Processing

从整体系统加载流程分析看,自wp_loaded调用后,前端页面与管理员页面处理流程上就开始分别进行。

前端

管理端

​parse_request​​​  ​​rest_api_init​​ *conditionally

 ​​auth_redirect​

​send_headers​​ 

​_admin_menu​

​parse_query​​ 

 ​​admin_menu​

​pre_get_posts​​ 

 ​​admin_init​

​posts_selection​

 ​​current_screen​

 

​load-(page)​

 

​send_headers​

 

​pre_get_posts​

 

​posts_selection​

​wp​ 

 ​​wp​

​template_redirect​

 

​get_header​

 

​wp_enqueue_scripts​

 ​​admin_enqueue_scripts​

​wp_head​

 

 

 ​​admin_print_styles-(hookname)​

 

 ​​admin_print_styles​

 

 ​​admin_print_scripts-(hookname)​

 

 ​​admin_print_scripts​

​wp_print_scripts​​ 

 ​​wp_print_scripts​

 

 ​​admin_head-(hookname)​

 

 ​​admin_head​

 

 ​​adminmenu​

 

​in_admin_header​

​get_search_form​

 ​​admin_notices​

 

​all_admin_notices​

​loop_start​

 ​​restrict_manage_posts​

​the_post​​ 

​the_post​

​get_template_part_content​​ 

 ​​pre_user_query​

​loop_end​​ 

 

​get_sidebar​​ 

 

​dynamic_sidebar​​ 

 

​get_search_form​​ 

 

​pre_get_comments​​ 

 

​wp_meta​​ 

 

​get_footer​​ 

  ​​in_admin_footer​

​get_sidebar​​ 

 

​wp_footer​​ 

 ​​admin_footer​

​wp_print_footer_scripts​​ 

 

​admin_bar_menu​​ 

 ​​admin_bar_menu​

​wp_before_admin_bar_render​​ 

​wp_before_admin_bar_render​

​wp_after_admin_bar_render​​ 

​wp_after_admin_bar_render​

 

 ​​admin_print_footer_scripts​

 

 ​​admin_footer-(hookname)​

​shutdown​​ 

​shutdown​

 

​wp_dashboard_setup​

 

在网站的前端,WordPress 的模板调用 wp_head() 函数,会触发 wp_head 钩子。插件使用这个钩子在 <head> 和 </head> 标签之间添加 HTML。


template_redirect 动作钩子很有用,因为它是 WordPress 知道用户正在浏览的页面的关键。它在特定的页面选择 theme template 之前执行。在只在网站的前端触发,并不在管理员页面触发。

当你需要为特定的页面加载代码的时候,这个钩子很有用。


有些插件错误的使用了 wp_head 动作钩子来添加 JavaScript 代码,实际上应该使用 wp_enqueue_script() 函数的。唯一一种使用这个钩子来添加 JavaScript 的情形是当 JavaScript 代码不在一个单独的文件中时。

 三、小结

开发Wordpress主题或者插件时,经常面临系统提供的很多action/filter可以使用,那么,这些action/filter哪个先调用哪个后执行,这是一个必须先要弄清的基本问题,类似于其它系统架构学习之初对于框架生命周期的学习一样。有兴趣深入研究Wordpress开发的朋友可以参考上面列表。

参考