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

  1. Penseesトップ
  2. How to HubSpot
  3. HubLの変数の値を、他の変数の呼び出しに使う(evalっぽいハック)
CMS

HubLの変数の値を、他の変数の呼び出しに使う(evalっぽいハック)

いわゆる、eval的な挙動になります。あまり文章で説明してもピンと来づらいと思いますので、実際の使用例を先にご紹介します。始めに断っておくと、あまり推奨できる方法ではありません。

例えば次のような構造のデータからnameの値を抽出する場合、普通は次のようにforループを回します。

{% set offices = [
  {
    name: '東京オフィス'
  },
  {
    name: '札幌オフィス'
  }
] %}

{%- for item in offices -%}
  {{ item.name }}
{%- endfor -%}
出力結果
東京オフィス
札幌オフィス

ここまでは何も問題ありません。では、forループ内でオフィス名を出力している「item.name」の「name」をハードコードしないで出力したい場合、どうすればよいでしょうか?

目次

基本となるコード

今回は仮に「name」というkeyが、「name_key」という変数に値として格納されているとしましょう。雰囲気的には次のような感じですが、当然次のコードは動きません。

{% set name_key = 'name' %}
{% set offices = [
  {
    name: '東京オフィス'
  },
  {
    name: '札幌オフィス'
  }
] %}

{%- for item in offices -%}
  {{ item.name_key }} {# この呼び出し方では当然動かない #}
{%- endfor -%}

これは次のように書くことで、期待通りの出力を得ることが可能です(変数宣言は同じなので省略します)。

{%- for item in offices -%}
  {% set call_value = '{{ item.' + name_key + ' }}' %} {# 変数の呼び出しを文字列として組み立てる #}
  {{ call_value }} {# 文字列として組み立てた変数の呼び出しを展開する #}
{%- endfor -%}

ここまでの解説ではただ単に非現実的で、使いどころのないコードに思えます。この方法が必要になるのは、次のように「プロパティの数が可変なテーブル的構造のデータを、自動でで出力したい」という場合です。

実用例

次のデータを先ほどの方法を使用して、tableタグで出力してみます。

{%- for item in offices -%}
{% set offices = {
  columns: {
    name: '支店名',
    address: '住所',
    tel: '電話番号'
  },
  contents: [
    {
      name: '東京オフィス',
      address: '東京都千代田区',
      tel: '03-XXXX-XXXX'
    },
    {
      name: '札幌オフィス',
      address: '北海道札幌市',
      tel: '011-XXX-XXXX'
    }
  ]
} %}

<table>
  <tr>
    {# 1. 見出しの出力 #}
    {%- for val in offices.columns -%}
      <th>{{ val }}</th>
    {%- endfor -%}
  </tr>
  {# 2. contentsでループを回す #}
  {%- for item in offices.contents -%}
    <tr>
      {# 3. keyを取得するため、1.と同じようにループを回す #}
      {%- for key, val in offices.columns.items() -%}

        {# 4. 取得したkeyを使用して、contentsのデータを取り出す変数呼び出しを文字列として組み立てる #}
        {% set call_value = '{{ item.' + key + ' }}' %}

        {# 5. 4を展開する #}
        <td>{{ call_value }}</td>
        
      {%- endfor -%}
    </tr>
  {%- endfor -%}
</table>
出力結果
<table>
  <tr>
    <th>支店名</th>
    <th>住所</th>
    <th>電話番号</th>
  </tr>
  <tr>
    <td>東京オフィス</td>
    <td>東京都千代田区</td>
    <td>03-XXXX-XXXX</td>
  </tr>
  <tr>
    <td>札幌オフィス</td>
    <td>北海道札幌市</td>
    <td>011-XXX-XXXX</td>
  </tr>
</table>

一気に複雑になってしまったので、順を追って解説します。

  1. 見出しの出力

    まずはcolumnsに格納されている各valueを見出しとして出力します。columnsはディクショナリですが、普通にループを回すとvalue値が取得できます。

  2. contentsでループを回す

    次に、contentsの要素ごとにループを回します。これ自体は特に特別なコードではありません。

  3. keyを取得するため、dictループを回す

    contents内の各ディクショナリのvalueにアクセスするため、columnsの各キーを取得する必要があります。for文をこのように記述するとディクショナリのkeyにもアクセスできるようになり、これはHubSpot CMSの公式ドキュメントにも紹介されている方法です。

  4. 取得したkeyを使用して、contentsのデータを取り出す変数呼び出しを文字列として組み立てる

    本記事で紹介するメインのコードです。先ほどの「基本形」セクションのコードと本質的に同じです。

  5. 4を展開する

    こちらも本記事で紹介するメインのコードで、「基本形」セクションのコードと本質的に同じです。

この状態であれば、次のようにコンテンツが増えても、HTMLの出力をしている側のコードは一切修正する必要がありませんので、つまりデータと出力を疎結合に保てている証となります。

{% set offices = {
  columns: {
    name: '支店名',
    address: '住所',
    tel: '電話番号',
    staff_num: 'スタッフ数' {# 追加 #}
  },
  contents: [
    {
      name: '東京オフィス',
      address: '東京都千代田区',
      tel: '03-XXXX-XXXX',
      staff_num: '10名' {# 追加 #}
    },
    {
      name: '札幌オフィス',
      address: '北海道札幌市',
      tel: '011-XXX-XXXX',
      staff_num: '3名' {# 追加 #}
    }
  ]
} %}
{# 出力の方のコードには一切変更なし #}
出力結果
<table>
  <tr>
    <th>支店名</th>
    <th>住所</th>
    <th>電話番号</th>
    <th>スタッフ数</th>
  </tr>
  <tr>
    <td>東京オフィス</td>
    <td>東京都千代田区</td>
    <td>03-XXXX-XXXX</td>
    <td>10名</td>
  </tr>
  <tr>
    <td>札幌オフィス</td>
    <td>北海道札幌市</td>
    <td>011-XXX-XXXX</td>
    <td>3名</td>
  </tr>
</table>

この方法が何より真価を発揮するのは、カスタムモジュール内でHubDBテーブルを選択できるようにしている場合です。これについては基本形のHubDB記事にて、実例を紹介しています。

まとめ

以上、変数の値を他の変数の呼び出しに使う方法をご紹介しました。この方法をとることによってデータと出力の疎結合性を高められるため、コード設計としても出来ることがかなり広がると思います。

しかし公式ドキュメントで紹介されている方法ではなく、ハックの域を出ないものですので、使用の際は万が一のことを考え、影響範囲が広くなりすぎないようにすることをオススメします。

MAIL NOTIFY

パンセへのご相談はこちら