symfonyにてテンプレートコードの共通化や再利用する方法はいくつかある。今回はそのあたりをまとめてみる。
方法としては、
- インクルード(include)
- パーシャル(partial)
- コンポーネント(component)
- コンポーネントスロット(component_slot)
- スロット(slot)
これを一つ一つ見てみる。
インクルード(include)
共通化されたコードが静的なHTMLだったり、actionなどに依存しないPHPコードくらいなら、include()がよさそう。
共通化したいフッタファイルを、アプリケーション共通のtemplateディレクトリに配置した場合はこんな感じで呼び出す。
[php]
[/php]
用途としては、ヘッダ、フッターファイル、静的なメニューなど。
パーシャル(partial)
上記のインクルードに、actionからの引数を渡せるようなイメージ。
呼び出し側は下記のように、userオブジェクトをsidebarパーシャルに渡している。
[php]
$site)) ?>
[/php]
呼び出される側は_(アンダーバー)から始まるファイル名をつける。上記の呼び出しの場合は、
app/application/template/_sidebar.phpというファイル名になる。
[php]
現在のパス:getName() ?>
[/php]
用途としては、サイドバーにカートの内容を表示したり、動的な部分を部品化するイメージ。
コンポーネント(component)
上記のパーシャルよりもさらに独立した動的なロジックが必要な場合。本来のactionとかけ離れた処理をサイドバーなどに表示させるときなどは、サイドバー用の処理とactionの処理を分け、サイドバー用の処理をコンポーネントでまとめるといったことができる。
サイドバーにて、ニュースの一覧記事を取得するような処理を想定した、呼び出し側は下記のようになる。
[php]
$user)) ?>
[/php]
呼び出される側のロジックは、actionクラスをcomponentクラスとして名前を変更すれば、普段のアクションクラスのようなロジックを書ける。
apps/application/module/news/action/components.class.php
[php]
addDescendingOrderByColumn(NewsPeer::PUBLISHED_AT);
$c->setLimit(5);
$this->news = NewsPeer::doSelect($c);
}
}
?>
[/php]
上記の例の場合、テンプレートは下記の位置に配置する。
apps/application/module/news/template/_headlines.php
用途としては、上記のようなサイドバーにてニュースの一覧を表示したりするとき。
コンポーネントスロット(component_slot)
上記のコンポーネントにさらに、呼び出しの度に変化するような場合はコンポーネントスロットを利用する。ここが少しややこしい気がするが、呼び出し側は同じでも、view.ymlにより呼び出すロジックを変更できるようなイメージ。
呼び出し側は、layout.phpなどで下記のようになる。
[php]
[/php]
app/application/config/view.ymlにはデフォルトのコンポーネントを登録しておく。
[code]
default:
components:
sidebar: [menu, default]
[/code]
そして、モジュールによって呼び出すロジックが変わる場合は、
app/application/module/foo/view.ymlなどのmodule側のview.ymlを下記のようにしておく。
[code]
default:
components:
sidebar: [menu, user]
[/code]
こうすることで、componentのdefaultを呼ぶか、userを呼ぶかなどモジュール、アクションなどにより変更できる。
スロット(slot)
いままでのものとはちょっと違うが、1回のレスポンスの中で部品化したい場合に2度同じテンプレートロジックを利用したいときなどに利用できる。
[php]
hoge
[/php]
slotで囲んだhogeがもう一度、下のinclude_slotで呼びだせます。
少しややこしいですが、こうしたテンプレートの部品化は設計にも影響与えてくる部分なのでしっかり見につけておきたい。
しかしこのややこしさ、どうにかならんものか。。。
symfony View:テンプレート、レイアウト、パーシャルとコンポーネント
Check Tweet