I have a custom post type - Poems.
And I create a two taxonomy - Cities and Authors.
When I clicked on "Paris" menu item - I need to displayed all Authors and his list of poems in that city.
How to do it ?
Thanks.
You'll likely want to take a look at the Codex entry for WP Query. That gives you all the information you could want on creating custom WordPress queries. Including taxonomy arguments.
You'd want to pass to tax query arguments using the AND relation. Something along the lines of this example:
$args = array(
'post_type' => 'post',
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'city',
'field' => 'slug',
'terms' => 'london',
),
array(
'taxonomy' => 'author',
'field' => 'slug',
'terms' => 'dickens',
),
),
);
$query = new WP_Query( $args );
Edit: 10/30/17 per comment below
If you were saving your author's as post meta you could order by that. But if your author is also a taxonomy it gets a little trickier since there isn't a good way to order by a taxonomy. See this related question.
Instead we could get all of our author taxonomy terms using get_terms.
$authors = get_terms( 'author', array(
'hide_empty' => false,
) );
That gives us all author terms that have at least one post assigned to them.
Now that we have the terms we could run through each author and run a query to get the poems for that author in that city. Like so:
foreach ( $authors as $author ) {
$args = array(
'post_type' => 'poem',
'tax_query' => array(
relation => 'AND',
array(
'taxonomy' => 'city',
'field' => 'slug',
'terms' => 'london',
),
array(
'taxonomy' => 'author',
'field' => 'term_id',
'terms' => $author->term_id,
),
),
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) :
while ( $query->have_posts() ) : $query->the_post();
// Put your post markup here
endwhile;
endif; wp_reset_query();
}
If you are not good with coding you can use free Content Views plugin, and combine that yyou have to combine. I started like this.
Related
I have a custom post type "product", and two custom taxonomies: "productfamily" and "industry".
On my single product page, I need to show products that are in the same productfamily and industry.
Some products might be in a few different industries...and my related products section only needs to match one of the industries of the current post to show up.
Here's what I have so far...
$wp_query = new WP_Query(
array(
'posts_per_page' => '4',
'post_type' => 'product',
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'productfamily',
'field' => 'slug',
'terms' => $prodfam,
'operator' => 'IN'
),
array(
'taxonomy' => 'industry',
'field' => 'term_id',
'terms' => $prodindustry,
'operator' => 'IN'
),
),
'orderby' => 'title',
'order' => 'ASC',
)
);
If I change the "AND" relation to "OR", it seems to partly work by showing products from the same "productfamily", but doesn't seem to be taking the "industry" into account at all.
How can I get this to show related products based off of my two custom taxonomies please? Thanks in advance for your help.
As you described in comment that you have slugs array in variables but in one of your tax query condition, you've used term_id to match with slug. that is incorrect.
You can directly use the terms ids instead of slugs since it's dynamic things. in function wp_get_post_terms you can pass array( 'fields' => 'ids' ) as 3rd param and it will give you array of ids. so you don't have make an extra loop.
Then you'll have to check both terms array if they both are empty of one of them or both of them as values?
then you can check them individually and then add the tax query part if ids are available.
This is how you can write the code in a clean way with proper checks:
global $post;
// Get the terms ids array,
// we can pass 'fields' => 'ids' in 3rd param so we don't need to run the loop to collect ids.
$product_family_ids = wp_get_post_terms( $post->ID, 'productfamily', array( 'fields' => 'ids' ) );
$industry_ids = wp_get_post_terms( $post->ID, 'industry', array( 'fields' => 'ids' ) );
// Prepare query args.
$query_args = array(
'posts_per_page' => '4',
'post_type' => 'product',
'orderby' => 'title',
'order' => 'ASC',
'tax_query' => array(
'relation' => 'AND',
),
);
// We need to check if both ids are not empty.
// if both empty we don't wanna run query.
if ( ! empty( $product_family_ids ) || ! empty( $industry_ids ) ) {
// If product family terms are available.
if ( ! empty( $product_family_ids ) ) {
$query_args['tax_query'][] = array(
'taxonomy' => 'productfamily',
'field' => 'term_id',
'terms' => (array) $product_family_ids,
'operator' => 'IN',
);
}
// If industry terms are available.
if ( ! empty( $industry_ids ) ) {
$query_args['tax_query'][] = array(
'taxonomy' => 'industry',
'field' => 'term_id',
'terms' => (array) $industry_ids,
'operator' => 'IN',
);
}
$related_posts = new WP_Query( $query_args );
if ( $related_posts->have_posts() ) {
while ( $related_posts->have_posts() ) {
$related_posts->the_post();
/**
* DO you thing here.
*/
}
}
wp_reset_postdata();
}
Note: I have not tested the code so there might be syntax errors, if you use the code and find errors after using the code please let me know so that I could fix errors in my answers. Also, Make sure you have site backup and FTP access to fix the errors, Don't add code from WordPress backend
I need to exclude custom post type entries with a specific custom taxonomy from the main query. I have reviewed other similar entries on SE but can't make it work.
This is what I have:
$args = array(
'post_type' => 'pojazdy', //my cpt name
'tax_query' => array(
array(
'taxonomy' => 'oferta_aktywna', //my custom taxonomy name
'field' => 'slug',
'terms' => 'sprzedane', //specific custom category
'operator' => 'NOT IN',
),
)
);
$query = new WP_Query( $args );
I'm using WP_Query for Woocommerce products in attempt to query products in a particular category. This is the syntax that worked for me -
$args = array(
'posts_per_page' => -1,
'product_cat' => 'category-slug-here',
'post_type' => 'product',
'orderby' => 'title',
);
$the_query = new WP_Query( $args );
// The Loop
while ( $the_query->have_posts() ) {
$the_query->the_post();
echo '' . get_the_title() . '<br /><br />';
}
wp_reset_postdata();
This returns data, but I want to pass an ID, not a category slug, to filter and I want to find products that exist in multiple categories only.
The argument product_cat is not native to WP_Query (at least that I can find), so I'm assuming this is something custom to Woocommerce. Through their documentation, I haven't been able to find anything that will allow me to filter by category ID, nor use an AND condition for this filtering.
Using cat, the array of tax_query, and category__and have not yielded any results. Essentially, I would like to query all products that exist in both category ID 102, and 115. If I have to use slugs, I'm sure there is a way around getting that info based on the ID I have, but I'd like to avoid 2 queries to filter by multiple categories.
Does anyone know how to accomplish this?
UPDATE: I have learned that separating category slugs by commas in the product_cat argument will produce an "OR" effect, so it will combine distinct products from both, but this is not what I am looking for. So, for example:
'product_cat' => 'category-slug1, category-slug2'
will return products from both categories in total, but I am still searching for a way to find distinct products that ONLY belong to both, or multiple, categories.
Wow, so after hours of banging my head, this is how I was able to solve this -
$args = array(
'posts_per_page' => -1,
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => 'category-slug1'
),
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => 'category-slug2'
)
),
'post_type' => 'product',
'orderby' => 'title',
);
$the_query = new WP_Query( $args );
This takes advantage of the tax_query argument, including the relation => 'AND' to make sure the product falls under BOTH categories.
Hope this helps someone in the future.
I was also not able to figure out how to pass an ID, rather than a slug (although I'm sure there's a way), but here's the function to retrieve the slug based on an ID:
$terms = get_term($YOURID, 'product_cat');
$theslug = $terms->slug;
From the WordPress codex on WP_Query for Category Parameters:
equivalent of OR
$args = array( 'product_cat' => 'category-slug1,category-slug2' );
equivalent of AND
$args = array( 'product_cat' => 'category-slug1+category-slug2' );
e.g.
$query = new WP_Query( $args );
To query by category_ID this is what worked for me.
// First obtain term id:
//...
$all_categories = get_categories( $args );
$cat_ids = array();
foreach ($all_categories as $cat)
{
array_push($cat_ids, $cat->term_id);
}
//Now use ids from array:
$args = array(
'posts_per_page' => -1,
'post_type' => 'product',
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => $cat_ids
)
)
);
Inside a 'tax_query' array's array you can specify an 'operator' to be performed on the query. You can achieve what you want using the 'AND' operator.
$args = array(
'posts_per_page' => -1,
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( 'category-slug1', 'category-slug2' )
'operator => 'AND',
),
),
'post_type' => 'product',
'orderby' => 'title',
);
$the_query = new WP_Query( $args );
All of the products selected by this query will match the provided 'terms'. See this link for more info: https://codex.wordpress.org/Class_Reference/WP_Query#Taxonomy_Parameters
In case the link ever breaks, here's the relevant info:
operator (string) - Operator to test. Possible values are 'IN', 'NOT IN', 'AND', 'EXISTS' and 'NOT EXISTS'. Default value is 'IN'.
Thanks in advance for any help.
I've created a page that lists the taxonomy of a custom-post-type. The issue I'm running into is the page that links from this listing should only pull the category and a placement code (in the example that's standard). It's pulling the placement but how do I get it to add in the dynamically created category pulled from the previous page.
Code that dynamically pulls taxonomy (category header). This pulls the right category on the page.
$term = get_term_by( 'slug', get_query_var( 'term' ), get_query_var( 'taxonomy' ) ); echo $term->name;
Code below that pulls on the particular placement. How do I add the dynamically pulled taxonomy pulled by code above so content meets both criteria.
$args = array(
'post_type' => 'buyersguide',
'meta_query' => array(
array(
'key' => 'Placement',
'value' => 'standard',
'compare' => 'LIKE'
)
)
);
query_posts($args);
You can fix this by using the following code:
$args = array(
'post_type' => 'buyersguide',
'meta_query' => array(
array(
'key' => 'Placement',
'value' => 'standard',
'compare' => 'LIKE'
)
),
'tax_query' => array(
array(
'taxonomy' => $term->taxonomy,
'field' => 'slug',
'terms' => $term->slug
)
)
);
query_posts($args);
For more information on taxonomy parameters, go to: Taxonomy Parameters - WP_Query
I recently added post formats to my WordPress theme - on the blog page its fine as they are all styled accordingly. However on my home page template I only want to show 'standard' posts formats (no links, galleries, audio, video etc.).
In my theme options I can decide how many posts to display on the front page which is what 'dft_recent_number' is for.
Does anybody know how I can change the code below to exclude all but 'standard' post formats?
<?php
$query = new WP_Query();
$query->query('posts_per_page='.get_option('dft_recent_number'));
//Get the total amount of posts
$post_count = $query->post_count;
while ($query->have_posts()) : $query->the_post();
?>
Any help is much appreciated!
WP_Query does not seem to have a straightforward parameter for post_format.
From my quick research it appears that post formats are related through taxonomies. So, theoretically, using the taxonomy parameters should work.
$args = array(
'tax_query' => array(
array(
'taxonomy' => 'post_format',
'field' => 'slug',
'terms' => 'post-format-standard',
)
)
);
$query = new WP_Query( $args );
Note: you'll need to update the taxonomy names and slugs for your blog. This should be the names you set in your functions.php file.
// there's no post-format-standard so you should write it like this to exclude all other postpformats
array(
'taxonomy' => 'post_format',
'field' => 'slug',
'terms' => array('post-format-quote','post-format-audio','post-format-gallery','post-format-image','post-format-link','post-format-video'),
'operator' => 'NOT IN'
)
I know that's old, but I was facing the same issue and even though I've found a solution I wondered what other have done to "fix" that.
I think a more scalable solution could be something like that:
$post_formats = get_theme_support( 'post-formats' );
$tax_query = false;
if ( $post_formats ) {
$tax_query = array(
array(
'taxonomy' => 'post_format',
'field' => 'slug',
'terms' => $post_formats[0],
'operator' => 'NOT IN'
)
);
}
// WP_Query arguments
$args = array(
'post_type' => 'post',
'order' => 'DESC',
'orderby' => 'date',
'tax_query' => $tax_query
);
This would exclude the post formats that have been enabled and also will work in case WP will add more post formats (or add the ability to add more).