Skip to content

Instantly share code, notes, and snippets.

@veewee
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save veewee/9fa72438953a5ad98dbe to your computer and use it in GitHub Desktop.
Save veewee/9fa72438953a5ad98dbe to your computer and use it in GitHub Desktop.
Spiffy Navigation - Breadcrumbs view helper
<?php
namespace Application\View\Helper;
use RuntimeException;
use SpiffyNavigation\Page\Page;
use SpiffyNavigation\View\Helper\AbstractHelper;
class Breadcrumbs extends AbstractHelper
{
/**
* An array of valid HTML5 attributes.
* @var array
*/
protected $validAttribs = array(
'class',
'href',
'id',
'rel',
'target'
);
/**
* Render default breadcrumbs.
*
* @param string|\SpiffyNavigation\Container|null $container
* @param array $options
* @return string
*/
public function renderBreadcrumbs($container = null, array $options = array())
{
$isActiveRecursion = $this->navigation->getIsActiveRecursion();
$this->navigation->setIsActiveRecursion(false);
$breadcrumbs = $this->getBreadcrumbs($container);
$html = '<ol class="breadcrumb">';
/** @var Page $page */
foreach ($breadcrumbs as $page) {
if (!$this->navigation->isAllowed($page)) {
continue;
}
$activeClass = $this->navigation->isActive($page) ? ' class="active"' : '';
$html .= sprintf('<li%s>', $activeClass);
$html .= $this->htmlify($page);
$html .= '</li>';
}
$html .= '</ol>';
$this->navigation->setIsActiveRecursion($isActiveRecursion);
return $html;
}
/**
* Renders the given $container by invoking the partial view helper
*
* The container will simply be passed on as a model to the view script
* as-is, and will be available in the partial script as 'container', e.g.
* <code>echo 'Number of pages: ', count($this->container);</code>.
*
* @param string|\SpiffyNavigation\Container|null $container [optional] container to pass to view script.
* @param string $partial [optional] partial view script to use.
* @return string
* @throws RuntimeException if no partial provided
*/
public function renderPartial($container = null, $partial = null)
{
$isActiveRecursion = $this->navigation->getIsActiveRecursion();
$this->navigation->setIsActiveRecursion(false);
$container = $this->getContainer($container);
if (null === $partial) {
$partial = $this->getPartial();
}
if (empty($partial)) {
throw new RuntimeException(
'Unable to render menu: No partial view script provided'
);
}
$model = array(
'breadcrumbs' => $this->getBreadcrumbs($container),
'navigation' => $this->navigation,
);
$html = $this->view->render($partial, $model);
$this->navigation->setIsActiveRecursion($isActiveRecursion);
return $html;
}
/**
* Default render.
*
* @param string|\SpiffyNavigation\Container|null $container
* @return string
*/
public function render($container = null)
{
$container = $this->getContainer($container);
if ($this->getPartial()) {
return $this->renderPartial($container);
}
return $this->renderBreadcrumbs($container);
}
/**
* @param \SpiffyNavigation\Container|string|null $container
*
* @return array
* @throws \RuntimeException
*/
protected function getBreadcrumbs($container)
{
$container = $this->getContainer($container);
$routeName = $this->getCurrentRouteName();
$pages = $container->findByOption('route', $routeName);
if (!$pages) {
return [];
}
/** @var Page $page */
$page = array_pop($pages);
$breadcrumbs = [$page];
while ($page->hasParent()) {
$page = $page->getParent();
array_unshift($breadcrumbs, $page);
};
return $breadcrumbs;
}
/**
* @return string
* @throws \RuntimeException
*/
protected function getCurrentRouteName()
{
$routeMatch = $this->navigation->getRouteMatch();
if ($routeMatch === null) {
throw new RuntimeException('No RouteMatch instance provided');
}
$name = $routeMatch->getMatchedRouteName();
if ($name === null) {
throw new RuntimeException('RouteMatch does not contain a matched route name');
}
return $name;
}
/**
* Convert a page to the html version.
*
* @param Page $page
* @return string
*/
protected function htmlify(Page $page)
{
if ($page->getOption('label')) {
$label = $page->getOption('label');
} else {
$label = $page->getName();
}
$href = null;
try {
$href = $this->navigation->getHref($page);
} catch (RuntimeException $e) {
; // intentionally left blank
}
$attribs = $page->getAttributes();
if ($href) {
$element = 'a';
$attribs['href'] = $href;
} else {
$element = 'span';
}
return sprintf('<%s%s>%s</%s>', $element, $this->htmlAttribs($attribs), $label, $element);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment