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
Related
We have some site example.com and I want to make routes for different cities (eg.
example.com/city1, example.com/city2).
We also want to show all other controllers and methods for the current city (eg.
example.com/city1/:controller/:action, example.com/city2/:controller/:action).
This will look like 2 or more different sites that use the same methods in the controllers but will display different info according to the city.
A router prefix won't work for us, because there could be more than 10 cities, and it must use the same methods in the controllers.
We can add cities from the admin panel.
How can we make routes that will take cities from the database and display all the links properly?
Router::connect('/:city/:controller/:action/*', array());
Router::connect('/:city/:controller/*', array());
This will add a prefix to your routes, but all your URLs will be affected. There is probably an easier way too.
Instead of having example.com/users/login, you will need to have example.com/New-York/users/login.
If you want to generate all these links, let us know what kind of controllers and methods you have.
The routes I pasted work for any prefix (city name)
I'd suggest you change your url scheme a little bit, use
example.com/cities/city1 instead of example.com/city1. This change is not only making it easier for routing/rewriting, but it will also rule out the possibility of you adding a city that will accidentally have the same name as a controller!
(Of course there will be some way to keep your original naming scheme, but it will be harder to implement and have the risk of a collision with a controller name)
Once you've got the /cities part in there you can do something like this (sample code taken from CakePHP Routing and not tested, just to give you an idea):
// routes.php
Router::connect(
'/cities/:city/:controller/:action/:id',
array(),
array(
// order matters since this will simply map ":id" to
// $articleId in your action
'pass' => array('id', 'city'),
'id' => '[0-9]+'
)
);
in your controller:
public function view($articleId = null, $city = null) {
// some code here...
}
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')
)
);
}
I have a search form.
The form values are passed to query and results are displayed as expected.
I am using Cakes built in pagination methods.
On the initial search, I need the url to reflect the search path values as when I use the sort() or Next >> pagination methods.
When I use sort() or Next >>, my url is formatted with the paginator structure like:
// pagination to Next page note Page 2
...plans/search/55/22/1/0/33758/page:2
When I do the first search I get url:
...plans/search/
Here are the appropriate fragments of my search action:
function search(
...
// query and other action code here unrelated to pagination
...
// start of applicable array and pagination code
$url = array('controller' => 'plans', 'action' => 'search');
$this->paginate = $options; // $options is my query
$this->set('searchdetails', array_merge($url, $searchdetails)); //$searchdetails isi any array of the values entered in the search input boxes. Joining my url and search details.
$this->set('plans', $this->paginate('Plan'));
I tried to break down the above to ONLY include what is applicable to my problem.
NOTE: I am running a default "order" through this action in my query and its working fine, but is not reflected in the url.
I need to know how to update the url to reflect the initial search input results. I have ALL of the array data passed to my view just fine.
I tried recreating the path with a rather large method I wrote, but it did nothing but complicate my problem...
Is there a simple Cake type solution for this? Or is this just not in Cakes cards currently?
Please set me straight on this.
Have you tried
echo $this->Form->create(null, array('url' => $this->passedArgs));
How do I make cakephp website URL SEO friendly? Is there a plugin available for cakephp 1.2.6
First define what you mean by "SEO friendly".
Most likely this just means you want to add the name of your "object" to the URL, i.e. add a slug. You can do that without any plugin:
echo $html->link($record['Model']['name'], array(
'controller' => 'foo',
'action' => 'bar',
$record['Model']['id'],
Inflector::slug($record['Model']['name'])
));
// -> /foo/bar/42/the-name
If you require any more customized URLs, first specify what exactly you need, then use Routing to create these custom URLs.
it's the only way to do it wothut any trouble...
but if you don't like id in the url, then you should take a title, remove all symbols, replace spaces with -, and write to the datebase...
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'