WooCommerce – Adding product category to order-details table


Here’s what I’m attempting to do and where.

In the check out process for an order, in the plug-in WooCommerce; you are taken to a page when the check out is process is complete. It displays an overview of the order details. The template file used to output this page is order-details.php.

Read More

Here’s what I’d like to add

I would like to display the product’s product category like so:

enter image description here

This is area of code I’m attempting to add to, the first section of the order details table.

<tbody>
    <?php
    if ( sizeof( $order->get_items() ) > 0 ) {

        foreach( $order->get_items() as $item ) {
            $_product     = apply_filters( 'woocommerce_order_item_product', $order->get_product_from_item( $item ), $item );
            $item_meta    = new WC_Order_Item_Meta( $item['item_meta'], $_product );

            ?>
            <tr class="<?php echo esc_attr( apply_filters( 'woocommerce_order_item_class', 'order_item', $item, $order ) ); ?>">
                <td class="product-name">
                    <?php
                        if ( $_product && ! $_product->is_visible() )
                            echo apply_filters( 'woocommerce_order_item_name', $item['name'], $item );
                        else
                            echo apply_filters( 'woocommerce_order_item_name', sprintf( '<a href="%s">%s</a>', get_permalink( $item['product_id'] ), $item['name'] ), $item );

                        echo apply_filters( 'woocommerce_order_item_quantity_html', ' <strong class="product-quantity">' . sprintf( '&times; %s', $item['qty'] ) . '</strong>', $item );

This is my understanding so far;

  • That a custom query is being applied.
  • That for each product listed details are being echoed.
  • That a WooCommerce Class is being used to get specific product meta.

My understandings are observations at my current knowledge level.

What I was hoping was that I could use something like

echo apply_filters( 'woocommerce_order_item_name', ' <strong class="product-category">' . e_( $item['product_cat'] ) . '</strong>', $item );

I can’t find a more relevant filter and I’m really not sure that [‘product_cat’] is even relevant here. This is an example of the way I’m attempting to solve my requirement.

As you can tell, I don’t work in PHP full time. I’m learning as much as I can when I can. Advise would be greatly appreciated

Related posts

Leave a Reply

1 comment

  1. This is how you might add the product categories to the Product title. I don’t particularly like how it is outputting for me, but then I am testing it on a variable subscription, so that is amending its own data. This would go in your theme’s functions.php

    function kia_woocommerce_order_item_name( $name, $item ){
    
        $product_id = $item['product_id'];
        $tax = 'product_cat';
    
        $terms = wp_get_post_terms( $product_id, $tax, array( 'fields' => 'names' ) );
    
        if( $terms && ! is_wp_error( $terms )) {
            $taxonomy = get_taxonomy($tax);
            $name .= '<label>' . $taxonomy->label . ': </label>' . implode( ', ', $terms );
        }
    
        return $name;
    }
    add_filter( 'woocommerce_order_item_name', 'kia_woocommerce_order_item_name', 10, 2 );
    

    Otherwise you could copy the order-details.php template into your own theme (so yourtheme/woocommerce/order/order-details.php and add the code directly. This would give you more control over where you want the category to appear since there aren’t a lot of hooks available in this section, but put you at risk if WooCommerce ever modifies this code. I have worked on a few sites that broke because the the theme was using outdated template.

    Any way, an example would be:

    <?php
    /**
     * Order details
     *
     * @author      WooThemes
     * @package     WooCommerce/Templates
     * @version     2.2.0
     */
    
    if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
    
    global $woocommerce;
    
    $order = new WC_Order( $order_id );
    ?>
    <h2><?php _e( 'Order Details', 'woocommerce' ); ?></h2>
    <table class="shop_table order_details">
        <thead>
            <tr>
                <th class="product-name"><?php _e( 'Product', 'woocommerce' ); ?></th>
                <th class="product-total"><?php _e( 'Total', 'woocommerce' ); ?></th>
            </tr>
        </thead>
        <tfoot>
        <?php
            if ( $totals = $order->get_order_item_totals() ) foreach ( $totals as $total ) :
                ?>
                <tr>
                    <th scope="row"><?php echo $total['label']; ?></th>
                    <td><?php echo $total['value']; ?></td>
                </tr>
                <?php
            endforeach;
        ?>
        </tfoot>
        <tbody>
            <?php
            if ( sizeof( $order->get_items() ) > 0 ) {
    
                foreach( $order->get_items() as $item ) {
                    $_product     = apply_filters( 'woocommerce_order_item_product', $order->get_product_from_item( $item ), $item );
                    $item_meta    = new WC_Order_Item_Meta( $item['item_meta'], $_product );
    
                    ?>
                    <tr class="<?php echo esc_attr( apply_filters( 'woocommerce_order_item_class', 'order_item', $item, $order ) ); ?>">
                        <td class="product-name">
                            <?php
                                if ( $_product && ! $_product->is_visible() )
                                    echo apply_filters( 'woocommerce_order_item_name', $item['name'], $item );
                                else
                                    echo apply_filters( 'woocommerce_order_item_name', sprintf( '<a href="%s">%s</a>', get_permalink( $item['product_id'] ), $item['name'] ), $item );
    
                                echo apply_filters( 'woocommerce_order_item_quantity_html', ' <strong class="product-quantity">' . sprintf( '&times; %s', $item['qty'] ) . '</strong>', $item );
    
                                $item_meta->display();
    
                                // insert product category here
                                $tax = 'product_cat';
                                $terms = wp_get_post_terms( $_product->id, $tax, array( 'fields' => 'names' ) );
    
                                if( $terms && ! is_wp_error( $terms )) {
                                    $taxonomy = get_taxonomy($tax);
                                    echo '<strong>' . $taxonomy->label . ': </strong>' . implode( ', ', $terms );
                                }
    
                                // end edit
    
                                if ( $_product && $_product->exists() && $_product->is_downloadable() && $order->is_download_permitted() ) {
    
                                    $download_files = $order->get_item_downloads( $item );
                                    $i              = 0;
                                    $links          = array();
    
                                    foreach ( $download_files as $download_id => $file ) {
                                        $i++;
    
                                        $links[] = '<small><a href="' . esc_url( $file['download_url'] ) . '">' . sprintf( __( 'Download file%s', 'woocommerce' ), ( count( $download_files ) > 1 ? ' ' . $i . ': ' : ': ' ) ) . esc_html( $file['name'] ) . '</a></small>';
                                    }
    
                                    echo '<br/>' . implode( '<br/>', $links );
                                }
                            ?>
                        </td>
                        <td class="product-total">
                            <?php echo $order->get_formatted_line_subtotal( $item ); ?>
                        </td>
                    </tr>
                    <?php
    
                    if ( $order->has_status( array( 'completed', 'processing' ) ) && ( $purchase_note = get_post_meta( $_product->id, '_purchase_note', true ) ) ) {
                        ?>
                        <tr class="product-purchase-note">
                            <td colspan="3"><?php echo wpautop( do_shortcode( $purchase_note ) ); ?></td>
                        </tr>
                        <?php
                    }
                }
            }
    
            do_action( 'woocommerce_order_items_table', $order );
            ?>
        </tbody>
    </table>
    
    <?php do_action( 'woocommerce_order_details_after_order_table', $order ); ?>
    
    <header>
        <h2><?php _e( 'Customer details', 'woocommerce' ); ?></h2>
    </header>
    <dl class="customer_details">
    <?php
        if ( $order->billing_email ) echo '<dt>' . __( 'Email:', 'woocommerce' ) . '</dt><dd>' . $order->billing_email . '</dd>';
        if ( $order->billing_phone ) echo '<dt>' . __( 'Telephone:', 'woocommerce' ) . '</dt><dd>' . $order->billing_phone . '</dd>';
    
        // Additional customer details hook
        do_action( 'woocommerce_order_details_after_customer_details', $order );
    ?>
    </dl>
    
    <?php if ( ! wc_ship_to_billing_address_only() && $order->needs_shipping_address() && get_option( 'woocommerce_calc_shipping' ) !== 'no' ) : ?>
    
    <div class="col2-set addresses">
    
        <div class="col-1">
    
    <?php endif; ?>
    
            <header class="title">
                <h3><?php _e( 'Billing Address', 'woocommerce' ); ?></h3>
            </header>
            <address><p>
                <?php
                    if ( ! $order->get_formatted_billing_address() ) _e( 'N/A', 'woocommerce' ); else echo $order->get_formatted_billing_address();
                ?>
            </p></address>
    
    <?php if ( ! wc_ship_to_billing_address_only() && $order->needs_shipping_address() && get_option( 'woocommerce_calc_shipping' ) !== 'no' ) : ?>
    
        </div><!-- /.col-1 -->
    
        <div class="col-2">
    
            <header class="title">
                <h3><?php _e( 'Shipping Address', 'woocommerce' ); ?></h3>
            </header>
            <address><p>
                <?php
                    if ( ! $order->get_formatted_shipping_address() ) _e( 'N/A', 'woocommerce' ); else echo $order->get_formatted_shipping_address();
                ?>
            </p></address>
    
        </div><!-- /.col-2 -->
    
    </div><!-- /.col2-set -->
    
    <?php endif; ?>
    
    <div class="clear"></div>