Posted on by & filed under Content - Highlights and Reviews, Programming & Development.

Aaron Kavlie is a developer at Stremor working on a mobile voice platform called Plexi.

Internationalization and localization of a web app can be an enormous undertaking. Supporting a second language adds a significant overhead to every change you make, and that only increases as you add more languages. The good news is that Flask, a Python microframework, together with Flask-Babel, gives you some good tools to streamline the process.

There are a lot of things to consider when internationalizing and localizing a complex web application, including design and layout, number and date formatting, graphics with text, and so on. In this post we will focus on the fundamental issues that all apps, even basic brochure sites, need to support multiple languages: string extraction, translation files, and URL routing.

Translating strings with Babel and gettext

Let’s start with a couple of basic handlers:

And a simple template for the about page:

For a simple English-only static site, this is all fine and dandy. As soon as you need to translate the site to Spanish, however, things get more complicated.

Fortunately the Flask-Babel extension gives us some good tools to manage string translations, building on the gettext support in the Python standard library and the Babel i18n library.

Getting started with Babel is simple:

This will load the Jinaj2 i18n extension with the gettext function aliased to the conventional shortcut _. Let’s modify that template now by feeding our copy into gettext:

Reload the page. If all is well, things will look exactly the same.

The translation workflow

Now that we have a couple of gettextified strings, let’s produce a file to send to the translator.

First of all, we need a basic babel.cfg in the root directory of the project:

With that out of the way, Babel will come to our aid again with a command line tool to produce the .po and .pot files we need. First of all, produce a .pot file:

Next, add a translation. In this example we’ll use Spanish. Note that translations are indicated by ISO 639-1 codes. Substitute the proper two-letter code for es to add other languages. You’ll need to do this once for each language you plan to support:

Now you have a .po file ready to be translated. Fortunately this is a very common format, and there are a number of good GUI tools to assist in the translation process, so translators don’t have to edit the plain text by hand.

After the translation is done, compile the the translated .po file:

This will add a .mo file alongside the .po file.

Note: Instances of #, fuzzy must be removed before running the compile command. Those are intended to mark a string as modified for the translator, but for some reason Babel marks an empty string as fuzzy every time.

Finally, every time you add or modify strings in the future, run the first command again, get translations for the .po files, then run:

Now our translations are ready to go. We just need to tell the app which language to use.

URL Routing

Modify the routes to add a lang_code parameter as follows:

Ordinarily that would require an argument in each view handler (index(lang_code) rather than just index()), but we’re going to take care of that for all the views as follows:

Now that we’ve stored the language in Flask’s g object, this is what we need to do to select a language:

Now everything should be working. Give it a try! Assuming that you provided string translations in the previous step, /en/about should be showing the English text, and /es/about the Spanish.

You may notice that an invalid lang_code breaks the app (e.g. /klingon/about). To prevent that, we just need to check for a valid code like so:

Finally, what about the root URL? Just redirect that to the English version of the home page like this:


There’s still a lot we could do to refine our language handling. For example, we could store the preferred language in a session (so we don’t always redirect to the English page if the user explicitly chose Spanish), or ask Babel for the supported translations, rather than hard-coding them. But this is a solid foundation upon which you can build further enhancements and optimizations as needed.

All of the code for this tutorial is available on GitHub.

See below for Flask resources from Safari Books Online.

Safari Books Online has the content you need

Instant Flask Web Development takes you beyond the quick start in the Flask documentation and shows you a bottom-up approach to organizing your Flask application. It shows you how to build a small deployable scheduling application with pointers to the various design decisions you can make when developing with Flask.
Instant Data Intensive Apps with pandas How-to starts with Pandas’ functionalities such as joining datasets, cleaning data, and other data munging tasks. It quickly moves onto building a data reporting tool, which consists of analysis in Pandas to determine what’s relevant and present that relevant data in an easy-to-consume manner, and also provides a section on Flask.

About the author

aaron Aaron Kavlie started doing web development a few years ago and is currently a developer at Stremor working on a mobile voice platform called Plexi. He mainly does backend work with Python these days, but has been known to do frontend web development in the past. He can be reached at @akavlie.

Tags: Babel, english, Flask, gettext, Internationalization, Localization, microframework, Python, spanish, URL routing, Web App,

Comments are closed.