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"
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/
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/ >