Skip to content

flask-wtf i18n does not work without flask-babel #582

@azmeuk

Description

@azmeuk

wtforms has no hard dependency to babel/flask-babel, and translations work out of the box when properly configured, e.g. Form(flask.request.form, meta={"locales": ["fr"]})

However translations for a simple flask-wtf form with the same configuration won't work, unless flask-babel is installed and initialized.

This behavior feels unexpected, and adds an unnecessary dependency against flask-babel for non-English applications.

This can be fixed by manually setting WTF_I18N_ENABLED to False. Maybe WTF_I18N_ENABLED should default to True only if flask-babel is installed and False otherwise?

vanilla wtforms

assertions pass

import flask
import wtforms


class Form(wtforms.Form):
    email = wtforms.EmailField(validators=[wtforms.validators.Email()])


app = flask.Flask(__name__)


@app.route("/", methods=["GET", "POST"])
def index():
    form = Form(flask.request.form, meta={"locales": ["fr"]})
    form.validate()
    return form.errors


res = app.test_client().post("/", data={"email": "invalid-email"})
assert "Invalid email address." not in res.json["email"]
assert "Adresse électronique non valide." in res.json["email"]

flask-wtf without flask-babel

assertions fail

import flask
import wtforms
import flask_wtf


class Form(flask_wtf.FlaskForm):
    email = wtforms.EmailField(validators=[wtforms.validators.Email()])


app = flask.Flask(__name__)
app.config["WTF_CSRF_ENABLED"] = False


@app.route("/", methods=["GET", "POST"])
def index():
    form = Form(flask.request.form, meta={"locales": ["fr"]})
    form.validate()
    return form.errors


res = app.test_client().post("/", data={"email": "invalid-email"})
assert "Invalid email address." not in res.json["email"]
assert "Adresse électronique non valide." in res.json["email"]

flask-wtf with flask-babel

assertions pass

import flask
import wtforms
import flask_wtf
import flask_babel


class Form(flask_wtf.FlaskForm):
    email = wtforms.EmailField(validators=[wtforms.validators.Email()])


app = flask.Flask(__name__)
app.config["WTF_CSRF_ENABLED"] = False

babel = flask_babel.Babel()
babel.init_app(app, locale_selector=lambda: "fr")

@app.route("/", methods=["GET", "POST"])
def index():
    form = Form(flask.request.form, meta={"locales": ["fr"]})
    form.validate()
    return form.errors


res = app.test_client().post("/", data={"email": "invalid-email"})
assert "Invalid email address." not in res.json["email"]
assert "Adresse électronique non valide." in res.json["email"]

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions