Module Language

Hi Softark,

yes, your explanation is very clear and actually the 3 uses cases are helpful to understand how to use ‘sourceLanguage’ and ‘Language’ configuration settings in Yii.

What I notice is that the definition of these 2 parameters in the Yii tutorial is, let’s says, too simple, in particular to handle cases like the ones you presented.

The Yii tutorial says that :

It is obiouvsly not true for the first example, where you don’t set the ‘sourceLanguage’ so it is assumed to be ‘en_us’ when in fact it is ‘ja’.

Then of course the third example is even more obvious as the ‘sourceLanguage’ is set to ‘ja’ or to an imaginary language ‘foo’, when it should be in fact ‘en_us’… and this is just to force Yii to perform translation to ‘ja’ (the language that your module uses).

Again, the solution you provide is working fine, but in my opinion this looks like a trick, a hack or anyway far from the tutorial simple definition of what ‘sourceLanguage’ is.

One solution would be to define a “category sourceLanguage map” in the configuration file that would map a translation category, with the actual source language used by this category. For instance, if your module uses category ‘softark’, and if I want to use it in my own webapp,(fr) I would write in the configuration file :




	'sourceLanguage' => 'fr',  // the 'real' source language

	'language'   	=> 'fr',  // the 'real' target language

	'categorySourceLanguage'  	=> array(

		'softark' => 'ja'   // the 'real' source language of your module

	),



With this map, Yii::t() would be able to translate any string from your module …




echo Yii::t('softark','こんにちは、世界 !!');



… into the target language : french (of course, if you provide a french message file).In my opinion this would be much more “clean” than playing with imaginary ‘foo’ language ;)

Anyway, this is just an idea…

Again thank your very much for your explanation.

ciao

B)

tl;dr ;) but couldn’t you try to set the application’s sourceLanguage in the init() method of that module?

Hi Mike,

I don’t think it would help because the sourceLanguage applies to the whole webapp (it is member of CApplication) and not to a module, so the 3 uses cases softark presented are still valid and you’ll have to play with sourceLanguage/language values again.

Apart from the ‘category source language’ map above, another solution would be to not use t() as a static method, but (for instance) as a member of CComponent. Of course sourceLanguage would also become member of CComponent ( language would stay in CApplication) and you could call :


$this->t('my_category', 'hello world');

ciao

B)

But you do set the sourceLanguage of the complete app - but only if the module is active (= a module action was requested):




// In your module's init():

Yii::app()->sourceLanguage = 'en';

Or is your question about how to create the message catalogues in this case?

Ok but in this case, once the module is initialized, all calls to Yii::t() would consider that the sourceLanguage is then ‘en’ (to follow your example). So what happen if the module makes a call to another module (that would be written in another source language) ?

… or call some piece of code outside of itself ?

… or maybe in another module that itself (that would redefine the sourceLanguage) ? …

(and I’m not even talking about reloaded modules ;) )

What about extensions ? I mean, to take a module as example is ok, but my concern is with any third party component included in a webapp. Imagine I have plenty of friends all around the world, each one with a single goal in life : provide the best component (widgets, etc …) to my great webapp :)… and possible to the whole Yii community. Each one should be able to use its own sourceLanguage, and the host webapp should be able to take that into account.

Well, your examples show, that in this situation things are a bit out of your control. As a rule of thumb i would state:

  • If you create an extension (which could also be a module) that contains text, use ‘en_us’ as source language if you want to make it easy for others to use your extension

  • If you write an application that will use extensions (which could also be a module) that contain text, then use ‘en_us’ as your sourceLanguage to make your life easy

:)

In fact, English is the most convenient language, not just for the native speakers but also for all the rest.

If I ever want to provide some translations of my work, the first one should be "en_us", because it will be the most useful one. And, I will be sure to swap the roles of "ja" and "en_us": I will rewrite my source in English and create a translation in Japanese. It will make it much easier for others to create other translations.

BTW, what "tl;dr" stands for?

TL;DR = Too Long; Don’t Read :)

It usually marks the summary of a really long text/post so that if people don’t want to read the long text, they can skip to the summary.

I think it’s natural to write in English, not only for the default source language, but also for the code: function names, comments, etc.

I mean: PHP is based on English, as is every other programming language (SQL included).

I see, thanks. :)

As jacmoe said - but in this case rather “too long, didn’t read” - which means that i’m a lazy bone and hate to read lengthy posts. BTW it’s my belief that real languages behave much like programming languages in this regard: The experienced programmer (or speaker, writer) will use less code (or words) to express the same information :P.

:-[

[EDIT] You are right.

Sorry softark, that was no offense - everybody can use as many words (or code) as he/she likes, of course. It’s just my personal opinion/preference.

Ok, en_us then, but I’m still not convinced (even if I do understand your points).

‘en_us’ Maybe the best option, but what is sure, is that english is far from being mastered by everyone (including myself). I definitly prefer a good source code in native language that will be translated later in other languages by people who feel confortable, than some strange, approximative, low quality english-like dialect that noone (including the author after 6 month) will be able to understand and less to translate.

But ok, en_us then… and thank for participating to this discussion ;)

ciao

B)

Don’t worry, Mike. I’m not offended.

I would rather want to be too verbose than to be too concise, in order to say what I want. But I agree, the shorter the better in general.

anyway Softark, your explanation was very intresting and complete … it did help me a lot. Thanks

8)

Dear Raoul

I hope you remember me, Since I have given a PM to you when you initially made this post.

That time I just downloaded some user management modules(or extensions) and istalled them.

Some of them have intrinsic message translation files for very few languages.

What all I needed was just to add one line in CWebModule::init method.




Yii::app()->language='de';



After that tranlation messages all over the application in German.

I felt that since these extensions strictly adhered to the modular architecture of YII,once language setting

changed they started to look into the message files available inside the module itself.

What can we do when modules or extensions failed in localizing the message files?.

How we can we force the a module to look into a particular messages folder that may reside in the other module?.

Let us have a module with an id sunlight.

Now when this module is instantiated, we are going to change the language to fr.

modules/sunlight/SunlightModule.php




class SunlightModule extends CWebModule

{

	public function init()

	{

		$this->setImport(array(

			'sunlight.models.*',

			'sunlight.components.*',

		));


		Yii::app()->language="fr";//SETTING THE LANGUAGE

	}

.............................



Now we can create the folder messages in sunlight folder.

Inside the sunlight folder we can create the folder fr.

Let me have translation file inside the fr.

modules/sunlight/messages/fr/greeting.php




?php

return array(

	'hello!, good morning!'=>'bonjour!',

	'hello!, good evening!'=>'bonsoir!',

	'have a good day!'=>'bonne journée!',

	'have a good evening!'=>'bonne soirée!',

	'good luck!'=>'bon courage!'

);

?>



Now we can instruct YII to look at these files.

We have to declare messages component inside the main.php.




'components'=>array(

    'messages'=>array(

			'class'=>'CPhpMessageSource',

			'extensionPaths'=>array(

				'sunlight'=>'application.modules.sunlight.messages',

			),

		),

...........................................



By setting the extensionPaths property, we can literally map the message files situated in various extensions or

modules.

Have a look at the API.

CPhpMessageSource::extensionPaths

Now we can translate a message into french in a view inside the Module.




echo Yii::t('sunlight.greeting','have a good evening!'); //ouputs bonne soirée! 



Note that the first parameter should be in the format of classId.catagoryName.

The same things can be easily achieved withoUt declaring messages component.

For that we can add one more line to CWebModule::init method.




public function init()

	{

		$this->setImport(array(

			'sunlight.models.*',

			'sunlight.components.*',

		));

		Yii::app()->language="fr";

		Yii::app()->messages->basePath=Yii::getPathOfAlias('application.modules.sunlight.messages');

//You can have your messages files wherever you want.

//We can instruct YII to look into those files.

	}



Now we can translate a message into french in a view inside the Module.




echo Yii::t('greeting','have a good evening!'); //ouputs bonne soirée!. no need to call sunlight.greeting



I hope I helped a bit.

Regards.

Hi seenivasan,

yes I remember your PM and the explanation you give here is very intresting to me. In particular the fact that extensionPaths is now an array (since 1.1.13) and not a string anymore. I didn’t noticed that change.

Just one question : in your example, what is the sourceLanguage of the webapp your module is pluged in ?

B)

ciao

Friend

that is en_us.

Hi seenivasan,

I think that the problem with your solution is that you assume that after module initialization no component outside of the module will output a string …

I have a webapp that is able to provide widgets that can be used by plugged-in modules. A module can use its own widget, or use the ones provided by the web app it is plugged into. In this scenario, your solution doesn’t always work (in particular if the source language is not ‘en_us’).

for example :

  • webapp : sourceLanguage = ‘fr’ (french)
  • plugged-in module :[list]
  • sourceLanguage = ‘ja’ (japaneese)
  • translation provided for fr

[/list]I want pages to be displayed in french, so I’m suppose to write language = ‘fr’… but in this case :


Yii::app()->sourceLanguage == Yii::app()->language; 

…is TRUE : no tranlsation will be performed. Strings from the module will be displayed in Japaneese.

[i]It seems very much to me that parameter sourceLanguage is useless.

B)

[/i]

Dear Raoul

Yes that is a problem.

But that is happening when you are setting the basepath of component messages explicitely in CWebModule::init method.

If you are configuring messages component in main configuration files with extensionPaths, that is not at all issue.

You can easily test that by putting some messages files in protected/messages(which is basepath for main application) ,creating some widgets using translation and calling them in the module.

But anyway one has to declare the language in CWebModule::init method.


Yii::app()->language="fr";

Regarding sourceLanguage, my conviction is that it is like declaring the version id of application.

If I am correct the only purpose it serves is that when language is not defined, it points to sourceLanguage.

So by declaring the different sourceLanguage,we are not going to do any magic.

If someone writes a module in Japanese language and if he intends to give a multilingual support then he has to

ensure that messages files should return array with array index written in japanese and array value in other languages.

Regards.