Creating urls with deep paths

Hi, I have a table with categories in a nested tree with a structure like this:







-Sports Cars






Each category has many articles associated with it. I want to use URL rules so that I can create urls like


(I’m already converting the category and article names to their URL friendly equivelents, e.g. “Sports Cars” becomes “sports-cars”)

The problem is the current URL rule system doesn’t seem to support this kind of behaviour, I don’t want to create a new URL rule for each category as it’ll hog resources and be a nightmare to maintain - I’m dealing with hundreds of categories and sub categories.

Does anyone have any ideas on how best to approach this? Am I missing something obvious?

Many thanks

I think you need to post your rewrite rules and controller configuration to really get some solid answers.

It’s definitely do-able with one or two generic URL management rules.

Unfortunately I’m not at that stage yet, I’m planning out how it’s going to work and this seems to be a stumbling block. I’ll try to describe in more detail how it should work:

Say I have 2 models, one called "Category" and one called "Article".

The "Category" model has these attributes:


Category.parentId // Either null or the id of another category

and the following relations:

Category.children // has many -> Category

Category.parent // belongs to -> Category

Category.articles // has many -> Article

So the Category can either be a root node (it has no parent) or it can be a child of one of the other categories. (I’m aware a nested set is more efficient than this system, but I’m using this example for simplicity’s sake).

The "Article" model has these attributes:



As well as the relation:

Article.category // belongs to category

So the problem is, how do you efficiently link to a nested category or article?

Something like this sucks:

$this->createUrl("/article/show",array("category1" => $article->category->parent->parent->stub,"category2" =>  $article->category->parent->stub, "category3" =>  $article->category->stub,"stub" => $article->stub));

If instead we had a function on the Category model that returned that category’s path, like this:

class Category extends CActiveRecord


    public function getUrlPath()


        if (is_object($this->parent))


            $path = $this->parent->getUrlPath()."/".$this->stub;




            $path = $this->stub;


        return $path;




This would be much nicer:

$this->createUrl("/article/show",array("categoryPath" => $article->category->getUrlPath(),"stub" => $article->stub));

In my controller I should be able to find the appropriate article and category by accessing $_GET[‘categoryPath’] and $_GET[‘stub’].

The problem is that URL manager doesn’t seem to handle this kind of behavior, instead it splits the category path into seperate $_GET variables. I believe this is happening because of the slashes in the URLs, if getUrlPath() returned category stubs seperated by “.” instead of “/” this would work, but URLs like this aren’t really what I was after:


is not quite as good as


You can override CController::run method in ArticleController to handle this specific URL and than call needed action method.

Thanks, but how should the corresponding url rules be constructed? It seems if i have an url rule that matches anything then i’ll need to create URL rules for every other route before it, which becomes a bit of a pain.

I use default URL rules. For example, will work with default rules.