Search code examples
wordpresswoocommerceproductordersemail-notifications

Changing the position of the product image in WooCommerce email notifications


Based on Display the product image in Woocommerce email notifications answer code I wrote the following to display the product image in WooCommerce email notifications.

add_filter( 'woocommerce_email_order_items_args', 'custom_email_order_items_args', 10, 1 );
function custom_email_order_items_args( $args ) {
    $args['show_image'] = true;
    $args['image_size'] = array( 32, 32 );
     $args['show_sku'] = true;

    return $args;
    
}
add_filter( 'woocommerce_order_item_thumbnail', 'add_email_order_item_permalink', 10, 2 ); // Product image
add_filter( 'woocommerce_order_item_name', 'add_email_order_item_permalink', 10, 2 ); // Product name
function add_email_order_item_permalink( $output_html, $item, $bool = false ) {
    // Only email notifications
    if( is_wc_endpoint_url() )
        return $output_html;

    $product   = $item->get_product();

    return '<a href="'.esc_url( $product->get_permalink() ).'">' . $output_html . '</a>';
}
function cw_edit_order_item_name( $name ) {
    $name = '<br><br/>' .$name;
    return $name . '<br><br /><center><strong>SKU:</strong></center>';
}
add_filter( 'woocommerce_order_item_name', 'cw_edit_order_item_name' );

I have this problem with the WooCommerce order item table within the order emails that the product thumbnail needs to be moved to the left of the product title, and the title should fit neatly in to the right.

We would have to change the width of the order item tables columns so this fits in nicely. This also needs to be mobile responsive.

Here is a screenshot of exactly what I am trying to achieve:

What I Need

And this is what I have:

enter image description here

Things to consider,

  • SKU Must be displayed
  • Link to the product must be included
  • The Columns need to be wider.

I will really appreciate any help here.


Solution

  • You can solve your problem in several ways.

    To understand my answer I copied/pasted the piece of code responsible for the output in the emails from templates/emails/email-order-items.php line 33 - 58 @version 3.7.0

    if ( is_object( $product ) ) {
        $sku           = $product->get_sku();
        $purchase_note = $product->get_purchase_note();
        $image         = $product->get_image( $image_size );
    }
    
    <tr class="<?php echo esc_attr( apply_filters( 'woocommerce_order_item_class', 'order_item', $item, $order ) ); ?>">
        <td class="td" style="text-align:<?php echo esc_attr( $text_align ); ?>; vertical-align: middle; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif; word-wrap:break-word;">
        <?php
    
        // Show title/image etc.
        if ( $show_image ) {
            echo wp_kses_post( apply_filters( 'woocommerce_order_item_thumbnail', $image, $item ) );
        }
    
        // Product name.
        echo wp_kses_post( apply_filters( 'woocommerce_order_item_name', $item->get_name(), $item, false ) );
    
        // SKU.
        if ( $show_sku && $sku ) {
            echo wp_kses_post( ' (#' . $sku . ')' );
        }
    
        // allow other plugins to add additional product information here.
        do_action( 'woocommerce_order_item_meta_start', $item_id, $item, $order, $plain_text );
    
    • As you can see, if $show_image is true, the product image will be displayed. By default this is false, but this can be changed via the woocommerce_email_order_items_args filter hook.

    • The product name is displayed by default, but not as a link

    • The display of the sku is/can also determined via the woocommerce_email_order_items_args filter hook (by default false), however there is no option to add HTML tags to the output of the sku

    So you could use a few different filter hooks to place the values ​​from false to true as well as adding extra HTML to the output (except the sku). So this would only be partially controllable/adaptable.

    However, on the last line we find the woocommerce_order_item_meta_start action hook. Which allow other plugins to add additional product information. So we're going to use that hook, because it can hold/modify anything the previous filter hooks would contain.


    So you get:

    // Displayed by default, so hide!
    function filter_woocommerce_order_item_name( $item_name, $item, $false ) {
        // Only email notifications
        if ( is_wc_endpoint_url() ) return $item_name;
        
        $item_name = '';
    
        return $item_name;
    }
    add_filter( 'woocommerce_order_item_name', 'filter_woocommerce_order_item_name', 10, 3 );
    
    // NEW OUTPUT
    function action_woocommerce_order_item_meta_start( $item_id, $item, $order, $plain_text ) {
        // Only email notifications
        if ( is_wc_endpoint_url() ) return; 
    
        // Settings
        $image_size = array( 64, 64 );
        
        // Get product
        $product = $item->get_product();
        
        if ( is_object( $product ) ) {
            $sku    = $product->get_sku();
            $image  = $product->get_image( $image_size );
        }
        
        // OUTPUT
        
        // Show image
        echo '<span style="float:left;width: fit-content;">' . $image. '</span>';
    
        // Product name + link + SKU (if set).
        if ( $sku ) {
            echo '<span><a href="' . esc_url( $product->get_permalink() ). '">' . $item->get_name() . ' (#' . $sku . ')' . '</a></span>';
        } else {
            echo '<span><a href="' . esc_url( $product->get_permalink() ). '">' . $item->get_name() . '</a></span>';        
        }
    }
    add_action( 'woocommerce_order_item_meta_start', 'action_woocommerce_order_item_meta_start', 10 , 4 );
    

    RESULT

    enter image description here

    NOTE: by adjusting the HTML with accompanying CSS in my answer, you can fully adjust the output to your wishes