Задача следующая:
Когда создаем свой модуль с динамическими страницами под ЧПУ можно (точнее необходимо) регистрировать пути, например:
Code: Select all
// в рамках модуля:
$params = array(
'action' => 'default',
'returnid' => $return_id
);
$this->RegisterRoute('%my_module/t_(?P<type>[0-9]+)/p_(?P<page>[0-9]+)$%', $params);
(Фактически вызывается {cms_module module='my_module' type='...' page='...'}).
Это, конечно, хорошо, но появляется необходимость использовать данные параметры в другом месте. Например, делаем свой каталог. В нем 2 метода (action) - default (отрисовывает список элементов каталога в зависимости от категории (type)) и menu, который выводит список категорий со сформированными соответствующим образом ссылками (например, /my_module/t_1/ ...), причем метод menu должен знать, какая категория текущая, чтобы выделить ее.
Есть следующие способы реализации данной задачи:
1. метод menu вызывать из шаблона, который обрабатывается методом default. Тоесть вначале текущий type добавить в smarty (например, $smarty->assign('curType', $params['type'])), а в шаблоне, где выводится список элементов, в месте, предназначенном для меню вызываем {cms_module module='my_module' action='menu' type=$curType}.
Недостатком данного метода является то, что если по дизайну предусмотрено физическое разделение самого списка элементов и меню (например, меню каталога выводится сверху, далее идет какой-нть блок, затем справа меню основное и только потом нужно содержание каталога), то нужно будет создавать новый шаблон, в который помещать часть основного дизайна.
2. Если метод default вызывается до вызова menu, то в принципе переменная smarty, если ее не очищать принудительно, будет доступна далее по шаблону (тоесть назначаем как в предыдущем варианте). В случае динамической страницы - это значит, что {content} будет стоять выше по тексту шаблона, чем {cms_module module='my_module' action='menu' type=$curType}. В принципе - уже лучше, но опять-же нужно, чтобы блок меню располагался ниже по коду (теоретически, с помощью css можно выстраивать блоки как угодно, и проблема будет решена).
3. Вариант - развитие предыдущего. Можно вызывать метод контента в начале, перехватывать его, а затем выводить в нужном месте. Используем метод {capture name='myContent'}{content}{/capture} перед вызовом меню, а в нужном месте (там, где должен находится контент) выводим {$smarty.capture.myContent} при этом переменные модуля будут доступны ниже по коду.
Это были варианты, связанные с особенностями использования smarty. В принципе - они могут подойти, и для другого, например, в последнем случае можно перехватывать часть контента (заголовок новости, например), и выводить его в тайтл страницы...
Но встал вопрос - а вообще - как получить динамические переменные и использовать там, где нужно, еще во время работы метода, чтобы не пробрасывать переменную через шаблон? Есть вариант - сохранять ее в экземпляре класса модуля, но тогда остается зависимость от порядка вызова методов в шаблоне.
Вобщем, покопался в коде, посмотрел значения переменных во время работы и нашел следующий способ (вобщем-то тот способ, про который хотел узнать - есть ли более простой вызов).
Code: Select all
// адрес текущей страницу, в том виде, в котором она нужна нашел только здесь ($this->smarty - это ссылка на на экземпляр smarty, который я получаю выше):
$page = rtrim($this->smarty->params['page'], '/');
// примерно так cms разбирает адреса, при этом создается объект со всеми переменными или ничего не возвращается (если правильно понял, то null)
$route = cms_route_manager::find_match($page);
// вытаскиваем то, что нужно
if ($route) {
$prms = $route->get_results();
if (isset($prms['type'])) {
$curType = $prms['type'];
}
}
Как обойтись без вытаскивания текущего адреса из smarty - не нашел. (точнее - было еще много переменных и в смарти и в основном объекте cms, но проще всего, как я думаю, было получить так).