Вопрос или проблема
На моем сайте у меня есть пользовательский тип записи “listing”, который имеет иерархическую таксономию “local”.
Термины в этой таксономии представлены в форме Штаты > Города.
Например, “Вашингтон” является родительским термином, а Арлингтон, Оберн, Давенпорт и т.п. могут быть дочерними таксономиями.
Теперь, когда я экспортирую и импортирую этот пользовательский тип записи на другой сайт, мои дочерние таксономии становятся верхнего уровня и больше не сохраняют иерархию.
Я использовал код в functions.php для их создания, без плагинов. Что я делаю не так?
Я понимаю вашу проблему и также пришлось с ней справляться: wp_insert_term()
не обрабатывает связи родитель/дочерний.
Вы можете проверить это следующим образом:
$tax = 'category';
$terms = get_terms( array( $tax ) );
$children_to_update = array();
foreach ( $terms as $term )
{
$checked_term = get_term_by( 'name', $term, $tax );
// ... получаем родителя здесь ...
if ( ! $checked_term )
{
$term_data = wp_insert_term(
$term,
$tax,
array( 'parent' => $parent )
);
if (
is_array( $term_data )
AND ! is_wp_error( $term_data )
AND '0' !== $parent
)
$children_to_update[ $parent ][] = $term_data['term_id'];
}
}
// проверяем результат
var_dump( $children_to_update );
Вы увидите, что он остается пустым. Причина проста: существует опция, которая содержит эту информацию. Вам нужно обновить ее также:
$option = get_option( "{$tax}_children" );
foreach( $children_to_update as $new_p => $new_c )
{
if ( ! array_key_exists( $new_p, $option ) )
{
$option[ $new_p ] = $new_c;
}
else
{
foreach ( $new_c as $c )
{
if ( ! in_array( $c, $option[ $new_p ] ) )
$option[ $new_p ][] = $c;
}
}
}
update_option( "{$tax}_children", $option );
Изначально я не понял, что иерархия не работала, но когда вы смотрите на страницу обзора таксономии в интерфейсе администратора, вы увидите, что термины не выровнены, как должны (в дочерних/родительских списках).
Ответ или решение
Теория
Вы столкнулись с распространенной проблемой, возникающей при переносе иерархических таксономий между сайтами WordPress. Когда вы экспортируете и импортируете настраиваемый тип записи вместе с таксономией, которая имеет иерархическую структуру, например, "Штаты > Города", часто случается так, что дочерние термины утрачивают свою иерархию в процессе импорта. Это проблема связана с тем, что функция wp_insert_term()
в WordPress не обрабатывает связи родитель/дочерний, т.е. не сохраняет иерархию таксономии при ее восстановлении на новом сайте.
Пример
Представьте, что у вас есть настраиваемый пост типа "listing", с таксономией "local", где, например, "Вашингтон" является родительским термином, а "Арлингтон", "Оберн", "Давенпорт" — его дочерними терминами. При переносе этой структуры на новый сайт, дочерние термины становятся родительскими, нарушая первоначальную иерархию.
Применение
Теперь необходимо разобраться, как исправить эту проблему и правильно настроить импорт таксономий так, чтобы сохранить структуру. Сначала нужно импортировать термины таксономии и назначить им родителей после импорта. Это достигается путем манипуляции с опцией, где WordPress хранит информацию об иерархии таксономий — "{имя_таксономии}_children"
.
Шаги по решению проблемы:
-
Получение всех терминов:
Используйте функциюget_terms()
для получения списка всех терминов вашей таксономии.$tax = 'local'; $terms = get_terms(array('taxonomy' => $tax, 'hide_empty' => false));
-
Проверка текущих терминов:
Следующим шагом будет цикл по этим терминам и проверка, присутствует ли каждый терм на целевом сайте, используяget_term_by()
. -
Восстановление иерархии:
Если термина нет, применитеwp_insert_term()
для добавления термина с указанием родительского термина. Если родитель уже импортирован, укажите его ID. -
Обновление иерархической структуры:
Применитеupdate_option()
для обновления информации об иерархии в базе данных WordPress. Вам придется вручную обновить опцию"{имя_таксономии}_children"
.$option = get_option("{$tax}_children"); foreach ($children_to_update as $new_p => $new_c) { if (!array_key_exists($new_p, $option)) { $option[$new_p] = $new_c; } else { foreach ($new_c as $c) { if (!in_array($c, $option[$new_p])) { $option[$new_p][] = $c; } } } } update_option("{$tax}_children", $option);
-
Проверка результатов:
После обновления опции убедитесь, что иерархия была восстановлена. Это можно увидать на странице администрирования таксономии, где должна быть видна правильная структура родитель/дочерний термин.
Этот подход требует некоторой ручной работы по проверке наличия терминов и их обновления, но он решает проблемы, возникающие при стандартном процессе экспорта/импорта WordPress, который не учитывает иерархические связи.
Заключение
Таким образом, чтобы эффективно переносить иерархические таксономии между сайтами WordPress, необходимо использовать продуманную стратегию по реализации иерархии после импорта. Прямой импорт данных редко сохраняет структуры сложных таксономий корректно, и в этом случае требуется дополнительное кодирование для исправления структуры родитель/дочерний термин. Применяя правильные функции WordPress и обновляя нужные опции, можно восстановить иерархию и обеспечить корректное отображение таксономий на новом сайте.