Как поместить пользовательский мета-блок над редактором, но под заголовком на странице редактирования сообщения?

30

У меня есть пользовательское мета-поле для пользовательского типа сообщения, которое мой клиент хочет поместить между разделом title / permalink и редактором сообщений в панели администратора. Возможно ли это, и если да, есть ли крюк / фильтр / и т. Д., Который мне нужно будет использовать?

cstrouse
источник
Очень похожий вопрос здесь: wordpress.stackexchange.com/questions/35416/…
Саймон Ист

Ответы:

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_cbпараметр register_post_typeфункции. Я пробовал ваш код, но метабоксы не перемещаются над редактором. Можно ли это использовать в моем случае? Спасибо
Leemon
Я бы рекомендовал использовать пользовательский $context, вместо того , чтобы advanced, используйте что - то вроде my_before_editor, так что вы не двигаетесь все мета коробки в advancedконтексте, вы специально нацеливать свою конкретную мету коробки .. см developer.wordpress.org/reference/functions/add_meta_box
farinspace
14

Вот как вы можете переместить определенные мета-поля над редактором, но прежде чем я отправлю код, я просто хочу поблагодарить Эндрю и 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');
adamj
источник
1
change to something other then normal, advanced or sideбыл ключ в моем случае. Спасибо за информацию.
Mayeenul Islam
Это был самый полезный ответ для меня. Спасибо!
marvinpoo
12

Чтобы предоставить полный пример кода, основанный на ответе Эндрю ... Мне нужен был способ добавить «Палубу» (или подзаголовок) в мои сообщения; Я хотел, чтобы поле колоды появилось после основной строки заголовка.

/**
 * 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');

Очевидно, что приведенный выше код может использовать больше работы, но он должен помочь другим, пытающимся сделать то же самое (ответ Эндрю пролил свет, но я подумал, что было бы полезно на самом деле привести рабочий пример).

Этот ответ также помог .

Улучшения, которые могут быть сделаны:

  1. Сделать ООП / класс (ы).
  2. Добавьте styles / js, чтобы он выглядел / чувствовал / вел себя как поле заголовка.

Я планирую внести вышеуказанные улучшения в будущем, но, по крайней мере, приведенный выше код должен помочь другим попытаться понять это.

Посмотрите исходный код здесь для большего вдохновения (они решили использовать jQuery для перемещения «подзаголовка»).

mhulse
источник
В случае, если это помогает кому-то идти по тому же пути: я задал здесь вопрос, который имеет некоторый связанный / похожий код (я решил использовать поле «title» для хранения и фильтрации подзаголовка).
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приоритет.

Он работает на WordPress 4.4.2 для меня. Я не проверял это на других версиях WP.

titanic_fanatic
источник
1

Есть другой способ, кстати, мы можем поместить редактор в любую позицию:

  1. Удалить редактор из параметра поддержки при регистрации post_type

  2. добавить поддельный метабокс

    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' );
Hix.botay
источник
К вашему сведению, это все еще работает, но когда вы перемещаете поле, это вызывает странное поведение с содержимым поля. Пользователи остерегаются.
Экштейн