shopifyのページ作成で注意する事「sectionが記憶する」

shopify開発でよく作るのが、商品ページ用のテンプレートと固定ページ用のテンプレートです。以前にテンプレートの増やし方。と言うこんな記事を書いています。

この記事では単純にテンプレートの増やし方を解説していますが、今回はこれをもう掘り下げて、テンプレートの下に配置するsectionが色んな事を記憶している。と言う部分について触れてみたいと思います。

この記事読んだらshopify開発時に注意すべき、編集点が1つ理解できますよ^^

商品ページと固定ページで気を付ける事

shopify開発をしていれば、特定の商品ページや、固定ページをカスタマイズしなくちゃいけないシーンに必ず当たると思います。そんな時に理解しておかなくちゃいけない事が、テンプレートの中にsectionは置けます。その上でこの事を理解する必要があります。

何かのデータを記憶するのはtemplateじゃなくて、section

この事を念頭に置いて開発する必要があります。

一体どう言う事かと思うと思いますので、順を追って説明します。

indexとそれ以外のテンプレートの違い

まずshopifyはindexページだけとっても特殊な動きをしていて、indexページだけはsectionを自由に呼び出して、配置も自由に選べます。そして、それ以外のページではsectionは自由には増やせないと言う事から解説を進めましょう。

まずindexのここのところですね。左側から自由にいろいろ配置できるのがわかると思います。

この時indexページだけは「section」を呼び出せて、その呼び出せるsectionと言うのはschemaでpresetsが設定されいる物が呼び出し可能です。

schemaについて学びたい時はこちら

上下の位置も入れ替えられるし、好きに呼び出せてとっても便利なのですが、これが商品ページとか固定ページになると、どうでしょう?

見ての通り、左側にsectionが4つ入ってはいるのですが「セクションを追加する」の項目がなくて、追加できません。

両社のliquidコードの違いを見てみるとまず、indexはテンプレートファイルの「index.liquid」を見ると

{{ content_for_index }}

もうこれしか書いてません(debutの場合)
たったこれだけでコードが済んでしまう超特殊な作りだと言う事がお分かりいただけるでしょうか?

それに対して商品ページはテンプレートでいうと「product.***.liquid」とproductで始まるテンプレートを使っています。こちらの中身はと言うと・・とりあえず「product.liquid」を見てみると

{% comment %}
  The contents of the product.liquid template can be found in /sections/product-template.liquid
{% endcomment %}

{% section 'product-template' %}
{% section 'product-recommendations' %}

{% if collection %}
  <div class="text-center return-link-wrapper page-width">
    <a href="{{ collection.url }}" class="btn btn--secondary btn--has-icon-before return-link">
      {% include 'icon-arrow-left' %}
      {{ 'products.product.back_to_collection' | t: title: collection.title }}
    </a>
  </div>
{% endif %}

<script>
  // Override default values of shop.strings for each template.
  // Alternate product templates can change values of
  // add to cart button, sold out, and unavailable states here.
  theme.productStrings = {
    addToCart: {{ 'products.product.add_to_cart' | t | json }},
    soldOut: {{ 'products.product.sold_out' | t | json }},
    unavailable: {{ 'products.product.unavailable' | t | json }}
  }
</script>

{% assign current_variant = product.selected_or_first_available_variant %}

<script type="application/ld+json">
{
  "@context": "http://schema.org/",
  "@type": "Product",
  "name": {{ product.title | json }},
  "url": {{ shop.url | append: product.url | json }},
  {%- if product.featured_media -%}
    {%- assign media_size = product.featured_media.preview_image.width | append: 'x' -%}
    "image": [
      {{ product.featured_media | img_url: media_size | prepend: "https:" | json }}
    ],
  {%- endif -%}
  "description": {{ product.description | strip_html | json }},
  {%- if current_variant.sku != blank -%}
    "sku": {{ current_variant.sku | json }},
  {%- endif -%}
  "brand": {
    "@type": "Thing",
    "name": {{ product.vendor | json }}
  },
  "offers": [
    {%- for variant in product.variants -%}
      {
        "@type" : "Offer",
        {%- if variant.sku != blank -%}
          "sku": {{ variant.sku | json }},
        {%- endif -%}
        "availability" : "http://schema.org/{% if variant.available %}InStock{% else %}OutOfStock{% endif %}",
        "price" : {{ variant.price | divided_by: 100.00 | json }},
        "priceCurrency" : {{ cart.currency.iso_code | json }},
        "url" : {{ shop.url | append: variant.url | json }}
      }{% unless forloop.last %},{% endunless %}
    {%- endfor -%}
  ]
}
</script>

まぁまぁ長いコードが書いてありますよね。その中でも上の方で

{% section 'product-template' %}
{% section 'product-recommendations' %}

の部分に注目してください。この部分がさっきの商品ページのカスタマイズ画像でいう所の

この赤枠の中になります。つまり、テンプレート上にsection名を指定して読み込んでいるのです。index以外のテンプレートはみんなこちらの方式で作られており、テンプレートファイルごとに読み込むsectionはコードで書いて呼び出す必要があるのです。

sectionファイルを書き込んでみる

さて、indexとそれ以外のテンプレートはsectionの呼び出し方が根本的に違うことが分かったところで、まず思うことは

「ちくしょー!ほかのページもsection自由に増やさせてよ」

だと思うのですが、それはかなわないので忘れましょう(疑似的な方法はあるのですが、それは別の記事で紹介します)

まずはここに1つ書き込んでみましょう。増やすsectionは別記事でも作ったカスタムHTMLを書き込めるsectionにしてみましょう。debutは元々持っていないのでちょうどいいです。

カスタムHTMLの作り方はこちらをご覧ください。

出来上がりのsectionファイルのファイル名を「custom-html.liquid」にしたので、product.liquidにはこう書きます。

{% section 'custom-html' %}
{% section 'product-template' %}
{% section 'product-recommendations' %}

ほら、ご覧の通り、一番上に「カスタムHTMLだよ」と言うsectionが追加されていて、右側の画面にも、そのデフォルトで入れてある文字が出ていますでしょ?

こうやってsectionを増やしていきながら、商品ページや固定ページは作成していきます。

sectionが記憶するの核心部分(ここ重要)

いままでの解説でproductテンプレートにsectionを追加する方法がわかったかと思いますが、実はこれだけで先に進むと危険なので、sectionが記憶するという部分について解説します!

まずここまでの説明ではproductテンプレートに「section」を追加する方法を解説しました。その上で、別のproductテンプレートが必要になってきたとします。

くまちゃん2号に登場してもらいましょう。

くまちゃん2号はもっとカスタムHTMLが欲しいので「product.kuma2.liquid」と言うテンプレートファイルを作って、基本構造は同じですが呼び出し部分を

{% section 'custom-html' %}
{% section 'product-template' %}
{% section 'custom-html' %}
{% section 'product-recommendations' %}

こうしてみました。結果としては

狙い通り、2か所にsectionが挿入されていて、全然OKな感じじゃないですかね^^

が、ここが落とし穴です!!

では、このカスタムHTMLを書き換えてやりましょう。まずは上の「カスタムHTMLだよ」の方を開いて、中身の文章を「書き換えだってこの通り!一瞬で出来ちまうぜ!!」と書き換えてやりましょう。

ほらこの通り書き変わって・・・いま・・・す・・・・あれ?

なんてこった。下の緑で囲った部分・・・2つ目のカスタムHTMLを同時に書き変わりやがった・・・そして、最初に作った「くまちゃん」を見ると・・・

げげげっ!なんてこった!こっちまで書き変わってやがる!!

そう、最初に言った「sectionが記憶する」とはこう言う事で、1つのsectionファイルの記憶は他のどこに書いても引き継がれるのです!!

なのでこう言ったカスタマイズをしたい場合は面倒くさいですがsectionファイルを別に作る必要があります。このカスタムHTMLなら

custom-html.liquid
custom-html2.liquid
custom-html3.liquid

のように増やしてやるしかないのです。(さっきもちょろっと触れましたが、疑似的な方法で回避可能ですが、かなりレベルが上がるのでまた別記事で解説します)

でいろいろ増やして再編集したのがこちら。くまちゃんの方のテンプレートはそのままで、くまちゃん2号はこうします。

{% section 'custom-html2' %}
{% section 'product-template' %}
{% section 'custom-html3' %}
{% section 'product-recommendations' %}

するってーと見た目がこうなります。(あっ、ついでに中身も2と3で個別に編集しましたよ)

ほらね。無事に2つのカスタムHTMLが設置できてるし、別々の事が書けるようになってるでしょう?こうやって商品ページや固定ページにsectionを追加するときには

テンプレート専用のセクションを作る

と言う作業が必要になってきます。

sectionが記憶する理屈

難しいのでしっかりは触れませんが、なぜsectionが記憶するのかと言う理屈ですが、これは各セクションが持つscehmaのデータをconfigフォルダにある「settings_data.json」と言うファイルが記憶しているからです。

見ての通り、「custom-html」「custom-html2」「custom-html3」は別々に管理されています。だから同じものを呼び出すと同じ内容になっちゃうんですね。

でもindexのところでは同じセクション何回でも呼び出せるよ?

と言うのが次に疑問と思いますが、次にindexのデータの保持の仕方は見てみましょう。同じsettings_dataの中に(たぶん一番下のはず)

      "content_for_index": [
        "hero",
        "featured-collections",
        "slideshow",
        "1492033924902",
        "1492096252560",
        "1492033877875",
        "1492033809691"
      ]

こんな部分があるはずです(番号は各々の使い方で変わります)

その上で例えば一番上の「1492033924902」をsettings_dataの中で検索してみると

"1492033924902": {
          "type": "custom-content",
          "blocks": {
            "1492033924902-0": {
              "type": "text",
              "settings": {
                "width": "100%",
                "alignment": "center",
                "align_text": "center"
              }
            }
          },
          "block_order": [
            "1492033924902-0"
          ],
          "settings": {
            "title": ""
          }
        },

こんな部分が見つかるはずです。

そうindexだけsectionを増やすとオリジナルの番号が振られて、その番号に対してsectionの設定を保持する。と言う特殊能力が働くのです。

うーん、ずるい!index超ずるい!!

まとめ

要するにindexは好きにsection追加できるけど、それ以外のページでは必ず

テンプレート毎に追加したいセクションファイルもオリジナルで増やせ!

と言う事がわかったかと思います。

増やし方は単純にほぼコピペして、nameの部分とかだけわかりやすく書き換えておきなさいよ。と言うぐらいですが、いろいろファイルが増えていくので結構面倒ではあります。

疑似的に回避する方法もあるとは何度か書いてますが、こちらはこちらでそこそこ面倒くさいのでまた解説します。

とりあえずshopifyの面倒くさいけど便利な部分ではあるので、覚えておくといいと思いますよ!