Украшение урлов

Собственно очень нравится система роутинга в YII но несовсем понятно как сделать такое правило:

category/subcategory/…/<title>

Тобиш как в DLE (для проекта надо)

Возможно ли это?

Запросто, только надо сделать как-то так, чтобы category/subcategory можно было отличить от controller/action. У меня сделано так: /categories/[categoryName]/[subcategoryName]/[title], но вот произвольную вложенность ты не сделаешь с помощью этого механизма. Это как mod_rewrite. Альтернатива (если не хочется вперед добавлять categories) состоит в том, чтобы перечислить все правила:

/user/profile/<id:\d+> => user/profile,

/user/profile => user/myProfile,

/<category:\w+>/<subCategory:\w+>/<title:\w+> => post/view

Для произвольной вложенности надо самому парсить эту штуку. Если нужна произвольная - пиши, будем думать :)

Ну вообще хотелось бы произвольную вложенность, ибо так удобнее ориентироваться… впринцыпе можно обойтись вложенность в 2-3 подкатегории, но… Неизвесно какая структура может прийти в голову заказчику) Пока минимум 2 вложения

С произвольной сложнее. Тут два варианта - либо описать все возможные уровни в виде набора правил, либо написать правила:

/<categoryName:\w+>/t_<topic:\w+> => post/view,

/<categoryName:\w+>/<path:.+>/t_<topic:\w+> => post/view

Не уверен, что это будет работать. Тут суть такая, что у нас сначала идет имя категории, а затем (в первом правиле) имя топика, по которому ты его в базе найдешь. Во втором - идет весь путь, например: subcat1/subsubcat3/subsubsubcat5. Все равно он при выводе поста роли не играет, но парсить это дело надо самостоятельно потом.

Теперь для генерации урла, надо делать так:

$controller->createUrl(‘post/view’, array(‘categoryName’ => ‘cat1’, ‘topic’ => ‘topic1’, ‘path’ => ‘subcat1/subsubcat3’));

Если ты укажешь параметр path, то будет сгенерирован урл по второму правилу, если нет - то по первому.

/<path:.+>/<categoryName:w+>/t_<topic:w+>' => 'site/herhia

Спасибо)) вот это правило оказалось универсальным и ничего парсить ненадо)

p.s. Конкретно это правило универсально, а построенные на его основе… ну да несуть)

извиняюсь что понимаю тему, у самого вопрос с реализацией многоуровневым каталогом, нужно сделать что то вроде этого

cat1/cat2/cat3/catN

если я эту цепочку присваиваю параметру path так

‘path’ => ‘cat1/cat2/cat3/catN’

то urlManager знак слэша заменяет на символы %2F, получается что ссылка у меня такая

cat1%2Fcat2%2Fcat3%2FcatN

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

даётся мне что придётся разбивать каждый подраздел на несколько параметров так

cat=1&cat=2&cat=3&cat=N

потом PHP разбирать только параметры cat и выбирать последний, для вычисления id индификатора

Сделай в контроллере метод для создание ссылки…свой метод.

хм, чем должен заниматься этот метод? можно пример?

по сути создать свою ссылку не используя urlManager не проблема, другое дело сможет ли он разобрать эту ссылку?

у меня модульная система, в качестве модуля у меня новости имеющий имя News, ссылки на разделы могут быть такими news/cat1/cat2/cat3

конечный раздел должен обращаться к методу List модуля News

написал функцию в которой должна формироваться ссылка. Вот её код, правда немного изменил чтобы понятно было


$param = array();  			


$url_arr = explode('/', 'name1/name2/name3');

			

			if( is_array($url_arr) ) 

			{

				 $i = 0;

				 foreach($url_arr as $v)

				 {

					$i++;

					if( $i == 1 ) {

					   $param['cat'] = $v;

					}else{

					   $param['cat'.$i] = $v;

					}

				 }

			}	


Yii::app()->urlManager->createUrl('news/list', $param );




по сути получается такое


Yii::app()->urlManager->createUrl('news/list', array('cat'=>'name1','cat2'=>'name2','cat3'=>'name3') );

какое правило указать в rules чтобы ссылка формировалась так

news/list/name1/name2/name3

а не как сейчас

news/list/cat1/name1/cat2/name2/cat3/name3

указываю такое правило


'news/list/*'=>'news/news/list',

поэкспериментировал разными способами о которых знал, получилось составить правило только так




'news/list/<cat:\w+>/<cat2:\w+>/<cat3:\w+>/<cat4:\w+>/<cat5:\w+>/*'=>'news/news/list',	

'news/list/<cat:\w+>/<cat2:\w+>/<cat3:\w+>/<cat4:\w+>/*'=>'news/news/list',

'news/list/<cat:\w+>/<cat2:\w+>/<cat3:\w+>/*'=>'news/news/list',				 

'news/list/<cat:\w+>/<cat2:\w+>/*'=>'news/news/list',

'news/list/<cat:\w+>/*'=>'news/news/list',



тут возможны ссылки от одного уровня до пяти, нет ли более простого варианта?

Можно переопределить CController::run()

а зачем переопределять?

я решил эту задачу таким образом


'news/<cat:.+>/<page:\d+>/<sort>/*'=>'news/news/list',					 	

'news/<cat:.+>/<page:\d+>/*'=>'news/news/list',						 

'news/<cat:.+>/<sort>/*'=>'news/news/list',

'news/<cat:.+>/*'=>'news/news/list', 

где директория news у меня является модулем

при этом правиле, можно указывать номер постраничника, номер сортировки, и возможно любые другие параметры

А если требуется неограниченная вложенность, будет работать?


'news/<cat:.+>/*'=>'news/news/list', 

Разбор так работает, но как делать ссылки по этому правилу?

Как передать массив элементов пути?

Так не работает:


if( $i == 1 ) {

   $param['cat'] = $v;

}else{

   $param['cat'.$i] = $v;

}

первый элемент нормално добавляется, а остальные виде cat2/категория/cat3/ещёоднакатегория