【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に値を設定していないので、「名前が設定されていません」と表示されます。