
In het geval dat je gebruik gaat maken van meerdere frameworks, zul je al snel bemerken dat nagenoeg elk framework een eigen implementatie heeft van zogenaamd "i18n internationalization support", oftewel meertalige ondersteuning voor de te ontwikkelen software. Dit lijkt op het eerste gezicht mooi, maar is niet altijd ideaal. Doordat de oplossing is gebaseerd op het eigen framework, wordt er geen rekening mee gehouden dat er ook nog andere spelers in het spel zijn.
i18n, wat is het?
I18n staat voor de globalization van software, waarbij de afkorting i18n staat voor de afstand tussen de letter 'i' en de letter 'n' in het woord internationalization, dit is ooit eens bedacht door Digital (DEC) in de zeventiger jaren. Deze termen worden door zowel CodeIgniter als Extjs ook gebruikt om over dit onderwerp te spreken.
Extjs
In Extjs is een i18n ondersteuning die zowel statisch als dynamisch kan worden toegepast. Alle componenten en de standaard teksten gebruikt worden middels resources in de directory "<ext>\src\locale\ext-lang-xx.js" (waarbij xx is een taalafkorting) ondersteund. Zie voorbeeld hieronder.
Het is mogelijk om componenten in een volledig anderstalige versie aan te leggen en deze geconditioneerd te laden. Niet erg handig, omdat zowel kennis van de taal als van Extjs benodigd is, om dit te bereiken (zie voorbeeld van Sencha).
De dynamische variant laadt de internationale resource file en gebruikt dit vervolgens voor de presentatie. Maar de forms en dialogen blijven nog steeds handwerk.
CodeIgniter
In CodeIgniter bestaat een directory "language", waarin zich de taalbestanden bevinden die kunnen worden aangesproken. Standaard is dit alleen het Engels, zoals bv languages/en/date_lang.php.

Zoals het voorbeeld toont, is het telkens een associatieve PHP array in de array $lang. Dit is in elk taalbestand hetzelfde. Deze language files kunnen middels een library en helper, language worden aangesproken. Het betreffende taalbestand wordt dan middels een library load geladen en middels een enkele funktie aangesproken. Lijkt allemaal erg mooi, maar is in de praktijk in mijn ogen wat mager.
Spelen in structuur
Hieronder heb ik een kleine opzet gegeven van hoe ik Extjs en CodeIgniter met elkaar laat samenwerken. Daarbij valt het onmiddellijk op dat de views in CodeIgniter (MVC), nagenoeg niet worden aangesproken en dat deze taak volledig is overgenomen door Extjs.
Maar dat is niet zo verwonderlijk.

server
De praktijk wil dat de server alle het zware werk doet en hierover de client (frontend) telkens over bericht in de vorm van data en/of message feedback. Deze informatie is zeker onder de invloed van taalafhankelijkheid. Het is dan niet meer dan logisch dat de server daarvoor haar eigen mogelijkheden aanspreekt.
frontend
De frontend daarentegen laat vele teksten zien die middels forms en dialogen op het scherm komen te staan. Zie voorbeeld hieronder.
Deze teksten zoals "Einstellungen" worden aangelegd in de definities van de Extjs panels, waarbij de "tree" data uit een database komt. Maar het zou mooi zijn dat het er voor het Nederlands dan bijvoorbeeld zo uit zou zien:

De data uit de tree komt dan uit een tabel (MySQL) en de statische label teksten komen dan uit de CodeIgniter Languages.
Eén bron voor alle taalverwerkingen
Hoe krijg je nu gedaan dat zowel de frontend als de backend kunnen werken met dezelfde bron, waarbij ook nog eens dezelfde constraints (afhankelijkheden) worden gebruikt in de logica. Zo'n constraint is bijvoorbeeld dat er gebruik gemaakt kan worden van substituties in de tekst variabelen. Zie hieronder een voorbeeld van zo'n substitutie variabele.
In het taalbestand:
$lang['passwordconfirm_subject'] = '[&customer] Ihr neues Kennwort';
En in de logic (controller of model):
$subst = '&customer="' . $customer . '"';
$this->email->subject(
$this->jlanguage->getlang('passwordconfirm_subject', $subst));
Zoals dit voorbeeld laat zien, wordt er middels een library (jlanguage) funktie, de tekst variabele gehaald en wordt &customer vervangen door de waarde in het veld $customer, welke in de $subst string wordt meegegeven.
De CodeIgniter library jlanguage is door mij ontwikkeld en is een uitbreiding op de bestaande taal mogelijkheid in CodeIgniter.
Ajax, jQuery en Extjs
Tot nu toe wordt alles op de server verwerkt, maar het moet dan ook nog naar de frontend. Om dit dus in Extjs te krijgen, maken we gebruik van Ajax. Dit maal niet met de Ext.Ajax maar met de jquery ajax, omdat deze een synchrone ajax load mogelijk maakt. Dat lijkt gevaarlijk, maar dat is het in dit geval niet. De taalbestandjes zijn erg klein en de verwerking is betrouwbaar.
1: this.records = $.parseJSON (
2: $.ajax({
3: url: "main/languages",
4: type: "POST",
5: data: {
6: "file" : file, // file to load
7: // "language" : 'de', // language to load, when not loaded it's loading the default
8: "fn" : "ajax", // function to execute
9: "ext" : "jquery" // this can't be ext, just something else
10: },
11: async: false
12: }).responseText
13: )
In het voorbeeld hierboven is language in data in commentaar omgezet, omdat wij zo veel mogelijk sturing via de server willen laten verlopen, dit is ook beter voor de onderhoudbaarheid van de software. De belangrijke feature in de jquery Ajax is de opie "async : false". Deze zorgt er namelijk voor dat de call eerst tot een eind moet komen, alvorens er verder wordt verwerkt. Dit druist wel tegen de Ajax principes in (a staat voor asynchonous), maar is hier nodig omdat anders de panels van Extjs al zijn geladen voordat de taaldefinities zijn geladen. Is dit een performance killer. Zo lang niet "the lord of the rings" in je taalbestandjes staan, merk je er niet veel van.
DOM
De volledige taaldefinities worden vervolgens in de DOM geladen in een object base.i18n. Dit is een lege container. Deze wordt door mij geladen, gelijktijdig met de base.Eventmanager (wij werken alle events af, met eventmanagers). Dus je zou dit kunnen doen bij het laden van de viewport. Vervolgens wordt bij elke basis klasse van een module een paar regels code toegevoegd, welke de taalonafhankelijkheid vorm geeft.
In de wrapper klasse (module naam in voorbeeld is "settings":
// language object for this module
base.i18n.settings = new base.i18n.loadLanguage('settings');
In elke andere klasse binnen de "settings" module:
//include this always when you use the language module from Enovision
this.lang = function ( text, tag ) {
t = base.i18n.settings.getLang(tag);
return (t != false) ? t : text
}
De implementatie in de Extjs panels
Nou is het een eitje om het werkend te krijgen, onderstaand voorbeeld laat zien dat de hoeveelheid extra code best meevalt:
1: this.searcher = new Ext.form.TextField ({
2:
3: fieldLabel : this.lang('Suchen', 'search'),
4: labelWidth : 200,
5: id : 'settings_center_search',
6: labelAlign : "left",
7: emptyText : this.lang('Bitte Suche eingeben', 'enter_search'),
8: name : 'settings_center_search',
9: xtype : 'textfield',
10: width : 200
11: }),
Eigenlijk moet slechts de oorspronkelijke tekst worden vervangen door: this.lang('originele tekst', '<language_tag>'). Waarbij de originele tekst de fallback is voor het niet aanwezig zijn van de tekst in het taalbestand. Waarom met een funktie en niet direkt de waarde aanspreken in de DOM zoals:
fieldlabel : (i18n.settings.enter_search || 'Bitte Suche eingeben')
Wel, omdat dit goed werkt in Firefox en Internet Explorer, maar dat Google Chrome dan met een fatale syntax error komt.
Interesse?
Dus kortom gezegd heb ik met een nieuw Extjs extended component (Ext.i18n), een beetje jQuery, een CodeIgniter library en controller een consistente en stabiele i18n implementatie voor CodeIgniter en Extjs.
Ik heb de sources niet gepubliceerd, omdat ze hier en daar nog wat gepoetst moeten worden. Maar mocht er interesse zijn in deze combinatie, stuur gerust een mailtje. Ik zou wat ondersteuning en opbouwende kritiek graag willen ervaren.










Meertalig (i18n) met Extjs en CodeIgniter…
In het geval dat je gebruik gaat maken van meerdere frameworks, zul je al snel bemerken dat nagenoeg elk framework een eigen implementatie heeft van zogenaamd “i18n internationalization support”, oftewel meertalige ondersteuning voor de te ontwikkele…
Leave your response!