I need a cakephp route which will catch all urls if not matched in previous routes that do not contain file extensions.
Current route for catch all below
Router::connect('/*', array('controller' => 'frontend', 'action' => 'display',null));
I need the above route modified to not all urls with file extensions to be caught
What I have donr in my app based on CakePHP 1.2 to add extension to dynamic generated images is as follows:
Router::connect('/postImage/*', array('controller' => 'posts','action' => 'postImage', 'url' => array('ext' => 'png')));
The above code makes both the folloing url are accesible:
http://myhost.com/posts/postImage/125
and
http://myhost.com/posts/postImage/125.png
I think that the same will going with CakePHP 1.3 and I hope that It helps you.
I don't understand very well your demand, but you can do this:
Router::parseExtensions('html');
Router::connect('/*/:title', array('controller' => 'frontend', 'action' => 'display',null),
array(
'pass' => array('title')
)
);
And the link:
$html->link('Title', array('controller' => 'frontend', 'action' => 'display', 'title' => Inflector::slug('text to slug', '-'), 'ext' => 'html'))
I hope this will help you. good luck
Related
In my CakePHP, my routes.php file looks like this:
Router::connect('/premios/:category',
array('controller' => 'prizes', 'action' => 'category'),
array(
'category' => '\bmarcas|restaurantes|combustibles|peluqueria\b',
));
This way whenever a user enters the /premios url, the next parameter is matched with the "category" regex. This works perfect.
The problem is that when I want to generate a pretty url for the category, let's say, "peluqueria", using this line of code generates a "non-pretty" url:
Router::url(array('controller' => 'prizes', 'action' => 'category', 'peluqueria')); ?>
Instead of generating a pretty URL (/premios/peluqueria) it generates a non pretty url (/prizes/category/peluqueria).
What am I doing wrong? Or is this a limitation of the Router::url function?
A workaround would be to define every connect, avoiding the regex, but it isn't a pretty as the current solution plus it would get annoying when the categories count start to grow.
Any ideas?
You have to actually name the category parameter in Router::url, like this
Router::url(array('controller' => 'prizes',
'action' => 'category',
'category' => 'peluqueria'));
And you'd probably want to pass that "category" parameter to the category action in Prizes, so you're missing something
Router::connect(
'/premios/:category',
array('controller' => 'prizes', 'action' => 'category'),
array(
'pass' => array('category'),
'category' => '\bmarcas|restaurantes|combustibles|peluqueria\b'
)
);
Look this part of the docs with more detention :)
I use CakePHP 2.4.6.
In routes.php, I put
Router::mapResources('themes');
Then, I can access 'localhost/themes/211' which display screen generated by the action "view" of the controller "themes" just as I expect.
BUt in a view file, I use
<?php
echo $this->Html->url(array(
'controller' => 'themes',
'action' => 'view',
$theme['Theme']['id']));
?>
Then this generate '/themes/view/211' in html, where I expected '/themes/211'.
Does $this->Html->url() generate RESTful URL?
If not, How can Cake view file generate RESTful URL in other way?
Do I do any mistake?
Thanks in advance.
leave the action blank
<?php
echo $this->Html->url(array(
'controller' => 'themes',
'action' => '',
$theme['Theme']['id']));
?>
Or,
<?php
echo $this->Html->url(array(
'controller' => 'themes',
'action' =>$theme['Theme']['id']
));
?>
If you want this to happen, go to your \app\Config\routes.php and add Router::connect('/themes', array('controller' => 'themes', 'action' => 'view'));
You don't have to change
<?php
echo $this->Html->url(array(
'controller' => 'themes',
'action' => 'view',
$theme['Theme']['id']));
?>
You probably have some more Restfull api calls to define, so maybe something more generic:
Router::connect('/api/:controller', array('api' => true, 'action' => 'index', "[method]" => "GET"), array('pass' => array('id'), 'id' => '([0-9]+|me)'));
Router::connect('/api/:controller', array('api' => true, 'action' => 'add', "[method]" => "POST"), array('pass' => array('id'), 'id' => '([0-9]+|me)'));
Router::connect('/api/:controller/:id', array('api' => true, 'action' => 'view', "[method]" => "GET"), array('pass' => array('id'), 'id' => '([0-9]+|me)'));
Router::connect('/api/:controller/:id', array('api' => true, 'action' => 'edit', "[method]" => "POST"), array('pass' => array('id'), 'id' => '([0-9]+|me)'));
These route calls like "api/Themes/123" to the action index in the Themes controller, however, if you try and do a POST request it will route to the add action.
I want to do the following change in CakePHP routes. Any word or group of words (separated by hyphen) after a website URL like example.com/someword or example.com/some-word should be redirected to controller => posts, action => view. But my problem is that the word(s) should be in unicode. I have tried this regular expression for URL text, but it does not work.
Router::connect ( '/:link', array ('controller' => 'posts', 'action' => 'view' ), array ('pass' => array ('link'), 'link' => '/^['.json_decode('"\u0531"').'-'.json_decode('"\u0587"').'-]+$/u' ) );
I want to mention though, that my regex
'/^['.json_decode('"\u0531"').'-'.json_decode('"\u0587"').'-]+$/u',
works just fine if I am about to do some usual preg_match like
$regg = '/^['.json_decode('"\u0531"').'-'.json_decode('"\u0587"').'-]+$/u';
if (preg_match($regg, "my unicode string", $match)) {
var_dump($match); // outputs string as expected
}
die;
EDIT
I end up having this code
Router::connect ( '/:link', array ('controller' => 'posts', 'action' => 'view' ), array ('pass' => array ('link'), 'link' => '((?![a-zA-Z]).)+' ) );
like making my url to contain everything, but English letters, but this is not the thing I need, if I have 2 or more different languages than English - this method won't work. So, I want to send each language's word into separate action.
cake version 2.x
EDIT 2
There are alternative solutions, like in answers below, to bypass the question, but I am looking for the exact way of doing what I need.
Thanks
From http://en.wikipedia.org/wiki/Query_string at URL encoding paragraph you can't use these chars on a url query string:
In particular, encoding the query string uses the following rules:
Letters (A–Z and a–z), numbers (0–9) and the characters '.','-','~' and '_' are left as-is
SPACE is encoded as '+' or "%20" [8]
All other characters are encoded as %HH hex representation with any non-ASCII characters first encoded as UTF-8 (or other specified
encoding)
If you have two (or more) languages you can consider add on posts table one slug field for each language, for example with english and russian:
posts
id
title_eng
title_rus
slug_eng
slug_rus
On Post.php beforeValidate or beforeSave:
if(isset($this->data['Post']['title_eng'])){
$this->data['Post']['slug_eng'] = Inflector::slug(strtolower($this->data['Post']['title_eng']), '-');
}
if(isset($this->data['Post']['title_rus'])){
$this->data['Post']['slug_rus'] = Inflector::slug(strtolower($this->data['Post']['title_rus']), '-');
}
The link inside a view:
echo $this->Html->link($post['Post']['title_eng'], array('controller' => 'posts', 'action' => 'view', 'slug_eng' => $post['Post']['slug_eng']));
echo $this->Html->link($post['Post']['title_rus'], array('controller' => 'posts', 'action' => 'view', 'slug_rus' => $post['Post']['slug_rus']));
The route:
Router::connect('/posts/:slug_eng', array('controller' => 'posts','action' => 'view', 'eng'), array('pass' => array('slug_eng'), 'slug_eng' => '[a-zA-Z0-9]+'));
Router::connect('/ru/posts/:slug_rus', array('controller' => 'posts','action' => 'view', 'rus'), array('pass' => array('slug_rus'), 'slug_rus' => '[a-zA-Z0-9]+'));
The controller Posts:
public function view($locale, $slug){
....
validate and sanitize here
...
$post = $this->Post->find('first', array('conditions' => array('slug_' . $locale => $slug)));
....
}
I suggest to use wildcard
Router::connect('/*', array('controller' => 'posts', 'action' => 'view'));
Any other routes can be added before this line, for example
Router::connect('/:digits', array('controller' => 'posts', 'action' => 'view'), array('pass' => array('digits'), 'digits' => '/d+');
Router::connect('/*', array('controller' => 'posts', 'action' => 'view'));
Similar to this question, I have accomplished passing the format with the url extension, but you have have to declare the parameters passed upfront. Example:
new Zend_Controller_Router_Route_Regex(
'([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)(\.(\w+))?',
array(
'module' => 'Default',
'controller' => 'index',
'action' => 'index',
),
array(
1 => 'module',
2 => 'controller',
3 => 'action',
4 => 'extension',
5 => 'format'
)
);
But what if I want /:module/:controller/:action/*.:format???
So that no matter how many parameters I pass through the url, the '.whatever' will be the format parameter? Basically, I'm trying to take the default router and add extension as the 'format param'.
Edit:
The issue isn't grabbing the extension, the issue is adding other params. For example
/blogs/posts/view/post/500/foo/bar/format/html
will translate into:
array('module'=>'blogs','controller'=>'posts', 'action' => 'view', 'post'=>500, 'format' => 'html', 'foo' => 'bar');
But I want to be able to represent the format the same route like so:
/blogs/post/view/post/500/foo/bar.html
No matter how many parameters are declared between the action and the format.
Your whatever you can specify with .* expression.
To match it - simply: (.*)
If you want not to grab for example extension, use ?:
(.*?)(\.(\w+))
I have been trying to shortern this route:
http://abc.localhost/user/view/index/id/1
to this:
http://abc.localhost/user/1
with the following portion of code in my bootstrap but I keep getting an error stating that the 'Reversed route is not specified', any ideas why?
$route = new Zend_Controller_Router_Route_Regex(
'user/(\d+)',
array(
'module' => 'user',
'controller' => 'view',
'action' => 'index'
),
array(
1 => 'id'
)
);
$router->addRoute('user', $route);
Thanks,
Martin
If you want to use the URL helper with Regex routes you need to pass a 4th parameter to Zend_Controller_Router_Route_Regex that it can use to rebuild the route. This 4th parameter should be a string in a sprintf-format which it can inject the params into.
In your case it would be something like:
$route = new Zend_Controller_Router_Route_Regex(
'user/(\d+)',
array(
'module' => 'user',
'controller' => 'view',
'action' => 'index'
),
array(
1 => 'id'
),
'user/%d'
);
$router->addRoute('user', $route);
There is some info on this right at the end of the manual section on Regex routes: http://framework.zend.com/manual/en/zend.controller.router.html#zend.controller.router.routes.regex - but it's easy to miss.