0

I have a list of terms showing in slug order but I need to order them by most recent posts, so it will be changing depending on what term has the most recent entries... Is there a way to do so? I tried the solution proposed here: Retrieve taxonomy terms in order of their post's date?

But it is showing the terms in date of term creation, not the date of the most recent posts.

My code:

function wpse147412_order_terms_by_post_date( $pieces, $taxonomies, $args ) {
  global $wpdb;

  if ( 'post_date' !== $args['orderby'] ) {
    return $pieces;
  }

  $args = wp_parse_args( $args, array( 'post_types' => 'episode' ) );

  $pieces['fields']   = 'DISTINCT ' . $pieces['fields'];
  $pieces['join']    .= " JOIN $wpdb->term_relationships AS tr ON tr.term_taxonomy_id =   tt.term_taxonomy_id";
  $pieces['join']    .= " JOIN $wpdb->posts AS p ON p.ID = tr.object_id";
  $pieces['where']   .= " AND p.post_type IN ('" . implode( "', '", (array)   $args['post_types'] ) . "')";
  $pieces['orderby']  = 'ORDER BY p.post_date';

  return $pieces;
}
add_filter( 'terms_clauses', 'wpse147412_order_terms_by_post_date', 10, 3 );

Placed above in functions, then in the page I need the terms:

<?php 
$tax_terms = get_terms( 'series',
  array( 'post_types' => 'episode',
    'orderby' => 'post_date',
    'order' => 'DESC' ) 
  );

if( is_array( $tax_terms ) && count( $tax_terms ) > 0 ):
  foreach ($tax_terms as $tax_term):
  ?>

    <div class="series-button text-center">
      <a href="<?php echo esc_attr(get_term_link($tax_term, $taxonomy));?>">
        <figure class="align-items-center d-flex" style="background-image: url('<?php echo z_taxonomy_image_url($tax_term->term_id, 'series-img'); ?>');">  
          <h3 class="text-center uppercase"><?php echo $tax_term->name; ?></h3>
        </figure> 
      </a>
    </div>

  <?php 
  endforeach;
endif;
?>
2
0

This will not be the fastest way to achieve it, - but it will do the trick. If you have a bazillion posts (I'd say more than 1000) - or if you're server is slow, then this might be too heavy. But I wouldn't hesitate to use it on any of my sites.

If you want something fast, then you should probably go with some SQL of some sort.

<?php
$episode_query = new WP_Query([
  'post_type' => 'post',
  'post_status' => 'publish',
  'posts_per_page' => 999,
  'order' => 'DESC',
  'orderby' => 'date'
]);

$terms = [];
if( $episode_query->have_posts() ):
  while( $episode_query->have_posts() ):
    $episode_query->the_post();
    $post = get_post();

    // Tags
    $tags = get_the_terms( $post, 'post_tag' );
    if( !empty( $tags ) ):
      foreach( $tags as $tag ):
        if( does_array_contain_term( $tag, $terms ) ){
          $terms[] = $tag;
        }
      endforeach; // foreach( $tags as $item ):
    endif; // if ( !empty( $tags ) )

    // Category
    $categories = get_the_terms( $post, 'category' );
    if( !empty( $categories ) ):
      foreach( $categories as $cat ):
        if( does_array_contain_term( $cat, $terms ) ){
          $terms[] = $cat;
        }
      endforeach; // foreach( $categories as $item ):
    endif; // if ( !empty( $categories ) )


  endwhile; // while( $episode_query->have_posts() ):
  wp_reset_query();
endif; // if( $episode_query->have_posts() ):

function does_array_contain_term( $term_to_check, $terms ){
  $add_term = true;
  foreach( $terms as $term ){
    if( $term->slug == $term_to_check->slug ){
      $add_term = false;
    }
  }

  return $add_term;
}

// TO SEE THE RESULT
echo '<pre>';
print_r($terms);
echo '</pre>';
?>
1
  • Sorry to be typing really late on this. I got hanged on other projects and this one went to a waiting list. I tried changing the query to my custom post types but it isn't working. If I use the my post type or taxonomy terms I get "There has been a critical error on your website." :( I hope you can guide me to use this Jul 1 '20 at 19:15

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.