Metadata元数据
meta数据
meta数据是关于信息的信息。对于 WordPress,它是与帖子、用户、评论和术语相关的信息。
鉴于 WordPress 中元数据的多对一关系,您的选择相当无限。您可以拥有任意数量的元选项,并且可以在其中存储几乎任何内容。
本章将讨论管理帖子元数据、创建自定义元框以及呈现帖子元数据。
管理帖子meta数据
添加元数据
使用add_post_meta()可以非常轻松地添加元数据。该函数接受 a post_id
、 a meta_key
、 ameta_value
和一个unique
标志。
这meta_key
就是您的插件在代码中其他地方引用元值的方式。类似的东西mycrazymetakeyname
可以工作,但是与您的插件或主题相关的前缀后面跟着密钥的描述会更有用。wporg_featured_menu
可能是一个很好的。应该注意的是,meta_key
可以多次使用相同的元数据来存储元数据的变体(参见下面的唯一标志)。
可以meta_value
是字符串、整数或数组。如果是数组,在存入数据库之前会自动序列化。
该unique
标志允许您声明该键是否应该是唯一的。非唯一键是指帖子可以有多种变体,例如价格。
如果您只想要一个帖子的一个价格,您应该标记它unique
,并且该帖子meta_key
将只有一个值。
更新元数据
如果密钥已存在并且您想要更新它,请使用update_post_meta()。如果您使用此函数并且密钥不存在,那么它将创建它,就像您使用了add_post_meta()一样。
与add_post_meta()类似,该函数接受 a post_id
、 ameta_key
和meta_value
。它还接受一个可选参数prev_value
- 如果指定,将导致该函数仅使用该值更新现有元数据条目。如果未提供,该函数默认更新所有条目。
删除元数据
delete_post_meta() 接受 a post_id
、 ameta_key
和可选的meta_value
。它的作用正如其名称所暗示的那样。
字符转义
后元值在存储时通过stripslashes()函数传递,因此在传递可能包含转义字符的值(例如 JSON)时需要小心。
考虑 JSON 值{"key":"value with \"escaped quotes\""}
:
$escaped_json = '{"key":"value with \"escaped quotes\""}';
update_post_meta( $id, 'escaped_json', $escaped_json );
$broken = get_post_meta( $id, 'escaped_json', true );
/*
$broken, after stripslashes(), ends up unparsable:
{"key":"value with "escaped quotes""}
*/
解决方法
通过使用函数wp_slash() (在 WP 3.6 中引入)添加一级转义,您可以补偿对stripslashes() 的调用:
$escaped_json = '{"key":"value with \"escaped quotes\""}';
update_post_meta( $id, 'double_escaped_json', wp_slash( $escaped_json ) );
$fixed = get_post_meta( $id, 'double_escaped_json', true );
/*
$fixed, after stripslashes(), ends up as desired:
{"key":"value with \"escaped quotes\""}
*/
隐藏的自定义字段
meta_key
如果您是插件或主题开发人员,并且计划使用自定义字段来存储参数,请务必注意,WordPress 不会在自定义字段列表中显示以“_”(下划线)开头的自定义字段。发布编辑屏幕或使用the_meta() 模板函数时。
这对于使用add_meta_box() 函数以不寻常的方式显示这些自定义字段非常有用。
下面的示例将添加一个名为meta_key
“_color”和meta_value
“red”的唯一自定义字段,但此自定义字段不会显示在帖子编辑屏幕中:
add_post_meta( 68, '_color', 'red', true );
隐藏数组
另外,如果是一个数组,即使您没有在名称前添加下划线meta_value
,它也不会显示在页面编辑屏幕上。meta_key
自定义meta元数据框
什么是元框?
当用户编辑帖子时,编辑屏幕由几个默认框组成:编辑器、发布、类别、标签等。这些框是元框。插件可以将自定义元框添加到任何帖子类型的编辑屏幕。
自定义元框的内容通常是 HTML 表单元素,用户在其中输入与插件用途相关的数据,但内容实际上可以是您想要的任何 HTML。
为什么使用元框?
元框是方便、灵活、模块化的编辑屏幕元素,可用于收集与正在编辑的帖子相关的信息。您的自定义元框将与所有其他帖子相关信息位于同一屏幕上;这样就建立了明确的关系。
元框可以轻松地对不需要查看的用户隐藏,并显示给需要查看的用户。用户可以在编辑屏幕上排列元框。用户可以自由地以适合自己的方式排列编辑屏幕,从而使用户可以控制自己的编辑环境。
添加元框
要创建元框,请使用add_meta_box() 函数并将其执行插入到add_meta_boxes
操作挂钩中。
以下示例是向post
编辑屏幕和wporg_cpt
编辑屏幕添加元框。
function wporg_add_custom_box() {
$screens = [ 'post', 'wporg_cpt' ];
foreach ( $screens as $screen ) {
add_meta_box(
'wporg_box_id', // Unique ID
'Custom Meta Box Title', // Box title
'wporg_custom_box_html', // Content callback, must be of type callable
$screen // Post type
);
}
}
add_action( 'add_meta_boxes', 'wporg_add_custom_box' );
该wporg_custom_box_html
函数将保存元框的 HTML。
以下示例添加表单元素、标签和其他 HTML 元素。
function wporg_custom_box_html( $post ) {
?>
<label for="wporg_field">Description for this field</label>
<select name="wporg_field" id="wporg_field" class="postbox">
<option value="">Select something...</option>
<option value="something">Something</option>
<option value="else">Else</option>
</select>
<?php
}
笔记:请注意,元框中没有提交按钮。POST
元框 HTML 包含在编辑屏幕的表单标签内,当用户单击“发布”或“更新”按钮时,包括元框值在内的所有发布数据都会传输。
此处显示的示例仅包含一个表单字段,即一个下拉列表。您可以根据需要在任何特定元框中创建任意数量的元数据。如果您有很多字段要显示,请考虑使用多个元框,将每个元框中相似的字段分组在一起。这有助于使页面更有条理、更具视觉吸引力。
获取值
要检索保存的用户数据并使用它,您需要从最初保存它的位置获取它。如果它存储在表中,您可以使用get_post_meta()postmeta
获取数据。
以下示例使用基于保存的元框值的预填充数据增强了先前的表单元素。您将在下一节中了解如何保存元框值。
function wporg_custom_box_html( $post ) {
$value = get_post_meta( $post->ID, '_wporg_meta_key', true );
?>
<label for="wporg_field">Description for this field</label>
<select name="wporg_field" id="wporg_field" class="postbox">
<option value="">Select something...</option>
<option value="something" <?php selected( $value, 'something' ); ?>>Something</option>
<option value="else" <?php selected( $value, 'else' ); ?>>Else</option>
</select>
<?php
}
有关selected() 函数的更多信息。
保存价值
保存或更新帖子类型时,会触发多个操作,其中任何操作都可能适合挂钩以保存输入的值。在此示例中,我们使用save_post
操作挂钩,但其他挂钩可能更适合某些情况。请注意,save_post
对于单个更新事件可能会多次触发。相应地构建保存数据的方法。
您可以将输入的数据保存在任何您想要的地方,甚至可以在 WordPress 之外保存。由于您可能正在处理与帖子相关的数据,因此表postmeta
通常是存储数据的好地方。
以下示例将wporg_field
在_wporg_meta_key
元键中保存字段值,该元键是隐藏的。
function wporg_save_postdata( $post_id ) {
if ( array_key_exists( 'wporg_field', $_POST ) ) {
update_post_meta(
$post_id,
'_wporg_meta_key',
$_POST['wporg_field']
);
}
}
add_action( 'save_post', 'wporg_save_postdata' );
在生产代码中,请记住遵循信息框中概述的安全措施!
幕后花絮
您通常不需要关心幕后发生的事情。添加此部分是为了完整性。
当帖子编辑屏幕想要显示添加到其中的所有元框时,它会调用 do_meta_boxes () 函数。该函数循环遍历所有元框并调用callback
与每个元框关联的元框。
在每次调用之间,添加中间标记(例如 div、标题等)。
删除元框
要从编辑屏幕中删除现有元框,请使用remove_meta_box() 函数。传递的参数必须与用于使用add_meta_box()添加元框的参数完全匹配。
要删除默认元框,请检查所使用参数的源代码。默认的add_meta_box() 调用是从wp-includes/edit-form-advanced.php
.
实施变体
到目前为止,我们一直在使用实现元框的程序技术。许多插件开发人员发现需要使用各种其他技术来实现元框。
面向对象编程
使用 OOP 添加元框很容易,并且使您不必担心全局命名空间中的命名冲突。
为了节省内存并更容易实现,以下示例使用具有静态方法的抽象类。
abstract class WPOrg_Meta_Box {
/**
* Set up and add the meta box.
*/
public static function add() {
$screens = [ 'post', 'wporg_cpt' ];
foreach ( $screens as $screen ) {
add_meta_box(
'wporg_box_id', // Unique ID
'Custom Meta Box Title', // Box title
[ self::class, 'html' ], // Content callback, must be of type callable
$screen // Post type
);
}
}
/**
* Save the meta box selections.
*
* @param int $post_id The post ID.
*/
public static function save( int $post_id ) {
if ( array_key_exists( 'wporg_field', $_POST ) ) {
update_post_meta(
$post_id,
'_wporg_meta_key',
$_POST['wporg_field']
);
}
}
/**
* Display the meta box HTML to the user.
*
* @param WP_Post $post Post object.
*/
public static function html( $post ) {
$value = get_post_meta( $post->ID, '_wporg_meta_key', true );
?>
<label for="wporg_field">Description for this field</label>
<select name="wporg_field" id="wporg_field" class="postbox">
<option value="">Select something...</option>
<option value="something" <?php selected( $value, 'something' ); ?>>Something</option>
<option value="else" <?php selected( $value, 'else' ); ?>>Else</option>
</select>
<?php
}
}
add_action( 'add_meta_boxes', [ 'WPOrg_Meta_Box', 'add' ] );
add_action( 'save_post', [ 'WPOrg_Meta_Box', 'save' ] );
Ajax
由于元框的 HTML 元素位于form
编辑屏幕的标签内,因此默认行为是在用户提交页面后$_POST
从超级全局解析元框值。
您可以使用 AJAX 增强默认体验;这允许根据用户输入和行为执行操作;无论他们是否提交了页面。
定义触发器
首先,您必须定义触发器,这可以是链接单击、值更改或任何其他 JavaScript 事件。
在下面的示例中,我们将定义change
为执行 AJAX 请求的触发器。
/*jslint browser: true, plusplus: true */
(function ($, window, document) {
'use strict';
// execute when the DOM is ready
$(document).ready(function () {
// js 'change' event triggered on the wporg_field form field
$('#wporg_field').on('change', function () {
// our code
});
});
}(jQuery, window, document));
客户端代码
接下来,我们需要定义触发器要做什么,换句话说,我们需要编写客户端代码。
在下面的示例中,我们将发出POST
请求,响应将是成功或失败,这将表明 的值wporg_field
是有效的。
/*jslint browser: true, plusplus: true */
(function ($, window, document) {
'use strict';
// execute when the DOM is ready
$(document).ready(function () {
// js 'change' event triggered on the wporg_field form field
$('#wporg_field').on('change', function () {
// jQuery post method, a shorthand for $.ajax with POST
$.post(wporg_meta_box_obj.url, // or ajaxurl
{
action: 'wporg_ajax_change', // POST data, action
wporg_field_value: $('#wporg_field').val(), // POST data, wporg_field_value
post_ID: jQuery('#post_ID').val() // The ID of the post currently being edited
}, function (data) {
// handle response data
if (data === 'success') {
// perform our success logic
} else if (data === 'failure') {
// perform our failure logic
} else {
// do nothing
}
}
);
});
});
}(jQuery, window, document));
wporg_meta_box_obj
我们从下一步将创建的 JavaScript 自定义对象动态获取 WordPress AJAX 文件 URL 。
笔记:如果您的元框仅需要 WordPress AJAX 文件 URL;您可以使用预定义的 JavaScript 变量,而不是创建新的自定义 JavaScript 对象ajaxurl
。
仅在 WordPress 管理中可用。在执行任何逻辑之前确保它不为空。
排队客户端代码
下一步是将我们的代码放入脚本文件中并将其排队到我们的编辑屏幕上。
在下面的示例中,我们将向以下帖子类型的编辑屏幕添加 AJAX 功能:post、wporg_cpt。
脚本文件将驻留在/plugin-name/admin/meta-boxes/js/admin.js
主plugin-name
插件文件夹中,即/plugin-name/plugin.php
调用该函数的文件。
function wporg_meta_box_scripts()
{
// get current admin screen, or null
$screen = get_current_screen();
// verify admin screen object
if (is_object($screen)) {
// enqueue only for specific post types
if (in_array($screen->post_type, ['post', 'wporg_cpt'])) {
// enqueue script
wp_enqueue_script('wporg_meta_box_script', plugin_dir_url(__FILE__) . 'admin/meta-boxes/js/admin.js', ['jquery']);
// localize script, create a custom js object
wp_localize_script(
'wporg_meta_box_script',
'wporg_meta_box_obj',
[
'url' => admin_url('admin-ajax.php'),
]
);
}
}
}
add_action('admin_enqueue_scripts', 'wporg_meta_box_scripts');
服务器端代码
最后一步是编写将处理请求的服务器端代码。
// The piece after `wp_ajax_` matches the action argument being sent in the POST request.
add_action( 'wp_ajax_wporg_ajax_change', 'my_ajax_handler' );
/**
* Handles my AJAX request.
*/
function my_ajax_handler() {
// Handle the ajax request here
if ( array_key_exists( 'wporg_field_value', $_POST ) ) {
$post_id = (int) $_POST['post_ID'];
if ( current_user_can( 'edit_post', $post_id ) ) {
update_post_meta(
$post_id,
'_wporg_meta_key',
$_POST['wporg_field_value']
);
}
}
wp_die(); // All ajax handlers die when finished
}
最后提醒一下,本页所示的代码缺少考虑安全性的重要操作。确保您的生产代码包含此类操作。
有关 AJAX 的更多信息,请参阅手册的 AJAX 章节和Codex 。
更多信息
渲染后meta data元数据
以下是用于获取和呈现帖子元数据的函数和模板标签的非详尽列表:
- the_meta() – 自动列出帖子的所有自定义字段的模板标签
- get_post_custom() 和get_post_meta() – 检索帖子的一个或所有元数据。
- get_post_custom_values() – 检索自定义帖子字段的值。