🛍️

Shopify Online Store 2.0 テーマ構成まとめ

2023/08/18に公開

はじめに

こんにちは!Team DELTAでフロントエンドを担当している三浦です。
Shopifyのテーマ構築でOnline Store 2.0を使ったのですが、開発の情報を集めるのに手間取ったため、自分の頭の整理もかねて、改めてテーマ構成をまとめます!

こんな人向け

Shopifyのカスタマイズをしたことがない、または、旧バージョンのShopifyテーマをカスタマイズしたことはあるけど、Online Store 2.0には触ったことがない…という開発者の方向けです。作成したセクションをテンプレートで呼び出して表示するまでをまとめました。Liquidの書き方までは踏み込んでいないのでご了承ください。

Online Store 2.0とは

2021年8月にリリースされたアップデートです。(もう2年前なんですね…)
これまでとの違いはざっくり2点。

  • 今までトップページにしか表示できなかった「セクション」が、サイト内のどこにでも表示できる
    • テンプレートでも、管理画面からもセクションを自由に追加でき、カスタマイズの自由度が広がる!
  • メタフィールドが管理画面から簡単に追加できる
    • 管理画面からnoindex設定も一応できる

▼ 詳しくはShopify Japanの公式ブログもどうぞ
https://www.shopify.com/jp/blog/partner-shopify-online-store


準備(CLIが入っていない方のみ)

Shopify CLIを入れる

Shopify CLIのインストールにはNode.jsやRubyが必要です。こちらからご自分の環境に合わせて入れてください。
https://shopify.dev/docs/themes/tools/cli/install

デフォルトテーマをローカルにDL

任意のディレクトリを作成・移動後、shopify theme initします。theme名を聞かれるので答えると、Githubのリポジトリから「Dawn」のクローンが始まります。

shopify theme init
?  Name of the new theme:
✔  DawnDELTA

▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
Cloning https://github.com/Shopify/dawn.git into /xxx/shopifytest/DawnDELTA ...

先ほどつけたテーマ名のディレクトリに移動して、ローカル開発サーバーを立ち上げます。
適当なキーを押すとブラウザが立ち上がるので、画面に従ってログインします。(Shopifyで既にアカウントを作成している前提です)

cd DawnDELTA
shopify theme dev --store [ストアドメイン]

To run this command. log in to Shopify Partnars.
Press any key to open the login page on your browser.

テーマ構成

ディレクトリ構成は以下のようになっています。次から各ディレクトリの説明です。

DawnDELTA
├── assets
├── config
├── layout
├── locales
├── sections
├── snippets
└── templates
    └── customers

assets

├── animations.js
├── base.css
(略)
└── video-section.css

CSSファイル、JavaScriptファイル、画像ファイルを格納します。ここには下層ディレクトリは作成できません。
必然的にファイル数が多くなるため、ファイルの種類ごとに接頭辞を決めると見通しがよいです。

config

├── settings_data.json
└── settings_schema.json

settings_data.jsonは、テーマに入れ込む変数を書き込みます。presetsにはテーマのデフォルトの値が入っていて、currentにカスタマイズしたい値を追加すると上書きできます。

settings_schema.jsonは、管理画面の「テーマ設定」で設定できる項目を定義します。フォントサイズの設定を5px刻みから2px刻みにしたり、ボタンの最小値・最大値を変更できます。
(ここで定義された値に対して、setting_data.jsonが値を入れ込むイメージ)

layout

├── password.liquid
└── theme.liquid

全ページの共通となるheadタグ・bodyタグが記述されているtheme.liquidファイルと、パスワード設定時に表示する画面のpassword.liquidがあります。
metaタグや共通のstyle,scriptタグはtheme.liquidに書きます。

locales

├── ja.json
├── ja.schema.json
(略)
└── zh-TW.schema.json

各国の翻訳用ファイルです。ユーザーのページにもともと表示されている文章やボタンの文言はこちらからカスタマイズできます。

sections

├── announcement-bar.liquid
├── apps.liquid
(略)
└── video.liquid

sectionファイルが入っています。デフォルトで入っているsectionファイルを複製して変更するか、自分で一からHTMLを書いて作成します。ファイル名はデフォルトと被っていなければ恐らく自由。

snippets

├── header-drawer.liquid
├── icon-accordion.liquid
(略)
└── social-icons.liquid

snippetファイルが入っています。snippetファイルはsectionファイル内で呼び出すことができるため、アイコンとして使うsvg・ボタン・ナビゲーションなど、使いまわしたいパーツを記述することが多いです。

templates

├── 404.json
├── article.json
(略)
└── search.json

各ページのテンプレートが入っています。中には呼び出すsectionとその順番を記述します。新しいテンプレートを作成するときはドットでつないだファイル名にします。
例:固定ページのテンプレート→ page.◯◯.json
例:ブログのテンプレート→ blog.◯◯.json(Shopifyはブログを複数作成できます。)


各ファイルの書き方

sections

<section class="mysection mysection-{{ section.id }}">
	(略)
    //LiquidのURL filterを使って画像を表示
    <img src="{{ 'image1.jpg' | asset_url }}" width="xxx" height="xxx" alt="" loading="lazy">
</section>

{% style %}
.mysection-{{ section.id }} {
  margin-bottom: 40px;
  ...
}
{% endstyle %}

{% javascript %}
{% endjavascript %}

{% schema %}
{
  "name": "main-section-xxxx",
  "settings": [],
  "presets": [
    {
      "name": "xxxセクション"
    }
  ]
}
{% endschema %}

sectionファイルにはschemaが必須です。(テンプレートで呼び出すため)
presetsのnameは、管理画面からsectionを追加するときに選択肢として出てくる名前になります。

また、HTMLのクラス名にid(呼び出されるごとに割り振られる)を含めておくと安全です。同じセクションが他の場所で呼ばれても、個別に識別できるようになります。

ファイルの中にCSS、JavaScriptを書くこともできますが、idを含むもの以外は別ファイルとして分割したほうが見やすいと思います。

今回はLiquidのURL filterを使って画像を表示させるコードを書きましたが、他にも様々なフィルターがあります。ドキュメントにざっと目を通すと、何ができるかイメージしやすいと思います。
https://shopify.dev/docs/api/liquid/filters

snippets

section.liquid
<section class="mysection mysection-{{ section.id }}">
	(略)
    //リンク先を設定してリンクボタンを呼び出し
    {% render 'link-button', href: '/pages/xxx'  %}
</section>
(以下略)
link-button.liquid
<div class="section-link-wrap-button">
  <a href="{{ href }}" class="section-link-button">
    <button>view more</button>
  </a>
</div>

{% style %}
  .section-link-wrap-button {}
  .section-link-button {
    color: rgb(var(--color-base-text));
    display: flex;
    justify-content: right;
    align-items: center;
    gap: 8px;
  }
{% endstyle %}

snippetsにschemaは不要です。svgタグを置いてアイコンとして呼び出したり、変数を引き渡して自在にリンク先を変えられるボタンなどとして使用します。

templates

{
  "sections": {
  //以下で好きなsectionを呼び出す
    "main": {
      "type": "main-section-xxxx", //ファイル名
      "settings": {
        "padding_top": 28,
        "padding_bottom": 28
      }
    }
  },
  "order": ["main"]
}

sectionsの中に呼び出したいsectionの情報を書きます。settingsの中身はsectionファイルの中で定義されていなければ特に書かなくても大丈夫です。後はorderで表示順を指定します。

新しいテンプレートファイルを作成した場合、ローカルのテーマをpushしたあと、管理画面からオンラインストア > ページ を開き、任意のページで適用したいテーマテンプレートを選択すれば、ページに反映されます。


本番環境への反映

ローカルのテーマを反映するにはshopify theme pushを使います。現在適用されているテーマに[live]と表示されるので、選択すれば、現在の変更がテーマに反映されます。

shopify theme push
? Select theme to push to xxx.myshopify.com (Choose with ↑ ↓ ⏎, filter with 'f')
> 1. DawnDELTA [live]
  2. Development (xxxxx-xxxxxxxxxx) [development] [yours]

管理画面の設定値をローカルに反映

管理画面で色や文言を設定した時、ローカルのテーマをpushすると、settings_data.jsonの値で上書きされてしまいます。管理画面から設定を変更したときは、shopify theme pullを使えばローカルにも変更が反映されます。

現在本番環境に適用されている情報がほしければ[live]を、ローカルの開発サーバーを立ち上げて、その管理画面から設定した値をsettings_data.jsonに反映したければ[yours]を選択します。

shopify theme pull
? Select a theme to pull from xxx.myshopify.com (Choose with ↑ ↓ ⏎, filter with 'f')
> 1. DawnDELTA [live]
  2. Development (xxxxx-xxxxxxxxxx) [development] [yours]

まとめ

基本はsectionファイルを追加して、jsonテンプレートに反映する の繰り返しです。
では、複雑な条件分岐や、クエリパラメータをつけたページごとに処理をしたい場合は…?

第二弾で今回つまずいたポイントをまとめる予定ですので、ご期待ください!

(予定)

  • 複雑な条件分岐の書き方
  • クエリパラメータを取得したい
  • バリエーションのある商品を、商品ページ以外に表示する
  • 特定のページをnoindexにする
参考にさせていただいた記事

https://skillhub.jp/blogs/334
https://shopify.dev/docs/themes/architecture/sections/section-schema

We're hiring!

https://note.com/delta_sevenrich/n/n15f551a4d7a5

最後までお読みいただきありがとうございます。
現在DELTA では一緒に働いてくださる仲間を大募集中です!
ご興味をお持ちいただけましたら、お気軽にフォームからご連絡ください🎆

https://docs.google.com/forms/u/1/d/e/1FAIpQLSfQuWNU1il5lq2rVdICM0tSK_jTsjqwc52LYEwUxBq7_ImtrQ/viewform

DELTAテックブログ

Discussion