Скрытие таксономий без детей WP_Query и tax_query

Вопрос или проблема

У меня есть этот код, на который у меня ушло более 7 часов на его создание через исследование, но последние часы я наткнулся на тупик!

Мне нужно, чтобы заголовок таксономии скрывался, если с ним нет связанных записей.

Вот страница: http://cb.dannycheeseman.me/wine-menu/usa/california/

Вот мой код:

/**********************************************/
//  КАСТОМНЫЙ ШОРТКОД МЕНЮ ВИНО
/**********************************************/

add_shortcode( 'wine_list_per_cat', 'wine_list_per_cat' );

function wine_list_per_cat($atts){

    global $woocommerce_loop;

    extract(shortcode_atts(array(
        'cat' => '',    // список категорий в формате 0,1,2,3,4
        'tax' => 'product_cat', // используемая таксономия
        'per_cat' => '3',   // максимальное количество показываемых товаров в категории
        'columns' => '3',   // размер колонок
    ), $atts));
?>

<ul id="wine-menu">

    <?php  

        $wine_type_terms = get_terms( 'wine-type' );

        foreach ( $wine_type_terms as $wine_type_term ) {

            $args = array(
                'post_type' => 'product',
                'showposts' => -1,
                'tax_query' => array(
                    'relation' => 'IN',
                    array(
                        'taxonomy' => 'wine-type',
                            'field' => 'slug',
                            'terms' => array( $wine_type_term->slug ),
                        ),
                        array(
                            'taxonomy' => 'product_cat',
                            'field' => 'slug',
                            'terms' => $cat
                        )
                    ));

            $wine_type_query = new WP_Query($args);?>
            <li>
            <h2><?php echo $wine_type_term->name; ?></h2>
            <ul>
                <?php  while ( $wine_type_query->have_posts() ) : $wine_type_query->the_post();global $product ?>
                    <li class="wine-item"> 
                        <h3><?php the_title(); ?></h3>
                        <span class="wine-bottle-size">Размер: <?php echo get_post_meta( get_the_ID(),'wine_bottle_size', true );?></span><br/>
                        <span class="wine-percentage">Процент: <?php echo get_post_meta( get_the_ID(), 'wine_percentage', true );?></span><br/>
                        <span class="wine-year">Год: <?php echo get_post_meta( get_the_ID(), 'wine_year', true );?></span><br/>
                        <span class="wine-price">Цена: <?php echo $product->get_price_html(); ?></span><br/>
                        <div class="wine-content"><?php echo get_post_meta( get_the_ID(), 'wine_menu_content', true );?></div>
                        <?php woocommerce_template_loop_add_to_cart( $wine_type_query->post, $product ); ?>
                    </li>

                <?php endwhile;?>
                <?php wp_reset_postdata(); ?>
            </ul>

         </li>               
        <?php } ?>

        <?php wp_reset_query(); ?>

</ul><!--/.products-->
<?php } 

ОБНОВЛЕНИЕ!
Хорошо!!! Ура!
Я выяснил, в чем было дело.. Мне следовало проверять, есть ли записи, перед вызовом $tax->name;
Вот мой окончательный и работающий код! 🙂

/**********************************************/
//  КАСТОМНЫЙ ШОРТКОД МЕНЮ ВИНО
/**********************************************/

add_shortcode( 'wine_list_per_cat', 'wine_list_per_cat' );

function wine_list_per_cat($atts){

    global $woocommerce_loop;

    extract(shortcode_atts(array(
        'cat' => '',    // список категорий в формате 0,1,2,3,4
        'tax' => 'product_cat', // используемая таксономия
        'per_cat' => '3',   // максимальное количество показываемых товаров в категории
        'columns' => '3',   // размер колонок
    ), $atts));
?>

<ul id="wine-menu">

    <?php  

        $taxonomy = get_terms( 'wine-type', array('hide_empty' => true, 'pad_counts' => true));

        foreach ( $taxonomy as $tax ) {

            $args = array(
                'post_type' => 'product',
                'orderby' => 'title',
                'showposts' => -1,
                'tax_query' => array(
                    'relation' => 'AND',
                    array(
                        'taxonomy' => 'product_cat',
                        'field' => 'slug',
                        'terms' => $cat,
                        'operator' => 'IN'
                    ),
                    array(
                        'taxonomy' => 'wine-type',
                        'field' => 'slug',
                        'terms' => array( $tax->slug ),
                        'operator' => 'IN'
                    ),
                ));

            $wine_type_query = null;

            $wine_type_query = new WP_Query($args);

            if( $wine_type_query->have_posts() ) : ?>

                <li id="wine-type">
                    <h2><?php echo $tax->name; ?></h2>

                    <ul>
                        <?php while ( $wine_type_query->have_posts() ) : $wine_type_query->the_post();global $product ?>
                        <li class="wine-item"> 
                            <h3><?php the_title(); ?></h3>
                            <span class="wine-bottle-size">Размер: <?php echo get_post_meta( get_the_ID(),'wine_bottle_size', true );?></span><br/>
                            <span class="wine-percentage">Процент: <?php echo get_post_meta( get_the_ID(), 'wine_percentage', true );?></span><br/>
                            <span class="wine-year">Год: <?php echo get_post_meta( get_the_ID(), 'wine_year', true );?></span><br/>
                            <span class="wine-price">Цена: <?php echo $product->get_price_html(); ?></span><br/>
                            <div class="wine-content"><?php echo get_post_meta( get_the_ID(), 'wine_menu_content', true );?></div>
                            <?php woocommerce_template_loop_add_to_cart( $wine_type_query->post, $product ); ?>
                        </li>
                        <?php endwhile;?>

                    </ul>

                </li> 
            <?php endif; wp_reset_query(); ?>

    <?php } ?>

</ul><!--/.products-->
<?php } 

Ответ или решение

Проблема скрытия таксономий без детей в WP_Query и tax_query

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

Изначальный код и решение проблемы

Ваш первоначальный код успешно выполнял задачу по получению постов, но проблема заключалась в том, что вы не проверяли наличие постов перед тем, как выводить заголовок таксономии. Это привело к тому, что заголовки отображались даже в случаях, когда записи отсутствовали. Основным решением, которое вы нашли, было использование условия if ( $wine_type_query->have_posts() ) перед вызовом заголовка таксономии.

Ваш окончательный рабочий код выглядит следующим образом:

/**********************************************/
//  CUSTOM WINE MENU SHORTCODE
/**********************************************/

add_shortcode( 'wine_list_per_cat', 'wine_list_per_cat' );

function wine_list_per_cat($atts){

    global $woocommerce_loop;

    extract(shortcode_atts(array(
        'cat' => '',    // список категорий в формате 0,1,2,3,4
        'tax' => 'product_cat', // используемая таксономия
        'per_cat' => '3',   // макс. количество отображаемых напитков в категории
        'columns' => '3',   // размер столбцов
    ), $atts));
?>
<ul id="wine-menu">

    <?php  

        $taxonomy = get_terms( 'wine-type', array('hide_empty' => true, 'pad_counts' => true));

        foreach ( $taxonomy as $tax ) {

            $args = array(
                'post_type' => 'product',
                'orderby' => 'title',
                'showposts' => -1,
                'tax_query' => array(
                    'relation' => 'AND',
                    array(
                        'taxonomy' => 'product_cat',
                        'field' => 'slug',
                        'terms' => $cat,
                        'operator' => 'IN'
                    ),
                    array(
                        'taxonomy' => 'wine-type',
                        'field' => 'slug',
                        'terms' => array( $tax->slug ),
                        'operator' => 'IN'
                    ),
                ));

            $wine_type_query = new WP_Query($args);

            if( $wine_type_query->have_posts() ) : ?>

                <li id="wine-type">
                    <h2><?php echo $tax->name; ?></h2>

                    <ul>
                        <?php while ( $wine_type_query->have_posts() ) : $wine_type_query->the_post();global $product ?>
                        <li class="wine-item"> 
                            <h3><?php the_title(); ?></h3>
                            <span class="wine-bottle-size">Size: <?php echo get_post_meta(get_the_ID(),'wine_bottle_size', true); ?></span><br/>
                            <span class="wine-percentage">Percentage: <?php echo get_post_meta(get_the_ID(), 'wine_percentage', true); ?></span><br/>
                            <span class="wine-year">Year: <?php echo get_post_meta(get_the_ID(), 'wine_year', true); ?></span><br/>
                            <span class="wine-price">Price: <?php echo $product->get_price_html(); ?></span><br/>
                            <div class="wine-content"><?php echo get_post_meta(get_the_ID(), 'wine_menu_content', true); ?></div>
                            <?php woocommerce_template_loop_add_to_cart($wine_type_query->post, $product); ?>
                        </li>
                        <?php endwhile; ?>

                    </ul>

                </li> 
            <?php endif; wp_reset_query(); ?>

    <?php } ?>

</ul><!--/.products-->
<?php }

Комментарии к коду

  1. Получение терминов: Использование get_terms с параметром hide_empty => true позволяет вам получить только те термины таксономии, у которых есть посты.

  2. Проверка наличия постов: Использование условия if( $wine_type_query->have_posts() ) перед выводом заголовка таксономии обеспечивает отсутствие пустых заголовков.

  3. Восстановление данных: Вызов wp_reset_query() после цикла foreach гарантирует, что глобальная переменная $wp_query сбрасывается, предотвращая возможные конфликты с последующими запросами.

Заключение

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

Если у вас возникнут дополнительные вопросы или проблемы, не стесняйтесь обращаться за помощью.

Оцените материал
Добавить комментарий

Капча загружается...