Remove Controllers names from routing

Hello everyone,

I have a question about routing of Yii2.

I have for example 3 main controllers:

  1. PagesController

  2. BlogController

  3. ProductController

And inside each one I have an action which is getting details from database by sending "slug" as a param.

So my rules are like so now:

pages/main/test

blog/posts/test2

product/list/test3

So 3 different controllers and actions.

What I want to do is to redirect all that to main domain.

/test , /test2, /test3 and so each one will work.

I am trying this in URLManager.


 'urlManager' => [

            'enablePrettyUrl' => true,

            'showScriptName' => false,

            'rules' => [


                '<slug:[\w\-]+>' => 'pages/main',

                '<slug:[\w\-]+>' => 'blog/posts',

                '<slug:[\w\-]+>' => 'product/list',


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

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

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

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

                ],

After doing this on config/main.php only last term is working = ‘<slug:[\w\-]+>’ => ‘product/list’,

Can anyone help me with this please?

I am sure lot of other developers have this question as well.

Thanks in advance

It is not possible with ‘<slug:[\w\-]+>’ => … because everything will go this way. If there are only selected actions you want to make it this way you can do




'test' => 'pages/main/test',

'test2' => 'blog/posts/test2',

'test3' => 'product/list/test3'



To make it dynamic you can extend http://www.yiiframework.com/doc-2.0/yii-web-urlrule.html and create your own rule where the name of the slug will be checked and redirected to proper controller.

The property ‘rules’ is an associative array (an array of key-value pairs) in which the key is an url pattern and the value is the corresponding route.

In the above, you are trying to add 3 elements to the array, but only the last one is actually added, because all the 3 elements share the same key ‘<slug:[\w\-]+>’. It’s just like you are writing:




$array = [

    'a' => 'ABC',

    'a' => 'DEF',

    'a' => 'XYZ',

];

print_r($array);

// prints only 'a' => 'XYZ'



You have to define 3 different url patterns for pages, blog and product routes. Is there something in the slug which indicates the route? For example, slugs of ‘pages/main’ always start with ‘m-’ and those of ‘blog/posts’ with ‘p-’ and ‘product/list’ with ‘l-’, then you can create the url patterns accordingly:




            'rules' => [

                '<slug:m-[\w\-]+>' => 'pages/main',

                '<slug:p-[\w\-]+>' => 'blog/posts',

                '<slug:l-[\w\-]+>' => 'product/list',

                ...

                ],



If you can not recognize any distinguishing pattern in the slug, then probably you have to create a dedicated dispatching controller/action which analyse the slug and dispatches the request to the appropriate controller/action.




            'rules' => [

                '<slug:[\w\-]+>' => 'dispatch/main',

                ...

                ],



Or, as @Bizley has pointed, you have to create a custom rule that analyse the slug and dispatch the request to the proper controller/action.

Thanks a lot for reply, to say truth I already tried with Custom URLRule but failed as was not sure how to make it correctly. I had created components folder inside my frontend folder, there I have created CustomRule.php file, extended that from URLRule but not sure what to do the next?

Sorry for my questions, this is my first project on Yii2 so I am a little confused.