【Shopify(ショッピファイ)】Liquidの演算子について
中学生の時に趣味でZ80マシン語やFortran等を始めてから、現在まで数多くのプログラミング言語を経験。ShopifyによるECサイト構築では主にカスタマイズを担当。
はじめに
Shopifyで採用されているテンプレートエンジンLiquidには他のプログラミング言語とは異なるところが多々あり、コーディング時には注意が必要になる場合があります。
この記事ではその注意が必要なものの中から、Liquidの「演算子」を取り上げます。
算術演算子
算術演算子とは加減剰余など算術的な計算を行う演算子で、標準的なプログラミング言語や他のテンプレートエンジンであるSmarty・Twig等での算術演算子は、加算 ( + )、減算 ( – )、乗算 ( * )、除算 ( / ) で表される場合が多いです。
しかしLiquidには、なななんと!、「算術演算子」がありません。Liquidで演算したい時はMathフィルターを使用します。
{% assign result = 5 | minus:2 | times:4 %} {{ result }}
Liquidのフィルターは左から順番に実行されるので、上記コードの場合は「 ( 5 – 2 ) × 4 」という意味になり、その計算結果である「12」が出力されます。
比較演算子(関係演算子)
比較演算子(関係演算子ともいいます)はtrue(真)またはfalse(偽)のいずれかを返します。これらの演算子を使ってフロー制御(if/unless/else/elsif/case/when)をすることが出来ます。
演算子 | 意味 |
---|---|
== | 左右が等しい時にtrueを返し、それ以外はfalseを返します。 |
!= | 左右が等しくない時にtrueを返し、それ以外はfalseを返します。 |
> | 左が右よりも大きい時にtureを返し、それ以外はfalseを返します。 |
< | 左が右よりも小さい時にtrueを返し、それ以外はfalseを返します。 |
>= | 左が右以上の時にtrueを返し、それ以外はfalseを返します。 |
<= | 左が右以下の時にtrueを返し、それ以外はfalseを返します。 |
contains演算子
文字列内に部分文字列の存在有無をチェックするには「contains」を使います。文字列が部分一致した場合はtrue(真)を返し、部分一致しなかった場合はfalse(偽)を返します。
{% if product.title contains "シューズ" %} この商品の商品名には「シューズ」という文字が含まれています。 {% endif %}
配列内に文字列が存在するかどうかも「contains」でチェックできます。ただしこの場合は完全一致の場合だけtrueが返ります。
{% if product.tags contains "飲料" %} この商品のタグには「飲料」が含まれています。 {% endif %}
論理演算子
論理演算子は、比較演算子やcontains演算子の結果(true/false)やboolean型変数の真偽値を比較評価するのに使用し、true(真)またはfalse(偽)のいずれかを返します。
演算子 | 意味 |
---|---|
or | 左または右がどちらか一方でもtrueの時にtrueを返し、それ以外はfalseを返します。(論理和) |
and | 左も右もtrueの時にtrueを返し、それ以外はfalseを返します。(論理積) |
※Liquidには排他的論理和(XOR)はありません。
演算子の優先順位
Liquidの場合、「論理演算子」よりも「比較演算子・contains演算子」 の方が評価の優先順位が高いです。つまり、
「比較演算子・contains演算子」 > 「論理演算子」
という関係になります。
{% assign value = 50 %} {% if value >= 10 and value <= 100 %} 変数value({{- value -}})は10から100の間の値です。 {% endif %}
そのため上記の2行目は、
「{% if (value >= 10) and (value <= 100) %}」
という意味になります。
Liquidの場合、他の言語のように括弧でグルーピングして優先順位を変更するということはことは出来ません。
そもそも括弧は無効な文字になるので、Liquidタグが機能しなくなります。
論理演算子andとorとの優先順位です。他のプログラミング言語ではor(||)よりもand(&&)の方が優先順位が高い言語が多いですが、Liquidの場合はandとorには優先順位は無く、右から左の順で評価されます。
(左から右の順ではないので要注意です!)
{% if true or false and false %} 右のandから評価されるので、この場合は最終的にtrueと評価されます。 = true or (false and false) = true or false = true {% endif %}
{% if true and false and false or true %} 一番右のorから評価されるので、この場合は最終的にfalseになります。 そのため、このブロック内は実行されません。 = true and (false and (false or true)) = true and (false and true) = true and false = false {% endif %}
余談ですが、JavaScriptの論理和と論理積は、他の言語とは解釈が異なります。
演算子 | 意味 |
---|---|
|| (論理和) |
左側がtruthyの時は左側を返し、左側がfalsyの時は右側を返します。 |
&& (論理積) |
左側がtruthyの時は右側を返し、左側がfalsyの時は左側を返します。 |
分かりにくいかもしれませんが、結局は、論理値(true/false)同士の比較時には他言語の論理和・論理積と全く同じになります。
truthy(真値)とは、論理値として判定する時にtrueとして判定されるものです。falsy(偽値)として定義される値以外のもの、つまりfalse, null, NaN, 0, -0, 空文字, undefined以外のものがtruthyになります。
JavaScriptの||と&&は論理値を返すとは限らないので、特に「||」の場合には以下の様にPHPのエルビス演算子「?:」と同じ様な使用方法ができます。
let name; console.log(name || '名前が設定されていません'); //変数nameに値を設定していないので、「名前が設定されていません」と表示されます。