Posts Tagged ‘i18n’

Debug: Howto show variables used in Chamilo 1.8.7 translations

As a developer or translator for Chamilo 1.8.*, you might often be faced with the need to know what variable is used to look for a translated term to be shown on screen. While we don’t have a nice in-house feature for this just yet, you can easily hack your own. Here’s how:

  • Go to main/inc/lib/internationalization.lib.php
  • Find the function get_lang
  • Find the first and the third “return” statements
  • Put the whole value (after the equal sign) between parenthesis and prefix them with: $variable.’-‘. (this should give something like  return $cache[$language][$variable] = $variable.’-‘.($_api_is_translated ? ($is_utf8_encoding ? $langvar : api_utf8_decode($langvar, $encoding)) : $langvar); )

From then, you should see all the variables show before the translated term. You can then go on, click on “Advanced search” and change the translation to the right one.

Working on online translation for Akelos

October 27, 2009 Leave a comment

We are currently working on the development (or co-development, as a base was made available to us by the Akelos team itself) of a plugin to Akelos that fixes the current problems of language variables duplication, deprecation and need for a manual edition of the files.

There are still a few things to be fixed in terms of getting that into a production environment for Akelos instead of just the development environment, but we’re working on that.

Categories: Development, English, Good news Tags: ,

Why using partial strings for translations is not a good idea

October 4, 2009 4 comments

This article is clearly at level “piece of cake” for those of you working day to day with UTF-8 and unicode headaches, but I have plenty of problems with my own team to explain why they should never put a string like this:

$SomeString = “This value must not be inferior to”;

in the Dokeos translations system, but they never learn :-)

This would later appear in the code as something close to:

echo get_lang(‘SomeString’);

and this would make it available in all the supported languages (if translated by a good will in his own language).

So here is an attempt at explaining clearly  what it’s all about, and why this kind of expression should be avoided at all cost in a translation system.

First of all, let’s delve a bit deeper into the string above, to make sure we all start on the same bases. The idea is to have a final string in the user interface which will look like this:

This value must not be inferior to 25

OK, you all get the point?

Now where is the problem in that? Well, the problem is that not all languages work the same or, better said, have the same sentence construction rules. The same sentence would be translated in the following ways:

French: Cette valeur ne peut pas être inférieure à 25

Spanish: Este valor no puede ser inferior a 25

Dutch: Dit waarde macht niet minder dan 25 zijn

Did you see what just happened? Yes, “25” was not the last word of the sentence! So, how do you fix that now with your string, huh? You’re pretty stuck now, aren’t you? Well, that’s why I’m writing this. Dutch is not the only language with this kind of structural change. Japanese would most probably put 25 (ni-juu-go) right in the middle of that sentence.

Now, I hope you already learnt something right now. And I hope that what you learnt is that you have to think a bit more and be a little less egoistic when programming. A lot of people might use your program (particularly if it’s open-source), and a huge lot of these will not speak a work of English or French or even Spanish, so you will have to find new ways to do things properly.

One of these new ways is to use the nice sprintf() function in PHP (in our case, of course), and pass parameters in the form of %s (string) or %d (decimal) inside your string.

For example, the previous string could now be stored in a language file this way:

$SomeString = “This value must not be inferior to %d”;

When translating this string to Dutch, I would write:

$SomeString = “Deze waarde mag niet minder dan %d zijn”;

Did you see that? Now the translation is completely up to the translator. No more problem of positionning the number at the end of the string.

Then you would call it from your script not this way:

echo sprintf(get_lang(‘SomeString’),’25’);

Et voilà! Now you know why I’m upset when I see a partial string translation… So let’s make it a better world for all translators around! Let’s give them multilingual-ready strings to translate!

Note: Purists will tell me that I should use printf() instead of echo + sprintf(), and also that I should use %d and not %s, and I would agree, but I’m just trying to show a one-simple-step change between the previous form and this one.

Thanks for reading.

Fixes for Gallery 2 French translation in module ‘core’

August 29, 2009 Leave a comment

After years using G2, I finally fixed the fr.po for core module and submitted it to latest registered French translator of Gallery2 several weeks again. After review, he encoded the following tracker on for everybody to benefit from it, even if no G2 update is ever published again:

As G2 is using gettext, updating it it fairly easy.


Opinión sobre PHP 5.3, lo bueno y lo malo

La reciente salida de PHP 5.3.0, a pesar de generar una gran cantidad de comentarios negativos sobre el hecho de que rompe muchas herramientas, es un paso mayor hacia PHP 6.0.0. Las quejas provienen generalmente del hecho de que unas mejoras en el soporte del código orientado objeto implican ser más estrictos sobre la forma en que deben ser usados los objetos o las clases dentro de una aplicación (por ejemplo no deja más instanciar una clase que sea abstracta “de facto”).

Entre las cosas buenas más resaltantes de esta nueva versión, contamos con la inclusión en la base del lenguaje de las extensiones intl (facilitadora de muchos temas de internacionalización), fileinfo (que permite de determinar, de manera confiable, el tipo de un archivo, lo que permite a su vez de filtrar mejor peligros al acceptar ficheros externos). También vemos la inclusión ahí de “closures” (construcción del lenguaje conocida de los desarrolladores JavaScript), de espacios de nombre (parece que mucha gente estuvieron esperando esto, y de verdad podría servir en Dokeos para, por ejemplo, separar mejor los ficheros de idiomas).

También suele mencionar que varias fuentes reportan (buscar “benchmark PHP 5.3”) que esta versión tiene una eficiencia superior.

Cualquier sea el asunto en favor o en contra de PHP 5.3.0, no hay mucha preocupación que tener de inmediato. Dokeos 1.8.6 está siendo probado por Issac  aquí (muy probablemente la versión propondrá soporte completo de esta versión), pero de toda forma las empresas que proponen alojamiento de aplicaciones PHP necesitarán unos meses para pasar a esta nueva versión.

Categories: otros, php, Spanish, técnico Tags: , , , ,

PHP 5.3 and the Internationalization extension

In this article, Stas Malyshev describes the internationalization extension and mentions it’s been included in the PHP 5.3 core. It is an extensive article with plenty of examples to explain every component of Internationalization: Locale, Collator, Number formatter, Date formatter, Message formatter, Normalizer, Grapheme and Internation Domain Names.

Pretty useful. Storing it for later (when Dokeos will require 5.3 by default, or the installation of the extension in 5.2)

Traducciones con parámetros





La i18n (internationalization) de Akelos (framework PHP) nos permite incluir parámetros en la invocación. A continuación compartimos un ejemplo con ustedes:


Trabajaremos con el controlador product

Y el método greeting

archivo app/controller/product_controller.php
function greeting() {



En la vista (archivo app/views/product/greeting.tpl):
translate( 'Hello %user_name. Justice %question_mark', array('%user_name' => 'Osho', '%question_mark' => '?') );

Aquí debemos prestar atención a los parámetros que se indican con el prefijo de porcentaje (‘%’). Y como segundo parámetro del método translate tenemos el arreglo con llaves y valores para los parámetros.


En los archivos de traducción se puede ser flexibles con la presencia y posición de las variables al interior de las expresiones.


archivo app/locales/product/en.php
$dictionary['Hello %user_name. Justice %question_mark']='Hello %user_name. Justice %question_mark';

archivo app/locales/product/es.php
$dictionary['Hello %user_name. Justice %question_mark']='%user_name e. Justicia chu.';

Obtendríamos como resultado:
– Hello Joseph. Justice?
– Joseph e. Justicia chu.

De esta forma podemos ubicar las palabras en el lugar correspondiente de acuerdo a las reglas de cada lenguaje. Incluso prescindir de elementos como ciertos signos de puntuación que sólo son válidos en determinados idiomas.

También podemos reutilizar expresiones ya traducidas, así evitamos las variaciones en la traducción de frases muy similares. La clave es identificar patrones en las expresiones, cuando en la práctica escribimos repetidas veces lo mismo.

– Ha fallado el comando DELETE.
– Command EXECUTE has failed.

Y podemos dar por cerrada una etapa de traducción antes de terminar el proceso de desarrollo de la lógica de una solución.

– Le quedan 2 tareas por revisar.
– 1 task to do.

%d bloggers like this: