admin管理员组文章数量:1323157
I have a simple WP_Query:
$loop = new WP_Query(array(
'post_type' => array('image', 'video'),
'category_name' => $cat,
'meta_key'=>'total_votes',
'orderby'=>'date meta_value_num'
));
How can I alter this so that it return only videos with the tag editor-pick
while still returning all images regardless of tags?
I'm looking for a filter to add onto the MySQL query so that order and pagination remain intact.
I have a simple WP_Query:
$loop = new WP_Query(array(
'post_type' => array('image', 'video'),
'category_name' => $cat,
'meta_key'=>'total_votes',
'orderby'=>'date meta_value_num'
));
How can I alter this so that it return only videos with the tag editor-pick
while still returning all images regardless of tags?
I'm looking for a filter to add onto the MySQL query so that order and pagination remain intact.
Share Improve this question edited Dec 30, 2014 at 18:33 jetlej asked Dec 2, 2014 at 21:11 jetlejjetlej 5721 gold badge6 silver badges24 bronze badges 8- Where is this query happening? A widget? – Tom J Nowell ♦ Commented Dec 3, 2014 at 1:50
- Yes, you're going to want to use a query filter, along with some more advanced sql queries to achieve this goal. Just using the WP_Query object won't achieve this alone. – Hybrid Web Dev Commented Dec 3, 2014 at 4:56
- 1 I'm sure @tf is pretty close to solve this for you with his solution (+1), but in the meanwhile I wonder if this kind of experiment can help you? – birgire Commented Dec 30, 2014 at 19:03
- @birgire, that's exactly what I need! Thanks so much for putting together that plugin! – jetlej Commented Dec 30, 2014 at 23:59
- 1 The reason I wrote that it wasn't supported is that in general one sub-query might not contain any meta query, so ordering by a meta value might then not make sense. We must order by a field that's contained in both (all) sub-queries. I just played with it and found a way to order the combined query (where all the sub-queries contain a meta query) by a meta value, I will update that plugin version (plus some bug fixes) on Github in couple of days. Then we could continue on the Issue tracker over there. – birgire Commented Dec 31, 2014 at 11:00
5 Answers
Reset to default 4 +50I happened to be working on something similar today and just remembered you were looking for something like this, so let me share it with you.
Here's how one can use the posts_where
filter to restrict the WP_Query
, to posts in some custom post type cpt1 OR another post type cpt2 that's attached to some taxonomy term.
Here's an example:
add_filter( 'posts_where', 'wpse_posts_where' );
$loop = new WP_Query( $args );
where
/**
* Restrict WP_Query to ( cpt1 OR cpt2 attached to a given term in some taxonomy).
*
* @see http://wordpress.stackexchange/a/173889/26350
*/
function wpse_posts_where( $where )
{
global $wpdb;
// Run this filter callback only once:
remove_filter( current_filter(), __FUNCTION__ );
// Modify this to your needs:
$cpt1 = 'image';
$cpt2 = 'video';
$taxonomy = 'post_tag'; // Related to cpt2
$term_slug = 'editor-pick'; // Related to cpt2
// Get the term info for the term_taxonomy_id:
$term = get_term_by( 'slug', $term_slug, $taxonomy );
// Modify the SQL query:
if( ! is_wp_error( $term ) )
{
$where .= " AND ( {$wpdb->posts}.post_type = '{$cpt1}'
OR {$wpdb->posts}.post_type = '{$cpt2}'
AND {$wpdb->posts}.post_status = 'publish'
AND {$wpdb->posts}.ID IN (
SELECT object_id FROM {$wpdb->term_relationships}
WHERE term_taxonomy_id IN ( {$term->term_taxonomy_id} ) ) ) ";
}
return $where;
}
where you might have to modify it further to your needs.
Unfortunately, you can't. At least not with a single WP_Query
, that is. What you could do, however, is run two separate queries - one for each post type - then combine the results. Like so:
$args = array(
'post_type' => 'image',
'category_name' => $cat,
'meta_key' => 'total_votes',
'orderby' => 'date meta_value_num',
);
$loop = new WP_Query( $args );
$args = array(
'post_type' => 'video',
'category_name' => $cat,
'tag' => 'editor-pick',
'meta_key' => 'total_votes',
'orderby' => 'date meta_value_num',
);
$loop2 = new WP_Query( $args );
$loop->posts = array_merge( $loop->posts, $loop2->posts );
$loop->found_posts += $loop2->found_posts;
$loop->max_num_pages = ceil( $loop->found_posts / $loop->query_vars[ 'posts_per_pages' ] );
Note: This is untested code. I hope it may be of help to you, though.
// tell WordPress about our new query var
function wpse52480_query_vars( $query_vars ){
$query_vars[] = 'my_special_query';
return $query_vars;
}
add_filter( 'query_vars', 'wpse52480_query_vars' );
// check if our query var is set in any query
function wpse52480_pre_get_posts( $query ){
if( isset( $query->query_vars['my_special_query'] ) )
// do special stuff
return $query;
}
add_action( 'pre_get_posts', 'wpse52480_pre_get_posts' );
and in the template:
// set the query var (along with whatever others) to trigger the filter
$args = array(
'my_special_query' => true
);
$my_secondary_loop = new WP_Query( $args );
You can use the taxonomy params to achieve this https://codex.wordpress/Class_Reference/WP_Query#Taxonomy_Parameters
One WP_Query-way of doing this is to fetch all other categories than the ones you want to use, and use operator => NOT IN
like so:
$terms_to_use = [ 10, 12, 15 ];
$all_other_terms = get_terms( [
'taxonomy' => 'category',
'fields' => 'slugs',
'exclude' => $terms_to_use,
] );
$args = [
'post_type' => [ 'post', 'my_cpt' ],
'tax_query' => [
[
'taxonomy' => 'category',
'operator' => 'NOT IN',
'terms' => $all_other_terms
]
]
];
This way, you will only get posts with categories 10, 12 and 15, and you will get all posts from my_cpt
.
本文标签: wp queryWPQuery with two post typesbut requiring category on only one of those post types
版权声明:本文标题:wp query - WP_Query with two post types, but requiring category on only one of those post types 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742141674a2422606.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论