Від автора: з виходом 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;
?>
Код вище додає випадаючий список між оригінальними полями форми і кнопкою відправлення.
Форма створення нового терміна в кастомних таксономії тепер виглядає так. Для збереження метаданих терміна необхідно запускати спеціальний хук, 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 );
?>
Крім додавання нового елемента в форму, необхідно ще витягнути дані про існуючі термінах з допомогою 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 ‘
- ‘;
- ‘. $term->name . ‘(‘ . get_term_meta( $term->term_id, ‘feature-group’, true ) . ‘)’ . ‘
foreach ( $terms as $term ) {
echo ‘
‘;
}
echo ‘
‘;
}
Висновок
Я знаю безліч проектів, які вже зберігають метадані в кастомних таксономиях. З поширенням WordPress 4.4 більшість з них, найімовірніше, оновлять і будуть використовувати нову логіку метаданих.
Тепер мені не вистачає всього однієї речі – це можливість прикріплення метаданих до конкретних зв’язків термін-об’єкт. Якщо ви знаєте, як це зробити, пишіть в коментарях.