Как получить slug родительской категории текущей записи
В моей теме используется стилизация по категориям с помощью следующего кода, который добавляет slug текущей категории как CSS-класс.
<div class="CategorySpecificStyle
<?php $category = get_the_category(); echo $category[0]->slug; ?>">
<?php echo $category[0]->cat_name; ?>
</div>
Сейчас я собираюсь добавить большое количество новых подкатегорий, и кажется нелогичным добавлять их все в CSS, когда можно просто выбрать родительскую категорию текущей записи и применить стили к ней.
Мне удалось получить название родительской категории:
$parentcat = get_cat_name($category[0]->category_parent);
Но пробелы (и регистр букв) вызывают проблемы... И я не могу получить slug родительской категории.
Наверное, я упускаю что-то простое, но буду благодарен за любые подсказки.

Вам понадобится использовать значение ID, возвращаемое $category[0]->category_parent
, и передать его в функцию get_term()
. Пример:
$category = get_the_category();
$category_parent_id = $category[0]->category_parent;
if ( $category_parent_id != 0 ) {
$category_parent = get_term( $category_parent_id, 'category' );
$css_slug = $category_parent->slug;
} else {
$css_slug = $category[0]->slug;
}

Вам потребуется запросить данные родительской категории. Функция get_category
как раз предназначена для этого.
$category = get_the_category();
$parent = get_category($category[0]->category_parent);
echo $parent->slug;
Этот код вернет непосредственного родителя категории. Например, для такой структуры категорий:
- Мультфильмы
- Собаки
- Скуби-Ду
- Собаки
При передаче ID категории "Скуби-Ду" код вернет "Собаки". Если же вам нужна самая верхняя родительская категория ("Мультфильмы") независимо от глубины вложенности, используйте такой код:
$category = get_the_category();
$parent = get_ancestors($category[0]->term_id, 'category');
if (empty($parent)) {
$parent[] = array($category[0]->term_id);
}
$parent = array_pop($parent);
$parent = get_category($parent);
if (!is_wp_error($parent)) {
var_dump($parent);
} else {
echo $parent->get_error_message();
}
Этот вариант также имеет преимущество в виде достаточно аккуратной обработки ошибок.

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

Я обнаружил, что большинство вышеперечисленных решений не работают для пользовательских типов записей. Поэтому я написал следующую функцию.
Принимая ID текущей (дочерней) категории, функция поднимается вверх по цепочке, чтобы получить родительские категории. Возвращает массив, содержащий URL, название, слаг и ID родителей.
/** * @param $category_id * * @return array Возвращает либо пустой массив, если родителей нет, либо * массив категорий от базовой категории[0] до родительской * Массив содержит подмассивы с ['id'], ['name'], ['slug'], ['url'] * */ function get_category_parent_array( $category_id, $category_taxonomy = 'category'){ $category_id = abs((int)$category_id); $category_taxonomy = sanitize_key( $category_taxonomy); // Проверка на корневую родительскую категорию (id = 0) if( 0 == $category_id ){ return array(); } $child_category = get_term( $category_id, $category_taxonomy); if( empty($child_category)){ return array(); } $parent_category_id = $child_category->parent; if( 0 == $parent_category_id ){ return array(); // Мы не можем получить категорию с ID 0. } // Мы уже проверили, что parent_id не равен 0, но делаем двойную проверку на случай других проблем $parent_category = get_term( $parent_category_id, $category_taxonomy); if ( empty ( $parent_category ) ){ return array(); } // Подготавливаем возвращаемый массив $parent_array = array(); $parent_array['id'] = $parent_category_id; $parent_array['slug'] = esc_attr($parent_category->slug); $parent_array['name'] = esc_attr($parent_category->name); $parent_array['url'] = esc_url(get_term_link( $parent_category)); if ( 0 == $parent_category_id ){ return $parent_array; }else{ $new_parent = get_category_parent_array($parent_category_id, $category_taxonomy ); if(! empty( $new_parent ) ){ return array( $new_parent, $parent_array); }else{ return $parent_array; } } }
Например. В цепочке Главная>Продукция>Пластиковые-Пакеты>Полиэтиленовые-Пакеты>3muBags Где дочерняя/текущая категория - 3mu, функция возвращает следующее:
array ( 0 => array ( 'id' => 260, 'slug' => 'plastic-bags', 'name' => 'Plastic Bags', 'url' => 'https://example.com/product_category/plastic-bags/', ), 1 => array ( 'id' => 261, 'slug' => 'polybags', 'name' => 'Polybags', 'url' => 'https://exmapl.com/product_category/polybags/', ), );

Мне нравится предыдущий ответ от @s_ha_dum, но для получения родительской категории независимо от глубины вложенности я использовал, на мой взгляд, более простое решение:
$cats = get_the_category();
foreach ( $cats as $cat ) {
if ( $cat->category_parent == 0 ) {
return $cat->name; // ...или любой другой атрибут/обработку, которую вы хотите
}
}
return ''; // Это было из шорткода; измените возвращаемое значение по вашему усмотрению

Если кому-то пригодится... получить дочернюю или родительскую категорию, в зависимости от значения 0
или 1
, которое вы укажете в $category
$category = get_the_category();
$parent = get_cat_name( $category[0]->category_parent );
if( ! function_exists('get_cat_slug') )
{
function get_cat_slug($cat_id) {
$cat_id = (int) $cat_id;
$category = &get_category($cat_id);
return $category->slug;
}
}
if ( !empty($parent) ) {
$output .= '<H2>' . esc_html( $category[1]->name ) . '</H2>';
} else {
$output .= '<H2>' . esc_html( $category[0]->name ) . '</H2';
}

Вы можете упростить это следующим образом:
$category = get_the_category(); // Получаем категории текущего поста
$cat_parent = $category[0]->category_parent; // Получаем ID родительской категории
$category = $cat_parent != 0 ? get_term($cat_parent, 'category')->slug : $category[0]->slug; // Используем слаг родительской категории, если она есть, иначе слаг текущей категории

Следующая функция адаптирована для возврата корневой категории:
function get_root_category($category = null) {
if (!$category) $category = get_the_category()[0];
$ancestors = get_ancestors($category->term_id, 'category');
if (empty($ancestors)) return $category;
$root = get_category(array_pop($ancestors));
return $root;
}
Использование:
get_root_category()->slug

Все приведенные выше ответы верны, за исключением того, что "category_parent" теперь заменен на "parent" с 2018 года!
В 2021 году:
$custom_tax = 'books_category'; //Пользовательская таксономия
//Получаем термины по ID записи
$terms = get_the_terms( $post->ID, $custom_tax );
$parent_id = $terms[0]->parent;
if ($parent_id != 0){
$parent = get_term( $parent_id, $custom_tax);
echo $parent->slug;
}

Имена свойств parent
и category_parent
должны быть взаимозаменяемыми, поскольку объекты категорий проходят через функцию _make_cat_compat()
. Тем не менее, вы правы в том, что parent
— это новое каноническое свойство! Думаю, это лучше оформить как правку к существующему ответу, а не как совершенно новый ответ :)
