i have some simular Url Mapping in Yii2:
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
['pattern'=>'pages','route'=>'pages/index', 'suffix'=>'/'],
['pattern'=>'pages/<id:\d+>','route'=>'pages/single', 'suffix'=>'.html'],
]]
So, urls:
domain.com/pages/ - works fine
domain.com/pages - E404
domain.com/pages/321.html - works fine
domain.com/pages/321 - E404
If i remove suffix parameter from config array, then:
domain.com/pages/ - E404
domain.com/pages - works fine
domain.com/pages/321.html - E404
domain.com/pages/321 - works fine
Is it possible to make 'suffix' into link optional, e.g. 'pages' and 'pages/' will be followed to one direction?
Thanks.
Seems like it's not possible to achieve this with rules configuration in url manager.
Please check these related issues on Github:
https://github.com/yiisoft/yii2/issues/1807
https://github.com/yiisoft/yii2/issues/6498
So choose one option that more suitable for you and use it.
Need trailing slash or .html - add suffix, otherwise just leave that as is.
Also for search engines
domain.com/pages/
domain.com/pages
these are the two different pages and using that will entail content duplicates.
Related
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.
i am playing around with yii2 (recently been working in Yii 1.3) and need help to configure/write the Url-Manager Rules for my favorite URL-sheme.
As Example, i wanna call the action test from xmpleController with 2 parameters.
a normal GET request would looks like this:
?param1=value1¶m2=value2
at the moment, my url look like this:
index.php/xmple/test/?param1=value1¶m2=value2
This is how the url should look like:
index.php/xmple/test/param1/value1/param2/value2
here are my URL-Manager Rules:
'urlManager' => [
'enablePrettyUrl' => True,
'showScriptName' => false,
'rules' => [
'<a:\w+>/<b:\w+>/<c:\d+>/<d:\d+>' => 'a/b'
],
],
Does anybody have an Idea how I can use my favorite URL scheme? I think the only way to reach my goal is to edit the urlManager rule, but I don't have any experience in this. maybe someone here has some hint for me?
Thanks for your help!
Before you start making your desired URL format you need to understand first what formats are supported by the URL manager when working in Yii2. And how to create rules to create those formats.
Supported URL Formats
The default URL format;
The default URL format uses a query parameter named r to represent the route and normal query parameters to represent the query parameters associated with the route. The URL /index.php?r=xmple/test¶m1=100 represents the route xmple/test and the param1 query parameter 100. The default URL format does not require any configuration of the URL manager and works in any Web server setup.
The pretty URL format.
Uses the extra path following the entry script name to represent the route and the associated query parameters. For example, the extra path in the URL /index.php/xmple/100 is /xmple/100 which may represent the route xmple/test and the param1 query parameter 100 with a proper URL rule. To use the pretty URL format, you will need to design a set of URL rules according to the actual requirement about how the URLs should look like.
This rule can satisfy the above statement 'xmple/<param1:\d+>' => 'xmple/test',
Read More about it here
So it is not going to be showing
index.php/xmple/test/param1/value1/param2/value2 but
index.php/xmple/test/value1/value2 or index.php/xmple/value1/value2 or xmple/test/value1/value2.
How to create Rules
You can configure yii\web\UrlManager::$rules as an array with keys being the patterns and values the corresponding routes.
Read More here
You can use the rule 'xmple/test/<param1:\w+>/<param2:\w+>'=>'xmple/test' considering that you will be sending parameters that match any word character (equal to [a-zA-Z0-9_]) as a parameter, which will output xmple/test/value1/value2 with 'showScriptName' => false, or index.php/xmple/test/value1/value2 otherwise.
If the rule is going to be used for a single controller/action or you can use as described or use the parameterized routes which allows a URL rule to be used for matching multiple routes.
You can change your urlManager to the following
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'xmple/test/<param1:\w+>/<param2:\w+>'=>'xmple/test'
],
],
I have a URL rule with multiple optional parameters and it was working but it stopped after I upgraded from Yii 1.1.15 to 1.1.19.
const OPTIONAL_PARAMS = '(/<featured:featured>)?'
. '(/subType/<subType:.*?>)?'
. '(/type/<type:\d+>)?'
. '(/category/<category:.*>)?';
'<lang:(en|fr)>/reports'. OPTIONAL_PARAMS => 'reports',
Any one can provide me some ideas or someone faced similar issues?
P.S. The other URL manager rules are working fine, only this one with (SOME_CODE)? for optional params is not working. I'm using PHP 5.6 and Apache.
You may be interested in by this issue. But in short: this syntax (regexp outside of named params) was never officially supported and it was removed as a bugfix in Yii 1.1.17.
The last version which supports this is 1.1.16, but it is really old and I would not recommend using it. You should probably create custom UrlRule and use it instead of CUrlRule for this particular case.
You may also try to add /* at the end of the pattern, like this:
'<lang:(en|fr)>/reports/*' => 'reports',
This will allow to append GET params to URL as /key/value. So this:
$this->createUrl('reports', [
'type' => 'sometype',
'category' => 'somecategory',
'lang' => 'en',
]);
will create URL like:
/en/reports/type/sometype/category/somecategory
I have been looking around but haven't found what I needed. Basically, I have a few small modules which have just the DefaultController and a few bigger ones with multiple controllers.
My rules for the small modules work fine but the ones of the big modules won't. Here are my rules:
'<module:\w+>/<action:\w+>' => '<module>/default/<action>',
'<module:\w+>/<action:\w+>/<id:\d+>' => '<module>/default/<action>',
'<module:\w+>/<controller:\w+>' => '<module>/<controller>/index',
'<module:\w+>/<controller:\w+>/<action:\w+>' => '<module>/<controller>/<action>'
The first two rules work fine, allowing me to access:
http://host/news/create and routes to news/default/create.
The last two are supposed to do the following:
http://host/posts/category which should route to posts/category/index
and
http://host/posts/category/create which should route to posts/category/create
They do not seem to work, sadly. Any suggestions?
It looks like the first rule will capture any request that could also match the third one.
Think of it in the terms of its representing regex: w+/w+: as a generic rule for routes in Yii, more prescriptive rules should go on top and less more generic, catch-all rules should be at the bottom.
Now the best way to obtain what you need would be to do something along the lines of:
'<module:news>/<action:\w+>' => '<module>/default/<action>',
'<module:news>/<action:\w+>/<id:\d+>' => '<module>/default/<action>',
'<module:posts>/<controller:\w+>' => '<module>/<controller>/index',
'<module:posts>/<controller:\w+>/<action:\w+>' => '<module>/<controller>/<action>'
this way you are explicitly expressing the routes for each of the modules in a clear and immediate way which will also help you in the long-term.
I am trying to add OpenSearch functionality to my Yii application and have trouble configuring the UrlManager to route a search request to the right controller (called query in this case) and method (called index). The search works great if there are no white space in the search words. Whenever someone searches for more than one word, the UrlManager cannot find the controller and method to handle the search.
The url in the search.xml file that triggers the search is like this:
<Url type="text/html" template="[pathToMyApp]/application/index.php/query/{searchTerms}"/>
And my UrlManager is configured like this:
'urlManager' => array(
'urlFormat' => 'path',
'rules' => array(
'<_c:(name|tag)>s/*' => '<_c>/index',
'<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'query/suggest/<needle:\w+>'=>'query/suggest', // used to route OpenSearch JSON suggestions - works
'query/findbox'=>'query/findbox', // routes search queries from a form in the application - works
'query/<needle:\w+>'=>'query/index', // works only for search strings with no white space
),
'showScriptName' => true,
),
It seems that in query/<needle:\w+>, the \w+ part will stop matching at the first non-word char (e.g. a space). Changing the \w to something more forgiving (e.g. [\w ]) will probably do the trick.