От автора: если вы хоть раз создавали для себя или клиентов сайт на WordPress или работали на компанию, чей сайт под управлением WordPress, вы должны знать, что такое мета боксы. В прошлых статьях мы уже рассказывали о вставке пользовательских мета боксов в WP. В этой статье мы сделаем еще два шага и объясним их связь, а также интеграцию с типами постов, в том числе как использовать данные из мета боксов на фронте WP.
Вставка мета боксов на экран с типами постов
Про все полезные (если не все) PHP функции, их параметры и action’ы для создания мета боксов рассказал Narayan Prusty.
Чтобы вставить мета бокс на любой экран редактирования типов постов, необходимо использовать add_meta_box(), а после подцепить функцию к экшену add_meta_boxes.
Код ниже вставляет мета бокс на экран редактирования post. Обратите внимание на global_notice_meta_box_callback – это функция для отображения полей формы в мета боксе. Разберем ее немного позже.
1 2 3 4 5 6 7 8 9 10 11 |
function global_notice_meta_box() { add_meta_box( 'global-notice', __( 'Global Notice', 'sitepoint' ), 'global_notice_meta_box_callback', 'post' ); } add_action( 'add_meta_boxes', 'global_notice_meta_box' ); |
Чтобы вставить мета бокс на несколько экранов с типами постов (пользовательские типы постов post, page и book), создайте массив типов постов, пройдитесь по нему в цикле и с помощью add_meta_box() вставьте его на экраны.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
function global_notice_meta_box() { $screens = array( 'post', 'page', 'book' ); foreach ( $screens as $screen ) { add_meta_box( 'global-notice', __( 'Global Notice', 'sitepoint' ), 'global_notice_meta_box_callback', $screen ); } } add_action( 'add_meta_boxes', 'global_notice_meta_box' ); |
Чтобы вставить мета бокс на все существующие и созданные в будущем экраны с типами постов, создайте массив типов постов с помощью get_post_types(), после чего замените значение $screen сверху на массив.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
function global_notice_meta_box() { $screens = get_post_types(); foreach ( $screens as $screen ) { add_meta_box( 'global-notice', __( 'Global Notice', 'sitepoint' ), 'global_notice_meta_box_callback', $screen ); } } add_action( 'add_meta_boxes', 'global_notice_meta_box' ); |
Вставить мета бокс на все существующие и новые экраны типов постов можно и без третьего аргумента ($screen):
1 2 3 4 5 6 7 8 9 10 11 |
function global_notice_meta_box() { add_meta_box( 'global-notice', __( 'Global Notice', 'sitepoint' ), 'global_notice_meta_box_callback' ); } add_action( 'add_meta_boxes', 'global_notice_meta_box' ); |
Мета бокс можно ограничить типом постов (book в нашем примере). Для этого необходимо вставить имя типа поста в экшен add_meta_boxes:
1 2 3 4 5 6 7 8 9 10 11 |
function global_notice_meta_box() { add_meta_box( 'global-notice', __( 'Global Notice', 'sitepoint' ), 'global_notice_meta_box_callback' ); } add_action( 'add_meta_boxes_book', 'global_notice_meta_box' ); |
Среди аргументов массива, которые использует функция register_post_type() для настройки пользовательских типов постов, есть register_meta_box_cb, чье значение является колбэк функцией. Эта функция вызывается при установке мета боксов.
Например, мы создали пользовательский тип постов book с помощью кода ниже:
1 2 3 4 5 6 7 8 9 10 11 12 |
function book_cpt() { $args = array( 'label' => 'Books', 'public' => true, 'register_meta_box_cb' => 'global_notice_meta_box' ); register_post_type( 'book', $args ); } add_action( 'init', 'book_cpt' ); |
Если добавить функцию add_meta_box(), с помощью которой создается мета бокс внутри PHP функции global_notice_meta_box (значение register_meta_box_cb сверху), это добавит мета бокс на экран редактирования с типом постов book.
И снова наш пример с функцией global_notice_meta_box.
1 2 3 4 5 6 7 8 9 |
function global_notice_meta_box() { add_meta_box( 'global-notice', __( 'Global Notice', 'sitepoint' ), 'global_notice_meta_box_callback' ); } |
Мы выучили разные способы регистрации и вставки мета боксов в WP. Нам еще нужно создать функцию global_notice_meta_box_callback, в которой будет храниться поле формы для нашего мета бокса.
Ниже представлен код функции global_notice_meta_box_callback с текстовой областью в мета боксе.
1 2 3 4 5 6 7 8 9 |
function global_notice_meta_box_callback( $post ) { // Добавляем поле nonce, чтобы потом его проверить. wp_nonce_field( 'global_notice_nonce', 'global_notice_nonce' ); $value = get_post_meta( $post->ID, '_global_notice', true ); echo '<textarea style="width:100%" id="global_notice" name="global_notice">' . esc_attr( $value ) . '</textarea>'; } |
Экшен save_post обрабатывает сохранение данных, введенных в текстовую область, при сохранении черновика или публикации.
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 |
/** * При сохранении поста сохраняем наши пользовательские данные. * * @param int $post_id */ function save_global_notice_meta_box_data( $post_id ) { // Проверяем, задано ли поле nonce. if ( ! isset( $_POST['global_notice_nonce'] ) ) { return; } // Проверяем nonce на валидность. if ( ! wp_verify_nonce( $_POST['global_notice_nonce'], 'global_notice_nonce' ) ) { return; } // Если было автосохранение, наша форма не отправилась, нам ничего делать не нужно. if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { return; } // Проверяем разрешения пользователя. if ( isset( $_POST['post_type'] ) && 'page' == $_POST['post_type'] ) { if ( ! current_user_can( 'edit_page', $post_id ) ) { return; } } else { if ( ! current_user_can( 'edit_post', $post_id ) ) { return; } } /* OK, теперь сохранять данные безопасно. */ // Проверяем. if ( ! isset( $_POST['global_notice'] ) ) { return; } // Очищаем введенные данные. $my_data = sanitize_text_field( $_POST['global_notice'] ); // Обновляем мета поле в базе данных. update_post_meta( $post_id, '_global_notice', $my_data ); } add_action( 'save_post', 'save_global_notice_meta_box_data' ); |
Чтобы поместить данные, которые будут введены в текстовую область мета бокса, мы покажем их до отображения контента поста, в котором они сохранены.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
function global_notice_before_post( $content ) { global $post; // retrieve the global notice for the current post $global_notice = esc_attr( get_post_meta( $post->ID, '_global_notice', true ) ); $notice = "<div class='sp_global_notice'>$global_notice</div>"; return $notice . $content; } add_filter( 'the_content', 'global_notice_before_post' ); |
Объяснение кода
Сперва мы создали функцию global_notice_before_post, которую прицепили к фильтру the_content с параметром $content, в котором хранится контент поста.
В функции подключается глобальная переменная $post, в которой хранится объект WP_Post текущего просматриваемого поста.
Глобальное уведомление, сохраненное для данного поста, вытягивается с помощью get_post_meta и сохраняется в переменную $global_notice.
Уведомление оборачивается в div и записывается в переменную $notice.
И в конце, $notice, где хранится глобальное уведомление, с помощью конкатенации цепляется к $content, где хранится контент поста.
Ниже показан скриншот поста с глобальным уведомлением перед контентом поста.
Заключение
В этом уроке мы изучили несколько способов регистрации мета боксов на экранах в панели администратора WP, а также узнали, как ограничить их типами постов.
Также мы узнали, как добавить поля формы к мета боксу, а также как сохранять введенные данные при сохранении поста или его публикации.
И наконец, мы поняли, как на практике можно применить данные, введенные в мета бокс.
В следующей статье мы узнаем, как добавить контекстную вспомогательную вкладку на экраны с типами постов в панели администратора.
Автор: Collins Agbonghama
Источник: //www.sitepoint.com/
Редакция: Команда webformyself.