HubSpotの基本的な使い方から現場ベースのナレッジまで、HubSpotに特化して情報をご提供します。
どんどんコンテンツを追加していきますので、ご期待ください!

  1. Penseesトップ
  2. How to HubSpot
  3. HubSpot CMSとは
  4. HubL - 条件分岐

HubL - 条件分岐

本ページではHubLにおける条件分岐の基本を解説します。「何がtrue/falseとなるのか?」というところから、さまざまなケース別の条件分岐の書き方まで紹介しています。

truthyな値、falsyな値を知る

ここで扱う型は

  • Boolean(真偽値)
  • Number(数値)
  • String(文字列)
  • List(リスト)
  • Dictionary(ディクショナリ)

です。以下の例は、全てfalseとなります。判定方法は、いずれもif文に変数名だけを渡すシンプルなものです。

{% set bool = false %}
{% set num = 0 %}
{% set str = '' %}
{% set list = [] %}
{% set dict = {} %}

{# 判定方法のコード例 #}
{% if bool %}
  boolはtrue
{% else %}
  boolはfalse {# こちらが出力される #}
{% endif %}

次のコードは全てtrueとなります。

{% set bool = true %}
{% set num = -1 %}
{% set str = '1' %}
{% set list = [1] %}
{% set dict = { 'hoge': 1, 'fuga': 2 } %}

boolはtrueとなって当然ですね。listとdictに関しても、要素が1つでもあればtrueとなることがわかります。厳密に判定するのであればlengthフィルタを使用したいところですが、とりあえずこれで必要十分です。
数値に関しても、falsyなのは0のみであり、その他の値はマイナスの値、自然数含め全てtruthyです。ちなみに-0もtruthyです。

気をつけたいのは文字列です。JavaScriptでもありがちな話ですが、文字列で'false'や'0'とした場合、truthyとなります。以下はいずれもtrueと判定されます。

{% set str = 'false' %}
{% set str = '0' %}

数値のような文字列に関しては、roundフィルタを使用することにより、数値型へとキャストできます。次のコードはfalsyです。

{% set str = '0' %}

{% if str|round %}
  strはtrue
{% else %}
  strはfalse {# こちらが出力される #}
{% endif %}

条件分岐の書き方の基本

次に、いろいろな条件分岐の書き方を紹介します。どの例においても、値が数値型「2」である変数hogeを使用します。

{# サンプルとして使用する変数 #}
{% set hoge = 2 %}

if文、elif文、else文、unless文

まずは基本のif文です。→公式ドキュメント:If statements

{% if hoge == 2 %}
  hogeは2
{% elif hoge == 3 %}
  hogeは3
{% else %}
  hogeは他の数値
{% endif %}

使用出来る比較演算子は下記の通りです。これは他のプログラミング言語と大差ないため、詳しくは説明しません。

==、!=、>、>=、<、<=

なおifと==が「〜であれば」を表すのに対し、「〜でなければ」を表すunless文というものも存在します。次のコードは、unless文の中のコードが表示されます。

{% unless hoge == 3 %}
  hogeは3ではない {# hogeは2のため、表示される #}
{% endunless %}

ただしunless文は、基本的にif文と!=を使用することで等価となります。コード規約的な話になりますが、ややこしさを助長するだけなので基本的にunless文は使わない方がよいでしょう。

{% if hoge != 3 %}
  hogeは3ではない {# hogeは2のため、表示される #}
{% endif %}

なおもう1つ等価の書き方として、is演算子とequalto、論理演算子のnotを組み合わせる方法もあります。しかし、この程度の例ではかえって冗長な書き方なので推奨しません。

{% if not hoge is equalto 3 %}
  hogeは3ではない {# hogeは2のため、表示される #}
{% endif %}

論理演算子

1つの文で複数の式を組み合わせるには、論理演算子を使用します。これも、他のプログラミング言語と大差ありません。HubLの場合は記号ではなく、英単語を使用します。例として、値が3である変数fugaを追加します。→公式ドキュメント:Logical

{% set hoge = 2 %}
{% set fuga = 3 %}

{%- if hoge == 2 and fuga == 3 -%}
  hogeは2 かつ fugaは3
{%- endif -%}

{%- if hoge == 2 or fuga == 3 -%}
  hogeは2 または fugaは3
{%- endif -%}

真偽値を反転するには、notを使用します。また公式ドキュメントには載っていませんが、一応「!」を使用して真偽値を反転することもできます。

{% set piyo = false %}

{% if not piyo %} {# 「piyoがtrueであれば」の反転 → 「piyoがfalseであれば」 #}
  piyoはfalse {# 表示される #}
{% endif %}

{% if !piyo %}
  piyoはfalse {# 表示される #}
{% endif %}

ただし、notを使用した条件分岐はえてして冗長になりがちです。多くの場合はnotを使用せず、通常のif文で記述することができます。

{% set hoge = 2 %}
{% set fuga = 3 %}

{%- if not (hoge == 4) -%}
  hogeは4ではない
{%- endif -%}
↓
{%- if hoge != 4 -%}
  hogeは4ではない
{%- endif -%}

{%- if not (hoge == 4 and fuga == 5) -%}
  hogeは4ではない かつ fugaは5ではない
{%- endif -%}
↓
{%- if hoge != 4 and fuga != 5 -%}
  hogeは4ではない かつ fugaは5ではない
{%- endif -%}

{%- if not (hoge == 4) or not (fuga == 5) -%}
  hogeは4ではない または fugaは5ではない
{%- endif -%}
↓
{%- if hoge != 4 or fuga != 5 -%}
  hogeは4ではない または fugaは5ではない
{%- endif -%}

ifchanged

HubLがサポートしている少し変わった条件分岐文に、ifchangedというものがあります。これは「前回ifchangedで評価した変数の値と比べて、値が変わっていれば文の中のコードを実行する」というものです。初回は必ず実行されます。コードのイメージとしては次の通りです。

{% set foo = 'foo' %}

{% ifchanged foo %}
  fooが変わりました1 {# 初回なので実行される #}
{% endifchanged %}

{% ifchanged foo %}
  fooが変わりました2 {# 変数値に変更がないため、実行されない #}
{% endifchanged %}

{% set foo = 'bar' %}

{% ifchanged foo %}
  fooが変わりました3 {# 変数値に変更があったので、実行される #}
{% endifchanged %}

条件分岐をスッキリ書く(In-line ifと三項演算子、論理演算子)

In-line ifまたは三項演算子を利用することによって、条件分岐を1行でスッキリと書くことができます。その場ですぐ出力したい場合と、変数にセットしたい場合に分けて紹介します。→公式ドキュメント:In-line if statements

その場で値を出力する場合
{% set is_blue = true %}

{# In-line if #}
<p class="{{ 'color-blue' if is_blue else 'color-red' }}">青の文字</p>
{# 三項演算子 #}
<p class="{{ is_blue ? 'color-blue' : 'color-red' }}">青の文字</p>
変数にセットする場合
{% set is_blue = true %}

{# In-line if #}
{% set color_class = 'color-blue' if is_blue else 'color-red' %}
<p class="{{ color_class }}">青の文字</p>

{# 三項演算子 #}
{% set color_class = is_blue ? 'color-blue' : 'color-red' %}
<p class="{{ color_class }}">青の文字</p>

実務としては、私はよくカスタムモジュールのリンクフィールドのパラメーターを受け取るときに、よく三項演算子を利用します。

{% set is_blank = true %}
{% set is_noopener = true %}

{# 三項演算子を利用しない場合 #}
{% set ex_attr = '' %}
{%- if is_blank -%}
  {% set ex_attr = ex_attr + 'target="_blank"' %}
{%- endif -%}
{%- if is_noopener -%}
  {% set ex_attr = ex_attr + 'rel="noopener"' %}
{%- endif -%}
<a href="#" {{ ex_attr }}>hoge</a>

{# 三項演算子を利用した場合 #}
{% set ex_attr = is_blank ? 'target="_blank"' : '' %}
{% set ex_attr = is_noopener ? ex_attr + 'rel="noopener"' : ex_attr %}
<a href="#" {{ ex_attr }}>hoge</a>

等価ではありませんが、似たケースでよく用いるものにdefaultフィルタがあります。ケースに応じて、1番スッキリ書ける方法を選択するとよいでしょう。

また変数の値をそのまま利用できる場合は、論理演算子 || を利用することもできます。以下のコードは「html_tagに値があればそれを、無ければpを使用する」というコードです。

{% set tag = html_tag || 'p' %}

isを利用したさまざまな式評価

論理演算子のisと他のキーワードを組み合わせると、さまざまな式評価を行うことが可能になります。全ての場合において、返値はBooleanのtrueまたはfalseです。→公式ドキュメント:Expression tests

変数・型の判定

変数が宣言されているか?(defined, undefined)

{% set bar = '' %}
{{ bar is defined }} {# true #}
{{ lorem is undefined }} {# 変数loremを宣言してないため、undefinedになる→true #}

nullか?(none)

{{ lorem is none }} {# true undefinedでもtrueとなる #}

{% set lorem = null %}
{{ lorem is none }} {# true #}

{% set lorem = '' %}
{{ lorem is none }} {# false #}

trueになるか?(truthy)

{% set lorem = 'lorem' %}
{{ lorem is truthy }} {# true #}

数値型か?(number)

{% set lorem = 0 %}
{{ lorem is number }} {# true #}

文字列型か?(string)

{% set lorem = 'lorem' %}
{{ lorem is string }} {# true #}

反復可能か?(iterable, sequence)

{% set list = [1, 2, 3] %}
{% set dict = {
  hoge: 'hoge',
  fuga: 'fuga',
  piyo: 'piyo'
} %}

{{ list is iterable }} {# true #}
{{ list is sequence }} {# true #}

{{ dict.items() is iterable }} {# true #}
{{ dict.items() is sequence }} {# true #}

本来ディクショナリはiterable, sequenceともにfalseになりますが、「.items()」メソッドを利用すると反復可能になり、iterable, sequenceの式評価はtrueとなります。このコードは公式ドキュメントのKey, value pairs in loopsの記載に基づきます。

ディクショナリか?(mapping)

{% set dict = {
  hoge: 'hoge',
  fuga: 'fuga',
  piyo: 'piyo'
} %}

{{ dict is mapping }} {# true #}

リスト

リストが特定の要素を含んでいるか?(containing, within)

{% set numbers = [1, 2, 3] %}
{{ numbers is containing 2 }} {# true #}
{{ 2 is within numbers }} {# true #}

{% set strings = ['hoge', 'fuga', 'piyo'] %}
{{ strings is containing 'fuga' }} {# true #}
{{ 'fuga' is within strings }} {# true #}

リストが指定した要素を全て含んでいるか?(containingall)

{% set numbers = [1, 2, 3] %}
{{ numbers is containingall [1, 3] }} {# true #}

{% set strings = ['hoge', 'fuga', 'piyo'] %}
{{ strings is containingall ['hoge', 'fuga'] }} {# true #}

数値

偶数か?奇数か?(even, odd)

{% set num = 2 %}
{{ num is even }} {# true #}

{% set num = 3 %}
{{ num is odd }} {# true #}

指定した数値で割りきれるか?(divisibleby)

{% set num = 3 %}
{{ num is divisibleby 3 }} {# true #}
{{ num is divisibleby 2 }} {# false #}

文字列

全て小文字か?大文字か?(lower, upper)

{% set str = 'loremipsum' %}
{{ str is lower }} {# true #}

{% set str = 'LOREMIPSUM' %}
{{ str is upper }} {# true #}

半角スペースは小文字、大文字どちらにも該当しないようなので、これをtrueにするのは難しい気がします。

特定の文字列を含むか?(string_containing)

{% set str = 'lorem ipsum' %}
{{ str is string_containing 'sum' }} {# true #}

特定の文字列から始まるか?(string_startingwith)

{% set str = 'lorem ipsum' %}
{{ str is string_startingwith 'lorem' }} {# true #}

その他

2つの値は等しいか?(equalto, sameas)

{% set str = 'lorem' %}
{{ str is equalto 'lorem' }} {# true #}
{{ str is sameas 'lorem' }} {# false #}
{{ str == 'lorem' }} {# true #}

{% set str2 = 'lorem' %}
{{ str is sameas str2 }} {# true #}
{{ str == str2 }} {# true #}

equaltoは==と等価です。対してsameasは変数同士を比較するものであるため、値が同じであっても、変数と文字列を比較するとfalseになります。ただし、結局多くの場合は==で書き換えが可能です。

予約変数を使用した条件分岐

forループの中で使用できる条件分岐

forループ内では多くの予約変数が用意されており、それらを駆使してさまざまな条件分岐を行うことができます。全ては紹介しませんが、代表的なものを紹介します。公式ドキュメント:Loop properties

{%- for item in items -%}
  {% if loop.first %}
    最初のループ時のみに実行
  {% endif %}

  {% if loop.last %}
    最後のループ時のみに実行
  {% endif %}

  {% if loop.index is even %}
    偶数ループ毎に実行
  {% endif %}

  {% if loop.index is odd %}
    奇数ループ毎に実行
  {% endif %}

  {% if loop.index is divisibleby 5 %}
    5ループ毎に実行
  {% endif %}
{%- endfor -%}

ブログにまつわる条件分岐

ブログかどうか?(ウェブサイトページ/ランディングページでないか?)

公式ドキュメント:Blog variables

{%- if group.id -%}
  ブログである
{%- endif -%}

group変数にはブログにまつわる多くの情報が格納されています。全てを取得する必要はありませんので、そのうちidのみをチェックし、idが取得できればブログとみなすことができます。ウェブサイトページなどの場合は、nullが返ります。

アーカイブ(一覧)ページかどうか?

公式ドキュメント:If is_listing_view statement

{% if is_listing_view %}
  一覧ページである
{% else %}
  詳細ページである
{% endif %}

タグアーカイブページかどうか?

公式ドキュメント:If topic statement

{% if topic %}
  タグアーカイブページである
{% endif %}

著者アーカイブページかどうか?

公式ドキュメント:If blog_author statement

{% if blog_author %}
  著者アーカイブページである
{% endif %}

「全ての記事」ページかどうか?

公式ドキュメント:If not simple_list_page statement

{% if simple_list_page %}
  「全ての記事」ページである
{% else %}
  通常の一覧ページである
{% endif %}

前後のページが存在するか?(ページャー)

こちらはほぼ公式ドキュメント:Listing pagination からの引用です。

{% if last_page_num %}
  <a href="{{ blog_page_link(last_page_num) }}">前へ</a>
{% endif %}
  <a href="{{ group.absolute_url }}/all">全ての記事を見る</a>
{% if next_page_num %}
  <a href="{{ blog_page_link(next_page_num) }}">次へ</a>
{% endif %}

MAIL NOTIFY

HubSpot CMS 料金プラン "簡単に運用できるようになりたい" お任せください!今すぐ相談する→