Shopify ブログ

Shopifyのテンプレート言語 Liquidの概要

Shopifyのプラットフォームにまだ馴染みがないなら、Shopifyのコンテンツを読んだときに「Liquid」が何を指しているのか疑問に思うかもしれません。この記事では、Liquidについて知っておくべきすべてを説明します。LiquidShopifyのテーマ構築にどうフィットしているかについて、そして強力で開発者を引き込ませるeコマーステンプレートを作り上げるためのコアコンセプトについて見ていきます。まずはちょっとした歴史の話から始めましょう。

LiquidShopifyの共同創設者でCEOTobias Lütkeによって開発され、現在はGitHubオープンソースプロジェクトになっています。今日では、CMSからフラットファイルのサイトジェネレーター、そしてもちろんShopifyに至るまで、さまざまなソフトウェアプロジェクトで使われています。 

Liquid:言語かエンジンか?

Liquidはテンプレート言語と呼ばれることもあれば、テンプレートエンジンと言う人もいます。実際はどちらでも構いません、両方ともある意味で正しいので。個人的には筆者はテンプレート言語のほうを好みます。従来のプログラミング言語のように構文があり、アウトプット、ロジック、ループといったコンセプトがあり、変数(データ)を扱います。PHPのようなWeb中心の言語と似ています。

しかし類似点はそれくらいです。設計上Liquidでできないこともたくさんあります。たとえばステートという概念がありません。プラットフォームの奥まで入ることができず、経験豊富なコーダーからすれば直感に反するように見える部分もあるでしょう。ですがこれは十分に考えられたうえでのことなので、最初は制限と感じられる部分も正当な理由があります。

ShopifyLiquidのコードサンプル

テーマコンポーネント周りのコード例が検索できるLiquidライブラリを訪れてみてください。多様なLiquidオブジェクト、プロパティ、フィルターがテーマの中でコンポーネントとして動く仕組みを学べます。テーマを素早く安全にカスタマイズするために、それらのサンプルを直接テーマに加えてみましょう。

Liquidの機能

Liquidはほかのテンプレート言語同様、HTMLファイルとデータの橋渡しをします。わたしたちの文脈ではデータはShopifyストアのものになります。これは使いやすく読みやすい構文によって、テンプレート中の変数へアクセスできることで実現されます。

Shopifyではそれぞれのテンプレートによって、面倒な作業をすることなく特定の変数にアクセスできます。たとえば、product.liquidのテンプレートを使うと、現在見ることのできる商品に関連したすべての詳細へアクセス可能です。一方でLiquidは、実際の商品について何も知る必要なくこのデータをアウトプット可能にします。これらの変数はテンプレート変数と呼ばれています。またLiquidを使って、一般的な方法とは違ったやり方でデータを取得することもできます。たとえば、特定のコレクションの全商品をあなたが作成した変数に挿入するようなことも可能です

アクセスする、または作成する変数の名前がわかったら、アウトプットやループなどのLiquid構文を使って、データをテンプレートに表示させることができます。

あなたがテンプレートで使うLiquidコードに応じて、Shopifyのプラットフォームはどのデータが引き出されどう表示されるかを理解します。商品名をただ表示するだけの場合もあれば、もう少し複雑な、たとえば一連の商品画像のショーケースなどを表示する場合もあるでしょう。

Liquidのようなテンプレート言語の素晴らしい点は、デザイナーであるあなたが、データ自体について何も知っている必要がないということです。そのためあなたのテンプレートは完全に依存関係を持たず、ストアのコンテンツの知識がなくても複数のストアに適用することができるのです。

Liquidのファイル拡張子と区切り文字

Liquidファイルの拡張子は、.liquidです。.liquidのファイルは、標準HTMLLiquid構文の混成です。読みやすい構文で、テンプレートファイルを扱うときはHTMLと容易に区別できます。これは以下の2つの区切り文字によって、さらに簡単なものになっています。

二重中括弧{{ }}は出力を示します。中括弧とパーセンテージ{% %}はロジックを示します。Liquidのすべての構文はこのどちらかによって始まるので、次第にこれらに精通することになるでしょう。

区切り文字の別の考え方はプレースホルダーとして捉えることです。プレースホルダーはコードとして読めはするものの、最終的にコンパイルされてブラウザに送られるときにはデータに置き換わります。このデータはテンプレート内のLiquidコードの結果としてテーマデザイナーによって決定されます。そのためLiquidテンプレートはPHPHTMLをつなげるテンプレートのように、レンダリングの表現として機能するのです。

アウトプット/出力

アウトプットの構文を見てみましょう。名前が示すように、Liquidのアウトプットは、文字通りストアからのデータをテンプレートに出力します。

product.liquidのテンプレートでよく見かけるアウトプットのプレースホルダーの例がこちらです。

<h2>{{ product.title }}</h2>

レンダリングされると下記の例のように、現在見ている商品の名前が{{ }}の部分に出力されます。

<h2>アメリカン・ダイナー・マグカップ</h2>

フィルター(後ほど説明します)によって操作しない限り、アウトプットはプレースホルダー全体をストアからのテキストで置き換えます。

オブジェクトとプロパティ

この例ではLiquidのドット構文も使われています。これは多くのテンプレートやサーバーサイド言語では一般的なものです。shop.nameの例を取り上げると、これは2つのパートに分けることができます。

.」の手前の要素はオブジェクトです。この例では、shopオブジェクトということになります。これはShopify管理画面で定義されるショップに関連付けられるすべてのデータを表象する変数で、ここには下記のアイテムが含まれます。

shop.address

shop.collections_count

shop.currency

shop.description

shop.domain

shop.email

shop.enabled_payment_types

shop.metafields

shop.money_format

shop.money_with_currency_format

shop.name

shop.password_message

shop.permanent_domain

shop.products_count

shop.types

shop.url

shop.vendors

shop.locale

.」の後に続く要素は、shopオブジェクトのプロパティを表しています。これはショップの名前(上述の例であれば)のようなシンプルなものの場合もあれば、ストアで使用可能な決済の種類のようなアイテムのリストという場合もあります。

コレクションプロパティ

上記のリストの中に複数形のプロパティがあったことに気付かれたと思います。

shop.enabled_payment_types

shop.metafields

shop.types

これらのプロパティはLiquidコレクションを表しています。ショップの名前のような文字列のデータを返す代わりに、データの配列、言い換えるとLiquidループでアクセスできるアイテムのリストを返します。

ShopifyLiquidを初めて使用するときコレクションに悩まされるでしょう。ここでは「商品コレクション」と「Liquidコレクション」について説明します。前者はShopify管理画面で定義されたロジカルな商品グルーピングであり、後者はLiquidコードでアクセスできるアイテムのリストです。

Liquidコレクションの個々のリストアイテムは、プロパティを持つことができます。その良い例が、product.imagesです。これは特定の商品に追加されたすべての画像リストを表しています。

リストの各画像は、関連する複数のプロパティを持ちます。

image.alt

image.attached_to_variant?

image.id

image.product_id

image.position

image.src

image.variants

これらのプロパティにアクセスするには、Liquidループを使用する必要があります。

Liquidループ

ループはShopifyテーマにおいて広範に使われていますが、理解するのは簡単です。何らかの基礎的なプログラミング経験があれば、ループのコンセプトはなじみあるものでしょう。

ループ(forループとしても知られる)を使うことで、テンプレートで同じコードを既知の回数出力できます。上述したように典型的な使い方は、商品に関連するすべての画像を出力するような場合です。

すでに説明したLiquidコレクションのproduct.imagesを使用した例を見ていきましょう。

このループの目的は特定商品の画像をすべて出力することです。個々の画像をインラインで出力するもっともシンプルなループの例がこちらです。

{% for image in product.images %}

<img src="{{ image | img_url: 'medium' }}">

{% endfor %}

より深く理解するためにステップごとに分解して考察してみましょう。

Step 1

{% for image in product.images %}

この1行目は区切り文字の2つ目のスタイルである中括弧とパーセンテージ{% %}を導入しています。ここではLiquidforループを使っています。ループはLiquidコレクションと一緒に機能し、リストにあるアイテムを順番に処理します。今回の商品に関連する画像が6点あるなら、forループは6回処理をおこないます。10点の画像なら、10回です。全部のリストアイテムの処理が終わる(または別途指示を与える)と、そこで初めて次のテンプレート部分が考慮されます。

ここでの注意点はとくにループの大きさを尋ねない限り、ループの回数が何回なのかを知ることはできないということです。Liquidは所定回数、リストのアイテムを処理します。最後のアイテムを処理した時点で、テンプレートは次のプロセスに進むことになります。

各リストアイテムのプロパティにアクセスするには、ループ内の現在のアイテムを示す変数を指定します。今回の例では、画像(image)です。これは明白な選択であり、今後ほかのデザイナーがあなたのロジックを理解するのを助けますが、何でも入れようと思えば入れられます。たとえば、次のようなalltheimagesintheworldを使うこともできます。

{% for alltheimagesintheworld in product.images %}

もちろんこれは馬鹿げた例です。imageのほうが合理的ですが、Liquidコレクションと関係がない変数であることを強調したかっただけです。

Step 2

<img src="{{ image | img_url: 'medium' }}" />

2行目のコードはHTMLLiquidが混合しています。srcの属性がLiquidのアウトプットタグになっている点に気付かれたでしょうか。

ここでは、「|」によって示されたフィルターが導入されています。これの詳細は少し後で説明します。今回の例ではフィルターが画像の変数(ループ内の現在のアイテム)を取得して、「ミディアム」サイズの画像のURLを発行しています。これはShopify管理画面で商品画像が追加されたときに、作成されたものです。

フィルターについては後で見ていきますが、この短い構文はsrc属性をリスト内にある画像のミディアムバージョンのURLに置き換えている、と思っておけば今は十分でしょう。このフィルターが、src属性を作成するすべての作業をおこなっています。

Step 3

{% endfor %}

最後の行はクロージングendforステートメントです。ループが処理された後もテンプレートが引き続き実行されることを伝えています。

product.imagesオブジェクトに3つの画像がある場合、最終アウトプットは次のようになるでしょう。

<img src="//cdn.shopify.com/s/files/1/0222/9076/products/il_fullxfull.296506684_medium.jpg?v=1368007899" alt="" />

<img src="//cdn.shopify.com/s/files/1/0222/9076/products/moustache-mugs_by_peter-bruegger_1_ medium.jpg?v=1370429684" alt=" />

<img src="//cdn.shopify.com/s/files/1/0222/9076/products/tumblr_lhr5huUxXL1qfhlb1o1_500_ medium.jpg?v=1370429684" alt=" />

ループはとても便利で、あなたがテーマ開発をするにあたって日常的に対峙するものです。画像と商品バリエーションの出力は一般的で頻出する利用例でしょう。

Liquidフィルター

Liquidのもう1つの強力な機能がアウトプットフィルターです。上記のコードの例でも使いました。フィルターのおもな目的は次の3つになります。

・出力データを何らかの形で操作する

・テーマを依存関係から解放する

・書くコード量を減らすことでテーマデザイナーの時間を節約する

フィルターはつねにLiquidアウトプットと連結して使用されます。日付フィルターをまずは例として見てみましょう。

ブログ投稿を出力する際、公開日を読者に知らせることができます。

<p class="date-time">{{ article.published_at | date: '%d %B %Y' }}</p>

さきほど見た例と同じように「|」がアウトプットタグの中央に使われています。これの左側は、published_atプロパティを関連付けたarticleオブジェクトです。右側は、データ形式を指定した引数を持つ日付フィルターになっています(この例では、%d %B %Y)。

フィルターがなければShopifyは単純にデータベースのフォーマットによってブログが公開された日付を出力します。これは人の目で読み取りやすいものではありません。そこで日付フィルターを加えることにより自分が望む出力形式になるようフォーマットを操作することができるのです。

簡単に言うと、フィルターはストアから抽出したデータを別の形に変換することを可能にします。「|」の左側の内容がフィルターを通じて右側の形に変換されます。テンプレートに出力されるのはこの最終的に操作されたデータとなります。

別の例を見てみましょう。

{{ 'style.css' | asset_url | stylesheet_tag }}

2つのフィルターが使われています。ここでの目的は完全な形のスタイル要素をレイアウトファイルに作成することです。

まず左側のCSSファイルですがこれはアセットフォルダーにあります。次に最初のフィルター(この例ではasset_url)を適用しますが、これはとても実用的なので何度も使うことになると思います。ShopifyのテーマがLiquidのおかげで依存から自由であることは前述しました。適用されるストアの知識は必要なく、同じテーマを複数のストアに対して適用できます。しかしこれは、ネットワークのどこに目的のアセット(画像、JSファイル、CSSファイル)があるかを知るためにアセットを参照しようとするとき、問題を引き起こす可能性があります。

asset_urlはそんなときに頼りになります。このフィルターを使うとShopifyはアセットフォルダーへの完全なパスをテーマのために返し、最後にアセットの名前を追加します。ファイルが実在するかどうかはチェックしないことをお忘れなく。最初のタグ(例では'style.css')がアセットフォルダーにあることを確認するのはみなさんになります。

出力するとこのような感じです。

//cdn.shopify.com/s/files/1/0222/9076/assets/style.css

一連の最後のタグであるstylesheet_tag URLを取得してスタイル要素でラップし、それをレイアウトファイルに出力します。最終結果は次のとおりです。

<link href= "//cdn.shopify.com/s/files/1/0222/9076/t/10/assets/style.css?756" rel="stylesheet" type="text/css" media="all" />

それぞれのフィルターは先行する出力結果を受け取って順に修正をしていきます。データを渡すフィルターがそれ以上ないとき、結果がHTMLとしてテンプレートに出力されます。

たくさんの実用的なフィルターがありますが、おそらくよく利用するであろういくつかの例を下記に挙げてみます。

asset_url

stylesheet_tag

script_tag

date

pluralize

replace

handle

money

money_with_currency

img_url

link_to

Liquidロジック

最後に知っておくべきLiquidの要素はロジックです。さっそく例を示しましょう。

{% if product.available %}

<h2>在庫あり</h2>

{% else %}

<h2 class="sold-out">ただいま品切れ中です</h2>

{% endif %}

このスニペットではテンプレートのアウトプットを単純な「if, else, endif」のステートメントによってコントロールしています。ifステートメントはいろいろな意味で質問と同じです。この質問への答え次第で異なるマークアップが出力されます。または何もマークアップが出てこない場合もあります。

上述の例では、ifステートメントへの答えがtrueの場合(product.available truefalseを返します)、「在庫あり」というテキストがレンダリングされ、falseの場合は{% else %} の後に続くテキスト(「ただいま品切れ中です」)が出力されます。

ロジックのもう1つの見方は、テンプレートのフローをコントロールして最終的にどのデータを表示するかを決定するものとして捉えることです。アウトプットタグとは異なりロジックタグに含まれるものは、それ自体では何もレンダリングしないという点に注意が必要です。あくまで何がレンダリングされるかは、自分で決定します。

Shopifyテーマの開発中にあなたは何度もifステートメントを使うことになるはずです。また別の例を挙げてみます。

{% if cart.item_count > 0 %}

<p>カートには {{ cart.item_count }} 個の商品が入っています</p>

{% else %}

<p>カートには何も入っていません :( <a href= "/products">こちらで商品を探してみませんか?</a></p>

{% endif %}

このスニペットでは購入者のカート内の商品数を表示するか、商品ページへのリンクを表示します。

演算子

上記の例の中で、「>」の演算子が使われていました。cart.item_countの変数が現在のユーザーのカート内の商品数を返すために、それが「0」より大きいかどうか(商品が入っているかどうか)を確認しています。

この返り値がtrueの場合は商品数を出力し、そうでなければ下記のメッセージを表示します。

<p>カートには何も入っていません :( <a href= "/products">こちらで商品を探してみませんか?</a></p>

フィルターを使用してこの例をリファクタリングすることもできます。pluralizeフィルターを使うとカート内のアイテム数に応じて「item」か「items」が表示されます。ここでの利点はShopifyに正しい指示を送るためにカウント数を知っておく必要はないということです。

{% if cart.item_count > 0 %}

<p>カートには {{ cart.item_count }} {{ cart.item_count | pluralize: 'item', 'items' }} 入っています</p>

{% else %}

<p>カートには何も入っていません :( <a href= "/products">こちらで商品を探してみませんか?</a></p>

{% endif %}

リファクタリングされた例ではpluralizeフィルターに2つのパラメータが含まれています。1つ目は単数形、2つ目は複数形です。

例で示した演算子以外にもLiquidには多数の比較演算子があります。

== 等しい

!= 等しくない

> より大きい

< より小さい

>= 等しいかより大きい

<= 等しいかより小さい

or または

and および

contains 文字列内の一部の文字列を含む、または配列内の要素を含む

Liquidのチートシート

一般的にLiquidのフィルター、演算子、構文などを記憶するのは大変な作業になると思います。代わりにShopify Liquid Cheat Sheetをブックマークして、精読することを強くお勧めします。

まとめ

この記事ではたくさんの内容をカバーしてきました。Liquidの充実した紹介となっていれば幸いです。それでは、カバーしてきた内容のおさらいです。

Liquidは、テンプレートにデータを表示させるためのテンプレート言語です。

Liquidにはアウトプット、ロジック、ループなどの構文があり、変数を処理します。

Liquidファイルは、HTMLLiquidコードの混成で、「.liquid」という拡張子を持ちます。

Shopifyテーマに使われるLiquidには依存関係がなく、現在使用されているストアの概念を持ちません。

Liquidには2つのタイプの区切り文字があります。

・ストアからのデータをテンプレートに出力する方法を学びました。

・フィルターでデータを操作する方法を学びました。

・複数のアイテムを出力するためにLiquidコレクションでループ処理をする方法を学びました。

・テンプレートのロジックの使用法を学びました。

・比較演算子について学びました。

クライアントのためにShopifyテーマを開発する方法についてもっと知りたい方向けに、Liquidのコンセプトとテーマ開発における使用法について、Shopifyのドキュメントでさらに詳しい情報を提供しています。ご質問はShopifyコミュニティで!

 

原文:Keir Whitaker 翻訳:深津望

 

Shopifyパートナープログラムでビジネスを成長させる
マーケティング、カスタマイズ、またはWebデザインや開発など提供するサービスに関係なく、Shopifyパートナープログラムはあなたを成功へと導きます。プログラムの参加は無料で、収益分配の機会が得られ、ビジネスを成長させる豊富なツールにアクセスできます。情熱的なコマースコミュニティに今すぐ参加しましょう!

今すぐ登録