当前浏览:首页 / WordPress函数 / add_meta_box()

add_meta_box( string $id, string $title, callable $callback, string|array|WP_Screen $screen = null, string $context = 'advanced', string $priority = 'default', array $callback_args = null )

将meta组框添加到一个或多个屏幕

addmore...

meta_box meta组框


参数

$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开始引入

使用示例

  • 示例1


    这是一个如何从类内部添加元组框的示例

    /**
     * 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
    	}
    }
    
  • 示例2
    /**
     * 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' );
    
  • 示例3
    /**
     * 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();
    
  • 示例4

    回调参数

    $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 );
    }
    
  • 示例5

    这是注册菜单屏幕元组框的方法:)

    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>';
    }
    
  • 示例6

    在我看来,此页面应该引用$callback_args的‘__block_editor_compatible_meta_box’和‘__back_compat_meta_box’选项,如此文所述:https://make.wordpress.org/core/2018/11/07/meta-box-compatibility-flags/

  • 示例7

    一个经常被遗忘但也是非常重要的事实是,任何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(),则您的代码将在没有此检查的情况下覆盖错误的内容。

  • 示例8
    //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;
    }
  • 示例9

    例子:

    //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;
    } );
    
  • 示例10

    这是在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' );
    
  • 示例11

    不仅需要第二个参数$title。如果$title是空字符串或字符串"0",则不会呈现元组框。

  • 示例12

    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
    );
    
    
  • 示例13

    这是一个如何使用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
        }
    }
  • 示例14

    如何在自定义文章类型中添加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" ) );
        }
    }
  • 示例15

    对多个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 }
    
  • 示例16

    从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' );
    }
    
  • 示例17

    很抱歉,未找到任何编辑选项。最后一个函数应声明为静态函数:

    static public function wpdocs_register_meta_boxes_static() {
            add_meta_box( 'meta-box-id', __( 'My Meta Box', 'textdomain' ), 'wpdocs_my_display_callback', 'post' );
    }
    
  • 示例18

    这是在类中调用它的方式:

    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();
    
    
  • 示例19

    函数调用中有$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