I'm developing a web application using Yii Framework and I'm having a little problem with url rewriting.
The issue is with the last rule in the code below. It was supposed to turn localhost/app/category/some-friendly-url-category-name (this part would appear in the browser) into localhost/app/category/view/id/some-friendly-url-category-name
It works fine when the category name is only one word, like: vehicles.
But it doesn't work when it has more than a word, like: children-stuff
'urlManager'=>array(
'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>',
'category/<id:[A-Za-z0-9_\-]+>' => 'category/view',
),
),
You don't need to escape the hyphen in the ID:
'category/<id:[A-Z a-z 0-9 _ -]+>' => 'category/view',
A simpler solution would be:
'category/<id>' => 'category/view',
Also, do note that you have to place this specific rule above the general (default) rules.
Move the category rule above the <controller> ones. Otherwise, your app would try to find a actionChildrenStuff() in your CategoryController, for example.
Usually I would add new rules above those three general ones.
Related
I am trying to make a url with regex in YII1.
I want to create the url for 'pagename/username'.
I tried like this :
'<pagename:([A-Za-z0-9-A-zÀ-ú]+)>/<i:w+>' => 'site/Profile',
but it is not working. Page is just reloading on itself
I want to show the new page when url become like 'pagename/username'.
It should be:
'<pagename:([A-Za-z0-9-A-zÀ-ú]+)>/<i:\w+>' => 'site/profile',
w+ will handle handle usernames containing only "w" letters, you need to use \w+ to handle any word.
Also [A-Za-z0-9-A-zÀ-ú]+ looks suspicious - you should avoid non-ASCII letters in URLs, so -A-zÀ-ú should be unnecessary. I would recommend to use this rule:
'<pagename:[\w-]+>/<i:\w+>' => 'site/profile',
I make it work this way
'public/<pagename:([A-Za-z0-9-A-zÀ-ú]+)>/<i>' => 'site/Profile'
see that i had to put a "public" at the start to make it works, and remove the +w of i , my "site/profile" just is a print_r of the $_REQUEST;
Array ( [pagename] => pagename [i] => username )
EDIT: The answer of #rob06 is so much better, just remember put it first of the array "rules"
'rules' => array(
'<pagename:[\w-]+>/<i:\w+>' => 'site/profile',
'<controller:\w+>/<id:\d+>' => '<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
),
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'<controller:\w+>/<id:\d+>/<action:\w+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
],
],
Not it is clear why references of a /controller/name-action/id/1 do work, /controller/1/name-action do not work, and without hyphen everything works, according to documentation of action name-action it is actionNameAction??
public function actionNameAction($id) {
// some code
}
Inline Actions
In advance all thanks.
\w does not include -.
Change pattern to [\w\-]+.
I think you are confused with zend framework and Yii2.In yii2 it is actionActionName.While using it in url's the capitals are changed to lower case with a hyphen preceding them.
For example,
if the controller is Orders
and the action is OrderAnalysis
then the url would be something like orders/order-analysis.
Moreover any id or any other parameter is added only after routing the app to its correct controller action.
Also now coming to your problem I think i found a backdoor to it-
// creates an anchored URL: /index.php?r=post%2Fview&id=100#content --------------------------
echo Url::to(['post/view', 'id' => 100, '#' => 'content']);
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.
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.
I'm using Yii as a framework and I'm having trouble with this piece of code.
I want to output the apartments which has a "status" of "occupied"
So I have this CHtml link with querystring parameters
<?php echo CHtml::link('Occupied Apartments', array('/apartments/','status'=>'occupied')); ?>
But it still displays ALL outputs even if the status is "available". What must be the problem?
Any help would be appreciated
I think you are trying to construct the link as
http://yourdomain.com/controller/action/status/xyzStatus
For this, First you have configure this URL structure in urlManager in your config file ie, main.php in protected/config/
Just add bellow line in urlManager rules
'<controller:\w+>/<action:\w+>/<status:([A-Za-z0-9-]+)>' => '<controller>/<action>',
Finally your basic url rules will appear as
'rules' => array(
'<controller:\w+>/<action:\w+>/<status:([A-Za-z0-9-]+)>' => '<controller>/<action>', //This is newly added line
'<controller:\w+>/<id:\d+>' => '<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
),
Now your url will work. You can get the status value with $_GET['status'];
Please filter your data provider with $_GET['status']; mostly on conditions with CActiveDataProvider .
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.