前回の記事では、テーマブロックの概要と使用例についてご紹介しました。
今回は作成したコードを元に、テーマブロックファイルの書き方について説明します。記事の終わりにコードも記載していますので、ぜひご活用ください。
テーマブロック作成場所
テーマブロックファイルの作成場所は、 /blocks
フォルダです。/blocks
フォルダはShopifyによって作られていると思いますが、もし存在しない場合は作成してください。
テーマブロックファイルの書き方
前回作成した「指定した列数で表示するためのネスト可能なブロック(Gallery Block)」を使って、テーマブロックファイルの書き方を説明します。


以下は、Gallery Block用のテーマブロックファイルです。①マークアップと②スキーマのそれぞれについて、順に説明していきます。

① マークアップの記述
まず、ブロックに含めるHTML、Liquidを記述します。ポイントを2つ説明します。

ブロック設定へのアクセス
セクションブロックと同じく、テーマブロックでもブロックオブジェクトへアクセスすることができます。この例では、ブロックで設定したカラム数を{{ block.settings.layout_columns }} で参照しています。
他にも、親セクションのオブジェクトや、グローバルオブジェクトも参照することができます。(Liquidオブジェクトの使用について)
テーマブロックのレンダリング
{% content_for 'blocks' %}
はブロックを(動的に)レンダリングするための記述です。もしマーチャントに移動や削除をさせたくない場合は、{% content_for 'block' type:"type", id:"id" %}
で静的にレンダリングさせることもできます。(静的ブロックについて)
②スキーマの記述
ブロックを受け入れる(ネスト可能にする)方法とテーマエディタで操作できるようにする方法について説明します。ブロックスキーマの書き方については公式ドキュメントをご覧ください。

子要素(ブロック)の受け入れ
"blocks": [{ "type": "@theme" }]
は、テーマブロックを子要素として受け入れるための記述です。@theme の代わりにブロックを明示的に記述することで、個別のブロックを指定することもできます。@themeを指定した場合と、ブロックを明示的に記述した場合の例を載せていますので、見比べてみてください。
例)"blocks": [{ "type": "@theme" }]
の場合

例)"blocks": [{ "type": "image" }]
の場合

テーマエディターから追加できるための設定
セクションテーマと同じく、テーマエディタから追加できるようにするためにはpresets
を設定する必要があります。 presetsの設定については公式ドキュメントをご参照ください。
セクションファイルでテーマブロックを使えるようにする方法
テーマブロックを受け入れるために、セクションファイルにも必要な記述があります。テーマブロックファイル同様、テーマブロックを受け入れるために"blocks": [{ "type": "@theme" }]
を記述する必要があります。
{% content_for 'blocks' %}
はテーマブロックのレンダリングです。

おわりに
今回は、テーマブロックの使い方を紹介しました。テーマブロックで作成したブロックは、テーマエディタを使って様々なセクションで使い回すことができます。うまく活用すれば、今まで開発者へ依頼していたカスタマイズも、マーチャントで対応できるかもしれません。この記事が参考になれば幸いです。
(補足)コード
今回使ったコードを記載しますので、ぜひお試しください。
■ blocks/image.liquid
<div class="rw-image-block">
{% if block.settings.image %}
<img src="{{ block.settings.image | image_url: width:1000 }}" alt="{{ block.settings.alt_text }} " width="100%" height="auto">
{% endif %}
</div>
<style>
.rw-image-block {
width: 100%;
}
.rw-image-block img {
width: 100%;
height: auto;
}
.rw-image-text {
text-align: center;
margin-top: 10px;
}
</style>
{% schema %}
{
"name": "Image",
"settings": [
{
"type": "image_picker",
"id": "image",
"label": "Image"
},
{
"type": "text",
"id": "alt_text",
"label": "Alt Text",
"default": "This is ."
}
],
"presets": [
{
"name": "Image"
}
]
}
{% endschema %}
■ blocks/gallery-block.liquid
<style>
.rw-layout-group-container{
width: 100%;
display: grid;
grid-template-columns: repeat(1, 1fr);
gap: 20px;
}
.rw-layout-group-container.rw-column-2{
grid-template-columns: repeat(2, 1fr);
}
.rw-layout-group-container.rw-column-3{
grid-template-columns: repeat(3, 1fr);
}
.rw-layout-group-container.rw-column-4{
grid-template-columns: repeat(4, 1fr);
}
</style>
<div class="rw-layout-group-container rw-column-{{ block.settings.layout_columns }}">
{% content_for 'blocks' %}
</div>
{% schema %}
{
"name": "Gallery Block",
"blocks": [{ "type": "@theme" }, { "type": "@app" }],
"settings": [
{
"type": "header",
"content": "Layout Group"
},
{
"type": "range",
"id": "layout_columns",
"label": "Number of columns",
"min": 1,
"max": 4,
"step": 1,
"default": 1
}
],
"presets": [
{
"name": "Gallery Block"
}
]
}
{% endschema %}
■ sections/custom-section.liquid
<div class="custom-section-container">
<div class="custom-section color-{{ section.settings.color_scheme }}">
{% content_for 'blocks' %}
</div>
</div>
<style>
.custom-section-container {
display: flex;
justify-content: center;
}
.custom-section {
max: 100%;
max-width: 1080px;
}
</style>
{% schema %}
{
"name": "My Custom section",
"class": "my-section",
"tag": "section",
"blocks": [{ "type": "@theme" }, { "type": "@app" }],
"settings": [
{
"type": "header",
"content": "Color"
},
{
"type": "color_scheme",
"id": "color_scheme",
"label": "Color scheme",
"default": "scheme-1"
}
],
"presets": [
{
"name": "My Custom section"
}
]
}
{% endschema %}