PROBLEM
How to create a multilingual application in cakephp in a windows environment
DESCRIPTION
It is needed to translate web content for international audience. Cakephp uses the Localization (L10n) and Internationalization (I18n) standards. In cakephp the locale files are stored in the app/locale directory and arranged in language named subfolders, example: /app/locale/eng/LC_MESSAGES for english /app/locale/spa/LC_MESSAGES for spanish and so on, the name of the subfolder is the three letter standar located in http://www.loc.gov/standards/iso639-2/php/code_list.php
Locale files uses the ".po" file extension and cakephp uses the default.po name located in each language subfolder/LC_MESSAGES
SOLUTION
Add the following code to the app_controler.php in the beforeFilter function, this is to work in each cakephp page.
function beforeFilter() {
//For Localization
App::import('Core', 'l10n'); // Localization utility
$this->L10n = new L10n(); //instantiate the L10n class
$this->L10n->get("spa"); //select the
language, in this case spa=
Spanish }
And after this, everything contained in the
function __() will be looked up in the locales.
The function __() receives two parameters, the firs is the name of the text that is going to look for, and the second is a boolean value and when it is true, it returns the value without sending it to the view, this is a very useful parameter for anidated functions.
The .po files contains the strings to be replaced and have the following sintax:
msgid ""
msgstr ""
and it works very simple, msgid has the string located in the __() function and it is going to be replaced for msgstr, example __('home'), for the default.po located in /app/locale/spa/LS_MESSAGES that contains the following:
msgid "home"
msgstr "Inicio"
msgid "email"
msgstr "correo electrónico"
The function it is going to replace the string 'home' for the string 'Inicio'. The following example represents when the __() function has been called from inside another function:
echo $form->input('email', array('label'=>__('email',true)));
notice that it has the second parameter in true, that means that is going to return the value, but not for the view, instead it is going to return the value for the input function.
.po files must has the RTF-8 character groups, if you want your site to be in spanish you are going to need the "ñ,Ñ,á,é,í,ó,ú" characters, there is a utility that helps you to create the .po files it is called the poedit.exe and it is found in http://www.poedit.net/
The issue is that you can set up a parsers in Poedit, basically definitions of file types and command line parameters for
xgettext, which is executed fo find the parts in a file that should be translated. So there is a parser for PHP in there, but often, for example in the
CakePHP framework, you have to deal with files that are PHP files, but that have a different extension, in the CakePHP case views end with .ctp… Just adding “*.ctp” to the list of extensions in the PHP parser setup does not cut the mustard and you end up getting an error message like this:
xgettext: warning: file ‘[…].ctp’ extension ‘ctp’ is unknown; will try C.
To solve this, you need to tell xgettext that it has to deal with PHP files by adding “–language=PHP” to the list of commandline options. This is done by opening Poedit’s preferences and navigating to the parsers section there. In the PHP parser under “Parser command” (btw. this is the MAC version of Poedit) I have now the following line:
xgettext --language=PHP --force-po -o %o %C %K %F
.ctp files or any file specified in the PHP parser is now treated as PHP and translation sections are found.
PROBLEMA¿Cómo crear una aplicación multilenguaje en cakephp en un ambiente de windows?DESCRIPCIÓNSe necesita traducir contenido web para audiencias internacionales. Cakephp usa los estándares de Localización (L10n) e Internacionalización (I18n). En cakephp los archivos locales son guardados en el directorio app/locale y acomodados en subcarpetas nombradas según el lenguaje, ejemplo: /app/locale/engLC_MESSAGES para inglés, /app/locale/spa/LC_MESSAGES para español y así sucesivamente, el nombre de la subcarpeta es el estandar de tres letras localizado en http://www.loc.gov/standards/iso639-2/php/code_list.phpLos archivos de Localización usan la extensión ".po" y cakephp usa el archivo default.po localizado en cada subcarpeta de /LC_MESSAGESSOLUCIÓNAgregue el siguiente código en en el archivo app_controler.php en la función beforeFilter, esto es para que funcione en todas las páginas de cakephp. function beforeFilter() { //Para localización App::import('Core', 'l10n'); // Utilería de localización $this->L10n = new L10n(); //Instancia de la clase L10n $this->L10n->get("spa"); //selección del idioma, en este caso spa= Spanish }Y después de esto, todo lo contenido en la función __() será buscado en los archivos de localización.La función __() recibe dos parámetros, el primero es el nombre del texto que va a ir a buscar, y el segundo es un valor booleano y cuando es verdadero, regresa el valor sin enviarlo a la vista(view), este es un parámetro muy poderoso porque funciona para funciones anidadas.Los archivos .po contienen los textos a ser reemplazados y deben tener la siguiente sintaxis:msgid ""msgstr ""y funciona de una manera muy sencilla, msgid tiene los textos localizados en la función __() y van a ser reemplazados por msgstr, ejemplo __('inicio'), para el archivo default.po localizado en /app/locale/eng/LS_MESSAGES que contiene lo siguiente:msgid "inicio"msgstr "Home"msgid "correo electrónico"msgstr "email"La función va a reemplazar el texto 'inicio' por el texto 'home. El siguiente ejemplo representa cuando la función __() ha sido llamada desde dentro de otra función:echo $form->input('correo_electronico', array('label'=>__('correo electrónico',true)));Note que el segundo parámetro está en verdader, esto significa que va a regresar el valor, pero no para la vista, en su lugar va a regresar el valor a la función input.Los archvios .po deben tener caracteres en el grupo RTF-8, si usted quiere que el sitio esté en español va a necesitar los caracteres "ñ,Ñ,á,é,í,ó,ú", existe una utilidad que ayuda a crear los archivos .po llamada poedit.exe y se encuentra en http://www.poedit.net/El problema es que se pueden configuar analizadores de sintaxis (parsers) en Poedit, básicamente la definición de los tipos de archivo y los parámetros de la linea de comando para la función xgettext, la cual es ejecutada para encontrar las partes en un archivo que deba ser traducido. Así que existe un analizador sintáctico para PHP ahí, pero usualmente para por ejemplo en el caso de CakePHP se tiene que lidear con archivos que son archivos PHP, pero tienen diferente extensión, en el caso de CakePHP las vistas tienen extensión .ctp… solo agregando la extensión“*.ctp” a las listas de extensiones en el analizador sintáctico PHP no funciona, y se obtiene un error como el siguiente: xgettext: warning: file ‘[…].ctp’ extension ‘ctp’ is unknown; will try C.
xgettext: precaución: archivo‘[…].ctp’ la extensión ‘ctp’ es desconocida; se intentará usar C.
Para resolver esto se necesita decirle a xgettext que tiene que tratar con archivos PHP agregando “–language=PHP” a la lista de opciones de la linea de comandos. Esto se hace abriendo las preferencias de PoEdit y navegar hasta la sección de analizadores sintácticos (parsers). En el analizador sintáctico (parser) de PHP en el comando del parser hay se modifica la linea de la siguiente manera:
xgettext --language=PHP --force-po -o %o %C %K %F
Los archivos .ctp o cualquier otra extensión especificada en el parser de PHP es ahora tratado como PHP y las secciones de traducción ahora son encontradas.
REFERENCES
http://book.cakephp.org/view/161/Localization-Internationalization
http://g-roc.com/33_poedit-xgettext-parser-setup-reminder.html