Метаданные WordPress: знакомство и способы применения

Метаданные WordPress: знакомство и способы применения

От автора: с выходом WordPress 4.4 в данной CMS появился новый тип метаданных – метаданные терминов. Теперь вы можете сохранять метаданные для терминов так же, как и для постов. Долгожданное нововведение и логическое дополнение WordPress.

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

Что под капотом у метаданных для терминов

Логика далеко не нова и уже использовалась в постах, комментариях и для таблицы пользователей. У метаданных терминов появилась своя таблица termmeta с полями term_id, meta_key, meta_value и автоинкрементом meta_id.

Функции метаданных

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

add_term_meta(): добавляет метаданные

update_term_meta(): обновляет существующие метаданные

delete_term_meta(): удаляет метаданные

get_term_meta(): вытягивает метаданные

Под капотом у этих функций код почти такой же, как для функций метаданных постов.

Как использовать метаданные терминов

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

В проекте использовалась кастомная категория постов, посты были про дома. В качестве терминов кастомной таксономии были заданы свойства дома (т.е. диван, TV и т.д.). Редактору информации о домах необходимо было получить список свойств домов на основе групп. А группы в свою очередь не должны быть свойствами дома. И я решил добавить эту группу через метаданные терминов.

Я использовал свою таксономию house_feature, но если вы хотите добавить метаданные для категорий постов или тегов, можете воспользоваться стандартными category или post_tag. Сперва я создал свою таксономию:

add_action('init', 'register_feature_taxonomy');

function register_feature_taxonomy() {
    $labels = array(
        'name' => _x( 'Features', 'taxonomy general name', 'my_plugin' ),
        'singular_name' => _x('Features', 'taxonomy singular name', 'my_plugin'),
        'search_items' => __('Search Feature', 'my_plugin'),
        'popular_items' => __('Common Features', 'my_plugin'),
        'all_items' => __('All Features', 'my_plugin'),
        'edit_item' => __('Edit Feature', 'my_plugin'),
        'update_item' => __('Update Feature', 'my_plugin'),
        'add_new_item' => __('Add new Feature', 'my_plugin'),
        'new_item_name' => __('New Feature:', 'my_plugin'),
        'add_or_remove_items' => __('Remove Feature', 'my_plugin'),
        'choose_from_most_used' => __('Choose from common Feature', 'my_plugin'),
        'not_found' => __('No Feature found.', 'my_plugin'),
        'menu_name' => __('Features', 'my_plugin'),
    );

    $args = array(
        'hierarchical' => false,
        'labels' => $labels,
        'show_ui' => true,
    );

    register_taxonomy('house_feature', array('houses'), $args);
}

В последней строчке вам необходимо заменить тип поста houses на свой. Если вы хотите использовать новую таксономию на постах по умолчанию, то поставьте значение post.

В случае если вы используете код из данной статьи в файле темы functions.php или внутри плагина, проверьте, чтобы текст домена my_plugin совпадал с текстом домена темы или плагина. Текст домена my_plugin будет работать в плагине с текстом ссылки my_plugin.

Управление группами, которые я назначил свойствам дома, производится из панели настроек. Также это может быть просто массив. Чтобы быстро и наглядно показать принцип работы метаданных терминов для текущих групп я возьму глобальный массив.

$feature_groups = array(
    'bedroom' => __('Bedroom', 'my_plugin'),
    'living' => __('Living room', 'my_plugin'),
    'kitchen' => __('Kitchen', 'my_plugin')
);

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

Добавление метаданных к новому термину

Для того, чтобы расширить форму и добавить термин, необходимо воспользоваться хуком {$taxonomy}_add_form_fields. Для нашей таксономии house_feature это house_feature_add_form_fields.

add_action( 'house_feature_add_form_fields', 'add_feature_group_field', 10, 2 );
function add_feature_group_field($taxonomy) {
    global $feature_groups;
    ?><div class="form-field term-group">
        <label for="featuret-group"><?php _e('Feature Group', 'my_plugin'); ?></label>
        <select class="postform" id="equipment-group" name="feature-group">
            <option value="-1"><?php _e('none', 'my_plugin'); ?></option><?php foreach ($feature_groups as $_group_key => $_group) : ?>
                <option value="<?php echo $_group_key; ?>" class=""><?php echo $_group; ?></option>
            <?php endforeach; ?>
        </select>
    </div><?php
}

Код выше добавляет выпадающий список между оригинальными полями формы и кнопкой отправки.

Форма создания нового термина в кастомной таксономии теперь выглядит так. Для сохранения метаданных термина необходимо запускать специальный хук, created_{$taxonomy}.

add_action( 'created_house_feature', 'save_feature_meta', 10, 2 );

function save_feature_meta( $term_id, $tt_id ){
    if( isset( $_POST['feature-group'] ) && '' !== $_POST['feature-group'] ){
        $group = sanitize_title( $_POST['feature-group'] );
        add_term_meta( $term_id, 'feature-group', $group, true );
    }
}

Данные о термине, полученные из глобального массива $_POST, сохраняются с помощью новой функции add_term_meta(). Как и add_post_meta() функция принимает 4 аргумента:

$term_id: ID термина

$meta_key: мета ключ

$meta_value: значение

$unique: может ли ключ использоваться всего раз или нет. По умолчанию стоит false.

Аргумент $unique я задал в true, так как я хочу, чтобы каждое свойство дома находилось только в одной группе.

Обновление термина с помощью метаданных

Даже если у процессов есть что-то общее, все же добавление нового термина и обновление существующего технически отличается в WordPress. Поэтому необходимо добавить и функцию обновления. Для получения поля для группы в форме редактирования, мы использовали хук {$taxonomy}_edit_form_fields.

add_action( 'house_feature_edit_form_fields', 'edit_feature_group_field', 10, 2 );

function edit_feature_group_field( $term, $taxonomy ){
                
    global $feature_groups;
          
    // получаем текущую группу
    $feature_group = get_term_meta( $term->term_id, 'feature-group', true );
                
    ?><tr class="form-field term-group-wrap">
        <th scope="row"><label for="feature-group"><?php _e( 'Feature Group', 'my_plugin' ); ?></label></th>
        <td><select class="postform" id="feature-group" name="feature-group">
            <option value="-1"><?php _e( 'none', 'my_plugin' ); ?></option>
            <?php foreach( $feature_groups as $_group_key => $_group ) : ?>
                <option value="<?php echo $_group_key; ?>" <?php selected( $feature_group, $_group_key ); ?>><?php echo $_group; ?></option>
            <?php endforeach; ?>
        </select></td>
    </tr><?php
}

Кроме добавления нового элемента в форму, необходимо еще вытянуть данные о существующих терминах с помощью get_term_meta() и выбрать их. Функция принимает три аргумента:

$term_id: ID термина

$key: ключ метаданных

$single: вернуть одно значение или нет. По умолчанию false и возвращает массив.

Так как я ожидаю на выходе одно значение, я установил $single в true. Для сохранения данных необходимо использовать хук edited_{$taxonomy}.

add_action( 'edited_house_feature', 'update_feature_meta', 10, 2 );

function update_feature_meta( $term_id, $tt_id ){

    if( isset( $_POST['feature-group'] ) && '' !== $_POST['feature-group'] ){
        $group = sanitize_title( $_POST['feature-group'] );
        update_term_meta( $term_id, 'feature-group', $group );
    }
}

Вместо добавления новых значений метаданных мы переписываем существующие с помощью update_term_meta().

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

Метаданные сохранены, давайте теперь отобразим их в новой колонке в таблице терминов. Сперва добавим колонку и заголовок к ней. Поиск подходящего хука для добавления новой колонки в таблицу в WordPress опять же процесс немного запутанный, очень много подходящих имен.

В нашем случае можно использовать шаблон manage_edit-{$taxonomy}_columns, хотя хук не совсем так задан.

add_filter('manage_edit-house_feature_columns', 'add_feature_group_column' );

function add_feature_group_column( $columns ){
    $columns['feature_group'] = __( 'Group', 'my_plugin' );
    return $columns;
}

Для добавления контента в колонку воспользуйтесь шаблоном manage_{$taxonomy}_custom_column.

add_filter('manage_house_feature_custom_column', 'add_feature_group_column_content', 10, 3 );

function add_feature_group_column_content( $content, $column_name, $term_id ){
    global $feature_groups;

    $term_id = absint( $term_id );
    $feature_group = get_term_meta( $term_id, 'feature-group', true );

    if( !empty( $feature_group ) ){
        $content .= esc_attr( $feature_groups[ $feature_group ] );
    }

    return $content;
}

Еще раз, с помощью get_term_meta() мы получаем значения и просто прикрепляем их к существующему контенту. Другие разработчики могут прикрепить что-то другое.

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

add_filter( 'manage_edit-house_feature_sortable_columns', 'add_feature_group_column_sortable' );

function add_feature_group_column_sortable( $sortable ){
    $sortable[ 'feature_group' ] = 'feature_group';
    return $sortable;
}

Вот так теперь должна выглядеть наша таблица с дополнительной колонкой под метаданные терминов:

Список терминов с таблицей метаданных.

Удаление метаданных термина

При удалении термина, вместе с ним удаляются и соответствующие метаданные. Так что не надо убираться за собой. Однако если потребуется все же удалить метаданные термина, можно воспользоваться функцией delete_term_meta(). Она принимает три аргумента:

$term_id: ID термина

$meta_key: мета ключ

$meta_value: предыдущее значение

Метаданные с заданным значением можно удалить по полю $meta_value.

Получение терминов по мета значению

Как и с постами, вы можете вытянуть термины по мета значениям. Необходимо задать параметр meta_query в функциях get_terms() и wp_get_object_terms(). По следующему запросу я получу все свойства дома по группе kitchen.

$args = array(
    'hide_empty' => false, // also retrieve terms which are not used yet
    'meta_query' => array(
        array(
           'key'       => 'feature-group',
           'value'     => 'kitchen',
           'compare'   => 'LIKE'
        )
    )
);
                
$terms = get_terms( 'house_feature', $args );

Синтаксис у meta_query такой же, как и у WP_Query, что позволяет использовать различные операторы для compare: NOT LIKE, EXISTS или BETWEEN.

Так как для группировки терминов я использую метаданные, было бы просто замечательно получить результат, отсортированный по мета значению. Но в отличие от WP_Query, тут нельзя использовать orderby => meta_value. Результат можно сортировать только после получения. Для отображения терминов и метаданных необходимо пробежаться циклом по результату выборки и использовать функцию get_term_meta().

if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){
    echo '<ul>';
    foreach ( $terms as $term ) {
        echo '<li>' . $term->name . ' (' . get_term_meta( $term->term_id, 'feature-group', true ) . ')' . '</li>';
    }
    echo '</ul>';
}

Заключение

Я знаю множество проектов, которые уже сохраняют метаданные в кастомных таксономиях. С распространением WordPress 4.4 большинство из них, вероятнее всего, обновят и будут использовать новую логику метаданных.

Мне теперь не хватает всего одной вещи – это возможности прикрепления метаданных к конкретным связям термин-объект. Если вы знаете, как это сделать, пишите в комментариях.

Автор: Thomas Maier

Источник: http://www.smashingmagazine.com/

Редакция: Команда webformyself.

Хотите быстро научиться создавать сайты и блоги на WordPress с уникальным дизайном?

Получите самую полную в Рунете бесплатную систему обучения создания сайтов на WordPress “Уникальный сайт с нуля”

Получить

Метки: ,

Комментарии Вконтакте:

Комментарии Facebook:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree