Я уже писал про добавление метабоксов к постам (записям, страницам, произвольным типам постов), теперь давайте разберемся, как добавлять произвольные поля (дополнительные настройки) на страницы редактирования рубрик, меток и прочих таксономий, которые вы можете насоздавать.
Шаг 1. Создание таблицы в базе данных
Всё дело в том, что, в отличии от метабоксов для постов, которые можно прикрутить на основе значений произвольных полей постов, то для таксономий WordPress тупо не предусматривает никаких метаданных, места в базе данных для них не предназначено.
Ну что же, похоже, что единственный выход — это создание собственной таблицы в БД, наподобие wp_postmeta
.
Вообще назвать нужно её wp_termmeta
(естественно префикс может быть другим), иначе стандартные вордпрессовские функции по работе с метаданными у нас просто не будут работать.
Есть два способа создания таблицы:
- Лезем в phpMyAdmin и создаем там.
- Через SQL-запрос, который можно задействовать прямо в коде.
Способ 1. Создание таблицы в базе данных через phpMyAdmin
Открываем phpMyAdmin, выбираем базу данных своего сайта, затем нажимаем на ссылку . Настройки выставляем примерно следующие, одним словом ориентируемся на таблицу wp_postmeta
.
Способ 2. Использование SQL-запроса для создания таблицы
Тут я подразумеваю код, который мы вставим в functions.php
, после чего таблица сразу создастся. Понятное дело, что код нужно выполнить только один раз, а значит, лучше всего повесить его например на активацию темы.
if ( is_admin() && isset($_GET['activated'] ) && $pagenow == "themes.php" ) { // вешаем запрос создания таблицы на активацию темы global $wpdb; // глобальный класс $wpdb необходим при работе с базой данных в WordPress $collate = ''; if($wpdb->has_cap('collation')) { if(!empty($wpdb->charset)) $collate = "DEFAULT CHARACTER SET $wpdb->charset"; if(!empty($wpdb->collate)) $collate .= " COLLATE $wpdb->collate"; } // дальше идет сам SQL запрос $wpdb->query("CREATE TABLE IF NOT EXISTS ". $wpdb->prefix . "termmeta ( `meta_id` bigint(20) NOT NULL AUTO_INCREMENT, `term_id` bigint(20) NOT NULL, `meta_key` varchar(255) NOT NULL, `meta_value` longtext DEFAULT '' NOT NULL, PRIMARY KEY id (`meta_id`)) $collate;" ); } |
После того, как таблица будет создана, можно будет перейти к следующему шагу.
Шаг 2. Универсальное решение по добавлению настроек — использование PHP класса
Реально — использование готового класса это круто и легко. Вы на лету сможете создавать столько настроек в таксономиях, сколько захотите.
И я дам вам готовый класс с некоторыми базовыми полями: <input>
(текстовый и чекбокс), <select>
, <textarea>
. Также вы можете прикрутить поле с загрузкой изображения, используя код из этого поста.
Я решил не добавлять в код вообще ничего лишнего (я не хочу сказать, что nonce-проверки и проверки на права пользователей — лишнее, просто в этом примере я от них отказался для простоты восприятия кода).
<?php class trueTaxonomyMetaBox { /* * Функция-конструктор, в ней мы активируем хуки */ function __construct( $options ) { $this->options = $options; $this->prefix = $this->options['id'] .'_'; // префикс настроек foreach ( $this->options['taxonomy'] as $taxonomy ) { // для каждой таксономии, которая указана в параметрах add_action($taxonomy . '_edit_form_fields', array(&$this, 'fill'), 10, 2 ); // хук добавления полей } add_action('edit_term', array(&$this, 'save'), 10,1); // хук сохранения значений полей } /* * Функция, создающая поля, я описал в ней текстовые поля (input type=text и textarea), чекбокс и выпадающий список */ function fill( $term, $taxonomy ){ foreach ( $this->options['args'] as $param ) { // для каждого описанного параметра... ?><tr class="form-field"><?php // определяем значение произвольного поля таксономии if(!$value = get_metadata('term', $term->term_id, $this->prefix .$param['id'], true)) $value = $param['std']; switch ( $param['type'] ) { // input[type="text"] 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 ?>" class="regular-text" /> <?php if(isset( $param['desc'] ) ) echo '<p class="description">' . $param['desc'] . '</p>' ?> </td> <?php break; } // textarea 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 ?>" class="large-text" /><?php echo $value ?></textarea> <?php if(isset( $param['desc'] ) ) echo '<p class="description">' . $param['desc'] . '</p>' ?> </td> <?php break; } // input[type="checkbox"] 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 if(isset( $param['desc'] ) ) echo $param['desc'] ?></label> </td> <?php break; } // select 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> <?php if(isset( $param['desc'] ) ) echo '<p class="description">' . $param['desc'] . '</p>' ?> </td> <?php break; } } ?></tr><?php } } /* * Функция сохранения значений полей */ function save( $term_id ){ foreach ( $this->options['args'] as $param ) { if ( isset( $_POST[ $this->prefix . $param['id'] ] ) && trim( $_POST[ $this->prefix . $param['id'] ] ) ) { update_metadata('term', $term_id, $this->prefix . $param['id'], trim($_POST[ $this->prefix . $param['id'] ], '') ); } else { delete_metadata('term', $term_id, $this->prefix . $param['id'], '', false); } } } } |
Добавив этот класс в свой плагин или тему, можно приступить к заданию параметров класса, или иначе говоря к созданию настроек.
Вот пример:
$options = array( array( 'id' => 'metatax', // айдишник играет роль префикса названий полей 'taxonomy' => array('category', 'game'), // укажите таксономии, для которых нужно добавить ниже перечисленные поля 'args' => array( array( 'id' => 'order', // атрибуты name и id без префикса, например с префиксом будет meta1_field_1 'title' => 'Порядок', // лейбл поля 'type' => 'text', // тип, в данном случае обычное текстовое поле 'desc' => 'Укажите порядок сортировки.', // описание 'std' => '0' // значение поля по умолчанию ), array( 'id' => 'homepage', 'title' => 'Главная', 'type' => 'checkbox', // чекбокс 'desc' => 'Отображать на главной странице в списке рубрик', 'std' => '' ) ) ), array( 'id' => 'metagame', 'taxonomy' => array('game'), 'args' => array( array( 'id' => 'genre', 'title' => 'Жанр игры', 'type' => 'select', // выпадающий список 'desc' => 'Выберите жанр из выпадающего списка.', 'std' => '', 'args' => array('mmorpg' => 'MMORPG', 'strategy' => 'Стратегия', 'racing' => 'Гонки' ) // элементы задаются через массив, по типу атрибут value=>лейбл ), array( 'id' => 'reqs', 'title' => 'Системные требования', 'type' => 'textarea', 'std' => '' ) ) ) ); foreach ($options as $option) { $truetaxmetabox = new trueTaxonomyMetaBox($option); } |
Вот результат:
Вот в принципе и всё. Я написал только про самое основное.
Если у вас будут какие-то вопросы, пожалуйста, оставляйте их в комментариях к посту, обязательно постараюсь вам помочь.
Источник: misha.blog