В основном метабоксы в 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); |
По мере совершенствования класса содержимое этого поста будет обновляться.
Источник: misha.blog