What I'm trying to achieve: get n
terms from a custom taxonomy ordered by the newest post in each term. This will be used to display the newest m
posts under each term.
Is there a better way of doing this than getting an array of all the terms, and looping through to find the newest post in each? This approach doesn't feel very efficient or scalable.
Update
Here's my working code so far - can this be improved on?
$taxonomy = 'industry'; //taxonomy name
$terms_to_display = 5; //number of terms to display
$posts_per_term = 4; // number of posts per term to display
$terms = get_terms( array('taxonomy' => $taxonomy, 'hide_empty' => true, 'fields' => 'ids' ) );
$news_items = [];
foreach ( $terms as $term ) {
$args = array (
'post_type' => 'news',
'posts_per_page' => $posts_per_term,
'orderby' => 'date',
'order' => 'DESC',
'tax_query' => array (
array (
'taxonomy' => $taxonomy,
'field' => 'id',
'terms' => array($term),
),
),
);
$news = new WP_Query( $args );
if ( $news->post_count == $posts_per_term ) { // ignore terms with not enough posts
$news_items[$term] = get_the_date("U", $news->posts[0]->ID); //get date of newest post in this term
}
wp_reset_query();
}
arsort ( $news_items ); //sort descending, keeping keys
$term_ids = array_keys ( array_slice($news_items, 0, $terms_to_display, true) ); //take 'n' newest and return an array of keys (term ids)
foreach ( $term_ids as $term_id ) {
$term = get_term ( $term_id, $taxonomy );
echo "<h2>" . $term->name . "</h2>";
$args = array (
'post_type' => 'news',
'posts_per_page' => $posts_per_term,
'orderby' => 'date',
'order' => 'DESC',
'tax_query' => array (
array (
'taxonomy' => $taxonomy,
'field' => 'id',
'terms' => array($term_id),
),
),
);
$news = new WP_Query( $args );
if ( $news->have_posts() ) {
echo "<ul>";
while ( $news->have_posts() ) {
$news->the_post();
echo "<li>" . get_the_title() . "</li>";
}
echo "</ul>";
}
wp_reset_query();
}
What I'm trying to achieve: get n
terms from a custom taxonomy ordered by the newest post in each term. This will be used to display the newest m
posts under each term.
Is there a better way of doing this than getting an array of all the terms, and looping through to find the newest post in each? This approach doesn't feel very efficient or scalable.
Update
Here's my working code so far - can this be improved on?
$taxonomy = 'industry'; //taxonomy name
$terms_to_display = 5; //number of terms to display
$posts_per_term = 4; // number of posts per term to display
$terms = get_terms( array('taxonomy' => $taxonomy, 'hide_empty' => true, 'fields' => 'ids' ) );
$news_items = [];
foreach ( $terms as $term ) {
$args = array (
'post_type' => 'news',
'posts_per_page' => $posts_per_term,
'orderby' => 'date',
'order' => 'DESC',
'tax_query' => array (
array (
'taxonomy' => $taxonomy,
'field' => 'id',
'terms' => array($term),
),
),
);
$news = new WP_Query( $args );
if ( $news->post_count == $posts_per_term ) { // ignore terms with not enough posts
$news_items[$term] = get_the_date("U", $news->posts[0]->ID); //get date of newest post in this term
}
wp_reset_query();
}
arsort ( $news_items ); //sort descending, keeping keys
$term_ids = array_keys ( array_slice($news_items, 0, $terms_to_display, true) ); //take 'n' newest and return an array of keys (term ids)
foreach ( $term_ids as $term_id ) {
$term = get_term ( $term_id, $taxonomy );
echo "<h2>" . $term->name . "</h2>";
$args = array (
'post_type' => 'news',
'posts_per_page' => $posts_per_term,
'orderby' => 'date',
'order' => 'DESC',
'tax_query' => array (
array (
'taxonomy' => $taxonomy,
'field' => 'id',
'terms' => array($term_id),
),
),
);
$news = new WP_Query( $args );
if ( $news->have_posts() ) {
echo "<ul>";
while ( $news->have_posts() ) {
$news->the_post();
echo "<li>" . get_the_title() . "</li>";
}
echo "</ul>";
}
wp_reset_query();
}
Basically, what you are doing right now is this:
industry
taxonomyWP_Query
to get the newest posts, iterate through them to sort the terms, creating a new array with term idsWP_Query
to get the newest posts, and iterate through themThat's a lot of WP_Query
ies. Let's try to lower that number.
We can do it like this:
industry
taxonomyWP_Query
to get the newest posts, iterate through them to sort the terms, creating a new arrayU
format, and contain both the term object and the array with post objects, so we won't have to query them again.Here is my suggested code:
$taxonomy = 'industry'; //taxonomy name
$terms_to_display = 5; //number of terms to display
$posts_per_term = 4; // number of posts per term to display
$terms = get_terms( array('taxonomy' => $taxonomy, 'hide_empty' => true ) );
$news_items = [];
foreach ( $terms as $term ) {
$args = array (
'post_type' => 'news',
'posts_per_page' => $posts_per_term,
'orderby' => 'date',
'order' => 'DESC',
'tax_query' => array (
array (
'taxonomy' => $taxonomy,
'field' => 'id',
'terms' => array( $term->term_id ),
),
),
);
$news_query = new WP_Query( $args );
// ignore terms with not enough posts
if ( $news_query->post_count < $posts_per_term ) {
continue;
}
$news_posts = $news_query->get_posts();
// get date of newest post in this term
$newest_post_date = get_the_date( "U", $news_posts[0]->ID );
$news_items[$newest_post_date] = array(
'term' => $term,
'news' => $news_posts,
);
}
krsort( $news_items ); // sort descending by keys
$news_items = array_slice( $news_items, 0, $terms_to_display );
wp_reset_query();
I have made a few more changes as well:
1. $terms
is now array of the WP_Term
objects, not just ids
2. Made the $news_query->post_count < $posts_per_term
check slightly more readable
And how to use:
foreach ( $news_items as $item ) {
echo "<h2>" . $item['term']->name . "</h2>";
echo "<ul>";
foreach ( $item['news'] as $news_post ) {
setup_postdata( $news_post );
echo "<li>" . get_the_title() . "</li>";
}
echo "</ul>";
}
wp_reset_query();
This way, we have lowered the number of WP_Query
ies to the number of non-empty terms in the industry
taxonomy, and made the resulting array much more useful.
arra y
,"<h2">
. What editor/IDE are you using for coding? It should underline those things. – djboris Commented Apr 10, 2019 at 12:24