【Shopify】Liquid の Tag を全てまとめてみた

今回の記事では、ShopifyのLiquid tagを全てまとめてみました。

本記事は、Shopify公式ドキュメントを参考に、学習備忘録として書いておりますので、間違いがあれば優しく指摘して頂けると幸いです。

Liquid Tagとは

Liquid Tagは、Templateに対して、制御フローや繰り返し処理を指示するものになります。

Liquid Tagは、{% %}で囲んで使用します。

Liquid Tagには、以下の 5 種類があります。

それぞれについて見ていきましょう!!

Liquid Tag

Control flow tags

Control flow tags はその名の通り、制御フローを作成するタグです。

簡単にいうと、Liquidコードのブロックが実行されるかどうかを判断する条件を作成するタグです。

Control flow tag を見てみましょう。

if

条件が満たされた場合( 結果が true )のみ、コードブロックを実行します。

{% if product.title == 'UnReact' %}
    You are buying some UnReact!
{% endif %}

You are buying some UnReact!

unless

条件が満たされていない場合( 結果が false ) のみ、コードブロックを実行します。

{% unless product.title == 'UnReact' %}
    You are not buying UnReact.
{% endunless %}

You are not buying UnReact.

下記のように、unlessは、条件文で!=を用いることで、if文に書き直すこともできます。

!=は、左辺と右辺が等しくないときにtrueを返す演算子です。

{% if product.title != 'UnReact' %}
    You are not buying UnReact.
{% endif %}

elsif / else

if または unless ブロックに条件を追加することができます。

elsifは、ifと同様に、条件を指定することができ、trueが返されたときに中身が実行されます。

elseは、条件は書かず、ifelsifで書いた条件以外の時に中身が実行されます。

{% if shipping_method.title == 'International Shipping' %}
    You're shipping internationally. Your order should arrive in 2–3 weeks.
{% elsif shipping_method.title == 'Domestic Shipping' %}
    Your order should arrive in 3–4 days.
{% else %}
    Thank you for your order!
{% endif %}

Your order should arrive in 3–4 days.

また、andor演算子を使用することで、制御フロータグに複数の条件を含めることができます。

複数のandor演算子を使用する場合、and演算子が先に評価され、次にor演算子が評価されます。

括弧()を使用しても、Liquidタグ内では括弧は無効化されるため、制御することはできません。

#and

条件の左側と右側の両方が true のときに、true を返します。

{% if line_item.grams > 20000 and customer_address.city == 'Ottawa' %}
    You're buying a heavy item, and live in the same city as our store. Choose local pick-up as a shipping option to avoid paying high shipping costs.
{% endif %}

You're buying a heavy item, and live in the same city as our store. Choose local pick-up as a shipping option to avoid paying high shipping costs.

#or

条件の左側と右側のどちらか一方が true のときに。true を返します。

{% if customer.tags contains 'VIP' or customer.email contains 'mycompany.com' %}
    Welcome! We're pleased to offer you a special discount of 15% on all products.
{% else %}
    Welcome to our store!
{% endif %}

Welcome! We're pleased to offer you a special discount of 15% on all products.

case / when

変数の値によって条件分岐をしたいときに使用します。

caseには、変数名を指定し、whenには、条件分岐する変数の値を指定します。

whenブロックを追加することで、条件分岐を増やすことができます。

elseの中身は、whenで指定した値以外の値を変数が持つときに実行されます。

オプションで case の最後に else 文を追加して、条件が満たされなかった場合に実行するコードを提供することができます。

{% case shipping_method.title %}
    {% when 'International Shipping' %}
         You're shipping internationally. Your order should arrive in 2–3 weeks.
    {% when 'Domestic Shipping' %}
        Your order should arrive in 3–4 days.
    {% when 'Local Pick-Up' %}
        Your order will be ready for pick-up tomorrow.
    {% else %}
        Thank you for your order!
{% endcase %}

Your order should arrive in 3–4 days.

##Iteration tags
Iteration tags は、コードブロックの繰り返し処理を行うタグです。

Liquidでは、forcycletabelerowの三種類があり、それぞれのパーラメータも用意されています。

for

コードブロックの繰り返し実行ができます。

以下の例では、collection.productsの中に入っている全ての要素のtitle取り出して出力しています。

{% for product in collection.products %}
    {{ product.title }}
{% endfor %}

Fancy hat Snazzy shirt Dapper pants

このようにforでは、繰り返し処理がかけます。

forは出力できる最大数が決まっており、1ページあたり最大50件を出力できます。

それ以上出力する場合は、paginateタグを使用して複数ページに分割する必要があります。

pagenateタグは、後のTheme tagsで紹介しています。

for ループ内だけで使用できるforloopには、forの属性が入っており、以下の7つがあります。

  • **forloop.first:**一回目の処理のときにtrue、二回目以降の処理のときにfalseを返します。
  • **forloop.index:**現在の処理のインデックス番号を 1 から順に返します。
  • **forloop.index0:**現在の処理のインデックス番号を 0 から順に返します。
  • **forloop.last:**最後の処理のときにtrue、それ以外の処理のときfalseを返します。
  • **forloop.length:**forループで、行われる処理の回数を表示します。
  • forloop.rindex:forloop.indexを逆順に返します。
  • forloop.rindex0:forloop.index0を逆順で返します。

使用例については、The forloop object を御覧ください。

次に、forタグ内で使用されるタグについて見ていきます。

#else

ループの長さがゼロのときに、elseで書いた処理が実行されます。
商品が一つも登録されていない可能性があるコレクションを、forでループする際に使用します。

{% for product in collection.products %}
    {{ product.title }}
{% else %}
    The collection is empty.
{% endfor %}

The collection is empty.

#break

繰り返し処理をが終了します。

以下の例では、i = 4 の時に、{% break %}が実行されます。

そして、i = 5 の処理は実行せずに繰り返し処理が終了します。

{% for i in (1..5) %}
    {% if i == 4 %}
        {% break %}
    {% else %}
        {{ i }}
    {% endif %}
{% endfor %}

1 2 3

#continue

繰り返し処理を終了せずに、あるインデックス番号をスキップする際に使用します。

以下のように書くことで、インデックス番号 4 を飛ばして、その後も繰り返し処理を続ける事ができます。

{% for i in (1..5) %}
    {% if i == 4 %}
        {% continue %}
    {% else %}
        {{ i }}
    {% endif %}
{% endfor %}

1 2 3 5

for のパラメータ

#limit

指定した回数で、forループ処理を終了します。

以下の例では、limit2 が指定してあるので、処理が2回繰り返されます。

<!-- numbers = [1,2,3,4,5] -->

{% for item in numbers limit:2 %}
    {{ item }}
{% endfor %}

1 2

#offset

指定した数の処理を飛ばして、次の処理から繰り返されます。

以下の例では、offset2 が指定してあるので、処理を2回飛ばして、3回目の処理から実行されます。

<!-- numbers = [1,2,3,4,5] -->

{% for item in numbers offset:2 %}
    {{ item }}
{% endfor %}

3 4 5

#range

繰り返し処理をする範囲を決めることができます。

範囲の指定は、{% for i in (3..5) %}のように、**(数値..数値)**と指定します。

範囲は4などのリテラル値と、my_limitなどの変数値を用いて指定することができます。

{% for i in (3..5) %}
    {{ i }}
{% endfor %}

{% assign my_limit = 4 %}
{% for i in (1..my_limit) %}
    {{ i }}
{% endfor %}

3 4 5

1 2 3 4

#reversed

繰り返し処理を行う順番を逆にします。

<!-- if array = [1,2,3,4,5,6] -->
{% for item in array reversed %}
    {{ item }}
{% endfor %}

6 5 4 3 2 1

cycle

cycleが呼ばれるたびに、パラメータとして渡された文字列を順番に一つだけ出力します。

以下の例では、cycleが一回目呼ばれたときに、最初にパラメータに渡したoneが出力され、二回目を呼ぶと次はtwoが出力されます。

渡したパラメータがすべて出力されたときは、最初のパラメータに戻り、その文字列が出力されます。

{% cycle 'one', 'two', 'three' %}
{% cycle 'one', 'two', 'three' %}
{% cycle 'one', 'two', 'three' %}
{% cycle 'one', 'two', 'three' %}

one
two
three
one

forタグと一緒に使用することで、呼び出されるごとに異なる文字列を出力できる処理が書けます。

cycle のパラメータ

cycleは、1つのテンプレート内に複数cycleブロックが必要な場合に、cycle groupと呼ばれるパラメータを持つことができます。

以下の例を参考に、なぜパラメータが必要か見ていきましょう。

まずは、cycleにパラメータを渡していない場合です。

<ul>
    {% for product in collections.collection-1.products %}
        <li{% cycle ' style="clear:both;"', '', '', ' class="last"' %}>
            <a href="{{ product.url | within: collection }}">
                <img src="{{ product.featured_image.src | img_url: '240x' }}" alt="{{ product.featured_image.alt }}" />
            </a>
        </li>
    {% endfor %}
</ul>

<ul>
    {% for product in collections.collection-2.products %}
        <li{% cycle ' style="clear:both;"', '', '', ' class="last"' %}>
            <a href="{{ product.url | within: collection }}">
                <img src="{{ product.featured_image.src | img_url: '240x' }}" alt="{{ product.featured_image.alt }}" />
            </a>
        </li>
    {% endfor %}
</ul>

<ul>
  <li style="clear:both"></li>
  <li></li>
</ul>

<ul>
  <li></li>
  <li class="last"></li>
  <li style="clear:both"></li>
  <li></li>
</ul>

collection-1(コレクション)に2つの商品、collection-2 に4つの商品がが登録されている時を考えます。

colleciton-1には、2つの商品が登録してあるのでforは、二回繰り返し処理をします。

そのため、cycleも、二回実行されます。

その後、collection-2(コレクション)のfor内でcycleが実行されるときに、collection-1で実行したcycleの続きとして実行されるので、3回目として実行されます。

なので、

パラメータがない場合、cycleは独立して実行することができません。

次に、パラメータを渡した場合です。

<ul>
    {% for product in collections.collection-1.products %}
        <li{% cycle 'group1': ' style="clear:both;"', '', '', ' class="last"' %}>
            <a href="{{ product.url | within: collection }}">
                <img src="{{ product.featured_image.src | img_url: '240x' }}" alt="{{ product.featured_image.alt }}" />
            </a>
        </li>
    {% endfor %}
</ul>

<ul>
    {% for product in collections.collection-2.products %}
        <li{% cycle 'group2': ' style="clear:both;"', '', '', ' class="last"' %}>
            <a href="{{ product.url | within: collection }}">
                <img src="{{ product.featured_image.src | img_url: '240x' }}" alt="{{ product.featured_image.alt }}" />
            </a>
        </li>
    {% endfor %}
</ul>

<ul>
  <li style="clear:both"></li>
  <li></li>
</ul>

<!-- new cycle group starts! -->
<ul>
  <li style="clear:both"></li>
  <li></li>
  <li></li>
  <li class="last"></li>
</ul>

collection-1(コレクション)にgroup1、collection-2 にgroup2のパラメータを渡して、パラメータの値に先ほどと同様の文字列を設定しています。

colleciton-1でも、collection-2でも最初の<li>タグに、style="clear:both"を渡せています。

このように、パラメータを与えることで、同じページでcycleを複数用いたとしても独立させることが可能です。

tablerow

HTML tableの行を作成します。

<tablerow>タグを使用する際は、<table>タグでラップして使用します。

<table>
    {% tablerow product in collection.products %}
        {{ product.title }}
    {% endtablerow %}
</table>

<table>
  <tr class="row1">
    <td class="col1">
      Cool Shirt
    </td>
    <td class="col2">
      Alien Poster
    </td>
    <td class="col3">
      Batman Poster
    </td>
    <td class="col4">
      Bullseye Shirt
    </td>
    <td class="col5">
      Another Classic Vinyl
    </td>
    <td class="col6">
      Awesome Jeans
    </td>
  </tr>
</table>

<table>
<tr class="row1">
<td class="col1">
Cool Shirt
</td>
<td class="col2">
Alien Poster
</td>
<td class="col3">
Batman Poster
</td>
<td class="col4">
Bullseye Shirt
</td>
<td class="col5">
Another Classic Vinyl
</td>
<td class="col6">
Awesome Jeans
</td>
</tr>
</table>

tablerowループ内で使用できる属性は以下の11つです。

  • tablerow.length:繰り返し回数を返す
  • tablerow.index:現在のインデックスを1から返す
  • tablerow.index():現在のインデックスを0から返す
  • tablerow.rindex:tablerow.indexを逆から返す
  • tablerow.rindex():tablerow.index0を逆から返す
  • tablerow.first:一回目の処理の時、trueを返し、二回目以降は、falseを返す
  • tablerow.last:ループの最後の処理の時、trueを返し、それ以外の処理は、falseを返す
  • tablerow.col:1から始まる、現在の行のインデックスを返す
  • tablerow.col():0から始まる、現在の行のインデックスを返す
  • tablerow.col_first:現在の列が行の最初の列であればtrueを返し、二列目以降のとき、falseを返す
  • tablerow.col_last:現在の列が行内の最後の列であればtrueを返し、それ以外の時、falseを返す

tablerow のパラメータ

tablerowタグで使用できるパラメータは、colslimitoffsetrangeの4つです。

パラメータを使うことで、表の列数やセル数を設定することができます。

#cols

列の数を変更できます。

cols:2とすると、表が 2 列で表示されます。

<table>
    {% tablerow product in collection.products cols:2 %}
        {{ product.title }}
    {% endtablerow %}
</table>

<table>
  <tr class="row1">
    <td class="col1">
      Cool Shirt
    </td>
    <td class="col2">
      Alien Poster
    </td>
  </tr>
  <tr class="row2">
    <td class="col1">
      Batman Poster
    </td>
    <td class="col2">
      Bullseye Shirt
    </td>
  </tr>
  <tr class="row3">
    <td class="col1">
      Another Classic Vinyl
    </td>
    <td class="col2">
      Awesome Jeans
    </td>
  </tr>
</table>

<table>
<tr class="row1">
<td class="col1">
Cool Shirt
</td>
<td class="col2">
Alien Poster
</td>
</tr>
<tr class="row2">
<td class="col1">
Batman Poster
</td>
<td class="col2">
Bullseye Shirt
</td>
</tr>
<tr class="row3">
<td class="col1">
Another Classic Vinyl
</td>
<td class="col2">
Awesome Jeans
</td>
</tr>
</table>

#limit

limitで設定した数だけ繰り返し、表を表示します。

以下の例では、3個のセルが二列で表示されます。

{% tablerow product in collection.products cols:2 limit:3 %}
    {{ product.title }}
{% endtablerow %}

<table>
  <tr class="row1">
    <td class="col1">
      Cool Shirt
    </td>
    <td class="col2">
      Alien Poster
    </td>
  </tr>
  <tr class="row2">
    <td class="col1">
      Batman Poster
    </td>
  </tr>
</table>

<table>
  <tr class="row1">
    <td class="col1">
Cool Shirt</td>
    <td class="col2">
Alien Poster</td>
  </tr>
  <tr class="row2">
<td class="col1">
Batman Poster</td>
  </tr>
</table>

#offset

offsetで指定した次のインデックスから繰り返し処理を始めます。

以下の例では、offset:3となっているのでインデックスが 4 のところから表が作成されます。

{% tablerow product in collection.products cols:2 offset:3 %}
    {{ product.title }}
{% endtablerow %}

<table>
  <tr class="row1">
    <td class="col1">
      Bullseye Shirt
    </td>
    <td class="col2">
      Another Classic Vinyl
    </td>
  </tr>
  <tr class="row2">
    <td class="col1">
      Awesome Jeans
    </td>
  </tr>
</table>

<table>
<tr class="row1">
<td class="col1">
Bullseye Shirt
</td>
<td class="col2">
Another Classic Vinyl
</td>
</tr>
<tr class="row2">
<td class="col1">
Awesome Jeans
</td>
</tr>
</table>

#range

ループする数値の範囲を指定できます。

範囲は、forのときと同様で、リテラル値と変数値の両方で定義することができます。

<table>
    {% tablerow i in (3..5) %}
        {{ i }}
    {% endtablerow %}
</table>

{% assign num = 4 %}
<table>
    {% tablerow i in (1..num) %}
        {{ i }}
    {% endtablerow %}
</table>

##Theme tags
Theme tags は、template固有のHTMLマークアップの出力や、layoutやsnippetsのレンダー、配列を複数ページに分割等ができます。

comment

Liquidテンプレート内にレンダリングされないコードを残すことができます。

My name is Wilson Abercrombie{% comment %}, esquire{% endcomment %}.

My name is Wilson Abercrombie.

echo

レンダリングされた HTML 内の式を出力します。

{{ }}で式を囲んで実行するのと同じ挙動をします。

以下の例のように、echoは、後で紹介する{% liquid %} タグ内で使用します。

{% liquid
  if product.featured_image
    echo product.featured_image | img_tag
  else
    echo 'product-1' | placeholder_svg_tag
endif %}

<img src="//cdn.shopify.com/s/files/1/0159/3350/products/red_shirt_small.jpg?v=1398706734" alt="Red Shirt Small" />

form

エンドポイントに対してフォームを送信するために必要な HTML <input>タグと<form>タグを同時に作成します。

{% form 'new_comment', article %}
  ...
{% endform %}

Shopifyテーマで作成できるフォームには、カートに商品を追加するフォームや、顧客アカウントを作成するフォームなど様々な種類があります。

カートに商品を追加したり、顧客アカウントを作成したりするフォームを作成するときは、それぞれ異なる属性を持つ<form><input>が必要になります。

formで使用できる属性とパラメータを見ていきましょう。

#activate_customer_password

activate_account.liquid テンプレート内で顧客アカウントにアクセスするためのフォームを作成します

{% form 'activate_customer_password' %}
    ...
{% endform %}

<form accept-charset="UTF-8" action="https://my-shop.myshopify.com/account/activate" method="post">
  <input name="form_type" type="hidden" value="activate_customer_password" />
  <input name="utf8" type="hidden" value="✓" />
  ...
</form>

#contact

コンタクトフォームからメールを送信するためのフォームを作成します。

{% form 'contact' %}
  ...
{% endform %}

<form accept-charset="UTF-8" action="/contact" class="contact-form" method="post">
  <input name="form_type" type="hidden" value="contact" />
  <input name="utf8" type="hidden" value="✓" />
  ...
</form>

#currency

通貨を変更するためのフォームを作成します。

このフォームは currency_selector フィルタと一緒に使用することや、 cart.currency および shop.enabled_currencies を使用して独自の通貨セレクターを作成することもできます。

次の例では、 currency_selector フィルタを通貨フォームで使用しています。

{% form 'currency' %}
    {{ form | currency_selector }}
    <button type="submit">Submit</button>
{% endform %}

次の例では、カスタマイズされた通貨セレクターが通貨フォームで使用されています。

{% form 'currency' %}
    <select name="currency">
        {% for currency in shop.enabled_currencies %}
            {% if currency == cart.currency %}
                <option selected="true">{{currency.iso_code}}</option>
            {% else %}
                <option>{{currency.iso_code}}</option>
            {% endif %}
        {% endfor %}
    </select>
    <button type="submit">Submit</button>
{% endform %}

#customer

新規アカウントを登録せずに新規顧客を作成するためのフォームを生成します。

このフォームは、ニュースレターの登録からメールリストを構築するなど、顧客にログインしてほしくない場合に顧客情報を収集するのに便利です。

顧客アカウントを登録するフォームを生成するには、create_customerフォームを使用します。

{% form 'customer' %}
    ...
{% endform %}

<form method="post" action="/contact#contact_form" id="contact_form" class="contact-form" accept-charset="UTF-8">
  <input type="hidden" value="customer" name="form_type">
  <input type="hidden" name="utf8" value="✓">
  ...
</form>

#create_customer

register.liquid テンプレート内で新規顧客アカウントを作成するためのフォームを生成します。

{% form 'create_customer' %}
    ...
{% endform %}

<form accept-charset="UTF-8" action="https://my-shop.myshopify.com/account" id="create_customer" method="post">
  <input name="form_type" type="hidden" value="create_customer" />
  <input name="utf8" type="hidden" value="✓" />
   ...
</form>

#cuctomer_address

addresses.lquid テンプレート上で顧客アカウントのアドレスを作成または編集するためのフォームを生成します。

新しいアドレスを作成するときは、パラメータとしてcustomer.new_addressを指定します。

既存のアドレスを編集する場合は、パラメータにaddressを指定します。

{% form 'customer_address', customer.new_address %}
    ...
{% endform %}

<form accept-charset="UTF-8" action="/account/addresses/70359392" id="address_form_70359392" method="post">
  <input name="form_type" type="hidden" value="customer_address" />
  <input name="utf8" type="hidden" value="✓" />
...
</form>

#customer_login

login.liquidテンプレートで顧客アカウントにログインするためのフォームを作成します。

{% form 'customer_login' %}
    ...
{% endform %}

<form accept-charset="UTF-8" action="https://my-shop.myshopify.com/account/login" id="customer_login" method="post">
  <input name="form_type" type="hidden" value="customer_login" />
  <input name="utf8" type="hidden" value="✓" />
...
</form>

#guest_login

login.liquidテンプレートにゲストログインするためのフォームを作成します。

{% form 'guest_login' %}
    ...
{% endform %}

<form method="post" action="https://my-shop.myshopify.com/account/login" id="customer_login_guest" accept-charset="UTF-8">
  <input type="hidden" value="guest_login" name="form_type">
  <input type="hidden" name="utf8" value="✓">
...
  <input type="hidden" name="guest" value="true">
  <input type="hidden" name="checkout_url" value="https://checkout.shopify.com/store-id/checkouts/session-id?step=contact_information">
</form>

#new_comment

article.liquidテンプレートで新しいコメントを作成するためのフォームを作成します。

パラメータとして、articleオブジェクトが必要となります。

{% form 'new_comment', article %}
...
{% endform %}

<form accept-charset="UTF-8" action="/blogs/news/10582441-my-article/comments" class="comment-form" id="article-10582441-comment-form" method="post">
  <input name="form_type" type="hidden" value="new_comment" />
  <input name="utf8" type="hidden" value="✓" />
...
</form>

#product

カートに商品を追加するためのフォームを作成します。

パラメータとして、productオブジェクトが必要となります。

{% form "product", product %}
  ...
{% endform %}

<form method="post" action="/cart/add" enctype="multipart/form-data">
  <input type="hidden" name="form_type" value="product">
  <input type="hidden" name="utf8" value="✓">
...
</form>

#recover_customer_password

login.liquidテンプレートで消されたパスワードを回復するためのフォームを作成します。

{% form 'recover_customer_password' %}
...
{% endform %}

<form accept-charset="UTF-8" action="/account/recover" method="post">
  <input name="form_type" type="hidden" value="recover_customer_password" />
  <input name="utf8" type="hidden" value="✓" />
...
</form>

#reset_customer_password

顧客がパスワードをリセットするためのフォームをcustomers/reset_password.liquidテンプレートに作成します。

{% form 'reset_customer_password' %}
...
{% endform %}

<form method="post" action="https://my-shop.myshopify.com/account/account/reset" accept-charset="UTF-8">
  <input type="hidden" value="reset_customer_password" name="form_type" />
  <input name="utf8" type="hidden" value="✓" />
...
  <input type="hidden" name="token" value="408b680ac218a77d0802457f054260b7-1452875227">
  <input type="hidden" name="id" value="1080844568">
</form>

#storefront_password

パスワードで保護されたストアフロントを入力するためのpassword.liquidテンプレート上のフォームを作成します。

{% form 'storefront_password' %}
...
{% endform %}

<form method="post" action="/password" id="login_form" class="storefront-password-form" accept-charset="UTF-8">
  <input type="hidden" value="storefront_password" name="form_type">
  <input type="hidden" name="utf8" value="✓">
...
</form>

#<form>の属性の変更・追加

<form>要素を作成するとき、classidなどの属性を変更したり、新しい属性を追加したりすることができます。

追加または修正したい属性をformタグに名前付きパラメータとして含め、値を代入することで追加、変更することができます。

{% form "product", product, id: "newID", class: "custom-class", data-example: "100" %}
...
{% endform %}

<form method="post" action="/cart/add" id="newID" class="custom-class" data-example="100" enctype="multipart/form-data">
  <input type="hidden" name="form_type" value="product">
  <input type="hidden" name="utf8" value="✓">
...
</form>

以下のように、Liquid 変数をパラメータとして使用することもできます。

{% capture 'form_id' %}addToCartForm-{{ section.id }}{% endcapture %}

{% form 'product', product, id:form_id %}
...
{% endform %}

<form action="/cart/add" method="post" enctype="multipart/form-data" id="addToCartForm-36197306239">
  <input type="hidden" name="form_type" value="product">
  <input type="hidden" name="utf8" value="✓">
...
</form>

layout

テーマのLayoutフォルダから代替レイアウトファイルを使用するには、テンプレートファイルの先頭に{% layout 'alternate' %}を含めてください。代替レイアウトを定義しない場合、デフォルトでは theme.liquid テンプレートファイルが使用されます。

{% layout 'full-width' %}

レイアウトファイルを使用しないテンプレートを使用したい場合は、レイアウトとして none を指定することができます。

{% layout none %}

liquid

{% liquid %} の中に case や when などの複数のタグを書き込むことができます。

echoタグと一緒に使用することで、HTMLの式を出力することもできます。

{% liquid
case section.blocks.size
when 1
    assign column_size = ''
when 2
    assign column_size = 'one-half'
when 3
    assign column_size = 'one-third'
else
    assign column_size = 'one-quarter'
endcase %}

paginate

forタグと一緒に使用することでコンテンツを複数のページに分割できます。

forループでは、1ページあたり50個の商品やブログ、検索結果しか載せられないため、表示数が多くなったときに使用します。

また、paginateタグには、byパラメータがあり、byパラメータに1から50の整数を指定することで、1ページあたりの表示数を設定できます

以下の例では、{% paginate collection.products by 5 %}とすることで、1ページに5個の項目を出力しています。

{% paginate collection.products by 5 %}
    {% for product in collection.products %}
        <!--show product details here -->
    {% endfor %}
{% endpaginate %}

paginateタグ内では、paginate オブジェクトの属性にアクセスすることができます。

pagineteオブジェクトには、生成されたページ内をナビゲートするために必要なリンクを出力する属性が含まれます。

paginate タグ内で使用できる属性は以下の8つです。

  • paginate.current_offset:現在のページよりも前のページに有るアイテムの総数を返します。
    例えば、1ページに載せるアイテムを5個にしておいて、3ページ目にいるとき、paginate.current_offset10を返します。
  • paginate.current_page:現在のページ番号を返します。最初は1です。
  • paginate.items:ページ分割するアイテムの総数を返します。
    例えば、120個の商品が登録されたコレクションをページ分割する場合、page.itemsは、120を返します。
  • paginate.parts:ページ分割のすべてのpartの配列を返します。
    paginate.parts 配列が返す各 part は、ページネーションのナビゲーションのリンクを表します。
  • paginate.next:現ページの次ページのリンクの part 変数を返します。
  • paginate.previous:現ページの前ページのリンクの part 変数を返します。
  • paginate.page_size:ページごとに表示されるアイテム数を返します。
  • paginate.pagespaginationタグによって作成されたページ数を返します。

raw

ページ上のLiquidコードをそのまま出力できるようにします。

以下の例では、{{ 5 | plus: 6 }}がそのまま出力されています。

{% raw %}{{ 5 | plus: 6 }}{% endraw %} equals 11.

{{ 5 | plus: 6 }} equals 11.

render

テーマのsnippetsフォルダからスニペットをレンダリングすることができます

renderタグは、非推奨タグの include の代わりに使用されます。

スニペットを指定する際に、.liquid拡張子は書かなくても大丈夫です。

{% render 'snippet-name' %}

スニペットがレンダリングされるとき、レンダリングした親ファイルとスニペットで同じ変数を使用していても親の変数の値は自動的に代入されません。

同様に、スニペット内で定義された変数は、スニペット外のコードからはアクセスできません。

このように他のファイルからのアクセスをできなくすることでパフォーマンスの向上と保守性が確保できます。

次に、renderタグで使用される3つのパラメータ(変数、withfor)について見ていきます。

#変数

以下の例のようにrenderタグのパラメータとして変数を指定することで、スニペットの変数に値を渡すことができます。

例では、name.liquidという名前のスニペットファイル内で定義されているmy_variableやmy_other_variableの変数に値を代入しています。

{% assign my_variable = 'apples' %}
{% render 'name', my_variable: my_variable, my_other_variable: 'oranges' %}

グローバルオブジェクトは、すべてのファイルからアクセスが可能になるので渡す必要は無いです。

※スニペット内で親テンプレートで定義されている変数を変更しても、親テンプレートの値は上書きされません。

#with

withasパラメータを使用することで、単一のオブジェクトをスニペットに渡すことができます。

下記の例では、スニペットのproductという変数に、featured_productという親テンプレートで使用されている変数の値を入れてレンダリングすることができます。

{% assign featured_product = all_products['product_handle'] %}
{% render 'product' with featured_product as product %}

#for

forasパラメータを使用することで、オブジェクトの各値に対してスニペットを一度だけレンダリングすることができます。

下記の例では、商品の各バリエーションごとにスニペットが一回レンダリングされます。

{% assign variants = product.variants %}
{% render 'variant' for variants as variant %}

asパラメータで指定しているvariantはスニペット内の商品バリエーションのオブジェクトを持ちます。

forパラメータを使用すると、スニペット内で、forloopオブジェクトにもアクセスすることができます。

section

テーマのsectionフォルダから静的なセクションをレンダリングします。

以下の例のように、Templateのページ内で{% section 'header' %}と書くことで、sectionフォルダのheader.liquidファイルを呼び出すことができます。

{% section 'header' %}

<div id="shopify-section-header" class="shopify-section">
  
</div>

style

HTMLの<style>タグを生成できます。

{% style %}タグを使用するときは、末尾に{% endstyle %}を書く必要があります。

以下の例のように、{% style %}タグ内に、sectionファイルで定義したbackground-colorTemplate(各ページ)に反映させることもできます。

{% style %}
  .hero__background-color-container {
    background-color: {{ section.settings.background_color }}
  }
{% endstyle %}

##Variable tags
Variable tags は、Liquidの変数を定義するときに使用します。

assign

名前付き変数を定義できます

以下の1つ目の例では、favorite_foodに、applesという文字列、
2つ目の例では、first_time_visitorに、trueというboolean値を定義しています。

変数の値を出力したいときは、定義した変数を{{ }}で囲みます。

{% assign favorite_food = 'apples' %}

My favorite food is {{ favorite_food }}.

My favorite food is apples.

{% assign first_time_visitor = true %}
{% if first_time_visitor == true %}
    Welcome to the site!
{% endif %}

Welcome to the site!

capture

{% capture 変数名 %} 値 {% endcapture %}とすることで、変数を定義できます

変数の値は文字列として、代入されます。

{% assign %}タグと違い、{% capture %}タグは複数行の値を定義することが出来ます。

以下の例のように、assignで定義された変数を使用して、複雑な文字列を定義するすることも可能です。

{% assign favorite_food = 'pizza' %}
{% assign age = 35 %}

{% capture about_me %}
I am {{ age }} and my favorite food is {{ favorite_food }}.
{% endcapture %}

{{ about_me }}

I am 35 and my favorite food is pizza.

increment

値に数値(number)を持つ変数を作成することができる

変数の初期値は0で、変数がincrementタグで呼び出されるたびに、1プラスされます。

以下の例のように、リスト項目ごとに一意の番号つきクラスを作成したいときなどに使用します。

<ul>
    <li class="item-{% increment counter %}">apples</li>
    <li class="item-{% increment counter %}">oranges</li>
    <li class="item-{% increment counter %}">peaches</li>
    <li class="item-{% increment counter %}">plums</li>
</ul>

<ul>
  <li class="item-0">apples</li>
  <li class="item-1">oranges</li>
  <li class="item-2">peaches</li>
  <li class="item-3">plums</li>
</ul>

ここで注意が必要なのですが、incrementで定義された変数とassigncaptureで定義された変数は、異なる変数として扱われます。

以下の例を見てみます。

まず、assignを用いてmy_numberという変数を定義しています。

そして、同じ変数名に対してincrementタグを使用します。

そのあとに、{{ my_number }}とすると10と出力されます。

このように、assigncaptureで定義された変数とincrementで定義された変数は全く違うものとして扱われるため、同じ変数名を使用しないようにする必要があります。

{% assign my_number = 10 %}

{% increment my_number %}
{% increment my_number %}
{% increment my_number %}

{{ my_number }}

0
1
2

10

decrement

値に数値(number)を持つ変数を作成することができる

変数の初期値は-1で、変数がdecrementタグで呼び出されるたびに、1マイナスされます。

先程のincrementと同様に、assigncaptureで定義された変数とdencrementで定義された変数は全く違うものとして扱われるため、同じ変数名を使用しないようにする必要があります。

{% decrement variable %}
{% decrement variable %}
{% decrement variable %}

-1
-2
-3

##Deprecated tags
Deprecated tags は、非推奨のタグになります。

Deprecated tags は、まだいくつかのテーマで使用されていますが、可読性や保守性が低下するので代替タグを使用することが推奨されております。

include

テーマのsnippetsフォルダからスニペットファイルをレンダリングできます。

renderタグと同様にスニペットファイルをレンダリングするが、決定的な違いとしてスニペット内のコードが親テンプレート内の変数にアクセスして値を上書きすることが可能です。

スニペットが親の変数を勝手に変更していまう可能性があるため、可読性と保守性が低下します。

includeは、良くテーマ内で見かけるので、見つけた際にはぜひrenderタグに置き換えてみてください。

{% include 'snippet-name' %}

代替タグ:render

#終わりに
今回は、Liquid Tagについてまとめてみました。

結構多いので、Liquidを編集していてわからなくなった時に見ていただければと思います。

他にも、Shopify公式ドキュメントの和訳をしているのでそちらも参考にしていただけると幸いです。

お疲れさまでした。

Shopify アプリのご紹介

Shopify アプリである、「商品ページ発売予告アプリ | リテリア Coming Soon」は、商品ページを買えない状態のまま、発売日時の予告をすることができるアプリです。Shopify で Coming Soon 機能を実現することができます。

https://coming-soon.reterior.jp/

https://apps.shopify.com/shopify-application-314?locale=ja&surface_detail=リテリア&surface_inter_position=1&surface_intra_position=1&surface_type=search

おすすめ記事