twigには別のテンプレートファイルを埋め込む仕組みが用意されており、{% include('template path name') %}
のように書けば、外部テンプレートの内容を埋め込むことができます。
が、取り込めるのは PHP側で指定したtwigテンプレートファイルの基準ディレクトリ配下のファイルに限られるようです。
今回は、.twig内に、テンプレートファイル基準ディレクトリの外側にあるファイルの内容を埋め込むのに、僕がとった方法の紹介です。
さて、twigには、filter という仕組みがあり、これを使うと、phpから渡ってきた変数やべた書きした文字列を twig template内で加工することができます。
標準でも、以下のような様々なフィルターが用意されています。
{# 配列の長さを出力する #}
{{valArray|length}}
{# html escapeせずに値をそのまま出力する #}
{{htmlSource|raw}}
{# PHPのnl2br関数と同等 #}
{{"今日は\n良い天気ですね\n"|nl2br}}
さらに、独自フィルターも簡単に追加できるようになっています。
filter の本来想定された使い方からは逸脱してしまうような気もしますが、今回は、.twig ファイル内に書かれたファイルパス名をファイルの内容に置き換えるようなフィルターを書いてみました。
// 自作フィルターを集めた class
// global function でもいいけど、classにまとめといたほうが煩雑にならないと思う
class TwigCustomFilter {
// $fileをファイルのパス名とみなし、ファイルの中身を返却する
public function twig_embed($file) {
if (!empty($file) &&
file_exists($file) &&
is_file($file)) {
return file_get_contents($file);
} else {
return '';
}
}
}
$loader = new Twig_Loader_Filesystem($templateDir);
$twig = new Twig_Environment($loader, ['debug' => false]);
// フィルターの追加
$twigCustomFilter = new TwigCustomFilter();
// embed というフィルターが .twigに書かれていたら $twigCustomFilter->twig_embed($file) を呼び出す
$filter = new Twig_SimpleFilter('embed', [$twigCustomFilter, 'twig_embed']);
$twig->addFilter($filter);
$template = $twig->loadTemplate($templateFileName);
$template->display(['documentRootPath' => $_SERVER['DOCUMENT_ROOT']);
<script>
{# スクリプトの内容を(htmlエスケープせずに)そのまま埋め込む #}
{{documentRootPath~'/assets/js/common.js'|embed|raw}}
</script>
{# テキストファイルの内容を htmlエスケープして埋め込む #}
{{documentRootPath~'/resource/license.txt'|embed}}
補足
twigの文字列連結演算子は、PHPの書き方とは異なっています。
PHPでは 「 . 」ですが、 twigの場合「 ~ 」になります。
フィルターはパイプ同様に数珠つなぎにすることができます。