Twigテンプレート

目次

Twigとは


Twigは、PHPで広く利用されているテンプレートエンジンの1つです。
HTMLとPHPのコードを分離し、読みやすく保守しやすいテンプレートを作成できるのが特徴です。SymfonyやDrupalなど多くの有名フレームワークやCMSでも採用されています。

テンプレート内では、変数の出力、条件分岐、ループ処理、フィルターや関数の利用などを簡潔な構文で記述できます。また、変数を自動的にエスケープする仕組みが備わっており、クロスサイトスクリプティング(XSS)などのセキュリティリスクを軽減します。

  • 可読性の高い構文 … PHPコードを直接埋め込む必要がなく、デザイナーやフロントエンドエンジニアも理解しやすい。

  • セキュリティ … 自動エスケープにより、安全なHTML出力が可能。

  • 拡張性 … 独自のフィルターや関数を追加できるため、柔軟なカスタマイズが可能。

  • 高速動作 … コンパイルされたPHPコードとしてキャッシュされるため、パフォーマンスに優れる。

Ver. 3.2 で追加されたTwigテンプレートを利用することで、テンプレートの保守性・再利用性が向上し、チーム開発や長期運用の負担を軽減できます。

Twigテンプレートの有効化


管理画面 > テーマ から、使用テーマの編集画面に入り「Twigテンプレート」を有効にすることで、Twig記法が利用することができるようになります。

テーマ設定のTwigテンプレートを有効に選択する
テーマ設定画面

もしくは、テーマ内の「template.yaml」を以下のように設定することでも可能です。

tpl_top : index.twig
tpl_index : index.twig
tpl_detail : _entry.twig
tpl_404 : 404.twig
tpl_admin : admin.html
tpl_entry_edit : _entry.twig
tpl_login : _member-admin/login.html
tpl_twig : enabled

template.yaml の設定は、管理画面のテーマ設定より優先されます(load_yaml_tpl: on のとき。既定で on)。template.yaml は使用中のテーマから親テーマへ順に探し、最初に値が見つかったものを使います。管理画面で切り替えても反映されない場合は、使用テーマ・親テーマの template.yaml に tpl_twig が書かれていないか確認してください。

テンプレートファイルの探索順

Ver. 3.2.18 以降、指定されたファイル名に対して、以下の順にテンプレートが探索されます。

拡張子が .html、または .twig の場合

探索順

候補ファイル名の例

1

index.twig

2

index.html.twig

3

index.html

.html 以外の拡張子(例:.xml)の場合

探索順

候補ファイル名の例

1

foo.xml.twig

2

foo.xml

.xml などの場合は foo.twig(汎用の .twig ファイル)は候補に含まれません。これは、XMLテンプレートをHTMLテンプレートとして誤って解決するのを防ぐためです。

探索はテーマ単位で行われます。使用中のテーマで上の順に探し、見つからなければ親テーマ、最後に system テーマで同じ順に探します。そのため、子テーマに index.html、親テーマに index.twig がある場合は、子テーマの index.html が使われます。

Twigテンプレートのキャッシュ

Twig テンプレートはコンパイルされた PHP コードとしてキャッシュされます。デバッグモードがオフのときは、テンプレートファイルを編集しても自動では再コンパイルされません。この動作は「テンプレートキャッシュ」(template_cache)の設定とは関係なく、template_cache が off でも同じです。

開発中はデバッグモードをオンにして作業し、本番環境にテンプレートを反映したときは、ダッシュボードからテンプレートのキャッシュをクリアしてください。

Twigテンプレートの拡張子


拡張子は「twig」がおすすめ

Twigテンプレートには特に拡張子の制限はありません。
そのため、拡張子が .html のテンプレートファイルにTwigの記法を使っても、正しく動作します。

しかし、Twigで記述する場合は .twig 拡張子を使用することをおすすめします。
理由は、エディタがテンプレートをTwigとして認識し、構文ハイライトやコード補完、Twig専用のフォーマット機能など、開発を効率化する機能を利用できるためです。

ファイル例

_top.twig
index.twig
_entry.twig

URLでテンプレートを指定する場合の注意点

通常、動的テンプレートやインクルード用テンプレートでは、ファイル名をURLで直接指定することはありません。 しかし、ページURLとテンプレートファイル名を合わせたい場合には注意が必要です。

拡張子が html の場合

例として、検索結果ページを

https://example.com/search.html

で表示したい場合、テンプレートは twig → html.twig → html の順に探索されるため、search.twig というファイル名で正しく読み込まれます。

search.html.twig という命名も利用できます。URLとの対応が明示的になるため、チームでの可読性を重視する場合はこちらも有効な選択肢です。

xml・csv など HTML 以外の拡張子の場合

.xml や .csv など HTML 以外の拡張子をURLに含む場合は、search.twig のような汎用の .twig ファイルは候補に含まれません。この場合は search.csv.twig / search.xml.twig のように元の拡張子を含めたファイル名が必要です。

コンテキスト

利用できるファイル名の例

HTML(.html)

search.twig / search.html.twig / search.html

XML(.xml)

search.xml.twig / search.xml

CSV(.csv)

search.csv.twig / search.csv

Twig記法と従来記法の併用について


Twigが有効なテーマでは、Twig記法と従来のテンプレート記法を混在させて記述できます。
ただし、テンプレートの解決順により、特定の組み合わせでは記法が正しく反映されない場合があります。

テンプレートの解決順

Twigが有効な場合、テンプレートは以下の順序で解決されます。

  1. Twigによる記述の解決
    ({% include %} や {% extends %} など、Twigの構文を含む部分が先に処理されます)

  2. Twigが解決された後に、従来のテンプレート記法が解決される
    (@include や @extends など、従来の構文が後から処理されます)

このため、処理順の都合で、テンプレートが正しく解決されないパターンがあります。

テンプレートが解決されないパターン

  • 従来の @include で読み込んだテンプレートにあるTwig記法は解決されない

  • 従来の @extends で継承したテンプレート以下にあるTwig記法は解決されない

  • 従来の @extends で継承されているテンプレートは、Twig記法でインクルード出来ない


簡単に整理すると、Twigが先に解決されるため、従来記法によるインクルードやテンプレート継承されたテンプレートでは、Twig記法は使えないということになります。逆にいうとルートテンプレートからTwigによるテンプレート継承や、インクルードがされていれば、従来記法と併用が可能です。

Twigの基本記法


ここでは、Twigの基本的な構文を紹介します。すでにTwigの利用経験がある方は読み飛ばして構いません。

変数の書き方

変数は {{ }} で囲んで出力します。

{{ title }}
{{ entry.id }}

グローバル変数の書き方

Twigでは、グローバル変数と変数の記法に区別はありません。{{ }} で囲むことで出力できます。Twig標準の仕様に従います。

<h1>{{ BLOG_NAME }}</h1>

従来の記法では、グローバル変数に校正オプションを適応できませんでしたが、Twigでは変数と同じ記法になるので、グローバル変数に校正オプションも同様に適応できるようになります。

{{ NOW_DATE|date('Y年m月d日') }}

変数を定義する

Twig内では、テンプレート内で新しく変数を定義することができます。
変数定義には set タグ を使用します。計算結果や文字列の組み立て、繰り返し処理での一時的な値の保持などに便利です。

従来記法の SetTemplate や SetRendered に近い概念ですが、Twigでは定義した値を変数として直接利用できる点が異なります。従来テンプレートには同等の機能はありません(Twig標準の仕様に準拠)。

{% set greeting = "こんにちは" %}
{% set name = "山田" %}

<p>{{ greeting }}, {{ name }}さん!</p>

文字列の連結

Twigでは、~(チルダ) 演算子を使って文字列を結合できます。
これは、PHPの . 演算子やJavaScriptの + 演算子に相当し、文字列と変数を簡単に組み合わせることができます。

{% set title = "今日の天気" %}
{% set weather = "晴れ" %}

<p>{{ title }} は {{ weather }}です。</p>
<p>{{ title ~ "は" ~ weather ~ "です。" }}</p> <!-- 連結して出力 -->

if文の書き方

Twigでは「ifタグ」を使用して記述します。(Twig標準の仕様に従います)

{% if SESSION_USER_AUTH %}
  <p>
    ログイン中です
  </p>
{% endif %}

条件式の記述例

比較演算子

  • ==(等しい)

  • !=(等しくない)

  • >(大きい)

  • <(小さい)

  • >=(以上)

  • <=(以下)

{% set age = 18 %}

{% if age >= 18 %}
  <p>成人です。</p>
{% else %}
  <p>未成年です</p>
{% endif %}

論理演算子

  • and(かつ)

  • or(または)

  • not(否定)

{% set isLogin = true %}
{% set isAdmin = true %}

{% if isLogin and isAdmin %}
    <p>ログイン済みの管理者です。</p>
{% endif %}

{% if not isLogin %}
    <p>ログインしてください。</p>
{% endif %}

is 演算子

  • empty: 空かどうか

  • defined: 定義されているかどうか

  • null: nullであるかどうか

  • even/odd: 偶数か奇数か

  • divisible by: 指定した数で割り切れるか

{% set name = '山田' %}
{% set list = [] %}
{% set number = 6 %}

{% if name is defined %}
    <p>名前: {{ name }}</p>
{% endif %}

{% if list is empty %}
    <p>リストは空です。</p>
{% endif %}

{% if number is even %}
<p>
  {{ number }}は偶数です。
</p>
{% endif %}

{% if number is divisible by(2) %}
  <p>{{ number }}は2で割り切れます。</p>
{% elseif number is divisible by(3) %}
  <p>{{ number }}は3で割り切れます。</p>
{% else %}
  <p>{{ number }}は2でも3でも割り切れません。</p>
{% endif %}

in 演算子

{% set colors = ["red", "blue", "green"] %}

{% if "blue" in colors %}
    <p>青色が含まれています。</p>
{% endif %}

他のプログラミング言語と同様に、括弧を使って条件式の優先度を制御できます。


ループ処理

Twigでのループの書き方はとてもシンプルです。「forタグ」を使って、配列やリストを簡単にループ処理できます。基本的な構文は以下の通りです。(Twig標準の仕様に従います)

{% set fruits = ['Apple', 'Banana', 'Cherry'] %}

<ul>
    {% for fruit in fruits %}
        <li>{{ fruit }}</li>
    {% endfor %}
</ul>

モジュールで取得したデータをループする例

{% set entrySummary = module('V2_Entry_Summary') %}

<ul>
  {% for entry in entrySummary.items %}
    <li>{{ entry.title }}</li>
  {% endfor %}
</ul>

インデックスの取得

「loop」という特殊な変数を使用して、ループのインデックスやその他の情報を取得できます。loop.index で1から始まるインデックスを取得したり、loop.index0 で0から始まるインデックスを取得できます。

<ul>
  {% for entry in entrySummary.items %}
    <li>{{ loop.index }}: {{ entry.title }}</li>
  {% endfor %}
</ul>

その他のloopオプション

  • loop.first:ループの最初の要素の場合にtrueを返す

  • loop.last:ループの最後の要素の場合にtrueを返す

  • loop.revindex:残りの要素数(1からカウント)

  • loop.revindex0:残りの要素数(0からカウント)


「loop.first」や「loop.last」を使用することで、従来の <!-- BEGIN glue --> の代替ができます。

{% for entry in entrySummary.items %}
  {{ entry.title }}
  {% if not loop.last %} | {% endif %}
{% endfor %}

モジュールの使用方法


Twigを拡張し、モジュールのデータを取得するa-blog cms独自の関数を追加しています。関数で呼び出したモジュールのデータを変数に格納して使用します。

例:V2_Entry_Summary モジュールを呼び出して使用する

{% set entrySummary = module('V2_Entry_Summary', 'モジュールID名', { bid: BID, cid: CID }) %}
<div>
  <div class="acms-cssgrid acms-g-cols-1 acms-g-cols-md-3">
    {% for entry in entrySummary.items %}
    <div>
      {% if entry.mainImage.path %}
      <img
        src="{{ entry.mainImage.path|resizeImg(360) }}"
        alt="{{ entry.mainImage.alt }}"
        class="acms-img-responsive"
        width="{{ entry.mainImage.width }}"
        height="{{ entry.mainImage.height}}"
        loading="lazy"
        decoding="async"
      >
      {% endif %}
      <h3>{{ entry.title }}</h3>
      <p>{{ entry.summary }}</p>
      <p><a href="{{ entry.url }}" class="acms-btn">詳細をみる</a></p>
    </div>
    {% endfor %}
  </div>
</div>

module() 関数の引数について

引数

内容

第1引数

V2モジュール名(例:V2_Entry_Summary)

第2引数

モジュールID(管理画面で設定されたIDを指定)

第3引数

URLコンテキスト(従来の ctx に該当。例:{ bid: BID, eid: EID } など)

* 「モジュールID」と「URLコンテキスト」は、従来モジュール同様に省略可能です。

{% set entrySummary = module('V2_Entry_Summary') %}

第3引数には bid・cid・eid・uid・page・limit・keyword・tag・field・order・start・end を指定できます(bid・cid・eid・uid は配列でも指定できます)。limit で表示件数を指定すると、モジュールIDやコンフィグの表示件数より優先されます。

モジュールIDと第3引数を併用した場合の優先順位は次のとおりです(標準モジュールの ctx と同じ)。

  1. モジュールIDの引数にチェックがあり、表示中の URL にその値がある場合は、URL の値

  2. モジュールIDの条件設定に入力した値

  3. 第3引数の値

モジュールIDで空欄の項目だけ、第3引数の値が使われます。

指定したモジュールIDが存在しない・非公開・別ブログのもの(グローバル設定でない)の場合は、エラーにはならず、モジュールIDなしの状態で動作します。表示が想定と違うときは、まずモジュールIDの名前・ステータス・所属ブログを確認してください。


Twig記法では従来のモジュールは呼び出せないのでご注意ください。Twigで呼び出せるモジュールはモジュール名の最初が「V2」から始まるモジュールのみになります。

V2モジュール例

  • V2_Entry_Summary

  • V2_Entry_Body

  • V2_Entry_TagRelational

  • V2_Category_Tree

  • V2_Media_Banner

  • V2_Blog_Field

  • V2_Module_Field

  • V2_Links

名前が似ていても従来のモジュールとは出力される変数や構造は違いますのでご注意ください。


V2モジュールの変数の見方

V2モジュールでは、従来のような「変数表」は用意されていません。
その代わりに、Twigテンプレートでモジュールを読み込んだ状態で、クイックサーチ機能から利用可能な変数を確認できる仕組みになっています。

クイックサーチの起動方法

管理者としてログイン中に、以下のショートカットキーを押すことでクイックサーチが開きます。

  • Windows / Linux:Ctrl + K

  • Mac:⌘(Command)+ K

デバッグモードでの変数確認

クイックサーチを開いた状態で、デバッグモードが有効になっているときに #(シャープ)を入力すると、現在のページで読み込まれているV2モジュールの変数一覧(変数表)が表示されます。

クイックサーチから変数表を表示
クイックサーチから変数表を表示
実際の値が入った変数表が確認できる
実際の値が入った変数表が確認できる

変数名をクリックすると、その変数のパスがクリップボードにコピーされます。
これにより、Twigテンプレートへ変数を貼り付ける際に、手入力せず正確な変数名を利用できます。

タッチモジュールの使用方法


Twigを拡張し、タッチモジュールを呼び出すa-blog cms独自の関数を追加しています。関数で呼び出すことで真偽値が返却されるので、if記法と併用して出し分けます。

{% if touch('Touch_Login') %}
  <p>ログイン中です</p>
{% endif %}

touch関数は、module関数と違い既存のすべてのタッチモジュールを呼び出せます。


表示・非表示を制御しているのは、単なる「ifタグ」なので、条件式をtouch関数だけではなく組み合わせて利用することもできます。

{% if touch('Touch_Login') and IS_ADMIN %}
  <p>ログイン中 かつ 管理ページの場合</p>
{% endif %}

校正オプション(フィルター)


Twigの記法では、変数の中にパイプ(|)で区切りフィルターを指定します {{ 変数|フィルター1|フィルター2 }} (Twig標準の仕様に従います)

{% set content = '今日の天気は\n晴れです' %}

<p>{{ content|nl2br|safe_html }}</p>

使用できる校正オプションの種類

従来の標準校正オプションは利用できますが、Twig標準のフィルターと名前がかぶるものもあります。この場合Twigのフィルターが優先されるので、従来の標準校正オプションを指定したい場合は、プレフィックス acms_ を付与して指定ください。

名前がかぶる校正オプション・フィルター(Ver. 3.2 系の標準の校正オプションの場合)

date escape nl2br number_format split striptags trim

これらは Twig 標準のフィルターとして動きます。a-blog cms の校正オプションとして使いたい場合は acms_date acms_trim のように acms_ を付けてください。

Corrector.php で独自に追加した校正オプションの名前が Twig 標準のフィルターと重なる場合も、同じく acms_ を付けた名前でだけ使えます。

従来の校正オプションを使用する

{{ entry.datetime|acms_date('Y年m月d日') }}

従来のa-blog cmsの校正オプションに加え、Twig標準のフィルターも全く同じ記法で指定することができます。

{% set sizes = [34, 36, 38, 40, 42] %}

{{ sizes|filter(v => v > 38)|join(', ') }}
{# output 40, 42 #}

引数に変数を指定

従来の校正オプションでは、一部校正オプションのみ引数に変数を利用できましたが、Twig記法だと全てのフィルターに変数が利用できます。

{% set content = '文書を途中で切ります' %}
{% set length = 4 %}
{% set ellipsis = '...' %}

<p>
  {{ content|mb_trim(length, ellipsis) }}
</p>

フィルターを使用したデフォルト値

変数の値がなかった場合に、デフォルト値を出力することができます。

<p>{{ nickname | default("ゲスト") }}</p>

twigでの「raw」校正オプション(フィルター)の仕様が変更になります。

既存テンプレート
{hoge}[raw]
危険なタグはエスケープされ、安全なHTMLは出力されます

{hoge}[raw|allow_dangerous_tag]
scriptを含めエスケープを無効にして、値をそのまま出力します。使用箇所には注意が必要です。

Twigテンプレート
{{ hoge|safe_html }}
危険なタグはエスケープされ、安全なHTMLは出力されます。

{{ hoge|raw }}
scriptを含めエスケープを無効にして、値をそのまま出力します。使用箇所には注意が必要です。

インクルードの書き方


Twigでのインクルードの書き方について解説します。(Twig標準の仕様に従います)

基本的なインクルード

include関数を使ってテンプレートをインクルードします。

{{ include('/path/to/parts.twig') }}

変数を渡す

インクルードするテンプレートに変数を渡したい場合は、第2引数として変数を渡します。

{{ include('/path/to/parts.twig', { title: 'タイトルです' }) }}

このように書くことで、/path/to/parts.twig 内で title 変数が使えるようになります。

ファイルが存在しない場合のエラー回避

従来のインクルード文だと、インクルードするファイルがない場合でもエラーは発生しませんでしたが、Twigのインクルードはファイルが存在しない場合エラーが出力されます。

インクルードするファイルが存在しない場合にエラーを回避するには、名前付き引数 ignore_missing に true を渡します。

{{ include('/path/to/parts.twig', {}, ignore_missing = true) }}

引数を位置で渡す場合、ignore_missing は第4引数です。第3引数は親テンプレートの変数を引き継ぐかどうかを指定する with_context です(Twig 標準の include と同じ順序)。

{# 位置で渡す場合(第3引数 with_context、第4引数 ignore_missing) #}
{{ include('/path/to/parts.twig', {}, true, true) }}

インクルード文の中にはグローバル変数以外にも全ての変数が利用できます。

従来のインクルードだと、インクルードパス内に利用できる変数はグローバル変数かつ特定のものに制限されていましたが、Twigのインクルードはすべての変数をインクルードパスに含めることが可能です。

{% set filename = 'hoge' %}

{{ include('/include/' ~ filename ~ '.twig', ignore_missing = true) }}

テンプレートの継承


Twigでも従来テンプレートと同じようにテンプレートの継承機能が利用できます。Twig標準の仕様に従います。

継承元テンプレート

継承元テンプレートでは、シンプルなHTMLレイアウトを定義します。

<!DOCTYPE html>
<html>
  <head>
    {% block headMeta %}
      {{ include('/include/head/meta.twig') }}
    {% endblock %}
    {% block headLink %}
      {{ include('/include/head/link.twig') }}
    {% endblock %}
    {% block headJs %}
      {{ include('/include/head/js.twig') }}
    {% endblock %}
  </head>
  <body>
    <header>
      <h1>ヘッダー</h1>
    </header>
    <main>
      {% block main %}
        <p>継承してメインコンテンツを設定してください</p>
      {% endblock %}
    </main>
    <footer>
      {% block footer %}
        <p>Site Footer</p>
      {% endblock %}
    </footer>
  </body>
</html>

この例では block タグを使用して、継承(子)テンプレートが継承する5箇所のブロックを定義しています。

このblockタグが行うことは、子テンプレートがテンプレートのその部分を上書きする可能性があることをテンプレート エンジンに伝えることだけです。

継承(子)テンプレート

継承(子)テンプレートは次のようになります。

{% extends 'parent_template.twig' %}

{% block headLink %}
  {{ parent() }}
  <link rel="stylesheet" href="/include/edit/custom.css" />
{% endblock %}

{% block main %}
  <p>
    メインコンテンツを上書き
  </p>
{% endblock %}

extendsタグは、テンプレートエンジンにこのテンプレートが別のテンプレートを「拡張」していることを伝えます。このテンプレートを評価する際、まず親テンプレートを探します。extendsタグはテンプレートの最初のタグである必要があります。

ここでは headLink ブロックと main ブロックを上書きしてます。子テンプレートは、 headMeta headJs footer ブロックを定義していないため、代わりに親テンプレートの値が使用されることに注意してください。

親ブロック

親ブロックの内容をレンダリングするには、  parent 関数を使用します。これにより、親ブロックの結果が返されます。

{% block headLink %}
  {{ parent() }}
  <link rel="stylesheet" href="/include/edit/custom.css" />
{% endblock %}

名前付きブロック

Twig では、読みやすさを向上させるために、終了タグの後にブロック名を置くことができます。

{% block main %}
  <p>
    メインコンテンツ...
  </p>
{% endblock main %}

Twigのブロック名にはいくつかの命名規則があります

  • 英字(アルファベット)と数字、アンダースコア(_)のみが使用可能

  • 英字から始めなければならない

有効なブロック名の例

  • headJs

  • head_js

  • headJs123

無効なブロック名の例

  • head-js

  • 123headJs

その他のTwig機能について


a-blog cms での Twig の基本的な使い方について学んできましたが、他にも便利なTwigの機能がありますので、ぜひ目を通してみてください。

Twigのドキュメント

以下一部便利な機能を紹介します。

macro(マクロ)機能

Twigには、テンプレート内で関数のように使える macro(マクロ)機能 があります。
複雑なHTML構造や繰り返し処理をひとつの関数としてまとめられるため、特に階層構造のデータを扱うときに便利です。

階層データの例

たとえば「V2_Category_Tree」モジュールは、カテゴリが入れ子になった階層構造のデータを返します。

{
  items:
    [
      {
        cid: 1,
        name: "お知らせ",
      },
      {
        cid: 2,
        name: "製品",
        children:
          [
            {
              cid: 3,
              name: "家庭用製品",
            },
            {
              cid: 4,
              name: "業務用製品",
              children:
                [
                  {
                    cid: 6,
                    name: "業務用製品のお知らせ",
                  },
                ],
            },
          ],
      },
    ]
}

for文のみで書く場合

階層をすべて表示しようとすると、階層分だけfor文をネストする必要があり、コードが深く複雑になります。

{% set tree = module('V2_Category_Tree') %}

<ul>
  {% for category in tree.items %}
    <li>
      {{ category.name }}
      {% if category.children is not empty %}
        <ul>
          {% for child in category.children %}
            <li>
              {{ child.name }}
              {% if child.children is not empty %}
                <ul>
                  {% for child2 in child.children %}
                    <li>{{ child2.name }}</li>
                  {% endfor %}
                </ul>
              {% endif %}
            </li>
          {% endfor %}
        </ul>
      {% endif %}
    </li>
  {% endfor %}
</ul>

macroを使ってシンプルに書く

macroを使えば、階層構造の処理を再帰的に呼び出せる関数としてまとめられるため、コードがすっきりします。

{% set tree = module('V2_Category_Tree') %}

{% macro renderCategories(categories) %}
  <ul>
    {% for category in categories %}
      <li>
        {{ category.name }}
        {% if category.children is not empty %}
          {{ _self.renderCategories(category.children) }}
        {% endif %}
      </li>
    {% endfor %}
  </ul>
{% endmacro %}

{{ _self.renderCategories(tree.items) }}
  • macroはテンプレート内で定義できる関数のような構文。

  • 上記例ではrenderCategoriesというマクロを作成し、カテゴリをリスト表示。

  • 子カテゴリ(children)が存在すれば同じマクロを再帰的に呼び出し、階層の深さに制限なく対応可能。

  • 呼び出しは_self.マクロ名()で行います。

Twig記法をそのまま出力する

{{ ... }} や {% ... %} など、テンプレートとして解釈されてほしくない場合は verbatim タグを使用することで、そのまま出力することができます。

たとえば、他のテンプレートエンジン(Vue.js や Angular など)と併用し、{{ }} がTwigに解釈されないようにしたい場合などに便利です。

{% verbatim %}
  {{ message }}
  {% if user %}
    Hello, {{ user }}!
  {% endif %}
{% endverbatim %}

組み込み Twig 関数 acms_config


組み込み Twig 関数 acms_config()

acms_config() は、Twig テンプレートからコンフィグ(設定)を参照するための組み込み関数です。現在のコンテキストに対応するコンフィグセットやルールなどを考慮したコンフィグを 1 つのオブジェクトとして受け取り、メソッド経由で値を取り出します。

この関数は a-blog cms のすべての Twig 環境に組み込まれています。管理画面の差し込みだけでなく、公開側テーマの Twig でも使えます(公開側はテーマが Twig で描画される場合)。

設定画面(フォームと保存)を作るための機能は 設定画面を Twig で書く に分けて解説しています。このページでは値を参照するための API を扱います。


対応バージョン: Ver. 3.2.24 以降で利用できます。


基本

acms_config() の戻り値を変数に受けて、メソッドで値を取り出します。

{% set config = acms_config() %}

<p>{{ config.get('site_title') }}</p>

引数なしで呼ぶと、現在のコンテキストに対応するコンフィグセットやルールなどを考慮したコンフィグを参照します。

引数(スコープの指定)

特定のルール・モジュール・コンフィグセットのコンフィグを参照したい場合は、連想配列でスコープを指定します。

{% set config = acms_config({ blogId: 1 }) %}

キー

型

説明

blogId

int

ブログを指定する

configSetId

int

コンフィグセットを指定する

ruleId

int

ルールを指定する

moduleId

int

モジュールIDを指定する。(指定時は configSetId より優先)

値の重ね合わせ順

コンフィグは次の順に重ね合わされ、後のものが優先されます。

システムデフォルト(config.system.default.yaml, config.system.yaml)
  → ブログ設定(または configSetId 指定時はコンフィグセット)
  → ルール設定/モジュール設定(指定時)
  → POST 値(フォーム送信時)   ← デフォルトで重なる

最後の「POST 値の重ね合わせ」については後述します。公開側で参照する場合、通常 POST 値はないため、保存済みの値がそのまま返ります。

値を参照するメソッド

メソッド

戻り値

説明

get(key, default = null, index = null)

string

単一値を取得する。index で配列値の特定要素を取得

string(key, default = null, index = null)

string|null

単一値を文字列として取得する。index で配列値の特定要素を取得

integer(key, default = null, index = null)

integer|null

単一値を数値として取得する。index で配列値の特定要素を取得

float(key, default = null, index = null)

float|null

単一値を浮動小数点数として取得する。index で配列値の特定要素を取得

boolean(key, default = null, index = null)

boolean|null

単一値を真偽値として取得する。index で配列値の特定要素を取得

array(key)

array

配列値を取得する

selected(key, value, index = null)

Markup

値が一致すれば selected="selected" を出力

checked(key, value, index = null)

Markup

値が一致すれば checked="checked" を出力

field(key)

array

フィールド 1 件分(value と array)を取得

group(name)

array

フィールドグループの行ループ配列を取得

all()

array

コンフィグ全体を取得

persisted()

ConfigAccessor

POST 値を重ねない版のアクセサを返す

引数のないメソッドは、Twig のプロパティ記法でも書けます(config.saved のように)。値を取るメソッドは config.get('key') のように呼びます。

単一値と配列値

{# 単一値 #}
<input type="text" value="{{ config.get('site_title') }}">

{# デフォルト値つき #}
{{ config.get('items_per_page', '10') }}

{# 配列値 #}
<ul>
  {% for tag in config.array('default_tags') %}
    <li>{{ tag }}</li>
  {% endfor %}
</ul>

select / checkbox / radio の状態

selected() と checked() は、現在値と一致したときだけ属性文字列を返します。戻り値は Twig\Markup なので、自動エスケープを通さずそのまま属性として出力されます。

<select name="status">
  <option value="open" {{ config.selected('status', 'open') }}>公開</option>
  <option value="close" {{ config.selected('status', 'close') }}>非公開</option>
</select>

<input type="checkbox" name="notify" value="on" {{ config.checked('notify', 'on') }}>

フィールド / グループ

カスタムフィールドのように「1 キーに複数値」「グループの繰り返し」を扱う場合は field() / group() / all() を使います。

{# グループの繰り返し #}
{% for row in config.group('links') %}
  <a href="{{ row.url.value }}">{{ row.label.value }}</a>
{% endfor %}

persisted(保存済みの値だけを参照する)

acms_config() はデフォルトで、フォーム送信中の POST 値を最後に重ね合わせます。これはフォームの再描画でユーザー入力を保持するための挙動です。

「ユーザー入力ではなく、純粋に保存済みの値だけを見たい」場合は persisted() を使います。

{# POST 値を考慮せず、保存済みの値だけを参照 #}
{{ config.persisted.get('site_title') }}

閲覧側テーマで参照する場合は通常 POST 値がないため、get() と persisted().get() の結果は同じになります。

自動エスケープについて

  • get() などで取り出した値を {{ }} で出力すると、Twig の自動エスケープが効きます(HTML 特殊文字はエスケープされます)。

  • selected() / checked() は属性として出力するため Twig\Markup で返され、エスケープされません。

プラグイン(拡張アプリ)の管理画面を作るには

保存通知・バリデーション・フォーム送信を伴う設定画面を作る場合は、このページの API に加えて posted / valid / errors / invalid などのメソッドと、フォームのバリデーション宣言を組み合わせます。詳しくは次を参照してください。

→ 設定画面を Twig で書く

組み込み Twig 関数 acms_link / acms_path


組み込み Twig 関数 acms_link() / acms_path()

acms_link() と acms_path() は、Twig テンプレートから a-blog cms の URL を生成するための組み込み関数です。ブログ・カテゴリー・エントリーなどの URL コンテキストを連想配列で指定すると、対応する URL(またはそのパス部分)を返します。PHP 関数の acmsLink() / acmsPath() に相当します。

この関数は a-blog cms のすべての Twig 環境に組み込まれています。管理画面の差し込みだけでなく、公開側テーマの Twig でも使えます(公開側はテーマが Twig で描画される場合)。

対応バージョン: Ver. 3.2.39 以降で利用できます。

基本

acms_link() は、プロトコルとドメインを含む URL を返します。

{# ブログ ID 1 のカテゴリー ID 5 の一覧ページ #}
<a href="{{ acms_link({ bid: 1, cid: 5 }) }}">カテゴリー</a>

{# ブログ ID 1 のエントリー ID 10 の詳細ページ #}
<a href="{{ acms_link({ bid: 1, eid: 10 }) }}">詳細</a>

引数に指定しなかった項目は、現在の URL コンテキスト(現在のページの bid・eid など)を引き継ぎます。引き継ぎたくない場合は、オプションで inherit: false を指定します。

第 1 引数(クエリ)

URL コンテキストを連想配列で指定します。配列以外を渡すと InvalidArgumentException になります。

キー

説明

bid

ブログ ID

cid

カテゴリー ID

eid

エントリー ID

uid

ユーザー ID

keyword

キーワード

tag

タグ

field

フィールドによる絞り込み

order

並び順

tpl

テンプレート

page

ページ番号

limit

表示件数

admin

管理ページ名

fragment

URL のフラグメント(# 以降)

第 2 引数(オプション)

オプションは連想配列で指定します。値は true / false の真偽値だけを受け付けます。

acms_link() で指定できるオプションです。

オプション

既定値

説明

inherit

true

現在の URL コンテキストを引き継ぐかどうか

explicitTpl

false

URL コンテキストの tpl を必ず生成するかどうか。false のときは、tpl を指定していても不要な場合は生成しない

ignoreTplIfAjax

true

Ajax リクエストのときに tpl を付けないかどうか

{# 現在のページの状態を引き継がず、指定した内容だけで URL を作る #}
{{ acms_link({ bid: 1 }, { inherit: false }) }}

PHP 関数の旧い呼び出し形式(真偽値の第 2 引数や位置引数)は使えません。未対応のオプション名や、真偽値以外の値を指定すると InvalidArgumentException になります。

acms_path()

acms_path() は、ドメインを含まない URL のパス部分を返します。

{{ acms_path({ bid: 1, eid: 10 }) }}

acms_path() で指定できるオプションです。

オプション

既定値

説明

admin

false

管理画面向けに、ID を指定した形式(bid/1/cid/5/ のようなパス)で生成するかどうか

baseId

false

ID を指定した形式(bid/1/cid/5/ のようなパス)で生成するかどうか

explicitTpl

false

URL コンテキストの tpl を必ず生成するかどうか

管理画面へのリンク

管理画面のページへのリンク(bid/1/admin/... の形式)は、クエリに admin(管理ページ名)を指定すると生成できます。管理画面にログインしている状態では、ブログ・カテゴリー・エントリーの ID を指定した形式のパス(/bid/1/cid/5/admin/... のような形)になります。オプションの追加は要りません。

{# カテゴリーの編集画面へのリンク #}
<a href="{{ acms_link({ bid: BID, cid: cid, admin: 'category_edit' }, { inherit: false }) }}">カテゴリーを編集</a>

パス部分だけが必要なときは、acms_path() に admin: true を指定します。

{{ acms_path({ bid: BID, cid: cid, admin: 'category_edit' }, { admin: true }) }}

URL を生成できないとき

どちらの関数も、URL を生成できないとき(ブログ ID が決まらないときなど)は空文字を返します。

従来記法(.html テンプレート)でのセグメント名の出力

従来記法のテンプレートからは acms_link() / acms_path() を呼べません。管理画面や、公開側に出す管理用リンク(編集ボタンなど)で bid/ や admin/ を直接書くと、URL のセグメント名を変更した環境で動かなくなります。そのため、URL のセグメント名をグローバル変数として出力できます(Ver. 3.2.39 以降)。

変数

内容

%{BID_SEGMENT}

ブログ ID のセグメント名

%{CID_SEGMENT}

カテゴリー ID のセグメント名

%{EID_SEGMENT}

エントリー ID のセグメント名

%{ADMIN_SEGMENT}

管理ページのセグメント名

%{TPL_SEGMENT}

テンプレートのセグメント名

<a href="/%{BID_SEGMENT}/%{BID}/%{ADMIN_SEGMENT}/entry_editor/">エントリー一覧</a>

ログイン中のユーザーが所属するブログの URL は、%{SESSION_USER_BLOG_URL} で出力できます(未ログイン時とプレビュー時は空です)。会員向けページのプロフィール更新リンクのように、現在のブログと無関係に表示するリンクでは、%{BLOG_URL} ではなくこちらを使ってください。

Twig のテンプレートでは、セグメント名を直接書かずに acms_link() / acms_path() を使います。