web-dev-qa-db-fra.com

Menu de taxonomie avec nombre de posts et parents multiples

J'utilise WordPress 3.1.3 et j'essaie de créer un menu "produit" avec un nombre de posts dans chaque catégorie. Comme ça:

  • Voitures neuves (4)
    • BMW (2)
    • Ford (1)
    • Nissan (1)
  • Voitures d'occasion (10)
    • BMW (3)
    • Ford (1)
    • Nissan (6)

Pour cela, j'ai créé un type de message personnalisé Cars et des taxonomies Type et Brand. Je ne sais pas si c'est la meilleure façon de faire cela, mais voici mon code:

<?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>

Donc mes questions sont:

  • est-ce une bonne façon de le faire?
  • comment puis-je filtrer les comptes post?

Edit - J'ai réussi à résoudre mon deuxième problème, mais je ne suis toujours pas sûr que ce soit un bon moyen de le faire. Voici le nouveau code:

<?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>

Edit 2 - Changement de la méthode query_posts() en wp_query() (merci à VicePrez), mais est-il efficace d'utiliser une requête pour obtenir uniquement le nombre de publications correct ou existe-t-il un meilleur moyen de créer ce menu?

5
Kovas

J'ai un peu ajusté votre code pour intégrer la classe wp_query() au lieu de query posts(), qui est uniquement destiné à modifier la boucle principale . Vous devriez toujours opter pour utiliser wp_query() lorsque vous essayez de créer des boucles secondaires.

Puisque nous utilisons wp_query(), nous devrons également utiliser wp_reset_postdata() au lieu de wp_reset_query. Je ne sais pas si cela résoudra votre problème, mais adaptez votre code à cela et nous nous attaquerons au reste de vos problèmes, étape par étape.

<?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>

UPDATE:J'ai ajouté le paramètre posts_per_page et le définir sur -1 pour afficher tous les articles. Je l'ai testé de mon côté. Il devrait vous donner les résultats que vous recherchiez.

<?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
VicePrez