Benutzer:Elkuku/Proyektz/EasyCreator/Language handling/Javascript translations
Inhaltsverzeichnis |
[Bearbeiten] The Joomla! way
Joomla! 1.6 introduces a nice new feature: A Joomla namespace in JavaScript that includes a JText function which acts almost as its JText counterpart from PHP - almost..
[Bearbeiten] Step # 1 Definition in language ini file
NAFU_HELLO_WORLD = "Hello world !"
Add similar definitions to your other language files.
[Bearbeiten] Step # 2 Injecting the definition from PHP
Every definition must be 'injected' with some PHP code to be included in your page source, so it is 'reacheable' for JavaScript scripts.
Find a suitable location - maybe a layout file..
JText::script('NAFU_HELLO_WORLD');
[Bearbeiten] Step # 3 Use in JavaScript
Now you are ready to use the definition in your JavaScript files using the following code:
alert(Joomla.JText._('NAFU_HELLO_WORLD');
Of course, you are not limited to 'alert' - it's just a demo =;)
Note: The function accepts a second parameter - a default value. If no translation is found, and no default value is given, the function returns a plain, simple and unfriendly undefined. So the preceding example would produce just an empty alert box.
[Bearbeiten] The EasyCreator way
While the Joomla! method works great if you have only a few translatable strings in your JavaScript files. For extensions with more then a few alert boxes it might seem quite redundant to define your strings three times.. Also strings that are common throughout the application must be 'injected' in every view or must be injected in a central place, which IMHO makes the code quite ugly.
So here is a solution:
[Bearbeiten] Step # 1 Create a separate language ini file for your JavaScript translations
This is a normal ini file that will hold only translations that are meant to be used in JavaScript code - which doesn't mean that they can't also be used in PHP.
All the definitions included in this file will be available to your JavaScript code.
NAFU_HELLO_WORLD = "Hello world !"
Add similar definitions to your other language files.
[Bearbeiten] Step # 2 Auto load the contents and inject them 'all at once'
The trick here is to explicitly load the special javascript language files and then verify which keys have been loaded.
These keys will be added to the global JText script storage in Joomla! 1.6 or, with our 1.5 implementation, will be written at once to the <head> section of the page.
In Joomla! 1.6 it is possible to add other strings afterwards, so you may have one common file and add other strings afterwards or - have another set(s) of language file(s) for a special view(s) - infinite possibilities :)
[Bearbeiten] J! 1.5 implementation
This is an implementation for Joomla! 1.5.
It does an ugly trick accessing a property which is marked as 'protected'. This will not work any more in Joomla! 1.6, but it's good for now..
class NafuComponentHelper { /** * @see JComponenthelper::renderComponent() * * This doesn't really render the component =;) * * @return void */ public static function renderComponent($option, $params = array()) { $lang = JFactory::getLanguage(); //-- Record already known strings - @protected property access ! $strings = $lang->_strings; //-- Now we load the language files and add them to the global array $lang->load($option.'.js', JPATH_COMPONENT, null, false, false) || $lang->load($option.'.js', JPATH_COMPONENT, $lang->getDefault(), false, false); //-- Compute the difference - @protected property access ! $jsStrings = array_diff_assoc($lang->_strings, $strings); //-- Add the entries to the page $js = array(); $js[] = '/* Joomla! 1.6 Joomla.JText javascript implementatin for Joomla! 1.5 */'; $js[] = '(function() {'; $js[] = 'var strings = '.json_encode($jsStrings).';'; $js[] = 'if (typeof Joomla == \'undefined\') {'; $js[] = ' Joomla = {};'; $js[] = ' Joomla.JText = strings;'; $js[] = '}'; $js[] = 'else {'; $js[] = ' Joomla.JText.load(strings);'; $js[] = '}'; $js[] = '})();'; JFactory::getDocument()->addScriptDeclaration(implode("\n", $js)); }//function }//class
Please note that strings that have been defined (and loaded) in your main language file will not be found with this method, so you should proper namespace your keys.
This is a copy of the Joomla.JText method from Jomla! 1.6.
You may include it as a separate file or simply add the code to a JavaScript file of your application that will be loaded.
//-- Only define the Joomla namespace if not defined. if (typeof(Joomla) === 'undefined') { var Joomla = {}; } /** * Custom behavior for JavaScript I18N in Joomla! 1.6 * * Allows you to call Joomla.JText._() to get a translated JavaScript string pushed in with JText::script() in Joomla. */ Joomla.JText = { strings: {}, '_': function(key) { return typeof this.strings[key.toUpperCase()] !== 'undefined' ? this.strings[key.toUpperCase()] : key; }, load: function(object) { for (var key in object) { this.strings[key.toUpperCase()] = object[key]; } return this; }, };
So all you have to do is adding the JavaScript function and the PHP class and call the "component helper" as early as you can.
e.g. in you entry file:
JFactory::getDocument()->addScript('path/to/j_16_joomla_jtext.js');//-- Example file name JLoader::import('nafucomponenthelper', JPATH_COMPONENT.DS.'helpers');//-- Example file name NafuComponentHelper::renderComponent('com_yourcomponent');//-- Example file name
[Bearbeiten] J! 1.6 implementation
In Joomla! 1.6 there are no dirty tricks any more... To overcome the fact that we can not access a protected property, we will create a fake class that provides a getter to access that property for our purpose.
class NafuComponentHelper { /** * 2B implemented in JComponentHelper * @see JComponenthelper::renderComponent() * * This doesn't really render the component =;) * * @return void */ public static function renderComponent($option, $params = array()) { $HACKED_Language = HACKED_JLanguage::getInstance(JFactory::getConfig()->getValue('config.language')); $lang = JFactory::getLanguage(); //-- Record already known strings $strings = $HACKED_Language->getStrings(); //-- Load the javascript language ini file - only to get the keys $HACKED_Language->load($option.'.js', JPATH_COMPONENT, null, false, false) || $HACKED_Language->load($option.'.js', JPATH_COMPONENT, $lang->getDefault(), false, false); //-- Compute the difference $jsStrings = array_diff_assoc($HACKED_Language->getStrings(), $strings); //-- Now we really load the language files and add them to the global array //-- Load common and local language files for the use in javascripts. $lang->load($option.'.js', JPATH_COMPONENT, null, false, false) || $lang->load($option.'.js', JPATH_COMPONENT, $lang->getDefault(), false, false); //-- Store them in JTexts "JavaScript language store" foreach(array_keys($jsStrings) as $KEY) { JText::script($KEY); }//foreach }//function }//class /** * The purpose of this class is to provide access to * the internal (protected) array $strings of JLanguage */ class HACKED_JLanguage extends JLanguage { public static function getInstance($lang, $debug = false) { return new HACKED_JLanguage($lang, $debug); }//function public function getStrings() { return $this->strings; }//function }//class
So all you have to do is adding the PHP classes and call the "component helper" as early as you can.
e.g. in you entry file:
JLoader::import('nafucomponenthelper', JPATH_COMPONENT.'/helpers');//-- Example file name NafuComponentHelper::renderComponent('com_yourcomponent');//-- Example file name
[Bearbeiten] Step # 3 Use in JavaScript
This one is exactly the same as the Joomla! way.
alert(Joomla.JText._('NAFU_HELLO_WORLD');
We are compatible.
[Bearbeiten] Where is EasyCreator ¿
EasyCreator comes to your rescue with the ability to
- Search your JavaScript files for the use of Joomla.JText and translate their contents.
- Create a separate js.ini file and translate them separated.
[Bearbeiten] Do you have a working example of this method ?
Yes. EasyCreator uses this technique.
Happy coding =;)