SYmfony2でパンくず機能をつけようと思うとBundleを入れてーとか面倒なことになります。様々な方法を考えた結果、牡蠣の方法が一番楽でスマートということがわかりこれを採用しています。
Twigテンプレにbread_addしていき、bread_showで表示するという流れです。考え方がわかれば簡単です。
service.yml にクラスを登録
app/config/service.yml に書きましたが、それぞれのBundle以下のservice.ymlに書いても構いません。下記ではCommonExtensionクラスを読み込ませ、TwigのExtensionを利用するようにサブクラスを作ります。
services:
app_common.twig.extension:
class: App\CommonBundle\Twig\CommonExtension
arguments: ["@service_container", "@router"]
tags:
- { name: twig.extension }
public: true
CommonExtensionクラス
CommonExtension.php の中身は下記のとおりです。bread_add, bread_showのfunctionをtwigテンプレ内で使えるようにしています。このサブクラスの作り方は今回のパンくずに限らず利用ができます。
<?php
namespace App\CommonBundle\Twig;
class CommonExtension extends \Twig_Extension
{
private $breads;
private $container, $router;
public function __construct($container, $router)
{
$this->container = $container;
$this->router = $router;
}
public function getFilters()
{
return array(
'bread_add' => new \Twig_Filter_Method($this, 'addBread'),
'bread_show' => new \Twig_Filter_Method($this, 'showBread', array('is_safe' => array('html')))
);
}
public function addBread($var)
{
if(!is_array($this->breads)) $this->breads = array();
if(is_array($var)){
foreach($var as $label=>$params){
if(isset($params['path'])){
if(isset($params['params'])){
$url = $this->container->get('router')->generate($params['path'], $params['params']);
} else {
$url = $this->container->get('router')->generate($params['path']);
}
$this->breads[ $label ] = $url;
} else {
$this->breads[ $label ] = '';
}
}
}
}
public function showBread($var)
{
if(!is_array($this->breads)) $this->breads = array();
$this->addBread($var);
$breads = array();
foreach($this->breads as $label => $url){
if($url){
array_push($breads, '<a title="'.$label.'" href="'.$url.'" itemprop="url"><span itemprop="title">'.$label.'</span></a>');
} else {
array_push($breads, $label);
}
}
return join(' > ', $breads);
}
}
?>
bread_add, bread_show 利用方法
bread_addしていき、bread_showで表示します。bread_add('label' => array('path'=>'', 'title'=>''))
{% set bread = { 'ページタイトル':{'path':'page'}, (title):{} } %}
{{ {'トップページ':{'path':'homepage'}}|bread_add }}
{{ bread|bread_show }}
という風にすると
<a title="トップページ" href="/" itemprop="url"><span itemprop="title">トップページ</span></a> > ページタイトル
という風に出力されます。