Yogesh Saroya
Yogesh Saroya

Reputation: 1505

How to use internationalization in cakephp with custom URL and extensions

I am using cakephp 2.0 for an application...
everything is fine but I am getting some problem with custom URL or SEO friendly URL.

Here are Route rules that I am using

Router::parseExtensions('html', 'rss', 'xml','json');
    Router::connect('/:language/:controller/:action/*',array(),array('language' => 'eng|chi'));
    Router::connect('/', array('controller' => 'homes', 'action' => 'index'),array('language' => 'eng|chi'));       
    Router::connect('/backend/*', array('controller' => 'users', 'action' => 'login', 'lab' => true));
    Router::connect('/about-us/*', array('controller' => 'homes', 'action' => 'about_us'));
    Router::connect('/contact/*', array('controller' => 'homes', 'action' => 'contact'));
    Router::connect('/:slug', array('controller' => 'homes', 'action' => 'page'), array('pass' => array('slug'), 'slug'=>'[a-zA-Z0-9-]*'));

Here for "about-us", 'contact-us' and 3rd and main one is ":slug" ( dynamic )

Two problems:

  1. When I try to change language, url is showing lang/controller/action ( abc.com/eng/homes/about_us ) instead of abc.com/eng/about-us.html or abc.com/chi/about-us.html
  2. for other dynamic url eg. abc.com/page-1.html, abc.com/page-2.html, abc.com/page-3.html so on... how to use abc.com/lang/slug with .html ( abc.com/eng/page-1.html or abc.com/chi/page-1.html)

For this I am using the

Router::connect('/:slug', array('controller' => 'homes', 'action' => 'page'), array('pass' => array('slug'), 'slug'=>'[a-zA-Z0-9-]*')) 

rule.

Upvotes: 0

Views: 103

Answers (1)

AD7six
AD7six

Reputation: 66237

When i try to change language, url is showing lang/controller/action ( abc.com/eng/homes/about_us )

The route definitions in the question have this first:

Router::connect(
    '/:language/:controller/:action/*',
    array(),
    array('language' => 'eng|chi')
);

Routes are tested in the order they are declared - this route will match any url which has the language eng or chi passed to it, as all urls have a controller and an action this route will always match.

instead of abc.com/eng/about-us.html or abc.com/chi/about-us.html

If there needs to be a route match for /:lang/:slug - then there has to be a route defined matching that pattern - currently there isn't.

for other dynamic url eg abc.com/page-1.html, abc.com/page-2.html, abc.com/page-3.html so on ... how to use abc.com/lang/slug with .html ( abc.com/eng/page-1.html or abc.com/chi/page-1.html)

I don't fully understand the question but the answer is probably to ensure that all routes exist with a prefix and are defined before the routes without a prefix. e.g.:

Router::parseExtensions('html', 'rss', 'xml','json');

// Define Chinese language routes first as they have a prefix
Router::connect('/chi/', ['controller' => 'homes', 'action' => 'index'],['language' => 'chi']);
Router::connect('/chi/backend/*', ['controller' => 'users', 'action' => 'login', 'lab' => true],['language' => 'chi']);
Router::connect('/chi/about-us/*', ['controller' => 'homes', 'action' => 'about_us'],['language' => 'chi']);
Router::connect('/chi/contact/*', ['controller' => 'homes', 'action' => 'contact'],['language' => 'chi']);
Router::connect('/chi/:slug', ['controller' => 'homes', 'action' => 'page'], ['pass' => ['slug'], 'slug'=>'[a-zA-Z0-9-]*'],['language' => 'chi']);
Router::connect('/chi/:controller/:action/*',[],['language' => 'chi']);

// Define English language routes last as they don't have a prefix
Router::connect('/', ['controller' => 'homes', 'action' => 'index'],['language' => 'eng']);
Router::connect('/backend/*', ['controller' => 'users', 'action' => 'login', 'lab' => true],['language' => 'eng']);
Router::connect('/about-us/*', ['controller' => 'homes', 'action' => 'about_us'],['language' => 'eng']);
Router::connect('/contact/*', ['controller' => 'homes', 'action' => 'contact'],['language' => 'eng']);
Router::connect('/:slug', ['controller' => 'homes', 'action' => 'page'], ['pass' => ['slug'], 'slug'=>'[a-zA-Z0-9-]*'],['language' => 'eng']);
Router::connect('/:controller/:action/*',[],['language' => 'eng']);

In this way all routes can be parsed unambiguously, and generated unambiguously too - assuming language is always passed when generating a url; the persist parameter can help with that.

Upvotes: 1

Related Questions