Поддержка Проблемы и решения Вывод списка вложенных термов и записей привязанных к текущему терму.

  • Добрый день.
    Только начал осваивать wp и столкнулся с простейшей задачей: вывести список дочерних термов и записей. Благодаря поиску нашел некоторые решения, но хотелось бы разобраться, возможно есть более простые решения.

    Что имеется:

    • собственный тип записей ‘catalog’
    • привязанная к типу таксономия ‘catalog-category’ с поддержкой иерархии

    [spoiler]

    
    add_action( 'init', 'register_catalog_type' );
    add_filter( 'post_type_link', 'catalog_permalink', 1, 2 );
    function register_catalog_type() {
        register_taxonomy( 'catalog-category', array( 'catalog' ), array(
            'labels'            => array(
                'name'              => 'Категории',
                'singular_name'     => 'Категория',
                'search_items'      => 'Искать категорию',
                'all_items'         => 'Все категории',
                'parent_item'       => 'Родительская категория',
                'parent_item_colon' => 'Родительская категория:',
                'edit_item'         => 'Редактировать категорию',
                'update_item'       => 'Обновить категорию',
                'add_new_item'      => 'Добавить категорию',
                'new_item_name'     => 'Новая категория',
                'menu_name'         => 'Категории',
            ),
            'description'       => 'Категории позиций каталога',
            'public'            => true,
            'hierarchical'      => true,
            'rewrite'           => array(
                'slug'         => 'catalog',
                'hierarchical' => false,
                'with_front'   => false,
                'feed'         => false
            ),
            'show_admin_column' => true,
        ) );
    
        register_post_type( 'catalog', array(
            'labels'          => array(
                'name'          => 'Каталог',
                'singular_name' => 'Товар',
                'menu_name'     => 'Каталог',
                'all_items'     => 'Все товары',
                'add_new'       => 'Добавить товар',
                'add_new_item'  => 'Добавить новый товар',
                'edit'          => 'Редактировать',
                'edit_item'     => 'Редактировать товар',
                'new_item'      => 'Новый товар',
            ),
            'description'     => 'Каталог товаров/позиций',
            'public'          => true,
            'show_in_menu'    => true,
            'capability_type' => 'post',
            'map_meta_cap'    => true,
            'hierarchical'    => false,
            'rewrite'         => array(
                'slug'       => 'catalog/%catalog-category%',
                'with_front' => false,
                'pages'      => false,
                'feeds'      => false,
                'feed'       => false
            ),
            'has_archive'     => 'catalog',
            'query_var'       => true,
            'supports'        => array( 'title', 'editor', 'thumbnail', 'excerpt', 'custom-fields', ),
            'taxonomies'      => array( 'catalog-category' ),
            'menu_icon'       => 'dashicons-book'
        ) );
    
    }
    
    function catalog_permalink( $permalink, $post ) {
        if ( strpos( $permalink, '%catalog-category%' ) === false ) {
            return $permalink;
        }
    
        $terms = get_the_terms( $post, 'catalog-category' );
        if ( ! is_wp_error( $terms ) && ! empty( $terms ) && is_object( $terms[0] ) ) {
            $term_slug = array_pop( $terms )->slug;
        } 
        else {
            $term_slug = 'no-catalog-category';
        }
    
        return str_replace( '%catalog-category%', $term_slug, $permalink );
    }
    

    [/spoiler]
    Что хочу:

    1. Создать вложенную структуру категорий используя термы таксономии ‘catalog-category’ и привязать записи типа ‘catalog’ к ним. С этой частью проблем нет
    2. Вывести на странице терма непосредственно его дочерние термы и только те записи которые привязаны к нему. с этим уже проблема

    В качестве страницы терма использую файл ‘taxonomy-catalog-category.php’
    Список вложенных термов получаю так:

    
    $term_slug = get_query_var('term');
    $taxonomy = get_query_var('taxonomy');
    $term = get_term_by( 'slug', $term_slug, $taxonomy );
    $terms = get_terms($taxonomy, array( 'child_of' => $term->term_id ) );
    

    Но среди них оказываются не только дочерние, но и более вложенные термы

    Если выводить записи стандартным циклом wp то получаю абсолютно все записи вложенных термов(хочется исключить вывод записей дочерних термов), попытки получить записи через get_posts пока не привели к желаемым результатам. Несколько использованных вариантов(закомментированные):

    
    $posts = get_posts( array(
        //'numberposts' => 0,
        //'cat'         => $term->term_id,
        'orderby'     => 'date',
        'order'       => 'DESC',
        'post_type'   => 'any', //'catalog',
        'suppress_filters' => true,
        //'tag'         => $term_slug,
    ) );
    

    Документацию по обоим функция get_terms(), get_posts() перечитал по несколько раз, но видимо что-то упускаю…

    PS: на данном форуме натыкался на темы с использованием WP_Query с кучей кода, но не уверен что я правильно понимаю их и хочется попробовать разобраться более простыми методами.

Просмотр 8 ответов — с 1 по 8 (всего 8)
  • хочется попробовать разобраться более простыми методами.

    самый простой и правильный метод — это подобрать готовый плагин, который делает то, что вам нужно.

    Для WP_Query есть параметр include_children. https://wp-kama.ru/function/wp_query#taxonomies
    Для get_posts тоже наверное будет работать, я не знаю не проверял.

    Просто добавьте в ваш массив ‘suppress_filters’ => 0,

    @qwert555 спасибо за ответ.
    Я забыл указать что изначально я совсем не мог получить записи, сейчас удается их получать используя код

    
    $posts = get_posts( array(
        'numberposts' => 0,
        'post_type'   => 'catalog',
        'suppress_filters' => 0,
        'catalog-category' => $term_slug, //вместо названия таксономии в ключе использовал tag - с этим была проблема
        'tax_query' => array( 'include_children' => false )
    ) );
    

    но к сожалению вложенные записи добавленные во вложенные термы я все так же получаю. Правильно ли я понимаю, что вместо get_posts я могу написать new WP_Query с тем же массивом параметров и в дальнейшем работать как while ( $posts->have_posts() ) : $posts->the_post(); ?

    С получением термов без вложенных, пока тоже безрезультатно

    • Ответ изменён 4 года, 8 месяцев назад пользователем PenguiN560.
    Модератор Yuri

    (@yube)

    'numberposts' => 0, — это что должно значить?

    @yube https://wp-kama.ru/function/get_posts/comment-page-2#numberposts-chislo
    numberposts(число)
    Количество выводимых постов. Установить на 0, чтобы ограничить вывод максимальным числом постов на страницу (устанавливается в настройках ВП) или поставить -1 чтобы убрать ограничения вывода (LIMIT).
    По умолчанию: 5

    То есть хотел задать ограничение согласно настройкам

    Модератор Yuri

    (@yube)

    @penguin560
    https://developer.wordpress.org/reference/classes/wp_query/#post-type-parameters
    нет ни numberposts (описан для get_posts как алиас posts_per_page), ни 0 для posts_per_page.

    При всем уважении к Тимуру и его титанической работе, я бы не рисковал пользоваться тем, чего нет в официальной документации.

    @yube благодарю за замечание, уже удалил данный параметр.
    В итоге для вывода только дочерних записей у меня получился такой кусок кода.

    
    $term_slug = get_query_var('term');
    $taxonomy = get_query_var('taxonomy');
    $posts = get_posts( array(
        'post_type'   => 'catalog',
        'tax_query' => array(
            array(
                'taxonomy' => $taxonomy,
                'field' => 'slug',
                'terms' => $term_slug,
                'include_children' => false
            )
        )
    ) );
    

    На первый взгляд работает как и задумывалось и без усложнений. Правильно ли я понимаю, что после foreach( $posts as $post ) : setup_postdata($post); я могу использовать все возможности цикла, в том числе выводить пагинацию на странице the_posts_pagination( $args ); а после мне необходимо вызвать wp_reset_postdata();?

    Так же смежный вопрос: есть какая-то большая разница между получением записей используя get_posts и WP_Query? Есть смысл стараться использовать get_posts или отказаться от него в пользу WP_Query?

    С выводом термов без вложенных пока больше не экспериментировал, продолжу чуть позже.

    • Ответ изменён 4 года, 8 месяцев назад пользователем PenguiN560.

    С получением термов разобрался. Глупая ошибка была, стоило только в очередной раз документацию перечитать и заменить ‘child_of’ на ‘parent’

Просмотр 8 ответов — с 1 по 8 (всего 8)
  • Тема «Вывод списка вложенных термов и записей привязанных к текущему терму.» закрыта для новых ответов.