Хлебные крошки

 

Всем доброго времени суток. Сегодня мы немного отступимся от реализации роутинга в CMS RS-MINI, и реализуем очень полезную, и важную вещь — хлебные крошки. Под хлебными крошками, на данном этапе разработки, я имею ввиду не выведенные подряд ссылки на странице сайта, а лишь данные которые нам понадобятся для реализации этих самых ссылок в будущем.

При сборке и запуске контроллеров у нас имеется прямой доступ к данным страниц, по которым строятся хлебные крошки, поэтому реализовать их сейчас самое то.

Откуда брать данные?

Если вы помните, первый цикл, в методе controllerRun() класса application.class.php, перебирает все найденные страницы, то бишь объекты класса page.class.php. В объектах этого класса имеется свойство pageAlias содержащие псевдоним и свойство pageName содержащие название страницы. Это именно то что нам нужно.

Но тут есть один маленький нюанс. У наших основных контроллеров имеется метод getCaption() который позволяет переназначить имя страницы, и нам необходимо будет учитывать то, что название страницы которое храниться в базе данных, может не совпадать с реальным названием.

Где хранить данные о хлебных крошках?

Для этих целей у нас есть очень хороший класс-прослойка между контроллером и представлением. Название этому классу dom.class.php. Именно там мы создадим узел (breadcrumbs) хлебных крошек и наполним этот узел данными (узлами page с атрибутами caption (заголовок) и path (путь)).

Правим метод controllerRun()

Вот новый код метода (файл application.class.php в папке /rs-mini/core/)

    /*
     * метод стартует контроллеры
     *
     * @access - private
     *
     */

    private static function controllerRun()
    {
        // создаем узел хлебных крошек
        $breadCrumbs = self::$dom->addNode('breadcrumbs');
        // массив с псевдонимами страниц для формирования пути
        $path        = array();
        
        // массив с контроллерами которые необходимо будет запустить
        $runList     = array();

        // листаем страницы
        foreach (self::$map->pageList as $key => $page) {

            // список блоков контроллеров
            $blockList = array(
                'top',
                'center',
                'bottom'
            );
            
            // создаем узел в хлебных крошках
            $pageNode = $breadCrumbs->addNode('page');
            // созраняем название страницы
            $caption  = $page->pageName;
            // сохраняем псевдоним в массиве пути
            $path[]   = $page->pageAlias;

            // если на странице контроллеры
            if ($page->controllerList) {
                // листаем все возможные блоки
                foreach ($blockList as $blockAlias) {
                    // листаем контроллеры страницы
                    foreach ($page->controllerList as $block => $controllerList) {
                        // если листаемый блок совпадает с блоком контроллеров страницы - то разбираем контроллеры данного блока
                        if ($blockAlias == $block) {
                            // сначало проглядываем наследуемые контроллеры (потом подключенные на прямую)
                            for ($inh = 0; $inh <= 1; $inh++) {
                                // листаем контроллеры
                                foreach ($controllerList as $controller) {

                                    // проверка наследия (первая итерация ищет только наследованные контроллры)
                                    // при $inh == 0 запускаются только унаследованные контроллеры
                                    // при $inh == 1 запускаются подключенные на прямую
                                    if ($controller->inheritFlag != ( ($inh == 0) ? TRUE : FALSE ))
                                        continue;

                                    // пропускаем отключенные контроллеры
                                    if ($controller->getParam('active') == 'disable')
                                        continue;

                                    // подставляем в путь допол. папку
                                    // бьем имя контроллера на массив
                                    $controllerClass                                  = explode('.', $controller->controllerName);
                                    // отрезаем два первых элемента массива
                                    $controllerSlice                                  = array_slice($controllerClass, 2);
                                    // во второй элемент массива вставляем слово controller
                                    $controllerClass[2]                               = 'controller';
                                    // вертаем в массив оставшие элементы после отработки функции array_slice
                                    for ($i = 0; isset($controllerSlice[$i]); $i++)
                                        $controllerClass[($i + 3)]                    = $controllerSlice[$i];

                                    // тем самым получаем полный путь к классу
                                    // пример: было pub.test.intro а стало pub\test\controller\intro
                                    $controllerClass                                  = implode('\\', $controllerClass);

                                    // записываем в параметры инфу о странице
                                    $controller
                                        ->setParam('page_id',     $page->pageID)
                                        ->setParam('page_alias',  $page->pageAlias)
                                        ->setParam('page_parent', $page->pageParent)
                                    ;

                                    // создаем объект контроллера
                                    $obj = new $controllerClass(self::$dom, $controller->getParams());
                                    
                                    // регистрируем динамичный алиас и его значение в
                                    // статичном свойстве абстрактного класса контроллера
                                    // если реальный алиас страницы row_id а в адресную строку было вбито
                                    // /123/ то в свойстве dynamicValue абстракного класса abstractcontroller
                                    // будет зарегистрирован ключ row_id с значением 123
                                    // dynamicValue['row_id'] = '123'
                                    if ($page->pageType == 'dynamic')
                                        $obj->setDynamicValue($page->pageDynamicAlias, $page->pageAlias);

                                    // проверяем на валидацию
                                    if (!$obj->validate())
                                        self::notFound();

                                    // получаем заголовок
                                    $caption = $obj->getCaption($caption);

                                    // если листается последняя страница
                                    if ($key == (count(self::$map->pageList) - 1))
                                        // сохраняем данные для запуска (запуск ниже)
                                        $runList[] = array(
                                            'obj'           => $obj,
                                            'controller'    => $controller
                                        );

                                }
                            }
                        }
                    }
                }
            }
            
            // атрибуты хлебных крошек
            $pageNode->addAttr('caption',  $caption);
            $pageNode->addAttr('path',     (count($path) > 1) ? implode('/', $path) . '/' : '/');
        }
        
        // тест хлебных крошек
        ?><xmp><?
        var_dump(self::$dom->getDom());
        ?></xmp><?
    }

Давайте я немного прокомментирую добавленные строчки.

// создаем узел хлебных крошек
$breadCrumbs = self::$dom->addNode('breadcrumbs');
// массив с псевдонимами страниц для формирования пути
$path        = array();

Начал я с создания узла крошек и массива для хранения псевдонимов страниц.

// создаем узел в хлебных крошках
$pageNode = $breadCrumbs->addNode('page');
// созраняем название страницы
$caption  = $page->pageName;
// сохраняем псевдоним в массиве пути
$path[]   = $page->pageAlias;

Далее, для каждой страницы из массива self::$map->pageList, создается узел page, сохраняется псевдоним страницы в массиве path, и запоминается имя страницы. Я специально сохранил имя в отдельную переменную, так как чуть ниже будет попытка перезаписать значение этой переменной.

// получаем заголовок
$caption = $obj->getCaption($caption);

Теперь сразу после проверки на валидацию я запускаю метод getCaption() у основного объекта контроллера. Если помните этот метод по умолчанию возвращает то, что было прислано в его параметры. У нас как у разработчиков будет возможность через этот метод поменять имя страницы, на любое какое нам захочется.

// атрибуты хлебных крошек
$pageNode->addAttr('caption',  $caption);
$pageNode->addAttr('path',     (count($path) > 1) ? implode('/', $path) . '/' : '/');

Ну и последнее, что нам понадобится сделать, это создать два атрибута. Первый это имя страницы, а второй путь до страницы. Путь как видите это склеенный с помощью слэша массив с псевдонимами.

Заключение

В конце метода есть код для проверки вставленных нами узлов. Если сейчас перейти вот на такую страницу http://mini.test.ru/about/ то мы должны увидеть вот такой массив:

массив с хлебными крошками

Как видите, у нас теперь в доме есть узел с хлебными крошками. Останется его лишь разобрать в шаблон, но это мы будем делать потом, а не сейчас Улыбаюсь

Если у Вас есть какие либо вопросы, то задавайте их в комментариях. Архив с движком на данном этапе разработки, можно скачать в конце статьи.

Всего Вам наилучшего, на сегодня у меня все!

Прикрепленные файлы

 

Возможно Вам будут интересны следующие заметки

Комментарии (2)

Ваше имя *
Сайт
Ваш E-mail *
Ваше сообщение *
 
Вы не подтвердили условия политики конфиденциальности.
Александр, 09 Сентября 2015 г. 17:15 пишет:
Читатель
Смотрю активнее начали писать, даже появилось желание прочитать всё. Ждемс следующую статью_)
Евгений, 11 Декабря 2019 г. 13:45 пишет:
Гость
Спасибо за описания