CakePHP: language switching and urls - cakephp

What is the best approach for implementing multilanugage site in CakePHP:
1) http://nuts-and-bolts-of-cakephp.com/2008/11/28/cakephp-url-based-language-switching-for-i18n-and-l10n-internationalization-and-localization/
2) http://cakedc.com/pierre_martin/2010/08/05/i18n-routes-with-cakephp-1-3
3) Or something else?
Thanks!

3) For a website that i worked on, i was asked to translate the url and the pages but REALLY translate the url, for example the urls should be:
[EN]
www.mysite.com/products
[ES]
es.mysite.com/productos
[FR]
fr.mysite.com/produits
I guess this improves SEO when someone makes a search in a specific language.
To achieve this, I stored the language in the session and i my routes were something like:
Router::connect(__('/products',true), array('controller' => 'products', 'action' => 'index'));
(Hmm now that i think about it... i dont even need to store the lang in Session because i know the language to display by reading the subdomain.)
And if you want to, you can store a cookie to save the preferred language for the user. To change the language, you only need to redirect the user to the corresponding subdomain. (but it will be tricky,but not impossible, if you want to redirect him to the same page he was in but in a different language)
Seems to me that this was a really simple way to translate urls.
Hope this helps

Related

ui-router and angular-translate working together

I read different SO posts and blog posts about that question but none of them answered my questions.
Here's what I have:
Angular-translate is activated to find the preferred language, store it in localstorage/cookie and use that to translate the page.
Most people are trying to do this the other way around: someone enters a URL like domain.com/en/pagename.
I do not care about the locale in the url (although it can be there, i really don't care).
Here is what I'm trying to do:
But an important thing would be to translate the title in there for SEO and user-friendly purposes. Having:
domain.com/find-a-car/
domain.com/trouver-une-voiture/
domain.com/ein-auto-finden/
or
domain.com/en/find-a-car/
domain.com/fr/trouver-une-voiture/
domain.com/de/ein-auto-finden/
Any suggestions to achieve that ? Knowing that the page title should be dynamic, coming from the locale-??.json files !

Multiple languages in cakephp issue

I am trying to get a multilingual site up according to this tutorial:
http://nuts-and-bolts-of-cakephp.com/2008/11/28/cakephp-url-based-language-switching-for-i18n-and-l10n-internationalization-and-localization/
Things look good in terms that clicking on a switch-language link works. However, when you first come to the site, i would like it to go to the default language example.com/eng/ instaed of just being example.com/.
Basically, for SEO purposes, I don't want my site to have non-lingual content, should always have the language in the url.
How could I do that and also go through the function that saves the language in session/cookie?
thanx
Looking at the article, all you should need is a simple check for the 'language' param in the URL:
function beforeFilter() {
// check and perform a redirect
if (empty($this->params['language'])) {
$this->redirect(array('language' => 'eng'));
}
// the following method sets any cookies
$this->_setLanguage();
}

CakePHP routing syntax

How do I do a simple route in CakePHP?
I need that each and every URL will be routed by swapping the action and the controller.
I just couldn't understand the placeholders syntax.
Example:
/files/read/3
to
/read/files/3
-- supplemental --
In my application I use aliases for the controllers.
and I want to route every url that have a certain keyword, as an action, to a certain controller.
I also want to provide the original controller name as a parameter.
Here is a 1:1 example:
There are to alises: fruits and streets.
The keyword that I want to catch in the action is find.
The new controller name is finder.
The following calls match my condition:
/fruits/find/apple/red and /streets/find/longer
The router should catch these urls and convert them, to:
/finder/fruits/apple/red(or supply the parameters in other way, I don't mind) and /finder/streets/longer
How should it be done?
Here is the line of code that you need to put in /app/config/routes.php:
Router::connect('/:action/:controller/*', array('controller' => ':controller', 'action' => ':action'));
Know more: As you can see from the CakePHP book, there are some 'reserved' patterns for routing configuration. An example would be what I used in the line above: :action and :controller. These patterns allow you to tweak routes extensively.
Beware: changing the order of controller and actions in urls might have unintended consequences in the functionality of other CakePHP features. I haven't tested thoroughly, but this is just a general warning.
Beware: Also, I noticed that you put in your example: /files/read/3. Maybe this was just some dummy example, but if you indeed plan to have an MVC named as 'file', be advised that it will conflict will CakePHP core classes (e.g. File model will conflict with File class).
Anyway, hope this answer helps you well. And I really like how the change of controller and action names make the url more readable. :D

Reverse Routing Slug-Based URL in CakePHP

(I know there's a couple of other reverse-routing-slugs questions on this site, but I'm not having much luck relating the answers to my particular issue, so I'll ask my more specific question...)
I am building a site whose URLs now need to be slug-based, i.e. what was initially news/item/1 now has to have the URL news/firstnewsitem. And so on for a number of other controllers. I can easily get these addresses to work, and maybe even not stomp on my existing utility actions, with something like:
Router::connect('/:controller/:slug',
array('action'=>'item'),
array('pass'=>array('slug'), 'slug'=>'[^(index|add|edit|view|delete)]')
);
However, the reverse routing of these new links seems to be a non-starter: Cake is still generating such links as news/item/3. It seems optimistic to hope that a slug-based URL would automagically happen, but is there any array that I can pass in my Html->link parameters that will create the :controller/:slug format I'm looking for? Or do I have to cut my losses and back away from reverse routing at this point?
There's a pretty decent plugin for handling slug-based routing here:
https://github.com/jeremyharris/slugger
If you used this, you would be able to create links something like this
$html->link("some item", array(
'controller'=>'items',
'action'=>'view',
'Item'=>$item['id']
));
and that would output a link to /items/view/slug-for-your-item

Dealing with Alias URLs in CakePHP

I am rewriting our company website in cakephp, and need to find a way to do the following:
A user enters our site by using one
of the promotional alias URLS that
has been pregenerated for a specific
media advert ( magazine, web
promotion etc )
The URL is checked against a
database of alias URLs, and if an
alias exists, then a specific
tracking code is written into the
session.
I have considered several options, none of which seem suitable for this purpose. They are:
Putting the lookup script in the
beforeFilter() in appcontroller, so
that its included in every
controller. (Writes a session value
so it only perfoms once.)
This option only works for existing contollers, and gives the
Cake 'missing controller' error if a
URL doesn't exist.
Specific routes for each alias in
Routes.php - Works but there are
potentially hundreds of alias urls
added/removed regularly via admin
interface.
Route all site URLs to their own
actions, and having an 'everything
else' rule, for the alias URLs that
maps to my lookup script. - Messy
and I lose the built in Cake
routing.
Custom 404. - I don't want to
return 404's for these urls, as I
feel its bad practice unless they
really don't map to anything.
I really could do with a place in the application flow where I can put this lookup/tracking script, and I'm fairly new to cake so I'm stumped.
EDIT: Also, I know that a subfolder called say 'promo' would easily do this, but I have a lot of legacy URLS from our old site, that need handling too.
Note: I'm making an assumption that your promo URLs are in the form of "domain.com/advert-259" or something like that (i.e. no "domain.com/adverts/advert-259'). That would be just too simple :)
Hopefully, you can use the routing with some regex. Add this to your /config/routes.php and let me know if a different regex will help :)
$controllers = Configure::listObjects('controller');
foreach ($controllers as &$value)
{
$value = Inflector::underscore($value);
}
Router::connect('/:promo', array('controller' => 'promos', 'action' => 'process'), array('promo' => '(?!('.implode('|', $controllers).')\W+)[a-zA-Z\-_]+/?$'));
Now you can handle all your promo codes in PromosController::process().
Basically, it checks for a promo code in url, excluding those in the $controllers array (i.e. your regular routes won't be messed up).
Later on you might want to consider caching the value of Configure::listObjects() depending on the speed of your app and your requirements.
A very interesting question. I think I would use item #3. It's not really that messy -- after all, this typically is handled by the pages controller in my stuff. That's how I'd handle it - hardcode your routes to your controllers in routes.php, then have a matchall route that will work for your promo codes. This allows you to keep legacy URLs, as well as use a lot of the standard cake stuff (you probably will just have to explicitly state each of your controllers routes, not such a chore...) Additionally, it will let you do some cool stuff with 404 errors -- you can put some logic in there to try and figure out where they were trying to go, so you can superpower your 404's.

Resources