CakePHP Routes with forward slash in argument - cakephp

I have started using cakePHP and have a little problem using routes. I'm trying to make some kind of catalog for products (e-shop without shopping :)) and like to have urls like "http://site.net/main_category/subcategory/subsubcategory-c154.htm" where -c means category and 154 is an Id of specified category. I like to pass this type of URLs to one controller, say CategoriesController but the route:
Router::connect('/:categoryUrl',
array(
'controller' => 'categories',
'action'=> 'display'
),
array(
':categoryUrl' => '(.*)-c([0-9]+).htm'
)
);
doesn't working. It keeps searching for "main_category" controller as main_category is after first slash.
Have you guys (ladies too of course ;)) have some idea?
Thank's a lot
kraklin

You probably need to escape the hyphen. It's listed as one of the characters escaped by preg_quote(). And you definitely need to escape the dot.
'(.*)\-c([0-9]+)\.htm'

Related

Anchor tags in cakephp

My codebase is built in Cakephp.
I have an update button which processes a "notes" field. I have a working controller update/write that redirects back to the page, so the "hard" bit is done...
However: from a usability point of view, this redirects to the raw URL, and hence to the top of the page every time.
The <input> field has an id, so I simply want to link back to it using an anchor tag.
Here's what works [controller]:
$this->redirect('/review/index/'.item->getEmployeeId());
I tried to add in the following:
$this->redirect('/review/index/'.$item->getEmployeeId().'#'.$item->getEmployeeId());
However - this seems to be stripped out... The write still works, but the anchor is stripped out.
For debugging/quick gotchas: I have tested the raw URL out and it redirects to the <input>.
Is there another way to do this? I'm assuming this is some cakephp "magic" and I simply don't know how to apend an anchor. Some google searches and poking in the API don't seem to clear things up though.
Many thanks.
Following: http://book.cakephp.org/2.0/en/controllers.html#Controller::redirect
Use this:
$url = array(
'controller' => 'review',
'action' => 'index',
$item->getEmployeeId(),
'#' => $item->getEmployeeId()
);
$this->redirect($url);

CakePHP customize Router URL order

I'm using CakePHP to one of my project. When I was designing the URL, I know CakePHP does well when I use
$this->Html->Link('Add Post', array('controller'=>'posts', 'action'=>'edit', 1234))
CakePHP will generate URI /appname/posts/edit/1234. But what I'm thinking /appname/post/1234/edit is better than the former one. I couldn't find a solution to workaround with it.
I've tried
$this->Html->Link('Add Post', array('controller'=>'posts', 1234, 'action'=>'edit'))
but CakePHP will ignore the order of array.
Does anyone know how to achieve this URL? Basically I don't want to modify function Router::url, what I need is to write code in my ctp view file and CakePHP to know the right order I put. How can I do that?
BTW, I'm using CakePHP 2.3.
This is a job for routing, more specifically reverse routing : http://book.cakephp.org/2.0/en/development/routing.html
In app/Config/routes.php you could add something along the lines of the following:
Router::connect(
'/:controller/:id/:action',
array('controller' => 'posts', 'action' => 'edit'),
array('id' => '[0-9]+')
);
Here, you tell Cake to reverse route any request coming from the edit method of the posts controller by defining the order of pre-route named parameters. In your view, the link should be constructed like this:
echo $this->Html->link('Add Post', array(
'controller' => 'posts',
'action' => 'edit',
'id' => 1234
));
Note the extra id parameter being passed that we assigned in routes.php. The Url should look like:
http://appdomain.com/posts/1234/edit
In my humble opinion, this is considered bad practice both from a conventional and SEO standpoint.

Configuring CakePHP 2.0 routing for domain/parameter (without controller name)

I would like to be able to route something like the following in CakePHP 2.0:
domain.com/london
domain.com/milton keynes
to a specific controller and action.
The application has multiple controllers so it should only use this route if the parameter provided doesn't match a controller name.
I achieved this with CakePHP 1.3.12 by adding the following code to the bottom of config/routes.php
Router::connect(
'/:location',
array('controller' => 'articles', 'action' => 'testing'),
array('pass' => array('location'), 'location' => '[a-z ]+')
);
Using this code with CakePHP 2.0 only works if I comment out the require line from config/routes.php, but then I loose the default routes so that a URL pointing at any other controller is caught by this.
How can I achieve the desired routing?
As far as I know this shouldn't work in Cake 1.3 either, simply because your [a-z ]+ regex also matches the case for a simple /controller_name route; the Router has no way to distinguish between the two and will thus always route to the one it encounters first.
You can, however, create a custom route class to achieve this. Mark Story (one of the Cake devs) wrote an excellent post about it quite some time ago, it's for Cake 1.3 but you can easily apply the principle to 2.0 (I know 'cause I'm using it in my 2.0 app). You can the find the post here.
This might not answer the specific question asked above, but it's relevant, this page comes up in search results, and my goal is to save whoever finds it (including future me I guess) some time on not having to research what I just researched.
I needed to add routing with a parameter for a different domain. For example, example.com should behave as usual, while example.org/some_page should route directly to a specific controller and action. So I've added the following to my Config/routes.php:
if ( CakeRequest::host()=='example.org' ) {
Router::connect('/:my_variable',
array(
'controller'=>'my_controller',
'action'=>'my_action'
),
array(
'my_variable'=>'[a-zA-Z-0-9 ]+',
'pass'=>array('my_variable')
)
);
}

CakePHP Routes: Isolating passed parameters in strings

I'm trying to set up routing for my CakePHP application.
One example of a URL I want is /:slug-c-:id/. (EG example.com/foo-c-1/)
This URL is supposed to have two passed parameters: :slug and :id.
However, CakePHP sees the two parameters as :slug-c and :id.
I tried separating the route like this :slug\-c-:id, but then when I use the HTML helper to build a URL, it includes the \ in the string it builds. (EG example.com/foo\-c-1/
Is there another way to separate passed parameters from other strings? Something like PHP's This is a string with a {$var}adjacent to letters
I found a somewhat hacky solution that I'd rather not use, but basically I set up my route as:
/:slug-:cslug-:id/* and set :cslug's regular expression to c
The problem with this is every time I set up a URL with HTML helper I have to do
array(
'controller' => 'products'
'action' => 'index'
'slug' => 'Foo'
'cslug' => 'c'
'id' => 1
)
make it /:slug-:id/ and set the regex for slug to include that '-c'.
I'm not entirely sure you can set greedy regex for slug with an id at the end. Also, if you use Inflector to create slug (which is the recommended way), it would create slug with underscores. So I think it's better to use '_c' instead. The regex should be something along the line [A-Za-z0-9_]+_c
More here: http://book.cakephp.org/view/945/Routes-Configuration

CakePHP, URLs, and SEO

I was explaining to our SEO specialist that cakephp url structure is domain/controller/view/params
so to view a particular product the URL might be something like this:
example.com/products/show/product-name-slug
This would then map to the show function on the products controller with the product-name-slug as a parameter so it could render the correct product page.
He thought this was good but asked if I could name the controller p and the view d so the url would then be:
example.com/p/d/product-name-slug
Since this would make the appropriate keywords (product-name-slug) have a higher ratio over the entire url.
I understand where he is coming from, from a SEO perspective but this make no sense from a programming perspective giving controllers and views single letter names.
Does the ambiguous controller/view names in the URL make that much of a difference? If so, what would be a good compromising solution?
having additional route in configuration:
example.com/seo/product-name-slug would make code and SEO person happy
Router::connect(
'/seo/:slug',
array('controller' => 'products', 'action' => 'show'),
array(
'pass' => array('slug')
)
);
It makes a big difference what is in your URL. I never ever used the default URL structure of CakePHP. It is good to have it by default, but it would make an unacceptable constraint.
Cake wouldn't be worthy to be called a framework if it couldn't map actions to arbitrary URLs http://book.cakephp.org/2.0/en/development/routing.html#route-elements
You can even match regexp to actions:
Router::connect(
'/:controller/:year/:month/:day',
array('action' => 'index', 'day' => null),
array(
'year' => '[12][0-9]{3}',
'month' => '0[1-9]|1[012]',
'day' => '0[1-9]|[12][0-9]|3[01]'
)
);

Resources