how to config yii2 urlManager rules with aliases and $_GET parameter - php

for my current (advanced) yii2-based project i just need one controller (SiteController). So there is no need to show it in the url. Thats why i added this rule to the frontend config:
'urlManager' => [
'rules' => array(
'<alias:product|contact|about>' => 'site/<alias>',
),
This is working fine and localhost/product points to localhost/site/product.
Of course, i activated prettyUrl and added this default rules to the common config:
'rules' => array(
'<controller:\w+>/<id:\w+>' => '<controller>',
'<controller:\w+>/<action:\w+>/<id:\w+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
),
Now i want to access a GET parameter like this: localhost/product/productname. But i get the error:
Unable to resolve the request "product"
but localhost/site/product/productname is working properly...
The "productname" should be $_GET['id']. What do i have to change to make this happen?
Thanks!

Your rules should be before the default ones, and you need 2 rules, e.g. :
'rules' => array(
'<alias:contact|about>' => 'site/<alias>',
'<alias:product>/<id:\w+>' => 'site/<alias>',
'<controller:\w+>/<id:\w+>' => '<controller>',
'<controller:\w+>/<action:\w+>/<id:\w+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
),

Just define var in your action, for example public function actionProduct($id) and $id been is $_GET['id']

Related

Yii2 UrlManager config

I have a UrlRoute as below:
<?= Url::toRoute(['/site/show-post', 'id' => $model->id, 'type_id' => $model->type_id]) ?>
which give the result as
mysitename.com/site/show-post/1405?type_id=1
I want to add the post title to url and I modified the above as
<?= Url::toRoute(['/site/show-post', 'id' => $model->id, 'type_id' => $model->type_id,'title'=>$mdoel->title]) ?>
which results in:
mysitename.com/site/show-post/1405?type_id=1&title=your+post+title
So it is working fine. but I want to modify it like & it should work getting the same result.
mysitename.com/site/show-post/1405/type_id/1/your+post+title
even here 'id'=>$model->id is returning as I expect that is /show-post/1405 but the subsequent parameter is resulting in query-string
I also tried in config.php under - UrlManager like this:
'<controller:[A-Za-z-]+>/<id:\d+>/<type_id:\d+>/<title>' => '<controller>/<action>',
but it doesn't seems to work.
How I can achieve it like what I mentioned.
How about:
'<controller:[A-Za-z-]+>/<action:\w+>/<id:\d+>/<type_id:\d+>/<title>' => '<controller>/<action>',
The method you are following is correct and the results you are getting are the expected result. I am not sure what you meant by query language, but what understand is you want the clean urls instead of extra characters being added to your urls. For this you will have to implement pretty urls for yii2.
Here is how you can get pretty urls in yii2, add the following code to your configs:
'urlManager' => [
'class' => 'yii\web\UrlManager',
// Disable index.php
'showScriptName' => false,
// Disable r= routes
'enablePrettyUrl' => true,
'rules' => array(
'<controller:\w+>/<id:\d+>' => '<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
),
],

Pretty Url formattion in Yii2

I have a Yii 2 application and I'd like to use some pretty URL. In my config file I already enable the pretty URL with the below rules:
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
//'suffix' => '.html',
'rules' => [
'<controller:\w+>/<id:\d+>' => '<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>/<slug:[a-zA-Z0-9_-]+>/' => '<controller>/<action>/<slug>',
'<controller:[\w\-]+>/<action:[\w\-]+>/slug/<slug:\d+>/id/<id:\w+>/itmNo/<itmNo:\w+>' => '<controller>/<action>/<slug>',
],
],
And the URL result is something like this http://192.168.1.101/myproject/item?Id=mens-body-fitted-t-shirt-2018-summer-fashion-2&itmNo=82813720
In the above URL item is the controller while Id and itmNO are queries, I'd like to get something like this below URL http://192.168.1.101/myproject/item/mens-body-fitted-t-shirt-2018-summer-fashion-2/82813720
The query name are replaced with /. How can I do this in Yii2 and still get the query in my controller to make the normal search?
My url creation looks like this
$myurl = \Yii::$app->UrlManager->createUrl(['/item','Id'=>$items['slug'].'-'.$items['product_id'],'itmNo'=>$items['item_number']]);
You need to put the most precise rule at the beginning:
'rules' => [
'<controller:[\w\-]+>/<action:[\w\-]+>/slug/<slug:\d+>/id/<id:\w+>/itmNo/<itmNo:\w+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>/<slug:[a-zA-Z0-9_-]+>/' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
'<controller:\w+>/<id:\d+>' => '<controller>/view',
],
And create URL like this:
$myurl = \Yii::$app->UrlManager->createUrl([
'/item/view',
'id' => $items['product_id'],
'slug' => $items['slug'],
'itmNo' => $items['item_number'],
]);
I think, what you are looking for is this rule:
> '<controller:[\w\-]+>/<action:[\w\-]+>/<id:[\w\-]+>/<itmNo:\w+>'=>'<controller>/<action>'
In this case, you should indicate a controller name, id and itmNo as parameters. Don't forget to put this rule before more general ones.
Sample query:
\Yii::$app->UrlManager->createUrl(['item/view','id'=>'slug'.'-'.'2', 'itmNo'=>'12313'])
read this post for better understanding

YII 2 Url Route not working with $_GET parameters

I'm new to Yii2 and their URL ruling is kinda tricky. I have a SiteController with an action like this
public function actionSuccessStories($slug = null)
{
// some codes
}
in my config i have this
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'enableStrictParsing' => true,
'rules' => [
// Default routes
'<controller:\w+>/<id:\d+>' => '<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
// page routes
'success-stories/<slug:\w+>' => 'site/success-stories',
// Remove 'site' parameter from URL
'<action:(.*)>' => 'site/<action>',
],
],
in my view i have this to generate my url
Url::to(['site/success-stories', 'slug' => 'slug_value'], true);
my problem is Url::to(); creates success-stories?slug=slug_value
instead of
success-stories/slug/slug_value am i doing this right? What i want to accomplish is the second format.
I've read this question related to mine but it covers only modules
Yii2 url manager don't parse urls with get parameter
Change your rules to:
'rules' => [
// page routes
'success-stories/<slug:\w+>' => 'site/success-stories',
// Default routes
'<controller:\w+>/<id:\d+>' => '<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
// Remove 'site' parameter from URL
'<action:(.*)>' => 'site/<action>',
],
Order of rules is important, Yii2 will try to match rule one by one, if it fits - it will use it.

Yii's URL manager rules reading from a MySQL table

Is it possible to have this kind of array:
'urlManager' => array(
'urlFormat' => 'path',
'showScriptName' => false,
'urlFormat' => 'path',
'rules' => array(
'<controller:\w+>/<id:\d+>' => '<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
'/admin' => '/admin/home',
'/admin/<controller:\w+>' => '/admin/<controller>',
'/admin/<controller:\w+>/<action:\w+>/<id:\d+>' => '/admin/<controller>/<action>',
'/admin/<controller:\w+>/<action:\w+>' => '/admin/<controller>/<action>',
),
),
Be read from a database table?
Why: I'm making a CMS in which I want to define a custom categories, pages and posts base so that I don't use a base controller.
Example: My Pages controller is PagesController and I can make a rule in URL manager like this:
/pages/some-page-alias
I want to be able to change /pages/, /categories/ and /posts/ to something localized, meaning to be able to change it i.e. on Bosnian:
/kategorije/ => /categories/,
/stranice/ => /pages/,
/clanci/ => /posts/,
Is there a solution for this, how it can be done?
Btw, I have not tried anything because I have no idea...
You can simply do this:
'urlManager' => array(
'urlFormat' => 'path',
'showScriptName' => false,
'urlFormat' => 'path',
'rules' => array(
'kategorije/<id:\d+>' => 'category/view',
'kategorije/<action:\w+>/<id:\d+>' => 'category/<action>',
'kategorije/<action:\w+>' => 'category/<action>',
'<controller:\w+>/<id:\d+>' => '<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
'/admin' => '/admin/home',
'/admin/<controller:\w+>' => '/admin/<controller>',
'/admin/<controller:\w+>/<action:\w+>/<id:\d+>' => '/admin/<controller>/<action>',
'/admin/<controller:\w+>/<action:\w+>' => '/admin/<controller>/<action>',
),
),
URLManager prioritizes by what is listed first. So if you put in a custom rule above the standard rules it will run those rules first. Once it finds a rule that applies it breaks out.
As for me, your question is not clear.
If you want to store array in DB you can do it by serialize'ing it before.
If you want multiple names pointing to same controller you can use such a rule:
array(
'<_c:(stranica|page)>/<id:\d+>'=>'myController/view',
)
In this case if any of urls
http://example.com/stranica/123
http://example.com/page/123
is requested, it will point to
http://example.com/myController/view?_c=stranica&id=123
http://example.com/myController/view?_c=page&id=123
accordingly. See CUrlManager examples in API.

Yii customizing the display of url parameters

I'm trying to change the way Yii is showing the url for my "product" page.
Now, it shows this:
localhost/~antonio/project/?r=site/product&id=HXW1410D260D0TB013&language=en
Or with urlFormat=path
localhost/~antonio/project/en/product/id/HXW1410D260D0TB013
I need the url's to look like this:
localhost/~antonio/project/en/product/HXW1410D260D0TB013
I looked into the Yii docs, but I can't find a way to do this.
Thanks.
Add the following rule to your main.php rules array:
'product/<id:[A-Z0-9]+>'=>'site/product',
so you should have something like
'urlManager' => array(
'urlFormat' => 'path',
'showScriptName' => false,
'rules' => array(
'product/<id:[A-Z0-9]+>'=>'site/product',
'<controller:\w+>/<id:\d+>' => '<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
),
),
essentially the rule format is as follows:
'product/<id:[A-Z0-9]+>'=>'site/product',
Terms in <> mean you are passing a variable, so
<id:[A-Z0-9]+>
means you are passing $_GET['id'] if the regex matches (if it has only capital letters and numbers).
So the rule above means if the url matches product/something, then send it to site/product and pass the "something" as a $_GET parameter called id.
Hope that clarifies.
For this, go to main.php file in config folder and uncomment the following to enable URLs in path format:
'urlManager' => array(
'urlFormat' => 'path',
'rules' => array(
'<controller:\w+>/<id:\d+>' => '<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
),
),

Categories