2

My question is close to other questions, but I dont' have enough reputation to comment.

I'm working for a restaurant and I 'd like, for my menu page, to organise my posts "meal" under terms "cat_meal".

This terms should respect an order (dessert after starter for example). And that's my probleme : I tried so many snippets, that I don't know which one I should write here... Here are some picture to explain, I hope. Page menu Page menu with comments But, there is always something wrong : either I can display my term in a right order and my query post is not good. Or meal posts are under the good terms, but, the order of the terms are wrong. Or, worth, nothing happens.

Here are two tests, thanks for your time and help :

$args_tax = [
    'parent'    => 0,
    'hide_empty' => 0,
    'meta_key'      => 'ordre',// I added an ACF with number from 1 to 8 to order
    'orderby'   => 'meta_value',
    'order'     => 'ASC'
];

$terms = get_terms('cat_meal', $args_tax); // tax cat_meal
// print_r($terms);

if (!empty($terms)):
    foreach ($terms as $term):
        $argsPost = [
            'post_type' => 'meal',//CPT meal
             'posts_per_page' => -1
        ];

        $query = new WP_Query($argsPost);
        while ($query->have_posts()) : $query->the_post();
            echo $term->name ;
            the_title();
        endwhile;
        wp_reset_postdata(); // reset the query 
    endforeach;
endif;
//PROBLEM : under each term, every posts are displaying ! I don't understand why...

Second version from this question Get all categories and posts in those categories


$args = array( 
        'post_type' => 'meal',  
        'posts_per_page' => -1
    );

    $query = new WP_Query($args);   
    $q = array();

    while ( $query->have_posts() ) { 
        $query->the_post(); 
        $a = '' . get_the_title() .'';
        $terms = wp_get_post_terms( $post->ID, 'cat_meal', $args );
        foreach ( $terms as $term) {
            $term_link = get_term_link( $term );
            $b = ''.$term->name.'';    
        }
        $q[$b][] = $a; 
    }
    wp_reset_postdata();
    foreach ($q as $key=>$values) {
        echo $key;
            foreach ($values as $value){
                echo $value;
            }
    }

The posts are well displaying under the terms, BUT the terms have wrong order (dessert before pizza)

I've just found this answer too, but I' dont undetsand wher the taxonomy is declared : Ordering Posts with Custom Taxonomy Terms Array.

I would really appreciate some advices into my fog : thanks

0

You could use tax_query to get only the posts with the term that is currently being looped.

$argsPost = [
 'post_type' => 'meal',//CPT meal
 'posts_per_page' => -1,
 'meta_key' => 'ordre', 
 'orderby'   => 'meta_value', // Use the custom post order
 'order'     => 'ASC' 
 'tax_query' => array(
    array(
        'taxonomy' => 'cat_meal',
        'field'    => 'term_id',
        'terms'    => $term->term_id, // Only query the posts that have the current term in foreach loop
    ),
 ),
];

Try replacing the $argsPost in your first code example with this one and see what happens.

I have a vague memory of doing something like this myself on couple of sites.

EDIT 20.10.2018

I looked at the Ordering Posts with Custom Taxonomy Terms Array discussion that you had linked and you could also use the solution Milo had posted.

Something like this (might need some tweaking)

$args = array(
'post_type' => 'meal',
'posts_per_page' => '-1',
// add extra sorting related key/value pairs here
);
$my_query = new WP_Query( $args );

// you original get_terms function
$args_tax = [
'parent'    => 0,
'hide_empty' => 0,
'meta_key'      => 'ordre',// I added an ACF with number from 1 to 8 to order
'orderby'   => 'meta_value',
'order'     => 'ASC'
];
$terms = get_terms('cat_meal', $args_tax); // tax cat_meal

// Loop terms
if ( ! is_wp_error( $terms ) && ! empty( $terms )  ) {
    foreach( $terms as $term ) {
        while( $my_query->have_posts() ) {
            $my_query->the_post();
            if( has_term( $term->term_id, 'cat_meal' ) ){
                // output post
            }
        }
        $my_query->rewind_posts(); // rewind custom query for the next foreach term loop
    }
}

This way you would only make one WP_Query and just loop the results over and over again for each term. This might be better performance wise instead of doing separate WP_Query for each term, but this is just a hunch.

  • Hello, thanks a lot for you help ! I have a message error "Trying to get property of non-object in"in the line "$term->term_id" Could this be a dirty story of array ? A problem of conversion ?... – Cha Oct 19 '18 at 20:27
  • 1
    get_terms should return a list of WP_Terms so $term->term_id should work, when you loop the array through. You can var_dump($term); to see if the term is an object or not - then you can tweak the code accordingly. – Antti Koskinen Oct 20 '18 at 10:26
0

Thank you again Antti Koskinen ! Here's my final code :


$myTax='cat_meal';

// I use an ACF named "ordre" from 1 to 7  to control the order of my terms
$_terms = get_terms($myTax, array(
     'parent'   => 0, // no child term
     'meta_key' => 'ordre',// my ACF
     'orderby'  => 'meta_value',
     'order'    => 'ASC'// from 1 to ...
) );

foreach ($_terms as $term) :
    $term_slug = $term->slug;

    $_posts = new WP_Query( array(
        'post_type'         => 'meal',// my CPT
        'posts_per_page'    => -1,
        'tax_query' => array(
            array(
                'taxonomy' => $myTax,
                'field'    => 'slug',
                'terms'    => $term_slug,
            ),
        ),
    ));

    if( $_posts->have_posts() ) :

        echo $term->name; // The term

        while ( $_posts->have_posts() ) : $_posts->the_post(); 

           the_title(); // the different meals under this term

         endwhile;

    endif;

Ouff, end of the story, thanks again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.