From 1e4338e61cf53c6e1f2b2b95868970fef4c23150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20H=C3=BChne?= Date: Wed, 1 Jun 2016 15:44:04 +0200 Subject: [PATCH 1/3] [#3073] smarter way to get available locales --- ckan/lib/i18n.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/ckan/lib/i18n.py b/ckan/lib/i18n.py index 2f888e8a73a..63b06d5aa80 100644 --- a/ckan/lib/i18n.py +++ b/ckan/lib/i18n.py @@ -1,7 +1,7 @@ import os from babel import Locale, localedata -from babel.core import LOCALE_ALIASES, get_locale_identifier +from babel.core import LOCALE_ALIASES, get_locale_identifier, UnknownLocaleError from babel.support import Translations from paste.deploy.converters import aslist from pylons import config @@ -48,7 +48,18 @@ def _get_locales(): i18n_path = os.path.join(config.get('ckan.i18n_directory'), 'i18n') else: i18n_path = os.path.dirname(ckan.i18n.__file__) - locales += [l for l in os.listdir(i18n_path) if localedata.exists(l)] + + # For every file in the ckan i18n directory see if babel can understan + # the locale. If yes, add it to the available locales + for locale in os.listdir(i18n_path): + try: + Locale.parse(locale) + locales.append(locale) + except (ValueError, UnknownLocaleError): + # Babel does not know how to make a locale out of this. + # This is fine since we are passing all files in the + # ckan.i18n_directory here which e.g. includes the __init__.py + pass assert locale_default in locales, \ 'default language "%s" not available' % locale_default From e54912ee578557fc6168c08f6ed9085ef018e015 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20H=C3=BChne?= Date: Thu, 2 Jun 2016 10:00:08 +0200 Subject: [PATCH 2/3] [#3073] Add `short_name` to locale for url construction --- ckan/lib/i18n.py | 22 ++++++++++++++----- .../templates/snippets/language_selector.html | 2 +- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/ckan/lib/i18n.py b/ckan/lib/i18n.py index 63b06d5aa80..28758f79313 100644 --- a/ckan/lib/i18n.py +++ b/ckan/lib/i18n.py @@ -49,7 +49,7 @@ def _get_locales(): else: i18n_path = os.path.dirname(ckan.i18n.__file__) - # For every file in the ckan i18n directory see if babel can understan + # For every file in the ckan i18n directory see if babel can understand # the locale. If yes, add it to the available locales for locale in os.listdir(i18n_path): try: @@ -134,11 +134,21 @@ def get_available_locales(): e.g. [ Locale('en'), Locale('de'), ... ] ''' global available_locales if not available_locales: - available_locales = map(Locale.parse, get_locales()) - # Add the full identifier (eg `pt_BR`) to the locale classes, as it does - # not offer a way of accessing it directly - for locale in available_locales: - setattr(locale, 'identifier', get_identifier_from_locale_class(locale)) + available_locales = [] + for locale in get_locales(): + # Add the short names for the locales. This equals the filename + # of the ckan translation files as opposed to the long name + # that includes the script which is generated by babel + # so e.g. `zn_CH` instead of `zn_Hans_CH` this is needed + # to properly construct urls with url_for + parsed_locale = Locale.parse(locale) + parsed_locale.short_name = locale + + # Add the full identifier (eg `pt_BR`) to the locale classes, + # as it does not offer a way of accessing it directly + parsed_locale.identifier = \ + get_identifier_from_locale_class(parsed_locale) + available_locales.append(parsed_locale) return available_locales diff --git a/ckan/templates/snippets/language_selector.html b/ckan/templates/snippets/language_selector.html index cb1a863653a..cf8e6dd281f 100644 --- a/ckan/templates/snippets/language_selector.html +++ b/ckan/templates/snippets/language_selector.html @@ -4,7 +4,7 @@