phpwordpressloopsadvanced-custom-fieldscustom-taxonomy

Multiple taxonomies to build a custom post grid (wordpress + ACF)


I need to create a custom post query loop from various custom taxonomy terms set per page with taxonomy fields.

As I am not a senior WP PHP developper, and as I need to move forward on other aspect of the project, I kindly ask you for your help to finish building the query. I almost have it but I am blocking on mixing taxonomies, put relationnal and hierarchical conditions.

The context is this: Website is for a real estate agency, with listing custom posts and custom taxonomies for offer rent/sale (categorie_offre), property type (type_bien) and city (ville). Property type has child taxonomies for Houses, appartments, garage, 1 room, 2 rooms, etc.

In single page editor, I have my taxonomies ACF fields for the 3 taxonomies where I decide what term must filter the listing grid.

In single page template, for now I have this code, that work for only one taxonomy, but not for multiple (I didn't put cities for now), I think array_merge is not the good solution:

I am thinking of using the idea of this tread but if some senior developper could give me a hand to achieve it quicker I would be very very very thankfull: https://wordpress.stackexchange.com/questions/371737/how-to-get-posts-that-contain-multiple-terms-from-multiple-taxonomies

Thanks

Roland

<?php
// Liste d'annonces pages SEO

$post_type = 'annonce';
$location_vente = get_field( 'location_ou_vente' );
$type_bien = get_field( 'type_de_bien' );
$termis = array_merge($location_vente,$type_bien);

foreach( $termis as $termi ) :
$argsi = array(
'post_type' => $post_type,
'posts_per_page' => 5,
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'categorie_offre',
'field' => 'term_id',
'operator' => 'OR',
'terms' => $location_vente
),
array(
'taxonomy' => 'type_bien',
'field' => 'term_id',
'operator' => 'OR',
'terms' => $type_bien
),
),
);

endforeach;

$annonces = new WP_Query( $argsi );

// Output posts, etc.

while ( $annonces->have_posts() ) : $annonces->the_post();
the_title();
the_excerpt();
echo '<br />';
endwhile;

wp_reset_query();

?>

Solution

  • maybe my question was unclear...

    Anyway, here is the solution I found:

    
    $categories = get_field('location_ou_vente');
    // make sure it is an array, if only one is
    // selected it may return a single value
    if (!is_array($categories)) {
      $categories = array($categories);
    }
    $types = get_field('type_de_bien');
    if (!is_array($types)) {
      $types = array($types);
    }
    $villes = get_field('ville_bien');
    if (!is_array($villes)) {
      $villes = array($villes);
    }
        
    $paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
    $postsPerPage = 10;
        
    $args = array(
      'post_type' => 'annonce',
      'posts_per_page' => $postsPerPage,
      'paged' => $paged,
      'tax_query' => array(
        'relation' => 'AND',
        array(
          'taxonomy' => 'categorie_offre',
          'relation' => 'OR',
          'terms' => $categories
        ),
        array(
          'taxonomy' => 'type_bien',
          'relation' => 'OR',
          'terms' => $types
        ),
        array(
          'taxonomy' => 'ville',
          'relation' => 'OR',
          'terms' => $villes
        )
      )
    );
    $annonces = new WP_Query($args);
            $nb_annonces = $annonces->found_posts;
        
        if ($nb_annonces < 2) : 
        echo 'Moins de 2 annonces';
        else :
    
    
    // loop reuslts here to display posts
    
    
            
    //    $annonces = new WP_Query( $argsi );
    
        // Output posts, etc.
        if ( $annonces->have_posts() ) : 
            echo '<div class="annonces">';
            while ( $annonces->have_posts() ) : $annonces->the_post(); 
    
                get_template_part( 'template-parts/grid', 'annonce' );
            endwhile;
        
        echo '<div class="pagination">';
    
            echo paginate_links( array(
                'base'         => str_replace( 999999999, '%#%', esc_url( get_pagenum_link( 999999999 ) ) ),
                'total'        => $annonces->max_num_pages,
                'current'      => max( 1, get_query_var( 'paged' ) ),
                'format'       => '?paged=%#%',
                'show_all'     => false,
                'type'         => 'plain',
                'end_size'     => 2,
                'mid_size'     => 1,
                'prev_next'    => true,
                'prev_text'    => sprintf( '<i></i> %1$s', __( 'Newer Posts', 'text-domain' ) ),
                'next_text'    => sprintf( '%1$s <i></i>', __( 'Older Posts', 'text-domain' ) ),
                'add_args'     => false,
                'add_fragment' => '',
            ) );
    
    echo '</div>';
            echo '</div>';
            echo '<a id="more_posts" href="#">Load More</a>';
            else :
    
            get_template_part( 'template-parts/content', 'none' );
            
            endif;
            
            
        wp_reset_query();
        
            
            
            
    ?>