Displaying product custom fields

As with all post types in WordPress, you can add custom fields (post meta) to your WooCommerce products:

There’s two ways to get these to display in your PDF invoice or packing slip: with a pdf template action hook in your themes functions.php (which is the most update safe method because you don’t have to create a custom template), or directly in a custom template.

Using an action hook #

If you’ve never edited your themes functions.php before, make sure to read this first.

Let’s say your custom field is called ‘Location’, you can display this below the product description with the following code:

add_action( 'wpo_wcpdf_after_item_meta', 'wpo_wcpdf_product_custom_field', 10, 3 );
function wpo_wcpdf_product_custom_field ( $template_type, $item, $order ) {
    // check if product exists first
    if (empty($item['product'])) return;
  
    // replace 'Location' with your custom field name!
    $field_name = 'Location';
    $location = $item['product']->get_meta($field_name,true,'edit');
    if (!empty($location)) {
        echo '<div class="product-location">Location: '.$location.'</div>';
    }
}

If you want to restrict this to the Packing Slip, you can add an if-statement around it:

add_action( 'wpo_wcpdf_after_item_meta', 'wpo_wcpdf_product_custom_field', 10, 3 );
function wpo_wcpdf_product_custom_field ( $template_type, $item, $order ) {
    if ( $template_type == 'packing-slip' ) {
       // check if product exists first
        if (empty($item['product'])) return;
      
        // replace 'Location' with your custom field name!
        $field_name = 'Location';
        $location = $item['product']->get_meta($field_name,true,'edit');
        if (!empty($location)) {
            echo '<div class="product-location">Location: '.$location.'</div>';
        }
    }
}

In a custom template #

If you’re making more than just this modification in the template, you may find it easier /more convenient to create a custom template and insert the code directly into it. Here’s what you can use in that case (replace ‘Location’ with your custom field name):

<?php
if (!empty($item['product'])) {
    // replace 'Location' with your custom field name!
    $field_name = 'Location';
    $location = $item['product']->get_meta($field_name,true,'edit');
    if ( !empty($location) ) {
        echo '<div class="product-location">Location: '.$location.'</div>';
    }
}
?>

You can only insert this code into the items table.

Outside of the items table loop you can loop separately through the products:

<?php
// replace 'Location' with your custom field name!
$field_name = 'Location';
 
// then loop through items in order and print each custom field
foreach ( $this->order->get_items() as $item_id => $item ) {
    if ( $product = $this->order->get_product_from_item( $item ) ) {
        $location = $product->get_meta( $field_name );
        if ( !empty($location) ) {
            echo '<div class="product-location">Location: '.$location.'</div>';
        }
    }
}
?>