I want to rewrite my url in YII to make url seo friendly .
The URL in my current system is
http://mysite/recipe/recipedetail/1
and i want to make it like
http://mysite/recipename
how i can do it
i am trying ot use rule but they are not working my rules in config/main files are
'url.rules' => array(
'recipe/<recipename:([A-Za-z0-9-]+)>/' => 'recipe/recipedetail/<recipename:\w+>/',
),
You may try this:
'recipe/recipedetail/<id:\d+>'=>'recipe/recipedetail',
A route part of rule must not contain parameters, but must be in controller/action format:
'url.rules' => array(
'recipe/<recipename:[A-Za-z0-9-]+>/' => 'recipe/recipedetail',
),
All named parameters will be available in $_GET, so inside your controller action you can access recipename value with $_GET['recipename]`.
Additionaly, please mention that you must not wrap parameter pattern ([A-Za-z0-9-]+ in your case) in brackets.
I guess you're missing var_name in your url
'recipe/<recipename:([A-Za-z0-9-]+)>/' => 'recipe/recipedetail/var_name/<recipename:\w+>/'
get the recipename inside your controller using var_name
Related
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 notice that when you use URL:::action, and set some arguments, sometimes laravel would cast them as GET requests, sometimes not.
Is there anyone know why and how to controller it?
echo URL::action('Campaign\\CampaignController#getIndex',['para' => 1]),"<br>";
echo URL::action('Campaign\\CampaignController#getOtherAction',['para' => 1]),"<br>";
echo URL::action('Campaign\\CampaignController#getOtherAction2',['para' => 1]),"<br>";
Output:
/campaign?para=1
/campaign/other-action/1
/campaign/other-action2/1
Note the getIndex gets argument as GET (?para=1)
This happens because system cannot differentiate requests to getIndex from others if they pass it as url segment.
Means
/campaign/other-action/1 translates to other-action as a method with 1 as param
By your expectation
/campaign/other-action/1 translates to getIndex as a method with other-action/1 as param
Index methods are not suppose to have URL segments as inputs. If you need url segments as inputs then you will have to pass it as a get parameter and thats what laravel is doing for you.
According to your first route output,
if the url is /campaign/1 which means it will expect a method named get1. Another example: if the url is /campaign/param system would expect a method getParam
NOTE for fellow stackoverflow-ers:Consider asking questions before downvoting
I actually found the reason.
when you are using route::controllers method, laravel would assume you have multiple parameters attached to each action
Route::controllers([
'order' => 'Order\OrderController',
'campaign' => 'Campaign\CampaignController'
]);
For example:
campaign/other-action/{VALUE1?}/{VALUE2?}/{VALUE3?}...
So when you pass ['para' => 1, 'para2' => 'abc'], laravel will try to match parameters to action. in this case: campaign/other-action/1/abc
Avoiding to use Route::controllers, an help you take control on laravel router argument behaviour.
For example, in routes.php:
Route::get('campaign/other-action/{id}','Campaign\CampaignController#getOtherAction2')
when you give
echo URL::action('Campaign\\CampaignController#getOtherAction2',['id'=>366, 'para' => 1, 'para2' => 'abc']);
you will get what you want:
campaign/other-action/366?para=1¶2=abc
I hope it is helpful and I now understand why laravel remove Route::controllers from 5.3 version.
Regarding the use of named routes, these 2 lines allow me to access the same page so which is correct?
// Named route
Route::get('test/apples', array('as'=>'apples', 'uses'=>'TestController#getApples'));
// Much simpler
Route::get('apples', 'TestController#getApples');
Is there any reason I should be using named routes if the latter is shorter and less prone to errors?
Named routes are better, Why ?
It's always better to use a named route because insstsead of using the url you may use the name to refer the route, for example:
return Redirect::to('an/url');
Now above code will work but if you would use this:
return Redirect::route('routename');
Then it'll generate the url on the fly so, if you even change the url your code won't be broken. For example, check your route:
Route::get('apples', 'TestController#getApples');
Route::get('apples', array('as' => 'apples.show', 'uses' => 'TestController#getApples'));
Both routes are same but one without name so to use the route without name you have to depend on the url, for example:
return Redirect::to('apples');
But same thing you may do using the route name if your route contains a name, for example:
return Redirect::route('apples.show');
In this case, you may change the url from apples to somethingelse but still your Redirect will work without changing the code.
The only advantage is it is easier to link to, and you can change the URL without going through and changing all of its references. For example, with named routes you can do stuff like this:
URL::route('apples');
Redirect::route('apples');
Form::open(array('route' => 'apples'));
Then, if you update your route, all of your URLs will be updated:
// from
Route::get('test/apples', array('as'=>'apples', 'uses'=>'TestController#getApples'));
// to
Route::get('new/apples', array('as'=>'apples', 'uses'=>'TestController#getApples'));
Another benefit is logically creating a URL with a lot parameters. This allows you to be a lot more dynamic with your URL generation, so something like:
Route::get('search/{category}/{query}', array(
'as' => 'search',
'uses' => 'SearchController#find',
));
$parameters = array(
'category' => 'articles',
'query' => 'apples',
);
echo URL::route('search', $parameters);
// http://domain.com/search/articles/apples
The only reason to name the route is if you need to reference it later. IE: from your page in a view or something, check whether you are in that route.
I have the following method that performs an Ajax request passing some dynamic value obtained from a select input.
It works fine, but the dynamic value is passed as parameter in the URL, something like states/listCities/?big_string_of_serialized_parameter .
$this->Js->event(
'change',
$this->Js->request(
array( #url
'controller' => 'states',
'action' => 'listCities'),
array( # ajax options that generates the serialized parameter
'update' => '#DealerCityId',
'data' => '$("#DealerStateId").serialize()',
'dataExpression' => true
)
)
);
I'm trying to do this in a more friendly URL way, something like states/listCities/2.
It's possible in CakePHP to generate a friendly URL like this with dynamic value from a input or is only possible passing the dynamic values as parameters?
As far as I understand it's not possible. You could pass an ID as third parameter in the URL array, but as the ID is not known at template generation time, it's not applicable in this situation. If you want to use JsHelper, you'll have to stick with the JavaScript code generation it provides.
As an alternative, you could write your own Helper: Derive it from JsHelper and override the request() method to suit your needs. You can probably take the source code of the original source code to get a head start and only modify the way the data parameter is used in code generation.
I would like to be able to match a URL like this
www.site.com/cc/[action-name-first-part].12345.[action-name-second-part]
Basically the resulting action would be a concatenation of the 2 action name.
My current route looks like this
$ccRoute = new Zend_Controller_Router_Route_Regex(
'cc/([^.]).([^.]).([^.]*)',
array('controller' => 'cc'),
array('action-first-part' => 1, 'arbitrary-number' => 2, 'action-second-part' => 3)
);
this partner matches fine. but with the third argument (mapping argument), how can I concat the 1 and 3 index and just pass the correct action to the controller.
Thanks.
As far as I remember, you cannot do this with the regex routes. However, it's quite trivial to make a new route class that can do this.
Here is a quick answer on how to make your own route class.
how to get dynamic URL like mydomain.com/username using zend framework