上一篇文章描述了如何在WooCommerce中创建自定义邮件模板,这个模板可以定制成任何样子,如果用发送邮件的方法来查看样式就太累了,所以这篇文章要讲述如何在后台添加一个浏览器里预览的功能。

本文源代码:预览自定义模板 已下载 210 次

添加preview方法

首先给定义好的CP_Custom_Order_Email class增加preview方法,其实就是trigger方法的复制。trigger先获取内容再发送邮件,preview只需要将内容返回即可。

function preview( $order_id ){
    if ( $order_id ) {
        $this->object                  = wc_get_order( $order_id );
        
        $this->find['order-date']      = '{order_date}';
        $this->find['order-number']    = '{order_number}';
        
        $this->replace['order-date']   = date_i18n( wc_date_format(), strtotime( $this->object->order_date ) );
        $this->replace['order-number'] = $this->object->get_order_number();
    }
    
    return $this->get_content();
}

在邮件设置页面增加预览按钮

要做到这样的效果

preview-template

在选项和HTML template之前加一个“预览邮件”的选项。点击预览模板的按钮就会打开新窗口显示邮件。邮件的内容是最新的真实订单,当然你可以做一个选择订单的功能,本文为了简化问题就直接调用最新的订单。

这部分代码将不会加到CP_Custom_Order_Email这个class中,因为这个class只在特定情况下加载,而我希望的预览地址是yoursite.com/?wc-custom-email-preview=1这种,所以代码如下

1. 添加预览按钮

代码加到邮件选项之后,我想woocommerce_email_settings_after这个action名称已经表述的相当清楚。

function cp_custom_order_email_preview_section( $email ){
    if( $email->id == 'cp_custom_order' ){
        $preview_url = wp_nonce_url( home_url('?wc-custom-email-preview=1'), 'wc-custom-email-preview', 'wc-preview-nonce' );
        echo '<h4>'.__( '预览邮件' ).'</h4>';
        echo '<p>使用最近的真实订单预览邮件模板 <a href="'.$preview_url.'" class="button" style="margin-left:10px;" target="_blank">预览模板</a></p>';
    }
}

add_action( 'woocommerce_email_settings_after',     'cp_custom_order_email_preview_section' );

2. 处理预览请求

function cp_custom_order_email_preview_handler(){
    // 检查get参数
    if( isset( $_REQUEST['wc-custom-email-preview'] ) && $_REQUEST['wc-custom-email-preview'] == 1 ){
        //检查用户权限
        if( is_user_logged_in() && current_user_can( 'manage_options') ){
            //检查wp nonce
            if ( isset( $_GET['wc-preview-nonce'] ) && wp_verify_nonce( $_GET['wc-preview-nonce'], 'wc-custom-email-preview' ) ){

                //获取最新订单
                $customer_orders = get_posts( array(
                    'posts_per_page' => 1,
                    'post_type'      => 'shop_order',
                    'post_status'    => array( 'wc-processing', 'wc-completed' )
                ) );
               

                if( empty( $customer_orders ) ){

                    wp_die( '<strong>无法预览</strong>: 请先创建一个订单');

                } else {

                    //调用preview方法获取模板html
                    $order_id = $customer_orders[0]->ID;
                    $emails   = WC_Emails::instance()->emails;
                    $email    = $emails['CP_Custom_Order_Email'];
                    $message  = $email->preview( $order_id );

                    //给html代码应用WooCommerce邮件样式并输出
                    echo $email->style_inline( $message );
                    exit;
                }                
            }            
        } 
    }    
}
  1. 检查参数、用户权限和WordPress nonce,都正确则开始获取最近的订单
  2. 订单也是post,所以用get_posts就能获取,只后去状态是processing或completed的订单
  3. 有了订单ID,就调用preview方法,最后的style_inline是调用了WooCommerce集成的Emogrifier库来格式化邮件,不明白可以看这篇文章

预览效果

preview-template-in

15条留言

  1. 抱歉,因为先前的文章关闭了评论,在这里讨论一下:

    PayPal 的 PayPal Identity Token,在申请设置的时候,需要将自动返回开启,并填写「返回 URL」,这个返回 URL 我觉得应该是动态的,每次不同的,那么具体要填什么呢?是 domain.com/check-out/order-received/ 吗?还是?

    1. 我按照 WC 官方文档 https://docs.woothemes.com/document/paypal-standard/ 的描述,填写了 xxx.com/check-out/order-received/ 试了好几次,都是浅黄色提示「我们无法验证您输入的URL。请检查您输入的内容,然后重试。」而链接是可以打开「已经收到您的订单」的页面的。
      按文档添加 IPN 为 http://example.com/?wc-api=WC_Gateway_Paypal 也是相同的黄色提示。如果直接打开的话,是「PayPal IPN Request Failure」。

    2. 不是太明白为何要写paypal的返回地址,这个woocommerce不是处理好了吗?
      返回地址确实是动态的,要带一些订单的东西,所以绝不可能去paypal网站填写,要在自己站点动态生成这个地址再传给paypal,一般由集成paypal的插件来解决,不需要自己填写。

      xxx.com/check-out/order-received/是订单已收到页面,没有订单信息时默认显示谢谢,没有任何实际作用。

      1. 因为 WC 内需要填写 Identity Token,填了这个就会回调的。但是申请 Identity Token 的时候,网页上需要输入返回 URL。WC 的官方文档也有说明,写的那个地址。但是我填进去,就返回浅黄色提示。另一个是 IPN 的通告 URL,也是返回相同提示。

        1. 你用的paypal不是woocommerce自带那个是吗。我记得identity token是给paypal PDT使用的,那么申请的时候填网站地址就可以了,真正付款时并不用这个地址。

          1. 这样的话每次看到 PayPal 付款的用户,都要亲自打开 PayPal 查看他是否付款了,而不会接到自动提醒,很麻烦的。WC 官方文档 https://docs.woothemes.com/document/paypal-standard/ 中说明的是 domain.com/check-out/order-received/ 但是输入一直提示错误。

        2. PS.我没用过真正的paypal PDT,只是开发时用过paypal sandobx的,记得当时就是随便填了个地址,重要的是有identity token,你说的是你无法申请到这个token吧。不知道实际账户和sandbox是否有区别,所以上面说的你只能试一下,我也不是太清楚。

          另外你要到woocommerce系统选项卡下看一看wp_remote_post是否能用,没这个PDT不能工作。

        3. 另外PDT只是IPN的有益补充,就算你不输入identity token,IPN也应该能更新订单状态,不可能出现用户付款了woocommerce还不知道的情况。真是这样你就要看看插件是不是有问题了。

          1. IPN 输入的时候,也是提示相同的浅黄色提示。也就是说,WC 完全不知道,付完款了还是保留的状态。那么我只能手动打开 PayPal 看了。

        4. 付款了wc还不知道那等于没集成paypal。自带的paypal付款你试了吗,那个是最简单得ipn,要是不行就是你服务器有问题,比如拦截了paypal请求。
          你用了付费插件,如果插件的server要求都满足了还不行,只能问作者了。

          1. 我用的是 WC 自带的 PayPal,按照你的方法,添加了两段函数,在人民币下启用了。没有使用第三方插件。并且 API 均有填写。差 Token、PIN。

      2. 我尝试了流程操作,的确我付完款后,WC 仍然是保留状态,不能识别为处理中。

    3. Identity token用于PDT(付款数据传输), API用于退款,两者皆为可选项目,不填不会影响paypal付款和订单状态更新,所以不要再想去paypal看状态的事,找自己服务器的问题。

      首先,去WooCommerce->系统状态下查看WordPress环境和Server环境,确保没有不符合要求的项目。
      其次,查看paypal的log记录,确保服务器有收到请求。记录位置wp-content/uploads/wc-logs/paypal-xxxxxxxx.log。
      最后,请用在线服务器测试,本地server肯定不行。

      如果问题依旧无法解决,还想问我的话,请提供更详细的信息,最好有在线站地址。

  2. 您好 想请教一下 我用的是 woocommerce 构架的商城,但是客户在进入支付页面的时候 即PAYPal 的时候出现中文页面 导致客户无法进行付款,这种一般什么情况啊,我用的是全部英文版wordpress , 不知道你有没有遇到过这种情况 谢谢

    1. 你说的付款是自己站点选择支付方式页面,还是跳转到paypal后的页面?中文页面如何导致客户无法付款的,报了什么错误吗?

发表评论

电子邮件地址不会被公开。 必填项已用*标注