librelist archives

« back to archive

WTForms and i18n

WTForms and i18n

From:
Wara Songkran
Date:
2010-08-30 @ 17:10
I've been learning to i18n FlaskWTF with Flask-Babel but I can't get
form's label and form's error message to be translated. Please note
that success message ("Your age are...") is properly translated.

== view.py ==
from flask import Flask, request, render_template
from flaskext.wtf import Form, DecimalField, Required
from flaskext.babel import Babel, gettext as _

app = Flask(__name__)
app.config['SECRET_KEY'] = 'key'
app.config['CSRF_ENABLED'] = False
app.config['BABEL_DEFAULT_LOCALE'] = 'de'
babel = Babel(app)

class AgeForm(Form):
    age = DecimalField(
        _(u'Age'),
        validators=[Required(message=_('Please input age.'))]
    )

@app.route('/', methods=['GET', 'POST'])
def age():
    form = AgeForm(request.form)
    if request.method == 'POST' and form.validate():
        return _(u'Your are %(age)s years old.', age=request.form['age'])
    return render_template('age.html', form=form)

if __name__ == '__main__':
    app.run(debug=True)

== templates/age.html ==
{% if form.errors %}
<p>{{ form.errors['age'][0] }}</p>
{% endif %}
<form method="POST" action=".">
	{{ form.age.label }} {{ form.age }}
	<input type="submit" value="submit" />
</form>

== translations/de/LC_MESSAGES/messages.po ==
# German translations for PROJECT.
# Copyright (C) 2010 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
#
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2010-08-30 23:32+0700\n"
"PO-Revision-Date: 2010-08-30 23:32+0700\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: de <LL@li.org>\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 0.9.5\n"

#: views.py:13
msgid "Age"
msgstr "Alter"

#: views.py:14
msgid "Please input age."
msgstr "Bitte geben Sie Alter"

#: views.py:21
#, python-format
msgid "Your are %(age)s years old."
msgstr "Du bist %(age)s Jahre alt"

Re: [flask] WTForms and i18n

From:
LeafStorm
Date:
2010-08-30 @ 20:36
On 08/30/2010 01:10 PM, Wara Songkran wrote:
> I've been learning to i18n FlaskWTF with Flask-Babel but I can't get
> form's label and form's error message to be translated. Please note
> that success message ("Your age are...") is properly translated.

The problem is that you're using immediate lookup on the translations. 
Instead of being looked up at request time, the translation is being 
looked up when the module is imported, and since the translations 
haven't been set up yet, it just returns the string.

What you want to do for any translation not directly in a view function 
(in forms, models, whatever) is to use lazy_gettext instead of gettext. 
For example:

from flaskext.babel import Babel, gettext as _, lazy_gettext as __
# your code
class AgeForm(Form):
     age = DecimalField(
         __(u'Age'),
         validators=[Required(message=__(u'Please input age.'))]
     )

Using lazy_gettext instead of gettext creates a lazy string object that 
delays the lookup until the string is actually displayed, when the 
translations *will* be available. (Note that to properly extract the 
translations, you will need to add "-k __" to the options of your 
"pybabel extract" command so it recognizes them.)

Still, only use the lazy translations outside view functions. Using it 
inside view functions has caused problems for me in the past.

Also, a few minor points not directly related to your problem:

- I would use an IntegerField for ages instead of a DecimalField. (Or 
just use a DateTimeField and have them enter their birthdate.)

- In "Your are %(age)s years old.", you should use "You" instead of 
"Your". You is the second-person subject pronoun ("You have a bicycle"), 
your is the possessive adjective ("Your bicycle").
-- 
Regards, Matthew "LeafStorm" Frazier
http://leafstorm.us/

Re: [flask] WTForms and i18n

From:
Wara Songkran
Date:
2010-08-31 @ 04:07
ah..., thank you for your help. I'm trying to understand more about
how gettext work. could you please point me to an article or
discussion.

On Tue, Aug 31, 2010 at 3:36 AM, LeafStorm <leafstormrush@gmail.com> wrote:
> On 08/30/2010 01:10 PM, Wara Songkran wrote:
>> I've been learning to i18n FlaskWTF with Flask-Babel but I can't get
>> form's label and form's error message to be translated. Please note
>> that success message ("Your age are...") is properly translated.
>
> The problem is that you're using immediate lookup on the translations.
> Instead of being looked up at request time, the translation is being
> looked up when the module is imported, and since the translations
> haven't been set up yet, it just returns the string.
>
> What you want to do for any translation not directly in a view function
> (in forms, models, whatever) is to use lazy_gettext instead of gettext.
> For example:
>
> from flaskext.babel import Babel, gettext as _, lazy_gettext as __
> # your code
> class AgeForm(Form):
>     age = DecimalField(
>         __(u'Age'),
>         validators=[Required(message=__(u'Please input age.'))]
>     )
>
> Using lazy_gettext instead of gettext creates a lazy string object that
> delays the lookup until the string is actually displayed, when the
> translations *will* be available. (Note that to properly extract the
> translations, you will need to add "-k __" to the options of your
> "pybabel extract" command so it recognizes them.)
>
> Still, only use the lazy translations outside view functions. Using it
> inside view functions has caused problems for me in the past.
>
> Also, a few minor points not directly related to your problem:
>
> - I would use an IntegerField for ages instead of a DecimalField. (Or
> just use a DateTimeField and have them enter their birthdate.)
>
> - In "Your are %(age)s years old.", you should use "You" instead of
> "Your". You is the second-person subject pronoun ("You have a bicycle"),
> your is the possessive adjective ("Your bicycle").
> --
> Regards, Matthew "LeafStorm" Frazier
> http://leafstorm.us/
>