От автора: в WordPress вы с легкостью можете сохранять метаданные для постов, страниц и других типов пользовательского контента, однако сохранение метаданных для таксономий раньше было слишком сложным процессом.
Раньше чтобы все заработало, необходимо было для каждого элемента данных сохранить метаданные термина как поле в таблице wp_options, и если у вас приличное количество терминов или просто несколько пользовательских таксономий это потенциально могло привести к появлению сотен, если не тысяч записей.
Однако с WordPress 4.4 и выше термины стали объектами, такими же как посты, страницы и пользовательские типы данных. Это изменение сильно упростило процесс добавления, удаления и обновления метаданных.
Предыстория Term Meta
Сообщество искало легкий способ контроля над терминами еще с WordPress 2.8. Процесс был медленный, однако наконец термины были переработаны с нуля для использования классовой структуры. Парочка изменений в WordPress 4.4 означает, что теперь термины в таксономиях (как теги, категории или другие) могут иметь свои собственные мета данные.
Старый способ манипуляции метаданными
До WP 4.4 не было четкого способа сохранения метаданных для терминов, это было неотъемлемое ограничение в самом строении терминов. Если вы расширяли таксономии или термины, вам приходилось сохранять данных напрямую в качестве опции сайта с помощью update_option. Не самый идеальный способ (он забивал таблицу опций).
Я уже писал о расширении таксономий, однако как только вы были готовы сохранить метаданные, вы должны были вызвать функцию наподобие этой:
1 2 3 4 5 6 7 8 9 10 |
//сохранение новых полей для категории function save_extra_taxonomy_fields($term_id){ $term = get_term($term_id); $term_slug = $term->slug; //собираем id категорий изображений из значений $term_category_image_id = isset($_POST['category_image_id']) ? sanitize_text_field($_POST['category_image_id']) : ''; //обновляем значение и сохраняем как опцию update_option('category_image_id_' . $term_slug, $term_category_image_id); } add_action('create_category','save_extra_taxonomy_fields'); |
В примере выше мы запустили функцию из хука create_category (срабатывает при создании нового термина категорий). Функция ищет наши значения и после обработки сохраняет их как опции. Способ рабочий, но не самый красивый.
Как добавить, обновить и удалить Term Meta
Для работы с метаданными терминов вам понадобятся функции add_term_meta, update_term_meta и delete_term_meta. Эти функции в паре с новыми элементами UI позволят вам сохранять и обновлять новые метаданные для терминов.
Как добавить метаданные терминов
Для добавления метаданных в термин нам понадобится функция add_term_meta. Необходимо задать 3 обязательных и 1 необязательный параметр.
$term_id – ID термина, к которому хотите сохранить метаданные
$meta_key – ключевое имя метаданных. Как вы будете обращаться к данным
$meta_value – Сами данные
$unique (необязательный) – Уникальность ключа метаданных. По умолчанию задано false, т.е. если другой ключ имеет такое же название, функцию перепишет его. Чтобы ключи были уникальными, необходимо установить true.
Пример: представьте, что ко всем терминам таксономии category вы хотите прикрепить новые метаданные на основе количества постов, принадлежащих данной категории. В WP 4.4 мы можем пройтись циклом по всем терминам и сохранить новые метаданные (чтобы потом использовать их в теме или плагинах).
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 |
function add_featured_to_categories(){ //получаем все термины из category $taxonomy_name = 'category'; $term_args = array( 'orderby' => 'name', 'hide_empty' => false, 'fields' => 'ids' ); $terms = get_terms($taxonomy_name, $term_args); if($terms){ $term_key = 'term_size'; $term_value = 'empty'; $term_unique = true; //проходимся по всем терминам и задаем новые метаданные терминов foreach($terms as $term_id){ $term = get_term($term_id, $taxonomy_name); $term_count = $term->count; //задаем новое значение метаданных if($term_count > 10){ $term_value = 'big'; }else if($term_count >= 5 && $term_count < 10){ $term_value = 'medium'; }else if($term_count >= 1 && $term_count < 5){ $term_value = 'small'; } //сохраняем значение add_term_meta($term_id, $term_key, $term_value, $term_unique); } } } add_action('init', 'add_featured_to_categories'); |
Как читать метаданные терминов
С помощью функции get_term_meta мы можем считывать сохраненные метаданные терминов. Функция работает схожим образом с get_post_meta, которая нужна для вытягивания метаданных из постов. Для работы с ней необходимо задать один обязательный и два опциональных параметра.
$term_id –ID термина, из которого будут вытягиваться метаданные
$key (опциональный) – Ключ, который вы хотите вернуть. Если не задан, возвращаются все метаданные.
$single (опциональный) – Если значение одно, будет возвращен ключ или пара значений. По умолчанию значение одно.
Рассмотрим еще один сценарий, где может понадобиться данная функция. Рассмотрим ситуацию, когда у нас уже сохранены метаданные ко всем терминам в таксономии category. В этих данных хранится URL изображения, которое должно отображаться при просмотре терминов. Мы хотим показывать это изображение как баннер под описанием или заголовком термина, но выше списка постов.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
function display_term_meta_image($term_id, $term_taxonomy){ //получаем термины $term = get_term($term_id, $term_taxonomy); if($term){ $term_image_id = get_term_meta($term_id, 'term_image_id', true); if($term_image_id){ //получаем среднее изображение для отображения $term_image = wp_get_attachment_image_src($term_image_id, 'medium', false); echo '<img src="' . $term_image[0] . '" title="' . $term->name . ' image"/>'; } } } |
Теперь в файле category.php или другом файле шаблона дочерней темы мы можем изменить функционал отображения терминов. В моем примере используется тема Twenty Fourteen, редактировал я файл category.php, а функцию вызываю сразу после описания термина.
1 2 3 4 5 6 |
//получаем текущий объект (термин) $term_obj = get_queried_object(); //отображаем изображение для него if(function_exists('display_term_meta_image')){ display_term_meta_image($term_obj->term_id, $term_obj->taxonomy); } |
Фото отобразится сразу после описания:
Как удалить метаданные терминов
Удалить метаданные терминов можно точно так же, как и для постов. В функции delete_term_meta необходимо задать два обязательных и 1 опциональный параметр.
$term_id –ID термина.
$meta_key – Мета ключ, который следует удалить из термина.
$meta_value (опциональный) – Удаляет метаданные, если значение совпадает переменной. Используйте этот параметр, если необходимо удалить какие-то определенные данные.
И опять же, рассмотрим сценарий, когда это можно использовать. Представьте, что у вас уже наполовину готов крупный проект, и вы уже сохранили различные метаданные во всех терминах категорий. И вдруг какие-то данные вам больше не нужны, т.е. вы можете почистить их, чтобы они не засоряли базу данных.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
//удаленные метаданные, которые нам больше не нужны в терминах категорий function delete_old_meta_data_from_category(){ //получаем все термины категорий $terms = get_terms('category', array('hide_empty' => false, 'fields' => 'ids')); if($terms){ //list of allowed term keys $allowed_term_keys = array('term_image_id', 'term_size'); //проходим циклом по всем терминам foreach($terms as $term_id){ $term_meta = get_term_meta($term_id); //проходим по всем метаданным в термине foreach($term_meta as $meta_key => $meta_value){ //если ключа нет среди заданных, удаляем его if(!array_key_exists($meta_key, $allowed_term_keys)){ delete_term_meta($term_id, $meta_key); } } } } } add_action('init', 'delete_old_meta_data_from_category'); |
Функция проходится по всем метаданным и удаляет те, которые не заданы в переменной $allowed_term_keys, тем самым освобождая место в базе данных (полезно, когда у нас остались десятки ненужных записей).
Обратная совместимость с WordPress 4.3 и ниже
Если вы хотите использовать данные функции, но также поддерживать старые версии, можно создать дополнительный функционал, чтобы все стабильно работало.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
//добавляем метаданные в термин function add_term_meta_compat($term_id, $term_key, $term_value){ if(function_exists('add_term_meta')){ //WP4.4+ add_term_meta($term_id, $term_key, $term_value, true); }else{ //Pre WP4.4 //получаем объект термина и данные $term_object = get_term($term_id); $term_taxonomy = $term_object->taxonomy; //создаем финальный ключ для сохранения (tax + termid + key) $term_final_key = ($term_taxonomy . '_' . $term_id . '_' . $term_key); //проверяем, чтобы ключ не был длиннее 64 символов (max limit) $term_final_key = strlen($term_final_key > 64) ? substr($term_final_key, 0, 63) : $term_final_key; //добавляем новую опцию add_option($term_final_key, $term_value); } } |
Начали мы с вызова функции function_exists, чтобы проверить, что новая функция add_term_meta задана. Данная функция работает только в WP 4.4 и выше. Если нужно поддерживать старые версии, используйте обычную функцию add_term_meta для привязки метаданных к нашим терминам.
Если поддержки нет, мы вытягиваем сам объект термина (через его ID), а из него извлекаем $term_taxonomy и используем эту переменную для создания финального ключевого значения. После сохранения данных в таблице опций необходимо проверить ключ на уникальность. Сделать это можно, добавив в одну переменную имя таксономии, ID термина и ключа термина. Необходимо проверить, что ключ не превышает 64 символа. Если превышает, необходимо обрезать. После всего можно вызывать функцию add_option для сохранения.
Как видите, метод немного длиннее, но он более гибкий, так как появляется поддержка старых и новых версий WordPress.
Заключение
Эти новые функции должны расширить возможности и упростить процесс управления терминами, а также добавить уникальный функционал. К примеру, вы захотите добавить изображение сверху от термина или получить метаданные. Тогда вы можете по-разному отображать термины по условию (как загрузка нового файла шаблона на основе отображаемого термина).
Благодаря гибкости и простоте новых функций для работы с метаданными вы можете начать использовать их в своих новых проектах уже сегодня!
Автор: Simon Codrington
Источник: //www.sitepoint.com/
Редакция: Команда webformyself.