Как получить 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();
}
Этот вариант также имеет преимущество в виде достаточно аккуратной обработки ошибок.
Спасибо за ответ, и, вероятно, я буду использовать подобный фрагмент кода в будущем, но он также вызывает ошибки, если запись находится в родительской категории / категории без подкатегорий.
DLR
Я обнаружил, что большинство вышеперечисленных решений не работают для пользовательских типов записей. Поэтому я написал следующую функцию.
Принимая 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 — это новое каноническое свойство! Думаю, это лучше оформить как правку к существующему ответу, а не как совершенно новый ответ :)
bosco