2

I want to convert Flask-WTF SelectField value with Flask-Babel.

Here is the snippet of my code:

from flask_babel import _, lazy_gettext as _l

class PaymentStatus(enum.Enum):
    REJECTED = 'REJECTED'
    COMPLETED = 'COMPLETED'
    EXPIRED = 'EXPIRED'

    def __str__(self):
        return self.value

payment_status = [(str(y), y) for y in (PaymentStatus)]

def course_list():
    return Course.query.all()

class PaymentForm(FlaskForm):
    course_name = QuerySelectField(_l('Course name'), validators=[required()], query_factory=course_list)
    status_of_payment = SelectField(_l('Payment Status'), choices=payment_status)
    # ...
    # ...

There, I want to localization the SelectField choices value and QuerySelectField query_factory value with Flask-Babel.

Is it possible..?, if so, any example or refer tutorial would be appreciated :)

Machavity
  • 30,841
  • 27
  • 92
  • 100
Tri
  • 2,722
  • 5
  • 36
  • 65

1 Answers1

4

The SelectField choices could be handled by lazy_gettext().

Quote from The Flask Mega-Tutorial Part XIII: I18n and L10n

Some string literals are assigned outside of a request, usually when the application is starting up, so at the time these texts are evaluated there is no way to know what language to use.

Flask-Babel provides a lazy evaluation version of _() that is called lazy_gettext().

from flask_babel import lazy_gettext as _l

class LoginForm(FlaskForm):
    username = StringField(_l('Username'), validators=[DataRequired()])
    # ...

For choices

from flask_babel import _, lazy_gettext as _l

class PaymentStatus(enum.Enum):
    REJECTED = _l('REJECTED')
    COMPLETED = _l('COMPLETED')
    EXPIRED = _l('EXPIRED')

    def __str__(self):
        return self.value

QuerySelectField query_factory accepts values queried from the database. These values should not be handled by Flask-Babel/babel. Cause the database stores data outside the Python source code.

Possible solutions:

BTW, The Flask Mega-Tutorial made by Miguel Grinberg is a very famous Flask tutorial. All these situations are included in it.

Simba
  • 23,537
  • 7
  • 64
  • 76
  • Thanks for the nice answer @Simba :) – Tri Oct 01 '19 at 14:02
  • Yea, I learn a lot from Flask Mega Tutorial, that's very great tutorial from Miguel Grinberg :) – Tri Oct 01 '19 at 14:04
  • Imagine a language selector ```SelectField``` translated with Flask-Babel (e.g.: in English it would be something like: English, Spanish; but then in Spanish: español, inglés). What would it be the best way to sort the ```choices``` from the ```SelectField```? Go with JS like this: https://stackoverflow.com/a/278509/488019 ? – Daniel García Baena Nov 01 '22 at 13:54
  • I solved with this on `@app.route("/", methods=["GET", "POST"])` : `form.language.choices = sorted(constants.IETF_LANGUAGE_TAGS, key=lambda tuple: tuple[1])` – Daniel García Baena Nov 01 '22 at 17:44