Skip to main content

Liquid テンプレート

Liquid は、すべての Shopify オンラインストアテーマを動かすテンプレート言語です。Shopify の共同創業者 Tobias Lutke によって作成された Liquid は、ストアのデータを使用してサーバー上で HTML をレンダリングします。テーマの構築、アプリブロックの作成、マーチャントのストアフロントのカスタマイズなど、Liquid の理解は不可欠です。このレッスンでは、言語の基礎、テーマアーキテクチャ、パフォーマンスのベストプラクティスをカバーします。

Liquid の基礎

Liquid には3つの構成要素があります:オブジェクトタグフィルター

オブジェクト

オブジェクトはデータを出力します。二重波括弧で囲まれます:

{{ product.title }}
{{ product.price | money }}
{{ shop.name }}
{{ customer.first_name }}

オブジェクトは現在のページコンテキストに基づいて Shopify から提供されます。商品ページでは product が利用可能です。コレクションページでは collection が利用可能です。shopcartsettings などのグローバルオブジェクトはどこでも利用可能です。

タグ

タグはロジックと制御フローを作成します。パーセント記号付きの波括弧で囲まれます:

{% if product.available %}
<button type="submit">Add to Cart</button>
{% else %}
<button disabled>Sold Out</button>
{% endif %}

{% for product in collection.products %}
<div class="product-card">
<h3>{{ product.title }}</h3>
<p>{{ product.price | money }}</p>
</div>
{% endfor %}

{% unless customer %}
<a href="/account/login">Log in for exclusive pricing</a>
{% endunless %}

一般的なタグには以下が含まれます:

タグ目的
if / elsif / else条件分岐
for配列の反復処理
unless否定条件
case / whenswitch 文
assign変数の作成
capture出力を変数にキャプチャ
renderスニペットのインクルード
sectionセクションのレンダリング
formShopify フォームの生成
paginateコレクションのページネーション
commentコードコメント(レンダリングされない)

フィルター

フィルターはオブジェクトの出力を変更します。パイプ | で区切られます:

{{ "hello world" | capitalize }}
<!-- 出力: Hello world -->

{{ product.price | money_with_currency }}
<!-- 出力: $29.99 USD -->

{{ product.title | handleize }}
<!-- 出力: premium-widget -->

{{ product.description | strip_html | truncate: 150 }}
<!-- 出力: 最初の150文字、HTML なし -->

{{ "now" | date: "%B %d, %Y" }}
<!-- 出力: March 30, 2026 -->

Shopify は EC に特化した多数のフィルターを提供しています:

<!-- 通貨フォーマット -->
{{ 2999 | money }} → $29.99
{{ 2999 | money_with_currency }} → $29.99 USD
{{ 2999 | money_without_trailing_zeros }} → $29.99

<!-- 画像操作 -->
{{ product.featured_image | image_url: width: 400 }}
{{ product.featured_image | image_url: width: 800, height: 600, crop: 'center' }}

<!-- URL 生成 -->
{{ product | product_url }}
{{ "cart" | link_to: routes.cart_url }}

<!-- 配列操作 -->
{{ collection.products | where: "available", true | size }}
{{ collection.products | sort: "price" | first }}
{{ collection.products | map: "title" | join: ", " }}

テーマアーキテクチャ

Shopify テーマは、Liquid ファイル、アセット、設定の構造化されたコレクションです。ファイル構造の理解は不可欠です。

theme/
├── layout/
│ └── theme.liquid # メインレイアウトラッパー
├── templates/
│ ├── index.json # ホームページテンプレート
│ ├── product.json # 商品ページテンプレート
│ ├── collection.json # コレクションページテンプレート
│ ├── page.json # カスタムページテンプレート
│ ├── blog.json # ブログテンプレート
│ ├── article.json # 記事テンプレート
│ ├── cart.json # カートページテンプレート
│ ├── 404.json # 404 ページ
│ ├── search.json # 検索結果
│ └── customers/
│ ├── account.json # カスタマーアカウント
│ ├── login.json # ログインページ
│ └── order.json # 注文詳細
├── sections/
│ ├── header.liquid # サイトヘッダー
│ ├── footer.liquid # サイトフッター
│ ├── featured-collection.liquid
│ ├── product-info.liquid
│ └── rich-text.liquid
├── snippets/
│ ├── product-card.liquid # 再利用可能な商品カード
│ ├── price.liquid # 価格表示ロジック
│ └── icon-cart.liquid # SVG アイコン
├── assets/
│ ├── theme.css
│ └── theme.js
├── config/
│ ├── settings_schema.json # テーマ設定定義
│ └── settings_data.json # 現在の設定値
└── locales/
├── en.default.json # 英語翻訳
└── fr.json # フランス語翻訳

レイアウト

レイアウトファイル(layout/theme.liquid)はすべてのページをラップします。<html><head><body> タグに加え、{{ content_for_header }}{{ content_for_layout }} タグを含みます:

<!DOCTYPE html>
<html lang="{{ request.locale.iso_code }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ page_title }} — {{ shop.name }}</title>
{{ content_for_header }}
{{ "theme.css" | asset_url | stylesheet_tag }}
</head>
<body>
{% sections "header-group" %}

<main id="MainContent" role="main">
{{ content_for_layout }}
</main>

{% sections "footer-group" %}

<script src="{{ 'theme.js' | asset_url }}" defer></script>
</body>
</html>
content_for_header は必須

{{ content_for_header }} タグは Shopify の必要なスクリプト(アナリティクス、App Bridge、チェックアウト統合など)を挿入します。このタグを削除するとテーマが壊れます。

JSON テンプレート

Online Store 2.0 では、テンプレートはどのセクションがどの順序で表示されるかを定義する JSON ファイルです。これがテーマエディターを機能させる仕組みです:

{
"name": "Product",
"sections": {
"main": {
"type": "product-info",
"settings": {
"show_vendor": true,
"show_sku": false
},
"blocks": {
"title": {
"type": "title",
"settings": {}
},
"price": {
"type": "price",
"settings": {
"show_compare_at": true
}
},
"variant_picker": {
"type": "variant_picker",
"settings": {
"picker_type": "button"
}
},
"buy_buttons": {
"type": "buy_buttons",
"settings": {
"show_dynamic_checkout": true
}
},
"description": {
"type": "description",
"settings": {}
}
},
"block_order": ["title", "price", "variant_picker", "buy_buttons", "description"]
},
"recommendations": {
"type": "related-products",
"settings": {
"heading": "You may also like",
"products_to_show": 4
}
}
},
"order": ["main", "recommendations"]
}

セクションとセクションスキーマ

セクションは OS 2.0 テーマのコア構成要素です。各セクションは独自のマークアップ、スタイル、設定、ブロックを持つ自己完結型の Liquid ファイルです。

{% comment %} sections/featured-collection.liquid {% endcomment %}

<div class="featured-collection" style="padding: {{ section.settings.padding }}px 0;">
<div class="page-width">
{% if section.settings.heading != blank %}
<h2 class="section-heading">{{ section.settings.heading }}</h2>
{% endif %}

{% assign collection = collections[section.settings.collection] %}

<div class="product-grid" style="
display: grid;
grid-template-columns: repeat({{ section.settings.columns }}, 1fr);
gap: 24px;
">
{% for product in collection.products limit: section.settings.products_to_show %}
{% render 'product-card', product: product %}
{% endfor %}
</div>
</div>
</div>

{% schema %}
{
"name": "Featured Collection",
"tag": "section",
"class": "featured-collection-section",
"settings": [
{
"type": "text",
"id": "heading",
"label": "Heading",
"default": "Featured Collection"
},
{
"type": "collection",
"id": "collection",
"label": "Collection"
},
{
"type": "range",
"id": "products_to_show",
"min": 2,
"max": 12,
"step": 1,
"default": 4,
"label": "Products to show"
},
{
"type": "range",
"id": "columns",
"min": 2,
"max": 5,
"step": 1,
"default": 4,
"label": "Columns"
},
{
"type": "range",
"id": "padding",
"min": 0,
"max": 100,
"step": 4,
"default": 40,
"unit": "px",
"label": "Section padding"
}
],
"presets": [
{
"name": "Featured Collection"
}
]
}
{% endschema %}

下部の {% schema %} ブロックは以下を定義します:

  • settings: テーマエディターに表示される設定オプション
  • blocks: セクション内の繰り返し可能なサブコンポーネント
  • presets: セクション追加時に表示されるデフォルト設定
  • templates: このセクションが使用できるページタイプ
スキーマ設定タイプ

Shopify は多くの設定タイプをサポートしています:texttextarearichtextimage_pickerurlvideocolorfont_pickercollectionproductblogpagelink_listrangeselectcheckboxradionumberhtmlliquid。それぞれがテーマエディターで特定の入力をレンダリングします。

Liquid でのメタフィールド

メタフィールドを使用すると、Shopify リソースにカスタムデータを添付できます。Liquid では、metafields プロパティを通じてアクセスします:

<!-- 商品メタフィールドへのアクセス -->
{{ product.metafields.custom.warranty_years.value }}

<!-- 条件ロジックでのメタフィールド使用 -->
{% if product.metafields.custom.is_featured.value == true %}
<span class="badge badge--featured">Featured</span>
{% endif %}

<!-- メタフィールド画像のレンダリング -->
{% assign hero_image = product.metafields.custom.hero_image.value %}
{% if hero_image %}
{{ hero_image | image_url: width: 1200 | image_tag: class: 'hero-image' }}
{% endif %}

<!-- リストメタフィールドの反復処理 -->
{% assign ingredients = product.metafields.custom.ingredients.value %}
{% if ingredients %}
<ul class="ingredient-list">
{% for ingredient in ingredients %}
<li>{{ ingredient }}</li>
{% endfor %}
</ul>
{% endif %}

テーマエディターでメタフィールドを利用可能にするには、セクションスキーマに追加します:

{
"settings": [
{
"type": "text",
"id": "heading",
"label": "Heading"
}
],
"blocks": [
{
"type": "metafield",
"name": "Custom Metafield",
"settings": [
{
"type": "text",
"id": "metafield_key",
"label": "Metafield key",
"info": "Format: namespace.key"
}
]
}
]
}

パフォーマンス最適化

テーマのパフォーマンスはコンバージョン率に直接影響します。Shopify はテーマを高速に保つためのツールとベストプラクティスを提供しています。

主要な原則

  1. Liquid ループを最小化: 各反復はサーバーサイドの処理時間です。for ループに limit を使用してください。
  2. 画像の遅延読み込み: image_tagloading: 'lazy' パラメーターを使用します。
  3. クリティカルアセットのプリロード: ファーストビューの画像とフォントに <link rel="preload"> を使用します。
  4. JavaScript の遅延: script タグに defer または async を使用します。
  5. セクションのネストを減らす: 深くネストされたセクションはレンダリング時間を増加させます。
<!-- 良い例: ファーストビュー以下の画像を遅延読み込み -->
{{ product.featured_image | image_url: width: 600 | image_tag:
loading: 'lazy',
widths: '200,400,600,800',
sizes: '(max-width: 600px) 100vw, 50vw'
}}

<!-- 良い例: ファーストビューのヒーロー画像をプリロード -->
<link
rel="preload"
as="image"
href="{{ section.settings.hero_image | image_url: width: 1400 }}"
media="(min-width: 750px)"
>

テーマインスペクター

Shopify の Theme Inspector は Liquid レンダリング時間をプロファイリングする Chrome DevTools 拡張機能です:

  1. Chrome ウェブストアからインストール
  2. ストアフロントを開いて DevTools を開く
  3. Shopify タブに移動
  4. Liquid レンダリングのフレームグラフを確認

インスペクターは、どのセクション、スニペット、Liquid オペレーションが最も多くのサーバー時間を消費しているかを表示します。最もホットなコードパスに最適化の取り組みを集中させましょう。

Liquid での N+1 クエリを避ける

一般的なパフォーマンスの間違いは、制限なしでループ内のメタフィールドや関連リソースにアクセスすることです。各アクセスがデータベースクエリをトリガーする可能性があります。Shopify はキャッシュで軽減していますが、ループをタイトに保ち limit を使用することは依然として重要です。

<!-- 悪い例: メタフィールドアクセス付きの無制限ループ -->
{% for product in collection.products %}
{{ product.metafields.custom.badge.value }}
{% endfor %}

<!-- 良い例: ループを制限 -->
{% for product in collection.products limit: 12 %}
{{ product.metafields.custom.badge.value }}
{% endfor %}

重要なポイント

  • Liquid には3つの構成要素があります:オブジェクト(データ出力)、タグ(ロジック)、フィルター(出力変換)
  • OS 2.0 テーマは JSON テンプレートを使用し、スキーマ定義を持つセクションを参照します
  • セクションは主要な構成要素です -- 設定とブロックを持つ自己完結型コンポーネント
  • メタフィールドはデータモデルを拡張し、Liquid とテーマエディターでアクセス可能です
  • パフォーマンス最適化はループの制限、画像の遅延読み込み、JavaScript の遅延に焦点を当てます
  • Theme Inspector Chrome 拡張機能はレンダリング時間のプロファイリングに不可欠です

次は、Hydrogen -- ヘッドレスストアフロント用の Shopify の React フレームワークを探ります。