2020.10.1

【Shopify】Content Schemaを理解して、管理画面からサイトをカスタマイズできるようにする - #08

Shopifyでは、管理画面上からサイトをカスタマイズすることができます。

 

ここで指す「カスタマイズ」とは、サイト上にお知らせを追加したり、おすすめ商品を追加したり削除したり…です。

無料テーマを使用している場合、管理画面 > 販売チャネル > オンラインストア > テーマの画面で「カスタマイズ」をクリックして、各セクションで様々な設定ができるはずです。

上記はリッチテキストのセクション設定画面で、表示させる文章などを設定できます。

 

 

このように、管理画面でカスタマイズできるような仕組みを実現するには、themeファイルのconfig/settings_data.jsonContent Schemaという機能を理解してカスタマイズする必要があります。

 

かなりややこしい内容ですが、これを理解すると柔軟な運用しやすいサイトを作れるので、ぜひマスターしましょう。

 

■今回の内容の公式ドキュメント

Content Schema
Rules for the Content Schema.

 

■バックナンバー

はじめに

今回使用するテーマは無料の「Minimal」です。

公式テーマのURL:https://themes.shopify.com/themes/minimal/styles/modern

このテーマをベースにカスタマイズしていきます。

とはいえ、各テーマの既存のコードは一切使わないので、どのテーマをベースにしても大丈夫だと思います。

今回のゴール

管理画面から以下のようなセクションを追加して、自由にテキストや画像を設定して表示できるようにします。

コードの実装など

新規sectionsファイルの作成

まず初めに、sectionsディレクトリに新規でファイルを作成します。

今回はsample_section.liquidとファイル名を付けます。

そして、以下コードを貼り付けます。

 

<section>

  <section>
    <h2>Images</h2>
    <div>
      {% assign get_sec_image = false %}

      {% for block in section.blocks limit: section.blocks.size %}
        {% if block.settings.image_picker != blank %}
          {% assign get_sec_image = true %}
          {{ block.settings.image_picker | img_url: '300×' | img_tag }}
        {% endif %}
      {% endfor %}

      {% if get_sec_image == false %}
        <p>Nothing image.</p>
      {% endif %}
    </div>
  </section>

  <br><hr><br>

  {% if section.settings.is_visivle %}
    <section>
      <h2>Text</h2>
      {% if section.settings.text != blank %}
        <p>{{ section.settings.text }}</p>
      {% endif %}
    </section>
  {% endif %}

</section>



{% schema %}
{
  "name": {
    "ja": "サンプルセクション"
  },
  "class": "sample_section",
  "blocks": [
    {
      "type": "custom",
      "name": {
        "ja": "画像"
      },
      "limit": 3,
      "settings": [
        {
          "type": "image_picker",
          "id": "image_picker",
          "label": {
            "ja": "画像"
          }
        }
      ]
    }
  ],
  "settings": [
    {
      "type": "checkbox",
      "id": "is_visivle",
      "label": {
        "ja": "表示する?"
      },
      "info": {
        "ja": "チェックを入れると表示、外すと非表示になります。"
      }
    },
    {
      "type": "textarea",
      "id": "text",
      "label": {
        "ja": "本文"
      },
      "default": {
        "ja": "default text. default text."
      }
    }
  ],
  "presets": [
    {
      "name": {
        "ja": "サンプルセクション"
      },
      "category": {
        "ja": "_カスタム"
      }
    }
  ]
}
{% endschema %}

 

これで、ベースとなるsectionsファイルの作成は完了です。

settings_data.jsonの編集

次に、configディレクトリのsettings_data.jsonを編集します。

 

まず、以下のようなコードの記述を探します。

※テーマによって記述が異なります
※以下コードは無料の「Minimal」の場合です

 

"sections": {
      "header": {
        "type": "header",
        "settings": {}
      },
      "footer": {
        "type": "footer",
        "blocks": {
          "footer-0": {
            "type": "blog",
            "settings": {
              "blog": "news"
            }
          },
          "footer-1": {
            "type": "menu",
            "settings": {
              "menu": "footer"
            }
          },
          "footer-2": {
            "type": "social",
            "settings": {}
          },
          "footer-3": {
            "type": "newsletter",
            "settings": {}
          }
        },
        "block_order": [
          "footer-0",
          "footer-1",
          "footer-2",
          "footer-3"
        ],
        "settings": {
          "show_methods_of_payment": true
        }
      },
      "slider": {
        "type": "slider",
        "blocks": {
          "slider-0": {
            "type": "image",
            "settings": {}
          },
          "slider-1": {
            "type": "image",
            "settings": {}
          },
          "slider-2": {
            "type": "image",
            "settings": {}
          },
          "slider-3": {
            "type": "image",
            "settings": {}
          }
        },
        "block_order": [
          "slider-0",
          "slider-1",
          "slider-2",
          "slider-3"
        ],
        "settings": {
          "slider_autorotate": false,
          "slider_autorotate_rate": 5,
          "slider_home_transition": "fade"
        }
      },
      "product-template": {
        "type": "product-template",
        "settings": {
          "product_vendor_enable": true,
          "product_quantity_enable": false,
          "product_image_zoom_type": "lightbox",
          "product_thumbnails_position": "right",
          "show_extra_tab": false,
          "extra_tab_content": "",
          "social_sharing": false
        }
      },
      "article-template": {
        "type": "article-template",
        "settings": {
          "article_author_enable": false,
          "social_sharing": false
        }
      },
      "collection-template": {
        "type": "collection-template",
        "settings": {
          "vendor_enable": false,
          "show_sale_circle": true,
          "show_sold_out_circle": true,
          "sort_enable": true,
          "tags_enable": true,
          "center_grid_link": false
        }
      },
      "collection-list": {
        "type": "collection-list",
        "blocks": {
          "collection-list-0": {
            "type": "collection",
            "settings": {}
          },
          "collection-list-1": {
            "type": "collection",
            "settings": {}
          },
          "collection-list-2": {
            "type": "collection",
            "settings": {}
          },
          "collection-list-3": {
            "type": "collection",
            "settings": {}
          }
        },
        "block_order": [
          "collection-list-0",
          "collection-list-1",
          "collection-list-2",
          "collection-list-3"
        ],
        "settings": {
          "title": "Collection list"
        }
      },
      "newsletter": {
        "type": "newsletter",
        "settings": {
          "color_bg": "#eaebea"
        }
      }
    }
  },

テーマによってsettings_data.jsonの内容はかなり異なるので、該当箇所を探すポイントを解説します。

まず、settings_data.jsonの1行目あたりは以下のようになっているかと思います。

{
  "current": {

この、current{}の中から、以下の"sections": {の部分を見つけます。

"sections": {
  "○○": {
    "type": "○○",
    ・
    ・
    ・
  },
  "○○": {
    "type": "○○",
    ・
    ・
    ・
  },
  ・
  ・
  ・
},

sections{}の次の階層に記述されているheaderfooterなどは、sectionsディレクトリの中のファイル名とリンクしています。

では、sections{}の中の一番最初でも一番最後でもどちらでもいいので、以下のように追記してください。

"sections": {
      "sample_section": {
        "type": "sample_section"
      },

ちなみに、これらはjson形式のファイルなので、要素が連続する場合は,の付け忘れに注意してください。

また、次の要素がないのに,を最後に付けているとエラーになるので気をつけましょう。

 

settings_data.jsonに上記のコードを追加することで、管理画面で該当するsectionsファイルを追加できるようになります。

 

以上で準備は完了です。

管理画面からセクションを追加しようとすると、以下のように_カスタムというグループが追加されているはずです。

そこから先程作成した「サンプルセクション」を追加して、挙動を確認してください。

自由にテキストや画像が変更できれば成功です。

 

もし、反映されなかったり、そもそも「サンプルセクション」が表示されない場合は、theme watchを実行しているか、watch中のターミナルにエラーが表示されていないか、などを確認してください。

コードの解説

では、sectionsファイルのコードの解説をしていきます。

 

このファイルの中のコードは大きく2つに分かれており、前半がサイト上に表示させるHTML後半の{% schema %}の部分が管理画面の設定関係のコードです。

 

管理画面で設定した値を、liquid側で受け取り、それをサイト上に反映させるようなイメージです。

まずは、{% schema %}の解説をします。

{% schema %}について

{% schema %}
// 設定
{% endschema %}

上記のように、schemaタグの中に設定を記述します。

主な構成は以下の通りです。

 


{% schema %}
{
  "name": {
    "ja": "セクション名"
  },
  "class": "セクションに自動で追加されるclass名",
  "blocks": [
    // 画像や商品など数が増える可能性がある設定を記述する
  ],
  "settings": [
    // 見出しやテキストなど数が増えない設定を記述する
  ],
  "presets": [
    {
      "name": {
        "ja": "管理画面のセクション一覧に表示されるセクション名"
      },
      "category": {
        "ja": "管理画面のセクション一覧のグループに表示される名前"
      }
    }
  ]
}
{% endschema %}

 

settingsblocksがややこしいので、こちらを解説します。

他のプロパティは上記の通りです。

 

基本的にはsettingsに設定を追加していきます。

settingsは、以下のように記述します。

 

"settings": [
    {
      "type": "checkbox",
      "id": "is_visivle",
      "label": {
        "ja": "表示する?"
      },
      "info": {
        "ja": "チェックを入れると表示、外すと非表示になります。"
      }
    },
    {
      "type": "textarea",
      "id": "text",
      "label": {
        "ja": "本文"
      },
      "default": {
        "ja": "default text. default text."
      }
    }
],

 

プロパティ名解説
type設定の種類。

一行のテキストボックスの場合はtext、複数行の場合はtextarea、チェックボックスの場合はcheckboxのように記述します。

種類によって戻り値が異なり、textの場合は入力したテキスト、checkboxの場合はtrue/falseで返ってきます。

他にも画像や商品、コレクションなども設定できます。

詳しくは公式ドキュメントを参照ください。

id一意のユニークな値を設定します。

このid名を使い、liquid側で設定した値を呼び出します。

変数名のようなイメージです。

label管理画面に表示される設定の名前
info管理画面に表示される設定の説明文
default設定のデフォルト値

typetextの場合、default: "デフォルトテキスト"のように記述しておくと、「デフォルトテキスト」が最初から入力された状態になります。

 

 

blocksは、以下のように記述します。

 

"blocks":[
  {
    "type": "custom",
    "name": {
      "ja": "画像"
    },
    "limit": 3,
    "settings": [
      {
        "type": "image_picker",
        "id": "image_picker",
        "label": {
          "ja": "画像"
        }
      }
    ]
  }
],

 

プロパティ名解説
type基本的にsuctomにしておけば大丈夫だと思います。

公式ドキュメントを読んでも、blockstypeを何にすればいいのかイマイチ仕様がわかりませんでした…。

name管理画面に表示される設定の名前
limit設定を複数登録する場合の上限数
settings先程解説したsettingsで設定を定義します。

 

settingsblocksの違いですが、今回のサンプルセクションを例にすると、見出しやテキストのような設定する値が1つの場合はsettings商品や画像のような値を複数設定する可能性があるものblocksにする…のような違いがあります。

設定した値の呼び出し方

次に設定した値の呼び出し方を解説します。

settingsblocksで少々異なります。

 

しかし、どちらも共通する点もあり、それは設定した値が無い可能性があるので、それを考慮した書き方をすることです。

settingsdefaultでデフォルト値を設定していればいいですが、基本的には値がある場合のみタグを呼び出すような書き方をしましょう。

 

例えば、<p>{{ name }}</p>のような書き方をしていて、もしnameの値が無かったらサイト上では<p></p>ように出力されてしまいます。

なので、if文などで値があるなら…のような書き方をしましょう。

 

少し話がそれてしまいましたが、値の呼び出し方を解説していきます。

settingsを呼び出す

section.settings.idのように、オブジェクトとプロパティのような形式になります。

idsettingsidで設定した値です。

idtextで設定した場合、section.settings.textのようにして値を呼び出します。

blocksを呼び出す

settingsはひとつしか値がないので前述のような書き方で呼び出せるのですが、blocksは値が複数(配列)ある場合があるので、forで回して値を呼び出します。

 

{% for block in section.blocks limit: section.blocks.size %}
    {% if block.settings.image_picker != blank %}
        {{ block.settings.image_picker | img_url: '300×' | img_tag }}
    {% endif %}
{% endfor %}

サンプルコードでは、上記のように呼び出しています。

  1. section.blocksオブジェクトをforで回しblockに代入
  2. if文でblock.settings.image_pickerオブジェクトだったら、その値を呼び出す

まとめ

settings_data.jsonContent Schemaはかなりややこしい内容だったと思います。

私自身、完全には理解していません。

しかし、これらを少しでも使いこなせると、冒頭でも書きましたが柔軟な運用しやすいサイトを作れるようになるので、まずはぜひ試してみて下さい。

 

■バックナンバー

シェアする
フォローする
Web-Guided - web業界で働く方を少しだけ手助けするメディア