WordPress 插件2

动作钩子 ( actions )

  • 动作钩子让你可以在 WordPress 加载过程中或者当某个事件发生的特定时刻触发一个函数。例如:你可能希望当 WordPress 第一次加载一个页面或者保存一篇文章时执行一个函数。
do_action() 函数。

当钩进 WordPress 中时,你的插件不会直接调用这个函数;但是你的插件几乎都会间接的使用它。

<?php
  do_action( $tag, $arg = '' );
?>
  • $tag — 动作钩子的名称
  • $arg — 传递给已注册的动作的值。动作钩子可以传递任何个数的参数,或者根本不传参数。

下面是一个具有多参数的动作钩子的例子

<?php
  do_action( $tag, $arg_1, $arg_2, $arg_3 );
?>

例子:

<?php
  do_action('wp_head');
?>
  • wp_head 的钩子现在前台的 <head> 里面。 WordPress 和插件经常用这个钩子来添加 meta 信息,样式表,和 js 脚本。

例子:

<?php
  do_action( 'save_post', $post_ID, $post );
?>
  • 这个 save_post 的钩子传递两个参数,一个 $post_ID,一个 $post。

add_action() 函数

<?php
add_action( $tag, $function, $priority, $accepted_args );
?>
  • $tag – 你的函数执行时代动作钩子的名称。
  • $function – WordPress 要调用的函数名。
  • $priority – 一个表示动作调用顺序的整数,默认是10。数字越小,这个函数越早被调用。
  • $accepted_args – 动作钩子要传递给你的函数的参数个数。默认只有一个参数。

动作钩子并不局限于单个动作。你的插件可以将多个函数添加到一个动作钩子上。其他插件,甚至是 WordPress 核心,经常将多个函数添加到同一个钩子上。

  • 常见的动作钩子是 wp_footer 。它提供给前端用户的 WordPress 模板使用。通常它刚好在</body>前调用。在下面的例子中,将要为 wp_footer 注册一个动作并添加一条自定义信息到 footer。
<?php
add_action( 'wp_footer', 'boj_example_footer_message', 100 );
function boj_example_footer_message() {
    echo "基于 <a href="http://wordpress.org" >WordPress </a>架设。;
}
?>
  • 第一个参数是钩子的名字( wp_footer )。第二个参数是要回调的函数 ( boj_example_footer_message )。第三个参数是优先级 ( 100 )。这个函数比起其他钩到 wp_footer 中的函数,会在比较靠后的次序执行。如果设置成1,就较先执行。

  • 钩子可能会因为许多原因在 WordPress 执行过程中多次触发。任何添加到这个钩子中的动作每当钩子触发时都会执行一次。

<?php
do_action_ref_arrray( $tag, $args );
?>
  • $tag – 动作钩子的名字。
  • $args – 要传递给注册到这个钩子的函数的参数的数组。通常,这是一个动作可以改变的对象。
    下面看一个 WordPress 如何调用 do_action_ref_array() 的实例。下面的代码展示了 pre_get_posts 动作钩子。WordPress 在从数据库取得 posts 之前执行这个钩子,使得插件可以改变查询 posts 的方式。
<?php
do_action_ref_array( 'pre_get_posts', array( & $this ) );
?>
  • 第一个参数 pre_get_posts 是钩子的名字。第二个参数是从数据库中查询 posts 的参数的数组。这个钩子使你可以执行基于那个参数数组的代码。

假如你想安装随机的顺序来得到首页的 blog,而不是默认的通过发布时间来得到。你就需要注册一个动作到这个钩子,并改变排序顺序。

<?php
add_action( 'pre_get_posts', 'boj_randomly_order_blog_posts' );
function boj_randomly_order_blog_posts( $query ) {
    if( $query -> is_home && empty( $query -> query_vars['suppress_filters']))
        $query -> set( 'rderby', 'rand' );
}
?>

remove_action 函数

  • remove_action() 可以删除先前添加到一个钩子的动作。如果动作被成功删除,则函数返回 true,否则返回 false。
<?php
remove_action( $tag, $function_to_remove, $priority, $accepted_args );
?>
  • 参数类似于 do_action()。要成功的从一个钩子中删除一个动作, $tag, $function_to_remove, 和 $priority 必须完全的复合 do_action() 中使用的参数。否则动作不会被溢出,同时 remove_action() 返回 flase。

remove_all_actions

  • 在有些插件中,可能需要删除所有特定 tag 或者 特定 tag + 特定优先级的所有钩子。使用 remove_all_actions() 可以一次删除所有符合条件的动作。
<?php
remove_all_actions( $tag, $priority );
?>
  • $priority 参数是可选的,默认是 false。如果你设置了这个参数,那么只有这个优先级的动作会被删除。下面的例子从 wp_head 动作钩子中删除不管任何优先级的动作。
<?php
remove_all_actions( 'wp_head' );
?>
  • 在使用这个函数的时候必须要小心。其他 plugin 或者 theme 可能添加了你不知道动作。这就可能破坏插件应有的功能。通常应该保持你的代码尽可能的特殊。在大多数情况下,你应该使用 remove_action() 函数来代替。

as_action

  • 有的时候需要确定一个钩子是否包含一些动作,或者一个特定的动作是否已经添加到了钩子里面。has_action() 提供了这些功能。
<?php
has_action( $tag, $function_to_check );
?>
  • has_action() 函数的返回值是 Boolean 或者 一个整型值。如果 $function_to_check 参数为空,那么如果有动作已经添加到了钩子中就返回 true,反之,返回 false。而如果 $function_to_check 设置了,而且这个函数已经添加到了钩子里面,则返回该动作的优先级,否则返回 false。

下面的例子中,根据 wp_footer 动作钩子中是否有注册的动作来确定显示的信息。

<?php
if( has_action( 'wp_footer' ) )
    echo '<p> footer 中已经注册有动作了。</p>';
else
    echo '<p> footer 中还没有注册动作。</p>';
?>
  • 下面看一个 WordPress 核心添加到 wp_footer 中的动作。wp_print_footer_script() 默认注册给这个钩子。
<?php
add_action( 'wp_footer', 'wp_print_footer_scripts' );
?>

did_action

  • did_action() 使你的插件可以检查一个动作钩子是否已经被执行,或者记录执行的次数。这也意味着这一次页面的加载过程中有些动作被执行了多次。
<?php
did_action( $tag );
?>
  • 这个参数返回动作已经执行的次数,如果还未执行,返回 false。这个函数的一般用途是判断一个动作钩子是否已经被触发,并执行基于 did_action() 的返回值的代码。

下面的例子中,如果 plugins_loaded 动作钩子已经被触发,就定义一个 PHP 常量。

<?php
if ( did_action( 'plugins_loaded' ) )
    define( 'BOJ_MYPLUGIN_READY' ,true );
?>

register_activation_hook 和 register_deactivation_hook

常用的动作钩子

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

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

下面的例子中,使用boj_example_footer_message 动作。
要把它添加到钩到 plugins_loaded 钩子中的安装动作中,而不是单独调用它。

<?php
 
add_action( 'plugins_loaded', 'boj_footer_message_plugin_setup' );
 
function boj_footer_message_plugin_setup() {
 
/* 添加 footer 信息动作 */
 
add_action( 'wp_footer', 'boj_example_footer_message', 100 );
 
}
 
function boj_example_footer_message() {
 
echo "基于 <a href="http://wordpress.org" >WordPress </a>架设。;
 
}
 
?>
  • 创建一个安装函数并把它钩到 plugins_loaded 中。这样做就可以确保不会由于特定的 WordPress 函数还没有加载而触发错误。
init
  • init 钩子在大多数的 WordPress 都建立之后。WordPress 同样添加许多内部的功能到这个钩子中,例如 post types 和 taxonomies 的厨厕以及默认 widgets 的初始化。

  • 因为这时几乎 WordPress 中的所有内容都就绪了,当 WordPress 的所有信息都可用时,你的插件使用这个钩子差不多可以做任何需要的事情了。

  • 下面的例子中,为用户添加了给 pages 写摘要的功能。这应该在 init 中执行,因为 “page” post type 在这时使用 add_post_type_support() 函数来创建。

<?php
 
add_action( 'init', 'boj_add_excerpts_to_pages' );
 
function boj_add_excerpts_to_pages() {
 
add_post_type_support( 'page', array( 'excerpt' ) );
 
}
 
?>

admin_menu

  • admin_menu 钩子在管理员页面加载的时候调用。无论何时你的插件直接在管理页面下工作,你都要用这个钩子来执行你的代码。

  • 下面的例子添加了一个内容是 BOJ Settings 的 sub-menu 项到 WordPress 管理页面的设置菜单。(详见:Part-7,”插件设置”)

<?php
 
add_action( 'admin_menu', 'boj_admin_settings_page' );
 
function boj_admin_settings_page() {
 
add_options_page(
 
'BOJ Settings',
 
'BOJ Settings',
 
'manage_options',
 
'boj_admin_settings',
 
'boj_admin_settings_page'
 
);
 
}
 
?>
template_redirect
  • template_redirect 动作钩子很有用,因为它是 WordPress 知道用户正在浏览的页面的关键。它在特定的页面选择 theme template 之前执行。在只在网站的前端触发,并不在管理员页面触发。

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

  • 下面的例子中,仅仅为 singular post 加载一个样式表文件。

<?php
 
add_action( 'template_redirect', 'boj_singular_post_css' );
 
function boj_singular_post_css() {
 
if( is_singular( 'post' ) ) {
 
wp_enqueue_style (       
 
'boj-singular-post',
 
'boj-example.css',
 
false,
 
0.1,
 
'screen'
 
);
 
}
 
}
 
?>
wp_head
  • 在网站的前端,WordPress 的模板调用 wp_head() 函数,会触发 wp_head 钩子。插件使用这个钩子在 <head> 和 </head> 标签之间添加 HTML。

下面的例子中在前端添加一个 meta description。

<?php
 
add_action( 'wp_head', 'boj_front_page_meta_description' );
 
function boj_front_page_meta_description() {
 
/* 得到站点描述 */
 
$description = esc_attr( get_bloginfo( 'description' ) );
 
/* 如果 description 设置了,显示 meta 元素 */
 
if ( !empty( $description ) )
 
echo '<meta name="description" content="'. $description. '"/>';
 
}
 
?>

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容