変数をブロックの外でも使えるようにできる a-blog cms のsetRenderedの使い方

Published


Ver.2.6.0から新しくテンプレートの変数化という機能が追加されました。今回の記事はテンプレートの変数化の機能の1つ、「setRendered」についてです。 もしテンプレートの変数化をまだご存知ない方は公式サイトのドキュメントをご覧ください。(※この記事ではsetRenderedを使うメリットをご紹介していますが、使い方については説明していません。使い方を知りたい場合は公式ドキュメントをご覧ください)

テンプレートの変数化の機能の話を他の製作者の方にすると、setTemplateは大体理解してもらえるのですが、なかなかsetRenderedの使いどころがぱっと思いつくことが難しいようで、私もはじめて機能ができたとき、どういったときにsetRenderedを使えばいいのかわかりませんでした。

ですが、setTemplateがテンプレートを管理する機能なら、setRenderedは今まで出来なかったことを可能にしてくれる機能です。今回の記事のタイトルにも書いてありますが、変数をブロックの外でも使えるようになります。setRenderedは、私のようなノンプログラマーが歯がゆい思いをしたときにも使えるので、今は便利な機能だと思っています。今回はそんなsetRenderedの便利な使い方をお伝えします。

SetRenderedを使うと具体的にできること

具体的に言うと、例えば、Entry_Summaryのモジュールのentry:loop内で使えない変数をentry:loop内でも使えるようになります。

SetRenderedの使いどころ

もし、エントリーサマリーモジュールで、各エントリーのリンク先を一覧ページにしたいとき、きっとこのように書くことが理想的だと思います。

各エントリーのリンク先を一覧ページにしたいときの理想の書き方

<!-- BEGIN_MODULE Entry_Summary -->
  <ul>
    <!-- BEGIN entry:loop -->
    <li><a href="{indexUrl}">{title}</a></li>
    <!-- END entry:loop -->
  </ul>
<!-- END_MODULE Entry_Summary -->

ですが、このソースコードで使用されている{indexUrl}は、loopブロック内では使用することができないので、ここには記述できません。記述したとしても、{indexUrl}と記述した部分には何も出力されません。


変数表を見ると、はloopブロックの外で使用できるようになっている

setRenderedを使えばloop内でも{indexUrl}が使えるようになる

今回の記事でおすすめしている「setRendered」を使えば、実はこの問題を解決することができます。setRenderedは、プログラムが解決したあとものを指定した好きな場所に表示できる機能だからです。 そのため、setRenderedにとってはloopブロックの中だろうが関係がないのです。

たとえば、setRenderedを使って{indexUrl}と同じ出力結果をhref属性の中に挿入するとするなら、以下のようなコードになります。以下の場合、2行目〜4行目と7行目のコードが修正されています。

setRenderedを使った例
<!-- BEGIN_MODULE Entry_Summary -->
  <!-- BEGIN_SetRendered id="index_url" -->
    {indexUrl}
  <!-- END_SetRendered -->
  <ul>
    <!-- BEGIN entry:loop -->
    <li><a href="<!-- GET_Rendered id="index_url" -->">{title}</a></li>
    <!-- END entry:loop -->
  </ul>
<!-- END_MODULE Entry_Summary -->

これで、loopブロック内でも一覧ページへのリンク先URLが表示されます。

以下が上記コードの出力結果の例です。

setRenderedを使ったテンプレートの出力結果
<ul>
  <li><a href="/blog/">ホームページをリニューアルしました</a></li>
  <li><a href="/blog/">今日も天気がいいですね</a></li>
  <li><a href="/blog/">6月30日に書籍が発売されます!</a></li>
</ul>

Renderedの上書き

ただ、これだけではある問題が起きる可能性があります。それは同じidを持つsetRenderedによる上書きです。

たとえば、先ほどのモジュールが同じsetTemplateを使って同じページで2回呼ばれていたとします。 お知らせカテゴリーのサマリーの後に採用情報のサマリーが記述されていた場合、どちらのモジュールもURLが採用情報の一覧になってしまいます。

setRenderedで上書きをしてしまっている失敗例

<!-- BEGIN_SetTemplate id="summary" -->
  <!-- BEGIN_MODULE Entry_Summary id="{{module_id}}" -->
    <!-- BEGIN_SetRendered id="index_url" -->
    {indexUrl}
    <!-- END_SetRendered -->
    <ul>
      <!-- BEGIN entry:loop -->
      <li><a href="<!-- GET_Rendered id="index_url" -->">{title}</a></li>
      <!-- END entry:loop -->
    </ul>
  <!-- END_MODULE Entry_Summary -->
<!-- END_SetTemplate -->

<!-- テンプレートはid「summary」を呼び出し、モジュールIDは個別で適用している -->
<!-- GET_Template id="summary" module_id="news" -->

<!-- GET_Template id="summary" module_id="blog" -->

これは、採用情報のサマリーがあとに記述されたことにより、全く同じidを持つRenderedの値を上書きしてしまっていることが原因です。

<!-- GET_Template id="summary" module_id="news" --><!-- このTemplateの中ではRenderedのid「index_url」が呼び出されている -->

<!-- GET_Template id="summary" module_id="blog" --><!-- このTemplateの中でもRenderedのid「index_url」が呼び出されている -->
<!-- モジュールID「news」 -->
<ul>
  <li><a href="/blog/">ホームページをリニューアルしました</a></li>
  <li><a href="/blog/">今日も天気がいいですね</a></li>
  <li><a href="/blog/">6月30日に書籍が発売されます!</a></li>
</ul>

<!-- モジュールID「blog」 -->
<ul>
  <li><a href="/blog/">ホームページをリニューアルしました</a></li>
  <li><a href="/blog/">今日も天気がいいですね</a></li>
  <li><a href="/blog/">6月30日に書籍が発売されます!</a></li>
</ul>

どうすればいいのかというと、Renderedのidの中ににmodule_idを含ませます。以下の場合、3行目と8行目のコードを修正しています。

上書きを防止した対応策の例

<!-- BEGIN_SetTemplate id="summary" -->
  <!-- BEGIN_MODULE Entry_Summary id="{{module_id}}" -->
    <!-- BEGIN_SetRendered id="{{module_id}}_index_url" -->
    {indexUrl}
    <!-- END_SetRendered -->
    <ul>
      <!-- BEGIN entry:loop -->
      <li><a href="<!-- GET_Rendered id="{{module_id}}_index_url" -->">{title}</a></li>
      <!-- END entry:loop -->
    </ul>
  <!-- END_MODULE Entry_Summary -->
<!-- END_SetTemplate -->

これで、同じ違うモジュールIDが使用されていた場合はsetRenderedの値が上書きされないようになりました。私は念のために、さらにテンプレートIDも一緒に記述しています。(たとえば:id="summary_{{module_id}}_index_url"

以上が、私がどうしても困ったときに使うsetRenderedの利用方法でした。きっと、setRenderedがなければノンプログラマーの私には動的に一覧へのリンク先をloopブロック内に表示できなかったと思います。

最後に

公式ドキュメントでは、同じモジュールをもう一度呼び出さなくて済むため、モジュールの解決が早くなるという風にメリットが書かれていますが、私のようなノンプログラマーにとっては、今までできなかったことをできるようにしてくれる素敵な機能だと思っています。

それでは以上になりますが、setTemplateと比べると利用頻度も少ないし、一見使い方もよくわからないsetRenderedですが、少しでもメリットを感じていただければなと思いました。

関連している記事

著者について

森田 かすみ

名古屋のWeb制作会社でマークアップエンジニアとして働いています。呼ばれれば登壇もします。Frontend Nagoya主催。ストレス発散方法はかっぱのイラストを描くこと。