Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Yii2 pretty URL: automatically convert everything with slashes (including all parameters)

I'm working with Yii2 and I would like to use urlManager with routing to convert all non-letter and non-number characters into slashes. I have looked at a lot of question what have already been asked (#1, #2, #3, #4) but none solved it since they either show a little similar but not what I want or not working for me at all.

I have simple urlManager rules:

//...
'urlManager' => [
    'class' => 'yii\web\UrlManager',
    'enablePrettyUrl' => true,
    'showScriptName' => false,
    'rules' => array(
        '<controller:\w+>/<id:\d+>' => '<controller>/view',
        '<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
        '<controller:\w+>/<action:\w+>' => '<controller>/<action>',
    ),
],

.htaccess (also simple):

RewriteEngine on
# If a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Otherwise forward it to index.php
RewriteRule . index.php

In my case, my ugly URL is this (SiteController -> public function actionTestRouter()):

localhost/frontend/web/index.php?r=site%2Ftest-router&ident=10&token=ADB&module=P120

With rules I have written above, I get better result (because it removes index.php?r= and converts %2F to /):

localhost/frontend/web/site/test-router?ident=10&token=ADB&module=P120

What I want to get:

localhost/frontend/web/site/test-router/ident/10/token/ADB/module/P120

My several attemps with rules were:

'test-route/<ident:\d+>/<token:\w+>/<module:\w+>' => 'test-route' // 1
'<controller:\w+>/<action:\w+>/<ident:\d+>/<token:\w+>/<module:\w+>' => '<controller>/<action>' // 2
'<controller:\w+>/<action:\w+>/<slug:[a-zA-Z0-9_-]+>/' => '<controller>/<action>/<slug>' // 3 (not even sure what slug does here

It would also be super nice if the rules would apply to any parameters and values, regardless of their name and values.

like image 701
Gytis TG Avatar asked Jun 30 '16 06:06

Gytis TG


1 Answers

Your second attempt

'<controller:[\w\-]+>/<action:[\w\-]+>/<ident:\d+>/<token:\w+>/<module:\w+>' => '<controller>/<action>' // 2

will take/create urls

localhost/frontend/web/site/test-router/10/ADB/P120

without names of params in url and these params will be used only in this order and their list is fixed as you see

If you want add their names in url (for estetic or seo purposes like in your question):

'<controller:[\w\-]+>/<action:[\w\-]+>/ident/<ident:\d+>/token/<token:\w+>/module/<module:\w+>' => '<controller>/<action>',  // 2

And url creation for these routes will be same:

echo Url::to(['site/test-router', 'ident' => 100, 'module' => 100, 'token' => 100]);

If you want parse various length of this list of params, you can use smth like this:

'<controller:[\w\-]+>/<action:[\w\-]+>/<params:[a-zA-Z0-9_\-\/]+>' => '<controller>/<action>'

or specify it only for one route:

'site/test-route/<params:[a-zA-Z0-9_\-\/]+>' => 'site/test-route'

So in action you will get parameter params: Yii::$app->request->get('params'); parse it with regexp.

like image 112
user1852788 Avatar answered Oct 16 '22 14:10

user1852788