Подскажите, Как Реализовать Категории И Подкатегории

Изучаю yii фреймворк.

Не могу разобраться с подкатегориями, вернее не соображу как реализовать это логически. К примеру. Есть в сайдбаре список категорий.

category1

category2

etc…

у каждой категории есть подкатегории.

category1

subcategory

category2

subcategory2

итд.

и родительские и дочерние каты имеют свои посты.

как реализовать это в урлах.

то есть я перешел по url category.post1

все хорошо.

но вот мне надо перейти в category.subcategory.post1

то есть нужно что бы в урлах было видно, что одно вкладывается в другое. Что сделать? Создавать еще один контроллер\действие? а если уровень вложенности будет глубже? В какую сторону копать?

На данный момент у меня вложенные списки категорий формируются таким видом




<h3>Список категорий<.h3>

<?php 

$level=0;

foreach($categories as $n=>$category)

{

    if($category->level==$level)

        echo CHtml::closeTag('li')."\n";

    else if($category->level>$level)

        echo CHtml::openTag('ul')."\n";

    else

    {

        echo CHtml::closeTag('li')."\n";


        for($i=$level-$category->level;$i;$i--)

        {

            echo CHtml::closeTag('ul')."\n";

            echo CHtml::closeTag('li')."\n";

        }

    }


    echo CHtml::openTag('li');

   

    echo CHtml::link($category->title, Yii::app()->createUrl('post.category', array('id'=>$category->title)));

    $level=$category->level;

}


for($i=$level;$i;$i--)

{

    echo CHtml::closeTag('li')."\n";

    echo CHtml::closeTag('ul')."\n";

}

?>



Данные идут из nested set behavior.

вложенность видно только в сайдбаре визуально…

Как вообще на сайтах реализуют вложенные категории? Роутингом? В какую сторону вообще смотреть, для меня загадка.

и еще. фиг бы с ними, с этими вложенными категориями,НО

вот я перехожу по yiitest.post.category.mycategory.

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

но за вывод постов у меня отвечает yiitest.post.view.id.4 то есть экшн view.

Вопрос, как сделать что бы при нахождении в категории http:…yiitest.post.category.mycategory.

кликая по посту видел такую ссылку http:…yiitest.post.category.cat.postname

надеюсь все правильно сформулировал…подскажите пожалуйста.

На данный момент пытаюсь отловить ссылку вида yiitest.post.category.cat.postname и перенаправить в yiitest.post.view.id.4

вот код роутера




'urlManager'=>array(

			'urlFormat'=>'path',

			'showScriptName'=>FALSE,

			'rules'=>array(

			'post.category.<id:\d+>'=>'post.category',

			'post.category.<alias>'=>'post.category.id.<alias>',

			'index'=>'post.index',

			'<controller>.<action>.<id>.<alias>'=>'post.view.<id>.<alias>',

			)

		),



оперирую в частности вот этой строчкой

‘<controller>.<action>.<id>.<alias>’=>‘post.view.<id>.<alias>’,(точки это слэши, по другому не могу создать этот пост)

надеюсь, что кто нибудь поймет, что я хочу сделать…

Ну тут есть несколько вариантов.

  1. Из моего опыта самый удобный:

таблицы:

  • cat_id parent_id url

  • product_id

  • product_id category_id

URL вида /my-category-123 будет выводить список категорий (ну и собственно тоже самое для вложений)

/my-product-123 будет выводить например информацию о продукте например.

В чем + данного решения - это независимость от количества вложений что избавит от огромных головных болей.

  1. Сделать это жестко. Тоесть таблицы с категорией, подкатегорией, продуктом. Минус этого метода в ограниченном количестве вложений и статической структуре.

'<category:[a-z0-9\-_\.]+>/<subcategory:[a-z0-9\-_\.]+>/<product:[a-z0-9\-_\.]+>' => 'product/view',

Полезное правило для реализации ссылки /category/subcategory/product

Надеюсь идея вам поможет.

Я тоже искал как-то и ничего не нашел по этой теме, поэтому делал так:

Хранил alias и полный url и расширял urlManager. По скорости - быстро, не нужно получать всех предков, чтобы составить URL. Такой подход используют многие CMS, но есть большой минус: если меняется алиас родителя - надо менять url у всех предков. Ну и не забывать про возможность перемещения раздела по дереву, тут тоже придется повозиться.

Хотелось бы услышать другие варианты реализации вложенностей разделов. :rolleyes:

Ну я собственно делал так как описал в 1м способе. Берем категорию, смотрим parent_id и ищем категорию родителя и т.п. Единственный наверное минус этого метода это “большой” поиск по категориям при формировании url если много вложений. Но у Вас ведь не будет миллионов категорий :) . То что действительно радует это то что для движения по дереву меняется только parent_id. Да и к алиасам мы непривязаны никак, что лишает нас дополнительных головных болей. Да и табличка отношений product-category необязательна впринципе, просто я не люблю many_many и как то с ними не умею работать поэтому стараюсь обходить табличками отношений.

В изложенном вами способе не совсем правильная с точки зрения иерархичности стурктура.

Я считаю что правильней будет так /catalog/category/{еще категории если есть}/product.html

Делаю так же плюс правило роута у меня выглядит примерно так:


'c_<id:\d+>_<uri>.html' => 'category/view'

ссылка генерируется так:


createUrl('category/view', array('id'=>1, 'uri'=>'cat1-cat2-cat3'));

В итоге получим c_1_cat1-cat2-cat3.html

строку "cat1-cat2-cat3" получаем в рекурсивно обращаясь к родителям пока они есть.

В дополнения к придыдущему посту. для генерации ссылки в модели лучше всего добавить метод getUrl() примерно такого содержания:




public function getUrl($params=array()) {

$route=strtolower(get_class($this)).'/view';

if(empty($params['uri'])

$params['uri']=$this->getUri();//если вам надо сложная логика генерации

return $urlManager->createUrl($route, CMap::mergeArray(array('id'=>$this->primaryKey), $params));

}



если ничего сверхестественного не надо, то строку




$params['uri']=$this->getUri();



можно заменить на




$params['uri']=$this->name;



для вывода ссылки вам надо будет написать


<?php echo $model->url;?>

Всем спасибо, прочитал статью DCategoryBehavior: Работа с категориями и списками в Yii, Елисеева, Если кому понадобиться, гуглите, ссылку не стал давать, что бы не сочли за рекламу. Отличное решение, для моих целей очень подошло.

Подскажите, пожалуйста, литературу поглобальнее - у Елисеева уже конкретика идет.

Честно говоря, сам такой, поискать, но по этим вещам мало чего есть. Попробуйте "Лаура Томсон,Люк Веллинг: Разработка Web-приложений на РНР и MySQL", что то оттуда можно почерпнуть. А так - как вариант читать исходники cms-ок, фреймворков, спрашивать.

Спасибо, идея с рекурсией очень помогла.