Localization of graphic resources for a Python Flask website

Over at Hungry.dk we are working hard on getting an Irish version of our site ready. In Ireland the company will be named Marvin.ie, and though it will have the same look and feel, there are of course graphic resources, that needs to be localized, such as logo's, graphics containing text, available payment types etc.

So we needed to come up with a strategy for localizing these resources. We are already using the excellent Flask-Babel extension to handle string/text localization, so an easy approach would be to simply use it for the resource reference as well. However I really prefer to keep these things out of the translation files, as it quickly becomes tedious and boring work to maintain it there.

Basically what I wanted was for both (and any future) sites to use the same set of resources, with the possibility to override any resource on a per locale basis. I wanted to control which resources to have localized versions for usng the filesystem only.

Example:

The resource has the following relative path:

/static/images/my-resource.png

So if I want to create a version for another locale I will just put it in a directory named after that locale in the same directory containing the original:

/static/images/en_IE/my-resource.png

I will then setup the webserver to see if a localized version of a requested resource exists, and if not fall back to the original and serve that.

I needed to set that up for both Flask for development, and in Nginx for production.

In Flask I set it up using the @app.before_request decorator:

#This should only be active in debug mode
if app.config['debug']:
    @app.before_request
    def localize_resources():
        if request.url_rule is not None and request.url_rule.rule == '/static/<path:filename>':
            filename = request.view_args['filename']
            parts = os.path.split(filename)
            localized_filename = os.path.join(parts[0], app.config['BABEL_DEFAULT_LOCALE'], parts[1])

            if os.path.isfile(os.path.join(app.static_folder, localized_filename)):
                return app.send_static_file(localized_filename)

In Nginx I used a location directive using a regular expression and the try_files statement

location ~ ^(/static.*/)([^/]*\.*)$ {
        root  /my-root-folder/;
        add_header "Access-Control-Allow-Origin" "*";
        add_header Cache-Control  "public, max-age=2678400";
        try_files $1en_IE/$2 $1$2 /404.html; 
}

Notice that using this approach in Nginx I have to set up each country individually, which is the way we do it any way, as they are separate sites and business units.

If you had one site with multiple languages, you could tell Nginx to look at the accept-language header instead to decide which subfolder to look in.

Et voilà! Now it's really easy to localize your graphic (or any other) resources you might want to.

Kommentarer

Populære opslag fra denne blog

Making the Canonical distribution of Kubernetes, deployed using juju, work with the vsphere cloud provider