Implements i18n and l10n support for Flask. This is based on the Python babel and pytz modules.
The latest documentation is available here.
i18n and l10n support for Flask based on Babel and pytz
Home Page: https://python-babel.github.io/flask-babel/
License: Other
I'm running into a strange problem where the pybabel extractor detects translations in an irregular pattern inside jsx files.
First off all, my babel.cfg looks like this:
[javascript:**.jsx]
encoding = utf-8
[jinja2: **/templates/**.html]
extensions=jinja2.ext.autoescape,jinja2.ext.with_
Then take this example jsx file, which is nonsensical, but works as a test:
export class HomeView extends React.Component {
render () {
let n = 1
return (
<div className='container text-center'>
<p>
{gettext('String1')}
</p>
<p>
{gettext('String2')}
</p>
</div>
)
}
}
The result here is that I get a .pot file where only the first string is detected:
# Translations template for PROJECT.
# Copyright (C) 2015 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2015-12-23 11:22+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.1.1\n"
#: beavy/jsbeavy/views/HomeView.jsx:10
msgid "String1"
msgstr ""
Does anyone have any insight into this problem?
The flask-babel docs only show how to use it with the _("foo %(bar)s", bar="baz") style.
Maybe one should add documentation about how to use it with unicode.format() method.
Hello,
In my tiny new Flask application, importing 'flask.ext.babel' takes relatively long time (~8 seconds). Is there a way to improve it?
Trying to pin-point the problem, I did this:
$ python
Python 2.7 (r27:82500, Apr 6 2013, 21:24:05)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import flask
>>> import babel
>>> import pytz
>>> import flask.ext.babel
All except the last "import" completes instantaneously. But the last import of 'flask.ext.babel' takes about 8 seconds (this is before any of my Flask code actually runs).
I'm using this version:
$ pip show flask-babel
---
Name: Flask-Babel
Version: 0.9
Location: /usr/local/lib/python2.7/site-packages
Requires: Flask, Babel, speaklater, Jinja2
Any suggestions ?
Thanks,
-gordon
TypeError is being thrown:
$ pybabel update -i messages.pot -d translations/
updating catalog 'translations/en/LC_MESSAGES/messages.po' based on 'messages.pot'
Traceback (most recent call last):
File "/home/georg/env/main/bin/pybabel", line 9, in <module>
load_entry_point('Babel==1.3', 'console_scripts', 'pybabel')()
File "/home/georg/env/main/lib/python3.3/site-packages/babel/messages/frontend.py", line 1151, in main
return CommandLineInterface().run(sys.argv)
File "/home/georg/env/main/lib/python3.3/site-packages/babel/messages/frontend.py", line 665, in run
return getattr(self, cmdname)(args[1:])
File "/home/georg/env/main/lib/python3.3/site-packages/babel/messages/frontend.py", line 1130, in update
width=options.width)
File "/home/georg/env/main/lib/python3.3/site-packages/babel/messages/pofile.py", line 444, in write_po
_write(comment_header + u'\n')
File "/home/georg/env/main/lib/python3.3/site-packages/babel/messages/pofile.py", line 388, in _write
fileobj.write(text)
TypeError: must be str, not bytes
Even if the formula for nplurals returns 2, ngettext uses 1st template for substitution.
Everything returns to normal upon reverting back to 0.9.
Here is the MWE: https://github.com/georgthegreat/mwe
Run it using make debug
(you have to setup virtualenv using provided requirements.txt
).
Open you browser using http://localhost:5000
The result with Flask-Babel==0.9.0 is:
Format according to rule #0 using locale=ru: 1
Format according to rule #1 using locale=ru: 3
Format according to rule #2 using locale=ru: 8
The result with Flask-Babel==0.10.0 is:
Format according to rule #0 using locale=ru: 1
Format according to rule #1 using locale=ru: 3
Format according to rule #1 using locale=ru: 8
Third line differs and this is the bug introduced.
UnicodeDecodeError: 'ascii' codec can't decode byte...
Environment:
Python=3.3.2
Flask=0.10.1
Flask-Babel=0.9
Any attempt to read translations directory files (*.po or *.mo) result in UnicodeDecodeError. Works as expected with Python 2.7.5.
My layout template folder is named _layout
and I noticed pybabel doesn't seem to be extracting any of my templates inside a folder starting with an underscore.
Didn't see this posted here, but figured I'd at least mention it.
is there a reason why flask-babel actively drops the tzinfo?
I use flask_script (and flask_migrate) to migrate my sql schema.
Since version 0.10 i got this error.
Everything works well with 0.9
File "/usr/local/lib/python2.7/dist-packages/flask_babel/__init__.py", line 215, in get_translations
babel = current_app.extensions['babel']
File "/usr/local/lib/python2.7/dist-packages/werkzeug/local.py", line 343, in __getattr__
return getattr(self._get_current_object(), name)
File "/usr/local/lib/python2.7/dist-packages/werkzeug/local.py", line 302, in _get_current_object
return self.__local()
File "/usr/local/lib/python2.7/dist-packages/flask/globals.py", line 34, in _find_app
raise RuntimeError('working outside of application context')
The latest official Babel release (0.9.6 at the time of writing) does not have format_timedelta() function in the dates module. Using the timedeltaformat filter in a template causes a traceback.
The missing function is available in the development version of Babel, though, and will be included in the 1.0 release, according to the ChangeLog. With the installation of Flask-Babel (easy_install or pip), one gets the latest released version of Babel and will not be able to use the timedeltaformat filter.
For some reason, using Flask Babel will disable the bytecode cache. Any way to turn it back on?
When I use modules in another package, flask-babel does not load their translations.
Every time there is need to translate the other packages in the current app.
The function get_translations() should load translations also from others dirnames.
https://github.com/mitsuhiko/flask-babel/blob/master/docs/conf.py#L52
and the title of my browser on http://pythonhosted.org/Flask-Babel/ state that Flask-Babel is version 1.0 but in fact 0.9 is the current version, is this a mistake or did I miss something?
Tests expect datetime in the format:
'Apr 12, 2010 1:46:00 PM'
recent Babel returns:
'Apr 12, 2010, 1:46:00 PM'
I am not sure if it is ok to just patch tests.py.
http://babel.pocoo.org/docs/api/dates/
https://bugzilla.redhat.com/show_bug.cgi?id=1106770
Since the return value is marked as safe, the autoescape feature or the "escape" filter won't work.
Sample (Template -> Output):
right now: _('foo & bar') -> foo & bar
should be: _('foo & bar') -> foo & bar
Hi, I have some problem with babel translation into a flask application. The translated accent é is rendered as é whereas the untranslated é still appears properly as é. At this stage, (and after lot os search and check) I do need some help to fix this.
It sounds that babel is reading/rendering the translation resource like ansi file?
I did noticed exactly the same rendering behaviour when I do display the po file content into a file viewer not supporting utf-8 (this can easily been simulated in PSPAD editor by switching format from UTF-8 to textonly ).
Any idea (additional information) to troubleshoot this issue?
Similar to #64
list_translations() currently only returns the default locale if no translation files exist. I believe it should always return the default locale.
For example, if my keys are in English, I will not have a .mo for English, but it is still a valid locale and would be returned as such if I hadn't yet translated into German.
Furthermore, I think that the default locale should be returned even if the translations folder does not exist (currently an empty list is returned in this case) - why is that any different to an empty translations folder?
In Flask-Babel 0.9.0, testing code that didn't use an Application Context worked, now in Flask-Babel 0.10.0 it throws a runtime exception "RuntimeError: working outside of application context"
This is a breaking change for at least testing. Is there a way to handle testing of code that doesn't go through the application test client?
Babel has an ability to specify threshold to control switch of time units display when formatting timedelta but Flask-Babel hides it using Babel default, which is 0.85 currently. With this setting timedelta of 6 days is shown as 1 week which may not always be desirable.
This smells like a bug since the failure is caused by the is None
check to avoid calling it multiple times. IMHO these two assignments should be moved from init_app
to __init__
.
self.locale_selector_func = None
self.timezone_selector_func = None
The classic ngettext interface is:
def ngettext(self, singular, plural, n):
Flaskext-babel extends this to be:
def ngettext(self, singular, plural, n, **variables):
in order to assist with doing the translation and interpolation steps in one go. Unfortunately applications relying on the standard interface can break, if they do the following:
str = ngettext('I like a car','I like %(cars)s cars',cars)
return str % dict(cars=cars)
In this case, if cars = 2, ngettext should return:
I like %(cars)s
Instead however the application crashes on https://github.com/mitsuhiko/flask-babel/blob/master/flaskext/babel.py#L479
return t.ungettext(singular, plural, num) % variables
because flaskext is forcing an interpolation against variables, which is empty.
It is explicitly not the fault of callers expecting the normal behaviour, the standard behaviour of ngettext is well defined. Flaskext is breaking a number of dependent applications and libraries silently, including wtforms which makes use of this functionality in the Length validator.
It seems like it has been a while since there has been a new version of this. Also, the package on PyPi (http://pypi.python.org/pypi/Flask-Babel) is quite outdated. It does not support initialising the app outside of the constructor which make its use difficult.
Would it be possible to create a new version or a new package on PyPi that contains a newer version?
How do I debug flask-babel? Its hanging on extraction and I don't know what is going on,
I have a base.html file and navbar.html file.
The navbar.html is included in base.html and base extended in other templates.
The problem is that babel does not extract strings from navbar.html even though i can see it read it.
extraction log
babel.cfg
[jinja2: **.htm*]
encoding = utf-8
extensions=jinja2.ext.autoescape,jinja2.ext.with_
What could be the problem?
I know that the GNU gettext is overriding whatever we think and just replace empty string with nonsense information. Its time to stop the crime! Its time that we can control the empty string!
Most likely, it will be just super convenient to translate empty strings to empty strings!
I just make gzilion of problems that empty string is translated to this wierd PO information. Is anybody see any reason to keep working that way?
Reference:
http://www.gnu.org/software/gettext/manual/gettext.html#MO-Files
Hello I was screwing around in the command line. I set my locale to a few different languages just to see what the output would be for a date.
It worked well on all languages I tried (even Burmese) but blew up on Khmer when used with 'full', without 'full' it works perfectly as you can see at the bottom of this console output:
I suppose it's not needed for avoiding circular imports but I like to keep all extension objects and their setup in a separate module.
Because they are not JSON-serializable. This is new limitation in Flask 0.10.
Hello!
My project is full working, but so far I've only translated .jinja and .py.
How can I make it work with javascript files? I do the extract,compilation, and I get all the string ..but return gettext is not defined. I look at the tutorial but I didn't find a solutio for that, any clue? Thank you!
When running pybabel extract -k lazy_pgettext
on my project, the context of each lazy_pgettext
is being parsed as the translation string.
Babel 1.3, Flask-Babel 0.9.6
Babel fails to resolve "no" locale. The catalog is initiated, no fuzzys appear but it doesn't use the translations.
No such problem with "nb" locale.
BTW. Pyramid Babel works well with "no" locale
.po files support translator comments, see https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html
Is there a way to add translator comments in or near the gettext() call? I have seen mentions of adding a comment before the gettext() call, but that doesn't seem to work (at least not in jinja2).
we have a version tag for 0.9.0 and v0.11.0, but not v0.10.0
Can we add one please?
Hi,
If you try to install flask-babel with pip 1.4, it will fail as it will not find a stable version for pytz package. A possible solution is adding the --pre to pip in order to install the package. Another possible solution is to specify a version in the setup.py.
Let me know if I can help debugging it.
Considering the assumption that a lot of people use Flask-Assets in their projects, it might be nice to mention the necessity of including their Jinja2 filter (webassets.ext.jinja2.AssetsExtension
) in babel.cfg when using Flask-Babel. (They've done the same thing vice-versa).
Flask-Babel currently does not provide any changelog. The lack of it make consumers hard to trace when features were introduced.
Also, it would be better if docs utilize Sphinx’s .. versionadded::
and .. versionchanged::
directives as well.
Some translation works... and some don't. How to troubleshoot without any errors?
Also Part of the translation work in local environment... why does production not work when I change the language via the browser? Thanks.
Has anybody gotten production version working of flask-babel?
I would like to see these functions automatically added to the app context. Perhaps jinja2 should do this as the babel extension adds gettext to the context.
from flaskext.babel import format_datetime, format_date, format_timedelta
@app.context_processor
def inject_babel_formatting():
return dict(format_datetime=format_datetime,
format_date=format_date, format_timedelta=format_timedelta)
EDIT: Just noticed that these are exposed as filters already. Needs documentation.
I'm not sure if this is a Flask-Babel or Flask issue, but I've noticed something very strange about flaskext importing.
If I install a Flask ext through pip and install another as --editable, I can't import the editable version unless I also install Flask-Babel (non-editable) and import it first.
I've narrowed this down to the fact that Flask-Babel imports from the actual Babel module (from babel import dates, numbers, support, Locale).
Without the import from Babel, any attempts to import editable modules will fail. What makes this even more perplexing is that this behavior is not observed from within ipython, only through the vanilla Python shell or during the normal running of my application. Through ipython, all imports work perfectly regardless of which modules I have installed and where.
Sample session (flask-kvsession is installed --editable, flask-babel is installed normally)
Python 2.7.2 (v2.7.2:8527427914a2, Jun 11 2011, 15:22:34)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from flask.ext.kvsession import KVSession
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/rroemmich/tmp/t/env/lib/python2.7/site-packages/flask/exthook.py", line 86, in load_module
raise ImportError('No module named %s' % fullname)
ImportError: No module named flask.ext.kvsession
>>> from flask.ext.babel import Babel
>>> from flask.ext.kvsession import KVSession
>>>
It's easy to implement locally, but I think it would make sense to have it in flask-babel so you don't end up having to import two almost identical functions from different packages.
It would be nice to be able to stash the current language somewhere and use another one for a while during a request execution.
The main use-case I see is sending out emails with Flask-Email. The email should be translated according to the recipient's language and not the current user's language.
Something like:
from flaskext.babel import stash, unstash
# do stuff with current user's language
print _('foo')
# Now switch to th recipient language
stash(new_lang=recipient.language)
send email with i18n tags
unstash()
# Now the language is back to the current user's lang
Well the API is terrible, but you get the idea..
There should be a short introduction in how to use gettext, trans etc in Jinja the jkji2 templates - it's not obvious from the docs that the jinja2 i18n ext is used and that the user does not need to configure this separately.
Hey guys,
When I run uwsgi in command line as sudo, the application works fine.
But the moment I run uwsgi as a daemon (www-data), the hell breaks loose with this error message:
File "/myproject/F11/Engineering/f11_app/templates/show_records.html", line 25, in block "body"
<td>{{ record.record_date|format_date }}</td>
File "./f11_app/filters.py", line 7, in format_date
day = babel_dates.format_date(value, "EE")
File "/myproject/myproject-env/local/lib/python2.7/site-packages/babel/dates.py", line 459, in format_date
return pattern.apply(date, locale)
File "/myproject/myproject-env/local/lib/python2.7/site-packages/babel/dates.py", line 702, in apply
return self % DateTimeFormat(datetime, locale)
File "/myproject/myproject-env/local/lib/python2.7/site-packages/babel/dates.py", line 699, in __mod__
return self.format % other
File "/myproject/myproject-env/local/lib/python2.7/site-packages/babel/dates.py", line 734, in __getitem__
return self.format_weekday(char, num)
File "/myproject/myproject-env/local/lib/python2.7/site-packages/babel/dates.py", line 821, in format_weekday
return get_day_names(width, context, self.locale)[weekday]
File "/myproject/myproject-env/local/lib/python2.7/site-packages/babel/dates.py", line 69, in get_day_names
return Locale.parse(locale).days[context][width]
AttributeError: 'NoneType' object has no attribute 'days'
it seems locale is not set, when run as a daemon. I am working since 12 hours on this problem and can't fix it. I am running it on Ubuntu 12.04 and also 13.10. when I type locale in terminal I can see this:
LANG=en_GB.UTF-8
LANGUAGE=en_GB:en
LC_CTYPE="en_GB.UTF-8"
LC_NUMERIC="en_GB.UTF-8"
LC_TIME="en_GB.UTF-8"
LC_COLLATE="en_GB.UTF-8"
LC_MONETARY="en_GB.UTF-8"
LC_MESSAGES="en_GB.UTF-8"
LC_PAPER="en_GB.UTF-8"
LC_NAME="en_GB.UTF-8"
LC_ADDRESS="en_GB.UTF-8"
LC_TELEPHONE="en_GB.UTF-8"
LC_MEASUREMENT="en_GB.UTF-8"
LC_IDENTIFICATION="en_GB.UTF-8"
LC_ALL=
Do I have to set the somehow inside the code?
This is the filter.py:
from f11_app import app
import babel.dates as babel_dates
@app.template_filter('format_date')
def format_date(value):
day = babel_dates.format_date(value, "EE")
return '{0} {1}'.format(day.upper(), affix(value.day))
this is the __init__.py
of my f11_app package:
from flask.ext.babel import Babel
app = Flask(__name__,static_folder=http_root, static_url_path="/static")
app.config.from_object('config.DevelopmentConfig')
babl = Babel(app)
If somebody is out there, please be so kind and help me please.
I also realized babel seems to be over 2 years old. Is that still actively maintained?
The definition get_translations in init.py states the following:
Returns the correct gettext translations that should be used for
this request. This will never fail and return a dummy translation
object if used outside of the request or if a translation cannot be
found.
However, it does fail at my test, because flask._request_ctx_stack.top is None.
I'm testing a function to send an email where the body of the email is a template with translatable strings. I figured, because there's no request, flask-babel doesn't "know" what language to use, but this function states it should return a dummy translation object in case it is used outside of the request or if a translation cannot be found.
This error is raised when trying to place the template into the body of the email:
AttributeError: 'NoneType' object has no attribute 'ugettext'
I've tried to ask in #pocoo, but I've received no answer.
I've the following code in my jinja2
template:
{% for language in languages %}
<option value="{{language}}">{{language}}</option>
{% endif %}
languages is a compile-time array, which depends on the database, but changes rarely. I would like {{language}} to be translated, but when I write {{ _(language) }}, nothing changes in my .pot
file.
How do I translate such array?
It seems the latest changes haven't been pushed to PyPI.
Hi,
I want to translate this:
Powered by {{meta['title']}} version {{meta['version']}}
How to do it?
Thanks,
Flask-Babel project hasn’t seemed updated about 2+ years. There are 20+ pull requests waiting review as well.
If the current maintainer has no enough time to maintain the project, how about electing a new maintainer?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.