Shopify 靜態與動態 Sections

Sections 當開發完 Sections 模組最常拿來在 theme 首頁做使用,在深入瞭解後其實還有其他使用方式來搭配 佈景主題編輯器 讓商家在各頁面版面配置外觀內容。

在 Shopify 上的 Sections 有分兩種類型:

靜態區段

頁面上特定位置的區段如頁首、頁尾、以及自定義的區段,使用靜態區段無法移除或重新排序。

Step 1: 新增頁面樣板

在主題上建立新的 liquid file template/page.static.liquid 並添加此標籤使用靜態區段

{% section 'section-file-name' %}

Step 2: 新增一個新頁面

網路商店 > 頁面

在右下角選擇我們剛剛建立的頁面樣板 page.static.liquid

完成此操作後,繼續打開主題編輯器並從下拉列表中選擇新頁面,就可以看到自定義的靜態區段

動態區段

theme editor 上面可讓商家自由的新增、重新排列或移除區段,比較靈活的進行版面配置。

動態區段 Shopify 文件上沒有任何的使用方式說明,原以為只能在首頁上使用,直到有一次在進行功能開發評估時發現在其他頁面上竟然也可以使用,接下來介紹一下使用方法。

Step 1: 新增頁面樣板

在主題上建立新的 json file template/page.dynamic.json

{
  "sections": {
    "list-collections-template": {
      "type": "list-collections-template",
      "disabled": false,
      "settings": {
      }
    }
  },
  "order": [
    "list-collections-template"
  ]
}

Step 2: 在頁面選擇 dynamic 頁面樣板

這次製作的樣板為 json 在這邊的內容就無法使用,所以可能要製作一個 Sections 提供內容上架。

完成此操作後,繼續打開主題編輯器並從下拉列表中選擇頁面,就可以看到動態的區段可讓商家自由的新增或移除。

Shopify 開發 Section 商品輪播組件


設計一個商品輪播的區段,輪播功能使用 Shopify 內的 Slick Carousel 套件

調整 sections/custom-section.liquid

<section class="custom-section" data-section-id="{{ section.id }}" data-section-type="custom-section">
  <div class="box">
    <div class="wrapper">
      <div class="grid grid-spacer slick slick-product-grid">
        {%- for block in section.blocks -%}
          {%- if block.settings.product_id == blank -%}
            <div class="grid__item grid-product flex empty"></div>
          {%- else -%}
            {%- render 'product-grid-item' with all_products[block.settings.product_id] as product -%}
          {%- endif -%}
        {%- endfor -%}
      </div>
    </div>
  </div>
</section>
{% schema %}
{
    "name": "Custom Section",
    "settings": [{
        "id": "custom_text_title",
        "type": "text",
        "label": "Text box heading",
        "default": "Title"
    }],
    "blocks": [{
        "type": "description",
        "name": "Product",
        "settings": [{
            "type": "product",
            "id": "product_id",
            "label": "Product"
        }]
    }],
    "presets": [{
        "name": "Custom Section",
        "category": "Product"
    }]
}
{% endschema %}

HTML

在這個例子中, section 標籤設定兩個 **data-* 屬性,當每個 section 建立時都會有一組 unique ID 可以通過這組 ID 來設定 script 的部分,所以將他儲存至 data-section-id,另外 data-section-type** 則是用來定義 script 的初始化類別。

blocks 的部分是由商家可以自行增加,在 Liquid 中可通過 section.blocks 取得,在使用迴圈的方式渲染每個商品,這邊引用預設 snippets 的 product-grid-item 來建立。

all_products 是一個 Global objects,我們在 schema 定義給商家的選擇欄位是 product_id,在轉換到 Liquid 時只能抓取到商品的 Object handles,所以需要通過 all_products objects 來找出指定的商品

schema

在 settings 標籤屬性:

  • id 指的是定義 Liquid 存取的變數
  • type 定義給商家輸入的類型,類型包括 image_picker、radio、video_url ⋯⋯等
  • label 顯示在主題編輯器上的名稱
  • default 設定輸入欄位預設值

接下來調整前端程式的部分

調整 layout/theme.liquid

<!-- <script src="{{ 'theme.min.js' | asset_url }}" defer="defer"></script> -->
<script src="{{ 'theme.js' | asset_url }}" defer="defer"></script>

這邊因為使用 theme 預設的 script,所以要調整一下載入的路徑

調整 asset/theme.js.liquid

theme.CustomSection = (function() {
  function CustomSection(container) {
    var $container = (this.$container = $(container));
    var sectionId = $container.attr("data-section-id");
    var slider = (this.slider = `#ProductGrid-${sectionId}`);
    var $slider = $container.find(".slick-product-grid");

    if (!$slider.length) {
      return;
    }

    var slickOptions = {
      arrows: true,
      dots: true,
      autoplay: true,
      autoplaySpeed: 1000,
      slidesToShow: 5,
      slidesToScroll: 1,
      swipeToSlide: true,
      infinite: false,
      speed: 200
    };

    var mobileOptions = $.extend({}, slickOptions, {
      slidesToShow: 2,
      centerMode: true,
      focusOnSelect: true,
      autoplay: false,
      infinite: true
    });

    enquire.register(theme.variables.mediaQuerySmallUp, {
      match: function() {
        theme.carousel.init({
          slider: $slider,
          slickOptions: slickOptions
        });
      }
    });

    enquire.register(theme.variables.mediaQuerySmall, {
      match: function() {
        theme.carousel.init({
          slider: $slider,
          slickOptions: mobileOptions
        });
      }
    });
  }

  CustomSection.prototype = _.assignIn({}, CustomSection.prototype, {
    onUnload: function() {
      theme.carousel.destroy($(this.slider));
    }
  });

  return CustomSection;
})();

$(document).ready(function() {
  $("body").addClass("page-loaded");

  theme.init();

  sections.register("custom-section", theme.CustomSection);
});

這邊使用原始架構的 script 進行區塊的擴充,在 jQuery 載入時使用 sections.register 註冊一個我們定義的 object,參數 custom-section 是在 sections/custom-section.liquid 裡設定的 data-section-type

在定義的 object 中所要控制的元素效果就可以寫在這裡,比較要注意的是需要提供一個 prototype.onUnload 方法,當在主題編輯器移除區段時可以清除。

在 JavaScript global variable 中有個 Shopify.designMode 參數,往後需要開發更複雜功能時可以使用,區別目前所執行的程式是否在主題編輯器中。

以下是這個例子中設計的商品輪播 Sections:

Shopify 探索 Theme Sections

Sections 是 Shopify 使用組件方式構成頁面,使開發者更加模組化可以更好地控制自訂義每個單獨組件,商家也能使用 Shopify theme editor 輕鬆自訂內容和商店外觀,以及即時預覽自訂變化。

Shopify 本身已經提供相當多的 Sections 組件可以應用,開發者可以將內建的 Sections 重新設計再定義樣式或功能,當需求遠遠不夠時我們也可以新增 Sections 組件。

開始開發一個新的 Sections 組件

在 sections 資料夾建立一個 liquid 檔案

theme 資料夾結構

shopift-theme
  - assets
  - config
  - layout
  - sections
    - custom-section.liquid
  - templates

custom-section.liquid 文件中架構

<section class="custom-section">

</section>
{% schema %}
{
    "name": "Custom Section",
    "settings": [],
    "blocks": [],
    "presets": [{
        "name": "Custom Section"
    }]
}
{% endschema %}

{% stylesheet %}
{% endstylesheet %}

{% javascript %}
{% endjavascript %}

通過在線商店進入 Shopify 主題編輯器點選左下角新增區段,就可以看到剛剛新增的組件。

schema

定義在 Shopify 主題編輯器裡的組件可設置的內容,例如文字輸入欄位和圖像選擇器、自定義 HTML 和選擇商品 ⋯⋯ 等等,讓商家可以自定內容。

設計的架構屬性:

  • name - 定義新增後區段顯示的名稱

  • settings - 定義區段可讓商家可輸入的內容

  • blocks - 定義可以使用多個子區塊可讓商家重複新增、刪除和排序

    依目前經驗只能設置 1 維數組,目前還無法使用多維數組進行需求開發,可能必須使用其他方法

  • presets - 這裡的 name 屬性是用來定義新增前顯示在可選組件中的名稱

stylesheet

定義在區段新增後渲染的 CSS 樣式,用法與一般開發 CSS 方式相同,需要注意的是因為區段是可以重複新增的在這裡定義的 CSS 就會重複出現造成 HTML 會很肥,如果不需要重複設定的樣式可以略過在這裡定義直接設計在其他共用的 CSS 中。

javascript

定義在區段新增後渲染的 script,這邊的用法與 stylesheet 一樣,需要注意重複新增問題。

Shopify 使用 Git 開發工作流程


一開始接觸 shopify 做主題開發時,用的是 shopify admin 提供的 online code editor 來做簡單的業務需求,不過這樣不太適合做整個主題的更動。

更好開發工作流程

安裝 shopify cli 的命令行工具,它可以快速生成 Node.js 開發環境,在本地進行更改並將這些更改與 shopify 網站同步

brew tap shopify/shopify
brew install shopify-cli

# 初始化專案一個新主題
shopify theme init

# 或者可以初始化已經存在的 git repository 
shopify theme init [NAME] --clone-url=https://github.com/shopify/dawn.git

# 使用 Shopify CLI 進行身份驗證
shopify login --store shoptestex.myshopify.com

在本地環境預覽開發的主題

開啟連結 http://127.0.0.1:9292 就可以觀看本地環境開發的程式,另外也支援 hot reloading

shopify theme serve

安裝 Shopify GitHub 集成

  1. 在 github 建立新的 repository,將開發的主題提交上去
  2. 從 shopify 後台,轉到 網路商店 → 佈景主題
  3. 佈景主題庫 新增佈景主題從 github 連接
  4. 登錄 github 選擇要連接的 repository
  5. 找到連接的主題,然後點擊 動作 → 發佈

Shopify 版本控制最佳實踐

通過 shopify 後台編輯主題時,任何更改都會由 shopify 自動提交到 github,這樣當開發人員在提交到 github 有可能就會遇到衝突和錯誤。

所以應該建立一個 staging branch ,在多個開發人員在同一個商店上開發功能時,都只處理 staging branch,當主題準備上線時,再將 staging branch 合併到 master branch。

安裝 Visual Studio Code plugin

theme check 可以檢查主題中的 liquid 和 json,可以讓我們在開發時快速檢測錯誤

https://marketplace.visualstudio.com/items?itemName=Shopify.theme-check-vscode