I am struggling with this problem and not found any suitable answer.
I want my_site/user/1 to become my_site/user/user_name
My urlManager looks like this:
'urlManager' => array(
'urlFormat' => 'path',
'rules' => array(
'user/<username:\w+>'=>'user/view',
'<controller:\w+>/<id:\d+>'=>'<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
),
'showScriptName' => false,
),
User Controller:
public function actionView($username)
{
$this->render('view', array(
'model' => $this->loadModel($username),
));
}
When i hit /user/admin it redirects me to actionView not to the actionAdmin from my controller and i have multiple such actions like create, delete and so on.
How can i avoid this? Is there an alternative?
Thanks.
The urlManager try's to match the url to a controller and action.
the 1st part of
'user/<username:\w+>'=>'user/view',
has matched to the user controller and the next part it looking for any string that consists of words, then sent the user to user/view
I recommend changing user/<username> to manage-user/<username> or my-account/<username>, something like that.
Related
I need to perform routing for the following url schemas:
website.com/some-category-name
website.com/some-category-name/entryName
some-category-name will be variable - some name of category
How to configure routing for this? I need to enter previous controllers, for example:
website.com/account
website.com/regiter
and want to everything that does not have controller name (so will be category name) going to controller Category.
I can't work it out.
use
'urlManager' => array(
'urlFormat' => 'path',
'showScriptName' => false,
'rules' => array(
'categoryName/<categoryName:\w+>' => array('site/category'),
'register' => array('site/register'),
'account' => array('site/account')
),
),
At first you must declare all rules for "non Category" actions, and after that dynamic rules (associated with category and antry):
'urlManager' => array(
'urlFormat' => 'path',
'showScriptName' => false,
'rules' => array(
// for example if your account and register actions in user controller
// ... you can write
'account' => 'user/account',
'register' => 'user/register',
// or with one rule
'<action(account|register)>' => 'user/<action>',
// and for all other 'static actions', such as login, logout ...
// after yhat you can declire dynamic rules
'<categoryName:\w+>' => 'category/index',
'<categoryName:\w+>/<entryName:\w+>' => 'category/entry'
),
),
So the code Yii::app()->createUrl('user/register') will generate url website.com/register, and accordingly the url website.com/register "goes to" register action of user controller (all other static rules like this way).
Now dynamic rules: code
Yii::app()->createUrl('category/index', array(
'categoryName' => 'first-category-name'
))
will generate url website.com/first-category-name, and vice versa: the url website.com/first-category-name "goes to" category/index action and in it will be available $_GET['categoryName'] parameter, which will be equal to "second-category-name"․
Accordingly code
Yii::app()->createUrl('category/index', array(
'categoryName' => 'some-category-name',
'entryName' => 'some-entry-name'
))
will generate url website.com/some-category-name/some-entry-name, and in category/entry action you can get $_GET['categoryName'] equal to "some-category-name" and $_GET['entryName'] equal to some-entry-name.
I hope this help you to understand how works rules in Yii.
Thanks!
I set to the main config the following url rules:
'urlManager'=>array(
'urlFormat'=>'path',
'showScriptName'=>false,
'rules'=>array(
'<controller:\w+>'=>'<controller>/list',
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
'<controller:\w+>/<id:\d+>/<title>'=>'<controller>/view',
'<controller:\w+>/<id:\d+>'=>'<controller>/view',
'\?r=<controller:\w+>/<action:\w+>' => '<controller>/<action>'
),
),
Everything is woking fine, but I also want the previous url format to keep working so I don't have to rewrite lots of urls that I don't care it to be seo-friendly:
index.php?r=controller/action¶m1=value1
But it shows an error now. Is there a way to keep it working?
To my opinion the best way is to replace all old urls with your IDE regex replace option. But anyway you can do what you want this way:
Use following route rule in the urlManager config:
'rules' => [
[
'class' => 'my\namespace\UrlRule',
'pattern' => '<controller>/<action>',
'route' => '<controller>/<action>',
],
...
Extend yii\web\UrlRule with your my\namespace\UrlRule and rewrite its 'parseRequest' method so that it could use $_GET['r'] parameter value if is set:
namespace my\namespace;
class UrlRule extends \yii\web\UrlRule
{
public function parseRequest($manager, $request)
{
if ($pathInfo = \Yii::$app->request->get('r')) {
\Yii::$app->request->setPathInfo($pathInfo);
}
return parent::parseRequest($manager, $request);
}
}
You may also extend yii\web\Request instead so that it's 'getPathInfo' method could use $_GET['r'] parameter if set.
Ok, removed my previous question and reformulated the new one, otherwise no one would understand, sorry. So here the problem that's left:
So I want to rewrite an URL to a single word which works with zero, one and two parameters, but not with 3:
Original url with 2 paramaters:
index.php?r=site/page&view=exposities&tijd=nu
urlmanager rule:
'exposities_nu'=>array('site/page', 'defaultParams' => array('view' => 'exposities', 'tijd'=>'nu')),
result:
/exposities_nu/
Now what doesn't work:
Original url with 3 parameters:
index.php?r=site/page&view=exposities&tijd=vestiging&locatie=1
urlmanager rule:
'knsm'=>array('site/page', 'defaultParams' => array('view' => 'exposities', 'tijd'=>'nu', 'locatie'=>'1')),
result:
index.php?r=site/page&view=exposities&tijd=vestiging&locatie=1
Does anyone why this last url isn't shortened to /knsm/?
Maybe you didn't set the url in the URL Manager right. See this example:
return array(
......
'components'=>array(
......
'urlManager'=>array(
'urlFormat'=>'path',
'rules'=>array(
'post/<id:\d+>/<title:.*?>'=>'post/view',
'posts/<tag:.*?>'=>'post/index',
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
),
),
),
);
Also you have to create you URLs correct:
Yii::app()->createUrl('post/view', array(
'id'=>$this->id,
'title'=>$this->title,
));
I have folder hierarchy
---protected
------...
------controller
---------admin
------------OneController.php
------------TwoController.php
---------user
------------ThreeController.php
------------FourController.php
also i add them in main.php as
'import' => array(
'application.models.*',
'application.forms.*',
'application.components.*',
'application.fetcher.*',
'application.controllers.admin.*',
'application.controllers.user.*', ...
add route for admin
'urlManager' => array(
'showScriptName' => false,
'urlFormat' => 'path',
'rules' => array(
// ...
'admin' => 'admin/one/index',
but this doesn't work, can you help to deal with it? I want do simply routes to subfoldered controllers.
I think your syntax of rule is wrong. Try to use
'rules' => array(
'admin' => 'admin/one/index'
)
I Found solution. My mistake was on controller, I have default (old) OneController in /protected/controllers that's why routes give me 'old' data, when I change name of (old) OneController, trouble gone. And after that route give me new one from /protected/controllers/admin/OneController.
it was like this one
---protected
------...
------controller
---------OneController.php <-- this gives wrong data even error because of routes
---------admin
------------OneController.php
------------TwoController.php
---------user
------------ThreeController.php
------------FourController.php
I have configured the CUrlManager in the config/main.php to use clean URL:
'urlManager' => array(
'showScriptName' => FALSE,
'urlFormat' => 'path',
'rules' => require(dirname(__FILE__) . '/routes.php'),
),
The clean URL function works perfectly, but I would like to prevent the default <controller>/<action> pattern match to occur.
This is my config/route.php:
<?php
return array(
'books' => 'book/index'
);
Now people can go to the same book page by 2 different URLs:
http://www.mysite.com/books
http://www.mysite.com/book/index
I want to disable the second URL pattern. Is this possible?
You can enable useStrictParsing in your url manager component.