Создание мета-блоков является важной частью разработки темы / плагина WordPress . Это способ добавления привлекательного редактора на экран поста, позволяющий избежать необходимости заставлять пользователей полагаться на пользовательские поля. Если вы когда-либо создавали пользовательский тип записей в WordPress, вы, вероятно, хотели бы добавить к нему какие-то дополнительные данные. Конечно, вы можете использовать настраиваемые поля , но это ужасно. Начать работу с пользовательскими метабоксами легко, поэтому давайте углубимся!
Что такое пользовательские мета-боксы?
Пользовательская мета (или запись) коробка невероятно проста в теории. Это позволяет вам добавить пользовательский фрагмент данных к сообщению или странице в WordPress.
Представьте, что вы работаете над темой для клиента, который хочет каталогизировать свою обширную коллекцию концертных плакатов. Вы сразу же начинаете искать основную функциональность WordPress, чтобы увидеть, как вы можете организовать тему: каждый пост будет представлять постер, который идеально подходит для добавления изображения, заголовка и описания. Мы также можем использовать систему категорий и тегов в WordPress для организации постеров. Но что, если мы хотим добавить новый тип метаданных для «исполнителя» каждого постера? Хммм. WordPress не имеет ничего для этого прямо из коробки … что приводит нас к настраиваемым метабоксам.
Пользовательская мета (или запись) коробка невероятно проста в теории. Он позволяет вам добавлять пользовательский фрагмент данных к сообщению или странице в WordPress — более того, он может вписываться непосредственно в большинство страниц по умолчанию в WP, поэтому вы можете легко поместить его в Post-Editor для удобного использования нетехнические типы. Как я уже говорил во вступлении, вы можете добавить такие же «метаданные» к вашему сообщению, используя встроенные настраиваемые поля для сообщения или страницы. В этом нет ничего плохого, но это не очень изящно и не удобно для пользователя.
Вместо этого вы хотите создать пользовательский мета-блок, который содержит поля для всех ваших данных и сохраняет все эти вещи прямо при публикации публикации. Это то, что мы здесь освещаем. Это разбито на три больших шага:
- Добавление мета-блока
 - Рендеринг метабокса
 - Сохранение данных ( правильный путь — да, неправильный путь)
 
Стоит отметить, что большая часть этой информации также может быть использована в API пользовательских типов записей (мы вернемся к этому вопросу позже!), Но ради того, чтобы держать вещи в фокусе сегодня, мы собираемся добавить это непосредственно к редактор сообщений по умолчанию.
Для продвинутых читателей в аудитории: Да, пользовательские типы постов — это то, к чему мы в конечном итоге пойдем, но сначала важно настроить некоторые основы. Кроме того, поскольку вы можете использовать собственные мета-блоки в самых разных местах, это будет полезно для всех.
 Все в этом уроке будет работать в файле functions.php темы.  Это не правильное место для этого, однако.  Если вы добавляете данные в сообщение, скорее всего, вы хотите, чтобы они там были, независимо от вашего внешнего интерфейса.  Таким образом, вы должны поместить этот код в место, не зависящее от вашего дизайна: файл плагина. 
Шаг 1 Добавление мета-бокса

Удобно, WordPress предоставляет функцию для добавления мета-полей на заданный экран администратора: add_meta_box .
Запись кодекса хорошо сделана для этой функции, но вот краткий обзор. Его прототип:
| 
 1 
 | 
 <?php add_meta_box( $id, $title, $callback, $page, $context, $priority, $callback_args ); 
 | 
  $id — это атрибут html ID этого поля.  Это полезно, если вы загружаете пользовательский CSS или Javascript на страницу редактирования для обработки параметров.  В противном случае, это не имеет большого значения. 
  $title отображается в верхней части мета-поля. 
  $callback — это функция, которая фактически отображает метабокс.  Мы опишем это на шаге 2. 
  $page — это то место, где вы хотите отобразить метаблок.  Это должна быть строка с ‘post’ или ‘page’ или ‘some_custom_post_type’. 
  $context — это то место, где вы хотите отобразить мета-поле.  ‘normal’ помещает его ниже редактора сообщений.  ‘side’ перемещает мета-поле в правую боковую панель редактирования (по категориям, тегам и т. д.).  ‘advanced’ также помещает флажок в тот же столбец, что и редактор сообщений, но дальше вниз. 
  $priority сообщает wordpress, где разместить мета-блок в контексте.  ‘high’, ‘default’ или ‘low’ помещают коробку ближе к вершине, в ее нормальное положение или к нижней части соответственно.  Поскольку все мета-блоки можно перетаскивать, $priority не так уж значителен. 
  Наконец, $callback_args позволяет передавать данные в $callback в виде массива.  Мы не собираемся использовать это здесь, но это может быть полезно для передачи некоторых данных в мета-блок.  Скажем, если у вашего плагина было несколько опций, которые влияли на то, что отображалось в мета-окне.  Вы можете передать значения этих опций через массив $callback_args . 
  Итак, наш вызов add_meta_box будет выглядеть так: 
| 
 1 
 | 
 <?php add_meta_box( ‘my-meta-box-id’, ‘My First Meta Box’, ‘cd_meta_box_cb’, ‘post’, ‘normal’, ‘high’ ); 
 | 
  Мы не можем просто вставить это в наш файл плагина в одиночку.  Это приведет к белому экрану смерти и фатальной ошибке PHP: вызов неопределенной функции.  Почему?  Потому что мы add_meta_box функцию add_meta_box до загрузки WordPress.  Поэтому нам нужно использовать хук WordPress, который является частью API плагина .  По сути, функции подключаются к заданному действию WordPress или фильтру, затем эти функции запускаются при загрузке.  Оборачивая наш вызов add_meta_box в функцию, затем подключая эту функцию к add_meta_boxes действия add_meta_boxes , мы избегаем фатальной ошибки. 
Наш код для добавления мета-блока на наш экран постов будет выглядеть так:
| 
 1 
2 
3 
4 
5 
6 
7 
 | 
 <?php 
add_action( ‘add_meta_boxes’, ‘cd_meta_box_add’ ); 
function cd_meta_box_add() 
{ 
    add_meta_box( ‘my-meta-box-id’, ‘My First Meta Box’, ‘cd_meta_box_cb’, ‘post’, ‘normal’, ‘high’ ); 
} 
?> 
 | 
Шаг 2 Рендеринг мета-бокса
Приведенного выше кода достаточно для добавления мета-блока, но теперь мы должны отобразить объект и фактически добавить поля. Это просто код формы HTML, смешанный с небольшим количеством PHP для отображения сохраненных данных. Нам не нужно включать теги формы, поскольку WordPress делает это для нас.
  Помните строку, которую мы передали как $callback в add_meta_box ?  Теперь мы собираемся создать функцию с тем же именем.  Эта функция позаботится обо всем отображении внутри мета-блока. 
| 
 1 
2 
3 
4 
5 
6 
 | 
 <?php 
function cd_meta_box_cb() 
{ 
    echo ‘What you put here, show\’s up in the meta box’; 
} 
?> 
 | 

Мы собираемся добавить несколько полей в наш мета-блок: ввод текста, раскрывающееся меню и флажок. Начнем с ввода текста.
Добавление ввода текста
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
 | 
 <?php 
function cd_meta_box_cb() 
{ 
    ?> 
    <label for=»my_meta_box_text»>Text Label</label> 
    <input type=»text» name=»my_meta_box_text» id=»my_meta_box_text» /> 
    <?php 
} 
?> 
 | 

  Но как насчет отображения данных?  Итак, как вы увидите на шаге 3, мы будем хранить эти данные в таблице wp_postmeta с помощью функции update_post_meta.  Эта функция имеет две родственные функции: get_post_meta и get_post_custom , которые получают данные из wp_postmeta.  get_post_meta данные только с одного ключа, а get_post_custom все.  Поскольку на данный момент мы используем только одно поле, давайте использовать get_post_meta . 
  Также обратите внимание, что функция add_meta_box передает одну переменную нашему add_meta_box вызову: $ post, который является объектом post. 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
 | 
 <?php 
function cd_meta_box_cb( $post ) 
{ 
$values = get_post_custom( $post->ID ); 
$text = isset( $values[‘my_meta_box_text’] ) ? 
$selected = isset( $values[‘my_meta_box_select’] ) ? 
$check = isset( $values[‘my_meta_box_check’] ) ? 
    ?> 
<p> 
    <label for=»my_meta_box_text»>Text Label</label> 
    <input type=»text» name=»my_meta_box_text» id=»my_meta_box_text» value=»<?php echo $text; ?>» /> 
        </p> 
    <?php 
} 
?> 
 | 
Добавление выпадающего
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
 | 
 <?php 
function cd_meta_box_cb( $post ) 
{ 
$values = get_post_custom( $post->ID ); 
$text = isset( $values[‘my_meta_box_text’] ) ? 
$selected = isset( $values[‘my_meta_box_select’] ) ? 
$check = isset( $values[‘my_meta_box_check’] ) ? 
    ?> 
    <p> 
        <label for=»my_meta_box_text»>Text Label</label> 
        <input type=»text» name=»my_meta_box_text» id=»my_meta_box_text» value=»<?php echo $text; ?>» /> 
    </p> 
         <p> 
        <label for=»my_meta_box_select»>Color</label> 
        <select name=»my_meta_box_select» id=»my_meta_box_select»> 
            <option value=»red» <?php selected( $selected, ‘red’ ); 
            <option value=»blue» <?php selected( $selected, ‘blue’ ); 
        </select> 
    </p> 
    <?php 
} 
?> 
 | 
  С добавлением второго поля мы изменили или вызов get_post_meta для get_post_custom , который возвращает ассоциативный массив всех пользовательских ключей и значений сообщения.  Затем мы просто получаем доступ к нашим полям через их имена.  Тернарные операторы удерживают наш код от выдачи предупреждений PHP (неопределенные индексы и тому подобное).  Мы рассмотрим функцию esc_attr на третьем шаге. 
  В раскрывающемся списке мы будем использовать одну из самых удобных функций WordPress: выбранный .  Это сравнивает первое значение, данные, которые мы сохранили, со вторым, атрибутом значения <option> .  Если они одинаковы, функция echo selected="selected" отображает это значение в раскрывающемся списке.  Довольно мило, и это спасает нас от написания множества слов if или ternary.  Вы также можете использовать функцию selected() с переключателями. 
Добавление флажка
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
 | 
 <?php 
function cd_meta_box_cb() 
{ 
    // $post is already set, and contains an object: the WordPress post 
    global $post; 
    $values = get_post_custom( $post->ID ); 
    $text = isset( $values[‘my_meta_box_text’] ) ? 
    $selected = isset( $values[‘my_meta_box_select’] ) ? 
    $check = isset( $values[‘my_meta_box_check’] ) ? 
         // We’ll use this nonce field later on when saving. 
    wp_nonce_field( ‘my_meta_box_nonce’, ‘meta_box_nonce’ ); 
    ?> 
    <p> 
        <label for=»my_meta_box_text»>Text Label</label> 
        <input type=»text» name=»my_meta_box_text» id=»my_meta_box_text» value=»<?php echo $text; ?>» /> 
    </p> 
         <p> 
        <label for=»my_meta_box_select»>Color</label> 
        <select name=»my_meta_box_select» id=»my_meta_box_select»> 
            <option value=»red» <?php selected( $selected, ‘red’ ); 
            <option value=»blue» <?php selected( $selected, ‘blue’ ); 
        </select> 
    </p> 
         <p> 
        <input type=»checkbox» id=»my_meta_box_check» name=»my_meta_box_check» <?php checked( $check, ‘on’ ); 
        <label for=»my_meta_box_check»>Do not check this</label> 
    </p> 
    <?php 
} 
?> 
 | 
  Снова WordPress предоставляет удобную функцию checked () .  Он работает так же, как selected() сравнивая первое значение (наши сохраненные данные) со вторым и выводя checked="checked" selected() checked="checked" если они совпадают. 
  wp_nonce_field добавляет два скрытых поля в наш мета-блок.  Одним из них является одноразовый номер .  Это случайные строки чисел, которые действительны для каждого пользователя в течение 24 часов.  Одноразовые номера — это способ проверки намерения, и они удостоверяются, что WordPress ничего не делает, если запрос не поступил из очень определенного места.  Другими словами, мы не хотим случайно обновить наши данные, запустив функцию сохранения (см. Шаг 3) в другом месте, отличном от ловушки save_post, поэтому мы проверяем, что одноразовый номер действителен, прежде чем что-либо делать. 

Шаг 3 Сохранение данных
Правило номер один при помещении чего-либо в вашу базу данных или на ваш сайт — не доверяйте пользователю . Даже если этот пользователь — ты.
  Чтобы сохранить наши данные, мы будем полагаться на другую ловушку WordPress: save_post .  Это работает так же, как наш хук действия выше: 
| 
 1 
 | 
 <?php add_action( ‘save_post’, ‘cd_meta_box_save’ ); 
 | 
  Функция cd_meta_box_save получит один аргумент, идентификатор записи и позаботится об очистке и сохранении всех наших данных.  save_post срабатывает после нажатия кнопки обновления или сохранения черновика.  Таким образом, у нас есть доступ ко всем данным $_POST , включая поля мета-поля, в нашей функции сохранения.  Однако прежде чем мы сможем что-либо сделать, нам нужно сделать три вещи: проверить, является ли публикация автосохранением, проверить значение nonce, которое мы создали ранее, и убедиться, что текущий пользователь действительно может редактировать сообщение. 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
 | 
 <?php 
add_action( ‘save_post’, ‘cd_meta_box_save’ ); 
function cd_meta_box_save( $post_id ) 
{ 
    // Bail if we’re doing an auto save 
    if( defined( ‘DOING_AUTOSAVE’ ) && DOING_AUTOSAVE ) return; 
         // if our nonce isn’t there, or we can’t verify it, bail 
    if( !isset( $_POST[‘meta_box_nonce’] ) || !wp_verify_nonce( $_POST[‘meta_box_nonce’], ‘my_meta_box_nonce’ ) ) return; 
         // if our current user can’t edit this post, bail 
    if( !current_user_can( ‘edit_post’ ) ) return; 
} 
?> 
 | 
Теперь самое интересное: на самом деле мы сохраняем наши данные. Правило номер один при помещении чего-либо в вашу базу данных или на ваш сайт — не доверяйте пользователю . Даже если этот пользователь — ты. В связи с этим, прежде чем сохранять какие-либо данные, мы хотим убедиться, что в них нет ничего вредоносного. К счастью, WordPress предоставляет множество функций для проверки данных .
  Вы уже видели esc_attr() выше (шаг 2).  Это кодирует символы «» и <> в сущности HTML. Зачем использовать это? Таким образом, пользователи не могли ввести <script> в ваш мета-блок. Если вы хотите разрешить определенные теги HTML, но лишить других, wp_kses может сделать Это требует двух аргументов, первый из которых — строка, которую вы хотите проверить, а второй — ассоциативный массив разрешенных тегов. WordPress предоставляет гораздо больше инструментов для проверки данных, но не бойтесь их использовать. 
  Мы собираемся использовать функцию update_post_meta чтобы заботиться о сохранении наших данных.  Он принимает три аргумента: идентификатор сообщения, мета-ключ и значение. 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
 | 
 <?php 
add_action( ‘save_post’, ‘cd_meta_box_save’ ); 
function cd_meta_box_save( $post_id ) 
{ 
    // Bail if we’re doing an auto save 
    if( defined( ‘DOING_AUTOSAVE’ ) && DOING_AUTOSAVE ) return; 
         // if our nonce isn’t there, or we can’t verify it, bail 
    if( !isset( $_POST[‘meta_box_nonce’] ) || !wp_verify_nonce( $_POST[‘meta_box_nonce’], ‘my_meta_box_nonce’ ) ) return; 
         // if our current user can’t edit this post, bail 
    if( !current_user_can( ‘edit_post’ ) ) return; 
         // now we can actually save the data 
    $allowed = array( 
        ‘a’ => array( // on allow a tags 
            ‘href’ => array() // and those anchors can only have href attribute 
        ) 
    ); 
         // Make sure your data is set before trying to save it 
    if( isset( $_POST[‘my_meta_box_text’] ) ) 
        update_post_meta( $post_id, ‘my_meta_box_text’, wp_kses( $_POST[‘my_meta_box_text’], $allowed ) ); 
             if( isset( $_POST[‘my_meta_box_select’] ) ) 
        update_post_meta( $post_id, ‘my_meta_box_select’, esc_attr( $_POST[‘my_meta_box_select’] ) ); 
             // This is purely my personal preference for saving check-boxes 
    $chk = isset( $_POST[‘my_meta_box_check’] ) && $_POST[‘my_meta_box_select’] ? 
    update_post_meta( $post_id, ‘my_meta_box_check’, $chk ); 
} 
?> 
 | 

Заворачивать
Это оно! У вас должен быть полностью рабочий метабокс. Другие примеры, которые вы можете найти в веб-цикле по множеству полей, не очищая данные. Это неправильный подход. Всегда используйте встроенные функции проверки данных; разные поля / значения могут требовать различной проверки данных.
  Чтобы использовать эти настраиваемые поля в интерфейсе вашего сайта, используйте функции get_post_meta или get_post_custom (см. Шаг 2).