admin管理员组文章数量:1025535
I have a new WP_Query
that I use to generate a custom loop and display a set of posts. One of the things the query does is provide pagination.
Before I display the queried posts though, I'd like to get a list of all the tags for the posts found. I know I can do this by looping through each of the posts and then removing duplicates, but I was hoping for a more elegant approach.
I have a new WP_Query
that I use to generate a custom loop and display a set of posts. One of the things the query does is provide pagination.
Before I display the queried posts though, I'd like to get a list of all the tags for the posts found. I know I can do this by looping through each of the posts and then removing duplicates, but I was hoping for a more elegant approach.
Share Improve this question asked Jan 29, 2013 at 9:14 JackJack 2463 silver badges11 bronze badges3 Answers
Reset to default 1I don't think that is possible. The SQL query performed by WP_Query
returns only the post objects (and perhaps some metadata), while the tags resides in a different table. When looping through the returned posts in templates you usually put the_tags();
or something similar in your templates, which in turns runs a new database query for each post.
However, you could run a separate query to load the tags prior to running your primary posts query. As far as I know there is no function WordPress API that will let you load the tags of more than one post at the time, but you could accomplish that by directly calling $wpdb
.
Something like this might help get you started:
global $wpdb;
$sql = $wpdb->prepare(
"SELECT DISTINCT $wbdb->terms.* FROM $wbdb->term_relationships
JOIN $wbdb->posts
ON $wbdb->posts.ID = $wbdb->term_relationships.object_id
JOIN $wbdb->term_taxonomy
ON $wbdb->term_taxonomy.term_taxonomy_id = $wbdb->term_taxonomy.term_taxonomy_id
JOIN $wbdb->terms
ON $wbdb->term_taxonomy.term_id = $wbdb->terms.term_id
WHERE $wbdb->term_taxonomy.taxonomy = 'post_tag'
AND $wbdb->posts.ID IN (1,2,3,4,5,6,7,8,9,10)"
);
$tags = $wpdb->query($sql);
As you can see this assumes that you know your post IDs beforehand, which you most likely does not. In that case you would need to replace the lists in the parentheses with a subquery, which in it's simplest form would be SELECT ID FROM $wpdb->posts
, but more likely will need to filter/order/limit posts by category, date, etc. A problem I encountered is that my version of MySQL did not support LIMIT
in subqueries. If yours doesn't either it might be hard to accomplish this in one query. Unless you have a lot of posts you could just loop through your WP_Query
first and collect the post IDs. In any case, this will be faster than running separate queries for each post since you will only run one tag-related query instead of running one for each post.
For the sake of posterity, I ended up just iterating through the loop twice: once to get the tags, and then to actually display the page.
Here's my code:
if ( have_posts() ) :
// get tags for found posts
$recent_tags = array();
while ( $loop->have_posts() ) : $loop->the_post();
foreach(get_the_tags() as $t) $recent_tags[$t->slug] = $t->name; // this adds to the array in the form ['slug']=>'name'
endwhile;
// de-dupe
$recent_tags = array_unique($recent_tags);
// sort
natcasesort($recent_tags);
// do something with the array
while ( $loop->have_posts() ) : $loop->the_post();
// normal wp loop
Getting the tags of multiple posts can be achieved by passing 'object_ids'
to get_terms()
.
First, let another WP_Query
return you only the IDs of your desired posts. For example get all posts of a given category:
// Get the posts.
$category = get_queried_object();
$args = [
'cat' => $category->term_id,
'fields' => 'ids',
];
$the_query = new WP_Query($args);
Now that you have the IDs you can simply hand them over to get_terms()
and will be returned a list of all tags of these selected posts:
// Get the terms of these posts.
if ($the_query->have_posts()) {
$terms = get_terms([
'taxonomy' => 'post_tag',
'object_ids' => $the_query->posts,
]);
}
Source: https://developer.wordpress/reference/classes/wp_term_query/__construct/#comment-2500
I have a new WP_Query
that I use to generate a custom loop and display a set of posts. One of the things the query does is provide pagination.
Before I display the queried posts though, I'd like to get a list of all the tags for the posts found. I know I can do this by looping through each of the posts and then removing duplicates, but I was hoping for a more elegant approach.
I have a new WP_Query
that I use to generate a custom loop and display a set of posts. One of the things the query does is provide pagination.
Before I display the queried posts though, I'd like to get a list of all the tags for the posts found. I know I can do this by looping through each of the posts and then removing duplicates, but I was hoping for a more elegant approach.
Share Improve this question asked Jan 29, 2013 at 9:14 JackJack 2463 silver badges11 bronze badges3 Answers
Reset to default 1I don't think that is possible. The SQL query performed by WP_Query
returns only the post objects (and perhaps some metadata), while the tags resides in a different table. When looping through the returned posts in templates you usually put the_tags();
or something similar in your templates, which in turns runs a new database query for each post.
However, you could run a separate query to load the tags prior to running your primary posts query. As far as I know there is no function WordPress API that will let you load the tags of more than one post at the time, but you could accomplish that by directly calling $wpdb
.
Something like this might help get you started:
global $wpdb;
$sql = $wpdb->prepare(
"SELECT DISTINCT $wbdb->terms.* FROM $wbdb->term_relationships
JOIN $wbdb->posts
ON $wbdb->posts.ID = $wbdb->term_relationships.object_id
JOIN $wbdb->term_taxonomy
ON $wbdb->term_taxonomy.term_taxonomy_id = $wbdb->term_taxonomy.term_taxonomy_id
JOIN $wbdb->terms
ON $wbdb->term_taxonomy.term_id = $wbdb->terms.term_id
WHERE $wbdb->term_taxonomy.taxonomy = 'post_tag'
AND $wbdb->posts.ID IN (1,2,3,4,5,6,7,8,9,10)"
);
$tags = $wpdb->query($sql);
As you can see this assumes that you know your post IDs beforehand, which you most likely does not. In that case you would need to replace the lists in the parentheses with a subquery, which in it's simplest form would be SELECT ID FROM $wpdb->posts
, but more likely will need to filter/order/limit posts by category, date, etc. A problem I encountered is that my version of MySQL did not support LIMIT
in subqueries. If yours doesn't either it might be hard to accomplish this in one query. Unless you have a lot of posts you could just loop through your WP_Query
first and collect the post IDs. In any case, this will be faster than running separate queries for each post since you will only run one tag-related query instead of running one for each post.
For the sake of posterity, I ended up just iterating through the loop twice: once to get the tags, and then to actually display the page.
Here's my code:
if ( have_posts() ) :
// get tags for found posts
$recent_tags = array();
while ( $loop->have_posts() ) : $loop->the_post();
foreach(get_the_tags() as $t) $recent_tags[$t->slug] = $t->name; // this adds to the array in the form ['slug']=>'name'
endwhile;
// de-dupe
$recent_tags = array_unique($recent_tags);
// sort
natcasesort($recent_tags);
// do something with the array
while ( $loop->have_posts() ) : $loop->the_post();
// normal wp loop
Getting the tags of multiple posts can be achieved by passing 'object_ids'
to get_terms()
.
First, let another WP_Query
return you only the IDs of your desired posts. For example get all posts of a given category:
// Get the posts.
$category = get_queried_object();
$args = [
'cat' => $category->term_id,
'fields' => 'ids',
];
$the_query = new WP_Query($args);
Now that you have the IDs you can simply hand them over to get_terms()
and will be returned a list of all tags of these selected posts:
// Get the terms of these posts.
if ($the_query->have_posts()) {
$terms = get_terms([
'taxonomy' => 'post_tag',
'object_ids' => $the_query->posts,
]);
}
Source: https://developer.wordpress/reference/classes/wp_term_query/__construct/#comment-2500
本文标签: wp queryGiven a WPQueryhow can I get a list of tags
版权声明:本文标题:wp query - Given a WP_Query, how can I get a list of tags? 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745629747a2160087.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论