cakephp routing with language sub directory - cakephp

I am generating a link (this is for when the language is set as "fre"):
$html->link('About', array('controller' => 'pages', 'action' => 'about', 'language'=> 'fre')) ;
I also have a sub directory for languages [eng|fre] as shown above this can be either languages:
I am routing like so:
Router::connect('/:language/:controller/:action/*',
array(),
array('language' => 'eng|fre'));
// this worked before the language subdomain
Router::connect('/about',array('controller'=>'pages','action'=>'about'));
the problem I have is, I want the urls to be:
/eng/about
/fre/about
but obviously they are coming out as:
/eng/pages/about
/fre/pages/about

I think hypothetically this should work
Router::connect('/:language/about',array(
'controller'=>'pages',
'action'=>'about',
'language' => 'eng|fre'
));
EDIT: If all 20 are pages you could try something like
Router::connect('/:language/:action',array(
'controller'=>'pages',
'action' => 'about|contact|something|else',
'language' => 'eng|fre'
));

This allows you to use any 3-character language code for any page:
Router::connect(
'/:language/:controller/:action/*',
array(),
array('language'=>'[a-z]{3}')
);

Related

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...

cakephp: multilingual routing

I have such a link:
<?=$this->Html->link(__('Kontakt'), array('controller' => 'contacts', 'action' => 'show', 'language' => $this->Session->read('Config.language')));?>
My route looks like this:
Router::connect('/kontakt', array('controller' => 'contacts', 'action' => 'show', 'language' => 'deu'));
This way I get such a link in browser:
domain.com/kontakt (german is my base language)
Now I want the other languages as well, therefore I transport the language flag with the url in order to get this:
domain.com/eng/contact (all languages except german need this language shortcut)
I have this route
Router::connect('/:language/kontakt', array('controller' => 'contacts', 'action' => 'show'),
array(
'language' => 'eng|spa|fre|rus'
));
This creates my nicely urls like:
/spa/kontakt or /eng/kontakt or /fre/kontakt
I wonder now, how I can set the the translated words into the routes, without having a single line for each translation? Is there a way to make it somehow dynamic?
Thanks!
Use the translation methods, just like in any other place:
Router::connect('/' . __d('routes', 'kontakt'), array('controller' => 'contacts', 'action' => 'show', 'language' => 'deu'));
The issue with that is that you don't set the language dynamically which will cause that the translation works but what ever "kontakt" will become is going to be routed to /deu/.
You must set the language dynamically to the route, not static as you do or you'll still have to add each language manually to the routes. If you prefer to do that I would check conditionally what language is active and load a separate route file depending on the language.

CakePHP 2.x i18n route

There is some solution for using CakePHP route with params only when are not empty?
Now I code below, but I would like some better:
if(Configure::read('Config.language') !== 'en') { // en is default language
$language = '/:language';
} else {
$language = '';
}
Router::connect($language .'/'. __('register', true), array(
'controller' => 'users',
'action' => 'register'));
This code works perfectly, but I still must set language in AppHelper by url() method.
In older apps I was always duplicate Router::connect:
Router::connect('/:language/'. __('register', true), array(
'controller' => 'users',
'action' => 'register')); // for all languages without default language
Router::connect('/'. __('register', true), array(
'controller' => 'users',
'action' => 'register')); // only for default language (en)
Maybe there is simplest solutions?
You need to use 2 routes but add the 'persist' option for your language based routes. Adding 'persist' will avoid having to specify 'language' key each time when generating urls.
// for all languages without default language.
Router::connect(
'/:lang/'. __('register', true),
array(
'controller' => 'users',
'action' => 'register'
),
array(
'persist' => array('lang')
)
);
// only for default language (en)
Router::connect(
'/'. __('register', true),
array(
'controller' => 'users',
'action' => 'register'
)
);
You might also want to checkout CakeDC's I18n plugin.
Ok, these things work better, but I still other problem.
I set default language by Configure::write('Config.language'); to en in bootstrap.php
Next i wrote shema for url like this:
Router::connect('/:language/'. __('register', true), array('controller' => 'users', 'action' => 'register'), array('persist' => array('lang')));
Router::connect('/'. __('register', true), array('controller' => 'users', 'action' => 'register'));
And when users change language by beforeFilter in AppController (set new Config.language) will content from static .po and db worsk perfeclty, but links not translated.
Parametr :language works but magic function __() in Router:connect() not works.
Because first loaded is bootstrap.php, next is router.php and last is AppController.php
My question is, how to force router.php to translate links (__())?
Sorry, but still learn english...

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

how to use i18n for one language cakephp

I need to launch a web app in spanish for the moment and I need to translate the app...
I already modified the default.po and added configure::write('Config.language', 'es') to the core.php...
what now? I don't want to add routing rigth now. Any suggestions?
PD: did everything as it is in the manual and ##$%^&%$## I cant get it to work
i18n is a tricky one to get your head around. If you're producing a website that will just be in Spanish, there is no need to use it, but I do use po messages as a matter of course, just in case.
There is a component that will help you a lot: http://bakery.cakephp.org/articles/p0windah/2007/09/12/p28n-the-top-to-bottom-persistent-internationalization-tutorial
There also used to be a script that would allow translation of slugs so that SEO would direct you to the right language. Last time I looked, it had vanished, but I'll try to piece it together for you.
For the moment, this is what I used in router.php
//route to switch locale
Router::connect('/lang/*', array('controller' => 'p28n', 'action' => 'change'));
//forgiving routes that allow users to change the lang of any page
Router::connect('/eng?/*', array(
'controller' => "p28n",
'action' => "shuntRequest",
'lang' => 'en-gb'
));
Router::connect('/ca?/*', array(
'controller' => "p28n",
'action' => "shuntRequest",
'lang' => 'cat'
));
Router::connect('/es?/*', array(
'controller' => "p28n",
'action' => "shuntRequest",
'lang' => 'es_es'
));
I'll dig around for the url translation, but it may take a while....

Resources