File Translation for dummies

Hello Yii folks,

i’m having some problems in implementing file translations in my webapp… i’m sure there is something that i miss, so i post this to try to get any help.

My app has two language sets, it (italian) and en (english). I can use the Yii::t() method to translate successfully messages and labels but i can’t work with view translation.

Here is the scenario:

I have set Yii::app()->language() to the current language (it is done in a preloaded component).

here is the code:


<?php

class LangComponent extends CComponent

{

    function init()

    {

        $app = Yii::app();

        if (isset($_POST['_lang']))

        {

            $app->language = $_POST['_lang'];

            $app->session['_lang'] = $app->language;

        }

        else if (isset($app->session['_lang']))

        {

            $app->language = $app->session['_lang'];

        }

    }

}

?>

So now i have my app set to the current language, when i call t() in fact all translations are made just fine according to the language being used.

I will expect to have my app also looking for language subdirectories into the view folders and to use them when available. For example i have this folder structure in the app:

protected/views/mail/it

protected/views/mail/en

there are stored views used with the mail extension. The problem is that the app only looks in mail folder and not in language subfolders when looking for mail views. I would expect my app to go into the ‘it’ or ‘en’ folder to look for views but nope.

I hope i’ve been clear enough to address the problem. I’m sure i miss something, and i will be grateful to whoever will spend 2 minutes explaining where the problem is.

I hope this thread will be useful also to people experiencing my same problem.

Thanks in advance!

Which sourceLanguage did you specify in config?

/Tommy

Well, in my config file i just set


'language' => 'it',

to set it as the default language. I didn’t set any sourceLanguage attribute.

I thought, wrongly i guess, that this was enough to set the initial language to ‘it’ and

thus letting the app look for a ‘it’ subdir into the views.

I didn’t get very well the use of sourceLanguage indeed.

I just set the default language prop and went on creating the two subdirs ‘it’ and ‘en’ into the messages folder…

It appeared to work correctly until now, with this file translation issue.

Thanks for your help!

the function stack when resolving a layout file is (usually) as follows, content render through renderPartial is similar.

CController::render -> CController::getLayoutFile -> CController::resolveViewFile -> CApplication::findLocalizedFile

So the code that in the end is responsible for choosing between regular views and localized views is as follows

base/CApplication.php




  /**

   * Returns the localized version of a specified file.

   *

   * The searching is based on the specified language code. In particular,

   * a file with the same name will be looked for under the subdirectory

   * named as the locale ID. For example, given the file "path/to/view.php"

   * and locale ID "zh_cn", the localized file will be looked for as

   * "path/to/zh_cn/view.php". If the file is not found, the original file

   * will be returned.

   *

   * For consistency, it is recommended that the locale ID is given

   * in lower case and in the format of LanguageID_RegionID (e.g. "en_us").

   *

   * @param string the original file

   * @param string the language that the original file is in. If null, the application source language is used.

   * @param string the desired language that the file should be localized to. If null, the application language will be used.

   * @return string the matching localized file. The original file is returned if no localized version is found

   * or if source language is the same as the desired language.

   */


  public function findLocalizedFile($srcFile,$srcLanguage=null,$language=null)

  {

    if($srcLanguage===null)

      $srcLanguage=$this->sourceLanguage;

    if($language===null)

      $language=$this->getLanguage();

    if($language===$srcLanguage)

      return $srcFile;

    $desiredFile=dirname($srcFile).DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.basename($srcFile);

    return is_file($desiredFile) ? $desiredFile : $srcFile;

  }



resolveViewFile passes only one parameter to this function, so application defaults are used. Source language is only used to compare, so if the current language setting is the same as the sourceLanguage setting then the normal view will be utilized, otherwise it will test for existance in a subdirectory which is case sensitive(on *nix servers, maybe windows). If case sensitivity is not an issue i would add some variable dumping in the above mentioned function stack starting with findLocalizedFile to determine how yii is choosing your view file. The functions are all short and mostly straight forward.

Hope this information helps

I’ve been reading the documentation and all related posts and I still don’t get it :-[

I have a simple website based on the default webapp where all pages are static. There are only two languages, English (en) and Spanish (es).

In config/main.php I have:




// This is the main Web application configuration. Any writable

// CWebApplication properties can be configured here.

return array(

...

    'sourceLanguage'=>'en',

    'language'=>'es',

...



In protected/views/site I have two subdirectories:

-> protected/views/site/en

-> protected/views/site/es

In each subdirectory I have a localized index.php:

-> protected/views/site/en/index.php (content in English)

-> protected/views/site/es/index.php (content in Spanish)

actionIndex() in SiteController.php is unmodified because I understand the render() method eventually calls findLocalizedFile() which should find the correct file according to the settings in config/main.php.




	public function actionIndex()

	{

		$this->render('index');

	}



Therefore I expect that the initial page displayed be in Spanish, but it’s not. Instead, I get an ugly error:




CException

Descripción

SiteController no ha podido encontrar la vista "index" solicitada.

Archivo Fuente:

/home/content/.../framework/web/CController.php(807)



The error messages are displayed in Spanish, so the application knows what the target language is. I haven’t created any customized message translations (in protected/messages/e{n|s} or whatever) yet.

What am I missing? Any help is greatly appreciated.

Hi, do you have an index view in the

protected/views/site/ directory?

maybe the system is looking there for your spanish view.

For what i understood so far the localized views for the sourceLanguage

are to be found in the "root" view dir, while translations for other supported

languages are to be found in the "en" or "es" subdir under your views dir.

So if you’re writing your app in spanish and plan to add support for english at a latter

time you should set sourceLanguage to spanish, put spanish views into the root view folder

(i mean protected/views/site/ in this case) and the add views in the en directory with translated

content.

for example i have:




'sourceLanguage' => 'it_it',

'language' => 'it', 



in my main.php config and then i have

my italian views in: view/mail/

my english views in: view/mail/en

hope this helps, but i must say i’m not totally confident yet with the

localization framework, so if anybody finds my approach is wrong then any further

explanations will be welcome!

suerte y feliz yii coding!

ivan

Thank you, that fixed it!

Instead of two directories “es” and “en” under site, I moved the Spanish content to the root view directory and just kept the “en” directory for the English content. Then fixed ‘sourceLanguage’=‘es’ and will switch ‘language’ between ‘es’ and ‘en’ upon user request.

The documentation and all I had read were not very clear on this issue, I thank you again for your help.

you’re welcome!

Thank you :)