How can I clean this url up?

I’m working on a CMS and I’m trying to figure out routing with Yii. This is the url I’m working with:


pages/default/index/pid/24/edit/1

Obviously, the module is ‘pages’, ‘default’ is the controller, ‘index’ is the action, and the rest are parameters. How can I condense this to: pages/24/1 ? Also, to make things more interesting, the above url is generated by this redirect expression:


$this->redirect(array('/pages/default/index','pid'=>$model->id, 'edit' => true));

How would I get yii internals, like redirect, to recognize my cleaned up urls? It’s also really important to me to be able to do this from within each module and not have to hard code every single module’s custom route into main.php or a supporting config file.

I’m used to working with Zend but I’m trying to figure out the Yii way of doing things!

Thanks!

You need to look into Url Manager settings:

http://www.yiiframework.com/doc/guide/1.1/en/topics.url

I read the docs on the url manager but still don’t know what to do. I can add a pattern to main.php but after that I’m lost

As a quick setup, try this. First add the following to protected/config/main.php:




'urlManager' => array(

    'urlFormat' => 'path',

    'showScriptName' => FALSE,

    'rules' => array(

        array('class' => 'pages.components.PagesUrlRule'), // <-- add this line above the default routes

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

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

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

    ),

),



Then, create modules/pages/components/PagesUrlRule.php and add the following code:




<?php


class PagesUrlRule extends CBaseUrlRule

{


    public function createUrl($manager, $route, $params, $ampersand)

    {

        if ($route == 'pages/default/index')

        {

            if (isset($params['pid']) && isset($params['edit']))

                return 'pages/' . $params['pid'] . '/' . $params['edit'];

            else

                return FALSE;

        }

        // use else if to check other module routes

    }


    public function parseUrl($manager, $request, $pathInfo, $rawPathInfo)

    {

        // Matches a route like 'pages/24/1'

        if (preg_match('~pages/(\d+)/(0|1)~i', $pathInfo, $matches))

        {

            $_GET['pid'] = $matches[1];

            $_GET['edit'] = $matches[2];

            return 'pages/default/index';

        }

        // use else if to check other module routes

        else

            return FALSE;

    }


}



When the application is parsing the routes, it will call the parseUrl() method and check any routes you may have defined there. This means you include multiple routes that are specific to your module, while only adding one entry to your config file. Creating a url is exactly the same as you did before, but the createUrl() method in your url rule class is used to create the simplified url.

(edited to include missing return false statement in parseUrl() )