WordPress 中的商店組合外掛 WooCommerce ,預設安裝好就有一個公版架構,大部分流程其實沒有什麼問題,結帳(Checkout)頁欄位想要調整成台灣常見的表單欄位(含郵遞區號自動選擇)可以參考之前寫過的 文章

本篇文章針對進階的互動程式多一點筆記。而既然提到互動程式設計,就會是 AJAX 導向架構為主。

WooCommerce 有提供兩個片段事件可以使用:woocommerce_add_to_cart_fragmentswoocommerce_update_order_review_fragments

woocommerce_add_to_cart_fragments

處理的互動:

  • 加入購物車(Cart)時,後端可以接手處理的事件
  • 更新購物車數量時的也使用此事件

woocommerce_update_order_review_fragments

處理的互動:

  • 更新結帳頁面欄位資訊
  • 更新結帳頁面訂單總覽

為何稱為「片段」事件?

因為這些互動的方法只會在前端觸發,後端執行完後返回前端更新「部分畫面」。回傳格式如下:

{
"fragments":{"CSS SELECTOR HERE":"HTML CODE HERE"},
"cart_hash":"5d3480ef551b1641ecec0c442546e230"
}

fragments 中是一個 key:value 格式的組合, key 為前端 CSS 選擇器參數, value 則為選擇到元件後要做替換的 HTML 程式。意思就是把資料透過 AJAX 方式傳送回後端後,再由後端計算過,包裝成新的一段 HTML 元件塞回前端畫面。

互動時的工具和方法有什麼?

前端 JavaScript 可以綁定操作物件事件,並在確定要與後端通知更新時使用更新方法送值回後端。

結帳頁面: jQuery(document.body).trigger("update_checkout");

購物車頁面: jQuery(document.body).trigger("wc_update_cart");

結帳頁面發送到後端的結構也有一定格式,如果有客製化欄位的部分可以透過 $_POST['post_data'] 參數取得,取得資料後的操作如果有保存需求,可以使用 WC()->session->set('key', $value)WC()->session->get('key') 兩個方法搭配存取值。而讀取結帳欄位的方法為 WC()->checkout->checkout_fields ,根據條件修改過的結帳欄位需要使用 woocommerce_form_field($key, $field, WC()->session->get('key')) 方法來產生對應欄位的 HTML 結構。

結帳頁面中捕捉欄位事件有兩個是預設綁定事件:國家、郵遞區號

國家的下拉選單比較特別,捕捉事件方法可以參考(包含運送區塊的選單): jQuery('select#billing_country, select#shipping_country').change(function(){});

下面以儲存結帳欄位為例:

function save_data_before_open_new_page($value) {
    $data = $_POST['post_data'];
    parse_str(html_entity_decode($data), $pdata);
    if (isset($pdata['billing_first_name']) && $pdata['billing_first_name'] != "") {
        WC()->session->set('billing_first_name', $pdata['billing_first_name']);
    }
    if (isset($pdata['billing_phone']) && $pdata['billing_phone'] != "") {
        WC()->session->set('billing_phone', $pdata['billing_phone']);
    }
    if (isset($pdata['billing_company']) && $pdata['billing_company'] != "") {
        WC()->session->set('billing_company', $pdata['billing_company']);
    }
    if (isset($pdata['billing_email']) && $pdata['billing_email'] != "") {
        WC()->session->set('billing_email', $pdata['billing_email']);
    }
    $value['#billing_first_name'] = '<input type="text" class="input-text " name="billing_first_name" id="billing_first_name" placeholder="請填入最多中文5個字或英文10個字" value="' . WC()->session->get('billing_first_name') . '" autocomplete="given-name" autofocus="autofocus">';
    $value['#billing_phone'] = '<input type="tel" class="input-text " name="billing_phone" id="billing_phone" placeholder="手機號碼格式為:0912345678" value="' . WC()->session->get('billing_phone') . '" autocomplete="tel">';
    $value['#billing_company'] = '<input type="text" class="input-text " name="billing_company" id="billing_company" placeholder="" value="' . WC()->session->get('billing_company') . '" autocomplete="organization">';
    $value['#billing_email'] = '<input type="email" class="input-text " name="billing_email" id="billing_email" placeholder="" value="' . WC()->session->get('billing_email') . '" autocomplete="email">';
    return $value;
}
add_filter('woocommerce_update_order_review_fragments', 'save_data_before_open_new_page', 10, 1);

Gist: Link

結語

購物行為是很講求順暢的,為此要達成目地需要的組合技巧也不少。完成客製化的方式有很多,舉凡自己寫過 API 後端來跟前端互動,或是整個包過介面處理一頁式結帳等等的作法都好,如果能夠不要大規模重寫,多了解一點 WooCommerce 本身的設計架構,嘗試多使用事件設計整合,更能確保在日後升級可以延續體驗。

雖然 WooCommerce 正在接受市場考驗,版本快速更新,但花點時間跟進這產品的發展也是有助於增長自己程式設計經驗與市場動向,完全是雙贏!

參考資料

Facebook 外掛功能


Share:

作者: Chun

資訊愛好人士。主張「人人都該為了偷懶而進步」。期許自己成為斜槓到變進度條 100% 的年輕人。[//////////____30%_________]

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *