Twig 拡張 API(テンプレート・Filter・Function・Extension の登録)


プラグイン(拡張アプリ)やサイト拡張から、Twig を拡張するための API をまとめたリファレンスです。Twig ファサード(Acms\Services\Facades\Twig)と extendsTwig フックを通じて、テンプレートディレクトリの登録・部分描画・独自フィルターや関数の追加を行います。

全体像と位置づけは プラグイン(拡張アプリ)で Twig 管理画面を作る を参照してください。


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


登録経路は 2 つに分かれる

拡張は「登録するもの」によって書く場所が変わります。これは内部の都合(後述)によるもので、最初に押さえておくと迷いません。

登録するもの

書く場所

API

テンプレートディレクトリ

ServiceProvider::init()(一度だけ)

Twig::addTemplatePath()

Filter / Function / Extension

extendsTwig フック

Twig::registerFilter() ほか

テンプレートディレクトリの登録

Twig::addTemplatePath(string $dir, ?string $namespace = null): void

自前のテンプレートディレクトリを Twig のローダーに登録します。$namespace を指定すると、@namespace/... の形でテンプレートを参照できます。省略するとメイン名前空間に登録されます。

use Acms\Services\Facades\Twig;

// init() の中で一度だけ呼べばよい
Twig::addTemplatePath(PLUGIN_LIB_DIR . 'MyPlugin/template', 'myplugin');
{# 登録後はこう参照できる #}
{{ include('@myplugin/parts/header.twig') }}
  • $dir にはファイルシステムのパスを渡します。プラグインでは PLUGIN_LIB_DIR を使います。

  • ローダーの状態は Twig サービス内に保持され、Twig 環境が作り直されても引き継がれます。そのため初期化時に一度呼べば十分です。

  • @system はシステムテーマ参照用に予約された名前空間です。プラグインは独自の名前空間を切ってください。

Twig テンプレートを解決する

Twig::renderTemplate(string $name, array $context = []): string

指定したテンプレートを描画して、結果の HTML 文字列を返します。$context で変数を渡せます。差し込みポイントに登録する callable の中などで使います。

use Acms\Services\Facades\Twig;

$html = Twig::renderTemplate('@myplugin/admin/main.twig', [
    'title' => 'MyPlugin 設定',
    'items' => $items,
]);
<h1>{{ title }}</h1>
<ul>
  {% for item in items %}
    <li>{{ item }}</li>
  {% endfor %}
</ul>

描画結果をどこに出すかは InjectTemplate を参照してください。

Filter / Function / Extension の登録

独自のフィルター・関数・拡張クラスは、extendsTwig フックの中で登録します。フックは Twig 環境が組み立てられるたびに呼ばれます。

extendsTwig フック

extension/acms/Hook.php やプラグイン(拡張アプリ)のフックに extendsTwig メソッドを実装します。引数には Twig サービスが渡されます。

/**
 * Twig Environment 構築時に呼ばれる拡張ポイント
 */
public function extendsTwig(\Acms\Services\Template\Twig $twig): void
{
    $twig->registerFilter('site_format', fn(string $s) => '⚡' . $s);
    $twig->registerFunction('site_now', fn() => date('Y-m-d H:i:s'));
    $twig->registerExtension(new \Acms\Custom\Twig\SiteExtension());
}
{{ 'hello'|site_format }}   {# ⚡hello #}
{{ site_now() }}            {# 2026-06-17 10:00:00 #}

各メソッド

メソッド

説明

registerFilter(string $name, callable $callable, array $options = []): void

フィルターを登録する

registerFunction(string $name, callable $callable, array $options = []): void

関数を登録する

registerExtension(\Twig\Extension\AbstractExtension $extension): void

Twig Extension クラスを登録する

$options には Twig 標準の TwigFilter / TwigFunction のオプション(is_safe など)を渡せます。

同名のフィルター・関数を複数回登録した場合は、最後の登録が採用されます。同じ型の Extension も最後の登録にまとまります。

なぜ登録場所が分かれるのか

テンプレートディレクトリの登録と、Filter / Function / Extension の登録で書く場所が違うのには理由があります。

  • テンプレートディレクトリは Twig の「ローダー」に追加します。ローダーの状態はサービス側に保持され、環境が作り直されても保たれるため、初期化で一度登録すれば以後ずっと有効です。

  • Filter / Function / Extension は Twig の「環境(Environment)」インスタンスに結び付きます。環境は状況によって作り直されることがあり、そのたびに登録し直す必要があります。extendsTwig フックは環境の構築時に毎回呼ばれるので、ここに書いておけば作り直されても確実に再登録されます。

init()registerFilter() を呼んでも、内部で保留して環境構築時に反映する作りにはなっていますが、意図が明確になる extendsTwig フックに書くことを推奨します。