Skip to content

Commit

Permalink
[#959] extra 18n directory, rename interface names
Browse files Browse the repository at this point in the history
Add config options
  'ckan.i18n.extra_directory'
  'ckan.i18n.extra_gettext_domain'
  'ckan.i18n.extra_locales'

'ckan.i18n.extra_directory' should be a fully qualified path
'ckan.i18n.extra_gettext_domain' should be the filename of mo files
'ckan.i18n.extra_locales' should be a list for each locale handled

Rename the interfaces method names to reduce the risk of clashing
'domain' and 'directory' are too generic and might be used by other
plugins in the future and there is no indication as a plugin writer that
these methods are related to the ITranslation interface. So they have
been changed to 'i18n_domain' etc.
  • Loading branch information
joetsoi committed Jun 16, 2015
1 parent 93d3a54 commit 4f199d1
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 25 deletions.
45 changes: 27 additions & 18 deletions ckan/lib/i18n.py
Expand Up @@ -4,6 +4,7 @@
from babel import Locale, localedata
from babel.core import LOCALE_ALIASES
from babel.support import Translations
from paste.deploy.converters import aslist
from pylons import config
from pylons import i18n
import pylons
Expand Down Expand Up @@ -139,29 +140,37 @@ def handle_request(request, tmpl_context):
if lang != 'en':
set_lang(lang)

extra_directory = config.get('ckan..i18n.extra_directory')
extra_domain = config.get('ckan.i18n.extra_gettext_domain')
extra_locales = aslist(config.get('ckan.i18n.extra_locales'))
if lang in extra_locales:
_add_extra_translations(extra_directory, lang, extra_domain)

for plugin in PluginImplementations(ITranslation):
if lang in plugin.locales():
translator = Translations.load(
dirname=plugin.directory(),
locales=lang,
domain=plugin.domain()
)
try:
pylons.translator.merge(translator)
except AttributeError:
# this occurs when an extension has 'en' translations that
# replace the default strings. As set_lang has not been run,
# pylons.translation is the NullTranslation, so we have to
# replace the StackedObjectProxy ourselves manually.
environ = pylons.request.environ
environ['pylons.pylons'].translator = translator
if 'paste.registry' in environ:
environ['paste.registry'].replace(pylons.translator,
translator)
if lang in plugin.i18n_locales():
_add_extra_translations(plugin.i18n_directory(), lang,
plugin.i18n_domain())

tmpl_context.language = lang
return lang

def _add_extra_translations(dirname, locales, domain):
translator = Translations.load(dirname=dirname, locales=locales,
domain=domain)
try:
pylons.translator.merge(translator)
except AttributeError:
# this occurs when an extension has 'en' translations that
# replace the default strings. As set_lang has not been run,
# pylons.translation is the NullTranslation, so we have to
# replace the StackedObjectProxy ourselves manually.
environ = pylons.request.environ
environ['pylons.pylons'].translator = translator
if 'paste.registry' in environ:
environ['paste.registry'].replace(pylons.translator,
translator)


def get_lang():
''' Returns the current language. Based on babel.i18n.get_lang but
works when set_lang has not been run (i.e. still in English). '''
Expand Down
8 changes: 4 additions & 4 deletions ckan/lib/plugins.py
Expand Up @@ -529,7 +529,7 @@ def activity_template(self):


class DefaultTranslation(object):
def directory(self):
def i18n_directory(self):
'''Change the directory of the *.mo translation files
The default implementation assumes the plugin is
Expand All @@ -541,20 +541,20 @@ def directory(self):
module = sys.modules[extension_module_name]
return os.path.join(os.path.dirname(module.__file__), 'i18n')

def locales(self):
def i18n_locales(self):
'''Change the list of locales that this plugin handles
By default the will assume any directory in subdirectory in the
directory defined by self.directory() is a locale handled by this
plugin
'''
directory = self.directory()
directory = self.i18n_directory()
return [ d for
d in os.listdir(directory)
if os.path.isdir(os.path.join(directory, d))
]

def domain(self):
def i18n_domain(self):
'''Change the gettext domain handled by this plugin
This implementation assumes the gettext domain is
Expand Down
6 changes: 3 additions & 3 deletions ckan/plugins/interfaces.py
Expand Up @@ -1436,11 +1436,11 @@ def abort(self, status_code, detail, headers, comment):


class ITranslation(Interface):
def directory(self):
def i18n_directory(self):
'''Change the directory of the *.mo translation files'''

def locales(self):
def i18n_locales(self):
'''Change the list of locales that this plugin handles '''

def domain(self):
def i18n_domain(self):
'''Change the gettext domain handled by this plugin'''

0 comments on commit 4f199d1

Please sign in to comment.