Support

Account

Home Forums General Issues Possible to Group By values of custom field

Solved

Possible to Group By values of custom field

  • I’d like to loop through posts in a WordPress category and group the results by the values in a custom field.

    I’ve got the posts and can retrieve the custom field values, so I can display:

    [custom field: trend_category value]:

    [Post Title]
    [custom field: trend_email_text value]
    *****************************************************

    But what I want to do is this:

    [All posts with trend_category value Marketing]

    [Post Title]
    [custom field: trend_email_text value]
    *****************************************************
    [Post Title]
    [custom field: trend_email_text value]
    *****************************************************

    [All posts with trend_category value Digital]

    [Post Title]
    [custom field: trend_email_text value]
    *****************************************************
    [Post Title]
    [custom field: trend_email_text value]
    *****************************************************

    Any hints? I’m assuming a for … each construction, but can’t seem to grab the custom field values necessary to do that.

  • Hi @tjb1013

    This is a good question, and one that can be accomplished with some simple PHP.

    What you want to do is loop through your posts, load the custom field data, and then add them to the appropriate array. Then loop through this new array and display the data like so:

    
    <?php 
    
    // vars
    $posts = array( /* this is the array which holds all your posts. */);
    $sorted = array();
    
    // loop through posts
    foreach( $posts as $p )
    {
    	// load custom category:
    	$cat = get_field('trend_category');
    	
    	
    	// add to $sorted
    	if( !isset($sorted[ $cat ]) )
    	{
    		$sorted[ $cat ] = array();
    	}
    	
    	$sorted[ $cat ][] = $p;
    }
    
    // now loop through sorted
    foreach( $sorted as $cat_name => $cat_posts )
    {
    	echo '<h3>' . $cat . '</h3>';
    	
    	echo '<ul>';
    	
    	foreach( $cat_posts as $p )
    	{
    		echo '<li>' . get_the_title( $p->ID ) . '</li>';
    	}
    	
    	echo '</ul>';
    }
    
    ?>
    

    Please note the above code is untested and does not include any fail safe if statements. I hope it helps you understand how to solve your task.

    Good luck!

  • Thanks so much – tweaked it a little:

    `// load custom category:
    $cat = get_field(‘trend_category’);`

    went with:

    $cat = get_post_meta($p->ID, "trend_category", $single);

    and

    echo '<h3>' . $cat . '</h3>';

    went with:

    echo '<h3>' . $cat_name . '</h3>';

    Huge help!

  • Hi. I’m trying to get the same result: looping through CPT (distributors), in order to group them by the values of a custom field (region). I followed your suggestion – quite useful indeed – but I’m getting only the first post repeated. There must be something wrong with it… could you please add your complete final code?

  • Hello. I found this post which is very useful and allowed me to find a mid solution to my problem.
    I’m building a widget, and my goal is to display a list of lessons (custom posts) grouped by cities (custom ACF fields) and then display the corresponding dates (custom ACF fields) like the following:
    Paris
    from 11/04/2020 to 18 /04/2020
    from 12/05/2020 to 20/05/2020
    Nice
    from 13/06/2020 to 18/06/2020

    I was blocked and thanks to your code i managed to do it.But what i’m trying to do is to group by city. If two posts have the same city name, display only once the city name and under that all the corresponding dates. Now i have a list that display each time the city name like this :

    Paris
    from 11/04/2020 to 18 /04/2020
    Paris
    from 12/05/2020 to 20/05/2020
    Nice
    from 13/06/2020 to 18/06/2020

    Here is my code. For the last part if i use the loop:

    foreach( $cat_posts as $p )
    	{

    it repeats the dates 3 times under each city. So i don’t use it:

    `public function widget( $args, $instance ) {
    extract( $args );
    $title = apply_filters( ‘widget_title’, $instance[‘title’] );
    $tax_id = absint( $instance[‘tax_id’] ) ;
    $niveau_id = absint( $instance[‘niveau_id’] ) ;

    $args = array(
    ‘post_type’ => ‘formation’,
    ‘posts_per_page’ => $instance[‘number_events’],
    ‘tax_query’ => array(
    ‘relation’ => ‘AND’,
    array(
    ‘taxonomy’ => ‘categories-formations’,
    ‘field’ => ‘id’,
    ‘terms’ => $tax_id,
    ),
    array(
    ‘taxonomy’ => ‘niveau-formations’,
    ‘field’ => ‘id’,
    ‘terms’ => $niveau_id,
    ),
    ),
    );

    $upcoming_events = new WP_Query($args);

    if ( $title ) {
    echo $before_title . $title . $after_title;
    }
    // vars
    ?>

    <ul class=”event_entries”>
    <?php
    while( $upcoming_events->have_posts() ): $upcoming_events->the_post();
    $event_start_date = get_field( ‘date_de_debut’);
    $event_end_date = get_field(‘date_de_fin’ );
    $event_venue = get_field(‘ville’);
    $posts = array();
    $sorted = array();
    $posts = $upcoming_events->posts;

    foreach( $posts as $p )
    {

    $city = get_field(‘ville’);

    // add to $sorted
    if( !isset($sorted[ $city ]) )
    {
    $sorted[ $city ] = array();
    }

    $sorted[ $city ][] = $p;
    }

    // now loop through sorted
    foreach( $sorted as $city_name => $city_posts )
    {
    echo ‘<h3>’ . $city_name . ‘</h3>’;

    echo ‘

      ‘;

      echo ‘

    • Du’ . $event_start_date . ‘ au ‘ . $event_end_date . ‘
    • ‘;

      echo ‘

    ‘;
    }
    endwhile;
    ?>

    <?php
    wp_reset_query();

    echo $after_widget;
    }

    So my goal is when two posts are in the same city group them under the same city name like this :

    Paris
    from 11/04/2020 to 18 /04/2020
    from 12/05/2020 to 20/05/2020
    Nice
    from 13/06/2020 to 18/06/2020

    Can someone help me to change the loop to get this result ??

Viewing 5 posts - 1 through 5 (of 5 total)

The topic ‘Possible to Group By values of custom field’ is closed to new replies.