如何在编辑帖子页面的标题上方和下方的编辑器上方放置自定义元框?


Answers:


51
  • 只需使用高级上下文和优先级添加元框
  • 然后,扣上edit_form_after_title钩子
  • 在此处打印您的元框,然后将其删除,这样就不会出现两次。

    // Move all "advanced" metaboxes above the default editor
    add_action('edit_form_after_title', function() {
        global $post, $wp_meta_boxes;
        do_meta_boxes(get_current_screen(), 'advanced', $post);
        unset($wp_meta_boxes[get_post_type($post)]['advanced']);
    });

我正在使用的网站使用register_meta_box_cbregister_post_type函数的参数注册了一些元框。我已经尝试过您的代码,但元框不会在编辑器上方移动。可以在我的情况下使用吗?谢谢
leemon

我建议您使用custom $context,而不是advanced使用like之类的my_before_editor,这样您就不会在advanced上下文中移动所有元框,而是专门针对特定的元框..参见developer.wordpress.org/reference/functions/add_meta_box
farinspace

14

这是将特定的 meta框移到编辑器上方的方法,但是在发布代码之前,我只想感谢Andrew和mhulse。你们真棒!

function foo_deck( $post_type ) {
    if ( in_array( $post_type, array( 'post', 'page' ) ) ) {
        add_meta_box(
            'contact_details_meta',
            'Contact Details',
            'contact_details_meta',
            $post_type,
            'test', // change to something other then normal, advanced or side
            'high'
        );
    }
}

add_action('add_meta_boxes', 'foo_deck');

function foo_move_deck() {
        # Get the globals:
        global $post, $wp_meta_boxes;

        # Output the "advanced" meta boxes:
        do_meta_boxes( get_current_screen(), 'test', $post );

        # Remove the initial "advanced" meta boxes:
        unset($wp_meta_boxes['post']['test']);
    }

add_action('edit_form_after_title', 'foo_move_deck');

1
change to something other then normal, advanced or side是我的关键 谢谢(你的)信息。
Mayeenul Islam 2014年

这是对我最有用的答案。谢谢!
marvinpoo

12

为了提供基于安德鲁答案的完整代码示例,我需要一种在帖子中包含“ Deck”(又称副标题)的方法。我希望甲板字段出现在主标题栏之后。

/**
 * Add a "deck" (aka subhead) meta box to post page(s) and position it
 * under the title.
 *
 * @todo Move to class.
 * @see http://codex.wordpress.org/Function_Reference/add_meta_box
 * @see http://wordpress.org/extend/ideas/topic/add-meta-box-to-multiple-post-types
 * @see https://github.com/Horttcore/WordPress-Subtitle
 * @see http://codex.wordpress.org/Function_Reference/wp_nonce_field
 */

# Adds a box to the main column on the Post and Page edit screens:
function foo_deck($post_type) {

    # Allowed post types to show meta box:
    $post_types = array('post', 'page');

    if (in_array($post_type, $post_types)) {

        # Add a meta box to the administrative interface:
        add_meta_box(
            'foo-deck-meta-box', // HTML 'id' attribute of the edit screen section.
            'Deck',              // Title of the edit screen section, visible to user.
            'foo_deck_meta_box', // Function that prints out the HTML for the edit screen section.
            $post_type,          // The type of Write screen on which to show the edit screen section.
            'advanced',          // The part of the page where the edit screen section should be shown.
            'high'               // The priority within the context where the boxes should show.
        );

    }

}

# Callback that prints the box content:
function foo_deck_meta_box($post) {

    # Use `get_post_meta()` to retrieve an existing value from the database and use the value for the form:
    $deck = get_post_meta($post->ID, '_deck', true);

    # Form field to display:
    ?>

        <label class="screen-reader-text" for="foo_deck">Deck</label>
        <input id="foo_deck" type="text" autocomplete="off" value="<?=esc_attr($deck)?>" name="foo_deck" placeholder="Deck">

    <?php

    # Display the nonce hidden form field:
    wp_nonce_field(
        plugin_basename(__FILE__), // Action name.
        'foo_deck_meta_box'        // Nonce name.
    );

}

/**
 * @see https://wordpress.stackexchange.com/a/16267/32387
 */

# Save our custom data when the post is saved:
function foo_deck_save_postdata($post_id) {

    # Is the current user is authorised to do this action?
    if ((($_POST['post_type'] === 'page') && current_user_can('edit_page', $post_id) || current_user_can('edit_post', $post_id))) { // If it's a page, OR, if it's a post, can the user edit it? 

        # Stop WP from clearing custom fields on autosave:
        if ((( ! defined('DOING_AUTOSAVE')) || ( ! DOING_AUTOSAVE)) && (( ! defined('DOING_AJAX')) || ( ! DOING_AJAX))) {

            # Nonce verification:
            if (wp_verify_nonce($_POST['foo_deck_meta_box'], plugin_basename(__FILE__))) {

                # Get the posted deck:
                $deck = sanitize_text_field($_POST['foo_deck']);

                # Add, update or delete?
                if ($deck !== '') {

                    # Deck exists, so add OR update it:
                    add_post_meta($post_id, '_deck', $deck, true) OR update_post_meta($post_id, '_deck', $deck);

                } else {

                    # Deck empty or removed:
                    delete_post_meta($post_id, '_deck');

                }

            }

        }

    }

}

# Get the deck:
function foo_get_deck($post_id = FALSE) {

    $post_id = ($post_id) ? $post_id : get_the_ID();

    return apply_filters('foo_the_deck', get_post_meta($post_id, '_deck', TRUE));

}

# Display deck (this will feel better when OOP):
function foo_the_deck() {

    echo foo_get_deck(get_the_ID());

}

# Conditional checker:
function foo_has_subtitle($post_id = FALSE) {

    if (foo_get_deck($post_id)) return TRUE;

}

# Define the custom box:
add_action('add_meta_boxes', 'foo_deck');
# Do something with the data entered:
add_action('save_post', 'foo_deck_save_postdata');

/**
 * @see https://wordpress.stackexchange.com/questions/36600
 * @see https://wordpress.stackexchange.com/questions/94530/
 */

# Now move advanced meta boxes after the title:
function foo_move_deck() {

    # Get the globals:
    global $post, $wp_meta_boxes;

    # Output the "advanced" meta boxes:
    do_meta_boxes(get_current_screen(), 'advanced', $post);

    # Remove the initial "advanced" meta boxes:
    unset($wp_meta_boxes['post']['advanced']);

}

add_action('edit_form_after_title', 'foo_move_deck');

显然,上面的代码可能需要做更多的工作,但是它应该可以帮助其他尝试做同样事情的人(Andrew的回答很亮,但我认为实际提供一个有效的示例可能会有所帮助)。

这个答案也有所帮助

可以进行的改进:

  1. 进行OOP /分类。
  2. 添加样式/ js,使其看起来/感觉/像标题字段一样。

我计划在将来的某个时候进行上述改进,但是至少上面的代码应该可以帮助其他人解决这个问题。

请参阅此处的源代码以获取更多启发(他们选择使用jQuery移动“字幕”)。


万一它有助于任何人走同一条路:我在这里问了一个包含一些相关/相似代码的问题(我选择使用“标题”字段来保存和过滤子标题)。
mhulse,

6

与其将高级部分中的所有内容移到顶部,不如创建一个新部分并将其移到顶部:

// Create 'top' section and move that to the top
add_action('edit_form_after_title', function() {
  global $post, $wp_meta_boxes;
  do_meta_boxes(get_current_screen(), 'top', $post);
  unset($wp_meta_boxes[get_post_type($post)]['top']);
});

现在,您要做的就是注册top用于部分和high优先级的meta框。

它对我来说适用于WordPress 4.4.2。我尚未在其他WP版本上对此进行测试。


1

还有另一种方式,我们可以将编辑器置于任何位置:

  1. 注册post_type时,从支持参数中删除编辑器

  2. 添加一个假的metabox

    add_meta_box( 'does-not-matter', 
    __( 'Description'), 
    function($post){ 
      wp_editor($post->post_content,'post_content',array('name'=>'post_content'));
    },
    'post_type_type', 
    'advanced', 
    'high' );

仅供参考,这仍然有效,但是当您移动框时,它会导致字段内容有些奇怪的行为。用户要当心。
埃克斯坦(Eckstein)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.