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.
Related
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.
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
I've been tasked with rewriting an existing website with large pre-existing link catalog. For argument's sake, let's assume we can't do anything that would change the link catalog. Here's a few examples of the link structure we're working with:
An item page would be:
www.domain.com/widgets/some-totally-awesome-large-purple-widget
A category sub page page would be:
www.domain.com/widgets/purple-widgets
A category parent page page would be:
www.domain.com/widgets/
A custom page may be:
www.domain.com/some-random-page
The various page types are too numerous to write individual Routers for.
Using Router::connect I can easily account for the first and second scenarios using something like:
Router::connect('/{:pageroot}/{:pagekey}', 'Pages::index');
In turn, the Pages::index method looks for entries in our database with the "key" of '/widgets/purple-widgets'.
However, the framework defaults to the '/{:controller}/{:action}/{:args}' route for pages like the third and fourth. I know that this is the correct behavior for the framework. Also, best practice would state that I should write the site to match this behavior. But, that isn't an option here.
What I need is a Router that would allow the third and fourth examples to function the same as the first. All examples should be sent to the Pages::index controller, which in turn queries a database using the URL path as a key.
If you don't have any convention in the URL for what is what, between page, item and category. I'd go with a very generic router.
Router::connect('/{:category}/{:page}/{:item}', 'Pages::any');
Router::connect('/{:category}/{:page}', array('Pages::any', 'item' => null));
Router::connect('/{:category}', array('Pages::any', 'page' => null, 'item' => null));
And in Pages::any() to search for the correct stuff. Is that category a page after all (example 4)? Is that page an item (example 1)?
or
You store the URL somewhere (e.g. a mapping table in the database) and use the pattern version of a lithium Route.
Router::connect(new Route(array(
'pattern' => '#^/(?<path>.+)$#',
'params' => array('controller' => 'pages', 'action' => 'any'),
'keys' => array('path' => 'path'),
// extra stuff, if the path is `tata`, it skips this route and uses
// any of the following ones that matches.
'handler' => function($request) {
if ($request->params['path'] == 'tata') {
return false;
} else {
return $request;
}
}
)));
From that point, you'll get the full URL.
You probably should write a smart Router Helper which is maybe able to process your request based on your db defined routes.
Take a look into: net/http/Router.php
especially connect(), parse() and match()
I would start to write some kind of anonymous function and progress it to a testable Class which is located in /extension.. ?
Im using "Zend form". What should I do to get correct "action" parameter in my FORM tag?
For example, the form Form_Search used in SearchController in indexAction. Where and how should I set the action parameter to form to make it "/my/app/directory/search/index"?
Update: "action" parameter should be the same as the form will assume if not set. I just need the param in FORM to simplify JS coding.
You can use setAction method of Zend_Form, e.g.:
$yourForm->setAction('/my/app/directory/search/index');
Hope this is what you are looking for.
EDIT:
You can retrieve many info about the request, in an action, using $this->getRequest() method that returns an instance of Zend_Controller_Request_Http. For example, if to get basePath and everything between the BaseUrl and QueryString you can do:
$infoPath = $this->getRequest()->getPathInfo();
$basePath = $this->getRequest()->getBaseUrl();
$yourForm->setAction($basePath . $infoPath);
Zend_Controller_Request_Http has other methods that might be useful to you.
You can use the url() view helper to create your action urls.
$view->url(array(
'module' => 'mymodule',
'controller' => 'mycontroller',
'action' => 'myaction',
'param1' -> 'myvalue1',
// etc
), 'default');
// 'default' here refers to the default route.
// If you specify a custom route, then that route will be used to
// assemble() the url.
Depending where you call $form->setAction(), you can access to the $view in different ways.
In the controller: $this->view
In the form itself: $this->getView()
In a view script: $this
In view helper extending Zend_View_Helper_Abstract: $this->view
Hope it helps!
Just an addition to previous answers. Kind of "industry standard approach" is to render/validate/process the form all on the same page. Then there is no need to set the action as it's filled with current URL.
Exception is for example serch field in layout. Then use $form->setAction($url). But always remember to echo the form in the search action. If the form value is invalid, ZF would expect you to render it in page with the errors. Or you can use $form->getErrors().
`$this->setAttribs(array(
'accept-charset' => 'utf-8',
'enctype' => Zend_Form::ENCTYPE_URLENCODED,
'method' => 'get',
'action' => '/controller/action/param/attr'
))`
let's say i have:
http://some-domain/application/controller/action/parameter
This is somehow working in cakePHP. Now I want to now what exactly 'parameter' is. But inside the Model. How to get to this information?
I have to say that there is a formular including a 'Next' Button and I want to validate the input inside of the Model in beforeValidate(). But I have to know on which page the user was at the time of clicking the submit button. This page is 'parameter'.
Router::getParams() is available from everywhere and gives
[plugin] =>
[controller] => leads
[action] => step1
[named] => Array()
[pass] => Array()
[url] => Array(
[ext] => html
[url] => someurl/post-1
)
http://api.cakephp.org/2.3/class-Router.html#_getParams
There are two type of parameter in CakePHP, you have passed parameters and named parameters. A passed parameter is as shown in your example and will be passed as part of the url.
http://example.com/controller/action/passed_param
echo $this->params['passed'][0] // 'passed_param'
http://example.com/controller/action/name:param
echo $this->params['named']['name'] // 'param'
I would recommend getting the parameters in your controller and calling model methods with them passed through.
Such as
$this->Model->find('all', array('conditions'=>array('id'=>$this->params['passed'][0])));
As to how it's working, you will want to have a look at your routes file. In your app/config/routes.php you will find all the routing and which parts are passed.
The standard cake url format is usually as follows, as you'll see in the routes.
array('controller'=>'MyController', 'action'=>'MyAction', 'MyParam');
I can't seem to find a specific page in the book on Params, but have a google around for guides.
Model (in MVC design pattern) shouldn't have direct access to any external variables. The proper way is to pass that variable as a parameter from Controller or View:
$myModelObj->doSth($getParameter);