Как разместить произвольный метабокс между заголовком и редактором на странице редактирования записи?

15 дек. 2011 г., 22:38:17
Просмотры: 38.3K
Голосов: 36

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

1
Комментарии

Очень похожий вопрос здесь: http://wordpress.stackexchange.com/questions/35416/re-order-editor-to-be-after-meta-box

Simon East Simon East
29 авг. 2014 г. 04:53:08
Все ответы на вопрос 5
3
58
  • Просто добавьте метабокс, используя контекст advanced и приоритет high
  • Затем подключитесь к хуку edit_form_after_title
  • Выведите ваши метабоксы в этом месте, а затем удалите их, чтобы они не отображались дважды.

    // Перемещаем все "advanced" метабоксы выше стандартного редактора
    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']);
    });
    
23 февр. 2013 г. 20:48:37
Комментарии

Над сайтом, над которым я работаю, регистрируются несколько метабоксов с использованием параметра register_meta_box_cb функции register_post_type. Я попробовал ваш код, но метабоксы не перемещаются выше редактора. Можно ли использовать этот подход в моем случае? Спасибо.

leemon leemon
28 авг. 2016 г. 21:57:31

Я бы рекомендовал использовать пользовательский $context вместо advanced, например my_before_editor, чтобы вы не перемещали все метабоксы в контексте advanced, а конкретно нацеливались на нужные вам метабоксы... см. https://developer.wordpress.org/reference/functions/add_meta_box/

farinspace farinspace
8 дек. 2017 г. 23:41:59

edit_form_after_title не поддерживается блок-редактором https://github.com/WordPress/gutenberg/issues/5821

Fanky Fanky
9 июн. 2022 г. 15:29:43
2
18

Вот как можно переместить определенные метабоксы над редактором, но прежде чем опубликовать код, я хотел бы поблагодарить Эндрю и mhulse. Ребята, вы крутые!

function foo_deck( $post_type ) {
    // Проверяем, относится ли тип записи к постам или страницам
    if ( in_array( $post_type, array( 'post', 'page' ) ) ) {
        add_meta_box(
            'contact_details_meta', // ID метабокса
            'Контактные данные', // Заголовок метабокса
            'contact_details_meta', // Функция обратного вызова
            $post_type, // Тип записи
            'test', // Контекст (изменяем на что-то отличное от normal, advanced или side)
            'high' // Приоритет
        );
    }
}

// Добавляем метабокс при загрузке страницы редактирования
add_action('add_meta_boxes', 'foo_deck');

function foo_move_deck() {
    // Получаем глобальные переменные
    global $post, $wp_meta_boxes;

    // Выводим метабоксы с контекстом 'test'
    do_meta_boxes( get_current_screen(), 'test', $post );

    // Удаляем исходные метабоксы с контекстом 'test'
    unset($wp_meta_boxes['post']['test']);
}

// Перемещаем метабоксы после заголовка записи
add_action('edit_form_after_title', 'foo_move_deck');
20 авг. 2014 г. 07:49:43
Комментарии

изменить на что-то другое, кроме normal, advanced или side - это было ключевым моментом в моем случае. Спасибо за информацию.

Mayeenul Islam Mayeenul Islam
28 сент. 2014 г. 12:39:50

Это был самый полезный ответ для меня. Спасибо!

marvinpoo marvinpoo
4 дек. 2018 г. 16:48:43
1
13

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

/**
 * Добавляет метабокс "Декабрь" (подзаголовок) на страницу(ы) записи и позиционирует его
 * под заголовком.
 *
 * @todo Перенести в класс.
 * @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
 */

# Добавляет блок в основную колонку на экранах редактирования Записи и Страницы:
function foo_deck($post_type) {

    # Разрешенные типы записей для отображения метабокса:
    $post_types = array('post', 'page');

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

        # Добавляем метабокс в административный интерфейс:
        add_meta_box(
            'foo-deck-meta-box', // HTML атрибут 'id' секции редактирования.
            'Декабрь',          // Заголовок секции редактирования, видимый пользователю.
            'foo_deck_meta_box', // Функция, выводящая HTML для секции редактирования.
            $post_type,         // Тип экрана редактирования, на котором показывать секцию.
            'advanced',         // Часть страницы, где должна отображаться секция.
            'high'              // Приоритет в контексте отображения блоков.
        );

    }

}

# Функция обратного вызова, выводящая содержимое блока:
function foo_deck_meta_box($post) {

    # Используем `get_post_meta()` для получения существующего значения из базы данных и используем его для формы:
    $deck = get_post_meta($post->ID, '_deck', true);

    # Поле формы для отображения:
    ?>

        <label class="screen-reader-text" for="foo_deck">Декабрь</label>
        <input id="foo_deck" type="text" autocomplete="off" value="<?=esc_attr($deck)?>" name="foo_deck" placeholder="Декабрь">

    <?php

    # Отображаем скрытое поле nonce:
    wp_nonce_field(
        plugin_basename(__FILE__), // Название действия.
        'foo_deck_meta_box'        // Название nonce.
    );

}

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

# Сохраняем пользовательские данные при сохранении записи:
function foo_deck_save_postdata($post_id) {

    # Имеет ли текущий пользователь право выполнять это действие?
    if ((($_POST['post_type'] === 'page') && current_user_can('edit_page', $post_id) || current_user_can('edit_post', $post_id))) { // Если это страница, ИЛИ, если это запись, может ли пользователь ее редактировать?

        # Препятствуем WP очищать пользовательские поля при автосохранении:
        if ((( ! defined('DOING_AUTOSAVE')) || ( ! DOING_AUTOSAVE)) && (( ! defined('DOING_AJAX')) || ( ! DOING_AJAX))) {

            # Проверка nonce:
            if (wp_verify_nonce($_POST['foo_deck_meta_box'], plugin_basename(__FILE__))) {

                # Получаем отправленный декабрь:
                $deck = sanitize_text_field($_POST['foo_deck']);

                # Добавить, обновить или удалить?
                if ($deck !== '') {

                    # Декабрь существует, поэтому добавляем ИЛИ обновляем его:
                    add_post_meta($post_id, '_deck', $deck, true) OR update_post_meta($post_id, '_deck', $deck);

                } else {

                    # Декабрь пуст или удален:
                    delete_post_meta($post_id, '_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));

}

# Отображаем декабрь (это будет выглядеть лучше при ООП):
function foo_the_deck() {

    echo foo_get_deck(get_the_ID());

}

# Проверка условия:
function foo_has_subtitle($post_id = FALSE) {

    if (foo_get_deck($post_id)) return TRUE;

}

# Определяем пользовательский блок:
add_action('add_meta_boxes', 'foo_deck');
# Делаем что-то с введенными данными:
add_action('save_post', 'foo_deck_save_postdata');

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

# Теперь перемещаем расширенные метабоксы после заголовка:
function foo_move_deck() {

    # Получаем глобальные переменные:
    global $post, $wp_meta_boxes;

    # Выводим "расширенные" метабоксы:
    do_meta_boxes(get_current_screen(), 'advanced', $post);

    # Удаляем изначальные "расширенные" метабоксы:
    unset($wp_meta_boxes['post']['advanced']);

}

add_action('edit_form_after_title', 'foo_move_deck');

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

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

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

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

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

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

7 мая 2013 г. 04:04:46
Комментарии

Если кому-то будет полезно, кто идет по тому же пути: я задал вопрос здесь, где есть некоторый связанный/похожий код (я решил использовать поле "title" для хранения и фильтрации подзаголовка).

mhulse mhulse
21 мая 2013 г. 03:14:14
0

Вместо того чтобы перемещать всё из расширенного раздела наверх, почему бы не создать новый раздел и поместить его в начало:

// Создаем раздел '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.

19 мар. 2016 г. 13:16:11
1

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

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

  2. Добавить фейковый метабокс

    add_meta_box( 'does-not-matter', 
    __( 'Описание'), 
    function($post){ 
      wp_editor($post->post_content,'post_content',array('name'=>'post_content'));
    },
    'post_type_type', 
    'advanced', 
    'high' );
    
26 мая 2016 г. 13:03:13
Комментарии

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

Eckstein Eckstein
12 февр. 2018 г. 06:19:32