[Solved] using CHtml::link() to generate routed url

I have a pretty basic question to which I failed to find a solution. Here goes:

In my view file there is:

CHtml::link('<em>Download</em>', array('/project/download/', 'id' => $data->project->id, 'category' => $data->category, 'filename' => $data->filename));

// Generates: http://localhost/myapp/project/123?category=foo&filename=bar

Now, in my config urlManager rules, I have:

'<controller:\w+>/<action:\w+>/<id:\d+>/<category:\w+>/<filename:\w+>' => '<controller>/<action>',

// Properly routes links like: http://localhost/myapp/project/download/123/foo/bar

My question is, how do I make CHtml::link generate the link according to the rule above?

It seems as if you will need to specify the urlFormat property of the UrlManager to be ‘path’:




As well as potentially make a few more changes to hide the entry script. See:


But specifying the rules in the UrlManager will apply to both the routing of requests as well as the construction of the url by the CHtml helper method.

This was the bit of information I was looking for. I already had urlFormat=‘path’, but the problem was that only a part of the path was converted. Moving my custom rule to the front of the array solved the problem. This shows that the rules are parsed in order they are assigned in, and the rules parser will stop at the first match. Conclusion: order your rules from most specific to least specific.

Here is my config part btw:

        'urlManager' => array(

            'urlFormat' => 'path',

            'showScriptName' => false,

            'rules' => array(

                '<controller:\w+>/<action:\w+>/<id:\d+>/<category:\w+>/<filename:\w+>' => '<controller>/<action>', //most specific

                '<controller:\w+>/<id:\d+>' => '<controller>/view',

                '<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',

                '<controller:\w+>/<action:\w+>' => '<controller>/<action>', //least specific