自定义WooCommerce Order Details模板明细部分(2021)

优质
小牛编辑
131浏览
2023-12-01

默认的WooCommerce Order Details模板的明细只显示产品名称、购买数量和总价,如果你想显示更详细的信息,或者修改显示格式,让数据更清晰,那就需要修改订单详情的模板。注意,这个修改也会影响结账后显示的“Order Received”页面。

目标

我们的目标是把图一变为图二。本文用到了文章WooCommerce Class WC_Order中提到的方法。

WooCommerce Order Details默认模板图一:默认的order details模板修改后的模板图二:修改后的order details模板

修改WooCommerce Order Details模板的方法

我们用覆盖WooCommerce模板的方法来定制,将order-details.phporder-details-item.php两个文件拷贝到主题/woocommerce/order目录下,目录不存在手动创建一下。

参考了后台界面的代码:woocommerce/includes/admin/meta-boxes/views/html-order-item.php

修改order-details.php

这个文件我们主要修改明细表单的表头,找到表头部分:

<thead>
	<tr>
		<th><?php esc_html_e( 'Product', 'woocommerce' ); ?></th>
		<th><?php esc_html_e( 'Total', 'woocommerce' ); ?></th>
	</tr>
</thead>

替换为如下代码,增加了Quantity、Cost、Tax字段。

<thead>
	<tr>
		<th><?php esc_html_e( 'Product', 'woocommerce' ); ?></th>
		<th><?php esc_html_e( 'Quantity', 'woocommerce' ); ?></th>
		<th><?php esc_html_e( 'Cost', 'woocommerce' ); ?></th>
		<th><?php esc_html_e( 'Total', 'woocommerce' ); ?></th>
		<?php
		$order_taxes = $order->get_taxes();
		if ( ! empty( $order_taxes ) ) :
			foreach ( $order_taxes as $tax_id => $tax_item ) :
				$tax_class      = wc_get_tax_class_by_tax_id( $tax_item['rate_id'] );
				$tax_class_name = isset( $classes_options[ $tax_class ] ) ? $classes_options[ $tax_class ] : __( 'Tax', 'woocommerce' );
				$column_label   = ! empty( $tax_item['label'] ) ? $tax_item['label'] : __( 'Tax', 'woocommerce' );
				/* translators: %1$s: tax item name %2$s: tax class name  */
				$column_tip = sprintf( esc_html__( '%1$s (%2$s)', 'woocommerce' ), $tax_item['name'], $tax_class_name );
				?>
				<th>
					<?php echo esc_attr( $column_label ); ?>
				</th>
				<?php
			endforeach;
		endif;
		?>
	</tr>
</thead>

修改order-details-item.php

这个文件要大改一下,代码如下。

<?php
/**
 * Order Item Details
 *
 * This template can be overridden by copying it to yourtheme/woocommerce/order/order-details-item.php.
 *
 * HOWEVER, on occasion WooCommerce will need to update template files and you
 * (the theme developer) will need to copy the new files to your theme to
 * maintain compatibility. We try to do this as little as possible, but it does
 * happen. When this occurs the version of the template file will be bumped and
 * the readme will list any important changes.
 *
 * @see https://docs.woocommerce.com/document/template-structure/
 * @package WooCommerce\Templates
 * @version 5.2.0
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

if ( ! apply_filters( 'woocommerce_order_item_visible', true, $item ) ) {
	return;
}
?>
<tr>

	<td>
		<?php
		$is_visible        = $product && $product->is_visible();
		$product_permalink = apply_filters( 'woocommerce_order_item_permalink', $is_visible ? $product->get_permalink( $item ) : '', $item, $order );

		// Product title
		echo wp_kses_post( apply_filters( 'woocommerce_order_item_name', $product_permalink ? sprintf( '<a href="%s">%s</a>', $product_permalink, $item->get_name() ) : $item->get_name(), $item, $is_visible ) );

		// Product sku
		if ( $product && $product->get_sku() ) {
			echo '<div><strong>' . esc_html__( 'SKU:', 'woocommerce' ) . '</strong> ' . esc_html( $product->get_sku() ) . '</div>';
		}

		do_action( 'woocommerce_order_item_meta_start', $item_id, $item, $order, false );

		wc_display_item_meta( $item ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped

		do_action( 'woocommerce_order_item_meta_end', $item_id, $item, $order, false );
		?>
	</td>

	<!-- Product Quantity -->
	<td>
		<?php
		$qty          = $item->get_quantity();
		$refunded_qty = $order->get_qty_refunded_for_item( $item_id );

		echo '<small>&times;</small> ' . esc_html( $item->get_quantity() );

		$refunded_qty = $order->get_qty_refunded_for_item( $item_id );

		if ( $refunded_qty ) {
			echo '<small style="color:red;"><br>Refunded: -' . esc_html( $refunded_qty * -1 ) . '</small>';
		}

		?>
	</td><!-- End Product Quantity -->

	<!-- Product Cost -->
	<td>
		<?php
		echo wc_price( $order->get_item_subtotal( $item, false, true ), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		?>
	</td>

	<!-- Product Total -->
	<td>
		<?php 
			echo $order->get_formatted_line_subtotal( $item ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 

			if ( $item->get_subtotal() !== $item->get_total() ) {
				/* translators: %s: discount amount */
				echo '<span>' . sprintf( esc_html__( '%s discount', 'woocommerce' ), wc_price( wc_format_decimal( $item->get_subtotal() - $item->get_total(), '' ), array( 'currency' => $order->get_currency() ) ) ) . '</span>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			}

			$refunded = $order->get_total_refunded_for_item( $item_id );

			if ( $refunded ) {
				echo '<small style="color:red;"><br>Refunded: -' . wc_price( $refunded, array( 'currency' => $order->get_currency() ) ) . '</small>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			}
		?>
	</td><!-- End Product Total -->

	<!-- Product Taxes -->
	<?php
	$tax_data = wc_tax_enabled() ? $item->get_taxes() : false;
	if ( $tax_data ) {
		$order_taxes       = $order->get_taxes();
		foreach ( $order_taxes as $tax_item ) {

			$tax_item_id       = $tax_item->get_rate_id();
			$tax_item_total    = isset( $tax_data['total'][ $tax_item_id ] ) ? $tax_data['total'][ $tax_item_id ] : '';
			$tax_item_subtotal = isset( $tax_data['subtotal'][ $tax_item_id ] ) ? $tax_data['subtotal'][ $tax_item_id ] : '';

			if ( '' !== $tax_item_subtotal ) {
				$round_at_subtotal = 'yes' === get_option( 'woocommerce_tax_round_at_subtotal' );
				$tax_item_total    = wc_round_tax_total( $tax_item_total, $round_at_subtotal ? wc_get_rounding_precision() : null );
				$tax_item_subtotal = wc_round_tax_total( $tax_item_subtotal, $round_at_subtotal ? wc_get_rounding_precision() : null );
			}
			?>
			<td>
				<?php
				if ( '' !== $tax_item_total ) {
					echo wc_price( wc_round_tax_total( $tax_item_total ), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
				} else {
					echo '&ndash;';
				}

				$refunded = $order->get_tax_refunded_for_item( $item_id, $tax_item_id );

				if ( $refunded ) {
					echo '<small style="color:red"><br>Refunded: -' . wc_price( $refunded, array( 'currency' => $order->get_currency() ) ) . '</small>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
				}
				?>
			</td>
			<?php
		}
	}
	?><!-- End Product Taxes -->	
</tr>

<?php if ( $show_purchase_note && $purchase_note ) : ?>

<tr>

	<td colspan="2"><?php echo wpautop( do_shortcode( wp_kses_post( $purchase_note ) ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></td>

</tr>

<?php endif; ?>

修改成功后,就能看到图二的样子了。除了增加了额外字段,还略微修改了退款的显示方式,让退款更明显。