Spiga

using Zend Framework Language component

by Gabi Solomon

Today i will continue the series of articles on the zend framework and i am going to talk about how i come to use the language component from zend.

The way i decided to go with it is by having a controller plugin that starts the language component and also detects the language.

But first thing first. We need to make the url to allow us to change the language. And to do that i added a new rule in the bootstrap file:
[php]
$route = new Zend_Controller_Router_Route(
‘:language/:controller/:action/*’,
array(
‘language’ => ‘en’,
‘module’ => ‘default’,
‘controller’ => ‘index’,
‘action’ => ‘index’
)
);
$router->addRoute(‘lang_default’, $route);
[/php]
This rule will produce urls like:

http://www.domain.com/en/controller/action

http://www.domain.com/es/controller/action

I decided to go with this type of URL instead of caching or storing the language in the session to not have google consider our pages as duplicate content. I have read that it better to go with subdomains (ex: http://en.domain.com/controller/action ) that with directories but for now i will do it this way.

Now that we are still in the bootstrapfile, we will also add our plugin:
[php]
Zend_Controller_Front::getInstance()->registerPlugin(new GSD_Controller_Plugin_Language());
[/php]

ANd now for the final touch the plugin:
[php]

/**
* Front Controller Plugin
*
* @uses Zend_Controller_Plugin_Abstract
* @category GSD
* @package GSD_Controller
* @subpackage Plugins
*/
class GSD_Controller_Plugin_Language extends Zend_Controller_Plugin_Abstract
{

public function routeShutdown(Zend_Controller_Request_Abstract $request)
{

$locale = new Zend_Locale();

$options = array('scan' => Zend_Translate::LOCALE_FILENAME);
$translate = new Zend_Translate(‘gettext’, Zend_Registry::get(‘siteRootDir’) . ‘/application/languages/’, ‘auto’, $options);

$requestParams = $this->getRequest()->getParams();
$language = (isset($requestParams['language'])) ? $requestParams['language'] : false;
if ($language == false) {
$language = ($translate->isAvailable($locale->getLanguage())) ? $locale->getLanguage() : ‘en’;
}
if (!$translate->isAvailable($language)) {
throw new Zend_Controller_Action_Exception(‘This page dont exist’,404);
} else {
$locale->setLocale($language);
$translate->setLocale($locale);

Zend_Form::setDefaultTranslator($translate);

setcookie(‘lang’, $locale->getLanguage(), null, ‘/’);

Zend_Registry::set(‘Zend_Locale’, $locale);
Zend_Registry::set(‘Zend_Translate’, $translate);
}
}
}
[/php]

A few explanations on the code.
I am using gettext adapter with auto mode … witch will basically crawl the language directory to detect what languages can you support. I also use it conjunction with Zend Locale and at the end i store the in the Registry.
Storing Zend translate in the registry will enable you to use it in the view in a very easy way using a built in helper.

Using translate in you controllers
[php]
$this->view->title = $this->view->translate(‘default-register-index-title’);
[/php]

Using translate in you views
[php]
translate(‘default-register-index-title’); ?>
[/php]

As a note i am not using the full text for translate i am using keys that have a naming conventions like “module-controller-action-message”. I find it much more easier then putting the whole string and also much more easier to maintain. Imagine if you misspelled a string, or want to modify it ? you will then have to modify it every in your code.

That is basically it.
Cheers

Update:
I have also published this plugin on phpclasses, you can find it here.

  • http://codeutopia.net/ Jani Hartikainen

    A good, although not perfect, approach =)

    It would be better if you made the plugin configurable, so that you could define the translation sources easily rather than having to edit the code of the plugin.

    Another thing is that it might be a good idea to attempt detecting the user’s own language from their browser, if no other language is found. I recall Zend_Locale can do that for you.

  • http://www.gsdesign.ro/ Gabi Solomon

    @Jani Hartikainen
    Thanks for the advice. I added the language detection.
    I will try to make time to modify it to take params.

  • Pingback: links for 2008-12-23 « sySolution

  • Pingback: Gabi Solomon’s Blog: Using Zend Framework Language Component : WebNetiques

  • Pingback: Gabi Solomon’s Blog: Using Zend Framework Language Component : Dragonfly Networks

  • Betty

    Thanks for the info.

    What do I need to do so that url’s () on a webpage are automatically like:
    EN/module/controller/action or
    DE/module/controller/action

    depending on the active language?

    At the moment all url’s start with EN.

  • http://www.gsdesign.ro/ Gabi Solomon

    @betty
    if you use the url view helper .. they should be automaticly generated

  • Betty

    @Gabi Solomon

    Right, I just found out:
    url ([array $urlOptions = array()], [mixed $name = null], [boolean $reset = false], [boolean $encode = true])

    $reset should be false.

    But this does not work for following:
    //our-service
    $route = new Zend_Controller_Router_Route(
    ‘:language/our-service/’,
    array(
    ‘language’ => ‘en’,
    ‘module’ => ‘default’,
    ‘controller’ => ‘index’,
    ‘action’ => ‘our-service’
    )
    );
    $router->addRoute(‘our-service’, $route);

    $this->url(array(), ‘our-service’, false)

    Language stays EN even when I ask for DE/our-service.

    For all other links I use the default router.

    And another question, how could I define an url to stay with same url, but just change the language?

    For example, EN/contact should change to DE/contact.

    Thanks for your help!

  • http://www.gsdesign.ro/ Gabi Solomon

    you can make a custom route class and save the language in a session or cookie to be sure that it remembers it.

    and for the second question:
    $this->url(array(‘language’ => ‘DE’), ‘our-service’);

    • http://www.modularhomesnetwork.com/ modular homes

      hello, i read this site and i think it is good idea!

  • Betty

    Gabi, thanks again, your second suggestion works, but now I had to put in every link language => xx.

    About the first one (save the language in a session or cookie to be sure that it remembers it.), at the moment I don’t find it necessary to remember the language in a session.

    But how do I change the current url to the same but with different language:
    EN/contact should change to DE/contact.
    (I don’t know how to do that with dynamic urls)

    Thanks again!

  • Pingback: Routes to support languages - Page 2 - Zend Framework Forum

  • dantan

    Works good so far.
    Using the Url view helper I have good links, IndexController and IndexAction are filtered. But I still have links with the default module inside e.g. /en/default/login instead of /en/login.

    Maybe you have a simple idea hot to get rid of the “default” when not needed.

  • http://www.gsdesign.ro/ Gabi Solomon

    @dantan how are you building your routes ?
    maybe your not using the lang route i described

  • http://ariscarrental.ro/ Jamie

    Very good aproach!

    • http://www.a1webdesigner.com/ Web design Company

      I agree with you Jamie and this is really something special on which we need to ponder over.

  • http://www.omnibet.ro/ Pariuri Sportive

    Well worth the read. Thanks for sharing this information. I got a chance to know about this.

  • http://tipseri.net/clasamente-fotbal/ clasamente fotbal

    thank's for sharing this!it'a great post!

  • http://biletul-zilei.info biletul zilei

    thank's for sharing this!it'a great post!

  • http://www.auto-tip.ro autovit

    It is interesting but it is hard to implement it.

  • http://www.auto-my.com/auto-sales auto sales

    Thanks that you offer that tips but i can use it because i dont know how. Thanks anyway

  • http://www.auto-my.ro/dezmembrari-auto dezmembrari auto

    It is good and very usefoul for us. We must now use it. thanks

  • http://www.pariorul-sportiv.com pariuri sportive

    What you`ve wrote here is very true and can be very usefull for the readers of this site. Have good luck with your site and i`ll be back to read your new informations because i think you have very good information about different subjects. Have a good day.

  • Tausiah
  • http://www.louisvuittonhandbagmall.com/ louis

    Say thanks to you truly for providing plenty of both useful and interesting advise. I will bookmark bookmark your website and will be absolutely coming back. Again, I truly appreciate all your work furthermore providing plenty of worthwhile info for the audience.

  • Pablomoreno61

    Hi, Im using your explanations but something doesnt works for me. How Can I set up the language in my zend_navigation menu? It allways shows the urls like /es/controller/action instead of /xx/controller/action where xx is the selected language

    • Eric P

      I run into the same situation. Did you suceed to solve it ?

      • Eric P

        I succeed to do it by adding the ‘language’ parameter to the Front_Controller:

        $router = Zend_Controller_Front::getInstance()->getRouter();
        $router->setGlobalParam(‘language’, $language);

        @gabi: many thanks for this post.
        Eric.

        • Anonymous

          Thanks also by me, I was searching for this solution!

  • http://www.modularhomesnetwork.com Modular Homes

    Thank you for this great idea!

  • http://www.modularhomesnetwork.com/ Modular Homes

    I happened to stumble across this website researching for something unsimilar, glad I stumbled into it though. Very interesting.

  • http://www.neojogos.com Jogos

    Nice entry! I personally really like your site.