How to Program With Yii2: Localization With I18n

Final product image
What You'll Be Creating

If you're asking, "What's Yii?" check out my earlier tutorial: Introduction to the Yii Framework, which reviews the benefits of  Yii and includes an overview of what's new in Yii 2.0, released October 12th, 2014.

In this Programming With Yii2 series, I'm guiding readers in use of the newly upgraded Yii2 Framework for PHP. In part one, we set up Yii2 locally, built a Hello World application, set up a remote server and used Github to deploy our code. In part two, we learned about Yii's implementation of its Model View Controller architecture and how to build web pages and forms that collect and validate data. In part three, we used Yii's database and active record capabilities to automate code generation for a basic web application. And, in part four, we learned how to integrate user registration.

In this tutorial, I'm going to show you how to make use of Yii's built-in I18n internationalization support to make your application ready for translation into a number of languages.

For these examples, we'll continue to imagine we're building a framework for posting simple status updates, e.g. our own mini-Twitter.

What's I18n?

According to Wikipedia, I18n is a numeronym for Internationalization:

18 stands for the number of letters between the first i and last n in internationalization, a usage coined at DEC in the 1970s or 80s.

With I18n, all of the text strings displayed to the user from the application are replaced by function calls which can dynamically load translated strings for any language the user selects.

The Goals of Internationalization

When building a web application, it's useful to think globally from the beginning. Does your app need to work in other languages for users from different countries? If so, then implementing I18n from the beginning will save you a lot of time and headaches later.

In our case, the Yii Framework provides built-in support for I18n so it's relatively easy to build support in for I18n as you go along.

How I18n Works

I18n operates by replacing all references to text displayed to the user with function calls that provide translation when needed. 

For example, here's what the attribute field names in the Status model look like before I18n:

Providing translated versions of the code would become very complicated. Non-technical translators would have to translate code in place, likely breaking syntax.

Here's what the same code looks like with I18n:

Yii:t() is a function call that checks what language is currently selected and displays the appropriate translated string. The 'app' parameter refers to a section of our application. Translations can be optionally organized according to various categories. But where do these translated strings appear?

The default language, in this case English, is written into the code, as shown above. Language resource files are lists of arrays of strings whose key is the default language text, e.g. 'Message' or 'Permissions'—and each file provides translated text values for their appropriate language.

Here's an example of our completed Spanish translation file, language code "es". The Yii:t() function uses this file to find the appropriate translation to display:

While this looks time-consuming, Yii provides scripts to automate the generation and organization of these file templates.

By separating the text from the code, we make it easier for non-technical multi-lingual experts to translate our applications for us—without breaking the code.

I18n also offers specialized functions for translating time, currency, plurals et al. I won't go into the detail of these in this tutorial. 

Configuring I18n Support

Unfortunately, the Yii2 documentation for I18n is not yet very descriptive, and it was difficult to find working, step by step examples. Luckily for you, I'm going to walk you through what I've learned from scouring the docs and the web. I found The Code Ninja's I18n example and the Yii2 Definitive Guide on I18n helpful, and Yii contributor Alexander Makarov offered me some assistance as well.

Generating the I18n Configuration File

We're using the Yii2 basic application template for our demonstration application. This places our codebase below the /hello root directory. Yii's configuration files in /hello/config/* are loaded whenever page requests are made. We'll use Yii's I18n message scripts to build out a configuration file for I18n in the common/config path.

From our codebase root, we'll run the Yii message/config script:

This generates the following file template which we can customize:

I'm customizing the file as follows. I move messagePath up to the top and customize sourcePath and messagePath. I am also specifying the languages I want my application to support besides English—in this case Spanish (es), German (de), Italian (it) and Japanese (ja). Here's a list of all the I18n language codes.

In the next step, we'll run Yii's extract script which will scan all the code in the sourcePath tree to generate default string files for all the labels used in our code. I'm customizing sourcePath to scan the entire code tree. I'm customizing messagePath to generate the resulting files in common/messages.

You'll see Yii scanning all of your code files:

When it completes, you'll see something like this in your codebase:

Yii2 Localization with I18n Directory Paths

Activating I18n and Selecting a Language

In the common configuration file, /hello/config/web.php, we're going to tell Yii about our new language support. I'll make Spanish my default language:

But there's still more to do. We have to make our code I18n aware.

Using Yii's Gii Code Generator With I18n

In part three of this series, we used Yii's database and active record capabilities to automate code generation. But we did not activate I18n, so all of our code had text strings embedded. Let's redo this.

We return to Gii, likely http://localhost:8888/hello/gii in your browser, and re-run the model and controller generators with I18n activated.

Here's an example of generating the Meeting model code with I18n activated. Notice that we specify "app" for our Message Category. We're placing all of our text strings in one app category file. 

Yii2 Gii Code Generator Status Model for I18n

Let's do the same for the CRUD generation for controllers and views:

Yii2 Gii Code Generator for Status CRUD With I18n

If you browse the generated code in models, controllers and views you'll see the text strings replaced with the Yii:t('app',...) function:

Making Static Views I18n Ready

Because we generate a number of views in our application by hand or in HTML, we need to manually convert these to use I18n. For example, our navigation bar in /views/layouts/main.php and our home page in /views/site/index.php both need to be edited by hand. 

Here's the navigation bar before I18n:

Here's the navigation bar after I18n:

Here's a fragment of the home page content from index.php after I18n—much of the HTML has been replaced by PHP calls to Yii::t():

Translating Your Message Files

Take a look at our Spanish message file, /common/messages/es/frontend.php. It's a long list of empty array values:

For the purposes of filling in our Spanish language translations for this tutorial, I'll use Google Translate. Tricky, huh?

Yii2 I18n Using Google Translator to Fill Message Files

Then, we'll do some cut and paste with those translations back into the message file. 

When we visit the Application home page, you'll see the Spanish version—nice, huh?

Yii2 I18n Our App Home Page in Spanish

Here's the Create Status form:

Yii2 I18n Create a Status Update in Spanish Form

If I want to switch back to English, I just change the configuration file, /config/web.php, back to English:

You'll also notice as you proceed that replacing strings in JavaScript has its own complexities. I haven't explored it myself, but the Yii 1.x JsTrans extension may provide a useful guideline for supporting this.

Going Further With I18n

Ultimately, we may want to translate our application into a number of languages. I've written a new tutorial called Using the Google Translate API to Localize Your I18n App (Tuts+) which automatically translates your application into a variety of languages. If it's not published yet, it will be published soon (check my instructor page). Of course, this just provides base translations. You may want to hire professional translators to tune the files afterwards.

Some applications allow users to select their native language so that when they log in, the user interface automatically translates for them. In Yii, setting the $app->language variable does this:

Other applications, like JScrambler.com below, leverage the URL path to switch languages. The user just clicks the language prefix they want, e.g. "FR", and the app is automatically translated: 

JScrambler Dynamic Language Paths

Note: Read my recent introduction to JScrambler to find out more—it's a pretty useful service.

Yii's URL Manager can provide this type of functionality as well. I will probably implement these features in a future tutorial in this Yii2 series when I focus on Routing.

What's Next?

I hope you're excited about the power of I18n and the benefits of using the Yii Framework over vanilla PHP. Watch for upcoming tutorials in our Programming With Yii2 series.

If you'd like to know when the next Yii2 tutorial arrives, follow me @reifman on Twitter or check my instructor page. My instructor page will include all the articles from this series as soon as they are published. You can also email me at my Lookahead Consulting website.

Related Links

Tags:

Comments

Related Articles