
Метабоксы в WordPress
Что такое метабоксы?
Чтобы не быть голословным скажу, что в WordPress есть стандартные метабоксы и вы часто их используете. Чаще всего вы видите метабоксы «Discussion» (Обсуждение) и Custom Fields (Произвольные поля). Те кто уже некоторое время работал с WordPress знают что отключать и подключать стандартные метабоксы можно в пункте Screen Options (Настройки экрана).
Когда вы разрабатываете сайты, вы используете плагины и многие из них используют API метабоксов. Этой технологией часто пользуются в SEO плагинах для добавления полей ввода заголовка, описания и ключевых слов. Кстати проверено экспериментально мета тег ключевых слов на страницах можно вовсе не добавлять на выдачу не заметил чтобы влияло.
Пример метабокса в плагинах.
![]() | ![]() |
Перед тем как создавать свои метабоксы, необходимо научиться удалять лишние.
remove_meta_box() – удаление метабокса.
1 | remove_meta_box( $id, $page, $context ); |
$page (строка) – тип постов, на странице создания/редактирования которых нужно удалить метабокс, например post, page.
$context (строка) – расположение метабокса, например normal, advanced или side.
Для работы функции ее необходимо разместить в functions.php. Для примера уберем слой с именем автора authordiv.
1 2 3 4 5 | function remove_author_div() { remove_meta_box( 'authordiv' , 'post' , 'side' ); // удалим метабокс с рубриками } add_action( 'admin_menu' , 'remove_author_div' ); |
Если вы вставите данный код то в Scrin Optn (настройках экрана) не будет выбора метабокса автора. Также и при редактировании статьи вы не увидите этот метабокс.
Рассмотрим еще какие стандартные метабоксы могут быть использоваы при разработке плагинов.
Идентификаторы метабоксов можно было бы найти и в коде но есть ряд стандартных которые думаю важно перечислить. Перечислю айдишники стандартных метабоксов.
commentstatusdiv – настройки обсуждения.
commentsdiv – отображает комментарии к текущему посту.
slugdiv – ярлык записи.
revisionsdiv – редакции.
authordiv – автор записи.
postcustom – добавление/редактирование произвольных полей.
postexcerpt – цитата.
trackbacksdiv – обратные ссылки.
categorydiv – метабокс список рубрик WordPress.
tagsdiv-post_tag – метки.
postimagediv – миниатюра записи.
pageparentdiv – метабокс с выбором родительской страницы и шаблона страниц.
submitdiv – блок с кнопкой «опубликовать».
Добавление метабоксов при помощи register_post_type()
Добавление метабоксов register_post_type()
Думаю вы слышали о типах материалов в WordPress. Стандартные типы это страницы, посты и те которые вы можете создать сами. Так вот, для создания типом материалов используется эта самая функция. В ней же можно сразу и определить какие метабоксы созданные типы будут поддерживать.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | function codex_custom_init() { $labels = array( 'name' => _x('Books', 'post type general name', 'your_text_domain'), 'singular_name' => _x('Book', 'post type singular name', 'your_text_domain'), 'add_new' => _x('Add New', 'book', 'your_text_domain'), 'add_new_item' => __('Add New Book', 'your_text_domain'), 'edit_item' => __('Edit Book', 'your_text_domain'), 'new_item' => __('New Book', 'your_text_domain'), 'all_items' => __('All Books', 'your_text_domain'), 'view_item' => __('View Book', 'your_text_domain'), 'search_items' => __('Search Books', 'your_text_domain'), 'not_found' => __('No books found', 'your_text_domain'), 'not_found_in_trash' => __('No books found in Trash', 'your_text_domain'), 'parent_item_colon' => '', 'menu_name' => __('Books', 'your_text_domain') ); $args = array( 'labels' => $labels, 'public' => true, 'publicly_queryable' => true, 'show_ui' => true, 'show_in_menu' => true, 'query_var' => true, 'rewrite' => array( 'slug' => _x( 'book', 'URL slug', 'your_text_domain' ) ), 'capability_type' => 'post', 'has_archive' => true, 'hierarchical' => false, 'menu_position' => null, 'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' ) ); register_post_type('book', $args); } add_action( 'init', 'codex_custom_init' ); |
Строка Support показывает, какие метабоксы должен использовать новый тип данных.
1 | 'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' ) |
Также можно для нового типа данных добавлять категорию и теги при помощи массива taxonomies.
1 | 'taxonomies' => array('category', 'post_tag'), |
Полный вид кода для нашего нового типа данных:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | function codex_custom_init() { $labels = array( 'name' => _x('Books', 'post type general name', 'your_text_domain'), 'singular_name' => _x('Book', 'post type singular name', 'your_text_domain'), 'add_new' => _x('Add New', 'book', 'your_text_domain'), 'add_new_item' => __('Add New Book', 'your_text_domain'), 'edit_item' => __('Edit Book', 'your_text_domain'), 'new_item' => __('New Book', 'your_text_domain'), 'all_items' => __('All Books', 'your_text_domain'), 'view_item' => __('View Book', 'your_text_domain'), 'search_items' => __('Search Books', 'your_text_domain'), 'not_found' => __('No books found', 'your_text_domain'), 'not_found_in_trash' => __('No books found in Trash', 'your_text_domain'), 'parent_item_colon' => '', 'menu_name' => __('Books', 'your_text_domain') ); $args = array( 'labels' => $labels, 'public' => true, 'publicly_queryable' => true, 'show_ui' => true, 'show_in_menu' => true, 'query_var' => true, 'rewrite' => array( 'slug' => _x( 'book', 'URL slug', 'your_text_domain' ) ), 'capability_type' => 'post', 'has_archive' => true, 'hierarchical' => false, 'taxonomies' => array('category', 'post_tag'), 'menu_position' => null, 'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' ), ); register_post_type('book', $args); } add_action( 'init', 'codex_custom_init' ); |
Также метабоксы можно добавлять при помощи функции register_taxonomy_for_object_type()
Функция присваивает таксономию к нужному типу записей, добавляется и метабокс:
1 2 3 4 | $taxonomy = 'post_tag'; // таксономия, в этом случае метки $post_type = 'game'; // тип поста register_taxonomy_for_object_type($taxonomy, $post_type); |
Данную функцию можно использовать, если таксономию изначально определять не надо.
Можно также добавить поддерживаемые метабоксы не сразу при вызове функции register_post_type(), а при дальнейшей обработке кода. Для добавления поддержки метабоксов используйте функцию add_post_type_support() вместо массива supports.
1 2 3 4 5 6 7 8 | function add_some_std_metaboxes() { add_post_type_support('game', 'excerpt'); // добавляем метабокс с цитатой для типа записей game add_post_type_support('movie', array('comments', 'thumbnail', 'excerpt')); // метабокс с комментами, миниатюрой и цитатой для типа записей movie } add_action('init', 'add_some_std_metaboxes'); |
Добавляем свои метабоксы add_meta_box()
Вы сможете добавить абсолютно любой собственный метабокс, неважно, будут ли это поля для указания мета-тегов или же загрузчик изображений в галерею.
1 | 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-функции.
В отличие от предыдущих способов, добавление своего метабокса будет проходить в несколько этапов, рассмотрим пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | /* * Этап 1. Добавление */ function tr_meta_boxes() { add_meta_box('truediv','Настройки','tr_echo_box','book','normal','high'); } add_action( 'admin_menu', 'tr_meta_boxes' ); /* также можно использовать и другие хуки: add_action( 'add_meta_boxes', 'tr_meta_boxes' ); если версия WordPress ниже 3.0, то add_action( 'admin_init', 'tr_meta_boxes', 1 ); */ /* * Этап 2. Заполнение */ function tr_echo_box($post) { wp_nonce_field( basename( __FILE__ ), 'seo_metabox_nonce' ); $title = get_post_meta($post->ID, '_seo_title',true); $noindex = get_post_meta($post->ID, '_seo_noindex',true); ?> <label>Заголовок <input name="seotitle" type="text" value="<?php echo $title ?>" /> </label> <label> <input checked="checked" name="noindex" type="checkbox" /> /> Скрыть запись от поисковиков? </label> <!--?php } /* * Этап 3. Сохранение */ function tr_save_box( $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 == 'book') { // укажите собственный 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','tr_save_box'); ?> |
Если после вставки кода вы попробуете создать запись в нашем новом типе данных Books, то при создании вы увидите новый метабокс с нашим содержимым.
Добавление метабоксов с использованием класса
Автор у которого я подсмотрел часть статьи обещал выложить еще уроки о создании виджетов, думаю буду следить за ним и искать сам, тема действительно интересная.
Описание класса:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | <!--?php if ( !class_exists('trueMetaBoxes') ){ class trueMetaBoxes { /* * параметры по умолчанию, например префикс для полей в таблице MySQL */ var $prefix = '_true_'; /* * массив с произвольными полями * содержание массива довольно размыто, * то есть никто не заставляет вас использовать те же самые ключи */ var $options = array( array( "name" =-->"title", // атрибуты id и name поля формы "title" => "Заголовок", // ну типо название поля "description" => "Содержимое тега title", // описание "type" => "text", // тип поля "cap" => "edit_posts", // необходимые права пользователя "val" => "" // значение по умолчанию ), array( "name" => "noindex", "title" => "Разрешить канонические URL?", "type" => "checkbox", "cap" => "edit_posts" ), array( "name" => "robots", "title" => "Содержимое мета-тега robots", "type" => "select", "cap" => "edit_posts", "val" => array( 'index' => 'index,follow', 'noindex' => 'noindex,follow', 'nofollow' => 'nofollow, index', 'noindexnofollow' => 'noindex, nofollow' ) ) ); /* * конструктор класса, при создании объекта сюда передаем параметры $id и $title * они пригодятся в функции add_meta_box() */ function __construct($id, $title) { $this->id = $id; $this->title = $title; add_action( 'admin_menu', array( &$this, 'create_true_box' ) ); add_action( 'save_post', array( &$this, 'save_true_box' ), 1, 2 ); } /* * функция добавления метабокса * как видите, в конструкторе я передал только самые важные аргументы * но точно так же можно с легкостью настраивать и остальные */ function create_true_box() { add_meta_box( $this->id, $this->title, array( &$this, 'display_true_box' ), 'post', 'normal'); } /* * функция, генерирующая содержимое метабокса */ function display_true_box(){ global $post; ?> |
options as $option ) { if (current_user_can( $option[‘cap’], $post->ID )) { ?>
prefix . $option[‘name’] . ‘» id=»‘ . $this->prefix . $option[‘name’] . ‘»‘; if ( get_post_meta( $post->ID, $this->prefix . $option[‘name’], true ) == «on» ) echo ‘ checked=»checked»‘; echo ‘» style=»width: auto;» />’; echo ‘‘; break; } case «select»: { echo ‘
‘ . $option[ ‘description’ ] . ‘
‘; break; } default: { // по умолчанию type=»text» echo ‘
‘ . $option[ ‘description’ ] . ‘
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <!--?php } /* * функция сохранения произвольных полей */ function save_true_box($post_id, $post){ if ( !wp_verify_nonce( $_POST[ 'seodiv_wpnonce' ], 'seo-div' ) ) return; if ( !current_user_can( 'edit_post', $post_id ) ) return; if ( $post--->post_type != 'page' && $post->post_type != 'post' ) return; foreach ( $this->options as $option ) { if ( current_user_can( $option['cap'], $post_id ) ) { if ( isset( $_POST[ $this->prefix . $option['name'] ] ) && trim( $_POST[ $this->prefix . $option['name'] ] ) ) { // как видите, вся инфа хранится в метаданных поста update_post_meta( $post_id, $this->prefix . $option[ 'name' ], $_POST[ $this->prefix . $option['name'] ] ); } else { delete_post_meta( $post_id, $this->prefix . $option[ 'name' ] ); } } } } } } |
1 2 3 4 5 | if (class_exists('trueMetaBoxes')) { $id = 'seodiv'; // id метабокса $title = 'Доп. Настройки'; // и его заголовок $obj = new trueMetaBoxes($id, $title); } |
Достаточно один раз подробно описать класс и после этого создавать сколько угодно объектов (это и будут метабоксы), лишь меняйте передаваемые ему параметры, в том числе и массив $options, не придётся писать кучу HTML-кода, всё будет вставляться по шаблону. Переменные, не используемые конструктором, можно будет поменять уже после создания объекта, например:
1 2 3 | // т.е. каждому объекту можно присвоить свои собственные $prefix и $options $obj->prefix = '_seo_'; $obj->options[0]['title'] = 'Типа новый лейбл первого поля в метабоксе'; |
Обращение к метаданным (произвольным полям) поста/страницы
1 | get_post_meta($post_id, $key, $single); |
$post_id (целое) (обязательное) – ID поста или страницы.
$key (строка) (обязательное) – значение произвольного поля.
$single (логическое) – если true – возвращает строку, false – массив, по умолчанию – false.
Последний пример для вывод содержимого метабокса в шаблоне:
1 2 3 4 5 6 7 8 | /* * $obj->prefix я взял из предыдущего примера, * можно также указать префикс самому: * get_post_meta($post->ID, '_seo_title', true); */ $title = ''; $title .= get_post_meta($post->ID, $obj->prefix.'title', true); $title .=''; |
Еще хотел бы подчеркнуть что данные которые записывались в метабокс храняться в «Произвольных полях«, а то что я указал вверху это вывод тех самых произвольных полей.

/*

- Базовый курс по веб-дизайну;
- Верстка сайтов;
- Общий курс по CMS WordPress и продолжение курса по разработке шаблонов;
- Разработка сайтов на PHP.
Статья была написана на основе CODEX WordPress и сайта truemisha.ru
Хочу добавить что созданный нами тип данных могут видеть все пользователи, включая и тех у которых самые низкие привилегии.