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"]
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
toFalse
. MaybeWTF_I18N_ENABLED
should default toTrue
only if flask-babel is installed andFalse
otherwise?vanilla wtforms
assertions pass
flask-wtf without flask-babel
assertions fail
flask-wtf with flask-babel
assertions pass