向 Woocommerce 发送的电子邮件添加元素的最佳实践

Best practice to add elements to email sent by Woocommerce

我是 Woocommerce 的新手,我知道很多语言......除了 PHP!此外,我不太了解 Wordpress 挂钩和回调的工作原理,所以对于我想完成的任务,我很迷茫。

我唯一想做的就是在订单完成后发送的电子邮件中添加一个二维码。

我首先理解的是我必须覆盖文件 customer-completed-order.php 并将其放在我的主题文件夹中。

事实是,这个文件是这样的:

<?php
/**
 * Customer completed order email
 *
 * This template can be overridden by copying it to yourtheme/woocommerce/emails/customer-completed-order.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\Emails
 * @version 3.7.0
 */

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

/*
 * @hooked WC_Emails::email_header() Output the email header
 */
do_action( 'woocommerce_email_header', $email_heading, $email ); ?>
s

<?php /* translators: %s: Customer first name */ ?>
<p><?php printf( esc_html__( 'Hi %s,', 'woocommerce' ), esc_html( $order->get_billing_first_name() ) ); ?></p>
<p><?php esc_html_e( 'We have finished processing your order.', 'woocommerce' ); ?></p>
<?php

/*
 * @hooked WC_Emails::order_details() Shows the order details table.
 * @hooked WC_Structured_Data::generate_order_data() Generates structured data.
 * @hooked WC_Structured_Data::output_structured_data() Outputs structured data.
 * @since 2.5.0
 */
do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email );

/*
 * @hooked WC_Emails::order_meta() Shows order meta data.
 */
do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email );

/*
 * @hooked WC_Emails::customer_details() Shows customer details
 * @hooked WC_Emails::email_address() Shows email address
 */
do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email );



/**
 * Show user-defined additional content - this is set in each email's settings.
 */
if ( $additional_content ) {
    echo wp_kses_post( wpautop( wptexturize( $additional_content ) ) );
}

/*
 * @hooked WC_Emails::email_footer() Output the email footer
 */
do_action( 'woocommerce_email_footer', $email );

好像不是添加我的回调的地方。我所做的是将此代码添加到我主题中的 functions.php 中,我想知道它是否合适,以及我的代码是否也可以接受(为简单起见,我没有使用 QR 码现在):

add_action( 'woocommerce_email_before_order_table', 'add_qr_code_to_email', 20, 4 );
  
function add_qr_code_to_email( $order, $sent_to_admin, $plain_text, $email ) {
   if ( $email->id == 'customer_completed_order' ) {
      echo '<h2 class="email-upsell-title">Get 20% off</h2><p class="email-upsell-p">Thank you for making this purchase! Come back and use the code "<strong>Back4More</strong>" to receive a 20% discount on your next purchase! Click here to continue shopping.</p>';
   }
}

最后,我的最后一个问题是(这不是最重要的):它为什么有效?我认为必须在 customer-completed-order.php 中使用“do_action”“调用回调”,但似乎我的函数仍被调用

  1. 没错。您不向模板文件添加函数。您在 functions.php 添加它们,然后从模板 运行 添加它们。

  2. 您的代码似乎没问题。一种常见的方法是创建不同的文件并将它们导入到您的 functions.php 中。但这是为了更容易维护和可读性。您可以在 this repo

    中查看如何完成此操作的示例
  3. 它为什么起作用?这实际上是最重要的问题,因为它是理解 WP 和 WC 开发如何工作的关键。


如果您仔细查看您正在覆盖的文件,它几乎只是输出 markup/content 并执行 WooCommerce 内置的操作 (do_action)。

我建议阅读文档(见末尾的链接),但要用简单的术语回答你的问题:

Actions 允许我们 运行 在执行 WordPress 核心、插件和主题的特定点上发挥作用。换句话说,Action Hook 是 Wordpress 让我们能够扩展或修改核心功能的方式。

这些动作可以分配不同的回调函数。那些 回调 函数将 运行 当它们 挂钩 的操作是 运行.

所以回来,模板中的每个 do_action() 函数都是 运行ning 一个动作,它只是 运行 挂钩到它的所有函数(在这种情况下WooCommerce)。

因此,之所以有效,是因为您将 函数挂钩到 'woocommerce_email_before_order_table' 操作。

如果您阅读每个 do_action 上面的评论,它实际上说明了它们所吸引的内容。 'woocommerce_email_order_details' 操作的注释,在您的模板中,说它有 WC_Emails::order_details() 挂钩并且它输出顺序 table.

现在,该函数正在获取模板文件并进行渲染。您在代码中加入的操作是该模板中的 运行。 (请参阅 wp-content/plugins/woocommerce/includes/class-wc-emails.php 的第 403 行了解 Class 及其方法)。

希望我说得够清楚了。

已更新资源列表 以阅读更多内容:

P.s: Actions 是 WP 中 2 种挂钩类型中的一种。还有过滤器。