Need to display the product shipping class to product page! any ideas why this is not working?
add_action('woocommerce_single_product_summary', 'display_product_shipping_class', 15 );
function display_product_shipping_class(){
global $product;
$term = get_term_by( 'slug', $product->get_product_shipping_class(), 'product_shipping_class' );
if( is_a($term, 'WP_Term') && $term->name == $product_shipping_class ){
echo '<p class="product-shipping-class">' . $term->name . '</p>';
}
}
There are multiple mistakes in your code. Try the following instead:
add_action('woocommerce_single_product_summary', 'display_product_shipping_class', 15 );
function display_product_shipping_class(){
global $product;
$shipping_class = $product->get_shipping_class();
if( ! empty($shipping_class) ) {
$term = get_term_by( 'slug', $shipping_class, 'product_shipping_class' );
if( is_a($term, 'WP_Term') ){
echo '<p class="product-shipping-class">' . $term->name . '</p>';
}
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
Related
I have set up an attribute for my products for a delivery time. And I am using the following functions to display it on product archives, on single product pages, on Orders and emails notifications:
add_action( 'woocommerce_single_product_summary', 'product_attribute_delivery', 27 );
function product_attribute_delivery(){
global $product;
$taxonomy = 'pa_delivery';
$value = $product->get_attribute( $taxonomy );
if ( $value && $product->is_in_stock() ) {
$label = get_taxonomy( $taxonomy )->labels->singular_name;
echo '<small>' . $label . ': ' . $value . '</small>';
}
}
add_action('woocommerce_order_item_meta_end', 'custom_item_meta', 10, 4 );
function custom_item_meta($item_id, $item, $order, $plain_text)
{ $productId = $item->get_product_id();
$product = wc_get_product($productId);
$taxonomy = 'pa_delivery';
$value = $product->get_attribute($taxonomy);
if ($value) {
$label = get_taxonomy($taxonomy)->labels->singular_name;
echo '<small>' . $label . ': ' . $value . '</small>';
}
}
add_action( 'woocommerce_after_shop_loop_item', 'product_attribute_delivery_shop', 1 );
function product_attribute_delivery_shop(){
global $product;
$taxonomy = 'pa_delivery';
$value = $product->get_attribute( $taxonomy );
if ( $value && $product->is_in_stock() ) {
$label = get_taxonomy( $taxonomy )->labels->singular_name;
echo '<small>' . $label . ': ' . $value . '</small>';
}
}
I have two questions:
Is there a way o combine these functions to optimize and clean up the code?
For the archive page (but not the single product page!) I want the text to change when the product is not on stock. Instead of not being displayed at all, I would like it to be "Sold Out".
Note that the rule on StackOverFlow is one question at the time. You can use a custom function that you will call on each hooked function like:
// Custom function that handle the code to display a product attribute
function custom_display_attribute( $product, $taxonomy = 'pa_delivery') {
$value = $product->get_attribute( $taxonomy );
if ( ! empty($value) && $product->is_in_stock() ) {
$label = wc_attribute_label( $taxonomy );
echo '<small>' . $label . ': ' . $value . '</small>';
}
}
// On product archive pages
add_action( 'woocommerce_after_shop_loop_item', 'product_attribute_delivery_archives', 1 );
function product_attribute_delivery_archives() {
global $product;
custom_display_attribute( $product );
// When product is out of stock displays "Sold Out"
if ( ! $product->is_in_stock() ) {
echo __("Sold Out", "woocommerce");
}
}
// On product single pages
add_action( 'woocommerce_single_product_summary', 'product_attribute_delivery_single', 27 );
function product_attribute_delivery_single() {
global $product;
custom_display_attribute( $product );
}
// On orders and email notifications
add_action('woocommerce_order_item_meta_end', 'custom_item_meta', 10, 4 );
function custom_item_meta( $item_id, $item, $order, $plain_text ) {
custom_display_attribute( wc_get_product( $item->get_product_id() ) );
}
It should works.
On archive pages only when product is not in stock, it will displays "Sold Out".
I want to add some attributes to the shop page of wordpress.
This code i found on Stackoverflow, is shows all attribute labes but on all the same attribute names.
add_action('woocommerce_after_shop_loop_item_title','add_attribute');
function add_attribute() {
global $product;
$product_attributes = array( 'pa_country','pa_class','pa_faction','pa_gender' );
$attr_output = array();
foreach( $product_attributes as $taxonomy ){
if( taxonomy_exists($taxonomy) ){
$label_name = get_taxonomy( $taxonomy )->labels->singular_name;
$value = $product->get_attribute('pa_country','pa_class','pa_faction','pa_gender');
if( ! empty($value) ){
$attr_output[] = '<span class="'.$taxonomy.'">'.$label_name.': '.$value.'</span>';
}
}}
echo '<div class="product-attributes">'.implode( '<br>', $attr_output ).'</div>';
}
current state
I just need a bit help to get it to show all the right attributes.
There a some little mistakes in your code. Try the following instead:
add_action('woocommerce_after_shop_loop_item_title', 'display_shop_loop_product_attributes');
function display_shop_loop_product_attributes() {
global $product;
// Define you product attribute taxonomies in the array
$product_attribute_taxonomies = array( 'pa_country', 'pa_class', 'pa_faction', 'pa_gender' );
$attr_output = array(); // Initializing
// Loop through your defined product attribute taxonomies
foreach( $product_attribute_taxonomies as $taxonomy ){
if( taxonomy_exists($taxonomy) ){
$label_name = wc_attribute_label( $taxonomy, $product );
$term_names = $product->get_attribute( $taxonomy );
if( ! empty($term_names) ){
$attr_output[] = '<span class="'.$taxonomy.'">'.$label_name.': '.$term_names.'</span>';
}
}
}
// Output
echo '<div class="product-attributes">'.implode( '<br>', $attr_output ).'</div>';
}
Code goes in functions.php file of your active child theme (or active theme). tested and works.
For simple products only you will use the following instead:
add_action('woocommerce_after_shop_loop_item_title', 'display_shop_loop_product_attributes');
function display_shop_loop_product_attributes() {
global $product;
// Only for simple products
if ( ! $product->is_type( 'simple' ) ) return;
// Define you product attribute taxonomies in the array
$product_attribute_taxonomies = array( 'pa_country', 'pa_class', 'pa_faction', 'pa_gender' );
$attr_output = array(); // Initializing
// Loop through your defined product attribute taxonomies
foreach( $product_attribute_taxonomies as $taxonomy ){
if( taxonomy_exists($taxonomy) ){
$label_name = wc_attribute_label( $taxonomy, $product );
$term_names = $product->get_attribute( $taxonomy );
if( ! empty($term_names) ){
$attr_output[] = '<span class="'.$taxonomy.'">'.$label_name.': '.$term_names.'</span>';
}
}
}
// Output
echo '<div class="product-attributes">'.implode( '<br>', $attr_output ).'</div>';
}
Code goes in functions.php file of your active child theme (or active theme). tested and works.
I solved the problem. its not pretty but it works.
add_action( 'woocommerce_after_shop_loop_item_title', 'display_size_attribute', 5 );
function display_size_attribute() {
global $product;
if ( $product->is_type('simple') ) {
$taxonomy = 'pa_country';
echo '<span class="attribute-s">Country: ' . $product->get_attribute($taxonomy) . '</span>','<br>';
}
if ( $product->is_type('simple') ) {
$taxonomy = 'pa_class';
echo '<span class="attribute-s">Class: ' . $product->get_attribute($taxonomy) . '</span>','<br>';
}
if ( $product->is_type('simple') ) {
$taxonomy = 'pa_faction';
echo '<span class="attribute-s">Faction: ' . $product->get_attribute($taxonomy) . '</span>','<br>';
}
if ( $product->is_type('simple') ) {
$taxonomy = 'pa_gender';
echo '<span class="attribute-s">Gender: ' . $product->get_attribute($taxonomy) . '</span>','<br>';
}}
This is my code for display an atributte below a product title. How can I display it like a link to archive page of this attributte?
add_action( 'woocommerce_single_product_summary', 'custom_template_single_title', 5 );
function custom_template_single_title() {
global $product;
$brand_name = $product->get_attribute('Autor');
echo '<div class ="author-product">';
if( $brand_name )
echo $brand_name;
echo '</div>';
}
First, $product->get_attribute('Autor') can give multiple coma separated term names.
Below, we add the term link to each term name (if there is more than one):
add_action( 'woocommerce_single_product_summary', 'custom_template_single_title', 5 );
function custom_template_single_title() {
global $product;
$taxonomy = 'pa_autor'; // <== The product attribute taxonomy
$linked_terms = []; // Initializing
if ( $term_names = $product->get_attribute($taxonomy) ) {
// Loop through the term names
foreach( explode(', ', $term_names) as $term_name ) {
$term_id = get_term_by('name', $term_name, $taxonomy)->term_id; // get the term ID
$term_link = get_term_link( $term_id, $taxonomy ); // get the term link
$linked_terms[] = '' . $term_name . '';
}
// Output
echo '<div class ="author-product">' . implode(', ', $linked_terms) . '</div>';
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
I am trying to accomplish a attribute and term list on the shop page using the hook woocommerce_shop_loop_item_title. The goal is to get the attribute(s) and term(s) for the product and then to display it like this example:
Color: Red, Blue, Green
Size: Small, Medium, Large
Dimensions: 90*90, 100*100 and 120*120
but without the spaces between the rows.
It should "fetch" all the attributes used with the product and the attributes terms.
I've tried this but got fatal error.
add_action( 'woocommerce_shop_loop_item_title', 'variable_att_and_terms_on_loop');
function variable_att_and_terms_on_loop() {
foreach( $product->get_variation_attributes() as $taxonomy => $terms_slug ) {
$taxonomy_label = wc_attribute_label( $taxonomy, $product );
foreach($terms_slug as $term) {
$term_name = get_term_by('slug', $term, $taxonomy)->name;
$attributes_and_terms_names[$taxonomy_label][$term] = $term_name;
}
}
foreach ( $attributes_and_terms_names as $attribute_name => $terms_name ) {
$terms_string = implode( ', ', $terms_name );
echo '<p>' . $attribute_name . ': ' . $terms_string . '</p>';
}
}
I've also tried this:
add_action('woocommerce_shop_loop_item_title','add_attribute', 5);
function add_attribute() {
global $product;
$product_attributes = array( 'pa_weight', 'pa_quantity', 'pa_length', 'pa_color' );
$attr_output = array();
foreach( $product_attributes as $taxonomy ){
if( taxonomy_exists($taxonomy) ){
$label_name = get_taxonomy( $taxonomy )->labels->singular_name;
$value = $product->get_attribute('pa_weight');
if( ! empty($value) ){
$attr_output[] = '<span class="'.$taxonomy.'">'.$label_name.': '.$value.'</span>';
}
}
}
echo '<div class="product-attributes">'.implode( '<br>', $attr_output ).'</div>';
}
without any result.
After trying the new result below from LoicTheAztec, this is what I get:
Uppdate 2020 - Removed an error when trying to get the term name from a term slug.
In your first code snippet there are some mistakes:
the $product variable was not defined
The function needed to be restricted to variable products only
the $attributes_and_terms_names variable was not initialized…
Here is the revisited code (without the spaces between the rows):
add_action( 'woocommerce_shop_loop_item_title', 'variable_att_and_terms_on_loop');
function variable_att_and_terms_on_loop() {
global $product;
if( ! $product->is_type('variable') ) return; // Only for variable products
$variation_attributes = $product->get_variation_attributes();
if( sizeof($variation_attributes ) == 0 ) return; // Exit if empty
$attributes = array(); // Initializing
foreach( $product->get_variation_attributes() as $taxonomy => $terms_slug ) {
$taxonomy_label = wc_attribute_label( $taxonomy, $product );
$terms_name = array();
foreach($terms_slug as $term_slug ) {
// We try to get the term name when it's a term slug
$term = get_term_by('slug', $term_slug, $taxonomy);
$terms_name[] = ! is_a($term, 'WP_Term') ? $term_slug : $term->name;
}
$attributes[] = $taxonomy_label . ': ' . implode( ', ', $terms_name );
}
echo '<div class="product-attributes">';
echo '<span>' . implode('</span><br><span>', $attributes) . '</span>';
echo '</div>';
}
Code goes in function.php file of your active child theme (active theme). Tested and works.
I have set up a Woocommerce attribute for delivery time and am displaying it on the single product page with this:
//Single Product
function product_attribute_delivery(){
global $product;
$taxonomy = 'pa_delivery';
$value = $product->get_attribute( $taxonomy );
if ( $value ) {
$label = get_taxonomy( $taxonomy )->labels->singular_name;
echo '<p>' . $label . ': ' . $value . '</p>';
}
}
add_action( 'woocommerce_single_product_summary', 'product_attribute_delivery', 25 );
Would it be possible to only display it when the product is in stock?
It is possible using WC_Product is_in_stock() method:
add_action( 'woocommerce_single_product_summary', 'product_attribute_delivery', 25 );
function product_attribute_delivery(){
global $product;
$taxonomy = 'pa_delivery';
$value = $product->get_attribute( $taxonomy );
if ( $value && $product->is_in_stock() ) {
$label = get_taxonomy( $taxonomy )->labels->singular_name;
echo '<p>' . $label . ': ' . $value . '</p>';
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and work