Step1:注册Meta Box
首先,你需要使用add_meta_boxes钩子(hook)来注册一个meta_box。将以下代码添加到你的功能性插件或主题的functions.php文件中。
function my_custom_meta_box() {
add_meta_box(
'my_meta_box_id', // Unique ID
__('My Custom Meta Box'), // Box title
'my_meta_box_html', // Content callback, must be of type callable
'post' // Post type
);
}
add_action('add_meta_boxes', 'my_custom_meta_box');
Step 2: 创建 Meta Box 内容
编写用于显示meta_box内容的回调函数。这个函数负责输出任何表单元素,用户会在此输入数据。
function my_meta_box_html($post) {
// Add a nonce field so we can check for it later.
wp_nonce_field('my_meta_box_nonce', 'meta_box_nonce');
// 获取现存的值从数据库
$value = get_post_meta($post->ID, '_my_meta_value_key', true);
// 输出字段
echo '<label for="my_meta_box_input"\>Description</label>';
echo '<input type="text" id="my_meta_box_input" name="my_meta_box_input" value="' . esc_attr($value) . '" />';
}
Step 3: 加载样式表和脚本
function enqueue_admin_style_for_price($hook) {
global $typenow;
// ↓Post Type作为条件
if ('post' === $typenow && ('post.php' == $hook || 'post-new.php' == $hook)) {
// 使用正确的路径注册你的样式表。
wp_register_style('price_wp_admin_css', get_stylesheet_directory_uri() . '/css/admin-price.css', false, version_num());
// 排队你的样式表。
wp_enqueue_style('price_wp_admin_css');
// 使用正确的路径注册你的脚本文件。
wp_register_script('price_wp_admin_js', get_stylesheet_directory_uri() . '/js/admin-price.js', array('jquery'), version_num(), true);
// 排队你的脚本文件。
wp_enqueue_script('price_wp_admin_js');
}
}
// 添加到WordPress的'admin_enqueue_scripts'动作。
add_action('admin_enqueue_scripts', 'enqueue_admin_style_for_price');
Step 4: 保存 Meta Box 数据
function my_save_meta_box_data($post_id) {
// 检查nonce安全性验证
if (!isset($_POST['meta_box_nonce']) || !wp_verify_nonce($_POST['meta_box_nonce'], 'my_meta_box_nonce')) {
return;
}
// 检查这次提交是否不是自动保存的草稿.
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
// 检查用户权限
if (!current_user_can('edit_post', $post_id)) {
return;
}
// 确保有数据被发送.
if (!isset($_POST['my_meta_box_input'])) {
return;
}
// 清理输入数据并保存它
$my_data = sanitize_text_field($_POST['my_meta_box_input']);
update_post_meta($post_id, '_my_meta_value_key', $my_data);
}
add_action('save_post', 'my_save_meta_box_data');
以上代码提供了在WordPress中创建和使用meta_boxes的基本框架。你可以通过注册具有不同字段类型的meta_box,比如下拉菜单、图片上传器、颜色选取器等,为你的帖子类型添加更多自定义数据字段。
确保所有自定义字段的名称都是唯一的,而且保存数据时进行了适当的权限检查和数据清洗,以避免安全漏洞。
如果my_meta_box_input是一个数组,你需要更改两个地方的代码:HTML表单元素的显示和数据保存逻辑。这里是如何修改上述示例的:
Step 2: 修改回调函数以显示数组类型的字段
如果你有多个输入字段或者一个字段接收多值,确保每个元素的name属性以数组形式命名,例如name=”my_meta_box_input[]”。
function my_meta_box_html($post) {
// Add a nonce field so we can check for it later.
wp_nonce_field('my_meta_box_nonce', 'meta_box_nonce');
// 获取现存的值从数据库
$values = get_post_meta($post->ID, '_my_meta_value_key', true);
if (!is_array($values)) {
$values = array();
}
// 输出字段
foreach ($values as $index => $value) {
echo '<label for="my_meta_box_input_' . $index . '">Description</label>';
echo '<input type="text" id="my_meta_box_input_' . $index . '" name="my_meta_box_input[]" value="' . esc_attr($value) . '" />';
}
// 添加一个按钮用来添加新的输入框(可用JavaScript实现)
echo '<button id="add_new_input">Add New</button>';
// 务必也为上面的按钮添加 JavaScript 脚本以便能动态添加新的输入桜
}
Step 4: 修改保存逻辑来处理数组
在保存时,你需要对$_POST[‘my_meta_box_input’]做一个循环操作,以遍历所有的值。然后对每个值进行清理并保存。
function my_save_meta_box_data($post_id) {
// 省略安全检查和权限检查代码...
// 确保有数据被发送.
if (isset($_POST['my_meta_box_input']) && is_array($_POST['my_meta_box_input'])) {
// 清理输入数据
$my_data = array_map('sanitize_text_field', $_POST['my_meta_box_input']);
// 保存它
update_post_meta($post_id, '_my_meta_value_key', $my_data);
} else {
// 如果没有接收到数据或者不是期待的数组,则删除meta key
delete_post_meta($post_id, '_my_meta_value_key');
}
}
add_action('save_post', 'my_save_meta_box_data');
要注意,update_post_meta()函数在处理单一键值对时会自动序列化和反序列化数组数据。因此,在保存一个数组时不需要额外的序列化步锤。
此外,在实际应用中,你可能还需要考虑添加和删除字段的用户界面逻辑,典型情况下使用JavaScript来动态增加或移除输入框。
技巧
Step2中使用了get_post_meta方法获得当前POST的meta数据,如果当前POST有多种类的meta情报的话,如果只想获得某个特定种类的meta数据的话,这个方法就不太适用了。
可以使用SQL文的方式获取你想要的meta数据。
function getPostMeta($post_id, $meta_key_pattern) {
global $wpdb;
$query = "SELECT meta_key, meta_value FROM {$wpdb->postmeta} WHERE post_id = {$post_id} and meta_key LIKE '{$meta_key_pattern}'";
$results = $wpdb->get_results($query, ARRAY_A);
$key_value_pairs = array();
foreach ( $results as $row ) {
$key_value_pairs[$row['meta_key']] = maybe_unserialize($row['meta_value']);
}
return $key_value_pairs;
}
批量删除特定的meta
function deletePriceMeta($post_id, $meta_key_pattern) {
global $wpdb;
$query = "SELECT DISTINCT meta_key FROM {$wpdb->postmeta} WHERE post_id = {$post_id} and meta_key LIKE '{$meta_key_pattern}'";
$meta_keys = $wpdb->get_col($query);
if (!empty($meta_keys)) {
foreach ($meta_keys as $meta_key) {
delete_post_meta($post_id, $meta_key);
}
}
}