Shopifyで独自のオンラインストアを構築・カスタマイズする際、避けては通れないのがテンプレート言語「Liquid」です。Liquidを理解し使いこなすことで、ストアのデザインや機能を柔軟にコントロールし、より魅力的で使いやすいEコマースサイトを実現できます。
この記事では、Shopifyテーマ開発に不可欠なLiquidの主要なオブジェクト、タグ、フィルタを網羅的に解説します。Liquidを学び始めた方から、日々の開発でリファレンスを求める方まで、幅広くご活用いただけるチートシート形式の技術ブログです。
Liquidとは?
Liquidは、Shopifyが開発したオープンソースのテンプレート言語です。Rubyで書かれており、Shopifyのテーマや通知メール、一部のアプリなどで、動的なコンテンツをサーバーサイドでレンダリングするために使用されます。HTMLに埋め込む形で記述され、ストアのデータベースから情報を取得し、ユーザーに表示する役割を担います。
Liquidの基本的な構文は主に3つの要素で構成されます。
-
オブジェクト (Objects):
{{ ... }}
二重波括弧で囲まれ、データを出力します。例えば、{{ product.title }}
は商品のタイトルを表示します。 -
タグ (Tags):
{% ... %}
波括弧とパーセント記号で囲まれ、ロジックや制御フロー(条件分岐やループなど)を記述します。 -
フィルタ (Filters):
|
パイプ記号を使用し、オブジェクトの出力形式を変更したり、特定の操作を加えたりします。例えば、{{ product.title | upcase }}
は商品タイトルを大文字で表示します。
それでは、具体的なLiquidの要素を詳しく見ていきましょう。
1. 主要なLiquidオブジェクト詳解 (Objects)
Liquidオブジェクトは、ページに動的なコンテンツを出力するためのデータを含んでいます。{{ object.property }}
のようにドット記法でプロパティにアクセスします。
order
(注文オブジェクト)
主に注文完了ページや通知メールで使用されるオブジェクトです。顧客の注文に関する詳細情報が含まれます。
-
order.name
: 注文番号 (例:#1001
) -
order.order_number
: 注文番号 (数値) -
order.email
: 顧客のメールアドレス -
order.customer_url
: 顧客アカウントページのURL -
order.financial_status
: 支払い状況 (例:paid
,pending
,voided
) -
order.fulfillment_status
: 配送状況 (例:fulfilled
,partial
,unfulfilled
) -
order.total_price
: 注文合計金額 (通貨フォーマット済み) -
order.subtotal_price
: 小計金額 -
order.total_tax
: 税金合計 -
order.total_shipping_price
: 送料合計 -
order.shipping_address
: 配送先住所オブジェクトorder.shipping_address.first_name
order.shipping_address.last_name
order.shipping_address.zip
order.shipping_address.city
order.shipping_address.country
-
order.billing_address
: 請求先住所オブジェクト (プロパティはshipping_address
と同様) -
order.line_items
: 注文商品アイテムの配列-
line_item.title
: 商品名 -
line_item.quantity
: 数量 -
line_item.original_price
: 単価 (割引前) -
line_item.final_price
: 単価 (割引後) -
line_item.line_price
: 合計金額 (数量 x 単価) -
line_item.image
: 商品画像オブジェクト -
line_item.product
: 商品オブジェクトへの参照 -
line_item.variant
: バリアントオブジェクトへの参照
-
-
order.customer
: 顧客オブジェクトorder.customer.first_name
order.customer.last_name
-
order.created_at
: 注文日時 -
order.note
: 注文メモ -
order.discounts
: 適用されたディスカウントの配列-
discount.code
: ディスカウントコード -
discount.amount
: 割引額 -
discount.savings
: 節約額
-
使用例:
{% if order.financial_status == 'paid' %}
<p>{{ order.name }} のお支払いは完了しています。</p>
<p>お届け先: {{ order.shipping_address.zip }} {{ order.shipping_address.city }}</p>
{% endif %}
product
(商品オブジェクト)
商品ページやコレクションページなどで、個々の商品情報を表示するために使用します。
-
product.title
: 商品名 -
product.handle
: 商品ハンドル (URLで使用される) -
product.description
: 商品説明 -
product.price
: 商品価格 (最安バリアントの価格) -
product.price_min
: 最安バリアントの価格 -
product.price_max
: 最高バリアントの価格 -
product.compare_at_price
: 割引前価格 (最安バリアント) -
product.available
: 商品が購入可能かどうか (true/false) -
product.featured_image
: メイン商品画像オブジェクト-
product.featured_image.src
: 画像URL -
product.featured_image.alt
: 画像のaltテキスト
-
-
product.images
: 商品画像の配列 -
product.variants
: 商品バリアントの配列-
variant.title
: バリアント名 -
variant.price
: バリアント価格 -
variant.sku
: SKU -
variant.available
: バリアントが購入可能かどうか
-
-
product.options
: 商品オプションの配列 (例: サイズ, 色) -
product.tags
: 商品タグの配列 -
product.type
: 商品タイプ -
product.vendor
: 販売元 -
product.url
: 商品ページのURL
使用例:
<h1>{{ product.title }}</h1>
<p>価格: {{ product.price | money }}</p>
{% if product.compare_at_price > product.price %}
<p>通常価格: <del>{{ product.compare_at_price | money }}</del></p>
{% endif %}
<img src="{{ product.featured_image | img_url: 'medium' }}" alt="{{ product.featured_image.alt | escape }}">
collection
(コレクションオブジェクト)
特定の商品グループ(コレクション)の情報を表示する際に使用します。
-
collection.title
: コレクション名 -
collection.handle
: コレクションハンドル -
collection.description
: コレクション説明 -
collection.image
: コレクション画像オブジェクト -
collection.products
: コレクション内の商品配列 -
collection.all_tags
: コレクション内の全商品タグ -
collection.url
: コレクションページのURL
使用例:
<h2>{{ collection.title }}</h2>
{% for prod in collection.products %}
<a href="{{ prod.url }}">{{ prod.title }}</a>
{% endfor %}
cart
(カートオブジェクト)
ショッピングカート内の情報を扱うオブジェクトです。
-
cart.item_count
: カート内のアイテム総数 -
cart.total_price
: カートの合計金額 -
cart.items
: カート内の商品アイテムの配列 (line_item
と同様のプロパティを持つ) -
cart.attributes
: カート属性 -
cart.note
: カートメモ
使用例:
<p>カート内の商品数: {{ cart.item_count }}</p>
<p>合計金額: {{ cart.total_price | money }}</p>
customer
(顧客オブジェクト)
顧客がログインしている場合や、アカウントページで顧客情報を表示する際に使用します。
-
customer.first_name
: 名 -
customer.last_name
: 姓 -
customer.email
: メールアドレス -
customer.tags
: 顧客タグ -
customer.orders
: 顧客の注文履歴の配列 -
customer.default_address
: デフォルト住所オブジェクト -
customer.addresses
: 登録住所の配列
使用例:
{% if customer %}
<p>ようこそ、{{ customer.first_name }} 様</p>
{% endif %}
shop
(ショップオブジェクト)
ストア全体の設定情報やグローバルな情報を持ちます。
-
shop.name
: ストア名 -
shop.domain
: プライマリードメイン -
shop.url
: ストアのベースURL -
shop.currency
: 通貨コード (例: JPY) -
shop.money_format
: 通貨表示フォーマット
使用例:
<footer>
<p>© {{ 'now' | date: "%Y" }} {{ shop.name }}</p>
</footer>
linklists
(ナビゲーションメニューオブジェクト)
ストアのナビゲーションメニュー(リンクリスト)の情報を持ちます。
-
linklists['main-menu'].links
: 'main-menu'ハンドルのメニューリンク配列-
link.title
: リンクタイトル -
link.url
: リンクURL -
link.active
: 現在のページに一致する場合true -
link.links
: 子リンクがある場合、その配列
-
使用例:
<nav>
<ul>
{% for link in linklists['main-menu'].links %}
<li {% if link.active %}class="active"{% endif %}>
<a href="{{ link.url }}">{{ link.title }}</a>
</li>
{% endfor %}
</ul>
</nav>
settings
(テーマ設定オブジェクト)
テーマエディタ(カスタマイザー)で設定された値にアクセスするために使用します。これらの値はテーマの config/settings_schema.json
ファイルで定義されます。
-
settings.logo_image
: (例) ロゴ画像 -
settings.color_primary
: (例) プライマリカラー
使用例:
{% if settings.logo_image %}
<img src="{{ settings.logo_image | img_url: 'master' }}" alt="{{ shop.name }} logo">
{% else %}
<h1>{{ shop.name }}</h1>
{% endif %}
<style>
body {
background-color: {{ settings.background_color | default: '#FFFFFF' }};
color: {{ settings.text_color | default: '#000000' }};
}
</style>
2. 必須Liquidタグガイド (Tags)
Liquidタグは、テンプレートのロジックや制御フローを記述します。{% tag %}
のように波括弧とパーセント記号で囲みます。
コメント
コード内に説明を残したり、一時的にコードを無効化したりするのに使用します。
-
{% comment %}
と{% endcomment %}
: 複数行コメント。このブロック内の内容はレンダリングされません。{% comment %} これは複数行コメントです。 ここには何でも書けます。 {% endcomment %}
-
{# これは単一行コメントです #}
: Liquid 5.0以降で導入された単一行コメント。Shopifyテーマチェックでも推奨される形式です。{# この行はレンダリングされません #}
制御フロータグ
条件に基づいて異なるコンテンツを表示したり、処理を分岐させたりします。
-
{% if condition %}
...{% elsif condition %}
...{% else %}
...{% endif %}
: 条件分岐{% if cart.item_count > 0 %} <p>カートに商品があります。</p> {% elsif customer %} <p>カートは空ですが、おすすめ商品があります。</p> {% else %} <p>カートは空です。お買い物を始めましょう!</p> {% endif %}
-
{% unless condition %}
...{% endunless %}
:if
の逆。condition
がfalseの場合にブロック内のコードを実行します。{% unless product.available %} <p>この商品は現在在庫切れです。</p> {% endunless %}
-
{% case variable %}
{% when value1 %}
...{% when value2 %}
...{% else %}
...{% endcase %}
: 多岐分岐。特定の値に基づいて処理を切り替えます。{% case product.type %} {% when 'T-Shirt' %} <p>このTシャツはコットン100%です。</p> {% when 'Mug' %} <p>このマグカップは食洗機対応です。</p> {% else %} <p>商品の詳細はお問い合わせください。</p> {% endcase %}
ループタグ
配列やコレクションの要素を反復処理し、リスト表示などに利用します。
-
{% for item in array %}
...{% endfor %}
: 配列 (array
) の各要素 (item
) に対してブロック内のコードを繰り返します。<ul> {% for product_tag in product.tags %} <li>{{ product_tag }}</li> {% endfor %} </ul>
-
{% for item in array limit:num offset:num %}
:limit
で表示する最大件数、offset
で開始位置(スキップする要素数)を指定できます。{% comment %} 最初の5つの商品を表示 {% endcomment %} {% for product in collection.products limit: 5 %} <p>{{ product.title }}</p> {% endfor %}
-
{% cycle 'class1', 'class2', 'class3' %}
: ループ内で呼び出されるたびに、指定した値を順番に出力します。主にCSSクラスの交互適用などに使われます。{% for item in cart.items %} <div class="{% cycle 'odd', 'even' %}"> {{ item.title }} </div> {% endfor %}
-
{% tablerow item in collection.products cols:3 %}
...{% endtablerow %}
: 配列の要素をHTMLのテーブル行 (<tr>
と<td>
) として出力します。cols
で1行あたりのカラム数を指定します。 -
forloop
オブジェクト:for
ループ内で自動的に利用可能になるオブジェクトで、ループの現在の状態に関する情報を提供します。-
forloop.index
: 現在の反復インデックス (1から開始) -
forloop.index0
: 現在の反復インデックス (0から開始) -
forloop.first
: 最初の反復であればtrue
-
forloop.last
: 最後の反CRIPTであればtrue
-
forloop.length
: ループ全体の要素数 -
forloop.rindex
: 残りの反復回数 (最後が1) -
forloop.rindex0
: 残りの反復回数 (最後が0)
{% for item in cart.items %} <p>商品 {{ forloop.index }} / {{ forloop.length }}: {{ item.title }}</p> {% if forloop.first %} <p>これが最初の商品です。</p> {% endif %} {% endfor %}
-
変数割り当てタグ
Liquid内で新しい変数を作成したり、既存の変数に値を代入したりします。
-
{% assign variable_name = value %}
:variable_name
という名前の変数にvalue
を割り当てます。{% assign featured_product = all_products['my-featured-product'] %} {% if featured_product %} <h2>おすすめ商品: {{ featured_product.title }}</h2> {% endif %}
-
{% capture variable_name %}
...{% endcapture %}
: このタグで囲まれたブロック内のレンダリング結果(HTMLやテキスト)を文字列としてvariable_name
に格納します。{% capture product_details %} <p>価格: {{ product.price | money }}</p> <p>SKU: {{ product.selected_or_first_available_variant.sku }}</p> {% endcapture %} <div>{{ product_details }}</div>
テーマタグ
テーマの構造化や特定機能の実装に関連するタグです。
-
{% layout 'theme' %}
: このテンプレートが使用するレイアウトファイルを指定します。通常、layout/theme.liquid
がデフォルトです。layout 'alternate'
のように別のレイアウトを指定することも可能です。 -
{% section 'header' %}
:sections
ディレクトリ内の指定されたセクションファイル(例:sections/header.liquid
)をレンダリングして読み込みます。 -
{% render 'snippet-name', variable1: value1, variable2: value2 %}
:snippets
ディレクトリ内の指定されたスニペットファイル(例:snippets/snippet-name.liquid
)をレンダリングして読み込みます。スニペットに変数を渡すことも可能です。パフォーマンス向上のため、include
よりもrender
が推奨されます。 -
{% include 'old-snippet-name' %}
: (旧タグ)snippets
ディレクトリ内のスニペットファイルを読み込みます。変数スコープの挙動がrender
とは異なります。新しい開発ではrender
の使用が推奨されます。 -
{% form 'product', product %}
...{% endform %}
: 商品をカートに追加するためのHTMLフォームを生成します。他にも{% form 'customer_login' %}
,{% form 'contact' %}
など、様々な種類のフォームがあります。{% form 'product', product %} <input type="hidden" name="id" value="{{ product.selected_or_first_available_variant.id }}"> <button type="submit">カートに追加</button> {% endform %}
-
{% paginate collection.products by 10 %}
...{% endpaginate %}
: コレクションなどのアイテムリストをページ分割(ページネーション)するために使用します。by
の後に1ページあたりのアイテム数を指定します。このブロック内ではpaginate
オブジェクトが利用可能になります。{% paginate collection.products by 5 %} {% for product in collection.products %} <!-- 商品表示 --> {% endfor %} {% if paginate.pages > 1 %} {{ paginate | default_pagination }} {% endif %} {% endpaginate %}
3. 便利なLiquidフィルタ集 (Filters)
Liquidフィルタは、オブジェクトの出力を変更したり、整形したりするのに役立ちます。{{ object.property | filter_name: argument }}
のようにパイプ |
の後にフィルタ名を記述し、必要に応じて引数をコロン :
の後に指定します。
文字列フィルタ
-
upcase
: 文字列をすべて大文字に変換します。{{ "hello" | upcase }}
->HELLO
-
downcase
: 文字列をすべて小文字に変換します。{{ "HELLO" | downcase }}
->hello
-
capitalize
: 文字列の先頭文字を大文字にし、残りを小文字にします。{{ "hello world" | capitalize }}
->Hello world
-
escape
: HTML特殊文字 (<
,>
,&
,"
) をエスケープします。セキュリティ上重要です。{{ "<script>" | escape }}
-><script>
-
truncate: characters, omission
: 文字列を指定した文字数 (characters
) で切り詰めます。末尾にはomission
(デフォルトは...
) が追加されます。{{ "非常に長い説明文です" | truncate: 10, "..." }}
->非常に長い説...
-
truncatewords: words, omission
: 文字列を指定した単語数 (words
) で切り詰めます。{{ "This is a long sentence." | truncatewords: 3 }}
->This is a...
-
strip_html
: 文字列からHTMLタグを除去します。{{ "<p>Text</p>" | strip_html }}
->Text
-
strip_newlines
: 文字列から改行文字を除去します。 -
newline_to_br
: 文字列中の改行文字をHTMLの<br>
タグに変換します。 -
replace: 'substring', 'replacement'
: 文字列中の特定のsubstring
をreplacement
に置換します。{{ "Hello Shopify" | replace: "Shopify", "World" }}
->Hello World
-
prepend: 'string'
: 文字列の先頭に指定したstring
を追加します。{{ "World" | prepend: "Hello " }}
->Hello World
-
append: 'string'
: 文字列の末尾に指定したstring
を追加します。{{ "Hello" | append: " World" }}
->Hello World
-
split: 'separator'
: 文字列を指定したseparator
で分割し、文字列の配列を返します。{{ "apple,banana,orange" | split: "," }}
->['apple', 'banana', 'orange']
-
handleize
(またはhandle
): 文字列をハンドル形式(小文字、スペースや特殊文字はハイフンに置換)に変換します。URLフレンドリーな文字列生成に便利です。{{ "My Awesome Product!" | handleize }}
->my-awesome-product
数値フィルタ
-
plus: number
: 数値にnumber
を加算します。{{ 5 | plus: 3 }}
->8
-
minus: number
: 数値からnumber
を減算します。{{ 10 | minus: 4 }}
->6
-
times: number
: 数値にnumber
を乗算します。{{ 3 | times: 4 }}
->12
-
divided_by: number
: 数値をnumber
で除算します。結果は整数になる場合があるので注意が必要です。{{ 10 | divided_by: 3 }}
->3
(Liquidのバージョンや環境により浮動小数点数を返す場合もあります) -
modulo: number
: 数値をnumber
で割った余りを返します。{{ 10 | modulo: 3 }}
->1
-
round
: 四捨五入して最も近い整数にします。{{ 3.14 | round }}
->3
,{{ 3.6 | round }}
->4
-
ceil
: 小数点以下を切り上げて最も近い整数にします。{{ 3.14 | ceil }}
->4
-
floor
: 小数点以下を切り捨てて最も近い整数にします。{{ 3.14 | floor }}
->3
-
abs
: 数値の絶対値を返します。{{ -5 | abs }}
->5
通貨フィルタ
Shopifyストアの通貨設定に基づいて価格をフォーマットします。
-
money
: ストアの通貨設定で価格をフォーマットします。{{ product.price | money }}
->¥1,000
(日本円設定の場合) -
money_with_currency
: 通貨コード付きで価格をフォーマットします。{{ product.price | money_with_currency }}
->¥1,000 JPY
-
money_without_trailing_zeros
: 小数点以下の末尾のゼロなしで価格をフォーマットします(例: $10.00 -> $10)。
配列フィルタ
配列の操作や要素の抽出に使います。
-
join: 'separator'
: 配列の要素を指定したseparator
文字列で連結します。{{ product.tags | join: ", " }}
->タグ1, タグ2, タグ3
-
first
: 配列の最初の要素を取得します。{{ product.images | first }}
-> 最初の画像オブジェクト -
last
: 配列の最後の要素を取得します。{{ product.images | last }}
-> 最後の画像オブジェクト -
size
: 配列の要素数を返します(文字列の長さも取得可能)。{{ product.tags | size }}
-> タグの数 -
map: 'property'
: 配列内の各オブジェクトから指定したproperty
の値を抽出した新しい配列を返します。{{ product.variants | map: 'price' }}
-> バリアント価格の配列[1000, 1200, 1500]
-
sort: 'property'
: 配列を指定したproperty
の値でソートします。{{ collection.products | sort: 'price' }}
-> 価格の昇順でソートされた商品配列 -
uniq
: 配列から重複する要素を除去した新しい配列を返します。 -
where: 'property', 'value'
: 配列内のオブジェクトで、指定したproperty
が指定したvalue
と一致する要素のみを抽出した新しい配列を返します。{{ collection.products | where: 'vendor', 'MyBrand' }}
-> 販売元が'MyBrand'の商品配列
日付フィルタ
日付オブジェクトを指定したフォーマットで文字列として表示します。
-
date: 'format'
:format
にはstrftime
と同様の書式指定子を使用します。{{ article.published_at | date: '%Y年%m月%d日 %H時%M分' }}
-
%Y
: 4桁の年 (例: 2025) -
%y
: 2桁の年 (例: 25) -
%m
: 2桁の月 (01-12) -
%b
: 月の略称 (例: Jan) -
%B
: 月のフルネーム (例: January) -
%d
: 2桁の日 (01-31) -
%e
: 日 (1-31、1桁の場合は先頭にスペース) -
%a
: 曜日の略称 (例: Sun) -
%A
: 曜日のフルネーム (例: Sunday) -
%H
: 24時間形式の時 (00-23) -
%I
: 12時間形式の時 (01-12) -
%M
: 分 (00-59) -
%S
: 秒 (00-59) -
%p
: AM/PM
-
URLフィルタ
アセットファイルや画像へのURLを生成・操作します。
-
asset_url
: テーマのassets
ディレクトリ内にあるファイルへの完全なURLを生成します。{{ 'style.css' | asset_url }}
-
asset_img_url: 'size'
:assets
ディレクトリ内の画像ファイルへのURLを生成し、指定したsize
にリサイズしたものを返します。{{ 'logo.png' | asset_img_url: '200x' }}
-
img_url: 'size'
: 画像オブジェクト (例:product.featured_image
) のURLを生成し、指定したsize
にリサイズします。ShopifyのCDNを利用して動的に画像が生成されます。- サイズ指定の例:
- プリセット名:
pico
,icon
,thumb
,small
,compact
,medium
,large
,grande
,original
- 幅指定:
200x
(幅200px、高さはアスペクト比維持) - 高さ指定:
x300
(高さ300px、幅はアスペクト比維持) - 幅x高さ指定:
200x300
(指定サイズにクロップまたはリサイズ)
- プリセット名:
<img src="{{ product.featured_image | img_url: 'medium' }}" alt="{{ product.featured_image.alt }}">
- サイズ指定の例:
-
file_url
: Shopify管理画面の設定 > ファイル
からアップロードされたファイルへのURLを生成します。{{ 'my-document.pdf' | file_url }}
-
shopify_asset_url
: ShopifyのCDNでホストされているグローバルなアセット(Shopifyが提供するJavaScriptライブラリなど)へのURLを生成します。 -
link_to: url, link_text
: HTMLのアンカータグ (<a>
) を生成します。{{ '商品一覧へ' | link_to: '/collections/all' }}
-><a href="/collections/all">商品一覧へ</a>
-
link_to_tag: tag, link_text
: 特定のタグが付いた商品をフィルタリングするコレクションページへのリンクを生成します。 -
link_to_type: type, link_text
: 特定の商品タイプでフィルタリングするコレクションページへのリンクを生成します。 -
link_to_vendor: vendor, link_text
: 特定の販売元でフィルタリングするコレクションページへのリンクを生成します。
デフォルトフィルタ
-
default: value
: 入力値がnil
,false
, または空文字列の場合に、指定したvalue
をデフォルト値として使用します。{{ product.metafields.custom.short_description | default: "詳細は商品ページをご覧ください。" }} {{ settings.custom_font_size | default: 16 | append: 'px' }}
Liquid学習のためのリソース
より深くLiquidを学びたい、または特定の機能について詳細を知りたい場合は、以下の公式リソースが非常に役立ちます。
-
Shopify開発者ドキュメント - Liquid: https://shopify.dev/docs/liquid
- こちらがLiquidに関する最も包括的で最新の情報源です。オブジェクト、タグ、フィルタの詳細なリファレンスや、テーマ開発のベストプラクティスなどが掲載されています。
まとめ
LiquidはShopifyテーマ開発の核となる強力なテンプレート言語です。今回ご紹介したオブジェクト、タグ、フィルタは、その中でも特によく使用される基本的な要素です。これらの組み合わせによって、静的なHTMLでは実現できない動的でインタラクティブなストアフロントを構築できます。
初めは覚えることが多く感じるかもしれませんが、実際にコードを書きながら試していくうちに、自然と身についていくでしょう。本記事が、あなたのShopifyテーマ開発の効率化とスキルアップの一助となれば幸いです。