Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make _make_new_gettext and _make_new_ngettext public #1323

Closed
dmoklaf opened this issue Dec 4, 2020 · 6 comments
Closed

Make _make_new_gettext and _make_new_ngettext public #1323

dmoklaf opened this issue Dec 4, 2020 · 6 comments

Comments

@dmoklaf
Copy link

dmoklaf commented Dec 4, 2020

I am currently using:
aiohttp
with aiohttp_jinja2
which provides integration with jinja2
with its i18n extension activated
with translations managed by babel
which is a superset of gettext

My goal is to implement per-HTTP-request localization of the messages.

I may have misunderstood how these 6 libraries interact together for i18n, but it seems it is not possible to internationalize template rendering per-request (ie with a different language for example for each HTTP request/response).
Calling jinja2.install_gettext_translations or jinja2.install_gettext_callables is not practical as they impact the entire HTTP environment (across all asynchronous requests/responses).

A temporary workaround for me as been to deploy into the context of each template rendering (the context dictionary argument) the gettext and ngettext methods from the translations object that fits this request's particular language.

This solution works as intended, as the context dictionary is local to each HTTP request. However this workaround has a limitation: I do not benefit from jinja i18n new-style message-formatting (with arguments) functionalities. These are provided by 2 private jinja2 functions which "wrap" gettext and ngettext to provide these new functionalities:
_make_new_gettext and _make_new_ngettext

A better solutioin is to provide an install_gettext_callables function that installs them in a context dictionary (and not in a global environment).

I hope I have not misunderstood jinja2's internal architecture and intent.

@davidism
Copy link
Member

davidism commented Dec 4, 2020

Sorry, I don't think I can help you with this. I have a feeling the issue is with gettext/babel not being unique to each async request, nothing to do with Jinja. I don't plan to make those patch functions public, do not rely on them continuing to exist.

@davidism davidism closed this as completed Dec 4, 2020
@dmoklaf
Copy link
Author

dmoklaf commented Dec 4, 2020

Are you suggesting the right solution is to provide a dedicated jinja environment to process each HTTP query instead of the current shared one?

If you confirrm that doing so is the usage intent of the jinja library, then I will move this ticket to aiohttp_jinja (because there a jinja environment is supposed to be global to an entire aiohttp web server so they will need to change that)

@davidism
Copy link
Member

davidism commented Dec 4, 2020

As stated above, I'm suggestion you look at how async interacts with gettext, not Jinja.

@dmoklaf
Copy link
Author

dmoklaf commented Dec 4, 2020

My (limited) understanding is that gettext and its wrapper babel do not have any issue with asyncio concurrency, if properly used. By properly, I mean, if I do not use the global gettext function but the gettext/babel.Translations.gettext methods on a set of gettext/babel.Translations pre-loaded (one per locale used by the website). This works great, you can have as many concurrent requests ongoing across many different locales, each locale having its own translation "context" properly isolated in a gettext/babel.Translations object. That's the workaround I am current using (writing myself the correct Translations.gettext method for that locale into the template context dictionary).

But jinja and aiiohttp_jinja2 seem to assume (specifically for new-style gettext extension functions) that a gettext/babel.Translations object is unique. This is not the case in a multilingual website.

@davidism
Copy link
Member

davidism commented Dec 4, 2020

Sorry, this is not the place to have this conversation. I know very little about async, aiohttp, gettext, or babel. All of those are other projects, not Jinja. This issue tracker is for issues with Jinja itself.

@dmoklaf
Copy link
Author

dmoklaf commented Dec 4, 2020

I quoted these libraries only to provide the full context of my analysis as I may be wrong, I am not an expert there.

But my point above is that the issue is indeed within Jinja i18n code, and has nothing to do with asyncio, gettext, babel or any other libraries. Because:

  • Jinja2 provides an i18n extension that provides better (new-style) gettext functions for jinja templating (this does not come from any other library, this is your invention and it is great)
  • However it restricts these to being global to the entire templating engine environment, thus imposing a single locale everywhere

These 2 points emanate from Jinja2 and no other library made these choices.

@pallets pallets locked and limited conversation to collaborators Dec 4, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants