librelist archives

« back to archive

Using Flask-WTF with Flask-Babel

Using Flask-WTF with Flask-Babel

From:
René Weiss
Date:
2012-09-03 @ 07:40
Hi

I try to use Flask-Babel to translate the messages from Flask-WTF.

At the moment i use the following code:

  class MyTranslations(object):
      def gettext(self, string):
          return gettext(string)

      def ngettext(self, singular, plural, n):
          return ngettext(singular, plural, n)


  class TranslatedFrom(wtf.Form):
      def _get_translations(self):
          return MyTranslations()

  class LoginForm(TranslatedFrom):
     [...]

This works for simple messages, but messages like this give a key error:

  #:
venv/lib/python2.7/site-packages/WTForms-1.0.1-py2.7.egg/wtforms/validators.py:90
  #, python-format
  msgid "Field must be at least %(min)d character long."
  msgid_plural "Field must be at least %(min)d characters long."
  msgstr[0] "Inhalt muss mindestens %(min)d Zeichen lang sein."
  msgstr[1] "Inhalt muss mindestens %(min)d Zeichen lang sein."

The error message:

  [...]
  File "/home/user/rw/pantask/pantask/pantask.py", line 38, in ngettext
    return ngettext(singular, plural, n, **variables)
  File
"/home/user/rw/pantask/venv/lib/python2.7/site-packages/flaskext/babel.py",
line 479, in ngettext
    return t.ungettext(singular, plural, num) % variables
KeyError: u'min'

I think the problem is that the Flask-Babel would need the variable "min"
as extra paramater like "ngettext(singular, plural, n, min=4)", but i have
no idea how to do this.

Can someone please show me the correct way to use Flask-WTF & Flask-Babel?

Thanks.

René

Re: [flask] Using Flask-WTF with Flask-Babel

From:
Alexander Jung-Loddenkemper
Date:
2012-09-03 @ 10:53
Hey Rene,

i am not exactly sure what you are doing here, but at first I would 
recommend you to use lazy_gettext, because otherwise the Fields will not 
be properly translated, when they are used, but on initialization of the 
app.

Secondly I think you are making things more complicated then necessary, 
but that is just my guess, just explain a little more, what you want to 
do, if I missed something:

You can just translate a form like this:

class LoginForm(Form):
name = fields.TextField(lazy_gettext('Username'), [validators.Required()])
password = fields.PasswordField(lazy_gettext('Password'), [validators.Required()])

In regards of your actual problem, I do not really see what it is about? 
Do you just do not now how to pass the parameter? Or do you need a dynamic
value in your form and do not now how make that work? As you did not show,
how you are actually using your classes, this is difficult to figure out.

Best regards,
Alex


--  
Alexander Jung-Loddenkemper


Am Montag, 3. September 2012 um 09:40 schrieb René Weiss:

> Hi
>  
> I try to use Flask-Babel to translate the messages from Flask-WTF.
>  
> At the moment i use the following code:
>  
> class MyTranslations(object):
> def gettext(self, string):
> return gettext(string)
>  
> def ngettext(self, singular, plural, n):
> return ngettext(singular, plural, n)
>  
>  
> class TranslatedFrom(wtf.Form):
> def _get_translations(self):
> return MyTranslations()
>  
> class LoginForm(TranslatedFrom):
> [...]
>  
> This works for simple messages, but messages like this give a key error:
>  
> #:
> 
venv/lib/python2.7/site-packages/WTForms-1.0.1-py2.7.egg/wtforms/validators.py:90
> #, python-format
> msgid "Field must be at least %(min)d character long."
> msgid_plural "Field must be at least %(min)d characters long."
> msgstr[0] "Inhalt muss mindestens %(min)d Zeichen lang sein."
> msgstr[1] "Inhalt muss mindestens %(min)d Zeichen lang sein."
>  
> The error message:
>  
> [...]
> File "/home/user/rw/pantask/pantask/pantask.py", line 38, in ngettext
> return ngettext(singular, plural, n, **variables)
> File
> "/home/user/rw/pantask/venv/lib/python2.7/site-packages/flaskext/babel.py",
> line 479, in ngettext
> return t.ungettext(singular, plural, num) % variables
> KeyError: u'min'
>  
> I think the problem is that the Flask-Babel would need the variable "min"
> as extra paramater like "ngettext(singular, plural, n, min=4)", but i have
> no idea how to do this.
>  
> Can someone please show me the correct way to use Flask-WTF & Flask-Babel?
>  
> Thanks.
>  
> René  

Re: [flask] Using Flask-WTF with Flask-Babel

From:
René Weiss
Date:
2012-09-03 @ 11:24
Hi Alex

I try to translate the error messages that Flask-WTF/WTForms generates
when the content of a field is invalid.

So instead of: "Field must be at least 6 characters long." the error
messages should be in german and read "Inhalt muss mindestens 6 Zeichen
lang sein."

It is not about the translating of the labels of the fields.

Best regards,
René

Am Mo, 3.09.2012, 12:53 schrieb Alexander Jung-Loddenkemper:
> Hey Rene,
>
> i am not exactly sure what you are doing here, but at first I would
> recommend you to use lazy_gettext, because otherwise the Fields will not
> be properly translated, when they are used, but on initialization of the
> app.
>
> Secondly I think you are making things more complicated then necessary,
> but that is just my guess, just explain a little more, what you want to
> do, if I missed something:
>
> You can just translate a form like this:
>
> class LoginForm(Form):
> name = fields.TextField(lazy_gettext('Username'), [validators.Required()])
> password = fields.PasswordField(lazy_gettext('Password'),
> [validators.Required()])
>
> In regards of your actual problem, I do not really see what it is about?
> Do you just do not now how to pass the parameter? Or do you need a dynamic
> value in your form and do not now how make that work? As you did not show,
> how you are actually using your classes, this is difficult to figure out.
>
> Best regards,
> Alex
>
>
> --
> Alexander Jung-Loddenkemper
>
>
> Am Montag, 3. September 2012 um 09:40 schrieb René Weiss:
>
>> Hi
>>
>> I try to use Flask-Babel to translate the messages from Flask-WTF.
>>
>> At the moment i use the following code:
>>
>> class MyTranslations(object):
>> def gettext(self, string):
>> return gettext(string)
>>
>> def ngettext(self, singular, plural, n):
>> return ngettext(singular, plural, n)
>>
>>
>> class TranslatedFrom(wtf.Form):
>> def _get_translations(self):
>> return MyTranslations()
>>
>> class LoginForm(TranslatedFrom):
>> [...]
>>
>> This works for simple messages, but messages like this give a key error:
>>
>> #:
>> 
venv/lib/python2.7/site-packages/WTForms-1.0.1-py2.7.egg/wtforms/validators.py:90
>> #, python-format
>> msgid "Field must be at least %(min)d character long."
>> msgid_plural "Field must be at least %(min)d characters long."
>> msgstr[0] "Inhalt muss mindestens %(min)d Zeichen lang sein."
>> msgstr[1] "Inhalt muss mindestens %(min)d Zeichen lang sein."
>>
>> The error message:
>>
>> [...]
>> File "/home/user/rw/pantask/pantask/pantask.py", line 38, in ngettext
>> return ngettext(singular, plural, n, **variables)
>> File
>> "/home/user/rw/pantask/venv/lib/python2.7/site-packages/flaskext/babel.py",
>> line 479, in ngettext
>> return t.ungettext(singular, plural, num) % variables
>> KeyError: u'min'
>>
>> I think the problem is that the Flask-Babel would need the variable
>> "min"
>> as extra paramater like "ngettext(singular, plural, n, min=4)", but i
>> have
>> no idea how to do this.
>>
>> Can someone please show me the correct way to use Flask-WTF &
>> Flask-Babel?
>>
>> Thanks.
>>
>> René
>
>

Re: [flask] Using Flask-WTF with Flask-Babel

From:
Alexander Jung-Loddenkemper
Date:
2012-09-03 @ 11:34
According to the source 
(https://bitbucket.org/simplecodes/wtforms/src/113994790508/wtforms/validators.py)
the validators are translatable already. You can see the gettext calls. 
Unfortunately I am not source how to supply the translations for that, but
you might be able to find that out with a little research. If you do, It 
would nice to write another message and explain it.

--  
Alexander Jung-Loddenkemper


Am Montag, 3. September 2012 um 13:24 schrieb René Weiss:

> Hi Alex
>  
> I try to translate the error messages that Flask-WTF/WTForms generates
> when the content of a field is invalid.
>  
> So instead of: "Field must be at least 6 characters long." the error
> messages should be in german and read "Inhalt muss mindestens 6 Zeichen
> lang sein."
>  
> It is not about the translating of the labels of the fields.
>  
> Best regards,
> René
>  
> Am Mo, 3.09.2012, 12:53 schrieb Alexander Jung-Loddenkemper:
> > Hey Rene,
> >  
> > i am not exactly sure what you are doing here, but at first I would
> > recommend you to use lazy_gettext, because otherwise the Fields will not
> > be properly translated, when they are used, but on initialization of the
> > app.
> >  
> > Secondly I think you are making things more complicated then necessary,
> > but that is just my guess, just explain a little more, what you want to
> > do, if I missed something:
> >  
> > You can just translate a form like this:
> >  
> > class LoginForm(Form):
> > name = fields.TextField(lazy_gettext('Username'), [validators.Required()])
> > password = fields.PasswordField(lazy_gettext('Password'),
> > [validators.Required()])
> >  
> > In regards of your actual problem, I do not really see what it is about?
> > Do you just do not now how to pass the parameter? Or do you need a dynamic
> > value in your form and do not now how make that work? As you did not show,
> > how you are actually using your classes, this is difficult to figure out.
> >  
> > Best regards,
> > Alex
> >  
> >  
> > --
> > Alexander Jung-Loddenkemper
> >  
> >  
> > Am Montag, 3. September 2012 um 09:40 schrieb René Weiss:
> >  
> > > Hi
> > >  
> > > I try to use Flask-Babel to translate the messages from Flask-WTF.
> > >  
> > > At the moment i use the following code:
> > >  
> > > class MyTranslations(object):
> > > def gettext(self, string):
> > > return gettext(string)
> > >  
> > > def ngettext(self, singular, plural, n):
> > > return ngettext(singular, plural, n)
> > >  
> > >  
> > > class TranslatedFrom(wtf.Form):
> > > def _get_translations(self):
> > > return MyTranslations()
> > >  
> > > class LoginForm(TranslatedFrom):
> > > [...]
> > >  
> > > This works for simple messages, but messages like this give a key error:
> > >  
> > > #:
> > > 
venv/lib/python2.7/site-packages/WTForms-1.0.1-py2.7.egg/wtforms/validators.py:90
> > > #, python-format
> > > msgid "Field must be at least %(min)d character long."
> > > msgid_plural "Field must be at least %(min)d characters long."
> > > msgstr[0] "Inhalt muss mindestens %(min)d Zeichen lang sein."
> > > msgstr[1] "Inhalt muss mindestens %(min)d Zeichen lang sein."
> > >  
> > > The error message:
> > >  
> > > [...]
> > > File "/home/user/rw/pantask/pantask/pantask.py", line 38, in ngettext
> > > return ngettext(singular, plural, n, **variables)
> > > File
> > > "/home/user/rw/pantask/venv/lib/python2.7/site-packages/flaskext/babel.py",
> > > line 479, in ngettext
> > > return t.ungettext(singular, plural, num) % variables
> > > KeyError: u'min'
> > >  
> > > I think the problem is that the Flask-Babel would need the variable
> > > "min"
> > > as extra paramater like "ngettext(singular, plural, n, min=4)", but i
> > > have
> > > no idea how to do this.
> > >  
> > > Can someone please show me the correct way to use Flask-WTF &
> > > Flask-Babel?
> > >  
> > > Thanks.
> > >  
> > > René  

Re: [flask] Using Flask-WTF with Flask-Babel

From:
René Weiss
Date:
2012-09-03 @ 12:10
Hi Alex

I know that they are translatable, and i have it already working with
simple strings like "This field is required.".

What doesn't work are strings that uses variables like "%(min)d" in "Field
must be at least %(min)d characters long.".

My partial working solution subclasses wtf.Forms to use the
gettext/ngettext functions of Flask-Babel:

    class MyTranslations(object):
        def gettext(self, string):
            return gettext(string)

        def ngettext(self, singular, plural, n):
            return ngettext(singular, plural, n)


    class TranslatedFrom(wtf.Form):
        def _get_translations(self):
            return MyTranslations()

(http://wtforms.simplecodes.com/docs/1.0.2/i18n.html)

I think the problem is that the (n)gettext from Flask-Babel
(http://packages.python.org/Flask-Babel/#flaskext.babel.gettext)
has the additional parameter "**variables" which the normal
gettext hasn't.

Because this is my first try to use gettext/i18n framework
i dont know if it is still possible to use Flask-Babel
or if i have to learn how to do it with the "normal"
gettext/ngettext functions.

Am Mo, 3.09.2012, 13:34 schrieb Alexander Jung-Loddenkemper:
> According to the source
> 
(https://bitbucket.org/simplecodes/wtforms/src/113994790508/wtforms/validators.py)
> the validators are translatable already. You can see the gettext calls.
> Unfortunately I am not source how to supply the translations for that, but
> you might be able to find that out with a little research. If you do, It
> would nice to write another message and explain it.
>
> --
> Alexander Jung-Loddenkemper
>
>
> Am Montag, 3. September 2012 um 13:24 schrieb René Weiss:
>
>> Hi Alex
>>
>> I try to translate the error messages that Flask-WTF/WTForms generates
>> when the content of a field is invalid.
>>
>> So instead of: "Field must be at least 6 characters long." the error
>> messages should be in german and read "Inhalt muss mindestens 6 Zeichen
>> lang sein."
>>
>> It is not about the translating of the labels of the fields.
>>
>> Best regards,
>> René
>>
>> Am Mo, 3.09.2012, 12:53 schrieb Alexander Jung-Loddenkemper:
>> > Hey Rene,
>> >
>> > i am not exactly sure what you are doing here, but at first I would
>> > recommend you to use lazy_gettext, because otherwise the Fields will
>> not
>> > be properly translated, when they are used, but on initialization of
>> the
>> > app.
>> >
>> > Secondly I think you are making things more complicated then
>> necessary,
>> > but that is just my guess, just explain a little more, what you want
>> to
>> > do, if I missed something:
>> >
>> > You can just translate a form like this:
>> >
>> > class LoginForm(Form):
>> > name = fields.TextField(lazy_gettext('Username'),
>> [validators.Required()])
>> > password = fields.PasswordField(lazy_gettext('Password'),
>> > [validators.Required()])
>> >
>> > In regards of your actual problem, I do not really see what it is
>> about?
>> > Do you just do not now how to pass the parameter? Or do you need a
>> dynamic
>> > value in your form and do not now how make that work? As you did not
>> show,
>> > how you are actually using your classes, this is difficult to figure
>> out.
>> >
>> > Best regards,
>> > Alex
>> >
>> >
>> > --
>> > Alexander Jung-Loddenkemper
>> >
>> >
>> > Am Montag, 3. September 2012 um 09:40 schrieb René Weiss:
>> >
>> > > Hi
>> > >
>> > > I try to use Flask-Babel to translate the messages from Flask-WTF.
>> > >
>> > > At the moment i use the following code:
>> > >
>> > > class MyTranslations(object):
>> > > def gettext(self, string):
>> > > return gettext(string)
>> > >
>> > > def ngettext(self, singular, plural, n):
>> > > return ngettext(singular, plural, n)
>> > >
>> > >
>> > > class TranslatedFrom(wtf.Form):
>> > > def _get_translations(self):
>> > > return MyTranslations()
>> > >
>> > > class LoginForm(TranslatedFrom):
>> > > [...]
>> > >
>> > > This works for simple messages, but messages like this give a key
>> error:
>> > >
>> > > #:
>> > > 
venv/lib/python2.7/site-packages/WTForms-1.0.1-py2.7.egg/wtforms/validators.py:90
>> > > #, python-format
>> > > msgid "Field must be at least %(min)d character long."
>> > > msgid_plural "Field must be at least %(min)d characters long."
>> > > msgstr[0] "Inhalt muss mindestens %(min)d Zeichen lang sein."
>> > > msgstr[1] "Inhalt muss mindestens %(min)d Zeichen lang sein."
>> > >
>> > > The error message:
>> > >
>> > > [...]
>> > > File "/home/user/rw/pantask/pantask/pantask.py", line 38, in
>> ngettext
>> > > return ngettext(singular, plural, n, **variables)
>> > > File
>> > > "/home/user/rw/pantask/venv/lib/python2.7/site-packages/flaskext/babel.py",
>> > > line 479, in ngettext
>> > > return t.ungettext(singular, plural, num) % variables
>> > > KeyError: u'min'
>> > >
>> > > I think the problem is that the Flask-Babel would need the variable
>> > > "min"
>> > > as extra paramater like "ngettext(singular, plural, n, min=4)", but
>> i
>> > > have
>> > > no idea how to do this.
>> > >
>> > > Can someone please show me the correct way to use Flask-WTF &
>> > > Flask-Babel?
>> > >
>> > > Thanks.
>> > >
>> > > René
>
>

Re: [flask] Using Flask-WTF with Flask-Babel

From:
Rene Weiss
Date:
2012-09-04 @ 17:53
Hi

It works now.

I removed flask-babel and my new MyTranslations class looks like this:

class MyTranslations(object):
    def __init__(self):
        self.lang = gettext.translation("messages", "translations", \
                                         ["de"])

    def gettext(self, string):
        return unicode(self.lang.gettext(string), "utf8")

    def ngettext(self, singular, plural, n):
        return unicode(self.lang.ngettext(singular, plural, n), "utf8")


Best regards,
René

Am 09/03/2012 02:10 PM, schrieb René Weiss:
> Hi Alex
> 
> I know that they are translatable, and i have it already working with
> simple strings like "This field is required.".
> 
> What doesn't work are strings that uses variables like "%(min)d" in "Field
> must be at least %(min)d characters long.".
> 
> My partial working solution subclasses wtf.Forms to use the
> gettext/ngettext functions of Flask-Babel:
> 
>     class MyTranslations(object):
>         def gettext(self, string):
>             return gettext(string)
> 
>         def ngettext(self, singular, plural, n):
>             return ngettext(singular, plural, n)
> 
> 
>     class TranslatedFrom(wtf.Form):
>         def _get_translations(self):
>             return MyTranslations()
> 
> (http://wtforms.simplecodes.com/docs/1.0.2/i18n.html)
> 
> I think the problem is that the (n)gettext from Flask-Babel
> (http://packages.python.org/Flask-Babel/#flaskext.babel.gettext)
> has the additional parameter "**variables" which the normal
> gettext hasn't.
> 
> Because this is my first try to use gettext/i18n framework
> i dont know if it is still possible to use Flask-Babel
> or if i have to learn how to do it with the "normal"
> gettext/ngettext functions.
> 
> Am Mo, 3.09.2012, 13:34 schrieb Alexander Jung-Loddenkemper:
>> According to the source
>> 
(https://bitbucket.org/simplecodes/wtforms/src/113994790508/wtforms/validators.py)
>> the validators are translatable already. You can see the gettext calls.
>> Unfortunately I am not source how to supply the translations for that, but
>> you might be able to find that out with a little research. If you do, It
>> would nice to write another message and explain it.
>>
>> --
>> Alexander Jung-Loddenkemper
>>
>>
>> Am Montag, 3. September 2012 um 13:24 schrieb René Weiss:
>>
>>> Hi Alex
>>>
>>> I try to translate the error messages that Flask-WTF/WTForms generates
>>> when the content of a field is invalid.
>>>
>>> So instead of: "Field must be at least 6 characters long." the error
>>> messages should be in german and read "Inhalt muss mindestens 6 Zeichen
>>> lang sein."
>>>
>>> It is not about the translating of the labels of the fields.
>>>
>>> Best regards,
>>> René
>>>
>>> Am Mo, 3.09.2012, 12:53 schrieb Alexander Jung-Loddenkemper:
>>>> Hey Rene,
>>>>
>>>> i am not exactly sure what you are doing here, but at first I would
>>>> recommend you to use lazy_gettext, because otherwise the Fields will
>>> not
>>>> be properly translated, when they are used, but on initialization of
>>> the
>>>> app.
>>>>
>>>> Secondly I think you are making things more complicated then
>>> necessary,
>>>> but that is just my guess, just explain a little more, what you want
>>> to
>>>> do, if I missed something:
>>>>
>>>> You can just translate a form like this:
>>>>
>>>> class LoginForm(Form):
>>>> name = fields.TextField(lazy_gettext('Username'),
>>> [validators.Required()])
>>>> password = fields.PasswordField(lazy_gettext('Password'),
>>>> [validators.Required()])
>>>>
>>>> In regards of your actual problem, I do not really see what it is
>>> about?
>>>> Do you just do not now how to pass the parameter? Or do you need a
>>> dynamic
>>>> value in your form and do not now how make that work? As you did not
>>> show,
>>>> how you are actually using your classes, this is difficult to figure
>>> out.
>>>>
>>>> Best regards,
>>>> Alex
>>>>
>>>>
>>>> --
>>>> Alexander Jung-Loddenkemper
>>>>
>>>>
>>>> Am Montag, 3. September 2012 um 09:40 schrieb René Weiss:
>>>>
>>>>> Hi
>>>>>
>>>>> I try to use Flask-Babel to translate the messages from Flask-WTF.
>>>>>
>>>>> At the moment i use the following code:
>>>>>
>>>>> class MyTranslations(object):
>>>>> def gettext(self, string):
>>>>> return gettext(string)
>>>>>
>>>>> def ngettext(self, singular, plural, n):
>>>>> return ngettext(singular, plural, n)
>>>>>
>>>>>
>>>>> class TranslatedFrom(wtf.Form):
>>>>> def _get_translations(self):
>>>>> return MyTranslations()
>>>>>
>>>>> class LoginForm(TranslatedFrom):
>>>>> [...]
>>>>>
>>>>> This works for simple messages, but messages like this give a key
>>> error:
>>>>>
>>>>> #:
>>>>> 
venv/lib/python2.7/site-packages/WTForms-1.0.1-py2.7.egg/wtforms/validators.py:90
>>>>> #, python-format
>>>>> msgid "Field must be at least %(min)d character long."
>>>>> msgid_plural "Field must be at least %(min)d characters long."
>>>>> msgstr[0] "Inhalt muss mindestens %(min)d Zeichen lang sein."
>>>>> msgstr[1] "Inhalt muss mindestens %(min)d Zeichen lang sein."
>>>>>
>>>>> The error message:
>>>>>
>>>>> [...]
>>>>> File "/home/user/rw/pantask/pantask/pantask.py", line 38, in
>>> ngettext
>>>>> return ngettext(singular, plural, n, **variables)
>>>>> File
>>>>> "/home/user/rw/pantask/venv/lib/python2.7/site-packages/flaskext/babel.py",
>>>>> line 479, in ngettext
>>>>> return t.ungettext(singular, plural, num) % variables
>>>>> KeyError: u'min'
>>>>>
>>>>> I think the problem is that the Flask-Babel would need the variable
>>>>> "min"
>>>>> as extra paramater like "ngettext(singular, plural, n, min=4)", but
>>> i
>>>>> have
>>>>> no idea how to do this.
>>>>>
>>>>> Can someone please show me the correct way to use Flask-WTF &
>>>>> Flask-Babel?
>>>>>
>>>>> Thanks.
>>>>>
>>>>> René
>>
>>
> 
>