phpzend-frameworkzend-translatezend-controller-router

Zend translate URL and language switcher


I have managed to make my URL i18n compliant using Zend_Controller_Router.

Ie: en/user/login becomes fr/utilisateur/connexion and both URLs go to the same controller/action.

The problem I am facing is the following

I have a language switcher that is displayed as follow :

Français
English
Italiano
etc.

The currently active language doesn't have an anchor tag, but all others do.

For the languages that have an anchor on them I am building the URL and I want them to be translated in their specific languages.

Currently if I am in French all the urls get builded in french, even if I set the @local key as a param in the URL view helper (tried "@locale" => 'en', "@locale" => new Zend_Locale('en'))

en/utilisateur/connexion
it/utilisateur/connexion

instead of

en/user/login
it/utente/collegamento

because the locale used while building the URL is the one that is defined application wide.

EDIT

I digged a bit deeper in my issue an I found that only the current locale add its resources loaded, which mean I can't get route in the proper language for the route to be built in the right language

My new issue is : how do I load multiple language translation resources?

(I am planning to implement cache in the far future (near release), so I might get better performances)


Solution

  • Hope this helps re the new issue.

    "My new issue is : how do I load multiple language translation resources?"

    Just a quick caveat to say I didn't write the code below, it was taken from a example app put together by the guys at Zend however it might help to have it broken down like this.

    Their approach for the example app was using a csv file containing translations and using your config file (the default one in a new project being application.ini) to specify the path to all your language translation resources.

    like this:

    ;; Languages
    language.file.en = APPLICATION_PATH "/../language/en/translate.csv"
    language.file.fr = APPLICATION_PATH "/../language/fr/translate.csv"
    language.file.de = APPLICATION_PATH "/../language/de/translate.csv"
    language.file.es = APPLICATION_PATH "/../language/es/translate.csv"
    language.name.zz = Language
    language.name.en = English
    language.name.fr = Français
    language.name.de = Deutsche
    language.name.es = Español
    

    And in each csv file, if you are using something like Excel or Open Office to create it, column A would be the original language and column B the translation.

    As an example where English is the original language and a Spanish translation is required:

    A       B
    login   entrar
    logout  salir
    

    You could do that for all the words/phrases you want to translate. If a translation isn't found then the default original word is used.

    Your main application bootstrap could have something like this:

    protected function _initLanguage()
    {
        $options = $this->getOptions();
        Zend_Registry::set('language',$options['language']);
        $langSess = new Zend_Session_Namespace('language');
        if (!isset($langSess->translate)) {
            $translate = new Zend_Translate('csv', $options['language']['file']['en']);
            $langSess->translate = $translate;
        }
        if (!isset($langSess->locale)) {
            $langSess->locale = 'en';
        }
        Zend_Locale::setDefault($langSess->locale);
    } 
    

    As the translate object is held in the session you can use it in any of your views etc using something like:

    $langSess = new Zend_Session_Namespace('language');
    $translate = $langSess->translate;
    

    and:

    <a href="/user/login"> <?php echo $translate->_('login') ?> </a>
    

    where you want something to be translated on selecting an alternative language. In the example above the word login would appear when English is selected and entrar when Spanish is selected.

    There's loads more to Zend_Translate than this and several ways to implement it so I'm not saying this is the best way by any means.

    If it helps or if I can give you more info let me know.

    Cheers,

    Dave