Search code examples
php.htaccessyiiyii-componentsyii-url-manager

seo friendly urls in YII framework with id and name


I've been searching all around Stackoverflow and YII forums, there are many answers, which didn't help me...

This is my case.

I have controller called: proj and an action called view. It gets: id(int), name(string).

The desired name gets sometimes with special chars such as: [+,!#$%^&*-]

So when I'm running createUrl() function it returns me not so friendly url.

For example: http://www.qa-mysite.com/proj/1029/Conservation+of+the+Vermont+Salt+Pan+System%2C+Hermanus%2C+South+Africa.

id = 1029 name = Conservation of the Vermont SaltPan System, Hermanus, South Africa.

I want the result to be: http://www.qa-mysite.com/proj/1029/conservation-of-the-vermont-salt-pan-system-hermanus-south-Africa

So actually i need to strip the special chars and change the delimiter between spaces to "-" instead of "+".

My current configurations of the curlManager are:

'urlManager'=>array(
            'urlFormat'=>'path',
            'showScriptName'=>false,
            'appendParams' => true,
            'rules'=>array(
            //array('proj/view/<name:\w+>', 'pattern'=>'proj/<id:\d+>'),
                //'<controller:\w+>/<id:\d+>'=>'<controller>/view',
                'proj/<id:\d+>/<name:\w+>'=>array('proj/view', 'caseSensitive'=>false),
                '<controller>/<id:\d+>/<name:.*?>'=>'<controller>/view',
                '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
                '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
            ),
        )

CreateUrl example:

$this->createUrl('proj/view', array('id' => $data->id, 'name' => $data->name));

After the urls will be changed I need to do 301 redirects of the old ones to the new-seo-friendly urls.

Note: I cannot do hardcoded str_replace.

Many thanks for any help :]


Solution

  • Create your own url manager by subclassing CUrlManager and ovveride createUrl a bit, in example:

    class MyUrlManager extends CUrlManager {
        public function createUrl($route,$params=array(),$ampersand='&') {
            if($route == 'proj/view' && isset($params['name'])) {
                $params['name'] = processYourParamFunction($params['name']);
            }
            return parent::createUrl($route,$params,$ampersand);
        }
    }
    

    Then modify your config to use this class:

    ...
    'urlManager' => [
        'class' => 'MyUrlManager'
    ...
    ]
    

    It is one of great Yii features, natural inversion of control:)

    For second part of question:

    In you view action simply redirect to new url with createurl if you detect unwanted characters . Just make sure you not hit redirect loop.

    Update:

    To redirect with 301 just pass redirect code a third param to redirect call:

    $this->redirect('route', true, 301);
    

    Side note:

    Use cannonical to point search engines to proper url