I am trying to customize the variations dropdown on the product page using the answers here:
Add the variation price to variable product dropdown item names in Woocommerce
function wiz_rebuild_variation_dropdown( $html, $args ) {
// Only if there is a unique variation attribute (one dropdown)
if( sizeof($args['product']->get_variation_attributes()) == 1 ) :
$options = $args['options'];
$product = $args['product'];
$attribute = $args['attribute'];
$show_option_none = $args['show_option_none'] ? true : false;
$show_option_none_text = $args['show_option_none'] ? $args['show_option_none'] : __( 'Choose an option', 'woocommerce' );
if ( empty( $options ) && ! empty( $product ) && ! empty( $attribute ) ) {
$attributes = $product->get_variation_attributes();
$options = $attributes[ $attribute ];
}
// Build the Select container
$html = '<select id="something">';
$html .= '<option value="something">' . esc_html( $show_option_none_text ) . '</option>';
if ( ! empty( $options ) ) {
foreach ( $options as $option ) {
// print_r($option);
$html .= '<option value="'. esc_html( $option ) . '">something</option>';
}
}
// Close the Select container
$html .= '</select>';
endif; // More than one attributes (multiple pulldowns) - code not executed
return $html;
}
add_filter( 'woocommerce_dropdown_variation_attribute_options_html', 'wiz_rebuild_variation_dropdown', 10, 2);
Somehow the dropdown will not show more than one tag. I have checked the array and there are 4 results (print_r in the foreach). If I comment out the 'Choose an option' option, the first result in the foreach will show, but not the other three. Is something going wrong with appending the $html variable?
I'm getting dizzy from trying :-/
Can anyone see what I am doing wrong here?
Cheers,
Mark
btw, this is my first ever post to this awesome platform that saved my life so many times before.
Thanks to all for the great help through the years!
So I found out what the problem was. Looks like this pulldown will not function without the correct name attribute in the SELECT tag.
by catching that like in the original example (see URL):
$name = $args['name'] ? $args['name'] : 'attribute_' . sanitize_title( $attribute );
and adding it to the SELECT:
name="' . esc_attr( $name ) . '"
the script adds the required class names to the option tags automatically and image/price changes function as well.
Thanks for the tips, guys! Pff.. one step made today :))
Related
i would like to use a shortcode to display product attributes which i defined in the WP Backend. But in a table Form. I managed to use this Code: Woocommerce - Display single product attribute(s) with shortcodes in Frontend
to display the correct attribute labels and values, but i cant manage to show them in a table like this:
https://ibb.co/r6xSFpj
My Code so far:
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 .= wp_get_object_terms( $product->get_id(), $taxonomy, '<li>' . $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' );
I have a WordPress website with WooCommerce installed. There are some global attributes with a product's specification. I want to callback them as text in long description using shortcode.
Here's what I am able to get at . Yet it shows only a label for only one attribute, and I want to include multiple attributes with their attribute labels.
/**
* Attribute shortcode callback.
*/
function testfunction( $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.
// heads up that in WC2.7 $product->id needs to be $product->get_id()
//echo strip_tags( get_the_term_list( $product->id, $taxonomy, $attribute_label . ' ' , ', ', '' ));
if ($attribute = Test){
echo $product->get_attribute('Test');
}
elseif ($attribute = Test1){
return $product->get_attribute('Test1');
}
}
}
return $html;
}
add_shortcode( 'display_attribute', 'testfunction' );
Reference 1: Woocommerce - Display single product attribute(s) with shortcodes in Frontend
[Reference 1] that I mentioned above allows me to fetch multiple attributes with multiple attribute labels as I want, but with this the only issue is that it also includes the attribute name which I can't have.
In short, I'd like to fetch 'multiple attribute labels' but without including the attribute itself within the callback text. Any clue ?
Thanks Kathy #helgatheviking for giving a real quick solution. Here's what I was looking for: Hope it helps other community members looking for something similar.
/**
* 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 ) ){
// Build the html string with the label followed by a clickable list of terms.
//$html .= get_the_term_list( $product->get_id(), $taxonomy, '<li class="bullet-arrow">': ' , ', ', '</li>' );
$html .= get_the_term_list( $product->get_id(), $taxonomy, '', ', ', '' );
}
}
// 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 = '' . $html . '';
}
}
return $html;
}
add_shortcode( 'display_attributes', 'so_39394127_attributes_shortcode' );
On woocommerce on my variable products each variation has specific price.
How can I display the variation price and stock status in the attribute dropdown options?
Note: This only works when there is ONLY ONE dropdown select field (so one attribute for the variations set in the variable product). With multiple attributes (so multiple dropdown select fields) it displays something that can be wrong depending on the variations stock status attributes terms combination.
The following code will display the variation price and stock status in a unique dropdown variation attribute options:
// Utility function to get the price or the stock status of a variation from it's attribute value
function get_variation_price_stock_string( $product, $name, $term_slug ){
foreach ( $product->get_available_variations() as $variation ){
if($variation['attributes'][$name] == $term_slug ){
$stock_status = $variation['is_in_stock'] == 1 ? __('In stock') : __('Out of stock');
return ' (' . strip_tags( $variation['price_html'] ) . ') ' . $stock_status;
}
}
}
// Add the price and stock status to the dropdown options items.
add_filter( 'woocommerce_dropdown_variation_attribute_options_html', 'show_stock_status_in_dropdown', 10, 2);
function show_stock_status_in_dropdown( $html, $args ) {
// Only if there is a unique variation attribute (one dropdown)
if( sizeof($args['product']->get_variation_attributes()) == 1 ) :
$options = $args['options'];
$product = $args['product'];
$attribute = $args['attribute'];
$name = $args['name'] ? $args['name'] : 'attribute_' . sanitize_title( $attribute );
$id = $args['id'] ? $args['id'] : sanitize_title( $attribute );
$class = $args['class'];
$show_option_none = $args['show_option_none'] ? true : false;
$show_option_none_text = $args['show_option_none'] ? $args['show_option_none'] : __( 'Choose an option', 'woocommerce' );
if ( empty( $options ) && ! empty( $product ) && ! empty( $attribute ) ) {
$attributes = $product->get_variation_attributes();
$options = $attributes[ $attribute ];
}
$html = '<select id="' . esc_attr( $id ) . '" class="' . esc_attr( $class ) . '" name="' . esc_attr( $name ) . '" data-attribute_name="attribute_' . esc_attr( sanitize_title( $attribute ) ) . '" data-show_option_none="' . ( $show_option_none ? 'yes' : 'no' ) . '">';
$html .= '<option value="">' . esc_html( $show_option_none_text ) . '</option>';
if ( ! empty( $options ) ) {
if ( $product && taxonomy_exists( $attribute ) ) {
$terms = wc_get_product_terms( $product->get_id(), $attribute, array( 'fields' => 'all' ) );
foreach ( $terms as $term ) {
if ( in_array( $term->slug, $options ) ) {
// Get the price and stock status
$price_stock_html = get_variation_price_stock_string( $product, $name, $term->slug );
// Insert the price and stock status
$html .= '<option value="' . esc_attr( $term->slug ) . '" ' . selected( sanitize_title( $args['selected'] ), $term->slug, false ) . '>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $term->name ) . $price_stock_html ) . '</option>';
}
}
} else {
foreach ( $options as $option ) {
$selected = sanitize_title( $args['selected'] ) === $args['selected'] ? selected( $args['selected'], sanitize_title( $option ), false ) : selected( $args['selected'], $option, false );
// Get the price and stock status
$price_stock_html = get_variation_price_stock_string( $product, $name, $term->slug );
// Insert the price and stock status
$html .= '<option value="' . esc_attr( $option ) . '" ' . $selected . '>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $option ) . $price_stock_html ) . '</option>';
}
}
}
$html .= '</select>';
endif;
return $html;
}
Code goes in function.php file of your active child theme (or active theme). tested and works.
Based on:
Add the variation price to variable product dropdown item names in Woocommerce
How to add variation stock status to Woocommerce product variation dropdown
enter image description hereprice and stock status in dropdown
1: https://i.strong textstack.imgur.com/yvBUH.jpg
Thank you very much for this (very fast) reply. I use Flatsome theme and it works great.
As a additional question:
Is there a chance to convert "In Stock" into "Verfügbar / in Stock" and
Out of Stock into "Ausverkauft / Out of Stock"?
We have customers from Germany and other EU-countries; most of them will understand. But my older customer from Germany will face problems if I am not able to provide some short words in german.
Once again; thank you for your work.
ct
I create a sample 'woocommerce' product list, then the single product page has didn't get the attribute label of the product. below show the code
<?php if ( !$product->variations ) {return;}$field_name = isset($field_name) ? $field_name :'';$calendar_id = isset($calendar_id) ? $calendar_id : 0; <?php if ( $field_name ):?><?php foreach($product->variations as $variation_id => $variation_data):?><?php echo $variation_data['variation_title'];?><?php endforeach ?>
The variables $field_name and $calendar_id are not defined in your code, so I don't use them.
Your code seems to be outdated since Woocommerce 3. From a variable product object, to get the variation attributes label names / term names pairs, use the following:
<?php
if ( $product->is_type('variable') && $variations = $product->get_available_variations() ) {
$field_name = isset($field_name) ? $field_name : '';
$calendar_id = isset($calendar_id) ? $calendar_id : 0;
if ( sizeof( $variations ) > 0 ) {
// Loop through available product variations
foreach( $variations as $variation ) {
// Get variation title
$variation_title = get_the_title( $variation['variation_id'] );
// Display variation title
echo '<p><strong>Title:</strong> ' . $variation_title . '</p>';
// Loop through variation attributtes
foreach( $variation['attributes'] as $variation_attribute => $term_slug ){
// Get attribute taxonomy name
$taxonomy = str_replace( 'attribute_', '', $variation_attribute );
// Get attribute label name
$label_name = wc_attribute_label($taxonomy);
// Get attribute term name value
$term_name = ( $term = get_term_by( 'slug', $term_slug, $taxonomy ) ) ? $term->name : $term_slug;
// Display attribute label / term name pairs
echo '<p><strong>' . $label_name . ':</strong> ' . $term_name . '</p>';
}
}
}
}
?>
Tested and works in Woocommerce 3+
I want to make some modification of my site, but for some reason, can get it. i tryed to use this function that found into this thread of Stack :
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 for some reason when insert into functions, show me "outofstock" next to every variation. I dont use standard Woocommerce dropdown variation style, and use WC Variations Radio Buttons to show radio buttons next to each variation, instead of dropdown. The problem is that i want to show only "Out Of Stock" , next to each variation. not "In Stock", so customer will know that wanted variation is not in stock before press Add to Cart button. SO seems that issue is this code:
if( $stock_qty>0 )
return $term_name .= ' - ' . $stock_status . ' ('.$stock_qty.')';
else
return $term_name .= ' - ' . $stock_status;
}
function looks like return
return $term_name .= ' - ' . $stock_status;
all the time. Any help ? Preview from my issue can be seen here. Thanks.
EDIT: This is the code from variable.php Radio Button Plugin where print variations as radio buttons:
<td class="value">
<?php
if ( ! empty( $options ) ) {
if ( taxonomy_exists( $name ) ) {
// Get terms if this is a taxonomy - ordered. We need the names too.
$terms = wc_get_product_terms( $product->get_id(), $name, array( 'fields' => 'all' ) );
foreach ( $terms as $term ) {
if ( ! in_array( $term->slug, $options ) ) {
continue;
}
print_attribute_radio( $checked_value, $term->slug, $term->name, $sanitized_name );
}
} else {
foreach ( $options as $option ) {
print_attribute_radio( $checked_value, $option, $option, $sanitized_name );
}
}
}
echo end( $attribute_keys ) === $name ?
apply_filters( 'woocommerce_reset_variations_link', '<a
class="reset_variations" href="#">' . __( 'Clear', 'woocommerce' ) . '</a>'
) : '';
?>
</td>
Maybe need to update something there to show properly?
do this instead
if( $stock_qty>0 )
//return $term_name .= ' - ' . $stock_status . ' ('.$stock_qty.')';
return $term_name;
else
//return $term_name .= ' - ' . $stock_status;
return $term_name .= ' - Out Of Stock';