Posts for the month of June 2010


This impressive number states how many evaluations have been realised since April 2008 by CITROEN employees on a web skill assessment software, developed by Net-ng.

The project is conducted by the GNFA, national association in charge of automotive training.

Implemented in 2008, the application is based on a set of modules, that have been for the most developed under Nagare. The application interacts with business management systems through webservices.

Among the set of modules, the reporting functionality (700 Mb of data for 6 million data units) has been fully developed with Nagare and widely uses YUI library for presentation (dynamic arrays, filters, ...), reportlab - the OpenSource PDF library for dynamic PDF generation with high quality and complex formatting (contents, inserting graphics) - and xlwt to generate multi-tabs Excel workbooks.

Other projects in skill assessment in the automotive sector are in progress ....To be continued!

More information on skills assessment tools developed by Net-ng: here (in french)

Some screenshots:

Project Internationalization with Nagare (message extraction)


Nagare doesn't have tight integration with gettext or Babel, here we're going to see a way to use those tools in a nagare project.

In the first part, we will integrate Babel into the project, in order to manage catalogs and extract messages. In the second part, we will set up effective message translation inside the project.


We need a working Nagare Installation.

We will use Babel to extract the template file and manage our catalog files, so let's install it:

$easy_install Babel

Then, we will create and register the example application this way

$ nagare-admin create-app example_i18n
Application 'example_i18n' created.
$ cd example_i18n
$ python develop
Finished processing dependencies for example-i18n==0.0.1

Set some defaults for Babel commands

Create a setup.cfg in your newly created app folder containing the following

keywords = _ , ugettext , lazy_ugettext:1 , N_:1,2 , ungettext:1,2 , lazy_ungettext:1,2
output_file = data/locale/messages.pot
input_file = data/locale/messages.pot
output_dir = data/locale
domain = messages
input_file = data/locale/messages.pot
output_dir = data/locale
domain = messages
directory = data/locale
domain = messages

Here, we decide to put translation files into data/locale, but this folder is not created by create-app so we have to create it manually:

$ mkdir data/locale

And finally, we add message extractors information into out file:

VERSION = '0.0.1'
from setuptools import setup, find_packages
      name = 'example_i18n',
      version = VERSION,
      author = '',
      author_email = '',
      description = '',
      license = '',
      keywords = '',
      url = '',
      packages = find_packages(),
      include_package_data = True,
      package_data = {'' : ['*.cfg']},
      zip_safe = False,
      install_requires = ('nagare', 'Babel'),
      entry_points = """
      example_i18n =
      message_extractors = {'example_i18n': [
                ('**.py', 'python', None)]}
Babel has been added as a dependency for the project, this way typing 'python develop' should install Babel if it is missing.

Prepare application for internationalization

Edit example_i18n/, put every strings between _() and define a fake _ function:

from __future__ import with_statement
import os
from nagare import presentation
_ = lambda x: x

class Example_i18n(object):
def render(self, h, *args):
    this_file = __file__
    if this_file.endswith('.pyc'):
        this_file = __file__[:-1]
    models_file = os.path.join(os.path.dirname(__file__), '')
    h.head << h.head.title(_('Up and Running !'))
    with h.div(class_='mybody'):
        with h.div(id='myheader'):
            h << h.a(h.img(src='/static/nagare/img/logo.gif'), id='logo', href='', title='Nagare home')
            h << h.span(_('Congratulations !'), id='title')
        with h.div(id='main'):
            h << h.h1(_('Your application is running'))
            with h.p:
                h << _('You can now:')
                with h.ul:
                    h <<'If your application uses a database, add your database entities into '), h.i(models_file))
                    h <<'Add your application components into '), h.i(this_file), _(' or create new files'))
            h << h.p(_('To learn more, go to the '), h.a(_('official website'), href=''))
            h << _("Have fun !")
    h << h.div(class_='footer')
    return h.root
# ---------------------------------------------------------------
app = Example_i18n

Message extraction and catalog manipulation

Messages can be extracted:

$ python extract_messages
running extract_messages
extracting messages from example_i18n/
extracting messages from example_i18n/
extracting messages from example_i18n/
writing PO template file to data/locale/messages.pot

A messages.pot file is now created into data/locale

For the next step, we have to initialize a catalog for your preferred locale (fr in this example):

$ python init_catalog -l fr
running init_catalog
creating catalog 'data/locale/fr/LC_MESSAGES/messages.po' based on 'data/locale/messages.pot'

The catalog is now added and is ready to be edited.

Once edited and filled in with the right translations, we can compile our catalog:

$ python compile_catalog
running compile_catalog
compiling catalog 'data/locale/fr/LC_MESSAGES/messages.po' to 'data/locale/fr/LC_MESSAGES/'

This way we can prepare as many catalogs as locales needed.

when changing messages in a project we have to do a extract_messages followed by a update_catalog, and add missing translation in every modified catalog.

Next Step

We are using a fake _ function, so nothing is translated at all, the next step is to plug gettext functions into example_i18n application, in order to get effective message translation.