Drupal Commerce 概念架構

By tky, 19 七月, 2012

Commerce 是 Drupal 7.x 版本的一個模組包 (modules packages),用於建置 e-commerce 線上購物網站。這個模組包是由 Drupal 6.x 上面流行的同類型模組包 Ubercart 的作者跳槽開發的,詳情在最近要出版的翻譯書籍裏面有介紹,有興趣者可以去看看內容。

在今年2月開始,我本來使用網絡行動科技公司所協力開發的 Ubercart + Paypal 安裝包,替朋友的有機農場架設了一個線上銷售網站,但因為許多其他因素遲遲無法上線(設計的太醜、羞於見人也是主要的因素之一 XD)。其實就各方面的功能而言,Ubercart + Paypal 已經相當符合一個小型農產品零售商店的需求。只要設定好商店資訊、付款方式、運費等項目,再把產品上架,立即開店是真的做得到。然而兩件事情讓我轉念改用 Drupal 7.x Commerce 來重做同一個商務網站。

第一件事是我剛好在6月參與了 "Using Drupal" 第2版的中文翻譯工作。這一版的主要案例都是用 Drupal 7.x 作為基礎,裡頭的最後一章(第九章)則介紹了如何用 Commerce 來搭建一個小型商務網站。讀完該章之後,讓正在研究 Drupal 7.x 的我不禁腦門充血。這就像武林中人剛好獲得一本刀法秘笈加一把好刀一般,雖然以前是練劍的,哪有不立刻試練一下的道理?

第二件事情是最近也碰巧接到第一個 Drupal 7 的網站設定工作。邊摸邊學又邊翻譯書籍,讓我實際了解到 Drupal 7 中力推的 Entity(單元)概念與運作原理,也了解到它能夠大大超越以往 Content Type 概念的地方。如果要用一句話來總結的話,Entity 的出現代表了 Drupal 在內容管理和架構上做了一個相當徹底的反省,在設計上往更抽象與更普遍的層次推進,企圖滿足更廣泛的應用情況。光就這點而言,Drupal 7.x 的彈性和深度就不知多過 6.x多少倍。而 Commerce 吸引我的地方就在於它徹底發揮了 Entity 的概念,可以更輕易做到 Ubercart 所做不到的事情,滿足更多樣的商務需求(比方說讓客戶做自訂金額的線上「捐款」或訂購含有客戶自訂資訊的客製化商品)。

這兩件事情讓我在 Drupal 6.x Ubercart + Paypal 網站上線前夕臨時喊停,決心花時間好好研究 Commerce,將網站轉換成 Commerce 系統。

由於 Commerce 本就有很多轉換工具,加上有 Feeds 模組幫忙,將原有的商品匯入 Commerce 沒花多久的時間。但是總共花了一個多星期,才讓我把 Commerce 網站搭建成原本的樣子與功能。事後反省,主要的原因就在於我沒有徹底擺脫掉 Ubercart 6.x 中把商品當作是 node 來處理的思考方式,以至於一開始無法理解 Commerce 處理商品的作法,結果連個簡單的商品展示頁都做不出來,遑論加入購物車、結帳等後續步驟。

萬事起頭難,尤其是要擺脫過去的概念和習慣最難。過了起頭這一關,Commerce 後續的設定工作其實和 Ubercart 相去不遠(除了大量使用 Rules 模組這點之外 XD)。所以有個明確的 Commerce 概念架構,對於運用 Commerce 來說是非常重要的一件事情。為此,我把我所理解的 Commerce 商品概念架構圖示如左。

Commerce 特別之處就在於它並不把商品當作是一個個的node,而是一個特殊的 entity 類型:product entity,所以你沒有辦法在內容管理或內容類型管理那邊找到 product 或者 product node。此外,product entity 可以有更上一層的 type 區別,這讓你能夠根據不同商品類型所具有的不同性質,規劃不同的欄位,自訂出你想要的 product entity。比方說農產品就和衣物商品不一樣,銷售單位不同(斤/件),各種屬性也不一(品種/顏色、尺寸)。如果你要同時在店裡賣這兩種商品,就可以利用欄位的區別,規劃出不同 type 的 product entity。

接下來的部份是 Commerce 最令人感到複雜與困惑的地方:沒有 product node,那要怎麼顯示商品呢?Commerce 的作法是在內容類型那邊建立另一個 product display entity,然後透過 product reference 欄位關聯到 product entity 去。以這種方式,把 product entity 引入到 product display node中顯示。為啥要搞成這樣子呢?網路上的教學文章或影片都會用產品的型號和屬性之間的搭配來舉例子說明。比方說你的店裡有賣兩種T恤,型號不一樣:001是尖領、002是圓領。而這兩種型號的衣服都有不同尺寸(L、M、S)和顏色(黑、白、紅、藍)的區別。不同顏色和尺寸的T恤有不同的商品編號(SKU),按照編號的區分,每個型號的衣服實際上會有3×4=12種商品。而你有兩個型號,那就會有2×3×4=24種商品。如果你現在要編個圖片型錄告訴人家你這家店裡有賣什麼商品,你會把這24種商品全部列出來嗎?

當然不會。你只會列出001和002兩個T恤型號的代表圖片,然後在旁邊用小字告訴大家有顏色和尺寸的選擇。product display entity就是這種「代表型號」的概念,你可以把它想成一種「容器」,把實際上有不同商品編號、庫存量和屬性但實際上屬於同一型號的 product entity 裝在一起展示。當顧客在網站上點選 001 的T恤 noce 時,他會看到一個列出「尺寸」和「顏色」選單的node,當切換不同的尺寸和顏色搭配時,他可以立刻看到 node 中會切換不同的商品圖片。

如果你習慣 Ubercart 的操作模式,你可能會覺得這種作法有點多此一舉,甚至看不出這樣做有什麼意義。老實說,這部份就像是在實現 Ubercart 裡頭product node + attibute 的作法,而 Commerce 動用兩種 entity來搞定同一件事情,看來真的很大費周張。尤其是,如果你店裡的商品只有型號的區別而沒有屬性區別的時候,Commerce 這種「先建立商品再裝入商品呈現 node」的作法就顯得非常冗餘,因為這等於同一件事情得做兩次的感覺。

然而,仔細想一下,其實可以發覺 Commerce 這種設計的強大之處:雖然一開始好像很麻煩,但是原則上你可以無限多種「商品+商品呈現」的搭配。比方說,在Ubercart 裡頭,attibute跟著特定的商品走,當你瀏覽001型號的T恤,你就只能在001型號底下做屬性的選擇而已。要買002型號的衣服,請去002 node做選擇。但是在 Commerce 裡頭,你可以建立某個 product display node,然後把這種兩型號的衣服「裝」在一起賣。比方說你可以建立一個標題是「過季存貨出清」的product display node,然後引入店裡全部的24種商品。在這個 node 中,顧客可以先選型號。再從屬性的選擇中看到商品圖片的變換。如此,他可以在同一個頁面中先買黑色L號的001 T恤,再繼續買一件白色S號的002 T恤。

這樣有沒有很厲害?yes

不只如此,由於product reference可以引用任意的商品,你可以甚至可以將不同 product type 的商品裝在同一個 product display node 裡頭賣。比方說你的單位是個靠著捐款和販售義賣商品收入來維持營運的非營利組織,那基本上就可以規劃兩種商品類型:小額捐款和義賣商品。小額捐款有個「捐款金額」欄位,可以讓客戶自行填寫金額。「義賣商品」則有不同的型號、屬性和價格搭配。這兩種商品在 Ubercart 裡頭除非透過是 Taxanomy+Views 的設定組合,否則是很難在一個頁面中隨選販售的。但是在 Commerce 裡頭,你可以建立一個標題為「支持我們」的 product display node,然後透過 product reference 欄位把所有的商品全都「裝」進去,讓客戶在同一個頁面進行隨選瀏覽,並且進行「無縫購物」流程:客戶將自訂金額的捐款加入購物車之後,可以繼續切換到義賣商品,繼續把商品加入購物車。

這樣,你看出 Commerce 的潛力和彈性了嗎?enlightened

如果你有興趣的話,以下在網路上的教學影片可以讓你了解 Commerce 實際的操作方式:

光是講概念架構就寫了這麼落落長一大串,那原本打算要寫的 Commerce + Views 的部份就只好等下一篇再講了。待續啦 cool

Area