Создание мета-блоков является важной частью разработки темы / плагина 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).