JRoute - ссылка на пункт меню по имени представления 23.07.2014


Пишу я тут компонент для Joomla, и в шаблоне потребовалось сделать ссылку на другое представление. SEF включен. Я открываю документацию Joomla по JRoute, и вижу, что всё довольно просто - достаточно вызвать JRoute::_('index.php?view=myview') для формирования ссылки на представление.
Но не тут-то было.
Вставив в шаблон такую конструкцию, я получил ссылку вида http://site.com/menuname/submenuname?view=myview , где menuname - это алиас пункта меню, который ведет на главную странцу компонента, а submenuname - такой же алиас на некоторое представление компонента. Конечно, это не то, что было нужно. Тогда я стал искать в интрнете способ, как получить через JRoute ссылку на представление, но везде у людей всё получалось гладко через обычный вызов фунции подчеркивание у JRoute.
И вот, я наткнулся на информацию о том, что JRoute подставляет в строку-аргумент еще параметры option и Itemid, если их там еще нет. При этом option равен имени компонента, из которого вызывается JRoute, а Itemid - числовой идентификатор текущего пункта меню. То есть можно даже не указывать в ссылке view=myview, а только Itemid - и уже роутинг сработает. Но как получить Itemid меню по имени представления? Ответа на этот вопрос я в интернете не нашел, зато нашел его в коде стандартного компонента Weblinks, который вы можете почитать в файле /components/com_weblinks/helpers/route.php.
Итак, нам понадобится копия этого файла, из которой можно удалить ненужные строки, у меня этот файл выглядит так:

<?php
// защита от прямого доступа
defined('_JEXEC') or die();

// Component Helper
jimport('joomla.application.component.helper');

abstract class MyComponentHelperRoute
{
    protected static $lookup;

     static function _findItem($needle = null)
     {
        $app        = JFactory::getApplication('site');
        $menus        = $app->getMenu('site');

        // Prepare the reverse lookup array.
        if (self::$lookup === null) {
            self::$lookup = array();

            $component    = JComponentHelper::getComponent('com_mycomponent'); // Измените на свой компонент!
            $items        = $menus->getItems('component_id', $component->id);
            foreach ($items as $item)
            {
                if (isset($item->query) && isset($item->query['view'])) {
                    $view = $item->query['view'];

                    if (!isset(self::$lookup[$view])) {
                        self::$lookup[$view] = $item->id;
                    }
                }
            }
        }

        return self::$lookup[$needle];
    }
}

Этот файл я расположил в /components/com_mycomponent/helpers/route.php. Он содержит минимальный функционал, в результате которого возвращается Itemid, а также в массив $lookup заносятся id остальных менюшек, относящихся к нашему компоненту, для того, чтобы в слудующий раз их снова не искать, т.е. это что-то типа кеша.
Далее, чтобы это всё заработало, надо в файле /components/com_mycomponent/mycomponent.php написать

require_once JPATH_COMPONENT.'/helpers/route.php';

где-нибудь вверху, например, после всех jimport.
Всё, теперь в шаблоне достаточно вызвать JRoute::_('index.php?Itemid='.MyComponentHelperRoute::_findItem('myview')) и сразу сформируется ссылка на пункт меню, выводящий представление myview.
На этом всё, спасибо за внимание.



Теги: Joomla, JRoute, PHP, заметки на полях