Как получить slug родительской категории текущей записи

25 янв. 2014 г., 23:40:08
Просмотры: 92.2K
Голосов: 16

В моей теме используется стилизация по категориям с помощью следующего кода, который добавляет 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 родительской категории.

Наверное, я упускаю что-то простое, но буду благодарен за любые подсказки.

0
Все ответы на вопрос 9
0
26

Вам понадобится использовать значение 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;
}
26 янв. 2014 г. 00:28:52
2

Вам потребуется запросить данные родительской категории. Функция 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();
}

Этот вариант также имеет преимущество в виде достаточно аккуратной обработки ошибок.

26 янв. 2014 г. 00:22:07
Комментарии

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

DLR DLR
26 янв. 2014 г. 02:10:03

@DLR: Да, я знаю. Мне пришлось уйти, прежде чем я смог завершить ответ. Я работал над чем-то более сложным и надежным. Смотрите обновление.

s_ha_dum s_ha_dum
26 янв. 2014 г. 02:30:13
0

Я обнаружил, что большинство вышеперечисленных решений не работают для пользовательских типов записей. Поэтому я написал следующую функцию.

Принимая 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/',
  ),
);

9 мая 2023 г. 05:02:19
0

Мне нравится предыдущий ответ от @s_ha_dum, но для получения родительской категории независимо от глубины вложенности я использовал, на мой взгляд, более простое решение:

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

Если кому-то пригодится... получить дочернюю или родительскую категорию, в зависимости от значения 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';
}
22 мар. 2019 г. 12:51:49
0

Вы можете упростить это следующим образом:

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

Следующая функция адаптирована для возврата корневой категории:

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

21 янв. 2020 г. 18:31:18
1

Все приведенные выше ответы верны, за исключением того, что "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;
}
6 авг. 2021 г. 12:53:40
Комментарии

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

bosco bosco
6 авг. 2021 г. 19:56:39
0

Для таксономий в 2021 году

$capitulos = get_the_terms( $post->ID, 'capitulos' );
if ($capitulos) {
foreach($capitulos as $capitulo) { if ($capitulo->parent == 0) 
echo '<a href="' . get_term_link($capitulo->term_id) . '">' . $capitulo->name . '</a> ';}
}
15 февр. 2022 г. 21:51:54