Сегодня при просмотре лога изменений в CakePHP обнаружил что в HtmlHelper есть функции для генерации хлебных крошек.
Всего 3 функции:
addCrumb -добавление элемента хлебных крошек
getCrumbs - генерирует хлебные крошки ввиде строки с сылками
getCrumbList - генерирует хлебные крошки ввиде списка с сылками
Для начала добавим элементы которые нужно будет вывести. Это необходимо делать в представлениях (View) или подобных местах - элементах или хелперах.
$this->Html->addCrumb(‘<i class="fa fa-home home-icon"></i> Главная’, ‘/’, array(‘escape’ => false)); $this->Html->addCrumb(‘Каталог’, ‘/catalog’); $this->Html->addCrumb(‘Сланцы’, Router::url(array(‘controller’ => ‘catalogs’, ‘action’ => ‘view’, 3)));
Теперь можно вывести хлебные крошки.
echo $this->Html->getCrumbs(' > ');
Это создаст простую строку:
Главная > Каталог > Сланцы
Если Вы хотите вывести хлебные крошки в список - как например это делается в Bootstrap, то Вам нужен getCrumbList.
echo $this->Html->getCrumbList();
Для Bootstrap.
echo $this->Html->getCrumbList(array( 'lastClass' => 'active', 'class' => 'breadcrumb', 'escape' => false ));
Этот хелпер не удобен тем что он хелпер и соответственно использовать его в контроллере проблематично. Например я обычно делаю так: в AppController->beforeFilter() добавляю в хлебные крошки ссылку на главную страницу, за тем так же в каждом контроллере в beforeFilter ссылку на index для текущего контроллера и для каждой функции так же свой элемент. Если есть плагин, то можно добавить и в AppControllerPlugin если необходимо показать такую иерархию.
Вот сам код компонента:
<?php
//app/Controller/Component/BreadcrumbsComponent.php
App::uses('Component', 'Controller');
/**
* Компонент для управления отображением "хлебными крошками"
*/
class BreadcrumbsComponent extends Component {
private $breadcrumbs = array();
public function initialize(Controller $controller) {
$this->add(__('Главная'), Router::url('/'));
}
public function beforeRender(Controller $controller) {
$controller->set('breadcrumbs', $this->breadcrumbs);
}
/**
* Добавление ссылки
*
* @param string|array $title Если передано string то добавляется одна
* ссылка указывающая на $url.
* Если передавать array, то будет добавлена группа ссылок, но
* в каждом элементе массива обязательно должны быть ключи 'title' и
* 'url'.
* @param string $url Строка представляющая относительную ссылку. Значение
* параметра в случае необходимости должно быть заранее подготовлено
* с помощью функции Router::url().
* @return boolean В случае ошибки возвращается false иначе true
*/
public function add($title, $url = '', $icon = '') {
if (is_array($title)) {
return $this->_add($title);
}
if (empty($this->breadcrumbs) || ($this->breadcrumbs[count($this->breadcrumbs) -1]['url'] != $url)) {
$this->breadcrumbs[] = array(
'title' => $title,
'url' => $url,
'icon' => $icon
);
}
return true;
}
public function clear() {
$this->breadcrumbs = array();
return true;
}
/**
* Добавление списка ссылок
*
* @param array $params Массив с описанием ссылок. В каждом элементе массива
* обязательно должны присутствовать ключи 'title' и 'url'.
*/
private function _add($params) {
if (!is_array($params)) return false;
foreach ($params as $param) {
$this->add($param['title'], $param['url']);
}
return true;
}
}
Так же есть компонент элемент для вывода хлебных крошек. Раньше список в нём генерировался с помощью sprintf, теперь же я его переделал так что бы использовались выше описанные функции.
<?php
if (!empty($breadcrumbs) && (count($breadcrumbs) > 1)) {
foreach($breadcrumbs as $key => $breadcrumb) {
$this->Html->addCrumb(
((isset($breadcrumb['icon']) && $breadcrumb['icon'])?sprintf('<i class="%s"></i> ', $breadcrumb['icon']):'').$breadcrumb['title'],
($key == (count($breadcrumbs) - 1))?null:$breadcrumb['url'],
array('escape' => false)
);
}
echo $this->Html->getCrumbList(array(
'lastClass' => 'active',
'class' => 'breadcrumb',
'escape' => false
));
}
Данный элемент может поддерживать иконки, а так же последний элемент списка всегда выводится без ссылки - что бы не создавать на странице ссылку на саму себя.
Для использования компонента и элемента в начале необходимо подключить компонент в AppController.
class AppController extends Controller {
public $components = array(
...
'Breadcrumbs',
...
);
...
}
За тем в коде можем проставить добавление элементов в хлебные крошки.
<?php
App::uses('AppController', 'Controller');
class PagesController extends AppController {
public function beforeFilter() {
parent::beforeFilter();
$this->Breadcrumbs->add(__('Страницы'), Router::url(array('plugin' => false, 'controller' => 'pages', 'action' => 'index')));
}
public function about(){
$this->Breadcrumbs->add(__(‘О нас’), Router::url(array('plugin' => false, 'controller' => 'pages', 'action' => 'about')));
...
}
…
}
И наконец выводим сам элемент. Я это делаю в шаблоне (Layout), но так же это можно делать и в представление (View).
<div class="breadcrumbs">
<?php echo $this->element('breadcrumbs');?>
</div>
На самом деле функции ещё сыроваты, например я обычно иконки для элементов выводил не оборачивая их в ссылки, но с помощью этих функций у меня не получилось так сделать. Как вариант можно попробовать элементам передавать параметры before.
Больше информации можно посмотреть в API - http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#creating-breadcrumb-trails-with-htmlhelper
Желаю всем приятной навигации на Ваших сайтах!
Автор: Сергей Степанов
Поделиться @