Skip to content

Commit ff7fe96

Browse files
committed
Added a first implementation of a BreadcrumbRenderer
1 parent ad10e1e commit ff7fe96

File tree

1 file changed

+142
-0
lines changed

1 file changed

+142
-0
lines changed
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
<?php
2+
3+
namespace Knp\Menu\Renderer;
4+
5+
use \Knp\Menu\ItemInterface;
6+
7+
/**
8+
* Renders MenuItem tree as a breadcrumb
9+
*/
10+
class BreadcrumbRenderer extends Renderer implements RendererInterface
11+
{
12+
private $defaultOptions;
13+
14+
/**
15+
* @param array $defaultOptions
16+
* @param string $charset
17+
*/
18+
public function __construct(array $defaultOptions = array(), $charset = null)
19+
{
20+
$this->defaultOptions = array_merge(array(
21+
'additional_path' => null,
22+
'compressed' => false,
23+
'root_attributes' => array(),
24+
), $defaultOptions);
25+
26+
parent::__construct($charset);
27+
}
28+
29+
/**
30+
* Renders a menu with the specified renderer.
31+
*
32+
* @param \Knp\Menu\ItemInterface $item
33+
* @param array $options
34+
* @return string
35+
*/
36+
public function render(ItemInterface $item, array $options = array())
37+
{
38+
$options = array_merge($this->defaultOptions, $options);
39+
40+
$breadcrumb = $item->getBreadcrumbsArray($options['additional_path']);
41+
42+
if (empty($breadcrumb)) {
43+
return '';
44+
}
45+
46+
return $this->renderBreadcrumb($breadcrumb, $options);
47+
}
48+
49+
/**
50+
* Renders the breadcrumb
51+
*
52+
* @param array $breadcrumb
53+
* @param array $options
54+
* @return string
55+
*/
56+
protected function renderBreadcrumb(array $breadcrumb, array $options)
57+
{
58+
$html = $this->format('<ul'.$this->renderHtmlAttributes($options['root_attributes']).'>', 'ul', 0, $options);
59+
$html .= $this->renderList($breadcrumb, $options);
60+
$html .= $this->format('</ul>', 'ul', 0, $options);
61+
62+
return $html;
63+
}
64+
65+
/**
66+
* Renders the breadcrumb list
67+
*
68+
* @param array $breadcrumb
69+
* @param array $options
70+
* @return string
71+
*/
72+
protected function renderList(array $breadcrumb, array $options)
73+
{
74+
$html = '';
75+
foreach ($breadcrumb as $label => $uri) {
76+
$html .= $this->renderItem($label, $uri, $options);
77+
}
78+
79+
return $html;
80+
}
81+
82+
/**
83+
* @param string $label
84+
* @param string $uri
85+
* @param array $options
86+
* @return string
87+
*/
88+
protected function renderItem($label, $uri, array $options)
89+
{
90+
// opening li tag
91+
$html = $this->format('<li>', 'li', 1, $options);
92+
93+
// render the text/link inside the li tag
94+
if (null === $uri) {
95+
$content = $this->renderLabel($label, $options);
96+
} else {
97+
$content = sprintf('<a href="%s">%s</a>', $this->escape($uri), $this->renderLabel($label, $options));
98+
}
99+
$html .= $this->format($content, 'link', 1, $options);
100+
101+
// closing li tag
102+
$html .= $this->format('</li>', 'li', 1, $options);
103+
104+
return $html;
105+
}
106+
107+
protected function renderLabel($label, array $options)
108+
{
109+
return $this->escape($label);
110+
}
111+
112+
/**
113+
* If $this->renderCompressed is on, this will apply the necessary
114+
* spacing and line-breaking so that the particular thing being rendered
115+
* makes up its part in a fully-rendered and spaced menu.
116+
*
117+
* @param string $html The html to render in an (un)formatted way
118+
* @param string $type The type [ul,link,li] of thing being rendered
119+
* @param integer $level
120+
* @param array $options
121+
* @return string
122+
*/
123+
protected function format($html, $type, $level, array $options)
124+
{
125+
if ($options['compressed']) {
126+
return $html;
127+
}
128+
129+
switch ($type) {
130+
case 'ul':
131+
case 'link':
132+
$spacing = $level * 4;
133+
break;
134+
135+
case 'li':
136+
$spacing = $level * 4 - 2;
137+
break;
138+
}
139+
140+
return str_repeat(' ', $spacing).$html."\n";
141+
}
142+
}

0 commit comments

Comments
 (0)