containsはLiquid編集を伴うカスタマイズをする際に、めちゃ役立つ「関数?」(関数なのかな?まぁいいや。)公式チートシートでは「operators」と言う所に分類されています。
= やら > やら < やら or やら and やらと同じ分類ですね。
このcontainsを覚えるとかなりliquid編集で出来る事が増えるので、覚えていろいろと利用しまくっちゃいましょう!覚えるだけで出来る事の幅がめちゃくちゃ増えるので、まず覚えたい技の1つでもあります。
containsとは
containsの意味をまず辞書で引いてみましょう。まぁ英語なのでsは排除してcontainを辞書で引くと「含む」と言う意味になります。
使う時もまさにこの意味通りの動きをしてくれて「~を含む場合」と言うプログラムが書ける感じです。
つまり「for文でループを作る時にif構文と組み合わせて特定の要素が含む場合」に使用する事が多いですが、shopify上ではそれ以外にも「おおっ!なるほどそんな手もあるのか!!」と言うのがあるので
- ループで使う場合
- それ以外の場合
についてを1つずつ解説していきます
ループで使う場合(主にfor内でifと組み合わせる)
まずはfor構文でループを作った時の使い方です。
基本的なfor文の動きとして書き方が
{% for tag in product.tags %}
・・・・・
{% endfor %}
のような構造で書きます。
意味合いとしては「product.tags」が商品についてるタグの一覧を取得、それをtagと言う変数に仮代入して、1タグずつ「・・・・」の処理をして、タグ全部終わったら終了ね!と言う意味です。
例えば「くまちゃん」にはこんな風にタグが付けられています
さんざんカスタマイズの度に色々な事されちゃってるので、可哀そうなタグが沢山ついてます。
product.tagsではこのタグをすべて取得してきて、for構文ではtagに仮代入しつつ
「送料無料」を処理したら、次は「ブリブリ」、次は「クール便」・・・・最後に「color_blue」と言う風にこの場合は9回のループが発生しています。
肝心の「contains」はこのループの中に「if構文」と一緒に使います。例えばこうです
<div>
{% for tag in product.tags %}
{% if tag contains '送料無料'%}
<p>{{tag}}</p>
{% elsif tag contains 'うんこ'%}
<p>{{tag}}</p>
{% elsif tag contains 'クール便'%}
<p>{{tag}}</p>
{% endif%}
</div>
この構文を商品ページのテンプレートにでも書いておけばいいわけです。
(ちなみに商品ページ以外で使う場合は、どの商品に対してこの構文を実行するのかをあらかじめ何かしらの手段で取得しておく必要があります!)
今回は「カートに追加する」ボタンの上あたりに書き出してみようと思います。
結果として出力はこんな感じです。
見ての通り別の記事で解説したカラースウォッチが残ってますが、その上に「うんこ」「クール便」「送料無料」が表示されているけど、全部で9個付いていたタグのうち、containsで指定した3つしか出力されていないのがわかるかと思います!
「うんこ」はともかくとして、「クール便」とか「送料無料」をタグに付けておくことで商品毎にこの文言を出力する事が出来るのでとっても便利です!
ちなみに何行にもなるのが面倒臭いのでこうやって書いてみたら
{% if tag contains '送料無料' or contains 'うんこ' or contains 'クール便'%}
shopifyさんに「そんなもん受付ねぇ」って怒られました。
特定のテンプレートの時のみ出力
もう1つの使い方がなかなかに便利です。
containsさんは色んなシーンで使える理由として「文字列」に対して、それがあるのか?ないのか??を判定してくれるプログラムなので、例えば「template」に対しても使う事が出来ます!
shopifyは基本的にLayoutで指定している「theme.liquid」が各ページにおいて「template」ファイルを最初に読み込みます。
そのテンプレートには当然ファイル名があって商品ページなら「product.liquid」、固定ページなら「page.liquid」、カートページなら「cart.liquid」を呼び出しています。
その「ファイル名もあくまでも文字列」なので、それを利用してあげると特定のテンプレートでのみ出力するプログラムと言うものが出来ます!
先日実装した例で見てみましょう!
お客さんのページなのでちょっとぼかしております。
先日の要件としては、この右下の「お問い合わせ」ボタンで遷移する場所を「トップページ」ならトップページ最下部にある「お問い合わせフォーム」、それ以外のページでは「お問い合わせページ」に遷移するような仕様を作りました。
その時に書いたコードがこれです。
<div class="contact__label">
{% if template contains "index" %}
<a href="#contact">
{% else %}
<a href="https://●●.com/page/contact" target="_blank">
{% endif %}
<img src="{{ 'contact-button.png' | file_url }}" alt="お問い合わせする">
</a>
</div>
これを書くとどうなるかと言うとまず、この部分
{% if template contains "index" %}
ここで指定しているのがtemplateなのに注目してください。これで今読み込んでいるテンプレートが「index」と言う文字列を含んでいる場合と言う意味になりindexテンプレート時には
<a href="#contact">
このコードを出力してね。そしてelseで繋いでそれ以外の場合は
<a href="https://●●.com/page/contact" target="_blank">
こっちを出力してね!と言う意味になっています。
これを全ページ共通で読み込む「theme.liquid」に書いておくことで、indexページではページ下部に設置したフォームへ遷移、それ以外のページではcontactページに遷移してね!と言う出力分けが出来て、いい感じに動くわけです!
ちなみにですがindexとか名前がズバリの物を指定する時は
{% if template == "index" %}
こんな風にイコールで繋いでもOKです。containsは例えば「product.liquid」以外にもいくつか
product.custom.liquid
product.kuma.liquid
など複数の商品ページテンプレートを作っている場合なんかに、すべてのproductが付くテンプレートで呼び出したい時に使います。たとえば
{% if template == "product" %}
の書き方だと、「product.custom」と「product.kuma」は除外されますが、イコールではなくてcontainsで繋いでいれば、全部のテンプレートで読み込んでくれます。
逆に考えれば
{% if template == "product.kuma" %}
なら「product.kuma」テンプレート限定で呼び出すことも可能です!
実験するならtheme.liquidの最下部に
{% if template contains 'product'%}
うんこブリブリ
{% endif %}
とか書いてみるといいです!商品ページの時だけ「うんこブリブリ」しますから!
まとめ
containsが便利な事はわかったと思います!基本的に覚える事は3つです
- ループの中で特定の文字列を発見する
- 特定のtemplateだけ出力する
- とにかく「文字列」を含むか判定してくれる
この辺りを把握してくると、カスタマイズする時の幅はかなり広がります!応用として考える事は
どうやって文字列を取得するのか?
と言う部分になってきます。あとはcontainsで判定してやればいいわけですから、別にfor文じゃなくてもtemplateじゃなくても色んな所で活躍させることが出来るわけです。
ぜひこのcontainsがあると言う事を知っておきましょう!世界が変わるぐらい開発がしやすくなりますよ!!