I am trying to create custom dynamic menu for Woocommerce, and it seem I am stuck.
To mark my categories as active, I need category ID of a page that I am in at the moment.
If I am in a category I get id like this:
if (is_product_category()) {
global $wp_query;
$curent_Cat_ID = $wp_query->get_queried_object()->term_id;
}
But it wont show anything on a product page.
Is there a way to get category id on a product page? What I was able to find wasn't working anymore.
Or somehow get an array like breadcrumbs with IDs?
Ok a good night sleep and eventually I found the answer. If someone will need it here it is:
if ( is_tax( 'product_cat' ) ) {
$current_cat = get_queried_object_id();
$cat_ancestors = get_ancestors( $current_cat, 'product_cat' );
} elseif ( is_singular( 'product' ) ) {
$terms = wc_get_product_terms(
get_queried_object_id(),
'product_cat',
apply_filters(
'woocommerce_product_categories_widget_product_terms_args',
array(
'orderby' => 'parent',
'order' => 'DESC',
)
)
);
if ( $terms ) {
$main_term = apply_filters( 'woocommerce_product_categories_widget_main_term', $terms[0], $terms );
$current_cat = $main_term->term_id;
$cat_ancestors = get_ancestors( $main_term->term_id, 'product_cat' );
}
}
Related
Good Day, I found this script from businessbloomer.com/woocommerce-exclude-category-from-products-shortcode/ how to use this script to exclude uncategorized from the front and admin panel
what I'm trying to do is if the product has 1 or more categories exclude uncategorized from the product
function bbloomer_exclude_cat_shortcodes($query_args){
$query_args['tax_query'] = array(array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array('uncategorized'), // Don't display products from this category
'operator' => 'NOT IN'
));
return $query_args;
}
AMMENDED
see an example what I'm looking for
The Client is very old school and he does not want to go to product and remove uncategorized then save and then go back to product and select the correct category
I'm sure this could be done via the Wordpress back-end options?
Visit WooCommerce > Products > Categories > Select Default Category you wish to use > Delete Uncategorized
This should remove the uncategorized without changing any code
This code snippet worked for me:
this code works for yitheme bulk product edit, it has been tested with the developers of the plugin.
Edited
To Explain wat the code snippet below does you will need to install yitheme bulk edit plugin https://yithemes.com/themes/plugins/yith-woocommerce-bulk-product-editing/
this plugin allows you to bulk edit products. I needed to remove a category from the category list if more than 1 category is available
the following line if ( $c->term_id != 1930 ) { you need to replace 1930 with the id of the category that you would like to remove from the list.
For example, if you have 3 categories for one product and category B, id is 1930 the that will e removed from the product.
,
but when a product only has category B, it will stay as a category
if( !function_exists('yith_wcbep_manage_custom_columns_disable_uncategorized_on_column_tab') ) {
function yith_wcbep_manage_custom_columns_disable_uncategorized_on_column_tab( $value, $column_name, $post ) {
if ( 'categories' == $column_name ) {
$cats = get_the_terms( $post->ID, 'product_cat' );
$cats = ! empty( $cats ) ? $cats : array();
$cats_count = count( $cats );
$cats_html = '';
$loop = 0;
$my_cats_id = array();
if ( $cats_count == 1 ) {
$cats_html .= $cats[0]->name;
} else {
foreach ( $cats as $c ) {
$loop ++;
if ( $c->term_id != 1930 ) {
$cats_html .= $c->name;
if ( $loop < $cats_count ) {
$cats_html .= ', ';
}
$my_cats_id[] = $c->term_id;
}
}
}
$value = '<div class="yith-wcbep-select-values">' . esc_html( $cats_html ) . '</div> <input class="yith-wcbep-select-selected" type="hidden" value="' . wp_json_encode( $my_cats_id ) . '">';
}
return $value;
}
add_filter( 'yith_wcbep_manage_custom_columns', 'yith_wcbep_manage_custom_columns_disable_uncategorized_on_column_tab', 10, 3 );
}
Correct me If I am wrong you want to remove categorized category from your product_category filter. Now you have n number of products which dont have any category?
Uncategory itself is category by, and no product is assigned by default to it. In Case If you want to hide it use filter use below code , checked and running
add_filter( 'get_terms', 'organicweb_exclude_category', 10, 3 );
function organicweb_exclude_category( $terms, $taxonomies, $args )
{
$new_terms = array();
if ( in_array( 'product_cat', $taxonomies ) && ! is_admin() && is_page() )
{
foreach ( $terms as $key => $term )
{
if ( ! in_array( $term->slug, array( 'uncategorised/*It can be any category name*/' ) ) )
{
$new_terms[] = $term;
}
}
$terms = $new_terms;
}
return $terms;
}
What I try to accomplish in WooCommerce:
I have many categories (e.g. shoes) with child categories (e.g. heels, mules, wedges). All standard shoes are only in the parent category and a few special shoes (like heels, mules and wedges) are only in child categories.
If a user opens the category "shoes", I want to display only the products in the current category (not these from the child categories).
What I've tried so far
I searches a lot and tried many different approaches, but no chance.
Approach #1: as seen here
function exclude_product_cat_children( $wp_query ) {
if ( isset( $wp_query->query_vars['product_cat'] ) && $wp_query->is_main_query() ) {
$wp_query->set(
'tax_query', array( array (
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $wp_query->query_vars['product_cat'],
'include_children' => false
) )
);
}
}
add_filter('pre_get_posts', 'exclude_product_cat_children', 99);
Approach #2: as seen here
add_filter( 'parse_tax_query', 'cyb_do_not_include_children_in_company_category_archive' );
function cyb_do_not_include_children_in_company_category_archive( $query ) {
if (
! is_admin()
&& $query->is_main_query()
&& $query->is_tax( 'shoes' )
) {
$query->tax_query->queries[0]['include_children'] = 0;
}
}
I really don't know how to fix this issue. It seems like this two approaches are working for all - just not for me. Any ideas?
Thank you!
I finally found the solution myself. Hopefully I can help someone with the code below.
What is the code for?
I hide all products in child categories in the current (parent) category.
function change_parent_category_query($query) {
if( ! is_admin() && $query->query_vars['post_type'] == 'product') {
global $wpdb;
$parent_id = get_queried_object()->term_id;
if( isset($parent_id) && is_numeric($parent_id) ){
$all_subcategory_ids = $wpdb->get_results( $wpdb->prepare( "SELECT term_taxonomy_id FROM {$wpdb->prefix}term_taxonomy WHERE taxonomy = 'product_cat' AND parent = %d", $parent_id ) );
$list_ids = array();
foreach( $all_subcategory_ids as $asi ){
$list_ids[] = esc_attr( $asi->term_taxonomy_id );
}
$tax_query = $query->get( 'tax_query' );
$tax_query[] = array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'parent' => 0,
'terms' => $list_ids,
'operator' => 'NOT IN'
);
$query->set( 'tax_query', $tax_query );
}
}
}
add_action( 'pre_get_posts', 'change_parent_category_query' );
I have the following block of code that allows for any empty category or subcategory archive pages to become hidden from the navbar but it has two distinct issues that I need help fixing.
The code hides the empty archive pages at both front and back ends which makes editing menus at the back end difficult as the code needs to be manually removed and then re-added after menu alterations have been made.
Categories and subcategories are not automatically added to the menu sections of the website. I cannot activate the section 'Automatically add new top-level pages to this menu' as this is global and doesn't apply only to product categories/subcategories.
The code I am currently using is as follows:
/* HIDE EMPTY CATEGORIES AND SUBCATEGORIES FROM NAVBAR - TO CORRECTLY EDIT THE MENU AT THE BACK-END, MAKE SURE YOU REMOVE THIS CODE */
function hide_empty_navbar_items ( $items, $menu, $args ) {
global $wpdb;
$empty = $wpdb->get_col( "SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE count = 0" );
foreach ( $items as $key => $item ) {
if ( ( 'taxonomy' == $item->type ) && ( in_array( $item->object_id, $empty ) ) ) {
unset( $items[$key] );
}
}
return $items;
}
add_filter( 'wp_get_nav_menu_items', 'hide_empty_navbar_items', 10, 3 );
I managed to find the following code which allows you to hide the empty category and subcategory levels from the navbar at the front end of the site whilst also allowing for anyone logged in as an Admin to still see the complete menu structure at the back end.
This code essentially fixes the issue with the code left in the initial question and offers a much more practical solution.
add_filter( 'wp_get_nav_menu_items', 'nav_remove_empty_category_menu_item',10, 3 );
function nav_remove_empty_category_menu_item ( $items, $menu, $args ) {
if ( ! is_admin() ) {
global $wpdb;
$nopost = $wpdb->get_col( "SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE count = 0" );
foreach ( $items as $key => $item ) {
if ( ( 'taxonomy' == $item->type ) && ( in_array( $item->object_id, $nopost ) ) ) {
unset( $items[$key] );
}
}
}
return $items;
}
I made this, to take care of item stock too. It wont show the menu if the category only contains out of stock items:
/**
Hide empty categories from menu
**/
if(!is_admin()) {
add_filter( 'wp_get_nav_menu_items', 'nav_remove_empty_category_menu_item', 10, 3 );
}
function nav_remove_empty_category_menu_item ( $items, $menu, $args ) {
global $wpdb;
$nopost = $wpdb->get_col( "SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE count = 0" );
foreach ( $items as $key => $item ) {
if ( ( 'taxonomy' == $item->type ) ) {
$object = get_term($item->object_id, $item->object);
$args = array(
'posts_per_page' => -1,
'product_cat' => $object->slug,
'post_type' => 'product',
'orderby' => 'title',
'meta_query' => array(
array(
'key' => '_stock_status',
'value' => 'instock'
)
)
);
$the_query = new WP_Query( $args );
if($the_query->post_count <= 0){
unset( $items[$key] );
}
}
}
return $items;
}
I have been trying to hide all products from a specific category (from shop page and single page) using this StackOverFlow answer code and following instructions on this other forum thread
On "Exclude specific product categories on Woocommerce single product pages" answer code I have defined one of my product categories as follow (here the term Id 43):
$category_ids = array( 43 );
I just need that all products of this category (ID 43) to be added to the cart and buy.
One of the products of the category ID 43 "Plan": https://mamasmateas.atac.cl/product/plan-personalizado-sin-seguimiento/
The other code I have tested is:
add_filter( 'get_terms', 'ts_get_subcategory_terms', 10, 3 );
function ts_get_subcategory_terms( $terms, $taxonomies, $args ) {
$new_terms = array();
// if it is 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( 'plan' ) ) ) { //pass the slug name here
$new_terms[] = $term;
}
}
$terms = $new_terms;
}
return $terms;
}
Any help would be much appreciated.
add_action( 'woocommerce_shop_loop', 'woocommerce_shop_loop' );
function woocommerce_shop_loop() {
global $product;
$category_ids = array( 20 );
var_dump(has_term( $category_ids, 'product_cat', $product->get_id());
if ( has_term( $category_ids, 'product_cat', $product->get_id() ) ) {
unset($GLOBALS['product']);
}
}
I am trying to create a template for sub-category where I can display products under sub-category and in parent category page want to display only related sub-categories of the parent category. Can anyone suggest me with the example of code? how to start this.
Try the following:
if ( is_product_category() ) {
$terms = get_terms( array('taxonomy' => 'product_cat', 'parent' => get_queried_object_id() ) );
foreach ( $terms as $term ){
$term_link = get_term_link( $term, $taxonomy );
echo '<a class="ccats" href="'.$term_link.'"><span class="label">'.$term->name.'</span></a>';
}
}