I've been trying to hide a specific category from SHOP page. I found this code:
add_filter( '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;
$q->set( 'tax_query', array(array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( 'CATEGORY TO HIDE' ),
'operator' => 'NOT IN'
)));
remove_filter( 'pre_get_posts', 'custom_pre_get_posts_query' );
}
I've pasted this code in my theme function.php file but I'm not achieving the result...
Can anybody help me please?
I know this is a bit late, but had this problem myself and solved it with the following function:
add_filter( 'get_terms', 'get_subcategory_terms', 10, 3 );
function get_subcategory_terms( $terms, $taxonomies, $args ) {
$new_terms = array();
// if a product category and on the shop page
if ( in_array( 'product_cat', $taxonomies ) && ! is_admin() && is_shop() ) {
foreach ( $terms as $key => $term ) {
if ( ! in_array( $term->slug, array( '**CATEGORY-HERE**' ) ) ) {
$new_terms[] = $term;
}
}
$terms = $new_terms;
}
return $terms;
}
The following snippet it works fine for me:
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() ) {
$q->set( 'tax_query', array(array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( 'your category slug' ), // Don't display products in the knives category on the shop page
'operator' => 'NOT IN'
)));
}
remove_action( 'pre_get_posts', 'custom_pre_get_posts_query' );
}
I'm wondering how can I achieve the same for the products excluded within the category to be searchable via product search, while using the snippet those products gets totally hidden.
Simple way to hide a category from everything except the admin backend:
In functions.php:
add_filter( 'get_terms', 'hide_category', 10, 1 );
function hide_category( $terms ) {
$new_terms = array();
foreach ( $terms as $term ) {
if ( $term->slug !== 'secret_category' ) {
$new_terms[] = $term;
} else if ( $term->taxonomy !== 'product_cat' || is_admin() ) {
$new_terms[] = $term;
}
}
return $new_terms;
}
If you want to only hide it from the shop, add || !is_shop() to the else if condition.
If you want to hide some categories in your theme you can just pass exclude argument in the wp_list_categories function:
wp_list_categories( array(
'taxonomy' => 'product_cat',
'hide_empty' => 1,
'use_desc_for_title' => 0,
'title_li' => ' ',
'show_count' => 0,
'exclude' => '63' // <-- Hidden) );
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 would like to disable categories that don't have any products in them. Here's the code that seems to not be working.
Placed in my functions.php
function woo_hide_product_categories_widget( $list_args ){
$list_args[ 'hide_empty' ] = 1;
return $list_args;
}
add_filter( 'woocommerce_product_categories_widget_args','woo_hide_product_categories_widget' );
add_filter( 'woocommerce_product_categories_widget_args', 'wpsites_exclude_product_cat_widget' );
function wpsites_exclude_product_cat_widget( $args ) {
$args['exclude'] = array('16','46');
return $args;
}
try this
you can hide specific categories by the following:
add_action( 'pre_get_posts', 'uw_remove_product_cats_shop_page' );
function uw_remove_product_cats_shop_page( $query ) {
// Comment out the line below to hide products in the admin as well
if ( is_admin() ) return;
if ( is_shop() && $query->is_main_query() ) {
$query->set( 'tax_query', array(
array(
'taxonomy' => 'product_cat',
'field' => 'ID',
'terms' => array( 200, 205, 210 ), //ID of categories here
'operator' => 'NOT IN'
)
) );
}
}
In WooCommerce I have checked the option "Visibility out of stock", but I need that some product category stay visible, even if that option is checked.
On the other hand, the main store doesn't show that category. For that I used this code:
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() ) {
$q->set( 'tax_query', array(array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( 'MYCATEGORY' ), // Don't show this category.
'operator' => 'NOT IN'
)));
}
remove_action( 'pre_get_posts', 'custom_pre_get_posts_query' );
}
As it would be possible to do this?
Thank you!
This is just a quick guess, not tested but could you try starting with something like:
global $product;
$terms = wp_get_post_terms( $post->ID, 'product_cat' );
foreach ( $terms as $term ) $categories[] = $term->slug;
$category_to_show = ‘MYCATEGORY’;
if( $categories ) {
if( in_array( $category_to_show, $categories ) && !$product->is_in_stock() ) {
apply_filters( 'woocommerce_product_is_visible', true, $product->id );
}
}
The code below with the 19 is working correctly as it is copied from the woocommerce website. Unfortunate I can't get it working to replace the 19 with $producten so that $producten contains an array with all categories.
$producten contains multiple categories that need to be hidden and are defined in the database. Is it possible what I want to do and how?
$userid = get_current_user_id();
$result = mysql_query("SELECT productID FROM bestellingen WHERE userID='$userid'");
$producten = array();
while($row = mysql_fetch_array($result)){
array_push($producten, $row['productID']);
}
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() ) {
$q->set( 'tax_query', array(array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( 19 ), // de categorienummers
'operator' => 'NOT IN'
)));
}
remove_action( 'pre_get_posts', 'custom_pre_get_posts_query' );
}
Thanks in advance!
It is solved using a session like:
$result = mysql_query("SELECT productID FROM bestellingen WHERE userID='$userid'");
$producten = array();
while($row = mysql_fetch_array($result)){
array_push($producten, $row['productID']);
}
$_SESSION['PRODUCTEN'] = $producten;
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() ) {
$q->set( 'tax_query', array(array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $_SESSION['PRODUCTEN'], // Don't display products in the knives category on the shop page
'operator' => 'NOT IN'
)));
}
unset($_SESSION['PRODUCTEN']);
remove_action( 'pre_get_posts', 'custom_pre_get_posts_query' );
}
I have an options page in my wordpress theme, it's to select a number of categories from a custom taxonomy.
$terms_obj = get_option('shop_features')
This returns an array with $key being the category-name and $value being either 1 or empty depending if the category was checked.
I need to grab a list of the checked categories to use in an array in another function:
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() ) {
$q->set( 'tax_query', array(array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( 'knives' ), // Don't display products in the knives category on the shop page
'operator' => 'NOT IN'
)));
}
remove_action( 'pre_get_posts', 'custom_pre_get_posts_query' );
}
Where I need to insert my category-names contained in a variable $terms to replace the 'terms' => array('knives') with 'terms' => array ( $terms )
Except it doesn't work by just doing that!
Here is how I've tried to accomplish that:
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() ) {
$terms_obj = of_get_option( 'eco_shop_features', $default );
foreach ( $terms_obj as $slug => $checked ) { //$key ==> value
if ( $checked > 0 )
$terms .= '\'' . $slug . '\', ';
}
$terms = rtrim( $terms, ', ' );
$q->set( 'tax_query', array(array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( "$terms" ), // Don't display products in the knives category on the shop page
'operator' => 'NOT IN'
)));
}
remove_action( 'pre_get_posts', 'custom_pre_get_posts_query' );
}
I'm stuck of how to insert just the list of category names in to the terms field so it works as an array.
The right way seems to be commented out by you, below should work
foreach ( $terms_obj as $slug => $checked ) { //$key ==> value
if ( $checked > 0 )
$terms[] = $slug;
}
$q->set( 'tax_query', array(array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $terms,
'operator' => 'NOT IN'
)));
To get your array of category names you can do :
$terms_obj = get_option('shop_features');
$category_name_array = array_keys($terms_obj, 1);
The array_keys($terms_obj, 1) function will extract in an array all the keys of the $terms_obj for witch the value match 1.
More info : http://php.net/manual/en/function.array-keys.php
Just prepare an array in the loop
$terms[] = $slug
And assign to term
'terms' => $terms,