插件开发文档

自定义钩子

💡 云策文档标注

概述

本文档介绍了在 WordPress 插件中使用自定义钩子的重要性,以便其他开发者能够扩展和修改插件。自定义钩子的创建和调用方式与 WordPress 核心钩子相同,包括使用 do_action() 创建动作钩子和 apply_filters() 创建过滤器钩子。

关键要点

  • 自定义钩子通过 do_action()(动作)和 apply_filters()(过滤器)创建,推荐对输出到浏览器的文本使用 apply_filters() 以增强可扩展性。
  • 使用 add_action() 和 add_filter() 为自定义钩子添加回调函数,实现功能扩展。
  • 为避免命名冲突,钩子名称应添加唯一前缀(如公司名、插件名),例如使用 wporg_ 作为前缀。

代码示例

// 创建动作钩子示例
do_action( 'wporg_after_settings_page_html' );

// 添加回调函数到动作钩子
add_action( 'wporg_after_settings_page_html', 'myprefix_add_settings' );

// 创建过滤器钩子示例
register_post_type(
    'post_type_slug',
    apply_filters( 'wporg_post_type_params', $post_type_params )
);

// 添加回调函数到过滤器钩子
function myprefix_change_post_type_params( $post_type_params ) {
    $post_type_params['hierarchical'] = true;
    return $post_type_params;
}
add_filter( 'wporg_post_type_params', 'myprefix_change_post_type_params' );

注意事项

  • 动作钩子不返回值,而过滤器钩子接收数据、修改后返回,回调函数应避免直接输出内容。
  • 未指定优先级时,钩子默认以优先级 10 运行;未指定参数数量时,默认假设为一个参数。

📄 原文内容

An important, but often overlooked practice is using custom hooks in your plugin so that other developers can extend and modify it.

Custom hooks are created and called in the same way that WordPress Core hooks are.

Create a Hook

To create a custom hook, use <a href="https://developer.wordpress.org/reference/functions/do_action/">do_action()</a> for Actions and <a href="https://developer.wordpress.org/reference/functions/apply_filters/">apply_filters()</a> for Filters.

We recommend using `apply_filters() ` on any text that is output to the browser. Particularly on the frontend.

This makes it easier for plugins to be modified according to the user’s needs.

Add a Callback to the Hook

To add a callback function to a custom hook, use <a href="https://developer.wordpress.org/reference/functions/add_action/">add_action()</a> for Actions and <a href="https://developer.wordpress.org/reference/functions/add_filter/">add_filter()</a> for Filters.

Naming Conflicts

Naming conflicts (“collisions”) occur when two developers use the same hook name for completely different purposes. This leads to difficult to find bugs. So it’s important to prefix your hook names with a unique string to avoid hook name collisions.collisions with other plugins.

For example, a filter named email_body is generic enough that two or more developers could use this hook in different plugins for different purposes. So to avoid this, a prefix is added. For example, functions used as examples in this handbook use wporg_ as the prefix.

When you choose your prefix, you can use your company name, your wp handle, the plugin name, anything you like really. The goal is to make it unique so choose wisely.

Examples

Extensible Action: Settings Form

If your plugin adds a settings form to the Administrative Panels, you can use Actions to allow other plugins to add their own settings to it.

    do_action( 'wporg_after_settings_page_html' );

Now another plugin can register a callback function for the wporg_after_settings_page_html hook and inject new settings:

add_action( 'wporg_after_settings_page_html', 'myprefix_add_settings' );

Note that because this is an action, no value is returned. Also note that since no priority is given, it will run at default priority 10.

Extensible Filter: Custom Post Type

In this example, when the new post type is registered, the parameters that define it are passed through a filter, so another plugin can change them before the post type is created.

function wporg_create_post_type() {
    $post_type_params = [/* ... */];

    register_post_type(
        'post_type_slug',
        apply_filters( 'wporg_post_type_params', $post_type_params )
    );
}

Now another plugin can register a callback function for the wporg_post_type_params hook and change post type parameters:

function myprefix_change_post_type_params( $post_type_params ) {
	$post_type_params['hierarchical'] = true;
	return $post_type_params;
}
add_filter( 'wporg_post_type_params', 'myprefix_change_post_type_params' );

Note that filters filters take data, modify it, and return it. So the code called ( myprefix_change_post_type_params ) doesn’t output anything using echo or html, or anything else directly to the screen. Also note that the retuned value is used directly by register_post_type without being assigned to a variable first. This is simple to skip that extra (an unnecessary) step.

Also note that since no priority is given, it will run at default priority 10. And since there is no value for the number of parameters expected, the default of one is assumed.