I am trying to exclude a specific category ID from showing in WordPress search results. I have tried with this code which I have found several places on the internet, but it does not seem to work. I have changed the ID to the correct ID.
function my_search_filter( $query ) {
if ( $query->is_search && !is_admin() )
$query->set( 'cat','-21' );
return $query;
}
add_filter( 'pre_get_posts', 'my_search_filter' );
Right now my solution is using the code below, where I have to manually insert every page ID. It is working, but not a good solution.
add_action('pre_get_posts','exclude_posts_from_search');
function exclude_posts_from_search( $query ){
if( $query->is_main_query() && is_search() ){
//Exclude posts by ID
$post_ids = array(52384,52366,52058,52392,52374);
$query->set('post__not_in', $post_ids);
}
}
Would it be possible to use my current code with categories instead of every page ID? Or is the first code example the way to go, but with some changes?
Place the following function in your active theme functions.php file
function exclude_categories_from_search($query) {
// run query only if we are searching
if ( !$query->is_search )
return $query;
$term_ids = array( 19, 18, 214, 226, 20 ); add category/term ids
$taxquery = array(
array(
'taxonomy' => 'category', //Here add your taxonomy eg: category
'field' => 'id',
'terms' => $term_ids,
'operator'=> 'NOT IN'
)
);
$query->set( 'tax_query', $taxquery );
}
add_action( 'pre_get_posts', 'exclude_categories_from_search' );
Related
I'm using this code to exclude some post category from the wordpress search results :
function SearchFilter($query)
{
if ($query->is_search)
{
$query->set('cat', '-709,-710,-614');
}
return $query;
}
add_filter('pre_get_posts','SearchFilter');
My problem is that it doesn't work for woocommerce categories and products are not filtered.
How can I filter some woocommerce categories too ?
Can you replace your category. hope this help you.
function wpse188669_pre_get_posts( $query ) {
if (
! is_admin()
&& $query->is_main_query()
&& $query->is_search()
) {
$query->set( 'post_type', array( 'product' ) );
// set your parameters according to
// https://codex.wordpress.org/Class_Reference/WP_Query#Taxonomy_Parameters
$tax_query = array(
array(
// likely what you are after
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => 'category-2',
'operator' => 'NOT IN',
),
);
$query->set( 'tax_query', $tax_query );
}
}
add_action( 'pre_get_posts', 'wpse188669_pre_get_posts' );
I am trying to move the posts in specific category (uncategorized) in the end of the search results in WordPress frontend search page.
The approach which I have for now is:
Remove the posts from the selected category from the main query
Create a new query and get posts from that category only
Merge both query results, so now the results from the specified category are in the end
Have to maintain pagination too
The code I am using for step 1 is:
function wcs_exclude_category_search( $query ) {
if ( is_admin() || ! $query->is_main_query() )
return;
if ( $query->is_search ) {
$query->set( 'cat', '-11' );
}
}
add_action( 'pre_get_posts', 'wcs_exclude_category_search', 1 );
Any guidance for this approach or a better approach would be appreciated. Thanks.
Normally I would prefer the "tax_query" parameter, something like
// in case there are other tax_query clauses on the query
$tax_query = (array) $query->get( 'tax_query' );
$tax_query[] = [
'taxonomy' => 'category',
'terms' => 11,
'field' => 'term_id',
'operator' => 'NOT IN'
];
$query->set( 'tax_query', $tax_query );
On the other hand, if the query already has posts from the "uncategorized" category, you could sort the results just before display by hooking on the_posts, something like:
add_action( 'the_posts', function( $posts, $query ){
if ( ! $query->is_search() ) {
return $posts;
}
usort( $posts, function ( $a, $b ){
$a_in_uncategorized = has_term( 11, 'category', $a );
$b_in_uncategorized = has_term( 11, 'category', $b );
// if neither or both are on the "uncategorized" category
// sort by date or whatever
if ( $a_in_uncategorized === $b_in_uncategorized ) {
return $b->post_date <=> $a->post_date;
}
if ( $a_in_uncategorized && ! $b_in_uncategorized ) {
return 1;
}
if ( ! $a_in_uncategorized && $b_in_uncategorized ) {
return -1;
}
return 0;
} );
return $posts;
}, 10, 2 );
I hope that helps :-)
I need to modify the WooCommerce product query because I want to filter the shown products on the shop pages based on product tag custom taxonomy.
So what I've tried is this here but it don't works:
add_filter( 'woocommerce_product_query_meta_query', 'filter', 10, 2 );
function filter( $meta_query, $query ) {
// Only on category pages
if ( ! is_product_category() ) {
return $meta_query;
}
$meta_query[] = array(
'key' => 'taxonomy',
'value' => 'product_tag',
'compare' => 'EXIST'
);
return $meta_query;
}
So I just want to display all products which have the taxonomy ABCSD in it.
The code is placed in my functions.php. What I'm doing wrong here?
Notice:
I mean the values I get when I call this function:
wp_get_post_terms( $product_id, 'product_tag' );
As it is about a taxonomy, you need to use a tax query and then the hook will be different. Also you can make it for specific product tags:
add_filter( 'woocommerce_product_query_tax_query', 'filter_products_with_specific_product_tags', 10, 2 );
function filter_products_with_specific_product_tags( $tax_query, $query ) {
// Only on category pages
if ( ! is_product_category() )
return $tax_query;
$tax_query[] = array(
'taxonomy' => 'product_tag',
'field' => 'name',
'terms' => array('Green', 'Yellow', 'Red'), // Defined product tags term names
);
return $tax_query;
};
Code goes in function.php file of your active child theme (or active theme). It should works.
I want to not display all the products that have category name is "shoes" in the shop page .
I mean in the shop page display all the products just that have a shoes categorie name and I'll add shoes products in another page exemple (I create a shoes page and will add all the shoes products in it) so please help me (I need that with code php or plugin).
Thank you
You could use the woocommerce_product_query hook, which is pretty similar to pre_get_posts except it already has the appropriate conditional logic.
add_action( 'woocommerce_product_query', 'custom_pre_get_posts_query' );
function custom_pre_get_posts_query( $q ) {
$tax_query = (array) $q->get( 'tax_query' );
$tax_query[] = array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( 'samples' ),
'operator' => 'NOT IN'
);
$q->set( 'tax_query', $tax_query );}
It’s easy to work, just you need to write one function in your function page.
add_action( 'pre_get_posts', 'custom_pre_get_posts_query' );
function custom_pre_get_posts_query( $q ) {
if ( ! $q->is_main_query() ) return;
if ( ! $q->is_post_type_archive() ) return;
if ( ! is_admin() && is_shop() && ! is_user_logged_in() ) {
$q->set( 'tax_query', array(array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( 'shirt', 'tshirt', 'pant' ), //Category name which not to want display products on the shop page
'operator' => 'NOT IN'
)));
}
remove_action( 'pre_get_posts', 'custom_pre_get_posts_query' );
}
Category name(‘shirt’, ‘tshirt’, ‘pant’) which not to want display products on the shop page
Just you can save your page then check,
If you see show any error then you can remove this code from above code lists.
remove_action( 'pre_get_posts', 'custom_pre_get_posts_query' );
I have a client with the following issue:
I need to be able to split their WooCommerce WordPress site into essentially two categories. If a user is logged in as a "Wholeseller", only products in the "Wholesale" category get pulled from the database.
However if the user is not logged in or is logged in but not a "Wholeseller", then only products without the "Wholesale" category get pulled from the database.
I figure I'll add something like this to the theme's functions.php file:
add_filter("some_woocommerce_hook", "wholeseller_filter");
function wholeseller_filter() {
if (current_user->role == "Wholeseller"){
//omit products without "wholesale" category while browsing whole site
} else {
//omit products with "wholesale" in the category while browsing whole site.
}
}
I've browsed around StackOverflow, but I haven't found what I'm looking for or quite know what keywords I should be using for my searches.
Can you point me in the right direction?
Yes it is possible. There is 2 ways:
1) With the pre_get_posts wordpress hook that is called after the query variable object is created, but before the actual query is run. So it is perfect for this case. We imagine here that the ID of 'Wholesale' category is '123'.
Here is the custom code:
function wholeseller_role_cat( $query ) {
// Get the current user
$current_user = wp_get_current_user();
if ( $query->is_main_query() ) {
// Displaying only "Wholesale" category products to "whole seller" user role
if ( in_array( 'wholeseller', $current_user->roles ) ) {
// Set here the ID for Wholesale category
$query->set( 'cat', '123' );
// Displaying All products (except "Wholesale" category products)
// to all other users roles (except "wholeseller" user role)
// and to non logged user.
} else {
// Set here the ID for Wholesale category (with minus sign before)
$query->set( 'cat', '-123' ); // negative number
}
}
}
add_action( 'pre_get_posts', 'wholeseller_role_cat' );
This code goes on function.php file of your active child theme or theme, or better in a custom plugin.
2) With the woocommerce_product_query WooCommerce hook. (We still imagine here that the ID of 'Wholesale' category is '123').
Here is the custom code:
function wholeseller_role_cat( $q ) {
// Get the current user
$current_user = wp_get_current_user();
// Displaying only "Wholesale" category products to "whole seller" user role
if ( in_array( 'wholeseller', $current_user->roles ) ) {
// Set here the ID for Wholesale category
$q->set( 'tax_query', array(
array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => '123', // your category ID
)
) );
// Displaying All products (except "Wholesale" category products)
// to all other users roles (except "wholeseller" user role)
// and to non logged user.
} else {
// Set here the ID for Wholesale category
$q->set( 'tax_query', array(
array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => '123', // your category ID
'operator' => 'NOT IN'
)
) );
}
}
add_action( 'woocommerce_product_query', 'wholeseller_role_cat' );
This code goes on function.php file of your active child theme or theme, or better in a custom plugin.
If you want to use the category slug instead of the category ID you will have to replace partially (both arrays) with:
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => 'wholesale', // your category slug (to use the slug see below)
You could add if you wish and need, some woocommerce conditionals tags in the if statements to restrict this even more.
References:
Modifying the WooCommerce Product Query
I can't fetch WooCommerce products by category id
WordPress Class Reference - WP Query
To make this more performant and only work on the woocommerce query use the following function and hook.
function exclude_product_from_wholesale( $q ){
$current_user = wp_get_current_user();
$ARRAY_OF_PRODUCT_IDS_YOU_WANT_HIDDEN = array();
if ( in_array( 'wholeseller', $current_user->roles ) ) {
$q->set( 'post__not_in', $ARRAY_OF_PRODUCT_IDS_YOU_WANT_HIDDEN );
}
}
add_action( 'woocommerce_product_query', 'exclude_product_from_wholesale' );
You can drop this simple function into your functions.php.
function exclude_categories_for_vendors( $query ) {
// Get the current user
$current_user = wp_get_current_user();
$ARRAY_OF_PRODUCT_CATEGORIES_IDS_YOU_WANT_HIDDEN = array(26,23,20);
if( is_user_logged_in() ){
if ( $query->is_main_query() ) {
if ( in_array( 'editor', (array) $current_user->roles ) ) {
//echo "editor";
//below query will hide categories for Vendor user in Admin Panel
$query->set( 'tax_query', array(
array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $ARRAY_OF_PRODUCT_CATEGORIES_IDS_YOU_WANT_HIDDEN, // your category ID
'operator' => 'NOT IN'
)
) );
} else{
//no changes
}
}
}
}
add_action( 'pre_get_posts', 'exclude_categories_for_vendors' );