cakePHP router annoying me with pagination system - cakephp

When i enter address: http://www.yourdomain.com/2 (without page:2)
It give you Missing View: (error)
Missing View
Error: The view for PagesController::display() was not found.
Error: Confirm you have created the file: /Users/username/Sites/mycakeapp/views/pages/2.ctp
Notice: If you want to customize this error message, create /views/errors/missing_view.ctp
In router config: (routes.php in config)
$chk = array('page' => '[0-9]');
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
Router::connect('/:page/*', array('controller' => 'pages', 'action' => 'display'), array(
'page' => $chk['page'], 'pass' => array('page')
));
In pages_controller.php:
function display($on_page=1) {
$this->paginate = array(
'limit' => $this->Cookie->read('pagelimit'),
'page' => $on_page,
'order' => array(
'data.dateadded' => 'asc'
));
$data = $this->paginate('data');
$this->set('data', $data);
$this->render(implode('/', $path));
$this->set('title_for_layout', null);
}

Try adding all named parameters to the routes config manually:
Router::connectNamed(array('page'[, ...]);

Like the error message states, you need to have a file called 2.ctp in your pages folder.
Confirm you have created the file:
/Users/username/Sites/mycakeapp/views/pages/2.ctp
The display method in the pages_controller is generally used to display static pages. A file named with the param you send, in your case 2, followed by '.ctp' must exist in the view/pages folder, this is what the error message tells you.
If you where expecting something else, you are not doing it right.

I found problem solved. the answer is:
add in controller page:
$this->render('/pages/home');
no need to add Router::connectNamed

Related

Routing all but certain parameters in CakePHP

I'm trying to set up a routing definition in my project which will allow users to have profiles accessible by simply using their username as the only parameter in the url, like www.example.com/username as opposed to www.example.com/user/view/username
I've set up a catch all route to go to an action which checks if the user exists, as the last route in the config file, and it works, but it over rides all of the basic routing that cake does. Meaning that I would have to define a route for every controller I want to provide access to just to make sure I never make it to the catchall. My routes:
Router::connect('/events/edit/*', array('controller' => 'events', 'action' => 'edit'));
Router::connect('/events/view/*', array('controller' => 'events', 'action' => 'view'));
Router::connect('/events/add', array('controller' => 'events', 'action' => 'add'));
Router::connect('/events/*', array('controller' => 'events', 'action' => 'index'));
Router::connect('/*', array('controller' => 'users', 'action' => 'view'));
So, this will allow me to access my events page, but any other pages get sent to the second router, expectedly.
What I'd like is to have is a route that does the basic cake function of /controller/action/param if the controller exists, but have it fall through to the last route which goes to the user/view page otherwise.
My question is, for what I'm trying to accomplish, am I doing this the right way? If I need to define a route for every controller I want access to, I will, but I have to think there's a better way to accomplish this.
Thanks
According to the my understanding of your question, I think You can proceed like this.
App::uses('UserRoute','Lib');
Router::connect('/:user_name', array('controller' => 'users', 'action' => 'view'),
array('routeClass'=>'UserRoute', 'pass' => array('user_name')));
and in your app/lib create a file UserRoute.php like this
<?php
App::uses('Lib', 'CakeRoute');
class UserRoute extends CakeRoute {
function parse($url) {
$params = parent::parse($url);
if (empty($params)) {
return false;
}
App::import('Model', 'User');
$User = new User();
$user_count = $User->find('count',array(
'conditions' => array('User.username' => $params['user_name']),
'recursive' => -1
));
if ($user_count) {
return $params;
}
return false;
}
}
Hope this will help you..

CakePHP - How to make routes with custom parameters?

My Cake URL is like this:
$token = '9KJHF8k104ZX43';
$url = array(
'controller' => 'users',
'action' => 'password_reset',
'prefix' => 'admin',
'admin' => true,
$token
)
I would like this to route to a prettier URL like:
/admin/password-reset/9KJHF8k104ZX43
However, I would like the token at the end to be optional, so that in the event that someone doesn't provide a token it is still routed to:
/admin/password-reset
So that I can catch this case and redirect to another page or display a message.
I've read the book on routing a lot and I still don't feel like it explains the complex cases properly in a way that I fully understand, so I don't really know where to go with this. Something like:
Router::connect('/admin/password-reset/:token', array('controller' => 'users', 'action' => 'password_reset', 'prefix' => 'admin', 'admin' => true));
I don't really know how to optionally catch the token and pass it to the URL.
You'll want to use named parameters. For an example from one of my projects
Router::connect('/:type/:slug',
array('controller' => 'catalogs', 'action' => 'view'),
array(
'type' => '(type|compare)', // regex to match correct tokens
'slug' => '[a-z0-9-]+', // regex again to ensure a valid slug or 404
'pass' => array(
'slug', // I just want to pass through slug to my controller
)
));
Then, in my view I can make a link which will pass the slug through.
echo $this->Html->link('My Link', array('controller' => 'catalogs', 'action' => 'view', 'type' => $catalog['CatalogType']['slug'], 'slug' => $catalog['Catalog']['slug']));
My controller action looks like this,
public function view($slug) {
// etc
}

Routing with named parameters

I have a URL that contains named parameters, which I want to map to a more user friendly URL.
Take, for example, the following URL:
/videos/index/sort:published/direction:desc
I want to map this to a more friendly URL, like:
/videos/recent
I have tried setting it up in the Router, but it doesn't work.
Code samples from the Router:
Router::connect(
'/videos/recent/*',
array('controller' => 'videos', 'action' => 'index'),
array('sort' => 'published', 'direction' => 'desc'
));
Which doesn't work. And the following also doesn't work:
Router::connect(
'/videos/recent/*',
array('controller' => 'videos', 'action' => 'index', 'sort' => 'published', 'direction' => 'desc'));
Any ideas?
Use get args
The easiest way to have routes work is to avoid named arguments all together. With pagination thats easy to achieve using appropriate config:
class FoosController extends AppController {
public $components = array(
'Paginator' => array(
'paramType' => 'querystring'
)
);
}
In this way when you load /videos/recent you should find it includes urls of the form:
/videos/recent?page=2
/videos/recent?page=3
Instead of (due to route mismatching)
/videos/index/sort:published/direction:desc/page:2
/videos/index/sort:published/direction:desc/page:3
But if you really want to use named args
You'll need to update your route definition - there's no page in the route config:
Router::connect(
'/videos/recent/*',
array(
'controller' => 'videos',
'action' => 'index',
'sort' => 'published',
'direction' => 'desc'
)
);
As such, if there is a page named parameter (which there will be for all urls generated by the paginator helper), the route won't match. You should be able to fix that by adding page to the route definition:
Router::connect(
'/videos/recent/*',
array(
'controller' => 'videos',
'action' => 'index',
'sort' => 'published',
'direction' => 'desc',
'page' => 1
)
);
Though even if it works, you may find it to be fragile.
lets see on [Router::connect documentation](Routes are a way of connecting request urls to objects in your application)
Routes are a way of connecting request urls to objects in your application
So, it's map urls to objects and not url to url.
You have 2 options:
use Router::redirect
Something like that:
Router::redirect( '/videos/recent/*', '/videos/index/sort:published/direction:desc');
but seems that's not that you want exactly
use Router::connect
use normal Router::connect which will connect url to some action which make appropriate scope. Something like that:
Router::connect(
'/videos/recent/*',
array(
'controller' => 'videos',
'action' => 'recent'
)
);
and in VideosController
public function recent() {
$this->request->named['sort'] = 'published';
$this->request->named['direction'] = 'desc';
$this->index();
}
it works and I saw such usage, but not sure, that is will satisfy you too.
as for me, I like normal named cakephp parameters. If such scope (published and desc) is your default state, just code default state in index action. For over cases i think it's normal to use ordinary named parameters.

How to redirect in CakePHP with # in url, and not %23?

I am using CakePHP and I am doing this:
$this->redirect(array('controller' => 'users', 'action' => 'view',$id));
output in the browser: .../users/view/42
Since I am using JQueryUI tabs, I want the user to be redirected to the tab he just edited, so it should looks something like :
$this->redirect(array('controller' => 'users', 'action' => 'view',$id."#groups"));
output in the browser: .../users/view/42%23groups
But expected result: .../users/view/42#groups
Q: How to send a correct url with #id in it to send the focus ?
I want, if possible, not use a custom GET param that echo a js in the view.ctp to get the focus asked.
I hope it is a CakePHP issue and don't need to change some .htaccess like (How to rewrite a URL with %23 in it?)
Please read the documentation
http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::url
$this->redirect(array(
'controller' => 'users', 'action' => 'view', $id, '#' => 'groups'));
This is how I achieved it:
// Redirect to the home page.
$this->redirect(array(
'controller' => 'cars',
'action' => 'index',
'#' => 'thankyou'
));

cakephp named parameters break REST based web service

I have a json REST based in the form of:
Router::mapResources('Test');
Which is equivalent to for the index method to:
Router::connect( '/Test',
array(
'controller' => 'ChannelSources',
'action' => 'index',
'[method]' => 'GET' ),
array();
I am trying to add support for named parameters this method.
but apparently its breaks the Router method as an index action is not part of the URL
i have tried using
Router::connectNamed(array('somenameparam'));
But it failed.
I would create a specific route so that you can pass in the right parameters, then you can pass your params into the route.
Have a look at, http://book.cakephp.org/2.0/en/development/routing.html#passing-parameters-to-action
Router::connect(
'/blog/:id-:slug', // E.g. /blog/3-CakePHP_Rocks
array('controller' => 'blog', 'action' => 'view'),
array(
// order matters since this will simply map ":id" to $articleId in your action
'pass' => array('id', 'slug'),
'id' => '[0-9]+'
)
);

Resources