I have a search form which, if someone fills it in and there are no results to report, I want to make them aware of that but then show them a result set of my choosing. The problem is that when I show them this result set of my choosing and I use the paginator helpers for prev/next they want to pass the search term which is in my URL along with the page number.
That obviously causes problems because there isn't a page:2 for the results search:termHasNoResults
How can I stop the paginator helper passing my search variable in the URL when I'm showing them my alternative result set?
Thanks
Use
$this->Paginator->options('url' => array(
'controller' => 'YOUR CONTROLLER', 'action' => 'YOUR ACTION', 'OTHER PARAMS');
You can pass 'url' option to pagination in your view like this:
$url = array_merge($this->request->pass, $this->request->named);
unset($url['page']);
$parts = explode('?', $_SERVER['REQUEST_URI'], 2);
if (count($parts) == 2) {
$url['?'] = $parts[1];
}
$this->Paginator->options(array(
'url' => $url,
));
More here: http://api.cakephp.org/2.2/class-PaginatorHelper.html
and here: http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::options
If you widely use filters and additional url params - make an element which will handle it for you
Related
Im working on a php project and first a have a value on url for example :
http:www.c/com/app.php?doctor_id=12
And then i want to add an another value on that url without losing the doctor id
For example : http:www.c/com/app.php?doctor_id=12?appoin_date=11pm
Also when i get the doctor id it redirects the appoin page :)
Do not generate a URL-encoded query string yourself. Use the http_build_query function for this. The function also takes over the necessary escaping of the parameters. Example:
$url = 'http:www.example.com/app.php';
$parameters = [
'doctor_id' => 12,
'appoin_date' => '11pm',
'name' => 'max&moritz'
];
$url .= '?'.http_build_query($parameters);
//"http:www.example.com/app.php?doctor_id=12&appoin_date=11pm&name=max%26moritz"
I wanted to ask, about strategy, how can i archive this:
I have url: www.mydomain.com/pages
Now, if some if clausure will return true, i want attach this param to all urls:
www.mydomain.com/pages?id=swa or
www.mydomain.com?id=swa
I have no idea how to start,
Thank You for help.
Your best bet would probably be to use a URL filter, it will affect all URLs that are being generated using the core helpers or the Router class, as long as they are being passed as routing arrays, ie
['controller' => 'abc', 'action' => 'xyz', /* ... */]
URLs passed as strings, like /abc/xyz will not be affected!
\Cake\Routing\Router::addUrlFilter(function ($params, $request) {
$key = 'id';
$value = 'swa';
if (!array_key_exists($key, $params)) {
$params[$key] = $value;
}
return $params;
});
This would add the parameter to all URLs (unless they already have that parameter set). But be careful, in case there is a matching connected route that defines a route element with the same name, it will steal the parameter and use it for the element instead of adding it to the query string!
Also note that this will only affect form actions that do explicitly define an action URL, if you'd wanted it to affect the ones that pick up the current URL too, then you'd also have to modify $request->query
$request->query[$key] = $value;
See also
Cookbook > Routing > Creating Persistent URL Parameters
API > \Core\Routing\Router::addUrlFilter()
If it is a one off you can do that using redirects
return $this->redirect(['controller' => 'Pages', 'action' => 'display', $pageId]);
or via html helper
echo $this->Html->link(
'Page 1',
['controller' => 'Pages', 'action' => 'display', 1]
);
I am trying to redirect and go to a specific element on the new page like this:
http://192.168.0.49/x/y/index.php/admin/user/update/id/3#certificate
$this->redirect(array('update', 'id' => $certificate->user_id));
How can this be done?
You can simply create the url without the fragment part and then append it manually:
$url = Yii::app()->createUrl('update', ['id' => $certificate->user_id]);
$url .= "#certificate";
$this->redirect($url);
This code works in a manner that is immediately obvious when reading the code. Apart from that there is also the Yii-specific solution: CUrlManager (the component responsible for building URLs) also recognizes # as a parameter. So you can write:
$url = Yii::app()->createUrl(
'update',
['id' => $certificate->user_id, '#' => 'certificate']
);
That can't be done using redirect.
A work around would be
$url = Yii::app()->createUrl('update', array('id' => $certificate->user_id, '#' => "certificate"));
$this->redirect($url);
I'm new to cakephp...and I have a page with a url this:
http://localhost/books/filteredByAuthor/John-Doe
so the controller is ´books´, the action is ´filteredByAuthor´ and ´John-Doe´ is a parameter.. but the url looks ugly so i've added a Route like this:
Router::connect('/author/:name', array( 'controller' => 'books','action' => 'filteredByAuthor'), array('pass'=>array('name'),'name'=>".*"));
and now my link is:
http://localhost/author/John-Doe
the problem is that the view has a paginator and when i change the page (by clicking on the next or prev button).. the paginator won't consider my routing... and will change the url to this
http://localhost/books/filteredByAuthor/John-Doe/page:2
the code on my view is just:
<?php echo $this->Paginator->prev('<< ' . __('previous', true), array(), null, array('class'=>'disabled'));?>
the documentation doesn't say anything about avoiding this and i've spent hours reading the paginators source code and api.. and in the end i just want my links to be something like this: (with the sort and direction included on the url)
http://localhost/author/John-Doe/1/name/asc
Is it possible to do that and how?
hate to answer my own question... but this might save some time to another developper =) (is all about getting good karma)
i found out that you can pass an "options" array to the paginator, and inside that array you can specify the url (an array of: controller, action and parameters) that the paginator will use to create the links.. so you have to write all the possible routes in the routes.php file. Basically there are 3 possibilities:
when the "page" is not defined
For example:
http://localhost/author/John-Doe
the paginator will assume that the it's the first page. The corresponding route would be:
Router::connect('/author/:name', array( 'controller' => 'books','action' => 'filteredByAuthor'),array('pass'=>array('name'),'name'=>'[a-zA-Z\-]+'));
when the "page" is defined
For example:
http://localhost/author/John-Doe/3 (page 3)
The route would be:
Router::connect('/author/:name/:page', array( 'controller' => 'books','action' => 'filteredByAuthor'),array('pass'=>array('name','page'),'name'=>'[a-zA-Z\-]+','page'=>'[0-9]+'));
finally when the page and the sort is defined on the url (by clicking on the sort links created by the paginator).
For example:
http://localhost/author/John-Doe/3/title/desc (John Doe's books ordered desc by title)
The route is:
Router::connect('/author/:name/:page/:sort/:direction', array( 'controller' => 'books','action' => 'filteredByAuthor'),
array('pass'=>array('name','page','sort','direction'),
'name'=>"[a-zA-Z\-]+",
'page'=>'[0-9]*',
'sort'=>'[a-zA-Z\.]+',
'direction'=>'[a-z]+',
));
on the view you have to unset the url created by the paginator, cause you'll specify your own url array on the controller:
Controller:
function filteredByAuthor($name = null,$page = null , $sort = null , $direction = null){
$option_url = array('controller'=>'books','action'=>'filteredByAuthor','name'=>$name);
if($sort){
$this->passedArgs['sort'] = $sort;
$options_url['sort'] = $sort;
}
if($direction){
$this->passedArgs['direction'] = $direction;
$options_url['direction'] = $direction;
}
Send the variable $options_url to the view using set()... so in the view you'll need to do this:
View:
unset($this->Paginator->options['url']);
echo $this->Paginator->prev(__('« Précédente', true), array('url'=>$options_url), null, array('class'=>'disabled'));
echo $this->Paginator->numbers(array('separator'=>'','url'=>$options_url));
echo $this->Paginator->next(__('Suivante »', true), array('url'=>$options_url), null, array('class' => 'disabled'));
Now, on the sort links you'll need to unset the variables 'sort' and 'direction'. We already used them to create the links on the paginator, but if we dont delete them, then the sort() function will use them... and we wont be able to sort =)
$options_sort = $options_url;
unset($options_sort['direction']);
unset($options_sort['sort']);
echo $this->Paginator->sort('Produit <span> </span>', 'title',array('escape'=>false,'url'=>$options_sort));
hope this helps =)
I am trying to use a drop down input in my cakephp application, with this I want the drop down on submit to render the url like so:
www.example.com/cake/FILE/VALUE
However the only url i can get the select input to create is the following:
www.example.com/cake/FILE?form_value=VALUE
How do I go about making the URL SEO friendly like the first example without using httaccess because I want the URL to appear seo friendly in the search engines eyes.
Here is the code I am using.
In The VIEW
echo $form->input('form_value', array(
'label' => '',
'type' => 'select',
'options' => $listOfOptions,
'selected' => '0',));
Thank you.
In your controller, get the value of "form_value" through $file = $this->data['FILE']['form_value'] and do a redirect $this->redirect(array('action' => 'download', $file)).
You then create a function called download which should look like this:
<?php
function download($file = null) {
if ($file != null) {
/*make download*/
} else {
$this->Session->setFlash('no file specified')
}
?>
If you don't want the action "download" to appear in the URL you can use Cakes built-in routes in cakephp/app/config/routes.php.
With something like this you could map the index-action to the download-action:
Router::connect('/FILE/*', array('controller' => 'files', 'action' => 'download'));
See http://book.cakephp.org/view/46/Routes-Configuration for better explanation.