stalno u pokretu

< IT & tech

17. 09. 2014. back end * cakephp * codeigniter * i18n&l10n * php * symfony * yii * zend

Internationalization How To for the 5 most popular PHP frameworks

I originally published this article on Lingohub blog in 2013, while working for the company. Lingohub specializes in providing app localization for developers and translators.</a>

As discussed in the previous articles on PHP internationalization, PHP provides native support for string translation using gettext and PHP arrays. These can be used in any PHP project. Additionally, some popular PHP frameworks offer their own way of string translation.

In this article, I want to provide a brief summary of the internationalization process with five of the most popular PHP frameworks currently out there. In this How-To you will read about using CodeIgniter, CakePHP, Zend, Yii and Symfony. If you would like us to focus on any of these (or some other PHP framework of your choice) in a future article of its own, please leave a comment.

CodeIgniter framework

CodeIgniter Language Class provides functions to retrieve language files and lines of text for purpose of internationalization. The language files are located within the language directory. CodeIgniter automatically looks for the language directory in two locations, first within the “languages” subdirectory of the application, and then, if not found, within the “languages” subdirectory of the CodeIgniter system directory. Each language is stored in its own subdirectory. For example, English language files can be stored either in




Language resource file names must end with _lang.php. Within the file, a line of text is assigned to a $lang array in each line this way:

$lang['language_key'] = "The actual message to be shown";

Recommended practice is to prefix all the keys with the name of the file in which they are located, in order to avoid collision with similar keys in different files. For example, the error message that informs the user about the missing email address that is located in the error_lang.php could have this key: “error_missing_email”.

Before fetching lines from any file, it has to be loaded first:

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

Filename is the name of the file without the extension. So for the previous example with error_lang.php, the filename to supply to the load function would simply be “error”. The language specifies the set that contains the file. If the second parameter is missing, the default language set in the application/config/config.php is used instead.

After the language file is loaded, a line of text can be fetched and echoed like this:

echo $this->lang->line('language_key');

Language files that are used globally can be auto-loaded by CodeIgniter. Auto loading can be set up in the autoload array in application/config/autoload.php.

Further reading:

CakePHP framework

CakePHP uses its own implementation of Gettext. In the previous blog article I described how gettext (po) files can be created. Functions used in CakePHP for application internationalization are as follows:

A complete list of global functions including those used for localization can be found in the CakePHP documentation.

Further reading:

ZEND framework

The Zend framework offers its own complete solution for localization and internationalization. It includes support for both gettext as well as some other resource file formats.

Available adapters for Zend_translate (a library used within the framework to handle translation) are:

  • Array (use PHP arrays)
  • Csv (use comma separated (.csv/.txt) files)
  • Gettext (use binary gettext (*.mo) files)
  • Ini (use simple INI (*.ini) files)
  • Tbx (use termbase exchange (.tbx/.xml) files)
  • Tmx (use tmx (.tmx/.xml) files)
  • Qt (use qt linguist (*.ts) files)
  • Xliff (use xliff (.xliff/.xml) files)
  • XmlTm (use xmltm (*.xml) files)

Further reading:

Symfony framework

In Symfony, translation of text is done through the translator service. To translate a message, the trans() method is used, following this process:

  • the locale is determined (from the request or a session variable)
  • a catalog of translated messages is loaded from the translation resource files defined for that locale
  • the requested translation is returned

The Symfony framework provides support for these loaders by default:

  • xliff: XLIFF file
  • php: PHP file
  • yml: YAML file

Howerver, custom loaders can be created by implementing the LoadInterface interface.

Further reading:

Yii Framework

With the Yii framework, message translation is done by calling Yii::t() method. When translating a message, its category has to be specified since a message may be translated differently under different categories (contexts). For example, the category yii is reserved for messages used by the Yii framework core code.

Parameter placeholders within the messages are replaced with the actual parameter values when calling Yii::t(). For example, the following message translation request would replace the {alias} placeholder in the original message with the actual alias value.

Yii::t('app', 'Path alias "{alias}" is redefined.', array('{alias}'=>$alias))

Translated messages are stored in a repositories called message sources. A message source is represented as an instance of CMessageSource or its child class. When Yii::t() is invoked, it will look for the message in the message source and returns its translated version if it is found.

Yii comes with the following types of message sources:

  • CPhpMessageSource: the message translations are stored as key-value pairs in a PHP array. The original message is the key and the translated message is the value. Each array represents the translations for a particular category of messages and is stored in a separate PHP script file whose name is the category name. The PHP translation files for the same language are stored under the same directory named as the locale ID. All these directories are located under the directory specified by basePath.
  • CGettextMessageSource: the message translations are stored as GNU Gettext files. For more information on gettext, you can check my previous blog post.
  • CDbMessageSource: the message translations are stored in database tables.

Custom message sources can be created as well by extending CMessageSource.

Further reading:

These quite popular PHP frameworks are not the only approaches to internationalization, let me know which ones you use and what your experiences are with them. We’ve outlined some approaches to getting your applications on the road towards localization before, and we’ll focus on some other programming languages and formats in future tutorials, too. Most of these are either based on customer experiences or our lessons learned from developing Lingohub. We’re looking forward to your comments.

Related posts

17. 09. 2014. back end * fuelphp * i18n&l10n * laravel * php
PHP internationalization frameworks: Laravel and FuelPHP

The article covers two more PHP frameworks that are frequently used, Laravel and FuelPHP
[ reading time: ~ 6 min. ]

17. 09. 2014. back end * i18n&l10n * php
PHP internationalization – i18n mechanisms tutorial

Static web and internationalization, dynamic web applications, localizing strings directly in the code, storing the strings in a relational database, message catalogues (string arrays), JSON, use of resource files
[ reading time: ~ 10 min. ]

17. 09. 2014. back end * gettext * i18n&l10n * php
PHP internationalization with gettext tutorial

Installation, portable object template files, plurals, an example of a PO file, directory structure, machine object files, gettext caching problems, setting up PHP for internationalization with gettext...
[ reading time: ~ 18 min. ]

17. 09. 2014. back end * i18n&l10n * ruby
i18n gem advanced features – Ruby on Rails internationalization

Using Different Backends for Ruby i18n gem, chaining backends, caching is an i18n gem advanced feature, fallbacks, Translation Metadata, cascading lookups, translation symlinks, using custom exception handlers
[ reading time: ~ 15 min. ]

17. 09. 2014. back end * i18n&l10n * padrino * ruby * sinatra
Internationalization for Ruby – i18n gem

i18n for plain Ruby & the i18n gem, i18n for Ruby on Rails, i18n for Sinatra, i18n for Padrino
[ reading time: ~ 20 min. ]

17. 09. 2014. back end * i18n&l10n * ruby
Internationalization for Ruby with the r18n gem

Installation and setup, translation lookup, filters for translations processing, pluralization, translating activeRecord models and plain Ruby objects, locale settings, r18n wrappers for rails and sinatra, r18n vs i18n
[ reading time: ~ 9 min. ]

17. 09. 2014. back end * i18n&l10n
Resource file formats

ini files, properties files, iOS .strings files, YAML files, RESX and RESW files, RESJSON files
[ reading time: ~ 4 min. ]

17. 09. 2014. back end * gettext * i18n&l10n * ruby
Ruby gettext internationalization tutorial on using the fast_gettext gem

Setup, translation lookup, managing translations (MO/PO, db, yaml), rails plugin, pluralization, defaults, multiple repositories, logging...
[ reading time: ~ 9 min. ]

10. 08. 2014. api * back end
Representational state transfer (REST)

[ reading time: ~ 3 min. ]

15. 08. 2014. api * back end * ruby
API - design, implementation, testing

notes and resources
[ reading time: ~ 3 min. ]

01. 09. 2014. api * back end * bdd / tdd * cucumber * ruby * ruby gem
Developing rails REST API with Cucumber

json_spec, writing the definitions, checking the http headers, testing authentication...
[ reading time: ~ 3 min. ]

03. 09. 2014. api * back end * ruby * ruby gem * security
Devise as authentication solution for rails API

Authentication token, the use of sessions, intsallation and setup, configuring the model, the routes, application controller, custom devise controllers, testing the controllers
[ reading time: ~ 9 min. ]

04. 09. 2014. api * back end
Design principles of the REST-ful JSON API (HATEOAS)

REST, JSON, API, HATEOAS, media types, top level resource representations, url templates, compound documents, urls, responses, errors, JSend response types, HTTP Status codes
[ reading time: ~ 12 min. ]

07. 09. 2014. api * back end * ruby
Building a JSON API in rails

[ reading time: ~ 1 min. ]

12. 09. 2014. back end * ruby
ActiveRecord notes

Uniqueness on a combination of fields, inclusion in array, getting all model associations, overriding model getters and setters, serialization...
[ reading time: ~ 2 min. ]

22. 11. 2014. back end * deployment * ruby
rails deployment

Setting up Debian 7 server on VPS, nginx, php-fpm, ruby, unicorn/phusion passanger, essentials, ssh keys, capistrano...
[ reading time: ~ 2 min. ]

24. 11. 2014. back end * dev_tool
nginx notes

[ reading time: ~ 1 min. ]

10. 12. 2014. back end * ruby gem

[ reading time: ~ 1 min. ]

Ovaj sajt ne sadrži first party kukije i druge mehanizme za aktivno praćenje poseta/ponašanja (facebook, google analytics, itd...). Na nekim stranicama se nalaze embedovani youtube video klipovi i google mape koji učitavaju svoje kukije.