Display WooCommerce category description and custom category titles

Woocommerce: Show attributes on single product page

David Nash woocommerce, wordpress 32 Comments

I’ve been working on a large Woocommerce site recently. Woocommerce gets updated regularly and unfortunately the documentation doesn’t always cover the new features.

Generally when I come across a new problem I ask Google. It’s easier to adapt code than it is to write it from scratch. To be honest, I find the attribute system a little confusing. I came across this Stack Overflow article, which helped. Then I realised there was a much easier way.

Step 1 – Create a Woocommerce action

Edit functions.php in your child theme. Add the following:

//show attributes after summary in product single view
add_action('woocommerce_single_product_summary', function() {
	//template for this is in storefront-child/woocommerce/single-product/product-attributes.php
	global $product;
	echo $product->list_attributes();
}, 25);

Reload the page for a product. You should now see the table of attributes.

Step 2 – Customise the output (optional)

The design I was working with showed the attributes in columns, not rows. I wanted the attribute name above each value. The Woocommerce template uses a table, which means I needed to edit the output.

If you haven’t already, create the directories woocommerce/single-product in your child theme. Copy the file product-attributes.php from the templates/single-product directory in the Woocommerce plugin. You can now edit this file to control the output.

Here’s the code that I used:

 * Product attributes
 * Used by list_attributes() in the products class.

// Instead of showing the attributes in a left-right table,
// we show them as columns with the name above each value.

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly

$has_row    = false;
$attributes = $product->get_attributes();


<div class="product_attributes">

	<?php foreach ( $attributes as $attribute ) :

		if ( empty( $attribute['is_visible'] ) || ( $attribute['is_taxonomy'] && ! taxonomy_exists( $attribute['name'] ) ) ) 

		$values = wc_get_product_terms( $product->get_id(), $attribute['name'], array( 'fields' => 'names' ) );
		$att_val = apply_filters( 'woocommerce_attribute', wpautop( wptexturize( implode( ', ', $values ) ) ), $attribute, $values );

		if( empty( $att_val ) )

		$has_row = true;

	<div class="col">
		<div class="att_label"><?php echo wc_attribute_label( $attribute['name'] ); ?></div>
		<div class="att_value"><?php echo $att_val; ?></div><!-- .att_value -->
	</div><!-- .col -->

	<?php endforeach; ?>

</div><!-- .product_attributes -->
if ( $has_row ) {
	echo ob_get_clean();
} else {

If you compare this to the original you can see I’ve removed the code for displaying weight and dimensions and made some other simplifications.

That’s it – now you’re good to go!

Did this post help you out, or just confuse you? Let me know in the comments!

Comments 32

  1. Great post!

    Is there a way to modify the display order of the attribute labels (att_label)? I have Googled it thoroughly but I can only find methods to sort the attribute values (att_value) when there are multiple values.

  2. I am not good with CSS. Can you help me display a bulleted list like this?

    * Lot No.: MG01-008
    * Size: 20x30in
    * Subject: Medieval, Nature, Scenic
    * Year of Creation: 1979
    * Medium: Oil on Canvas
    * Medium Description: Mounted Canvas Used
    * Available Types: Original
    * Framing: Framed, Removable
    * Status: Available

    1. Hi Mohit

      In the code above, replace 
      with a
      . Then inside the foreach loop, replace
    2. ...
    3. , and the att_label and att_value with ... elements.

      To answer your other comment, the full paths would be something like /path/to/site/wp-content/plugins/woocommerce/templates/single-product/product-attributes.php which gets copied to /path/to/site/wp-content/themes/your-theme/woocommerce/single-product/product-attributes.php

  3. David Nash,

    Great post no doubts this is for single product page but I want to display same information or attributes on the product page can you help me for that. Hopes you will.
    Thanks in advance!!


  4. Thank you for your post. I have got the same question like Mohit
    one small change needed:
    * Lot No.

    * Lot No. : TEST-1101
    Thank you ))

    1. You need to replace –
      $att_val = apply_filters( ‘woocommerce_attribute’, wpautop( wptexturize( implode( ‘, ‘, $values ) ) ), $attribute, $values );
      TO: $att_val = apply_filters( ‘woocommerce_attribute’, implode( ‘, ‘, $values ), $attribute, $values );

  5. Thank you so much David – This was very helpful. I tried using the Woocommerce Show Attribute Plugin but it would only show one attribute even when I had made all the attributes visible on the product page.

    Your code is wonderful as it solved my problem 🙂

  6. I know it’s maybe a bit late for this,
    But with 3.1.0 upgrade o WooCommerce,
    $product->id has been deprecated. Official announcement on GitHub says to use
    I have personally tested in on WP 4.8 and WC 3.1.1. Works great and doesn’t give an error “Product attributes should not be accessed directly[…]”.
    Hope this helps someone.

  7. Hello…I would like to place an object after attributes and before quantity selector /add to the cart button…Is there an after-attributes hook ? or Is there a hook for the before qty/add to the cart Button ?

    1. Not sure about that one. I find WooCommerce hooks a little frustrating, there seems to be plenty of them where you don’t need them, and none where you do!

      I would find the relevant file in woocommerce/templates/ and copy that to your theme directory, and then modify that – you could add the “global $product; echo $product->list_attributes();” lines where you want it.

      I’m not sure which file would be the right one off the top of my head, but my general process to find it is do a text search on all files in the directory (using grep or similar) to find strings you see in the developer console.

  8. Hi

    Its Very Helpful but
    But “”attr_val”” value has long string size which is to print in New line


    Instead of

    I have tried trim function also but still it showing me in different line

    Plzz Help me For this I am stuk since 2 days

    Thank you

  9. Hi there!
    Thanks for this post, I have a question though: How could I modify it for the attributes to be shown on single product page, cart&checkout table and emails? So basically through the whole order process?

    I have tried plugins for this but they don’t work the way I want to.

    Thanks for any help,

  10. Great, worked for me. Only I want to control where the attributes are shown.; instead of below the product price. Let’s say I have three rows on the product page.

    1. Left row shows a product image
    2. Middle row shows the product information
    3. Right row should show the product attributes.

    How can I make it show in the right row. E.g. via a short code.

    Best, Chris

Leave a Reply