Add woocommerce product type to body class array - wordpress

I am trying to add Woocommerce product types to the Wordpress body tag class array thats called in header.php with
body_class();
I have the following function in functions.php but it is not adding the class. If I remove the conditional and just have
$classes[] = 'simple-product';
Then the class is added. I assume this is to do with an issue getting global values. I am calling in $woocommerce, $post and $product globals as I am not sure which I actually need.
//Add Woocommerce body classes
add_filter('body_class','ttm_woocommerce_body_classes');
function ttm_woocommerce_body_classes($classes){
global $woocommerce, $post, $product;
if ( $product->product_type == 'simple' ) $classes[] = 'simple-product';
return $classes;
}
Thanks

Have you tried var_dump($product) to see what (if anything) exists in that object?
According to the codex, you might have to populate it yourself using $post->ID, like so:
//Add Woocommerce body classes
add_filter('body_class','ttm_woocommerce_body_classes');
function ttm_woocommerce_body_classes($classes){
global $post;
$product = get_product( $post->ID );
if ( $product->product_type == 'simple' ) $classes[] = 'simple-product';
return $classes;
}

In woocommerce page add product_type name in your website body tag. First you need to get this page is a product page.
Using with get_product() you got your page is working with woocommerce functionality.
This is a code to add all product_type name added in body tag.
Add this code into your activate theme folder : functions.php
add_filter('body_class','obw_woocommerce_body_classes');
function obw_woocommerce_body_classes( $classes ) {
global $woocommerce, $post, $product;
$product = get_product( $post->ID );
$product_type = $product->product_type;
if ( $product->product_type == 'external' ) $classes[] = 'external-product';
if ( $product->product_type == 'grouped' ) $classes[] = 'grouped-product';
if ( $product->product_type == 'simple' ) $classes[] = 'simple-product';
if ( $product->product_type == 'variable' ) $classes[] = 'variable-product';
return $classes;
}

Related

Add suffix text to specific product category in Woocommerce [duplicate]

I need to add 'per metre' to the price on most of my online catalogue, I tried the code on this thread in my finctions.php but I cannot get it to omit/include particular categories- it seems to be all or nothing. What am I doing wrong?
I have edited the code as such:
/*add 'per metre' after selected items*/
add_filter( 'woocommerce_get_price_html', 'conditional_price_suffix', 20, 2 );
function conditional_price_suffix( $price, $product ) {
// HERE define your product categories (can be IDs, slugs or names)
$product_categories = array('fabric','haberdashery', 'lining',);
if( ! has_term( $product_categories, 'fasteners', 'patches', 'remnnants', $product->get_id() ) )
$price .= ' ' . __('per metre');
return $price;
}
I want 'fabrics', 'haberdashery', 'lining' to show per metre, and 'fasteners', 'patches', 'remnants' to NOT show the suffix.
I have tried variations of the code -my exclusions in the top bit and the inclusions in the second part, and with/without the "( ! has term" section, but whichever I do takes all the suffix messages away, or applies to all categories.
It would be amazing if I could get this to work as have previously been using a very bloated plug-in. I'm only basically capable in this stuff so please feel free to talk me through it as if I am an idiot.
There is a little mistake in your code in the has_term() function.
To handle parent product categories, we will use a custom conditional function instead of has_tem().
I have also added some code to handle the product variation selected price of variable products, So try this instead:
// Custom conditional function that handle parent product categories too
function has_product_categories( $categories, $product_id = 0 ) {
$parent_term_ids = $categories_ids = array(); // Initializing
$taxonomy = 'product_cat';
$product_id = $product_id == 0 ? get_the_id() : $product_id;
if( is_string( $categories ) ) {
$categories = (array) $categories; // Convert string to array
}
// Convert categories term names and slugs to categories term ids
foreach ( $categories as $category ){
$result = (array) term_exists( $category, $taxonomy );
if ( ! empty( $result ) ) {
$categories_ids[] = reset($result);
}
}
// Loop through the current product category terms to get only parent main category term
foreach( get_the_terms( $product_id, $taxonomy ) as $term ){
if( $term->parent > 0 ){
$parent_term_ids[] = $term->parent; // Set the parent product category
$parent_term_ids[] = $term->term_id; // (and the child)
} else {
$parent_term_ids[] = $term->term_id; // It is the Main category term and we set it.
}
}
return array_intersect( $categories_ids, array_unique($parent_term_ids) ) ? true : false;
}
add_filter( 'woocommerce_get_price_html', 'conditional_price_suffix', 10, 2 );
function conditional_price_suffix( $price, $product ) {
// Handling product variations
$product_id = $product->is_type('variation') ? $product->get_parent_id() : $product->get_id();
// HERE define your product categories (can be IDs, slugs or names)
$product_categories = array('fabric','haberdashery', 'lining');
if( has_product_categories( $product_categories, $product_id ) )
$price .= ' ' . __('per metre');
return $price;
}
Code goes in function.php file of your active child theme (or active theme). tested and works.

Add extra class with product category IDs on WooCommerce archives pages

I want to add a custom class to the categories on the product archive page so that I can add custom styles to the categories tags.
Example:
Product X in Category 1 --> Category Tag in Yellow
Product Y in Category 2 --> Category Tag in Red
I'm using this php snippet, but this is for single product pages and is applied to the <body> element. How can I change it to work for shop archive pages as well?
add_filter( 'body_class','my_body_classes2' );
function my_body_classes2( $classes ) {
if ( is_product() ) {
global $post;
$terms = get_the_terms( $post->ID, 'product_cat' );
foreach ($terms as $term) {
$product_cat_id = $term->term_id;
$classes[] = 'product-in-cat-' . $product_cat_id;
}
}
return $classes;
}
You can use the newer woocommerce_post_class filter hook
So you get:
/**
* WooCommerce Post Class filter.
*
* #since 3.6.2
* #param array $classes Array of CSS classes.
* #param WC_Product $product Product object.
*/
function filter_woocommerce_post_class( $classes, $product ) {
// Returns true when viewing a product category archive.
// Returns true when on the product archive page (shop).
if ( is_product_category() || is_shop() ) {
// Set taxonmy
$taxonomy = 'product_cat';
// Get the terms
$terms = get_the_terms( $product->get_id(), $taxonomy );
// Error or empty
if ( is_wp_error( $terms ) || empty( $terms ) ) {
return $classes;
}
// Loop trough
foreach ( $terms as $index => $term ) {
// Product term Id
$term_id = $term->term_id;
// Add new class
$classes[] = 'product-in-cat-' . $term_id;
}
}
return $classes;
}
add_filter( 'woocommerce_post_class', 'filter_woocommerce_post_class', 10, 2 );
Note: the if condition can be extended/constrained with other conditional tags
Example:
is_product() - Returns true on a single product page. Wrapper for is_singular.
etc..
To NOT apply this, use ! in the if condition:
// NOT
if ( ! is_product_category() )..

External product feature image to external link in new tab -wordpress woocommerce

I have a woocommerce store.
Its an affiliate store.
I want that when clicked on the featured image on the shop page it goes to an external website
I have added below code to my function.php its working fine just need to know what code and where is to be added to open it in a new tab
**<?php // Do not include this if already open!
/**
* Code goes in theme functions.php.
*/
add_action( 'template_redirect', 'redirect_external_products' );
function redirect_external_products() {
global $post;
if ( is_singular( 'product' ) && ! empty( $post ) && ( $product = wc_get_product( $post ) ) && $product->is_type( 'external' ) ) {
wp_redirect( $product->get_product_url() );
exit;
}
}**
There is no way to redirect in a new tab, I will suggest adding "target='_blank'" to the tag where you display the featured image with probably the same condition as in the function above. The hacky way maybe
add_action( 'template_redirect', 'redirect_external_products' );
function redirect_external_products() {
global $post;
if ( is_singular( 'product' ) && ! empty( $post ) && ( $product = wc_get_product( $post ) ) && $product->is_type( 'external' ) ) {
echo "<script> window.open(" . $product->get_product_url() . ", '_blank') </script>";
}
}
But I strongly suggest you not to go this way!!

How to conditionally use a shortcode on WooCommerce single product pages

How is it possible to hide a shortcode conditionally on WooCommerce single product pages if stock is empty?
For example if a product is out of stock:
The shortcode [scale-prices] should disappear
(A green traffic light picture changes to a yellow traffic light picture)
Your question is quite broad. But you could add a CSS body class to the product page if a product (or a variation) is out of stock. You can then use that to manipulate your page for instance via CSS or JavaScript.
The following code snippet will add out-of-stock as a body class for a simple out of stock product, and a {variation-id}-out-of-stock body class for each variation that is out of stock:
add_filter( 'body_class', 'add_class_if_product_is_out_of_stock', 10, 1 );
function add_class_if_product_is_out_of_stock( $classes ) {
if ( is_product() ) {
global $post;
if ( $product = wc_get_product( $post->ID ) ) {
if ( $product->is_type( 'variable' ) ) {
$children = $product->get_children();
foreach ( $children as $child_id ) {
if ( $product = wc_get_product( $child_id ) ) {
if ( $product->is_in_stock() == false ) {
$classes[] = sprintf( '%s-out-of-stock', $child_id );
}
}
}
} elseif ( $product->is_in_stock() == false ) {
$classes[] = 'out-of-stock';
}
}
}
return $classes;
}
This snippet should be added to the functions.php of your child theme or via a plugin like Code Snippets.
You can use any of these single product page hooks and add a condition of your need.
https://www.businessbloomer.com/woocommerce-visual-hook-guide-single-product-page/
Like you can use woocommerce_before_single_product and check for product availablity and based on that result you can use add_shortcode, remove_shortcode. Also you can add script using wp_footer script if required.
You can share further details/scenario for exact solution.

Woocommerce product link url for simple products

Using the shortcode [add_to_cart_url sku="#"] will generate a link that will take the shopper to the single product page ONLY IF the product has variations.
What if I want a simple product (a product without variations) to link to its single product page instead of adding it to the cart?
IMO, this seems overlooked by the WooCommerce team.
All I want is a generated link to an item's single product page based on its SKU. Something as simple as implementing [product_url sku="#"] would be great.
Otherwise, searching Google has revealed no success.
Is this what you want ?
Below code is for the shortcode of Product URL only and you can use it with like :
[product_url sku="SKUofProduct"] or with ID [product_url id="productID"]
add_shortcode( 'product_url', 'rohils_product_url_function' );
function rohils_product_url_function($atts){
global $wpdb;
if ( empty( $atts ) ) {
return '';
}
if ( isset( $atts['id'] ) ) {
$product_data = get_post( $atts['id'] );
} elseif ( isset( $atts['sku'] ) ) {
$product_id = wc_get_product_id_by_sku( $atts['sku'] );
$product_data = get_post( $product_id );
} else {
return '';
}
if ( 'product' !== $product_data->post_type ) {
return '';
}
$_product = wc_get_product( $product_data );
return esc_url( get_post_permalink($_product->id) );
}

Resources