LoginSignup
9

More than 3 years have passed since last update.

Twigで開発していた困ったところまとめ

Last updated at Posted at 2018-11-30

最近、フレームワークを使っていない環境で、Twigを使う機会があったのですが、
わからない事も多く、その上日本語の解説ページがなくて詰まる場面がありました。

そのため、自分への備忘録も兼ねて、記事にまとめておきたいと思います。

共通テンプレートを読み込み時のパス指定

共通テンプレートを作成して、別画面で読み込み時は{% include 'テンプレート名' %}を使うのですが、
テンプレート名に以下のような相対パスや絶対パスを指定するとエラーになってしまいます。

エラーになる例
{% include '/path/to/common_templates/sample.twig' %}

正しく読み込むには、Twigの組み込みローダーを呼び出した後に、
addPathに共通テンプレートのパスを渡す必要があります。

呼び出し元PHP
$loader = new Twig_Loader_Filesystem('/path/to/templates');
$twig = new Twig_Environment($loader, array(
    'cache' => '/path/to/compilation_cache',
));
$twig->addPath(/path/to/common_templates/);
画面
{% include 'sample.twig' %}

addPathの第2引数に名前空間も指定する事ができます。

呼び出し元PHP
$twig->addPath(/path/to/common_templates/, 'common_templates');
画面
{% include '@common_templates/sample.twig' %}

配列のキー名を動的に生成して値を取得する

以下のようなキー名に数字の連番が含まれる配列データを、
画面にrenderしていて、その配列の値を、キー値を動的に生成して取得したい場合、
以下のようにすれば取得ができます。

呼び出し元PHP
$data = [
  'sample_1' => '1',
  'sample_2' => '2',
  'sample_3' => '3',
];

$loader = new Twig_Loader_Filesystem('/path/to/templates');
$twig = new Twig_Environment($loader, array(
    'cache' => '/path/to/compilation_cache',
));
$twig->render('sample.html', $data);

sample.html
<select name="sample_select">
   {% for index in 1..data|length %}
      {% set data_index = "sample_" ~ index %}
      <option value="{{attribute(data, data_index)}}">{{attribute(data, data_index)}}</option>
   {% endfor %}
</select>

自作フィルターを読み込み

Twigで用意されているフィルターではなく、自作フィルターを読み込みたい場合、
Twigの組み込みローダーを呼び出した後に、Twig_Filterクラスにフィルター名と
実行したファンクションを引数に渡してあげて、生成されたオブジェクトをaddFilterに渡してあげる必要があります。

呼び出し元PHP
$loader = new Twig_Loader_Filesystem('/path/to/templates');
$twig = new Twig_Environment($loader, array(
    'cache' => '/path/to/compilation_cache',
));
$filter = new Twig_Filter('フィルター名', 'ファンクション');
$twig->addFilter($filter);

画面側では通常のフィルターと同じ使い方が出来るようになります。

画面
{{処理したいデータ|フィルター名}}

また、Twig_Filterクラスの引数にはクラスを指定することもできます。

クラスを指定する場合
$filter = new Twig_Filter('フィルター名', ['クラスオブジェクト', 'ファンクション']);

私が開発した環境では自作フィルター用のクラスを作成して、
そのクラスからフィルターを読み込むようにしました。

CustomFilter.class.php
<?php

class CustomFilter
{
   private $customFilterList = [
       'customFilter' => 'customFunction',
   ];

    public function getCustomFilterList(): array
    {
        return $this->customFilterList;
    }

   public function customFunction(string $string): string
   {
       $result = $string . 'CustomFilter';
       return $result;
   }
}
呼び出し元PHP

$customFilter = new CustomFilter();
$loader = new Twig_Loader_Filesystem('/path/to/templates');
$twig = new Twig_Environment($loader, array(
    'cache' => '/path/to/compilation_cache',
));

$customFilterList = $customFilter->getCustomFilterList();
foreach ($customFilterList as $filterName => $functionName) {
      $filter = new Twig_Filter($filterName, [$customFilter, $functionName]);
      $this->twig->addFilter($filter);
}
画面
{{処理したいデータ|customFilter}}

まとめ

今後もTwigを使っていくと思うので、
この備忘録を更新していけたらと思います。

Twigを使いはじめて日が浅いので、
間違いや、こうしたほうが良いんじゃないかといった意見がありましたら、
ご指摘していただけましたら嬉しいです。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9