register_meta()
云策文档标注
概述
register_meta() 函数用于在 WordPress 中注册元数据键,允许开发者定义元数据的类型、验证规则和访问控制。它支持多种对象类型(如 post、user、term 等)和子类型(如自定义文章类型),并可通过参数配置元数据的 REST API 可见性、默认值和修订支持。
关键要点
- 注册元数据键时,推荐指定 object_type 和 object_subtype 以精确控制应用范围;若省略子类型,则应用于整个对象类型,但可能被子类型特定注册覆盖。
- 参数 $args 数组包含 type(数据类型,如 string、boolean、array 等)、single(是否单值)、show_in_rest(REST API 可见性)、sanitize_callback(清理回调)、auth_callback(权限回调)等关键选项。
- 对于不支持子类型的对象类型(如 user、comment),通常不传递 object_subtype。
- show_in_rest 参数需配合对象类型支持 custom-fields 才能生效,例如自定义文章类型必须在注册时声明支持 custom-fields。
- 从 WordPress 5.5 开始,可使用 default 参数设置元数据的默认值,简化了 REST API 中的默认值配置。
- revisions_enabled 参数仅适用于 object_type 为 'post' 的情况,且要求对象子类型支持修订。
- 函数返回布尔值:成功注册到全局数组返回 true,否则返回 false;但即使注册失败,sanitize_callback 和 auth_callback 仍可能被触发。
代码示例
register_meta('post', 'my_meta', [
'object_subtype' => 'my_article',
'type' => 'string',
'single' => true,
'show_in_rest' => true,
'default' => 'default_value',
'sanitize_callback' => function($meta_value, $meta_key, $object_type, $object_subtype) {
return sanitize_text_field($meta_value);
},
'auth_callback' => function($allowed, $meta_key, $object_id, $user_id, $cap, $caps) {
return current_user_can('edit_post', $object_id);
}
]);注意事项
- 注册 array 类型元数据时,若 show_in_rest 不为 false,必须提供 show_in_rest['schema']['items'] 以定义数组项的模式,否则会触发 _doing_it_wrong 警告。
- 默认情况下,若未提供 auth_callback,系统会根据 is_protected_meta() 自动设置:受保护的元数据返回 __return_false,否则返回 __return_true。
- 旧版回调参数($sanitize_callback 和 $auth_callback 作为单独参数)已弃用,应使用 $args 数组传递;使用旧方式不会添加到全局注册表,但回调仍会生效。
- 确保 default 值与 type 参数匹配,否则注册可能失败并触发错误。
原文内容
Registers a meta key.
Description
It is recommended to register meta keys for a specific combination of object type and object subtype. If passing an object subtype is omitted, the meta key will be registered for the entire object type, however it can be partly overridden in case a more specific meta key of the same name exists for the same object type and a subtype.
If an object type does not support any subtypes, such as blogs, users, or comments, you should commonly call this function without passing a subtype.
Parameters
$object_typestringrequired-
Type of object metadata is for. Accepts
'blog','post','comment','term','user', or any other object type with an associated meta table. $meta_keystringrequired-
Meta key to register.
$argsarrayrequired-
Data used to describe the meta key when registered.
object_subtypestringA subtype; e.g. if the object type is “post”, the post type. If left empty, the meta key will be registered on the entire object type. Default empty.typestringThe type of data associated with this meta key.
Valid values are'string','boolean','integer','number','array', and'object'.labelstringA human-readable label of the data attached to this meta key.descriptionstringA description of the data attached to this meta key.singleboolWhether the meta key has one value per object, or an array of values per object.defaultmixedThe default value returned from get_metadata() if no value has been set yet.
When using a non-single meta key, the default value is for the first entry.
In other words, when calling get_metadata() with$singleset tofalse, the default value given here will be wrapped in an array.sanitize_callbackcallableA function or method to call when sanitizing$meta_keydata.auth_callbackcallableOptional. A function or method to call when performing edit_post_meta, add_post_meta, and delete_post_meta capability checks.show_in_restbool|arrayWhether data associated with this meta key can be considered public and should be accessible via the REST API. A custom post type must also declare support for custom fields for registered meta to be accessible via REST.
When registering complex meta values this argument may optionally be an array with'schema'or'prepare_callback'keys instead of a boolean.revisions_enabledboolWhether to enable revisions support for this meta_key. Can only be used when the object type is'post'.
$deprecatedstring|arrayoptional-
Deprecated. Use
$argsinstead.Default:
null
Source
function register_meta( $object_type, $meta_key, $args, $deprecated = null ) {
global $wp_meta_keys;
if ( ! is_array( $wp_meta_keys ) ) {
$wp_meta_keys = array();
}
$defaults = array(
'object_subtype' => '',
'type' => 'string',
'label' => '',
'description' => '',
'default' => '',
'single' => false,
'sanitize_callback' => null,
'auth_callback' => null,
'show_in_rest' => false,
'revisions_enabled' => false,
);
// There used to be individual args for sanitize and auth callbacks.
$has_old_sanitize_cb = false;
$has_old_auth_cb = false;
if ( is_callable( $args ) ) {
$args = array(
'sanitize_callback' => $args,
);
$has_old_sanitize_cb = true;
} else {
$args = (array) $args;
}
if ( is_callable( $deprecated ) ) {
$args['auth_callback'] = $deprecated;
$has_old_auth_cb = true;
}
/**
* Filters the registration arguments when registering meta.
*
* @since 4.6.0
*
* @param array $args Array of meta registration arguments.
* @param array $defaults Array of default arguments.
* @param string $object_type Type of object metadata is for. Accepts 'blog', 'post', 'comment', 'term',
* 'user', or any other object type with an associated meta table.
* @param string $meta_key Meta key.
*/
$args = apply_filters( 'register_meta_args', $args, $defaults, $object_type, $meta_key );
unset( $defaults['default'] );
$args = wp_parse_args( $args, $defaults );
// Require an item schema when registering array meta.
if ( false !== $args['show_in_rest'] && 'array' === $args['type'] ) {
if ( ! is_array( $args['show_in_rest'] ) || ! isset( $args['show_in_rest']['schema']['items'] ) ) {
_doing_it_wrong( __FUNCTION__, __( 'When registering an "array" meta type to show in the REST API, you must specify the schema for each array item in "show_in_rest.schema.items".' ), '5.3.0' );
return false;
}
}
$object_subtype = ! empty( $args['object_subtype'] ) ? $args['object_subtype'] : '';
if ( $args['revisions_enabled'] ) {
if ( 'post' !== $object_type ) {
_doing_it_wrong( __FUNCTION__, __( 'Meta keys cannot enable revisions support unless the object type supports revisions.' ), '6.4.0' );
return false;
} elseif ( ! empty( $object_subtype ) && ! post_type_supports( $object_subtype, 'revisions' ) ) {
_doing_it_wrong( __FUNCTION__, __( 'Meta keys cannot enable revisions support unless the object subtype supports revisions.' ), '6.4.0' );
return false;
}
}
// If `auth_callback` is not provided, fall back to `is_protected_meta()`.
if ( empty( $args['auth_callback'] ) ) {
if ( is_protected_meta( $meta_key, $object_type ) ) {
$args['auth_callback'] = '__return_false';
} else {
$args['auth_callback'] = '__return_true';
}
}
// Back-compat: old sanitize and auth callbacks are applied to all of an object type.
if ( is_callable( $args['sanitize_callback'] ) ) {
if ( ! empty( $object_subtype ) ) {
add_filter( "sanitize_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $args['sanitize_callback'], 10, 4 );
} else {
add_filter( "sanitize_{$object_type}_meta_{$meta_key}", $args['sanitize_callback'], 10, 3 );
}
}
if ( is_callable( $args['auth_callback'] ) ) {
if ( ! empty( $object_subtype ) ) {
add_filter( "auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $args['auth_callback'], 10, 6 );
} else {
add_filter( "auth_{$object_type}_meta_{$meta_key}", $args['auth_callback'], 10, 6 );
}
}
if ( array_key_exists( 'default', $args ) ) {
$schema = $args;
if ( is_array( $args['show_in_rest'] ) && isset( $args['show_in_rest']['schema'] ) ) {
$schema = array_merge( $schema, $args['show_in_rest']['schema'] );
}
$check = rest_validate_value_from_schema( $args['default'], $schema );
if ( is_wp_error( $check ) ) {
_doing_it_wrong( __FUNCTION__, __( 'When registering a default meta value the data must match the type provided.' ), '5.5.0' );
return false;
}
if ( ! has_filter( "default_{$object_type}_metadata", 'filter_default_metadata' ) ) {
add_filter( "default_{$object_type}_metadata", 'filter_default_metadata', 10, 5 );
}
}
// Global registry only contains meta keys registered with the array of arguments added in 4.6.0.
if ( ! $has_old_auth_cb && ! $has_old_sanitize_cb ) {
unset( $args['object_subtype'] );
$wp_meta_keys[ $object_type ][ $object_subtype ][ $meta_key ] = $args;
return true;
}
return false;
}
Hooks
- apply_filters( ‘register_meta_args’, array $args, array $defaults, string $object_type, string $meta_key )
-
Filters the registration arguments when registering meta.
Changelog
| Version | Description |
|---|---|
| 6.7.0 | The label argument was added to the arguments array. |
| 6.4.0 | The $revisions_enabled argument was added to the arguments array. |
| 5.5.0 | The $default argument was added to the arguments array. |
| 5.3.0 | Valid meta types expanded to include “array” and “object”. |
| 4.9.8 | The $object_subtype argument was added to the arguments array. |
| 4.6.0 | Modified to support an array of data to attach to registered meta keys. Previous arguments for $sanitize_callback and $auth_callback have been folded into this array. |
| 3.3.0 | Introduced. |
Skip to note 10 content
Jan-Willem
The values of
$object_typeare not documented but I found.postfor all post types,termfor all taxonomies.There might be other ‘objects’.
Skip to note 11 content
michielve
As of WordPress 4.9.8 you can use the
object_subtypeparameter to specify a custom post type. Previously you could only register for all post types. For example to register a meta keymy_metafor only themy_articlecustom post type:register_meta('post', 'my_meta', [ 'object_subtype' => 'my_article', 'show_in_rest' => true ]);Or you can use the new
register_post_metafunction.Skip to note 12 content
Thomas Patrick Levy
For custom meta fields to be returned in the REST API for a custom post type the REST API Handbook notes that the post type must support custom-fields in order for the registered meta field to display.
From the handbook:
“Note that for meta fields registered on custom post types, the post type must have custom-fields support. Otherwise the meta fields will not appear in the REST API.”
Source: https://developer.wordpress.org/rest-api/extending-the-rest-api/modifying-responses/#read-and-write-a-post-meta-field-in-post-responses
custom-fields, the values will NOT be saved to the database.Skip to note 13 content
Aniket Ashtikar
Prior to WordPress 5.5, the defaults for a custom meta field to be made available to the REST API could only be achieved like this:
(Consider registering a custom checkbox field for certain user input – for example, a post type title toggle)
register_meta( 'post', '_custom_meta_key', array( 'single' => true, 'type' => 'boolean', // or any valid data type 'show_in_rest' => array( 'schema' => array( 'type' => 'boolean', // Should match the expected data type 'default' => true, ), ), ) );With WordPress 5.5, this could be done with the additional argument
default, like this:register_meta( 'post', '_custom_meta_key', array( 'single' => true, 'type' => 'boolean', 'default' => true, // this is what really does the trick instead of supplying REST schema 'show_in_rest' => true, ) );Worth noting, this could really be helpful while extending block editor sidebar to make custom fields available via custom meta boxes. Setting default values for custom fields in the block editor is not straightforward, otherwise.
Skip to note 14 content
tharsheblows
As of WordPress 4.7, you can use the function as follows. This will be expanded in future versions.
$object_type = 'post'; // The object type. // For custom post types, this is 'post', for custom comment types, this is 'comment'. $args1 = array( 'type' => 'string', // Validate and sanitize the meta value as a string. // Default: 'string'. // In 4.7 one of 'string', 'boolean', 'integer', 'number' must be used as 'type'. 'description' => 'A meta key associated with a string meta value.', // Shown in the schema for the meta key. 'single' => true, // Return a single value of the type. Default: false. 'show_in_rest' => true, // Show in the WP REST API response. Default: false. ); register_meta( $object_type, 'my_postmeta_key', $args1 ); $args2 = array( 'type' => 'string', // Validate and sanitize the meta value as a string. 'description' => 'A meta key associated with a string meta value.', // Shown in the schema for the meta key. 'single' => false, // Return an array with the type used as the items type. Default: false. 'show_in_rest' => true, // Show in the WP REST API response. Default: false. ); register_meta( 'user', 'my_usermeta_key', $args2 );This will return the meta key and meta value in the meta object in the response. For example, an individual post response where id=8 and a meta key `my_postmeta_key` as registered above:
{ "id": 8, // the post id ... "meta": { "my_postmeta_key": "the meta value" }, ... }Skip to note 15 content
Barry Ceelen
Note that for the ‘show_in_rest’ argument to take effect, the post type should be registered with ‘custom-fields’ support.
Skip to note 16 content
martinkolle
auth_callbackandsanitize_callbackis callable with arguments.Auth callback is applied in
map_meta_cap()(wp-includes/capabilities.php).Sanitize callback is applied in
sanitize_meta()(wp-includes/meta.php).$status = register_meta( 'post', '_candidate_title', array( 'type' => 'string', 'description' => 'event location', 'object_subtype' => 'resume', 'single' => true, 'show_in_rest' => array( 'schema' => array( 'type' => 'string', 'default' => true ) ), 'auth_callback' => function( $allowed, $meta_key, $object_id, $user_id, $cap, $caps ) { return current_user_can( 'edit_resume', $object_id ); }, 'sanitize_callback' => function( $meta_value, $meta_key, $object_type, $object_subtype ) { return $meta_value; } ) );Skip to note 17 content
kitchin
In WP Core, `register_meta() ` is only used by `register_post_meta` and `register_term_meta() `, and otherwise none of these functions are used in Core.
Jetpack uses `register_post_meta() `, and `register_meta() ` for ‘post’ and ‘user’. So Jetpack has code samples to examine for their use.
Skip to note 18 content
Codex
Basic Example