This question already has answers here:
Adding a custom text next to a specific product attribute label in WooCommerce
(2 answers)
Closed 10 months ago.
We are building a wine-shop and have a few typical attributes like alcohol, sugar, acid that have values. These attributes are measured in units - e.g. alcohol in vol.%, sugar in g/litre, etc.
The "additional information" tab shows the attribute names and values but just the values without the unit right after.
Consequently we want to add a suffix for each attribute via a snippet/hook in functions.php and have tried with below code:
add_filter( 'woocommerce_attribute_label', 'custom_attribute_label', 10, 3 );
function custom_attribute_label( $label, $name, $product ) {
$taxonomy = 'pa_'.$name;
if( $taxonomy == 'alk' )
$label .= '<span class="custom-label"> vol.%</span>';
return $label;
}
but this does not generate any output on frontend.
Any ideas and/or feedback to solve/tweak this are appreciated!
The condition should be if ( $taxonomy === 'pa_alk' )
I modified the code, now it's working:
add_filter( 'woocommerce_attribute_label', 'custom_attribute_label', 10, 3);
function custom_attribute_label( $label, $taxonomy, $product ) {
if( $taxonomy == 'pa_alk' )
$label .= '<span class="custom-label"> vol.%</span>';
return $label;
}
Related
i want see attributes in the back end on the all products page.
and can it shows the quanity vs in stock out of stock?
many plugins tried so far none suitable
I don't know about any plugin for these kind of functionality. But, I've created this functionality. Let me share the details with you.
Add following snippets of code to your active child-theme's functions.php file.
Below displayed snippets will add new columns to All Products page's Product Table. i.e. Stock Quantity and Color. Here Color is my product's attribute.
add_filter( 'manage_edit-product_columns', 'admin_products_column', 9999 );
function admin_products_column( $columns ){
$columns['stock_quantity'] = 'Stock Quantity'; // Stock
$columns['color'] = 'Color'; // Attribute
return $columns;
}
Now we need to bring the data in these columns, So for the Stock Quantity use below mentioned code snippets.
add_action( 'manage_product_posts_custom_column', 'admin_products_stock_column_content', 10, 2 );
function admin_products_stock_column_content( $column, $product_id ){
if ( $column == 'stock_quantity' ) { // condition to check stock qty. column.
$product = wc_get_product( $product_id );
echo $product->get_stock_quantity();
}
}
To get data in color attribute column use below mentioned code snippets.
add_action( 'manage_product_posts_custom_column', 'admin_products_attribute_color_column_content', 10, 2 );
function admin_products_attribute_color_column_content( $column, $product_id ){
if ( $column == 'color' ) { // condition to check color attribute column
$product = wc_get_product( $product_id );
echo $product->get_attribute('pa_color'); // 'pa_color' is Slug of Color Attribute.
}
}
Final result will look like this image.
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.
This question already has an answer here:
Adding custom attribute to WooCommerce shop loop product title
(1 answer)
Closed 4 years ago.
I have found some code here on the site, to show a product attribute on the category pages. This works fine, it shows the attribute I want perfectly, but it would be really perfect if I could get this just below th product title, and not below the button, as where it is now. Can someone help me how I can do this?
this is how it looks now
/**
* PPM
*/
add_action( 'woocommerce_after_shop_loop_item', 'acf_template_loop_product_meta', 20 );
function acf_template_loop_product_meta() {
global $product;
// Check that we got the instance of the WC_Product object, to be sure (can be removed)
if( ! is_object( $product ) ) {
$product = wc_get_product( get_the_id() );
}
echo '<h4>Afdruksnelheid: ' . $product->get_attribute('pa_afdruksnelheid') .' PPM</h4>';
}
add_action( 'woocommerce_before_shop_loop_item_title', 'custom_before_title' );
function custom_before_title() {
global $product;
// Check that we got the instance of the WC_Product object, to be sure (can be removed)
if( ! is_object( $product ) ) {
$product = wc_get_product( get_the_id() );
}
echo '<h4>Afdruksnelheid: ' . $product->get_attribute('pa_afdruksnelheid') .' PPM</h4>';
}
There is no hook exactly in the place you mentioned. Check this hook guide for more info
This question already has answers here:
How to add variation stock status to Woocommerce product variation dropdown
(4 answers)
Closed 4 years ago.
I Would like next to variation to show "Out of Stock" when product variation is out of stock. Below, I am using the code from this answer:
add_filter( 'woocommerce_variation_option_name',
'customizing_variations_terms_name', 10, 1 );
function customizing_variations_terms_name( $term_name ){
if(is_admin())
return $term_name;
global $product;
$second_loop_stoped = false;
// Get available product variations
$product_variations = $product->get_available_variations();
// Iterating through each available product variation
foreach($product_variations as $variation){
$variation_id = $variation['variation_id'];
$variation_obj = new WC_Product_Variation( $variation_id );
## WOOCOMMERCE RETRO COMPATIBILITY ##
if ( version_compare( WC_VERSION, '3.0', '<' ) ) # BEFORE Version 3 (older)
{
$stock_status = $variation_obj->stock_status;
$stock_qty = intval($variation_obj->stock);
// The attributes WC slug key and slug value for this variation
$attributes_arr = $variation_obj->get_variation_attributes();
}
else # For newest verions: 3.0+ (and Up)
{
$stock_status = $variation_obj->get_stock_status();
$stock_qty = $variation_obj->get_stock_quantity();
// The attributes taxonomy key and slug value for this variation
$attributes_arr = $variation_obj->get_attributes();
}
if(count($attributes_arr) != 1) // Works only for 1 attribute set in the product
return $term_name;
// Get the terms for this attribute
foreach( $attributes_arr as $attr_key => $term_slug){
// Get the attribute taxonomy
$term_key = str_replace('attribute_', '', $attr_key );
// get the corresponding term object
$term_obj = get_term_by( 'slug', $term_slug, $term_key );
if( $term_obj->name == $term_name ){ // If the term name matches we stop the loops
$second_loop_stoped = true;
break;
}
}
if($second_loop_stoped)
break;
}
if( $stock_qty>0 )
return $term_name .= ' - ' . $stock_status . ' ('.$stock_qty.')';
else
return $term_name .= ' - ' . $stock_status;
}
but when test on my site, it show "Out of Stock" for all variations i have on selected product. For example on this product it show "Out of Stock" for all variations i have, but in fact, only variation "50 ליטר" is in real "Out Of Stock". other variations are In Stock ! I using Woocommerce 3.3.5 version. Can someone to tell me what i need to do to show out of stock next to variations if product is out of stock for real, because i m using radio buttons as replacement for standard dropdown button from Woocommerce.
Seems over complicated, I managed to do it this way. Seems to work, displays out of stock for the correct variations when I tested it.
add_filter( 'woocommerce_variation_option_name', 'customizing_variations_terms_name', 10, 1 );
function customizing_variations_terms_name( $term_name ) {
global $product;
// Get available product variations
$product_variations = $product->get_available_variations();
// product_variation terms are normalized to lowercase with
// spaces replaced by dashes.
// if your term name contains capital letters or spaces i.e. 'SIZE 6'
// the product variation will be lowercase with dashes, i.e. 'size-6'
/*
$term_name = str_replace(' ', '-', strtolower($term_name));
*/
foreach ( $product_variations as $product_variation ) {
if( isset( $product_variation['attributes'] ) ) {
$key = array_search($term_name, $product_variation['attributes']);
if( $key !== false && ! $product_variation['is_in_stock'] ) {
return $term_name . ' - Out of Stock';
}
}
}
return $term_name;
}
In addition to this you can grey out the product so they can't select it if that's something that are after.
add_filter( 'woocommerce_variation_is_active', 'grey_out_variations_when_out_of_stock', 10, 2 );
function grey_out_variations_when_out_of_stock( $grey_out, $variation ) {
if ( ! $variation->is_in_stock() )
return false;
return true;
}
i've read many Q/A's here during the last few days, but unfortunately none of them solved my issue.
I'm trying to fetch product attributes and display them on the frontend with a shortcode. I have managed to display ALL available attributes and display them in a list, but i need to select only one or two of them in different locations (thats why using shortcodes). For example like [shortcode_attribute name="brand"].
Any help is highly appreciated!
my code so far:
function tutsplus_list_attributes( $product ) {
global $product;
global $post;
$attributes = $product->get_attributes();
if ( ! $attributes ) {
return;
}
foreach ( $attributes as $attribute ) {
// Get the taxonomy.
$terms = wp_get_post_terms( $product->id, $attribute[ 'name' ], 'all' );
$taxonomy = $terms[ 0 ]->taxonomy;
// Get the taxonomy object.
$taxonomy_object = get_taxonomy( $taxonomy );
// Get the attribute label.
$attribute_label = $taxonomy_object->labels->name;
// Display the label followed by a clickable list of terms.
echo get_the_term_list( $post->ID, $attribute[ 'name' ] , '<div><li class="bullet-arrow">' . $attribute_label . ': ' , ', ', '</li></div>' );
}
}
add_action( 'woocommerce_product_meta_end', 'tutsplus_list_attributes' );
add_shortcode('display_attributes', 'tutsplus_list_attributes');
While I am still not 100% clear what you're after, what I'm going to create is a shortcode that creates a list of all terms in all attributes. To make it more flexible I'll add support for a shortcode parameter so you can create a list of specific attribute terms.
One major thing you need to alter from your code, is that shortcodes need to RETURN a string and not ECHO out html. Echoing out shortcodes can result in unexpected weirdness.
/**
* Attributes shortcode callback.
*/
function so_39394127_attributes_shortcode( $atts ) {
global $product;
if( ! is_object( $product ) || ! $product->has_attributes() ){
return;
}
// parse the shortcode attributes
$args = shortcode_atts( array(
'attributes' => array_keys( $product->get_attributes() ), // by default show all attributes
), $atts );
// is pass an attributes param, turn into array
if( is_string( $args['attributes'] ) ){
$args['attributes'] = array_map( 'trim', explode( '|' , $args['attributes'] ) );
}
// start with a null string because shortcodes need to return not echo a value
$html = '';
if( ! empty( $args['attributes'] ) ){
foreach ( $args['attributes'] as $attribute ) {
// get the WC-standard attribute taxonomy name
$taxonomy = strpos( $attribute, 'pa_' ) === false ? wc_attribute_taxonomy_name( $attribute ) : $attribute;
if( taxonomy_is_product_attribute( $taxonomy ) ){
// Get the attribute label.
$attribute_label = wc_attribute_label( $taxonomy );
// Build the html string with the label followed by a clickable list of terms.
// Updated for WC3.0 to use getters instead of directly accessing property.
$html .= get_the_term_list( $product->get_id(), $taxonomy, '<li class="bullet-arrow">' . $attribute_label . ': ' , ', ', '</li>' );
}
}
// if we have anything to display, wrap it in a <ul> for proper markup
// OR: delete these lines if you only wish to return the <li> elements
if( $html ){
$html = '<ul class="product-attributes">' . $html . '</ul>';
}
}
return $html;
}
add_shortcode( 'display_attributes', 'so_39394127_attributes_shortcode' );
Usage: This would be used in 1 of 2 ways.
First, to display specific attributes use:
[display_attributes attributes="color|material"]
Second, to display all attributes use:
[display_attributes]
Edit
Here's an always single display edition:
/**
* Attribute shortcode callback.
*/
function so_39394127_singular_attribute_shortcode( $atts ) {
global $product;
if( ! is_object( $product ) || ! $product->has_attributes() ){
return;
}
// parse the shortcode attributes
$args = shortcode_atts( array(
'attribute' => ''
), $atts );
// start with a null string because shortcodes need to return not echo a value
$html = '';
if( $args['attribute'] ){
// get the WC-standard attribute taxonomy name
$taxonomy = strpos( $args['attribute'], 'pa_' ) === false ? wc_attribute_taxonomy_name( $args['attribute'] ) : $args['attribute'];
if( taxonomy_is_product_attribute( $taxonomy ) ){
// Get the attribute label.
$attribute_label = wc_attribute_label( $taxonomy );
// Build the html string with the label followed by a clickable list of terms.
// Updated for WC3.0 to use getters instead of directly accessing property.
$html .= get_the_term_list( $product->get_id(), $taxonomy, $attribute_label . ': ' , ', ', '' );
}
}
return $html;
}
add_shortcode( 'display_attribute', 'so_39394127_singular_attribute_shortcode' );
This removes all HTML markup, and so you'd need to provide your own... which would happen if you are making a custom list.
<ul>
<li class="arrow">Static List Item</li>
<li class="arrow">[display_attribute attribute="color"]</li>
<ul>
EDIT: This code can be added to your theme's functions.php, but preferably either in a site-specific plugin or via the Code Snippets plugin.
If anyone else just wants to simply output the attribute value as text, replace the $html .= line with this:
$html .= strip_tags(get_the_term_list($product->get_id(), $taxonomy));
#helgatheviking There must be a more elegant way than this! :)
Needed this recently - found https://wordpress.org/plugins/wcpas-product-attributes-shortcode/ does the trick.
With this plugin you can set an "attribute" parameter to match one of the product attributes you have setup.
For example if you have a brand attribute you can use:
[wcpas_product_attributes attribute="brand"]
This will output a <ul> list containing all brands.
There are also a number of parameters you can use alongside the attribute including:
orderby (order the list by an orderby value)
order (order asc, desc, rand, etc)
hide_empty (hide empty terms)
show_counts (show the total number of products in the brand)
archive_links (use an archive based URL instead of a filter based URL)
min_price (When using archive_links = 0 you can have a price filter based URL off a minimum price)
max_price (When using archive_links = 0 you can have a price filter based URL off a maximum price)