1. 程式人生 > 實用技巧 >shopfiy 二次開發之改變 layout ,實現購物車獨立模組載入

shopfiy 二次開發之改變 layout ,實現購物車獨立模組載入

購物車模組cart-template.liquid

在開發購物車的時候,需要這樣的效果,購物車不是一個單獨的頁面,而是作為一個彈框現的。

比如點選購買按鈕,側邊彈出這個購物車的面板,而板中的產品狀態是實時更新的,因此不能使用 iframe ,也不能 load一個頁面,load頁面會把整個頁面中的靜態資源或是其它js一起載入,會出現各種問題。

修改theme.liquid

shopfiy中的 layout只有一個theme.liquid檔案,所有的頁面都基於它顯示。我們要實現單個載入cart-template.liquid 就比較困難。

解決辦法是使用shopfiy中的Liquid 標記模板,{%- if template contains 'pa1ge.cart' -%}

,通過判斷當前的template contains是否包含pa1ge.cart字串來判斷當前頁面是否為cart-template

shopfiy中的Liquid 標記參考連結

theme.liquid中的網頁結構,通過 if ... else ...來做個判斷:

{%- if template contains  'pa1ge.cart' -%}
        // cart-template.liquid 模組
    {{ content_for_layout }}
{%- else -%}
        //正常網頁結構
     <!doctype html>
<html class="no-js" lang="{{ shop.locale }}">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <meta name="theme-color" content="{{ settings.color_button }}">
  <link rel="canonical" href="{{ canonical_url }}">
  <link rel="icon" href="{{'favicon.ico' | asset_url}}" type="image/x-icon">
  {
%- if settings.favicon != blank -%} <link rel="shortcut icon" href="{{ settings.favicon | img_url: '32x32' }}" type="image/png"> {%- endif -%} {%- capture seo_title -%} {%- if template == 'search' and search.performed == true -%} {{ 'general.search.heading' | t: count: search.results_count }}: {{ 'general.search.results_with_count' | t: terms: search.terms, count: search.results_count }} {
%- else -%} {{ page_title }} {%- endif -%} {%- if current_tags -%} {%- assign meta_tags = current_tags | join: ', ' -%} &ndash; {{ 'general.meta.tags' | t: tags: meta_tags -}} {%- endif -%} {%- if current_page != 1 -%} &ndash; {{ 'general.meta.page' | t: page: current_page }} {%- endif -%} {%- assign escaped_page_title = page_title | escape -%} {%- unless escaped_page_title contains shop.name -%} &ndash; {{ shop.name }} {%- endunless -%} {%- endcapture -%} <title>{{ seo_title | strip }}</title> {%- if page_description -%} <meta name="description" content="{{ page_description | escape }}"> {%- endif -%} {% include 'social-meta-tags' %} <!-- Theme CSS --> {{ 'theme2.scss.css?20200710100' | asset_url | stylesheet_tag }} {{ 'header.scss.css?20200707' | asset_url | stylesheet_tag }} {{ 'footer.scss.css?20200709' | asset_url | stylesheet_tag }} {{ 'viewer.min.css' | asset_url | stylesheet_tag }} {{ 'swiper.css' | asset_url | stylesheet_tag }} {{ 'u-tec.css?2020014' | asset_url | stylesheet_tag }} {{ 'font.css' | asset_url | stylesheet_tag }} {{ 'ubolt-pro-animation.css' | asset_url | stylesheet_tag }} {{ 'activity-banner.css' | asset_url | stylesheet_tag }} {{ 'new-store.css?20201409' | asset_url | stylesheet_tag }} {{ 'cart.scss.css?20200717' | asset_url | stylesheet_tag }} {% if product.available %} {{ 'product.scss.css' | asset_url | stylesheet_tag }} {% endif %} {%- if template.directory == 'customers' -%} <script src="{{ 'shopify_common.js' | shopify_asset_url }}" defer="defer"></script> {%- endif -%} <!-- Third Party JS Libraries --> {{ 'modernizr-2.7.1.min.js' | asset_url | script_tag }} {{ 'jquery.min.js' | asset_url | script_tag }} {{ 'api.jquery.js' | asset_url | script_tag }} {{ 'swiper.min.js' | asset_url | script_tag }} {{ 'viewer.min.js' | asset_url | script_tag }} {{ 'priceNavScroll.js' | asset_url | script_tag }} {{ 'cnav.js' | asset_url | script_tag }} {{ 'product-public.js' | asset_url | script_tag }} <script src="{{ 'lazysizes.js' | asset_url }}" async="async"></script> <script src="{{ 'vendor.js' | asset_url }}" defer="defer"></script> <script src="{{ 'theme.js' | asset_url }}" defer="defer"></script> {% comment %} {{ content_for_header }} {% endcomment %} </head> <body class="accessories activity form big-header show-cart-fixed {% if customer %}customer-logged-in{% endif %} template-{{ template | replace: '.', ' ' | truncatewords: 1, '' | handle }} navigation-{{ settings.header-navigation-location }} {% if template == 'product.slideshow' %}template-product-slideshow{% endif %}"> <div class="max-w1440"> <!-- cart --> <div class="cart-page"> <div class="close-cart"><span class="icon icon-utec-close"></span></div> <div class="cart-page-content"> </div> </div> <!-- header snippet --> {% include 'header' %} <!-- main content --> <main class="main-content {% if template contains 'collection' and collection.image and settings.collection-show-featured-image %}{% unless template contains 'list-collections' %}collection-has-featured-image{% endunless %}{% endif %}" role="main"> <!-- activity snippet --> {% include 'activity' %} {% unless template contains 'index' or fullBleed %} {% unless template contains 'slideshow' and settings.product-slideshow-layout == 'full-width' %} {% include 'breadcrumbs' %} {% endunless %} {% endunless %} {{ content_for_layout }} </main> {% section 'footer' %} </div> <!-- product pc show cart --> {% if product %} <!-- pc fixed cart --> <div class="cart-veiw-fixed"> {% include 'cart-template-fixed' %} </div> {% endif %}</body> </html> {% endif %}

解釋{{ content_for_layout }}

正常網頁結構,大部分人都是能理解的,但是{{ content_for_layout }}就是 body中的正文部分了。

剛在上面的程式碼中有用紅色字型標明 body中的 cart購物車結構,這個結構預設是隱藏的, 就是{{ content_for_layout }}通過這個來顯示的。

怎麼將購物車模組與{{ content_for_layout }}聯絡,需要進行下面的神操作:

1. 需要在 pages中新建一個頁面,叫 cart.html

在 cart的 page中關聯cart-template.liquid ,看下圖

使用 section標籤將購物車模組載入到當前 cart 頁面

2. 修改theme.js檔案以實現將購物車彈框載入

在 Assets中找到 theme.js面板檔案,這個檔案包含 shopfiy獨立站購物大部分的的 js

當我們在頁面中點選購物按鈕時,會觸發 shopfiy中的新增到購物車的事件:

//定義了好多的事件
this
.selectors = { addToCart: '[data-add-to-cart]', addToCartText: '[data-add-to-cart-text]', quantity: '[data-quantity-input]', SKU: '.variant-sku', productStatus: '[data-product-status]', originalSelectorId: '#ProductSelect-' + sectionId, productForm: '[data-product-form]', errorMessage: '[data-error-message]', errorMessageWrapper: '[data-error-message-wrapper]', productImageWraps: '.product-single__photo', productThumbImages: '.product-single__thumbnail--' + sectionId, productThumbs: '.product-single__thumbnails-' + sectionId, productThumbListItem: '.product-single__thumbnails-item', productFeaturedImage: '.product-featured-img', productThumbsWrapper: '.thumbnails-wrapper', saleLabel: '.product-price__sale-label-' + sectionId, singleOptionSelector: '.single-option-selector-' + sectionId, shopifyPaymentButton: '.shopify-payment-button', priceContainer: '[data-price]', regularPrice: '[data-regular-price]', salePrice: '[data-sale-price]' };

addToCart 就 shopfiy 中新增到購物車的事件。
而我們需要找到將單個產品新增到購物車的方法:_addItemToCart
這個方法會呼叫 shopfiy 的一個 post 方法
var params = {
        url: '/cart/add.js',
        data: jQuery(data).serialize(),
        dataType: 'json'
      };

當新增成功了,使用 jQuery的.load()方法將剛才建立的 cart.htmlPage頁面載入到 body中

body中 cart的結構,預設是隱藏的:

    <!--  cart    -->
    <div class="cart-page">
        <div class="close-cart"><span class="icon icon-utec-close"></span></div>
      <div class="cart-page-content">
      </div>
    </div>

在_addItemToCart載入成功之後的方法中將會這樣寫:

 _addItemToCart: function(data) {
      var self = this;
      var params = {
        url: '/cart/add.js',
        data: jQuery(data).serialize(),
        dataType: 'json'
      };

      jQuery
        .post(params)
        .done(function(data) {
     //    window.location.href = '/cart';  預設是跳轉到購物車頁面的,這裡需要關閉
    //     彈出側邊購物車
          jQuery('body').addClass('show-cart');
    //    僅載入這個頁面中的 #shopify-section-cart-template 結構
          jQuery('.cart-page-content').load('https://store.shop-name.com/pages/cart-1.html #shopify-section-cart-template');
        })
        .fail(function(response) {
          self._showErrorMessage(response.responseJSON.description);
        });
      
    },

為什麼一定要這樣操作呢,因為在購物車模組中,當它載入後還有其它事件需要觸發。