Browse files

Added speaklater

  • Loading branch information...
1 parent dd730e0 commit 1d2042062c13b9d093e139aad22e9d3afb034b95 @mitsuhiko mitsuhiko committed May 30, 2010
View
5 .gitignore
@@ -1,3 +1,6 @@
.DS_Store
*.pyc
-*.pyp
+*.pyo
+*.egg-info
+dist/
+docs/_build
View
BIN docs/_static/flask-babel.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
2 docs/conf.py
@@ -16,7 +16,7 @@
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
-sys.path.append(os.path.abspath('..'))
+sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
sys.path.append(os.path.abspath('_themes'))
# -- General configuration -----------------------------------------------------
View
33 docs/index.rst
@@ -4,9 +4,10 @@ Flask-Babel
.. module:: flaskext.babel
Flask-Babel is an extension to `Flask`_ that adds i18n and l10n support to
-any Flask application with the help of `babel`_ and `pytz`_. It has
-builtin support for date formatting with timezone support as well as a
-very simple and friendly interface to :mod:`gettext` translations.
+any Flask application with the help of `babel`_, `pytz`_ and
+`speaklater`_. It has builtin support for date formatting with timezone
+support as well as a very simple and friendly interface to :mod:`gettext`
+translations.
Installation
------------
@@ -17,7 +18,7 @@ Install the extension with one of the following commands::
or alternatively if you have pip installed::
- $ pip install Flask-babel
+ $ pip install Flask-Babel
Please note that Flask-Babel requires Jinja 2.5. If you are using an
older version you will have to upgrade or disable the Jinja support.
@@ -149,6 +150,16 @@ to translate strings that might become plural. Here some examples::
gettext(u'Value: %(value)s', value=42)
ngettext(u'%(num)s Apple', u'%(num)s Apples', number_of_apples)
+Additionally if you want to use constant strings somewhere in your
+application and define them outside of a request, you can use a lazy
+strings. Lazy strings will not be evaluated until they are actually used.
+To use such a lazy string, use the :func:`lazy_gettext` function::
+
+ from flask import lazy_gettext
+
+ class MyForm(formlibrary.FormBase):
+ success_message = lazy_gettext(u'The form was successfully saved.')
+
So how does Flask-Babel find the translations? Well first you have to
create some. Here is how you do it:
@@ -175,7 +186,12 @@ Save it as ``babel.cfg`` or something similar next to your application.
Then it's time to run the `pybabel` command that comes with Babel to
extract your strings::
- $ pybabel -F babel.cfg -o messages.pot
+ $ pybabel extract -F babel.cfg -o messages.pot
+
+If you are using the :func:`lazy_gettext` function you should tell pybabel
+that it should also look for such function calls::
+
+ $ pybabel extract -F babel.cfg -k lazy_gettext -o messages.pot
This will use the mapping from the ``babel.cfg`` file and store the
generated template in ``messages.pot``. Now we can create the first
@@ -220,7 +236,14 @@ your ``~/.profile`` file::
Then restart your terminal.
+API
+---
+
+.. automodule:: flaskext.babel
+ :members:
+
.. _Flask: http://flask.pocoo.org/
.. _babel: http://babel.edgewall.org/
.. _pytz: http://pytz.sourceforge.net/
+.. _speaklater: http://pypi.python.org/pypi/speaklater
View
BIN flaskext/__init__.pyc
Binary file not shown.
View
33 flaskext/babel.py
@@ -10,6 +10,7 @@
"""
from __future__ import absolute_import
import os
+import sys
# this is a workaround for a snow leopard bug that babel does not
# work around :)
@@ -95,6 +96,8 @@ def default_timezone(self):
def get_translations():
"""Returns the correct gettext translations"""
ctx = _request_ctx_stack.top
+ if ctx is None:
+ return None
translations = getattr(ctx, 'babel_translations', None)
if translations is None:
dirname = os.path.join(ctx.app.root_path, 'translations')
@@ -106,6 +109,8 @@ def get_translations():
def get_locale():
"""Returns the locale that should be used."""
ctx = _request_ctx_stack.top
+ if ctx is None:
+ return None
locale = getattr(ctx, 'babel_locale', None)
if locale is None:
babel = ctx.app.babel_instance
@@ -221,10 +226,34 @@ def _date_format(formatter, obj, format, rebase, **extra):
def gettext(string, **variables):
- return get_translations().ugettext(string) % variables
+ """Translates a string with the current locale and passes in the
+ given keyword arguments as mapping to a string formatting string.
+ """
+ t = get_translations()
+ if t is None:
+ return string % variables
+ return t.ugettext(string) % variables
_ = gettext
def ngettext(singular, plural, num, **variables):
+ """Translates a string with the current locale and passes in the
+ given keyword arguments as mapping to a string formatting string.
+ The `num` parameter is used to dispatch between singular and various
+ plural forms of the message. It is available in the format string
+ as ``%(num)d`` or ``%(num)s``. The source language should be
+ English or a similar language which only has one plural form.
+ """
variables.setdefault('num', num)
- return get_translations().ungettext(singular, plural, num) % variables
+ t = get_translations()
+ if t is None:
+ return (singular if num == 1 else plural) % variables
+ return t.ungettext(singular, plural, num) % variables
+
+
+def lazy_gettext(string, **variables):
+ """Like :func:`gettext` but the string returned is lazy which means
+ it will be translated when it is used as an actual string.
+ """
+ from speaklater import make_lazy_string
+ return make_lazy_string(gettext, string, **variables)
View
7 setup.cfg
@@ -0,0 +1,7 @@
+[build_sphinx]
+source-dir = docs/
+build-dir = docs/_build
+all_files = 1
+
+[upload_sphinx]
+upload-dir = docs/_build/html
View
1 setup.py
@@ -35,6 +35,7 @@
'Flask',
'Babel',
'pytz',
+ 'speaklater>=1.2',
'Jinja2>=2.5'
],
classifiers=[
View
12 tests/tests.py
@@ -9,7 +9,7 @@
import flask
from datetime import datetime
from flaskext import babel
-from flaskext.babel import gettext, ngettext
+from flaskext.babel import gettext, ngettext, lazy_gettext
class DateFormattingTestCase(unittest.TestCase):
@@ -113,6 +113,16 @@ def test_template_basics(self):
{%- pluralize %}{{ num }} Apples{% endtrans %}
''', name='Peter').strip() == u'3 Äpfel'
+ def test_lazy_gettext(self):
+ app = flask.Flask(__name__)
+ b = babel.Babel(app, default_locale='de_DE')
+ yes = lazy_gettext(u'Yes')
+ with app.test_request_context():
+ assert unicode(yes) == 'Ja'
+ app.config['BABEL_DEFAULT_LOCALE'] = 'en_US'
+ with app.test_request_context():
+ assert unicode(yes) == 'Yes'
+
if __name__ == '__main__':
unittest.main()
View
BIN tests/translations/de/LC_MESSAGES/messages.mo
Binary file not shown.
View
6 tests/translations/de/LC_MESSAGES/messages.po
@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2010-05-29 17:00+0200\n"
-"PO-Revision-Date: 2010-05-29 17:01+0200\n"
+"PO-Revision-Date: 2010-05-30 12:56+0200\n"
"Last-Translator: Armin Ronacher <armin.ronacher@active-4.com>\n"
"Language-Team: de <LL@li.org>\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
@@ -29,3 +29,7 @@ msgid_plural "%(num)s Apples"
msgstr[0] "%(num)s Apfel"
msgstr[1] "%(num)s Äpfel"
+#: tests.py:119
+msgid "Yes"
+msgstr "Ja"
+
View
6 tests/translations/messages.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2010-05-29 17:00+0200\n"
+"POT-Creation-Date: 2010-05-30 12:56+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -29,3 +29,7 @@ msgid_plural "%(num)s Apples"
msgstr[0] ""
msgstr[1] ""
+#: tests.py:119
+msgid "Yes"
+msgstr ""
+

0 comments on commit 1d20420

Please sign in to comment.