Меню таксономии с количеством записей и несколькими родителями


Я использую WordPress 3.1.3 и пытаюсь создать меню "продукт" с количеством сообщений в каждой категории. Вот так:

  • Новые автомобили (4)
    • BMW (2)
    • Форд (1)
    • Nissan (1)
  • Подержанные автомобили (10)
    • BMW (3)
    • Форд (1)
    • Nissan (6)

Для этого я создал пользовательский тип записи Cars и таксономии Type и Brand. Не уверен, что это лучший способ сделать это, но вот мой код:

<?php $auto_types = get_terms('type', 'hide_empty=1'); ?>
<ul>
<?php foreach( $auto_types as $auto_type ) : ?>
  <li>
    <a href="<?php echo get_term_link( $auto_type->slug, 'type' ); ?>">
      <?php echo $auto_type->name; ?> (<?php echo $auto_type->count; ?>)
    </a>
                <?php
                $terms = get_terms('brand');
                $count = count($terms);
                if($count > 0) :
                    ?>
                     <ul>
                        <?php foreach ($terms as $term) : ?> 

                        <li>
                            <a href="/?type=<?php echo $auto_type->slug ?>&brand=<?php echo $term->slug ?>">
                                    - - <?php echo $term->name; ?> (<?php echo $term->count; ?>)
                            </a>
                        </li>
                        <?php endforeach ?>
                    </ul>
                    <?php endif ?>

    </li>           
<?php endforeach ?>
</ul>

Итак, мои вопросы таковы:

  • это хороший способ сделать это?
  • как отфильтровать количество сообщений?

Редактировать - Мне удалось решить свою вторую проблему, но я все еще не уверен, что это хороший способ сделать это. Вот новый код:

<?php $auto_types = get_terms('type', 'hide_empty=1'); ?>
    <ul>
    <?php foreach( $auto_types as $auto_type ) : ?>
        <li>
        <a href="<?php echo get_term_link( $auto_type->slug, 'type' ); ?>"> 
            <?php echo $auto_type->name; ?>
        </a>
        <?php $auto_brands = get_terms('brand', 'parent=0' ); ?>
            <ul>
                <?php foreach ($auto_brands as $auto_brand) : ?>
                    <?php $brand_filter['tax_query'] = array(
                            'relation' => 'AND',
                            array(
                                'taxonomy' => 'type',
                                'terms' => array($auto_type->slug),
                                'field' => 'slug',
                            ),
                            array(
                                'taxonomy' => 'brand',
                                'terms' => array($auto_brand->slug),
                                'field' => 'slug',
                            ),
                        );
                    $tax_query = new WP_Query($brand_filter);
                        $count = 0;
                    if ( $tax_query->have_posts() ) : while ( $tax_query->have_posts() ) : $tax_query->the_post();
                        $count++;
                    endwhile; endif; wp_reset_postdata();
                        if ( $count > 0 ) : ?>
                            <li>
                                <a href="/?type=<?php echo $auto_type->slug ?>&brand=<?php echo $auto_brand->slug ?>">
                                    - - <?php echo $auto_brand->name; ?> (<?php echo $count; ?>)
                                </a>
                            </li>
                <?php endif; endforeach ?>
            </ul>                 
        </li>           
    <?php endforeach ?>
    </ul>

Редактировать 2 - Изменен метод query_posts() на wp_query() (благодаря VicePrez), но эффективно ли использовать запрос только для получения правильного количества сообщений или есть лучший способ сделать это меню?

Author: Kovas, 2011-05-27

1 answers

Я немного скорректировал ваш код, чтобы интегрировать класс wp_query() вместо query posts(), который предназначен только для изменения основного цикла . Вы должны всегда выбирать wp_query() при попытке создать вторичные циклы.

Поскольку мы используем wp_query(), нам также придется использовать wp_reset_postdata() вместо wp_reset_query. Я не уверен, что это решит вашу проблему, но скорректируйте свой код в соответствии с этим, и мы решим остальные ваши проблемы шаг за шагом шаг.

<?php $auto_types = get_terms('type', 'hide_empty=1'); ?>
<ul>
<?php foreach( $auto_types as $auto_type ) : ?>
    <li>
    <a href="<?php echo get_term_link( $auto_type->slug, 'type' ); ?>"> 
        <?php echo $auto_type->name; ?>
    </a>
    <?php $auto_brands = get_terms('brand', 'parent=0' ); ?>
        <ul>
            <?php foreach ($auto_brands as $auto_brand) : ?>
                <?php $brand_filter['tax_query'] = array(
                        'relation' => 'AND',
                        array(
                            'taxonomy' => 'type',
                            'terms' => array($auto_type->slug),
                            'field' => 'slug',
                        ),
                        array(
                            'taxonomy' => 'brand',
                            'terms' => array($auto_brand->slug),
                            'field' => 'slug',
                        ),
                    );
                    $tax_query = new WP_Query($brand_filter);
                    if ( $tax_query->have_posts() ) :

                        $count = 1;
                        while ( $tax_query->have_posts() ) : 
                        $tax_query->the_post();

                        if ( $count >= 1 ) { ?>
                           <li>
                               <a href="/?type=<?php echo $auto_type->slug ?>&brand=<?php echo $auto_brand->slug ?>">
                                   - - <?php echo $auto_brand->name; ?> (<?php echo $count; ?>)
                               </a>
                           </li>
                        <? }

                        $count++;

                        endwhile; 
                        wp_reset_postdata();

                    endif; 
                endforeach 
            ?>
        </ul>                 
    </li>           
<?php endforeach ?>
</ul>

ОБНОВЛЕНИЕ: Я добавил параметр posts_per_page и установил для него значение -1, чтобы показывать все сообщения. Я проверил это на своей стороне. Это должно дать вам результаты, которые вы искали.

<?php $auto_types = get_terms('type', 'hide_empty=1'); ?>
<ul>
<?php foreach( $auto_types as $auto_type ) : ?>
    <li>
    <a href="<?php echo get_term_link( $auto_type->slug, 'type' ); ?>"> 
        <?php echo $auto_type->name; ?>
    </a>
    <?php $auto_brands = get_terms('brand', 'parent=0' ); ?>
        <ul>
            <?php foreach ($auto_brands as $auto_brand) : ?>
                <?php $brand_filter = array(
                    'posts_per_page' => '-1',
                    'tax_query' => array(
                        'relation' => 'AND',
                        array(
                            'taxonomy' => 'type',
                            'field' => 'slug',
                            'terms' => array($auto_type->slug),
                        ),
                        array(
                            'taxonomy' => 'brand',
                            'field' => 'slug',
                            'terms' => array($auto_brand->slug),
                        )
                    )
                );
                $tax_query = new WP_Query($brand_filter);
                    $count = 0;
                if ( $tax_query->have_posts() ) : while ( $tax_query->have_posts() ) : $tax_query->the_post();
                    $count++;
                endwhile; endif; wp_reset_postdata();
                    if ( $count > 0 ) : ?>
                        <li>
                            <a href="/?type=<?php echo $auto_type->slug ?>&brand=<?php echo $auto_brand->slug ?>">
                                - - <?php echo $auto_brand->name; ?> (<?php echo $count; ?>)
                            </a>
                        </li>
            <?php endif; endforeach ?>
        </ul>                 
    </li>           
<?php endforeach ?>
</ul>
 1
Author: VicePrez, 2017-04-13 12:37:32