Ask your WordPress questions! Pay money and get answers fast! (more info)

How do I add product attributes to WooCommerce Emails WordPress


I need to mess around with the content of WooCommerce order emails and add in product attribute information below each row in the table.

I have two attributes that I would like to display the title and content from under each product title.

I have overridden and tried editing the email-order-items.php file but have not been able to get any attribute data to display.

Attributes are called:

Print Area

Filling Quantity

I have been trying this for but it does not seem to work:

// Attribute
echo ($show_attribute && $_product->get_attribute()) ? '<br/><small>Print Area: ' . nl2br( $_product->get_attribute( 'print-area' ) ) . '</small>' : '';

I would also like to lose the standard quantity column and replace it with a column that pulls in data from a product variation called: 'quantity'

Any help would be much appreciated.

Answers (4)


Dbranes answers:

Did you try this:

// Attribute
echo '<br/><small>Print Area: ' . nl2br( $_product->get_attribute( 'print-area' ) ) . '</small>';

instead of

// Attribute
echo ($show_attribute && $_product->get_attribute()) ? '<br/><small>Print Area: ' . nl2br( $_product->get_attribute( 'print-area' ) ) . '</small>' : '';

I think this part in your code is returning <em>FALSE</em>:

($show_attribute && $_product->get_attribute())

I just tested it, it works on my install, here's an example of the email order:

[[LINK href=""]][[/LINK]]

Sam Cranwell comments:

Perfect!! Thank you, works a treat.

You the man.

Dbranes comments:

Great, glad to hear it worked for you.

Sam Cranwell comments:

I thought I might have the second part of my question sorted armed with this knowledge but it isn't quite working out.

In the email I wanted to replace the contents of the quantity column with the contents of the product attribute called 'quantity' (this contains a unit cost for the items).

If I use the same method, it will display all the options in the attribute field (I only want to display the selected variation)

$_product->get_attribute( 'quantity' )
This code outputs: <strong>100 Units (£2.64 each) | 250 Units (£2.59 each)</strong>

So I tried:

$item_meta = new WC_Order_Item_Meta( $item['item_meta'] );

echo $item_meta->display( true, true )

This code outputs: <strong>Quantity: 100 Units (£2.64 each)</strong>

However, I just want to output: <strong>100 Units (£2.64 each) </strong>
(no label in front of the attribute data)

Any ideas on how to achieve this?

Dbranes comments:

ok, what about:

$item_meta = new WC_Order_Item_Meta( $item['item_meta'] );
echo str_ireplace( 'Quantity:', '', $item_meta->display( true, true ) );

Dbranes comments:

If I use this code:

if( isset( $item_meta->meta['quantity'][0] ) )
echo $item_meta->meta['quantity'][0];

then I get

100 Units (£2.64 each)

if that quantity variation was select in the order.

You can view the quantity array with

print_r( $item_meta->meta['quantity'] );

Sam Cranwell comments:

Excellent - both work perfectly. Thank you very much.

I take it the latter version is cleanest way of coding it?

Dbranes comments:

yes, I guess I would use the latter version too ;-)


Francisco Javier Carazo Gil answers:

Have you read this one?

Sam Cranwell comments:

Interesting but not quite what I'm looking for. That solution works with custom fields - I need to display WooCommerce product attributes.

Francisco Javier Carazo Gil comments:

Could you print the result for this product?

global $woocommerce, $post, $product;
$res = get_post_meta($product->id);

Sam Cranwell comments:

Unfortunately that didn't output anything.

This is how I used it within the row of the email table:

<td style="text-align:left; vertical-align:middle; border: 1px solid #eee; word-wrap:break-word;"><?php

// Show title/image etc
echo apply_filters( 'woocommerce_order_product_image', $image, $_product, $show_image);

// Product name
echo apply_filters( 'woocommerce_order_product_title', $item['name'], $_product );

// SKU
echo ($show_sku && $_product->get_sku()) ? ' (#' . $_product->get_sku() . ')' : '';

// File URLs
if ( $show_download_links && $_product->exists() && $_product->is_downloadable() ) {

$download_file_urls = $order->get_downloadable_file_urls( $item['product_id'], $item['variation_id'], $item );

$i = 0;

foreach ( $download_file_urls as $file_url => $download_file_url ) {
echo '<br/><small>';

$filename = woocommerce_get_filename_from_url( $file_url );

if ( count( $download_file_urls ) > 1 ) {
echo sprintf( __('Download %d:', 'woocommerce' ), $i + 1 );
} elseif ( $i == 0 )
echo __( 'Download:', 'woocommerce' );

echo ' <a href="' . $download_file_url . '" target="_blank">' . $filename . '</a></small>';


// Variation
echo ($item_meta->meta) ? '<br/><small>' . nl2br( $item_meta->display( true, true ) ) . '</small>' : '';

// Attribute
global $woocommerce, $post, $product;
$res = get_post_meta($product->id);

<td style="text-align:left; vertical-align:middle; border: 1px solid #eee;"><?php echo $item['qty'] ;?></td>
<td style="text-align:left; vertical-align:middle; border: 1px solid #eee;"><?php echo $order->get_formatted_line_subtotal( $item ); ?></td>

Francisco Javier Carazo Gil comments:

Change it:

$res = get_post_meta($_product->id);

Francisco Javier Carazo Gil comments:

And also you have to output it in a log or in the mail. Try to write it in the debug.log: error_log (you have to create a file debug.log in wp-content directory with all write permissions available).

Change print_r for error_log

Sam Cranwell comments:

Thanks - that outputs everything though (see attached image). Is there anyway to refine this to just show particular attributes?

What I need to display is:

Print Area: 68 x 37mm