CakePHP 2.3 pagination named args - cakephp

I create schema for my pagination:
Router::connect(__('news') .'/'. __('paginate') .'/:page', array(
'controller' => 'news',
'action' => 'index'), array(
'persist' => array(
'language')));
But 'named' params is still empty in Controller
My question is How to preapre router to work with pagination by links like this: news/paginate/4, news/paginate/5, etc...
I use Cake 2.3

You cannot used named params in routes.
Unrelated, you don't need the second argument true in calls to __() since 2.2. Check the API.

Related

make custom url pagination in cakephp

i m new in cakephp
first time load url like this
http://domain.com/td/city
http://domain.com/td/ is a static
city is a dynamic
in pagination the url display like
http://domain.com/controller/action/city/page:2
but i m want url like this in pagination
http://domain.com/td/city/2
please help me to solve this
UPDATE:
i don't want "controller", "action" and "page:" keyword in url
my routes define is
Router::Connect('/td/:city/*',
array('controller' => 'properties', 'action' => 'citybasedproperties' ),
array('city' => '[a-z0-9-]+', // regex again to ensure a valid city or 404
'pass' => array('city') // I just want to pass through city to my controller
));
http://www.website.com/post/page:2
we would like to change it to
http://www.website.com/post/page/2
1. /app/Config/routes.php
Add or modify the existing route to
Router::connect('/post/page/:page', array(
'controller' => 'post',
'action' => 'index'
), array(
'pass' => array(
'page'
),
'page' => '[\d]+'
));
2. /app/Controller/PostsController.php
Add or modify the existing controller to
public function index($page = 1) {
// ...
$this->request->params['named']['page'] = $page;
// ...
}
3. /app/View/Posts/index.ctp
Add or modify the existing view to
$paginator->options(array(
'url'=> array(
'controller' => 'post',
'action' => 'index'
)));
You should read this post SEO Friendly URL in CakePHP Pagination
Read the Routing chapter of the documentation it covers that case with an example and explains how routing in CakePHP works. I suggest you to actually read and try to understand the whole page and not just copy and paste the examples.

How to redefine the URLs generation without changes at the HtmlHelper#link(...) calls in CakePHP?

I have a CakePHP website with many internal links, that are build with the HtmlHelper:
/app/View/MyController/myaction.ctp
<?php
echo $this->Html->link(
$item['Search']['name'],
array(
'controller' => 'targetcontroller',
'action' => 'targetaction',
$profileId,
$languageId
)
);
?>
It works fine with the default route:
/app/Config/routes.php
Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
The generated links look like that: /mycontroller/myaction/$profileId/$languageId.
Now I want to use search engine friendly URLs (with profile names and ISO-639-1 language codes instead of IDs) for a part of the website and added a new Route:
/app/Config/routes.php
Router::connect(
'/:iso6391/:name.html',
array('controller' => 'mycontroller', 'action' => 'myaction'),
array(
'iso6391' => '[a-zA-Z]+',
'name' => '[0-9a-zA-ZäöüßÄÖÜ\-]+',
)
);
And it also works fine and the incomming URIs like /producer/en/TestName.html are interpreted correctly.
But the HtmlHelper is still generating the old URIs like /mycontroller/myaction/1/1.
The docu says:
Reverse routing is a feature in CakePHP that is used to allow you to easily change your URL structure without having to modify all your code. By using routing arrays to define your URLs, you can later configure routes and the generated URLs will automatically update.
Well, the HtmlHelper gets a routing array as input, that means: I'm using the reverse routing.
Why does it not work? How to make the HtmlHelper generate the new URLs (without changing the HtmlHelper#link(...) calls)?
Bit of explanation first
You are technically not using reverse routing. You see, the output link, /mycontroller/myaction/1/1 definitively doesn't match /iso/name.html. Like, in no way. So, the routing skips that rule because it doesn't apply.
Code
Try this
echo $this->Html->link(
$item['Search']['name'],
array(
'controller' => 'targetcontroller',
'action' => 'targetaction',
'iso6391' => $someStringWithIso,
'name' => $someName
)
);
But for that, you have to change your routing a bit, because you are not passing the parameters (check the docs for examples)
Router::connect(
'/:iso6391/:name.html',
array('controller' => 'mycontroller', 'action' => 'myaction'),
array(
'pass' => array('iso6391', 'name'),
'iso6391' => '[a-zA-Z]+',
'name' => '[0-9a-zA-ZäöüßÄÖÜ\-]+',
)
);
And you have to mind the first string match /:iso6391/:name.html. Do you want to match this route to every controller and action in your project, or just the one controller and the one view. If it is for all projects, just for precaution, use this
/:controller/:action/:iso6391/:name.html
if is just for, say, Controller1 and action "view", use
/controller1/view/:iso6391/:name.html
The detail you need to consider is the extension you use .html, is that really necessary in the url? If it is, add it as a parameter in the Html#link
echo $this->Html->link(
$item['Search']['name'],
array(
'controller' => 'targetcontroller',
'action' => 'targetaction',
'iso6391' => $someStringWithIso,
'name' => $someName
'ext' => 'html'
)
);
and also add parseExtensions to the routing file. Read this. Would be easier if you don't add the extension, but that's up to you.
In the end, you still have to change your calls to Html->link...

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.

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]+'
)
);

CakePHP routing - search parms

I need to set up routing based on search parms (I'm using CakeDC search plugin)
URL should look like this: /apartments/studio-apartments
instead of this: /apartments/propertytype_id:1
I've already tried adding routes like this one:
Router::connect('/apartments/studio-apartments', array('controller'=>'apartments', 'action'=>'index'), array('pass'=>array('propertytype_id:1')));
or
Router::connect('/apartments/studio-apartments', array('controller' => 'apartments', 'action' => 'index', 'propertytype_id:1'));
or that one from Cake book
Try this in your routes.php:
Router::connect('/apartments/studio-apartments',
array('controller' => 'apartments','action' => 'index'),
array('propertytype_id' => '[0-9\-]+')
);

Resources