create a multi level Yii route - php

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>',
),

Related

Yii2 does not find 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']);

Yii2 pretty URL: automatically convert everything with slashes (including all parameters)

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.

yii1 pagination with url-manager

i have problem with yii1 pagination
this is my url manage config:
'rules' => array(
'<controller:\w+>/<id:\d+>' => '<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>/<slug:\w+>' => '<controller>/<action>',
'adminproduces/producelist/<slug:\w+>/<id:\w+>' => 'adminproduces/producelist',
'adminrequests/requestlist/<slug:\w+>/<id:\w+>' => 'adminrequests/requestlist',
'userrequest/neworder/<type:\w+>/<slug:\w+>' => 'userrequest/neworder',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
),
every thing ok ,but when i use pagination the created url is not matched with my urlmanger config
this my requested Url:
"/adminrequests/requestlist/digital/status10021"
that match with line 5 of url manger
....
in same page i use
<?php
// the pagination widget with some options to mess
$this->widget('CLinkPager', array('pages' => $pages));
?>
but when run project the link create this link for next pages
"adminrequests/requestlist/status10021?slug=digital&page=2"
insted of "adminrequests/requestlist/digital/status10021?page=2"
why?
can ypu help me please ?
when i manualy type "adminrequests/requestlist/digital/status10021?page=2" in address bar next page loaad correctly....
but pagination dosent make correct links...
Yii's CPagination has route property. You can use this for your need. Something like this:
$pages->route = "adminrequests/requestlist/digital/status10021";
You should usually set the part of url which is before starting pagination part.

Is there a way to create a ZF2 console route with repeat parameters

I'm trying to set up a console route that can accept multiple email addresses.
Basically what I'm wanting is a route that accepts something like:
php public/index.php run-report --email=first#example.com --email=second#example.com
I've tried:
run-report [--email=]
But that will only accept a single address. Once you put in a second --email, it fails to match the route. I can hack it by passing in a comma separated string of email addresses, but I'm looking for a way that will result in an array of values, so that I don't have to parse the parameter myself.
From looking at the source code for the simple Console router (ie. Zend\Mvc\Router\Console\Simple), it doesn't appear that this is available out of the box. The console parameter matching is only written to match unique keys in the route.
However - you could try to use the 'catchall' route type instead.
So for example, use this as your console route:
'test' => array(
'type' => 'catchall',
'options' => array(
'route' => 'test', //this isn't actually necessary
'defaults' => array(
'controller' => 'Console\Controller\Index',
'action' => 'test'
)
)
)
Then you can pass as many --email values as you want, you just have to validate them in the controller.
So running this:
php index.php test --email=test#testing.com --email=test2#testing.com
Can be interpreted in the controller:
print_r( $this->getRequest()->getParams()->toArray() );
Array
(
[0] => test
[1] => --email=test#testing.com
[2] => --email=test2#testing.com
[controller] => Console\Controller\Index
[action] => test
)
This isn't exactly ideal as you can also get the same input by executing this (ie. passing email instead of test as the route) - because it's the catchall:
php index.php email --email=test#testing.com --email=test2#testing.com
So you'll have to validate the params directly in the controller as well.

Yii url management issue

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.

Categories