Skip to content

Unable to select locale when using Flask's app factory pattern and Flask-Babel 3+ #232

@nickjj

Description

@nickjj

Hi,

I've been using Flask-Babel 2.x for a long time and when using @babel.localeselector along with the app factory pattern I was able to successfully select a locale from the current user.

Now I've updated to Flask-Babel 3.1.x and when I do this:

# extensions.py

from flask import request
from flask_babel import Babel
from flask_login import current_user


def get_locale():
    if current_user.is_authenticated:
        return current_user.locale

    return request.accept_languages.best_match(["en", "es"])


babel = Babel(locale_selector=get_locale)
# app.py

from extensions import babel


def create_app():
    app = Flask(__name__)

    babel.init_app(app)

My application loads successfully but when I set the locale on the current user, it's never selected. It always uses the default locale which I have defined with BABEL_DEFAULT_LOCALE = "en".

I've also tried to set the parameter like this instead of at Babel() instantiation time:

    babel.init_app(app, locale_selector=get_locale)

It results in the same issue of the new locale never being selected.

If I drop a print statement into the get_locale function, it never gets called. I also went as far as putting a print statement on the first line within this function:

def get_locale() -> Optional[Locale]:

And it doesn't print out when I reload any page.

I noticed a while back someone had the same issue which they mentioned on StackOverflow https://stackoverflow.com/questions/76539307/flask-babel-in-flask-app-factory-method-not-translating-text-but-does-translate but it didn't receive any replies. This SO question mentions everything works fine when you're not using an app factory pattern which is what the documentation has. There's no examples in the docs for using an app factory pattern and defining this parameter.

This project's integration tests at https://github.com/python-babel/flask-babel/blob/master/tests/test_integration.py don't define locale_selector but they do use an app factory pattern. The tests at https://github.com/python-babel/flask-babel/blob/master/tests/test_force_locale.py do define locale_selector but don't use an app factory pattern. This leaves defining locale_selector when using an app factory an untested code path which may have a bug?

Any suggestions on how to get this to work? Thanks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions