react with yii urlManager rule to a specific url - php

I have a noob question, but googling for several hours didn't get me closer to the answer.
I want that when I enter the following url into my browser, that is gets assigned to a specific controller action.
Imagine I have the following url:
http://localhost:5555/tractor-unit/?param1=1&param2=abc
How should the rules looks like to process this request in a certain action in a certain controller.
What I've tried so far:
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'tractor-unit/?param1=<param1:\d+>&param2=<param2:\w+>' => 'tractor/do'
]
],
That doesn't work. I just don't understand how the rules entry should be written in order to pass this request to a controller named tractor and its action do. Or maybe I totally misunderstood the whole url manager concept.

simple add to action "do" in tractor-unit controller next:
public function actionDo($param1=null, $param2 = null)
if this don't work
remove section "rules" from config

Related

How can I use dash with multiple words in Yii2 page creation

I am trying to create a static page with Yii2. The page name has more has two words for example - privacy policy. I added the code below inside SiteController.php
public function actionPrivacyPolicy()
{
return $this->render('privacy-policy');
}
I then created a page inside the site folder named - privacy-policy.php
This however resulted in page not found error.
My website has many cases like this. What is the best way to fix this?
You need to access the url like below if using "enablePrettyUrl"=>true
http://yoursite.com/site/privacy-policy
and
http://yoursite.com/index.php?r=site/privacy-policy
if not using "enablePrettyUrl"=>true
after that you need to parse all the actions in SiteController by the action names only, so you need to turn "enableStrictParsing"=>false and then add the following rule in the urlManager
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
"enableStrictParsing" => false,
'rules' => [
"/" => "site/index",
"<action:(.*)>" => 'site/<action>',
],
],
EDIT:
Although this allows characters that are/should not be allowed but, The reason I have used (.*) in the rules is because the action name will be defined inside the controllers and you have to use the rules with the declared actions only inside the SiteController which isn't going to parse any action name for rules with any of the disallowed characters, means if the action name is going to be, say actionMyActionNameLong there is 0 possibility that any / or \ is generated with the action name which would break the things further when using the rule, so you can use it in this context otherwise you can use the [\w\-]+ if creating the urls manually.
Pattern <alias:\w+> will not match hyphen, since \w+ will accept only letters, numbers and underscore. You need to use [\w\-]+ to match also words separated by hyphen.
'rules' => [
'<alias:[\w\-]+>' => 'site/<alias>',
// ...
],
I think you can configure UrlManager in main.php on the config folder
and try to add some rules on urlManager so the URL can be accessed dynamically
'urlManager' => [
"enablePrettyUrl" => true,
"showScriptName" => false,
"enableStrictParsing" => false,
"suffix" => "",
"rules" => [
"<controller:\w+>/<action:\w+>" => "<controller>/<action>"
],
],
If you are using \yii\filters\AccessControl on your controllers behaviour, you might need to add allowed action to the list before creating a new action.

How to hide module name from url yii2

I am new to yii2.
mydomain.com/organisation/banks/index
from above url i want to remove organisation.
i add following code to my config file under component section.
'urlManager' => [
'showScriptName' => false,
'enablePrettyUrl' => true,
'rules' => [
'<controller:\w+>/<id:\d+>'=>'<controller>/view',
'<controller:\w+>/<action:\w+>'=>'modules/<controller:\w+>/<action:\w+>',
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
],
]
But still its not working.
Is there any way to do it?
Thanks
In case of multiple URLs to hide I'm afraid you have to add the rule for each URL like:
'banks/index' => 'organisation/banks/index',
'something/another' => 'organisation/something/another',
If there is an unique controller's name that this module uses you can make it easier by adding general rule. For example if controller's name is banks and there is no BanksController under the top namespace level of app you can add:
'banks/<action>' => 'organisation/banks/<action>',
If organisation module is the only one your app uses and you don't need top namespace level controllers you can add:
'' => 'organisation',
So entering the domain URL address gets you directly to organisation module default route.

use static url in url routing yii2

I have an old website, now I have written it with new version of yii framework and I want change the urls, but because of SEO problems I want to keep my old urls.
Now when the user enters www.mysite.pre/car/details/10908 I want application renders www.mysite.pre/site/show_detail/10908 how could I handle it in yii2 Routing?
Assuming you have got this action in your SiteController class
public function actionShow_detail($id) {}
Add this in your configuration file:
// ...
'components' => [
// ...
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
// ...
'car/details/<id:\d+>' => 'site/show_detail',
],
],
],
More details and information about Yii 2 routing can be found in "Routing and URL Creation" section of The Definitive Guide to Yii 2.0.

Yii 2 canonical URL in urlManager configuration

I've got urlManager section in app configuration with several URLs per route:
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'enableStrictParsing' => true,
'rules' => [
'article-a' => 'article/a', // canonic comes first
'article-deprecated-a' => 'article/a',
'article-another-a-is-deprecated' => 'article/a',
'b-annoucement' => 'announcement/b', // canonic comes first
'legacy-b-annoncement' => 'announcement/b',
...
SEF URLs for routes are stored in frontend/config/main.php as an array, with multiple URLs per route. The first URL for the given route (i.e. /article-a) is canonical and the rest are legacy URLs.
What's the most natural way to specify canonical URL for a group of URLs that are pointing to the same route? It can be either rel="canonical" in view or 301/302 redirect to canonical URL.
Canonical URLs should be preferably specified in a place where the routes were defined (frontend/config/main.php configuration file in this case). The requirement here is that canonical URL should be defined outside of the controller, not hard-coded to controller.
I'm not sure how exactly you need to manage your rules so I'll go for a general use case and I'll base my answer on what I did understand from Paddy Moogan's Article which I will resume within the following example and I hope it helps on designing your required solution:
requirement:
Assuming a Search Engine did send a robot to check page B in my website and I'm not fine with people getting to page B instead of page A. So this is how I can clarify my point to the robot:
Forcing a 301 redirect to page A:
Telling the Search Engine that this page is permanently moved to page A. So please don't send more people to it. Send them to page A instead.
Forcing a 302 redirect to page A:
Telling the Search Engine that this page is temporary moved to page A. So do whatever you think it
is appropriate.
Opening page B (200 status code) but insert a Canonical
link element
pointing to page A:
Telling the Search Engine that this page is working fine but it is to me a secondary page and I would suggest sending the next visitors to page
A instead.
design:
So based on that this is how I would see a possible structure to my rules configuration:
'rules' => [
[
// by default: 'class' => 'yii\web\UrlRule',
'pattern' => '/',
'route' => 'site/index',
],
[
// the custom class
'class' => 'app\components\SEOUrlRule',
'pattern' => 'about',
'route' => 'site/about',
'permanents' => [
'deprecated-about',
'an-older-deprecated-about'
],
'temporaries' => [
'under-construction-about',
],
'secondaries' => [
'about-page-2'
]
],
[
// different route with own action but canonical should be injected
'class' => 'app\components\SEOUrlRule',
'pattern' => 'experimental-about',
'route' => 'whatever/experimental',
'canonical' => 'about'
],
]
This way I can chain as much arrays as I need to use Yii's default class yii\web\UrlRule while I can have a custom one in my app components folder dedicated to SEO related controllers.
Before going to code, this is how I would expect my website to behave :
You visit the /about page you get a 200 response (no
canonical added).
You visit the /deprecated-about page you get redirected to
/about with 301 status code.
You visit the /under-construction-about page you get redirected to
/about with 302 status code.
You visit the /about-page-2 page you get a 200 response (rendered by index/about action). No redirections except a similar tag to this is automatically injected into source code:
<link href="http://my-website/about" rel="canonical">
You visit the /experimental-about page you get a 200 response (rendered by its own action whatever/experimental) but with that same canonical tag above injected.
code:
The SEOUrlRule will simply extend \yii\web\UrlRule and override its parseRequest method to define the extra attributes based on which we will force a HTTP redirection or call parent::parseRequest() after registering the canonical link tag to the Yii::$app->view:
namespace app\components;
use Yii;
class SEOUrlRule extends \yii\web\UrlRule
{
public $permanents = [];
public $temporaries = [];
public $secondaries = [];
public $canonical = null;
public function parseRequest($manager, $request)
{
$pathInfo = $request->getPathInfo();
if(in_array($pathInfo, $this->permanents))
{
$request->setPathInfo($this->name);
Yii::$app->response->redirect($this->name, 301);
}
else if(in_array($pathInfo, $this->temporaries))
{
$request->setPathInfo($this->name);
Yii::$app->response->redirect($this->name, 302);
}
else if($this->canonical or in_array($pathInfo, $this->secondaries))
{
$route = $this->name;
if ($this->canonical === null) $request->setPathInfo($route);
else $route = $this->canonical;
Yii::$app->view->registerLinkTag([
'rel' => 'canonical',
'href' => Yii::$app->urlManager->createAbsoluteUrl($route)
]);
}
return parent::parseRequest($manager, $request);
}
}
And that is all what it needs. Note that Yii::$app->controller or its related actions won't be yet available at this early stage of solving routes as it is shown in this lifecycle diagram but it seems that Yii::$app->view is already initialized and you can use its $params property to set custom parameters (as it is done in this example) which may be useful for more advenced cases where more data should be shared or populated to final output.
I think you will have problems when creating the URL from the application to "article/a".
Why not use htaccess or the vhost file to do a 302 redirect to the proper URL?
If you want to handle it through the urlManager, I think you can just register the canonical link
$this->registerLinkTag(['rel' => 'canonical', 'href' => 'article/a']);
in the view.
Mode details here: http://www.yiiframework.com/doc-2.0/yii-helpers-baseurl.html#canonical()-detail
Yii2 provides a tool to generate canonnical urls based on your rules.
\helpers\Url::canonical()
The idea is that it will provide you an url to 'article-a'.

Remove controller name from URLs in Yii2

How can I remove the controller name from URLs in Yii2?
I'm aware of simple aliases, but I'm not sure how to apply aliases to a little bit more complex rule, like the following one:
'rules' => [
'public/<seo_url:.*?>/<category_id:\d+>/<product_id:\d+>' => 'public/product'
]
This will create a rule so URLs like /product/this-is-a-slug/94/12 will call the actionProduct in my Public controller.
How can I make an alias that would call that same action if I try to access a product using this URL: /this-is-a-slug/94/12 ?
Set new rulw on top of all rules. Like that:
'rules' => [
'<seo_url:.*?>/<category_id:\d+>/<product_id:\d+>' => 'public/product',
]
This is work for me.

Categories