Метабоксы в WordPress, создание и удаление

Опубликовано: 01.09.2018

видео Метабоксы в WordPress, создание и удаление

Как создать меню в WordPress через админку, виджет и кастомайзер. Начальный гайд. Урок #1

В основном метабоксы в WordPress нужны для удобства (ну кроме стандартных разумеется), потому что все настройки, которые вы можете добавить в собственном метабоксе, можно заменить использованием произвольных полей .


Создание Вордпресс Темы - Урок 8 Опции для темы wordpress

remove_meta_box() — удаление метабоксов

remove_meta_box ( $id , $page , $context ) ;
$id (строка)

идентификатор метабокса, его можно найти в исходном коде странице, чуть ниже я перечислю айдишники всех стандартных метабоксов. $page (строка)

тип постов, на странице создания/редактирования которых нужно удалить метабокс, например post, page. $context (строка)

расположение метабокса, например normal, advanced или side

Простая вставка этой функции куда-либо не прокатит, поэтому привожу пример:

/* * удаляем со страницы редактирования постов метабокс с рубриками и цитатой */ function remove_category_div ( ) { remove_meta_box ( 'categorydiv' , 'post' , 'side' ) ; // рубрики remove_meta_box ( 'postexcerpt' , 'post' , 'normal' ) ; // цитата } add_action ( 'admin_menu' , 'remove_category_div' ) ;

Код вставлять в functions.php текущей темы.

Описание стандартных метабоксов в WordPress

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

commentstatusdiv — настройки обсуждения, commentsdiv — отображает комментарии к текущему посту, slugdiv — ярлык записи, revisionsdiv — редакции, authordiv — автор записи, postcustom — добавление/редактирование произвольных полей, postexcerpt — цитата, trackbacksdiv — обратные ссылки, categorydiv — список рубрик , tagsdiv-post_tag — метки, postimagediv — миниатюра записи, pageparentdiv — метабокс с выбором родительской страницы и шаблона страниц, submitdiv — блок с кнопкой «опубликовать».

Способы добавления метабоксов

register_post_type()

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

В примере перечислено лишь минимум необходимых параметров, но он все равно рабочий.

function true_register_post_type_example ( ) { $args = array ( 'hierarchical' => true , 'show_ui' => true , /* * присвоив таксономию для поста, мы автоматически подключаем метабокс этой таксономии */ 'taxonomies' => array ( 'category' ) , /* * а теперь прописываем уже сами названия метабоксов, * названия для register_post_type() и для remove_meta_box() будут отличаться!! */ 'supports' => array ( 'title' , 'editor' ) /* * Возможные варианты содержимого массива "supports": * * title - заголовок, * editor - редактор, * author - автор записи, * thumbnail - миниатюра записи, * excerpt - поле для цитаты, * trackbacks - обратные ссылки, * custom-fields - произвольные поля, * comments - комментарии, * revisions - редакции, * page-attributes - атрибуты поста, только при 'hierarchical' => true * */ ) ; register_post_type ( 'truepost' , $args ) ; } add_action ( 'init' , 'true_register_post_type_example' ) ;

register_taxonomy_for_object_type()

Функция приписывает таксономию к уже созданному типу записей, а значит, добавляется и метабокс:

register_taxonomy_for_object_type ( $taxonomy , $object_type ) ;
$taxonomy (строка) (обязательное)

название таксономии, например post_tag, $object_type (строка) (обязательное)

тут укажите тип поста, для которого нужно присвоить таксономию, например post, page, game;

Эту функцию тоже просто так не заюзать, поэтому пример:

function true_additional_taxonomies ( ) { register_taxonomy_for_object_type ( 'post_tag' , 'truepost' ) ; } add_action ( 'init' , 'true_additional_taxonomies' ) ;

add_post_type_support()

Позволяет добавить какой-нибудь из стандартных боксов.

add_post_type_support ( $post_type , $supports )
$post_type (строка) (обязательное)

тип поста (максимум 20 символов кстати), $supports (строка|массив)

названия стандартных метабоксов, которые перечислены двумя примерами выше;
function add_some_std_metaboxes ( ) { add_post_type_support ( 'game' , 'excerpt' ) ; // цитата add_post_type_support ( 'truepost' , array ( 'excerpt' , 'thumbnail' ) ) ; // цитата и миниатюра } add_action ( 'init' , 'add_some_std_metaboxes' ) ;

add_meta_box()

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

add_meta_box ( $id , $title , $callback , $post_type , $context , $priority , $args ) ;
$id (строка) (обязательное)

HTML-атрибут id для блока div будущего метабокса, $title (строка) (обязательное)

заголовок, $callback (функция) (обязательное)

функция которая будет заполнять метабокс, нужно указать название функции в виде строки, $post_type (строка) (обязательное)

тип записей, $context (строка)

в какой части страницы вставить метабокс (normal, side, advanced), по умолчанию — advanced, $priority (строка)

приоритет, чем он выше, тем ближе к верхней части страницы будет располагаться метабокс, (high, core, default или low), по умолчанию — default, $args (массив)

аргументы для callback-функции.

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

<?php /* * Этап 1. Добавление */ function true_meta_boxes ( ) { add_meta_box ( 'truediv' , 'Настройки' , 'true_print_box' , 'post' , 'normal' , 'high' ) ; } add_action ( 'admin_menu' , 'true_meta_boxes' ) ; /* * также можно использовать и другие хуки: * add_action( 'add_meta_boxes', 'tr_meta_boxes' ); * если версия WordPress ниже 3.0, то * add_action( 'admin_init', 'tr_meta_boxes', 1 ); */ /* * Этап 2. Заполнение */ function true_print_box ( $post ) { wp_nonce_field ( basename ( __FILE__ ) , 'seo_metabox_nonce' ) ; /* * добавляем текстовое поле */ $html .= '<label>Заголовок <input type="text" name="seotitle" value="' . get_post_meta ( $post -> ID , 'seo_title' ,true ) . '" /></label> ' ; /* * добавляем чекбокс */ $html .= '<label><input type="checkbox" name="noindex"' ; $html .= ( get_post_meta ( $post -> ID , 'seo_noindex' ,true ) == 'on' ) ? ' checked="checked"' : '' ; $html .= ' /> Скрыть запись от поисковиков?</label>' ; echo $html ; } /* * Этап 3. Сохранение */ function true_save_box_data ( $post_id ) { // проверяем, пришёл ли запрос со страницы с метабоксом if ( ! isset ( $_POST [ 'seo_metabox_nonce' ] ) || !wp_verify_nonce ( $_POST [ 'seo_metabox_nonce' ] , basename ( __FILE__ ) ) ) return $post_id ; // проверяем, является ли запрос автосохранением if ( defined ( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return $post_id ; // проверяем, права пользователя, может ли он редактировать записи if ( !current_user_can ( 'edit_post' , $post_id ) ) return $post_id ; // теперь также проверим тип записи $post = get_post ( $post_id ) ; if ( $post -> post_type == 'post' ) { // укажите собственный update_post_meta ( $post_id , 'seo_title' , esc_attr ( $_POST [ 'seotitle' ] ) ) ; update_post_meta ( $post_id , 'seo_noindex' , $_POST [ 'noindex' ] ) ; } return $post_id ; } add_action ( 'save_post' , 'true_save_box_data' ) ;

В итоге на странице редактирования поста получаем вот такой метабоксик:

Код можно вставить прямо в таком виде в functions.php — и всё будет работать, если конечно у вас нет функций, названия которых совпадают с моими.

Добавление метабоксов с использованием класса

На самом деле это просто потрясающая штука!

достаточно один раз описать класс и затем сколько угодно использовать его для добавления метабоксов на сайте, не придется каждый раз париться по поводу HTML полей ввода, как в случае с функцией add_meta_box(), все, что потребуется для создания нового метабокса — добавить несколько параметров в массив;

А теперь у меня для вас подарок! Уже готовый класс со всеми необходимыми типами полей.

Расскажу, как его использовать в двух шагах. Первый шаг — скопируйте к себе следующий блок с кодом. Если не знаете куда его засунуть — суйте в functions.php, не ошибетесь.

<?php class trueMetaBox { function __construct ( $options ) { $this -> options = $options ; $this -> prefix = $this -> options [ 'id' ] . '_' ; add_action ( 'add_meta_boxes' , array ( & $this , 'create' ) ) ; add_action ( 'save_post' , array ( & $this , 'save' ) , 1 , 2 ) ; } function create ( ) { foreach ( $this -> options [ 'post' ] as $post_type ) { if ( current_user_can ( $this -> options [ 'cap' ] ) ) { add_meta_box ( $this -> options [ 'id' ] , $this -> options [ 'name' ] , array ( & $this , 'fill' ) , $post_type , $this -> options [ 'pos' ] , $this -> options [ 'pri' ] ) ; } } } function fill ( ) { global $post ; $p_i_d = $post -> ID ; wp_nonce_field ( $this -> options [ 'id' ] , $this -> options [ 'id' ] .'_wpnonce' , false , true ) ; ?> <table class="form-table"><tbody> <?php foreach ( $this -> options [ 'args' ] as $param ) { if ( current_user_can ( $param [ 'cap' ] ) ) { ?> <tr> <?php if ( !$value = get_post_meta ( $post -> ID , $this -> prefix . $param [ 'id' ] , true ) ) $value = $param [ 'std' ] ; switch ( $param [ 'type' ] ) { case 'text' :{ ?> <th scope="row"><label for=" <?php echo $this -> prefix . $param [ 'id' ] ?> "> <?php echo $param [ 'title' ] ?> </label></th> <td> <input name=" <?php echo $this -> prefix . $param [ 'id' ] ?> " type=" <?php echo $param [ 'type' ] ?> " id=" <?php echo $this -> prefix . $param [ 'id' ] ?> " value=" <?php echo $value ?> " placeholder=" <?php echo $param [ 'placeholder' ] ?> " class="regular-text" /><br /> <span class="description"> <?php echo $param [ 'desc' ] ?> </span> </td> <?php break ; } case 'textarea' :{ ?> <th scope="row"><label for=" <?php echo $this -> prefix . $param [ 'id' ] ?> "> <?php echo $param [ 'title' ] ?> </label></th> <td> <textarea name=" <?php echo $this -> prefix . $param [ 'id' ] ?> " type=" <?php echo $param [ 'type' ] ?> " id=" <?php echo $this -> prefix . $param [ 'id' ] ?> " value=" <?php echo $value ?> " placeholder=" <?php echo $param [ 'placeholder' ] ?> " class="large-text" /> <?php echo $value ?> </textarea><br /> <span class="description"> <?php echo $param [ 'desc' ] ?> </span> </td> <?php break ; } case 'checkbox' :{ ?> <th scope="row"><label for=" <?php echo $this -> prefix . $param [ 'id' ] ?> "> <?php echo $param [ 'title' ] ?> </label></th> <td> <label for=" <?php echo $this -> prefix . $param [ 'id' ] ?> "><input name=" <?php echo $this -> prefix . $param [ 'id' ] ?> " type=" <?php echo $param [ 'type' ] ?> " id=" <?php echo $this -> prefix . $param [ 'id' ] ?> "<?php echo ( $value == 'on' ) ? ' checked="checked"' : '' ?> /> <?php echo $param [ 'desc' ] ?> </label> </td> <?php break ; } case 'select' :{ ?> <th scope="row"><label for=" <?php echo $this -> prefix . $param [ 'id' ] ?> "> <?php echo $param [ 'title' ] ?> </label></th> <td> <label for=" <?php echo $this -> prefix . $param [ 'id' ] ?> "> <select name=" <?php echo $this -> prefix . $param [ 'id' ] ?> " id=" <?php echo $this -> prefix . $param [ 'id' ] ?> "><option>...</option> <?php foreach ( $param [ 'args' ] as $val => $name ) { ?> <option value=" <?php echo $val ?> "<?php echo ( $value == $val ) ? ' selected="selected"' : '' ?> > <?php echo $name ?> </option> <?php } ?> </select></label><br /> <span class="description"> <?php echo $param [ 'desc' ] ?> </span> </td> <?php break ; } } ?> </tr> <?php } } ?> </tbody></table> <?php } function save ( $post_id , $post ) { if ( !wp_verify_nonce ( $_POST [ $this -> options [ 'id' ] .'_wpnonce' ] , $this -> options [ 'id' ] ) ) return ; if ( !current_user_can ( 'edit_post' , $post_id ) ) return ; if ( ! in_array ( $post -> post_type , $this -> options [ 'post' ] ) ) return ; foreach ( $this -> options [ 'args' ] as $param ) { if ( current_user_can ( $param [ 'cap' ] ) ) { if ( isset ( $_POST [ $this -> prefix . $param [ 'id' ] ] ) && trim ( $_POST [ $this -> prefix . $param [ 'id' ] ] ) ) { update_post_meta ( $post_id , $this -> prefix . $param [ 'id' ] , trim ( $_POST [ $this -> prefix . $param [ 'id' ] ] ) ) ; } else { delete_post_meta ( $post_id , $this -> prefix . $param [ 'id' ] ) ; } } } } }

Вставили и забыли, если не уверены, лучше в этом коде ничего не менять. Если не пашет — пишите в комментариях или мне на почте, лучше конечно в комментариях. На своем тестовом сайте я протестировал — всё ок.

Теперь шаг второй — создаем объекты и передаем им все параметры метабоксов.

В следующем блоке кода я создаю два метабокса, один по центру с несколькими полями, второй тоже по центру с одним полем — чекбоксом.

$options = array ( array ( // первый метабокс 'id' => 'meta1' , // ID метабокса, а также префикс названия произвольного поля 'name' => 'Доп. настройки 1' , // заголовок метабокса 'post' => array ( 'post' ) , // типы постов для которых нужно отобразить метабокс 'pos' => 'normal' , // расположение, параметр $context функции add_meta_box() 'pri' => 'high' , // приоритет, параметр $priority функции add_meta_box() 'cap' => 'edit_posts' , // какие права должны быть у пользователя 'args' => array ( array ( 'id' => 'field_1' , // атрибуты name и id без префикса, например с префиксом будет meta1_field_1 'title' => 'Текст' , // лейбл поля 'type' => 'text' , // тип, в данном случае обычное текстовое поле 'placeholder' => 'плейсхолдер, например введите email' , // атрибут placeholder 'desc' => 'пример использования текстового поля ввода в метабоксе' , // что-то типа пояснения, подписи к полю 'cap' => 'edit_posts' ) , array ( 'id' => 'terms' , 'title' => 'Чекбокс' , 'type' => 'checkbox' , // чекбокс 'desc' => 'пример чекбокса' , 'cap' => 'edit_posts' ) , array ( 'id' => 'textfield' , 'title' => 'Текстовое поле' , 'type' => 'textarea' , // большое текстовое поле 'placeholder' => 'сюда тоже можно забацать плейсхолдер' , 'desc' => 'пример использования большого текстового поля ввода в метабоксе' , 'cap' => 'edit_posts' ) , array ( 'id' => 'select1' , 'title' => 'Выпадающий список' , 'type' => 'select' , // выпадающий список 'desc' => 'тут тоже можно написать пояснение к полю, значения же задаются через ассоциативный массив' , 'cap' => 'edit_posts' , 'args' => array ( 'value_1' => 'Значение 1' , '2' => 'Значение 2' , 'Значение_3' => 'Значение 3' ) // элементы списка задаются через массив args, по типу value=>лейбл ) ) ) , array ( // второй метабокс 'id' => 'meta2' , 'name' => 'Доп. настройки 2' , 'post' => array ( 'post' , 'page' ) , // не только для постов, но и для страниц 'pos' => 'normal' , 'pri' => 'high' , 'cap' => 'edit_posts' , 'args' => array ( array ( 'id' => 'featured' , 'title' => 'На главную' , 'desc' => 'Отображать пост на главной странице' , 'type' => 'checkbox' , 'cap' => 'edit_posts' ) ) ) ) ; foreach ( $options as $option ) { $truemetabox = new trueMetaBox ( $option ) ; }

Вот скриншот получившихся метабоксов из админки, со страницы редактирования записи:

Обращение к метаданным поста/страницы

Понятное дело, что потом все эти настройки нужно как-то задействовать на сайте. Для этого отлично подойдет функция:

get_post_meta ( $post_id , $key , $single ) ;
$post_id (целое) (обязательное)

ID поста или страницы, $key (строка) (обязательное)

значение произвольного поля, $single (логическое)

если true — возвращает строку, false — массив, по умолчанию — false;

Пример использования — выведем значение произвольного поля meta1_field_1, то есть текстового поля из предыдущего примера:

echo get_post_meta ( $post -> ID , 'meta1_field_1' , true ) ;

По мере совершенствования класса содержимое этого поста будет обновляться.

rss