Permalink
Browse files

Merge pull request #3 from encukou/master

URL i18n
  • Loading branch information...
2 parents bdaca3c + 6e8602e commit 927721903237cb84d1f6bf37d4881c6feef1730f @eevee eevee committed May 22, 2012
View
@@ -79,6 +79,15 @@ def from_ast(node, keywords, options, comments):
except AttributeError:
actual_comments += comment
yield node.lineno, function, message, comments
+ elif funcname == 'connect':
+ for arg in node.args:
+ if isinstance(arg, ast.Str):
+ url = getstring(arg)
+ if url.startswith('/'):
+ for part in url.split('/'):
+ if part and '{' not in part and '*' not in part:
+ part = 'url|' + part
+ yield node.lineno, 'ugettext', part, []
child_comments = []
if isinstance(node, ast.BinOp) and isinstance(node.op, ast.Mod):
child_comments.append('Py2Format')
View
@@ -6,10 +6,80 @@
"""
import os
-from routes import Mapper
+from routes import Mapper, url_for
from routes.util import controller_scan as dir_controller_scan
+from pylons.i18n.translation import get_lang
from spline.lib.plugin.load import run_hooks
+from spline.i18n import Translator
+
+class I18nMapper(Mapper):
+ def connect(self, *args, **kwargs):
+ """Create and connect a new Route to the Mapper.
+
+ In addition to the what Routes' connect() does, this method will
+ connect language-specific routes for all languages available to Spline.
+
+ For named routes, the language-specific entries will have the language
+ identifier prepended, separated from the name by '!!'.
+ The string '!!' shouldn't be used in route names for other purposes.
+ """
+ translator_class = kwargs.pop('i18n_class', None)
+ # Connect the URL for the default language
+ super(I18nMapper, self).connect(*args, **kwargs)
+
+ # Now connect for all available languages
+ for lang in Translator.available_languages():
+ try:
+ name, url = args
+ except ValueError:
+ name = None
+ [url] = args
+ if translator_class:
+ # The first part of the URL is '/<lang>'
+ url_parts = ['', lang]
+ # Chop the URL into parts, translate each one individually,
+ # then join them back together
+ _ = translator_class(languages=[lang])
+ for part in url.split('/'):
+ if not part:
+ pass
+ elif '{' not in part and '*' not in part:
+ # Skip variable parts
+ url_parts.append(_(part, context='url').encode('utf-8'))
+ else:
+ url_parts.append(part)
+ translated_url = '/'.join(url_parts)
+ else:
+ if url == '/':
+ # Make bare language prefix work (e.g. '/de')
+ url = ''
+ translated_url = '/' + lang + url
+ # Add the `_lang` kwarg, and the language tag if we're named
+ kwargs['_lang'] = lang
+ if name:
+ name = lang + '!!' + name
+ # And we're off!
+ super(I18nMapper, self).connect(name, translated_url, **kwargs)
+
+ def generate(self, route=None, *args, **kwargs):
+ """Generate a route from a set of keywords
+
+ If the `_lang` argument is not given, the curent language used for it.
+
+ For a named route, a language tag will be prepended to the name
+ depending on the `_lang` arument.
+ """
+ try:
+ lang = get_lang()[0]
+ except TypeError:
+ lang = None
+ else:
+ kwargs.setdefault('_lang', lang)
+ if route and lang and '!!' not in route.name:
+ return url_for(kwargs['_lang'] + '!!' + route.name, *args, **kwargs)
+ else:
+ return super(I18nMapper, self).generate(*args, **kwargs)
def controller_scan(config, directory):
"""Looks for a controller in the plugin list, defaulting to the usual
@@ -21,7 +91,7 @@ def controller_scan(config, directory):
def make_map(config, content_dirs=[]):
"""Create, configure and return the routes Mapper"""
- map = Mapper(
+ map = I18nMapper(
controller_scan=lambda directory: controller_scan(config, directory),
directory=config['pylons.paths']['controllers'],
always_scan=config['debug'])
View
@@ -1,5 +1,6 @@
# Encoding: UTF-8
+import os
import gettext
import pkg_resources
from pylons.i18n.translation import get_lang
@@ -56,6 +57,21 @@ class BaseTranslator(object):
"""
dir = 'i18n'
+ @classmethod
+ def available_languages(cls):
+ """Return the available languages (not including the default)
+ """
+ available_languages = []
+ for root, dirs, files in os.walk(pkg_resources.resource_filename(
+ cls.package,
+ cls.dir
+ )):
+ components = root.split(os.sep)
+ if components[-1] == 'LC_MESSAGES':
+ if cls.package + '.po' in files:
+ available_languages.append(components[-2])
+ return available_languages
+
def __init__(self, context=None, languages=None, translations=None):
self.context = context
if translations is None:
@@ -70,12 +86,17 @@ def __init__(self, context=None, languages=None, translations=None):
self.dir
)
gettext.bindtextdomain(self.package, directory)
- self.translation = gettext.translation(
- domain=getattr(self, 'domain', self.package),
- localedir=directory,
- languages=languages,
- )
- self.language = languages[0]
+ try:
+ self.translation = gettext.translation(
+ domain=getattr(self, 'domain', self.package),
+ localedir=directory,
+ languages=languages,
+ )
+ except IOError:
+ self.translation = gettext.NullTranslations()
+ self.language = None
+ else:
+ self.language = languages[0]
else:
self.translation = translations
self.language = None
@@ -0,0 +1,61 @@
+# Catalan translations for spline.
+# Copyright (C) 2010 ORGANIZATION
+# This file is distributed under the same license as the spline project.
+#
+# Translators:
+# Il_Tifossi <lluita_i_no_dorm@hotmail.com>, 2011.
+msgid ""
+msgstr ""
+"Project-Id-Version: spline\n"
+"Report-Msgid-Bugs-To: http://bugs.veekun.com/projects/spline/issues\n"
+"POT-Creation-Date: 2010-10-01 15:04+0300\n"
+"PO-Revision-Date: 2012-01-12 23:08+0100\n"
+"Last-Translator: Il_Tifossi <lluita_i_no_dorm@hotmail.com>\n"
+"Language-Team: ca <LL@li.org>\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.4\n"
+
+msgid "url|error"
+msgstr ""
+
+msgid "url|css"
+msgstr ""
+
+msgid "url|cron"
+msgstr ""
+
+#. Py2Format
+#, python-format
+msgid "Rendered in %s seconds"
+msgstr "Renderitzat en %s segons"
+
+#. Py3Format
+#, fuzzy
+msgid "{queries} SQL query in {time:.02f} seconds"
+msgid_plural "{queries} SQL queries in {time:.02f} seconds"
+msgstr[0] "{queries} SQL {q} en {time:.02f} segons"
+msgstr[1] "{queries} SQL {q} en {time:.02f} segons"
+
+msgid "Powered by Spline"
+msgstr "Impulsat per Spline"
+
+msgid ""
+"Fugue icon set by <a href=\"http://www.pinvoke.com/\">Yusuke "
+"Kamiyamane</a>; country flags by <a "
+"href=\"http://www.famfamfam.com/lab/icons/flags/\">famfamfam</a>"
+msgstr ""
+"Set d'icones Fugue per <a href=\"http://www.pinvoke.com/\">Yusuke "
+"Kamiyamane</a>; banderes dels països per <a "
+"href=\"http://www.famfamfam.com/lab/icons/flags/\">famfamfam</a>"
+
+msgid "Untitled"
+msgstr "Sense títol"
+
+#. Py2Format
+#, python-format
+msgid "Error %s"
+msgstr "Error %s"
+
@@ -1,49 +1,48 @@
# Czech translations for spline.
-# Copyright (C) 2010 veekun contributors
+# Copyright (C) 2010 ORGANIZATION
# This file is distributed under the same license as the spline project.
-# Petr "En-Cu-Kou" Viktorin <encukou@gmail.com>, 2010.
#
+# Translators:
+# EnCuKou <encukou@gmail.com>, 2011.
msgid ""
msgstr ""
-"Project-Id-Version: spline 0.1\n"
-"Report-Msgid-Bugs-To: encukou@gmail.com\n"
-"POT-Creation-Date: 2010-09-30 23:08+0300\n"
-"PO-Revision-Date: 2010-10-01 15:09+0300\n"
-"Last-Translator: Petr \"En-Cu-Kou\" Viktorin <encukou@gmail.com>\n"
-"Language-Team: cs <encukou@gmail.com>\n"
-"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
-"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
+"Project-Id-Version: spline\n"
+"Report-Msgid-Bugs-To: http://bugs.veekun.com/projects/spline/issues\n"
+"POT-Creation-Date: 2010-10-01 15:04+0300\n"
+"PO-Revision-Date: 2012-01-12 23:08+0100\n"
+"Last-Translator: EnCuKou <encukou@gmail.com>\n"
+"Language-Team: cs <LL@li.org>\n"
+"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 0.9.5\n"
+"Generated-By: Babel 0.9.4\n"
+
+msgid "url|error"
+msgstr ""
+
+msgid "url|css"
+msgstr ""
+
+msgid "url|cron"
+msgstr ""
#. Py2Format
-#: spline/templates/base-footer.mako:5
#, python-format
msgid "Rendered in %s seconds"
msgstr "Zpracováno za %s s"
#. Py3Format
-#: spline/templates/base-footer.mako:6
-msgid "{queries} SQL {q} in {time:.02f} seconds"
-msgid_plural "{queries} SQL {q} in {time:.02f} seconds"
+#, fuzzy
+msgid "{queries} SQL query in {time:.02f} seconds"
+msgid_plural "{queries} SQL queries in {time:.02f} seconds"
msgstr[0] "{queries} SQL dotaz za {time:.02f}s"
msgstr[1] "{queries} SQL dotazy za {time:.02f}s"
msgstr[2] "{queries} SQL dotazů za {time:.02f}s"
-#: spline/templates/base-footer.mako:13
-msgid "query"
-msgid_plural "queries"
-msgstr[0] "dotaz"
-msgstr[1] "dotazy"
-msgstr[2] "dotazů"
-
-#: spline/templates/base-footer.mako:17
msgid "Powered by Spline"
msgstr "Stránka běží na Spline"
-#: spline/templates/base-footer.mako:18
msgid ""
"Fugue icon set by <a href=\"http://www.pinvoke.com/\">Yusuke "
"Kamiyamane</a>; country flags by <a "
@@ -53,12 +52,10 @@ msgstr ""
"Kamiyamane</a>; vlajky zemí z <a "
"href=\"http://www.famfamfam.com/lab/icons/flags/\">famfamfam</a>"
-#: spline/templates/base.mako:76
msgid "Untitled"
msgstr "Beze jména"
#. Py2Format
-#: spline/templates/error.mako:4
#, python-format
msgid "Error %s"
msgstr "Chyba %s"
@@ -0,0 +1,62 @@
+# Spanish (Puerto Rico) translations for spline.
+# Copyright (C) 2010 ORGANIZATION
+# This file is distributed under the same license as the spline project.
+#
+# Translators:
+# Vixie <adriane@fantasticmissfox.net>, 2011.
+msgid ""
+msgstr ""
+"Project-Id-Version: spline\n"
+"Report-Msgid-Bugs-To: http://bugs.veekun.com/projects/spline/issues\n"
+"POT-Creation-Date: 2010-10-01 15:04+0300\n"
+"PO-Revision-Date: 2012-01-12 23:08+0100\n"
+"Last-Translator: Vixie <adriane@fantasticmissfox.net>\n"
+"Language-Team: es_PR <LL@li.org>\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.4\n"
+
+msgid "url|error"
+msgstr ""
+
+msgid "url|css"
+msgstr ""
+
+msgid "url|cron"
+msgstr ""
+
+#. Py2Format
+#, python-format
+msgid "Rendered in %s seconds"
+msgstr "Dictada en %s segundos."
+
+#. Py3Format
+#, fuzzy
+msgid "{queries} SQL query in {time:.02f} seconds"
+msgid_plural "{queries} SQL queries in {time:.02f} seconds"
+msgstr[0] "{queries} SQL {q} en {time:.024} segundos."
+msgstr[1] "{queries} SQL {q} en {time:.024} segundos."
+
+msgid "Powered by Spline"
+msgstr "Construido con Spline"
+
+msgid ""
+"Fugue icon set by <a href=\"http://www.pinvoke.com/\">Yusuke "
+"Kamiyamane</a>; country flags by <a "
+"href=\"http://www.famfamfam.com/lab/icons/flags/\">famfamfam</a>"
+msgstr ""
+"Conjunto de iconos \"Fugue\" por <a "
+"href=\"http://www.pinvoke.com/\">Yusuke Kamiyamane</a>; Banderas del "
+"mundo por <a "
+"href=\"http://www.famfamfam.com/lab/icons/flags/\">famfamfam</a>"
+
+msgid "Untitled"
+msgstr "Sin título "
+
+#. Py2Format
+#, python-format
+msgid "Error %s"
+msgstr "Error %s"
+
Oops, something went wrong.

0 comments on commit 9277219

Please sign in to comment.