CodeIgniter Forums
A better language library - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Archived Discussions (https://forum.codeigniter.com/forum-20.html)
+--- Forum: Archived Libraries & Helpers (https://forum.codeigniter.com/forum-22.html)
+--- Thread: A better language library (/thread-4849.html)

Pages: 1 2


A better language library - El Forum - 12-19-2007

[eluser]Negligence[/eluser]
I've decided that I should probably start sharing the libraries I've created that I find very useful. So, I'll start with my Language library. Here's a few reasons why it's better than the native version.

- Developing multi-lingual sites, the prospect of doing $this->lang->line(); for hundreds of language strings was daunting. With this library, one call gets all your language strings, or individual ones if you like.
- You can create a set of "common" language strings that you reuse throughout your application, so you aren't repeating strings in different files.
- You do not have to separate between different languages with folders. Instead, you put related language strings in a single file, and using arrays, you distinguish between the different language versions of a string.
- You can switch between languages on-the-fly.

Code:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

/**
* If you don't mind, keep this block of text up here if you use this library. Thanks!
*
* Author: Scott Winfield
* http://www.palidia.com */

class Lang
{
     private $defaultLang = 'en';
     private $language = 'en';
     private $positions = array('en' => 0, 'fr' => 1); // Position of the language string within the array
     private $varPrefix = 'lang_';
     private $data;
    
    
     /* Get all the language strings from a file */
     public function getKeys ( $file, $language = null )
     {
         if (isset($language))
         {
             $this->setLanguage($language);
         }    

         require(APPPATH . 'language/' . $file . '.php');
        
         $this->getLangStrings($lang);
         return $this->data;
     }
    
    
     /* Get all the commonly-used language strings */
     public function getCommonKeys()
     {
         require(APPPATH . 'language/Common.php');
        
         $this->getLangStrings($lang);
         return $this->data;
     }
    
    
     /* Get a specific key from a file */
     public function getKey ( $key, $file )
     {
         require(APPPATH . 'language/' . $file . '.php');
         return $this->getCorrectString($lang[$key]);
     }
    
    
     public function setLanguage ( $language )
     {
         $this->language = $language;
     }
    
    
     public function getLanguage()
     {
         return $this->language;
     }
    
    
     /* Walk through the $lang var and pull out the strings */
     private function getLangStrings ( $lang )
     {
          foreach ($lang AS $name => $strings)
         {
             $this->data[$this->varPrefix . $name] = $this->getCorrectString($strings);
         }        
     }
    
    
     /* Get the correct, language-sensitive string */
     private function getCorrectString ( $strings )
     {
         // Make sure you've got a valid string in the current language
         if (isset($strings[$this->positions[$this->language]]))
         {
             return $strings[$this->positions[$this->language]];    
         }
        
          // Otherwise, return the default language string        
         return $strings[$this->positions[$this->defaultLang]];
     }
}

?>

Usage:
Code:
// Load the library
$this->load->library('Lang');
Code:
// Getting all language strings
$strings = $this->lang->getKeys('filename', 'optional language');
Code:
// Get common language strings
$strings = $this->lang->getCommonKeys();
Code:
// Change the current language
$this->lang->setLanguage('en');


And your language file would look like this (under application/language/file.php):
Code:
$lang['email'] = array('English string', 'French String', 'Spanish String', 'etc');
$lang['phone'] = array('Phone', 'Phone', 'etc.');

Now you can have your translated strings side-by-side for easy editing and viewing. If you have any questions, let me know. Otherwise, enjoy Smile


A better language library - El Forum - 12-20-2007

[eluser]imzyos[/eluser]
- You do not have to separate between different languages with folders. Instead, you put related language strings in a single file, and using arrays, you distinguish between the different language versions of a string.

this give's order, and we dont need load a lot of configs just the files that we need

- You can switch between languages on-the-fly.

$this->lang->load('filename', 'language');


A better language library - El Forum - 12-20-2007

[eluser]esra[/eluser]
imzyos is correct. Language switching can be handled using a cookie setting for the users current language. There should also be a user contribution on the wiki. You should be able to find sample code on the forums about how to create a reusable language selection view fragment for use in a template or master view.

-----
The CI user_guide mentions a number of optional directories under application/ that can be created. These are scattered throughout the user guide and not mentioned in a single location. CI checks these if they exist. These include application/plugins/, application/helpers, and application/language. It would probably be more intuitive if those directories were included in the distribution with instructions for removing them if not needed.

Language files can be stored in system/language or application/language. CI checks application/language first to scan for language files.

If you're using Matchbox or the older Modular Separation 2.4.x extensions for CI, a modules/modulename/language directory can exist for storing module-specific language files. In this case, I believe that the modules/modulename/language directories are scanned after application/language to look for files with the name you are attempting to load until a language file with that name is found, then system/language is scanned.


A better language library - El Forum - 12-20-2007

[eluser]Negligence[/eluser]
If you've ever had to develop multi-lingual applications before, and perform translations, you would come to appreciate having english, french, etc., language strings in a single file, instead of finding/replacing in two different files in two different directories.

Second, the current Language library requires that you retrieve individual language strings individually. What happens when you've got fifty different strings you need to retrieve? This new library replaces fifty calls to line(), with one call to getKeys().

As a side note, although its not included in the library, I set the language in the session. I just didn't include that in the setLanguage() function.


A better language library - El Forum - 12-20-2007

[eluser]imzyos[/eluser]
yap, a i wrote an app, so spanish... and if i need other languaje just load from the languaje folder, is not necessarry have and array load ALL Languajes if you only gona show one per time...


A better language library - El Forum - 12-20-2007

[eluser]Negligence[/eluser]
Perhaps you misunderstood - it doesn't load all the languages, it only loads the one you need. The major difference is that it loads all the language strings from a particular file at once, instead of one at a time.


A better language library - El Forum - 12-20-2007

[eluser]imzyos[/eluser]
And your language file would look like this (under application/language/file.php):
Code:
$lang['email'] = array('English string', 'French String', 'Spanish String', 'etc');
$lang['phone'] = array('Phone', 'Phone', 'etc.');

Long array, using a cookie you could choose the correct languaje and not load ALL posibles Strings for example 'yes' according to you

Code:
$lang['yes'] = array('Yes', 'We', 'si', '...');



A better language library - El Forum - 12-20-2007

[eluser]Negligence[/eluser]
I understand what you're saying. Technically, it loads the data from the $lang array, but it only passes back what you need.

It was a design decision because trying to maintain, update strings, and translate thousands of words/phrases for applications became a nightmare with files for the same language. This simplifies things tremendously.

If this design choice is a serious concern to you, I'm surprised you use CI at all because of the many things it does that makes it more inefficient than it could be. The way the database class returns results, the Benchmark class being loaded by default, etc.. You might be surprised.


A better language library - El Forum - 12-20-2007

[eluser]esra[/eluser]
[quote author="Negligence" date="1198176076"]If you've ever had to develop multi-lingual applications before, and perform translations, you would come to appreciate having english, french, etc., language strings in a single file, instead of finding/replacing in two different files in two different directories.[/quote]

The problem with this approach comes when you need to deal with multiple translators. We generally supply an English version of our language files and database tables to a language translation house which uses independent translators who then return their completed work for review cycles. By placing the strings for multiple languages in a single file, you either need to manually transfer the translations to one central language file (labor intensive) or need to incrementally pass the same file around between multiple translators (prone to mistakes and a slow process).

Lastly, this approach is not very extensible in a modular sense because the files containing the arrays need to be manually edited each time a new language is added. Using the existing approach, one only needs to add a directory with a new set of language files for the desired locale.


A better language library - El Forum - 12-20-2007

[eluser]Negligence[/eluser]
In my experience with translations, I have not sent off the actual PHP file containing the language strings. All the strings are put into Word, then sent off for translation. When it comes back in this format, it's easy to do the copy/paste into a single file. Most translators I've worked with do not know anything about code, so we don't give them a sight of it, however simply it may be.

As for the modularity, the only reason why it isn't modular (for you) is because you're sending code to the translators. I've never heard of this being done, hence the reason why the library doesn't account for that kind of situation.