I made a function for Woo store to display custom taxonomies. And somehow my span conatiners for each are destroyed. Here's the code:
add_action( 'woocommerce_product_meta_start', 'add_my_meta', 1 );
function add_my_meta() {
$series = the_terms($post->ID, 'series');
if ($series) {
$meta_output = '<span style="display:block;">Series: ';
$meta_array = array();
foreach ($series as $serie) {
$meta_array[] = '' . $serie->name . '';
}
$meta_output .= join( ', ', $meta_array ) . '</span>';
}
return $meta_output;
}
So expected output is <span style="display:block;">Series: My Series</span>
Current output is My Series
Spans and text removed. Never faced that problem before, what's the problem and how to solve?
Found some mistakes — needed to use get_the_terms (was the_terms) and $serie->term_id (was $serie->slug)
add_action( 'woocommerce_product_meta_start', 'add_my_meta', 1 );
function add_my_meta() {
$series = get_the_terms($post->ID, 'series');
if ( is_array($series) ) {
$meta_array = array();
foreach ($series as $serie) {
$meta_array[] = '' . $serie->name . '';
}
echo '<span class="tagged_as">Series: ' . implode( ', ', $meta_array ) . '</span>';
}
}
Related
I am trying to display certain attributes that have data on a custom tab in woocommerce. I have found several examples of code but none are working for me.
I was given the following code
add_filter( 'woocommerce_display_product_attributes', 'remove_product_information', 10, 2 );
function remove_product_information( $product_attributes, $product ) {
// Remove an attribute from the array
unset($product_attributes['color']);
return $product_attributes;
}
echo wc_display_product_attributes( $product );
but its not filtering anything out it still displays 'color' or any other attribute name I put in there. Also I need t filter out several attributes, so do I just add additional unset lines? or is there a cleaner way to do that? Any insight on this?
Solution 1:
If you want to customize single product page attributes, You need to customize/override the product attribute page with your custom attribute page, after that, you can modify the attribute accordingly.
To customise the page like:
Copy
plugins/woocommerce/templates/single-product/product-attributes.php
To
themes/your-theme/woocommerce/single-product/product-attributes.php
and modify that.
Solution 2:
You have to define first the desired product attributes slugs in an array, after that you will get in single product pages:
add_action( 'display_product_attributes', 'display_product_attributes', 25 );
function display_some_product_attributes(){
// HERE define the desired product attributes to be displayed
$defined_attributes = array('fyllighet', 'carrier', 'billing-e-number');
global $product;
$attributes = $product->get_attributes();
if ( ! $attributes ) {
return;
}
$out = '<ul class="taste-attributes">';
foreach ( $attributes as $attribute ) {
// Get the product attribute slug from the taxonomy
$attribute_slug = str_replace( 'pa_', '', $attribute->get_name() );
// skip all non desired product attributes
if ( ! in_array($attribute_slug, $defined_attributes) ) {
continue;
}
// skip variations
if ( $attribute->get_variation() ) {
continue;
}
$name = $attribute->get_name();
if ( $attribute->is_taxonomy() ) {
$terms = wp_get_post_terms( $product->get_id(), $name, 'all' );
// get the taxonomy
$tax = $terms[0]->taxonomy;
// get the tax object
$tax_object = get_taxonomy($tax);
// get tax label
if ( isset ( $tax_object->labels->singular_name ) ) {
$tax_label = $tax_object->labels->singular_name;
} elseif ( isset( $tax_object->label ) ) {
$tax_label = $tax_object->label;
// Trim label prefix since WC 3.0
if ( 0 === strpos( $tax_label, 'Product ' ) ) {
$tax_label = substr( $tax_label, 8 );
}
}
$out .= '<li class="' . esc_attr( $name ) . '">';
$out .= '<p class="attribute-label">' . esc_html( $tax_label ) . ': </p> ';
$tax_terms = array();
foreach ( $terms as $term ) {
$single_term = esc_html( $term->name );
// Insert extra code here if you want to show terms as links.
array_push( $tax_terms, $single_term );
}
$out .= '<span class="attribute-value">' . implode(', ', $tax_terms) . '</span><progress value="' . implode(', ', $tax_terms) .
'" max="10"><div class="progress-bar"><span style="width:'
. implode(', ', $tax_terms) . '0%">'
. implode(', ', $tax_terms) . '</span></div></progress></li>';
} else {
$value_string = implode( ', ', $attribute->get_options() );
$out .= '<li class="' . sanitize_title($name) . ' ' . sanitize_title( $value_string ) . '">';
$out .= '<p class="attribute-label">' . $name . ': </p> ';
$out .= '<progress value="' . esc_html( $value_string ) . '" max="10"></progress></li>';
}
}
$out .= '</ul>';
echo $out;
}
So the code I posted does work, I was just using the wrong name for the attribute. I needed to add 'attribute_pa_' so for example 'attribute_pa_brand'
I am working on a solution to have specific product attributes on a single product page. Based on Display specific custom product attributes on single product pages in Woocommerce answer code, I made some little changes here below
to display the selected attribute on single product pages:
add_action( 'woocommerce_single_product_summary', 'display_some_product_attributes', 25 );
function display_some_product_attributes(){
// HERE define the desired product attributes to be displayed
$defined_attributes = array('attributeB', 'attributeC', 'attributeD');
global $product;
$attributes = $product->get_attributes();
echo '<div style="font-size: 20px; font-weight: 500; margin-bottom: 5px; text-transform: uppercase;"><span>Sensorik</span></div>';
if ( ! $attributes ) {
return;
}
$out = '<ul class="taste-attributes">';
foreach ( $attributes as $attribute ) {
// Get the product attribute slug from the taxonomy
$attribute_slug = str_replace( 'pa_', '', $attribute->get_name() );
// skip all non desired product attributes
if ( ! in_array($attribute_slug, $defined_attributes) ) {
continue;
}
// skip variations
if ( $attribute->get_variation() ) {
continue;
}
$name = $attribute->get_name();
if ( $attribute->is_taxonomy() ) {
$terms = wp_get_post_terms( $product->get_id(), $name, 'all' );
// get the taxonomy
$tax = $terms[0]->taxonomy;
// get the tax object
$tax_object = get_taxonomy($tax);
// get tax label
if ( isset ( $tax_object->labels->singular_name ) ) {
$tax_label = $tax_object->labels->singular_name;
} elseif ( isset( $tax_object->label ) ) {
$tax_label = $tax_object->label;
// Trim label prefix since WC 3.0
if ( 0 === strpos( $tax_label, 'Product ' ) ) {
$tax_label = substr( $tax_label, 8 );
}
}
$out .= '<p class="' . esc_attr( $name ) . '">';
$out .= '<span class="attribute-label">' . esc_html( $tax_label ) . ': </span>';
$tax_terms = array();
foreach ( $terms as $term ) {
$single_term = esc_html( $term->name );
// Insert extra code here if you want to show terms as links.
array_push( $tax_terms, $single_term );
}
$out .= '<span class="attribute-value">' . implode(', ', $tax_terms) . '</span></p>';
} else {
$value_string = implode( ', ', $attribute->get_options() );
$out .= '<span class="' . sanitize_title($name) . ' ' . sanitize_title( $value_string ) . '">';
$out .= '<p class="attribute-label">' . $name . ': </p></span>';
}
}
$out .= '</ul>';
echo $out;
}
Then to transform text to an image for some attributes, I use the code below:
``` /**
* Insert JavaScript to replace WooCommerce product attributes text with images.
*/
function my_woocommerce_attributes_images(){
?>
<script>(function() {
var list, index, element, attValue, imgURL;
list = document.getElementsByClassName("attributeA");
for (index = 0; index < list.length; ++index) {
element = list[index];
attValue = element.getElementsByClassName("attribute-value")[0].innerText;
switch (attValue.trim()) {
case "valueA":
imgURL = "/wp-content/uploads/2020/10/cigar.png";
break;
case "valueB":
imgURL = "/wp-content/uploads/2020/10/fish.png";
break;
}
element.innerHTML = '<span class="attribute-label">Atteibute A: </span><img src="' + imgURL + '" width="20" height="20" />';
}
})();</script>
<?php
}
add_action('wp_footer', 'my_woocommerce_attributes_images'); ```
But I have the following problems:
Currently, only one case can be possible. If two ore more are true, it will not load any images. So we need a for each loop here and out put all true values => images. But all of my tryout was not sucessfull.
Currently we have to insert the code multiple times when we want to transform text to images from more than one attribute. I already tried to add a for each loop for list = document.getElementsByClassName("attributeA"); in order taht we can have there something like list = document.getElementsByClassName("attributeA", "attributeB", "attributeB"); But I'm not able to get this to work.
In order to make this more generic, also the element.innerHTML = '<span class="attribute-label">Attribute A: </span><img src="' + imgURL + '" width="20" height="20" />'; should be display the generic current Attribute lable name. But yeah, here I not able to add this in a ore generic way.
Any suggestions are welcome to make it work.
I found the following code to display all custom attributes on a product detail page (with a specific bar-style design that I need). The code works like a charm and I have the proper CSS to display horizontal bars of my custom attributes.
Problem I have is that I only want to display specific named
attributes and don't know how to change the loop to do that...
function isa_woocommerce_all_pa(){
global $product;
$attributes = $product->get_attributes();
if ( ! $attributes ) {
return;
}
$out = '<ul class="taste-attributes">';
foreach ( $attributes as $attribute ) {
// skip variations
if ( $attribute->get_variation() ) {
continue;
}
$name = $attribute->get_name();
if ( $attribute->is_taxonomy() ) {
$terms = wp_get_post_terms( $product->get_id(), $name, 'all' );
// get the taxonomy
$tax = $terms[0]->taxonomy;
// get the tax object
$tax_object = get_taxonomy($tax);
// get tax label
if ( isset ( $tax_object->labels->singular_name ) ) {
$tax_label = $tax_object->labels->singular_name;
} elseif ( isset( $tax_object->label ) ) {
$tax_label = $tax_object->label;
// Trim label prefix since WC 3.0
if ( 0 === strpos( $tax_label, 'Product ' ) ) {
$tax_label = substr( $tax_label, 8 );
}
}
$out .= '<li class="' . esc_attr( $name ) . '">';
$out .= '<p class="attribute-label">' . esc_html( $tax_label ) . ': </p> ';
$tax_terms = array();
foreach ( $terms as $term ) {
$single_term = esc_html( $term->name );
// Insert extra code here if you want to show terms as links.
array_push( $tax_terms, $single_term );
}
$out .= '<span class="attribute-value">' . implode(', ', $tax_terms) . '</span><progress value="' . implode(', ', $tax_terms) .
'" max="10"><div class="progress-bar"><span style="width:'
. implode(', ', $tax_terms) . '0%">'
. implode(', ', $tax_terms) . '</span></div></progress></li>';
} else {
$value_string = implode( ', ', $attribute->get_options() );
$out .= '<li class="' . sanitize_title($name) . ' ' . sanitize_title( $value_string ) . '">';
$out .= '<p class="attribute-label">' . $name . ': </p> ';
$out .= '<progress value="' . esc_html( $value_string ) . '" max="10"></progress></li>';
}
}
$out .= '</ul>';
echo $out;
}
add_action('woocommerce_single_product_summary', 'isa_woocommerce_all_pa', 20);
In the following code you will define first the desired product attributes slugs in an array, that will get displayed in single product pages:
add_action( 'woocommerce_single_product_summary', 'display_some_product_attributes', 25 );
function display_some_product_attributes(){
// HERE define the desired product attributes to be displayed
$defined_attributes = array('fyllighet', 'carrier', 'billing-e-number');
global $product;
$attributes = $product->get_attributes();
if ( ! $attributes ) {
return;
}
$out = '<ul class="taste-attributes">';
foreach ( $attributes as $attribute ) {
// Get the product attribute slug from the taxonomy
$attribute_slug = str_replace( 'pa_', '', $attribute->get_name() );
// skip all non desired product attributes
if ( ! in_array($attribute_slug, $defined_attributes) ) {
continue;
}
// skip variations
if ( $attribute->get_variation() ) {
continue;
}
$name = $attribute->get_name();
if ( $attribute->is_taxonomy() ) {
$terms = wp_get_post_terms( $product->get_id(), $name, 'all' );
// get the taxonomy
$tax = $terms[0]->taxonomy;
// get the tax object
$tax_object = get_taxonomy($tax);
// get tax label
if ( isset ( $tax_object->labels->singular_name ) ) {
$tax_label = $tax_object->labels->singular_name;
} elseif ( isset( $tax_object->label ) ) {
$tax_label = $tax_object->label;
// Trim label prefix since WC 3.0
if ( 0 === strpos( $tax_label, 'Product ' ) ) {
$tax_label = substr( $tax_label, 8 );
}
}
$out .= '<li class="' . esc_attr( $name ) . '">';
$out .= '<p class="attribute-label">' . esc_html( $tax_label ) . ': </p> ';
$tax_terms = array();
foreach ( $terms as $term ) {
$single_term = esc_html( $term->name );
// Insert extra code here if you want to show terms as links.
array_push( $tax_terms, $single_term );
}
$out .= '<span class="attribute-value">' . implode(', ', $tax_terms) . '</span><progress value="' . implode(', ', $tax_terms) .
'" max="10"><div class="progress-bar"><span style="width:'
. implode(', ', $tax_terms) . '0%">'
. implode(', ', $tax_terms) . '</span></div></progress></li>';
} else {
$value_string = implode( ', ', $attribute->get_options() );
$out .= '<li class="' . sanitize_title($name) . ' ' . sanitize_title( $value_string ) . '">';
$out .= '<p class="attribute-label">' . $name . ': </p> ';
$out .= '<progress value="' . esc_html( $value_string ) . '" max="10"></progress></li>';
}
}
$out .= '</ul>';
echo $out;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
I am working on project and I need some group help.
I am using woocommerce product system and on shop archive page product I am showing attribute-label: attribute-value (just like text).
attribute-label:attribute-value (ex. Transmission: Manual)
Is there a way to show attribute-label as image? I can't add html code like <img src..."/> and styling with CSS doesn't help too.
I have searched for plugins and more.. But nothing on web.
To show attributes on product shop page i have used this function:
function isa_woocommerce_all_pa(){
global $product;
$attributes = $product->get_attributes();
if ( ! $attributes ) {
return;
}
$out = '<ul class="custom-attributes">';
foreach ( $attributes as $attribute ) {
// skip variations
if ( $attribute->get_variation() ) {
continue;
}
$name = $attribute->get_name();
if ( $attribute->is_taxonomy() ) {
$terms = wp_get_post_terms( $product->get_id(), $name, 'all' );
// get the taxonomy
$tax = $terms[0]->taxonomy;
// get the tax object
$tax_object = get_taxonomy($tax);
// get tax label
if ( isset ( $tax_object->labels->singular_name ) ) {
$tax_label = $tax_object->labels->singular_name;
} elseif ( isset( $tax_object->label ) ) {
$tax_label = $tax_object->label;
// Trim label prefix since WC 3.0
if ( 0 === strpos( $tax_label, 'Product ' ) ) {
$tax_label = substr( $tax_label, 8 );
}
}
$out .= '<li class="' . esc_attr( $name ) . '">';
$out .= '<span class="attribute-label">' . esc_html( $tax_label ) . ': </span> ';
$out .= '<span class="attribute-value">';
$tax_terms = array();
foreach ( $terms as $term ) {
$single_term = esc_html( $term->name );
// Insert extra code here if you want to show terms as links.
array_push( $tax_terms, $single_term );
}
$out .= implode(', ', $tax_terms);
$out .= '</span></li>';
} else {
$value_string = implode( ', ', $attribute->get_options() );
$out .= '<li class="' . sanitize_title($name) . ' ' . sanitize_title( $value_string ) . '">';
$out .= '<span class="attribute-label">' . $name . ': </span> ';
$out .= '<span class="attribute-value">' . esc_html( $value_string ) . '</span></li>';
}
}
$out .= '</ul>';
echo $out;
}
add_action('woocommerce_single_product_summary', 'isa_woocommerce_all_pa', 25);
Can someone help me with this? How to change attribute-label with image?
Updated since WC 3.2+
As Product attributes dont have images, you should create a in your active theme a folder images (if it doesn't exist) and inside a subfolder attributes.
For each product attribute, you will have to add an image inside this subfolder attributes, which name will be the name of your attribute (the slug). For example for "Color" attribute you will have to add an image named color.jpg.
Then I have make some changes in your code, to get this working. Only the terms set in the product for each attribute will be displayed. For each attribute you will get an image.
Here is the code:
add_action('woocommerce_single_product_summary', 'isa_woocommerce_all_pa', 25);
function isa_woocommerce_all_pa(){
global $product;
$attributes = $product->get_attributes();
if ( ! $attributes ) return;
$out = '<ul class="custom-attributes">';
foreach ( $attributes as $attribute ) {
if ( $attribute->get_variation() ) continue; // skip variations
if ( $attribute->is_taxonomy() ) {
$taxonomy = $attribute->get_name();
$taxo_obj = $attribute->get_taxonomy_object();
$name = $taxo_obj->attribute_name; // <== Corrected
$label = $taxo_obj->attribute_label; // <== Corrected
$out .= '<li class="' . esc_attr( $taxonomy ) . '">';
## ATTRIBUTE IMAGE ##
// For a child theme use get_stylesheet_directory_uri() instead.
$out .= '<img class="attribute-image" src="'.get_template_directory_uri().'/images/attributes/'.$name.'.jpg" alt="Attribute '.$label.'"/> ';
$out .= '<span class="attribute-values">';
$terms = wp_get_post_terms( $product->get_id(), $taxonomy, array('fields' => 'names') );
foreach ( $terms as $term_name )
$term_names['name'] = $term_name;
$out .= implode(', ', $term_names);
$out .= '</span></li>';
} else {
$value_string = implode( ', ', $attribute->get_options() );
$out .= '<li class="' . sanitize_title($taxonomy) . ' ' . sanitize_title( $value_string ) . '">';
$out .= '<span class="attribute-label">' . $taxonomy . ': </span> ';
$out .= '<span class="attribute-value">' . esc_html( $value_string ) . '</span></li>';
}
}
$out .= '</ul>';
echo $out;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and work.
Any one please help me find the solution to the following:
I want to show specific product option value on woocommerce email template.
The code to show all option value:
public function tm_woocommerce_email_after_row($item_id, $item, $order , $flat=false){
$html = '';
$has_epo = isset($item['item_meta']) && isset($item['item_meta']['_tmcartepo_data']) && isset($item['item_meta']['_tmcartepo_data'][0]);
if ($has_epo){
$epos = maybe_unserialize($item['item_meta']['_tmcartepo_data'][0]);
$current_product_id=$item['product_id'];
$original_product_id = floatval(TM_EPO_WPML()->get_original_id( $current_product_id,'product' ));
if (TM_EPO_WPML()->get_lang()==TM_EPO_WPML()->get_default_lang() && $original_product_id!=$current_product_id){
$current_product_id = $original_product_id;
}
$wpml_translation_by_id=$this->get_wpml_translation_by_id( $current_product_id );
foreach ($epos as $key => $epo) {
if ($epo){
if(!isset($epo['quantity'])){
$epo['quantity'] = 1;
}
if(isset($wpml_translation_by_id[$epo['section']])){
$epo['name'] = $wpml_translation_by_id[$epo['section']];
}
if(!empty($epo['multiple']) && !empty($epo['key'])){
$pos = strrpos($epo['key'], '_');
if($pos!==false) {
$av=array_values( $wpml_translation_by_id["options_".$epo['section']] );
if (isset($av[substr($epo['key'], $pos+1)])){
$epo['value'] = $av[substr($epo['key'], $pos+1)];
}
}
}
if ($flat){
$html .= "\n" . $epo['name'] . ' : ' . $epo['value'];
$html .= "\n" . sprintf( __( 'Quantity: %s', 'woocommerce' ), ( $epo['quantity'] * (float) $item['item_meta']['_qty'][0] ) );
if (!empty($item['item_meta']['tm_has_dpd'])){
}else{
$html .= "\n" . sprintf( __( 'Cost: %s', 'woocommerce' ), (wc_price( (float) $epo['quantity'] * (float) $epo['price'] * (float) $item['item_meta']['_qty'][0] )) );
}
}else{
$html .= '';
$html .= ''.$epo['name'].': '.$epo['value'].'<br/>';
$html .= '';
}
}
}
}
echo $html;
}
I am using this plugin for extra option :
WooCommerce Extra Product Options
Any hint will be much appreciated.
Thank you so much!