DbUrlManager extension

Hello, people.

Let me introduce DbUrlManager extension.

DbUrlManager provides dynamic database-based URL rules.

These dynamic rules are like Wordpress’ “pretty permalinks” or “friendly URLs”. You do not have to have the controller name (or ID) on the URL: this extension can handle the request URI and route it to the correct controller.

Examples of clean and friendly URLs made possible by this extension:

http://mystore.com/blue-coffe-mug

http://myblog.com/my-first-post

If you are using it, please let me know about your opinion.

Note that you can set CUrlManager::$strictParsing to true, then it’s not possible to access the controller/action directly (eg: index.php?r=post/view), means one of the defined rules must match, otherwise 404. I saw you have a note about it in the documentation.

Yes, in some cases it can help indeed. But won’t help if you have a rule like


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

I don’t want to ask users of the extension to not make use of this nice feature.

Altough the new action parameters (currently in trunk) can help by requiring at least the parameters to be set.

Is it possible to get "working example" of using this extension?

I find it difficult to implement it.

[size="3"]Here it is[/size]

[list=1]

[*]Setup your application. Below are the minimum configuration, just for the purpose of getting the extension running:




// Configure the db application component to suit your needs.

'db'=>array(

    'connectionString' => 'mysql:host=127.0.0.1;dbname=myblog',

    'emulatePrepare' => true,

    'username' => 'username',

    'password' => 'password',

    'charset' => 'utf8',

    'schemaCachingDuration' => 3600,

),

'urlManager'=>array(

    'class'=>'ext.DbUrlManager.EDbUrlManager',

    'urlFormat'=>'path',

    'connectionID'=>'db',

    'rules'=>array(

        '<post:[\w-]+>'=>array(

            'post/view',

            'type'=>'db',

            'fields'=>array(

                'post'=>array(

                    'table'=>'tbl_post',

                    'field'=>'post_slug'

                ),

            ),

        ),

    ),

),



[*]Prepare the data (mysql example):

[sql]

create database myblog;

use myblog;

create table tbl_post (post_slug varchar(100));

insert into post values (‘first-post’),(‘another-post’);

[/sql]

[*]Have a controller (the route is post/view, then we will need a PostController) and an action (actionView):




// If you have trouble, try extending from Controller instead.

class PostController extends CController

{

    public function actionView()

    {

        $this->render('view', array(

            'post' => isset($_GET['post'])?$_GET['post']:'',

        ));

    }

}



[*]And a view




<h1>Post View Test</h1>

<br />

<?php

    if (isset ($post)) echo "post: $post";

?>



[/list]

If you still have trouble, reset your cache.

thank you for your help :)

You’re welcome. Is it working ok? Which RDBMS are you using?

Well… I am still fighting with it :)

I am using MySql.

What’s wrong?

Thanks for the extension. I was able to get it to work well using 2 tables in the rules section, and with sqlite.

Don’t forget to modify the controller, that got me a couple times :). And, don’t forget your .htaccess if showScriptName is false.

Dear,

I expect to cover at least some of the TODOs soon. The extension will have better performance with the caching implemented. The new features in Yii 1.1.7 will ease a lot this task.

Thank you,

Rodrigo Coelho - mentel

Hi Rodrigo, thanks very much for this extension :)

I have one question though. If you are using two fields to form the URL, e.g. author/post, am I correct in assuming that both fields are treated independently when processed by this extension. For example:

  • An author ‘John’ has a post called ‘hello-world’

  • An author ‘Sue’ has a post called ‘goodbye-cruel-world’

It seems from my testing that the following are all valid URLs and would return a post:

  • /john/hello-world

  • /john/goodbye-cruel-world

  • /sue/hello-world

  • /sue/goodbye-cruel-world

Yet, we would only want posts returned that reflected the relationship between the author and their individual posts, i.e.

  • /john/hello-world [OK]

  • /john/goodbye-cruel-world [404]

  • /sue/hello-world [OK]

  • /sue/goodbye-cruel-world [404]

Am I correct in assuming that your controller method must return the appropriate matching records based on multiple fields?

Tx, Rob

Hi Rob,

The extension was not made with relationships in mind. But this is indeed a very nice suggestion.

I’ll add it to the TODO list.

And you probably meant:

  • /sue/hello-world [404]

  • /sue/goodbye-cruel-world [OK]

Thanks!

Ooops, yes - thanks for pointing that out and clarifying my question!

Thanks, this extension is what I’ve been looking for.

Now I can configure dynamic routes.

One question:

Any idea how to integrate this with langhandler extension?

Or how to write your own language handler code for this extension?

I’ve been trying to integrate these two things but the result isn’t functioning properly yet.

Best regards

Roman Solomatin

Hi Rodrigo,

I want to show Country-name in url like websit.com/country-name. There are around 196 nations in world. Could you suggest any solution for this using the extension?