Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask-Babel localized strings within js

I'm pretty new to both Python and Flask (with Jinja2 as template engine) and I am not sure I am doing it the right way. I am using Flask-Babel extension to add i18n support to my web application. I want to get localized strings from my js code, for instance:

var helloWorld = gettext('Hello, world');
console.log(helloWorld); //should log a localized hello world message

For this, I configured babel (babel.cfg):

[python: **/**.py]
[jinja2: **/**.html]
extensions=jinja2.ext.autoescape,jinja2.ext.with_
[javascript: **/**.js]
encoding = utf-8

And its initialization is (imports omitted for simplicity):

#main Flask app
app = Flask(__name__)

#localization
babel = Babel(app)

LANGUAGES = {
    'ca': 'Catalan',
    'en': 'English',
    'de': 'Deutsch',
    'es': 'Español',
    'fi': 'Finnish',
    'it': 'Italian'
}

@babel.localeselector
def get_locale():
    return request.accept_languages.best_match(LANGUAGES.keys())

#some more stuff...

Babel identifies that string when building the POT/PO language files, but it seems I can't access these localized strings from js code since gettext function is not defined. It seems like Jinja2 is ignoring this part.

Any hints?

like image 334
jarandaf Avatar asked Mar 12 '14 15:03

jarandaf


1 Answers

I have finally found a solution, although I am not sure it is the way to go. The idea is to wrap the javascript code within an html template, which is interpretated by Jinja2 before it is rendered and apply a custom Jinja2 filter to get rid of some minor issues. I tried to keep js files separately but it did not work.

It seems that gettext function can be used like so:

var helloWorld = {{gettext('Hello, world')}};

But then, no quotes are inserted, and hence, js interpreter throws an error:

var helloWorld = Hello, world;

That's why I have finally applied a custom filter. A working example would be as follows.

hello_world.html:

<script type="text/javascript">
   var x = {{gettext('Hello, world')|generate_string|safe}};
   console.log(x);    //logs the localized hello world message
</script>

app.py:

#Jinja2 filters
from jinja2 import evalcontextfilter, Markup

#Mind the hack! Babel does not work well within js code
@app.template_filter()
@evalcontextfilter
def generate_string(eval_ctx, localized_value):
    if localized_value is None:
        return ""
    else:
        return Markup("\"" + localized_value + "\"").unescape()

Hope this helps!

like image 61
jarandaf Avatar answered Oct 15 '22 21:10

jarandaf