Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ change some internal defaults:
folders. Defaults to ``translations``.
`BABEL_DOMAIN` The message domain used by the application.
Defaults to ``messages``.

It can also be a semi-colon (``;``) separated
string of different domains for each of the
translation directories, eg::

BABEL_TRANSLATION_DIRECTORIES=/path/to/translations;/another/path/
BABEL_DOMAINS=messages;myapp

=============================== =============================================

For more complex applications you might want to have multiple applications
Expand Down
34 changes: 29 additions & 5 deletions flask_babel/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -512,13 +512,30 @@ class Domain(object):
"""Localization domain. By default will use look for translations in Flask
application directory and "messages" domain - all message catalogs should
be called ``messages.mo``.

Additional domains are supported passing a list of domain names to the ``domain``
argument, but note that in this case they must match a list passed
to ``translation_directories``, eg::

Domain(
translation_directories=[
"/path/to/translations/with/messages/domain",
"/another/path/to/translations/with/another/domain",
],
domains=[
"messages",
"myapp",
]
)
"""

def __init__(self, translation_directories=None, domain='messages'):
if isinstance(translation_directories, str):
translation_directories = [translation_directories]
self._translation_directories = translation_directories
self.domain = domain

self.domain = domain.split(';')

self.cache = {}

def __repr__(self):
Expand Down Expand Up @@ -553,15 +570,22 @@ def get_translations(self):
cache = self.get_translations_cache(ctx)
locale = get_locale()
try:
return cache[str(locale), self.domain]
return cache[str(locale), self.domain[0]]
except KeyError:
translations = support.Translations()

for dirname in self.translation_directories:
for index, dirname in enumerate(self.translation_directories):

domain = (
self.domain[0]
if len(self.domain) == 1
else self.domain[index]
)

catalog = support.Translations.load(
dirname,
[locale],
self.domain
domain
)
translations.merge(catalog)
# FIXME: Workaround for merge() being really, really stupid. It
Expand All @@ -571,7 +595,7 @@ def get_translations(self):
if hasattr(catalog, 'plural'):
translations.plural = catalog.plural

cache[str(locale), self.domain] = translations
cache[str(locale), self.domain[0]] = translations
return translations

def gettext(self, string, **variables):
Expand Down
36 changes: 36 additions & 0 deletions tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,42 @@ def test_multiple_directories():
) == 'Hallo Peter!'


def test_multiple_directories_multiple_domains():
"""
Ensure we can load translations from multiple directories with a
custom domain.
"""
b = babel.Babel()
app = flask.Flask(__name__)

app.config.update({
'BABEL_TRANSLATION_DIRECTORIES': ';'.join((
'renamed_translations',
'translations_different_domain',
)),
'BABEL_DEFAULT_LOCALE': 'de_DE',
'BABEL_DOMAIN': ';'.join((
'messages',
'myapp',
)),
})

b.init_app(app)

with app.test_request_context():
translations = b.list_translations()

assert(len(translations) == 2)
assert(str(translations[0]) == 'de')
assert(str(translations[1]) == 'de')

assert gettext(
u'Hello %(name)s!',
name='Peter'
) == 'Hallo Peter!'
assert gettext(u'Good bye') == 'Auf Wiedersehen'


def test_multiple_directories_different_domain():
"""
Ensure we can load translations from multiple directories with a
Expand Down