如何根据最近的帖子对分类术语进行排序?

时间:2020-04-28 作者:artist learning to code

我有一个以slug顺序显示的术语列表,但我需要按最近的帖子进行排序,因此它将根据最新条目的术语而变化。。。有没有办法做到这一点?我尝试了这里提出的解决方案:Retrieve taxonomy terms in order of their post's date?

但它显示的是术语的创建日期,而不是最近帖子的日期。

我的代码:

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 );
放在上面的函数中,然后在页面中我需要这些术语:

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

1 个回复
SO网友:Zeth

这并不是实现这一目标的最快方式,但它会成功的。如果您有大量帖子(我想超过1000篇),或者您的服务器速度很慢,那么这可能太重了。但我会毫不犹豫地在我的任何网站上使用它。

如果您想要快速的东西,那么您可能应该使用某种SQL。

<?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>\';
?>