深入理解 WordPress `register_meta()` 函数源码:如何将自定义元数据暴露给 REST API,并支持读取和写入。

各位,今天咱们聊聊WordPress里一个挺重要的函数——register_meta()。这函数就像个媒婆,专门给你的自定义元数据和WordPress的REST API牵线搭桥。让你的数据不仅能存储在数据库里,还能通过API轻松访问和修改,简直是开发自定义插件和主题的必备良药。

开场白:认识一下元数据这大家族

在WordPress的世界里,元数据就像是给各种东西贴标签,比如文章、页面、用户等等。它能让你给这些对象添加额外的信息,这些信息不是核心数据,但却能丰富它们的功能。

想象一下,你写了一篇关于旅游的文章,你想给它加上一个“旅游目的地”的标签。这时候,元数据就派上用场了。

register_meta():元数据与REST API的红娘

register_meta()函数的作用,就是把你的自定义元数据“注册”到WordPress系统里。更重要的是,它能让你控制这些元数据是否能通过REST API访问和修改。

语法结构:register_meta()的自我介绍

register_meta(
    string $object_type,
    string $meta_key,
    array|string $args = array()
);
  • $object_type:你想要关联元数据的对象类型。常见的值有'post' (文章)、'page' (页面)、'user' (用户)等等。
  • $meta_key:元数据的键名,就像标签的名字。
  • $args:一个数组,包含了各种配置选项,控制元数据的行为,比如是否允许通过REST API访问。

关键参数:show_in_rest的魔力

$args数组里最重要的一个参数就是show_in_rest。它决定了你的元数据是否会出现在REST API的响应中,以及是否允许通过REST API进行修改。

  • true:你的元数据会出现在REST API中,并且可以被读取和写入。
  • false:你的元数据不会出现在REST API中。
  • array:允许你更精细地控制元数据的显示和编辑。

实例演示:文章元数据的REST API之旅

咱们来创建一个自定义插件,给文章添加一个“阅读时长”的元数据,并且让它可以通过REST API访问。

1. 创建插件文件

创建一个名为wp-reading-time/wp-reading-time.php的文件,并添加以下代码:

<?php
/**
 * Plugin Name: WP Reading Time
 * Description: Adds a reading time meta field to posts and exposes it to the REST API.
 * Version: 1.0.0
 * Author: Your Name
 */

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Registers the reading time meta field.
 */
function wp_reading_time_register_meta() {
    register_meta(
        'post',
        'reading_time',
        array(
            'type'              => 'integer', // 数据类型
            'description'       => 'Estimated reading time in minutes.',
            'single'            => true,      // 是否是单值
            'show_in_rest'      => true,      // 暴露给REST API
            'sanitize_callback' => 'absint',  // 数据清洗函数
            'auth_callback'     => function() {
                return current_user_can( 'edit_posts' ); // 权限验证
            },
        )
    );
}
add_action( 'init', 'wp_reading_time_register_meta' );

/**
 * Adds a metabox to the post editor.
 */
function wp_reading_time_add_metabox() {
    add_meta_box(
        'wp_reading_time_metabox',
        'Reading Time',
        'wp_reading_time_metabox_callback',
        'post',
        'side',
        'default'
    );
}
add_action( 'add_meta_boxes', 'wp_reading_time_add_metabox' );

/**
 * Metabox callback function.
 *
 * @param WP_Post $post The current post object.
 */
function wp_reading_time_metabox_callback( $post ) {
    wp_nonce_field( 'wp_reading_time_save_meta', 'wp_reading_time_nonce' );
    $reading_time = get_post_meta( $post->ID, 'reading_time', true );
    ?>
    <label for="reading_time">Reading Time (minutes):</label>
    <input type="number" id="reading_time" name="reading_time" value="<?php echo esc_attr( $reading_time ); ?>" />
    <?php
}

/**
 * Saves the reading time meta data.
 *
 * @param int $post_id The ID of the post being saved.
 */
function wp_reading_time_save_meta( $post_id ) {
    // Check if our nonce is set.
    if ( ! isset( $_POST['wp_reading_time_nonce'] ) ) {
        return;
    }

    // Verify that the nonce is valid.
    if ( ! wp_verify_nonce( $_POST['wp_reading_time_nonce'], 'wp_reading_time_save_meta' ) ) {
        return;
    }

    // If this is an autosave, our form has not been submitted, so we don't want to do anything.
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
        return;
    }

    // Check the user's permissions.
    if ( ! current_user_can( 'edit_post', $post_id ) ) {
        return;
    }

    // Make sure that it is set.
    if ( ! isset( $_POST['reading_time'] ) ) {
        return;
    }

    // Sanitize user input.
    $reading_time = absint( $_POST['reading_time'] );

    // Update the meta field in the database.
    update_post_meta( $post_id, 'reading_time', $reading_time );
}
add_action( 'save_post', 'wp_reading_time_save_meta' );

2. 激活插件

在WordPress后台,激活WP Reading Time插件。

3. 编辑文章

现在,编辑一篇文章,你会看到一个新的元数据框,叫做“阅读时长”。输入一个数字,比如“5”,然后保存文章。

4. 通过REST API查看

打开你的浏览器,输入以下URL(替换[你的网站][文章ID]):

[你的网站]/wp-json/wp/v2/posts/[文章ID]

在返回的JSON数据中,你会看到:

{
    ...
    "meta": {
        "reading_time": 5
    },
    ...
}

看到了吗?你的“阅读时长”元数据已经成功地通过REST API暴露出来了!

5. 通过REST API修改

你可以使用PUTPOST请求来修改这个元数据。例如,使用curl命令:

curl -X POST 
  [你的网站]/wp-json/wp/v2/posts/[文章ID] 
  -H 'Content-Type: application/json' 
  -H 'Authorization: Basic [你的用户名和密码的Base64编码]' 
  --data-raw '{
    "meta": {
      "reading_time": 10
    }
  }'

注意:你需要替换[你的网站][文章ID][你的用户名和密码的Base64编码]

执行成功后,再次查看REST API的响应,你会发现“阅读时长”已经变成了10。

show_in_rest参数的进阶用法

show_in_rest参数还可以接受一个数组,让你更精细地控制元数据的显示和编辑。

'show_in_rest' => array(
    'name'   => 'reading_time', // REST API中使用的键名 (可选,默认为$meta_key)
    'schema' => array(
        'type'        => 'integer',
        'description' => 'Estimated reading time in minutes.',
        'context'     => array( 'view', 'edit' ), // 显示的上下文
    )
),
  • name:指定REST API中使用的键名。如果你想在REST API中使用不同的键名,可以使用这个参数。
  • schema:定义元数据的结构。type指定数据类型,description提供描述信息,context指定在哪些上下文中显示元数据。context可以设置为'view'(只读)或'edit'(可读写)。

权限控制:auth_callback保驾护航

register_meta()函数还提供了一个auth_callback参数,让你控制哪些用户可以访问和修改元数据。

'auth_callback' => function() {
    return current_user_can( 'edit_posts' );
},

上面的例子中,只有具有edit_posts权限的用户才能访问和修改“阅读时长”元数据。

数据清洗:sanitize_callbackupdate_callback的职责

  • sanitize_callback:在数据写入数据库之前,对数据进行清洗。例如,可以使用absint函数将数据转换为整数。
  • update_callback:在数据更新之后,执行一些额外的操作。例如,可以更新缓存。

表格总结:register_meta()参数一览

参数名称 类型 描述
type string 元数据的数据类型。常见的值有'string''integer''boolean''number''array''object'
description string 元数据的描述信息。
single boolean 是否是单值元数据。如果为true,则只能存储一个值。如果为false,则可以存储多个值。
show_in_rest boolean|array 是否通过REST API暴露元数据。如果为true,则暴露元数据。如果为false,则不暴露元数据。如果为一个数组,则可以更精细地控制元数据的显示和编辑。
sanitize_callback callable 数据清洗函数,在数据写入数据库之前执行。
auth_callback callable 权限验证函数,控制哪些用户可以访问和修改元数据。
update_callback callable 数据更新后的回调函数,在数据更新之后执行。

注意事项:一些容易踩坑的地方

  • 缓存问题: 在修改元数据之后,可能需要清除缓存才能看到最新的结果。
  • 权限问题: 确保你的用户具有足够的权限来访问和修改元数据。
  • 数据类型: 选择合适的数据类型,并使用sanitize_callback函数进行数据清洗,防止出现安全问题。

总结:register_meta()的强大之处

register_meta()函数是WordPress开发中一个非常强大的工具。它能让你轻松地将自定义元数据暴露给REST API,并且可以灵活地控制数据的访问和修改。掌握了这个函数,你就能开发出更加强大和灵活的WordPress插件和主题。

希望今天的讲解对你有所帮助!下次再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注