参数
- $id
-
(string)(必填) meta box ID(在元组框的'id'属性中使用)。
- $title
-
(string)(必填) 元组框的标题。
- $callback
-
(callable)(必填) 用所需内容填充box的函数。函数应该回显其输出。
- $screen
-
(string|array|WP_Screen)(可选) 显示box的一个或多个屏幕(如文章类型,'link',或'comment')。接受单个屏幕ID、WP_Screen对象或屏幕ID数组。默认为当前屏幕。如果您使用add_menu_page()或add_submenu_page()创建了新屏幕(screen_id),请确保您的菜单段符合sanitize_key()的限制,否则'screen'菜单可能无法在页面上正确呈现。
默认值: null
- $context
-
(string)(可选) 屏幕中box显示的上下文。可用的上下文因屏幕而异。文章编辑屏幕上下文包括'normal'、'side'和'advanced'。评论屏幕上下文包括'normal'和'side'。菜单元组框(手风琴部分)都使用'side'上下文。全局
默认值: 'advanced'
- $priority
-
(string)(可选) box显示的上下文中的优先级。接受'high'、'core'、'default'或'low'。
默认值: 'default'
- $callback_args
-
(array)(可选) 应设置为box数组的$args属性的数据(这是传递给回调的第二个参数)。
默认值: null
源码
更新日志
版本 | 描述 |
---|---|
4.4.0 | $screen 参数现在接受屏幕ID数组。 |
2.5.0 | 开始引入 |
使用示例
类
这是一个如何从类内部添加元组框的示例/** * Calls the class on the post edit screen. */ function call_someClass() { new someClass(); } if ( is_admin() ) { add_action( 'load-post.php', 'call_someClass' ); add_action( 'load-post-new.php', 'call_someClass' ); } /** * The Class. */ class someClass { /** * Hook into the appropriate actions when the class is constructed. */ public function __construct() { add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) ); add_action( 'save_post', array( $this, 'save' ) ); } /** * Adds the meta box container. */ public function add_meta_box( $post_type ) { // Limit meta box to certain post types. $post_types = array( 'post', 'page' ); if ( in_array( $post_type, $post_types ) ) { add_meta_box( 'some_meta_box_name', __( 'Some Meta Box Headline', 'textdomain' ), array( $this, 'render_meta_box_content' ), $post_type, 'advanced', 'high' ); } } /** * Save the meta when the post is saved. * * @param int $post_id The ID of the post being saved. */ public function save( $post_id ) { /* * We need to verify this came from the our screen and with proper authorization, * because save_post can be triggered at other times. */ // Check if our nonce is set. if ( ! isset( $_POST['myplugin_inner_custom_box_nonce'] ) ) { return $post_id; } $nonce = $_POST['myplugin_inner_custom_box_nonce']; // Verify that the nonce is valid. if ( ! wp_verify_nonce( $nonce, 'myplugin_inner_custom_box' ) ) { return $post_id; } /* * 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 $post_id; } // Check the user's permissions. if ( 'page' == $_POST['post_type'] ) { if ( ! current_user_can( 'edit_page', $post_id ) ) { return $post_id; } } else { if ( ! current_user_can( 'edit_post', $post_id ) ) { return $post_id; } } /* OK, it's safe for us to save the data now. */ // Sanitize the user input. $mydata = sanitize_text_field( $_POST['myplugin_new_field'] ); // Update the meta field. update_post_meta( $post_id, '_my_meta_value_key', $mydata ); } /** * Render Meta Box content. * * @param WP_Post $post The post object. */ public function render_meta_box_content( $post ) { // Add an nonce field so we can check for it later. wp_nonce_field( 'myplugin_inner_custom_box', 'myplugin_inner_custom_box_nonce' ); // Use get_post_meta to retrieve an existing value from the database. $value = get_post_meta( $post->ID, '_my_meta_value_key', true ); // Display the form, using the current value. ?> <label for="myplugin_new_field"> <?php _e( 'Description for this field', 'textdomain' ); ?> </label> <input type="text" id="myplugin_new_field" name="myplugin_new_field" value="<?php echo esc_attr( $value ); ?>" size="25" /> <?php } }
/** * Register meta box(es). */ function wpdocs_register_meta_boxes() { add_meta_box( 'meta-box-id', __( 'My Meta Box', 'textdomain' ), 'wpdocs_my_display_callback', 'post' ); } add_action( 'add_meta_boxes', 'wpdocs_register_meta_boxes' ); /** * Meta box display callback. * * @param WP_Post $post Current post object. */ function wpdocs_my_display_callback( $post ) { // Display code/markup goes here. Don't forget to include nonces! } /** * Save meta box content. * * @param int $post_id Post ID */ function wpdocs_save_meta_box( $post_id ) { // Save logic goes here. Don't forget to include nonce checks! } add_action( 'save_post', 'wpdocs_save_meta_box' );
/** * Register a meta box using a class. */ class WPDocs_Custom_Meta_Box { /** * Constructor. */ public function __construct() { if ( is_admin() ) { add_action( 'load-post.php', array( $this, 'init_metabox' ) ); add_action( 'load-post-new.php', array( $this, 'init_metabox' ) ); } } /** * Meta box initialization. */ public function init_metabox() { add_action( 'add_meta_boxes', array( $this, 'add_metabox' ) ); add_action( 'save_post', array( $this, 'save_metabox' ), 10, 2 ); } /** * Adds the meta box. */ public function add_metabox() { add_meta_box( 'my-meta-box', __( 'My Meta Box', 'textdomain' ), array( $this, 'render_metabox' ), 'post', 'advanced', 'default' ); } /** * Renders the meta box. */ public function render_metabox( $post ) { // Add nonce for security and authentication. wp_nonce_field( 'custom_nonce_action', 'custom_nonce' ); } /** * Handles saving the meta box. * * @param int $post_id Post ID. * @param WP_Post $post Post object. * @return null */ public function save_metabox( $post_id, $post ) { // Add nonce for security and authentication. $nonce_name = isset( $_POST['custom_nonce'] ) ? $_POST['custom_nonce'] : ''; $nonce_action = 'custom_nonce_action'; // Check if nonce is valid. if ( ! wp_verify_nonce( $nonce_name, $nonce_action ) ) { return; } // Check if user has permissions to save data. if ( ! current_user_can( 'edit_post', $post_id ) ) { return; } // Check if not an autosave. if ( wp_is_post_autosave( $post_id ) ) { return; } // Check if not a revision. if ( wp_is_post_revision( $post_id ) ) { return; } } } new WPDocs_Custom_Meta_Box();
回调参数
$callback_args
数组将作为第二个参数传递给回调函数。第一个参数是post的$post
对象。/** * This function adds a meta box with a callback function of my_metabox_callback() */ function add_wpdocs_meta_box() { $var1 = 'this'; $var2 = 'that'; add_meta_box( 'metabox_id', __( 'Metabox Title', 'textdomain' ), 'wpdocs_metabox_callback', 'page', 'normal', 'low', array( 'foo' => $var1, 'bar' => $var2 ) ); } /** * Get post meta in a callback * * @param WP_Post $post The current post. * @param array $metabox With metabox id, title, callback, and args elements. */ function wpdocs_metabox_callback( $post, $metabox ) { // Output last time the post was modified. echo 'Last Modified: ' . $post->post_modified; // Output 'this'. echo $metabox['args']['foo']; // Output 'that'. echo $metabox['args']['bar']; // Output value of custom field. echo get_post_meta( $post->ID, 'wpdocs_custom_field', true ); }
这是注册菜单屏幕元组框的方法:)
function op_register_menu_meta_box() { add_meta_box( 'op-menu-meta-box-id', esc_html__( 'Op Menu MetaBox Title', 'text-domain' ), 'op_render_menu_meta_box', 'nav-menus', 'side', 'core' ); } add_action( 'load-nav-menus.php', 'op_register_menu_meta_box' ); function op_render_menu_meta_box() { // Metabox content echo '<strong>Hi, I am MetaBox.</strong>'; }
在我看来,此页面应该引用$callback_args的‘__block_editor_compatible_meta_box’和‘__back_compat_meta_box’选项,如此文所述:https://make.wordpress.org/core/2018/11/07/meta-box-compatibility-flags/
一个经常被遗忘但也是非常重要的事实是,任何
save_post
处理程序都应该检查多站点切换上下文。以下是此类防护的一个示例:<?php namespace DevWpNote\MetaBox; add_action( 'save_post', __NAMESPACE_ . '\save_fields', 10, 3 ); function save_fields( $post_id, WP_Post $post, $update ) { // check nonce ... // check autosave ... // check user capabilities ... // check if there was a multisite switch before if ( is_multisite() && ms_is_switched() ) { return $post_id; } // handle your meta box input ... }
这确保了与使用
switch_to_blog()
的其他插件在save_post
钩子上工作时的兼容性。如果他们在其他站点上再次调用wp_insert_post()
,则您的代码将在没有此检查的情况下覆盖错误的内容。//Register Meta Box function rm_register_meta_box() { add_meta_box( 'rm-meta-box-id', esc_html__( 'RM MetaBox Title', 'text-domain' ), 'rm_meta_box_callback', 'post', 'advanced', 'high' ); } add_action( 'add_meta_boxes', 'rm_register_meta_box'); //Add field function rm_meta_box_callback( $meta_id ) { $outline = '<label for="title_field" style="width:150px; display:inline-block;">'. esc_html__('Title Field', 'text-domain') .'</label>'; $title_field = get_post_meta( $meta_id->ID, 'title_field', true ); $outline .= '<input type="text" name="title_field" id="title_field" class="title_field" value="'. esc_attr($title_field) .'" style="width:300px;"/>'; echo $outline; }
例子:
//Register Meta box add_action( 'add_meta_boxes', function() { add_meta_box( 'wpdocs-id', 'Social link', 'wpdocs_field_cb', 'post', 'side' ); } ); //Meta callback function function wpdocs_field_cb( $post ) { $wpdocs_meta_val = get_post_meta( $post->ID, 'wpdocs-meta-name', true ); ?> <input type="url" name="wpdocs-meta-name" value="<?php echo esc_attr( $wpdocs_meta_val ) ?>"> <?php } //save meta value with save post hook add_action( 'save_post', function( $post_id ) { if ( isset( $_POST['wpdocs-meta-name'] ) ) { update_post_meta( $post_id, 'wpdocs-meta-name', $_POST['wpdocs-meta-name'] ); } } ); // show meta value after post content add_filter( 'the_content', function( $content ) { $meta_val = get_post_meta( get_the_ID(), 'wpdocs-meta-name', true ); return $content . $meta_val; } );
这是在
save_post
操作中应如何处理metabox数据。function save_metabox_callback( $post_id ) { if ( ! isset( $_POST['nonce'] ) ) { return; } if ( ! wp_verify_nonce( $_POST['nonce'], 'nonce_value' ) ) { return; } if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { return; } if ( ! current_user_can( 'edit_post', $post_id ) ) { return; } if ( isset( $_POST['post_type'] ) && 'page' === $_POST['post_type'] ) { // do stuff } // Check if $_POST field(s) are available // Sanitize // Save } add_action( 'save_post', 'save_metabox_callback' );
不仅需要第二个参数
$title
。如果$title
是空字符串或字符串"0"
,则不会呈现元组框。metabox中的评论有点问题
如果你需要在评论编辑界面添加一个metabox,你必须为$context参数传入'normal'值。
// This will NOT work add_meta_box( 'my_comment_metabox_1', // ID __('My comment metabox 1' ), // Title 'prefix_comment_metabox', // Callback 'comment' // Screen ); // This WILL work. Same call, but with 'normal' for context instead of default 'advanced' add_meta_box( 'my_comment_metabox_2', // ID __('My comment metabox 2' ), // Title 'prefix_comment_metabox', // Callback 'comment', // Screen 'normal' // Context );
这是一个如何使用textarea从类内部添加元组框的示例。用自定义文章类型名称替换选项卡文章类型。
/** * The Class. */ class someClass { /** * Hook into the appropriate actions when the class is constructed. */ public function __construct() { add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) ); add_action( 'save_post', array( $this, 'save' ) ); } /** * Adds the meta box container. */ public function add_meta_box( $post_type ) { // Limit meta box to certain post types. $post_types = array('tabs' ); if ( in_array( $post_type, $post_types ) ) { add_meta_box( 'some_meta_box_name', __( 'Some Meta Box Headline', 'textdomain' ), array( $this, 'render_meta_box_content' ), $post_type, 'advanced', 'high' ); } } /** * Save the meta when the post is saved. * * @param int $post_id The ID of the post being saved. */ public function save( $post_id ) { /* * We need to verify this came from the our screen and with proper authorization, * because save_post can be triggered at other times. */ // Check if our nonce is set. if ( ! isset( $_POST['myplugin_inner_custom_box_nonce'] ) ) { return $post_id; } $nonce = $_POST['myplugin_inner_custom_box_nonce']; // Verify that the nonce is valid. if ( ! wp_verify_nonce( $nonce, 'myplugin_inner_custom_box' ) ) { return $post_id; } /* * 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 $post_id; } // Check the user's permissions. if ( 'page' == $_POST['post_type'] ) { if ( ! current_user_can( 'edit_page', $post_id ) ) { return $post_id; } } else { if ( ! current_user_can( 'edit_post', $post_id ) ) { return $post_id; } } /* OK, it's safe for us to save the data now. */ // Sanitize the user input. $mydata = sanitize_text_field( $_POST['myplugin_new_field'] ); // Update the meta field. update_post_meta( $post_id, '_my_meta_value_key', $mydata ); } /** * Render Meta Box content. * * @param WP_Post $post The post object. */ public function render_meta_box_content( $post ) { // Add an nonce field so we can check for it later. wp_nonce_field( 'myplugin_inner_custom_box', 'myplugin_inner_custom_box_nonce' ); // Use get_post_meta to retrieve an existing value from the database. $value = get_post_meta( $post->ID, '_my_meta_value_key', true ); // Display the form, using the current value. ?> <label for="myplugin_new_field"> <?php _e( 'Description for this field', 'textdomain' ); ?> </label> <textarea style="width:100%;min-height:200px;" type="textarea" class="form-control" name="myplugin_new_field" ><?php echo esc_attr( $value ); ?></textarea> <?php } }
如何在自定义文章类型中添加metabox:
class Register_Post_Type { /** * Register_Post_Type constructor. */ public function __construct() { add_action( "init", array( $this, "register_post_type" ) ); add_action( "add_meta_boxes", array( $this, "add_mata_box" ) ); add_action( "save_post", array( $this, "save_mata_date" ) ); } /** * Register post type */ public function register_post_type() { register_post_type( "newsletter", array( "labels" => array( "name" => esc_html( "Newsletter", "newsletter" ), "singular_name" => esc_html( "Newsletter", "newsletter" ), 'menu_name' => esc_html( "Newsletter", "newsletter" ), 'name_admin_bar' => esc_html( "Newsletter", "newsletter" ), 'add_new' => esc_html( "Add Newsletter", "newsletter" ), 'add_new_item' => esc_html( "Add Newsletter", "newsletter" ), 'new_item' => esc_html( "New Newsletter", "newsletter" ), 'edit_item' => esc_html( "Edit Newsletter", "newsletter" ), 'view_item' => esc_html( "View Newsletter", "newsletter" ), 'all_items' => esc_html( "All Newsletter", "newsletter" ), 'search_items' => esc_html( "Search Newsletter", "newsletter" ), 'not_found' => esc_html( "No news found.", "newsletter" ), 'featured_image' => esc_html( "Newsletter Cover Image", "newsletter" ), 'set_featured_image' => esc_html( "Set newsletter image", "newsletter" ), ), "public" => true, "has_archive" => false, "rewrite" => array( "slug" => "newsletter" ), 'menu_icon' => 'dashicons-book', //'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' ), 'supports' => array( 'title','editor','thumbnail' ), ) ); } /** * Add post mata box */ public function add_mata_box() { add_meta_box( "newsletter_main_post", esc_html( "Add article", "newsletter" ), array( $this, "add_article_html" ), "newsletter", 'advanced' ); } /** * Add article html */ public function add_article_html() { ?> <?php } /** * Save mata data */ public function save_mata_date( $post_id ) { update_post_meta( $post_id, "add_article_main", array( "adf", "bfdf" ) ); } }
对多个post_type使用相同的元组框
/** * Register Metabox */ function prefix_add_meta_boxes(){ add_meta_box( 'unique_mb_id', __( 'Metabox Title','text-domain' ),'prefix_mb_callback', ['page', 'post'] ); } add_action('add_meta_boxes', 'prefix_add_meta_boxes' ); /** * Meta field callback function */ function prefix_mb_callback(){ ?> <label for="mb_id"><?php echo esc_html('Field Label','text-domain'); ?></label> <input type="text" class="regular-text" name="unique_mb_id" id="mb_id"> <?php }
从WordPress 4.4开始,$screen参数可以是一个数组,这大大简化了meta box的大量添加或更改。以下代码将页面、文章、附件和所有自定义文章类型上的“作者”meta box的标题更改为“编辑器”,无论添加了多少或何时添加到站点。
add_action( 'do_meta_boxes', 'my_customize_meta_boxes'); //do_meta_boxes also allows plugin metaboxes to be modified function my_customize_meta_boxes(){ $post_types = get_post_types(); remove_meta_box( 'authordiv', $post_types, 'normal' ); add_meta_box( 'authordiv', __( 'Editor', 'textdomain' ), 'post_author_meta_box', $post_types, 'side', 'default' ); }
很抱歉,未找到任何编辑选项。最后一个函数应声明为静态函数:
static public function wpdocs_register_meta_boxes_static() { add_meta_box( 'meta-box-id', __( 'My Meta Box', 'textdomain' ), 'wpdocs_my_display_callback', 'post' ); }
这是在类中调用它的方式:
class MyClass{ public function __construct() { add_action( 'add_meta_boxes', array( &$this, 'wpdocs_register_meta_boxes' ) ); // If static add_action( 'add_meta_boxes', array( __CLASS__, 'wpdocs_register_meta_boxes_static' ) ); } // Singleton static function get_instance() { static $Inst = null; if( $Inst == null ) { $Inst = new self(); } return $Inst; } public function wpdocs_register_meta_boxes() { add_meta_box( 'meta-box-id', __( 'My Meta Box', 'textdomain' ), 'wpdocs_my_display_callback', 'post' ); } public function wpdocs_register_meta_boxes_static() { add_meta_box( 'meta-box-id', __( 'My Meta Box', 'textdomain' ), 'wpdocs_my_display_callback', 'post' ); } } MyClass::get_instance();
函数调用中有$screen=null,但如果为null,则没有检查和平衡。打开错误日志记录时,这会导致错误警告。
function add_meta_box( $id, $title, $callback, $screen = null, $context = 'advanced', $priority = 'default', $callback_args = null ) { global $wp_meta_boxes; if ( empty( $screen ) ) { $screen = get_current_screen(); } elseif ( is_string( $screen ) ) { $screen = convert_to_screen( $screen ); } elseif ( is_array( $screen ) ) { foreach ( $screen as $single_screen ) { add_meta_box( $id, $title, $callback, $single_screen, $context, $priority, $callback_args ); } } if ( ! isset( $screen->id ) ) { return; } $page = $screen->id; …
应替换为..
function add_meta_box( $id, $title, $callback, $screen = null, $context = 'advanced', $priority = 'default', $callback_args = null ) { global $wp_meta_boxes; if ( $screen == null ) { $screen = WP_Screen::get( ); } elseif ( empty( $screen ) ) { $screen = get_current_screen(); } elseif ( is_string( $screen ) ) { $screen = convert_to_screen( $screen ); } elseif ( is_array( $screen ) ) { foreach ( $screen as $single_screen ) { add_meta_box( $id, $title, $callback, $single_screen, $context, $priority, $callback_args ); } } $page = $screen->id; …
不是
if ( ! isset( $screen->id ) ) { return; }
依我拙见
最好的
设计是Drumm