Skip to content
Browse files

Added gettext and JSONTranslations with gettext example

  • Loading branch information...
1 parent 1262a1a commit 56e9173135ca195b29bd64e596c93af6d77f15bb @keesbos keesbos committed Jun 30, 2012
View
52 examples/gettext/Gettext.py
@@ -0,0 +1,52 @@
+import pyjd # this is dummy in pyjs.
+from pyjamas.ui.RootPanel import RootPanel
+from pyjamas.ui.Button import Button
+from pyjamas.ui.HTML import HTML
+from pyjamas.ui.Label import Label
+from pyjamas import Window
+from pyjamas.JSONTranslations import JSONTranslations
+
+t = JSONTranslations()
+_ = t.gettext
+lang = [
+ 'nl_NL',
+ 'de_DE',
+ 'en_US',
+]
+
+
+import pygwt
+
+class GettextExample(object):
+
+ def __init__(self):
+ self.b = Button(_("Click me"), self.greet, StyleName='teststyle')
+ self.h = HTML(_("<b>Hello World</b> (html)"), StyleName='teststyle')
+ self.l = Label(_("Hello World (label)"), StyleName='teststyle')
+ self.base = HTML(_("Hello from %s") % pygwt.getModuleBaseURL(),
+ StyleName='teststyle')
+ RootPanel().add(self.b)
+ RootPanel().add(self.h)
+ RootPanel().add(self.l)
+ RootPanel().add(self.base)
+
+ def change_texts(self, text):
+ self.b.setText(_("Click me"))
+ self.h.setHTML(_("<b>Hello World</b> (html)"))
+ self.l.setText(_("Hello World (label)"))
+ text = [_("Hello from %s") % pygwt.getModuleBaseURL()]
+ for i in range(4):
+ text.append(t.ngettext('%(num)d single', '%(num)d plural', i) % dict(num=i))
+ text = '<br />'.join(text)
+ self.base.setHTML(text)
+
+ def greet(self, fred):
+ fred.setText(_("No, really click me!"))
+ Window.alert(_("Hello, there!"))
+ t.load("lang", "Gettext", lang[0], onCompletion=self.change_texts)
+ lang.append(lang.pop(0))
+
+if __name__ == '__main__':
+ pyjd.setup("public/Hello.html?fred=foo#me")
+ ge = GettextExample()
+ pyjd.run()
View
19 examples/gettext/README
@@ -0,0 +1,19 @@
+
+This is an example of the use of pyjamas.JSONTranslations, which
+is some sort of gettext implementation. The JSONTranslations
+class extends the NullTranslations from the python gettext module.
+
+
+The following shell scripts are used:
+update_po.sh : updates the translations files (*.po) in lang/
+update_mo.sh : compiles the translations files in lang/
+update_json.sh : transform the *.mo files to json files that
+ can be used by the JSONTranslations class
+
+To add a translation, copy the Gettext_en_US.po and do the
+translations for all msgids. Then run update_mo.sh and update_json.sh.
+Finally add your language to the 'lang' list in Gettext.py.
+
+The update_po.sh is needed when you added messages to Gettext.py.
+
+
View
7 examples/gettext/build.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# you will need to read the top level README, and run boostrap.py
+# and buildout in order to make pyjsbuild
+
+options="$*"
+#if [ -z $options ] ; then options="-O";fi
+../../bin/pyjsbuild $options Gettext
View
51 examples/gettext/lang/Gettext_de_DE.po
@@ -0,0 +1,51 @@
+# Example messages for pyjs gettext example
+# Copyright (C) 2012 Kees Bos
+# This file is distributed under the same license as the Gettext example.
+# Kees Bos <cornelis.bos@gmail.com>
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: 0.1\n"
+"Report-Msgid-Bugs-To: yourself\n"
+"POT-Creation-Date: 2012-06-28 17:10+0200\n"
+"PO-Revision-Date: 2012-06-29 17:10+0200\n"
+"Last-Translator: Kees Bos <cornelis.bos@gmail.com>\n"
+"Language-Team: Kees Bos <cornelis.bos@gmail.com>\n"
+"Language: de_DE\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n!=1;\n"
+
+#: Gettext.py:23 Gettext.py:36
+msgid "Click me"
+msgstr "Klick mich"
+
+#: Gettext.py:24 Gettext.py:35 Gettext.py:37
+msgid "<b>Hello World</b> (html)"
+msgstr "<b>Hallo Welt</b> (html)"
+
+#: Gettext.py:25 Gettext.py:36 Gettext.py:38
+msgid "Hello World (label)"
+msgstr "Hallo Welt (Etikett)"
+
+#: Gettext.py:26 Gettext.py:37 Gettext.py:39
+#, python-format
+msgid "Hello from %s"
+msgstr "Hallo von %s"
+
+#: Gettext.py:40 Gettext.py:42
+msgid "No, really click me!"
+msgstr "Nein, wirkich klick auf mich"
+
+#: Gettext.py:41 Gettext.py:43
+msgid "Hello, there!"
+msgstr "Hallo dort!"
+
+#: Gettext.py:29
+#, python-format
+msgid "%(num)d single"
+msgid_plural "%(num)d plural"
+msgstr[0] "%(num)d Einzahl"
+msgstr[1] "%(num)d Mehrzal"
View
51 examples/gettext/lang/Gettext_en_US.po
@@ -0,0 +1,51 @@
+# Example messages for pyjs gettext example
+# Copyright (C) 2012 Kees Bos
+# This file is distributed under the same license as the Gettext example.
+# Kees Bos <cornelis.bos@gmail.com>
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: 0.1\n"
+"Report-Msgid-Bugs-To: yourself\n"
+"POT-Creation-Date: 2012-06-28 17:10+0200\n"
+"PO-Revision-Date: 2012-06-29 17:10+0200\n"
+"Last-Translator: Kees Bos <cornelis.bos@gmail.com>\n"
+"Language-Team: Kees Bos <cornelis.bos@gmail.com>\n"
+"Language: en_US\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n!=1;\n"
+
+#: Gettext.py:23 Gettext.py:36
+msgid "Click me"
+msgstr "Click me"
+
+#: Gettext.py:24 Gettext.py:35 Gettext.py:37
+msgid "<b>Hello World</b> (html)"
+msgstr "<b>Hello World</b> (html)"
+
+#: Gettext.py:25 Gettext.py:36 Gettext.py:38
+msgid "Hello World (label)"
+msgstr "Hello World (label)"
+
+#: Gettext.py:26 Gettext.py:37 Gettext.py:39
+#, python-format
+msgid "Hello from %s"
+msgstr "Hello from %s"
+
+#: Gettext.py:40 Gettext.py:42
+msgid "No, really click me!"
+msgstr "No, really click me!"
+
+#: Gettext.py:41 Gettext.py:43
+msgid "Hello, there!"
+msgstr "Hello, there!"
+
+#: Gettext.py:29
+#, python-format
+msgid "%(num)d single"
+msgid_plural "%(num)d plural"
+msgstr[0] "%(num)d single"
+msgstr[1] "%(num)d plural"
View
51 examples/gettext/lang/Gettext_nl_NL.po
@@ -0,0 +1,51 @@
+# Example messages for pyjs gettext example
+# Copyright (C) 2012 Kees Bos
+# This file is distributed under the same license as the Gettext example.
+# Kees Bos <cornelis.bos@gmail.com>
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: 0.1\n"
+"Report-Msgid-Bugs-To: yourself\n"
+"POT-Creation-Date: 2012-06-28 17:10+0200\n"
+"PO-Revision-Date: 2012-06-29 17:10+0200\n"
+"Last-Translator: Kees Bos <cornelis.bos@gmail.com>\n"
+"Language-Team: Kees Bos <cornelis.bos@gmail.com>\n"
+"Language: nl_NL\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n!=1;\n"
+
+#: Gettext.py:23 Gettext.py:36
+msgid "Click me"
+msgstr "Klik mij"
+
+#: Gettext.py:24 Gettext.py:35 Gettext.py:37
+msgid "<b>Hello World</b> (html)"
+msgstr "<b>Hallo wereld</b> (html)"
+
+#: Gettext.py:25 Gettext.py:36 Gettext.py:38
+msgid "Hello World (label)"
+msgstr "Hallo wereld (etiket)"
+
+#: Gettext.py:26 Gettext.py:37 Gettext.py:39
+#, python-format
+msgid "Hello from %s"
+msgstr "Hallo van %s"
+
+#: Gettext.py:40 Gettext.py:42
+msgid "No, really click me!"
+msgstr "Nee, klik echt op mij"
+
+#: Gettext.py:41 Gettext.py:43
+msgid "Hello, there!"
+msgstr "Hallo daar!"
+
+#: Gettext.py:29
+#, python-format
+msgid "%(num)d single"
+msgid_plural "%(num)d plural"
+msgstr[0] "%(num)d enkelvoud"
+msgstr[1] "%(num)d meervoud"
View
1 examples/gettext/public/lang/Gettext_de_DE.json
@@ -0,0 +1 @@
+{"": {"PO-Revision-Date": "2012-06-29 17:10+0200", "Language": "de_DE", "Content-Transfer-Encoding": "8bit", "Plural-Forms": "nplurals=2; plural=n!=1;", "Project-Id-Version": "0.1", "Report-Msgid-Bugs-To": "yourself", "Last-Translator": "Kees Bos <cornelis.bos@gmail.com>", "Language-Team": "Kees Bos <cornelis.bos@gmail.com>", "POT-Creation-Date": "2012-06-28 17:10+0200", "Content-Type": "text/plain; charset=UTF-8", "MIME-Version": "1.0"}, "Hello, there!": ["Hallo dort!"], "No, really click me!": ["Nein, wirkich klick auf mich"], "<b>Hello World</b> (html)": ["<b>Hallo Welt</b> (html)"], "Hello World (label)": ["Hallo Welt (Etikett)"], "Click me": ["Klick mich"], "%(num)d single": ["%(num)d Einzahl", "%(num)d Mehrzal"], "Hello from %s": ["Hallo von %s"]}
View
1 examples/gettext/public/lang/Gettext_en_US.json
@@ -0,0 +1 @@
+{"": {"PO-Revision-Date": "2012-06-29 17:10+0200", "Language": "en_US", "Content-Transfer-Encoding": "8bit", "Plural-Forms": "nplurals=2; plural=n!=1;", "Project-Id-Version": "0.1", "Report-Msgid-Bugs-To": "yourself", "Last-Translator": "Kees Bos <cornelis.bos@gmail.com>", "Language-Team": "Kees Bos <cornelis.bos@gmail.com>", "POT-Creation-Date": "2012-06-28 17:10+0200", "Content-Type": "text/plain; charset=UTF-8", "MIME-Version": "1.0"}, "Hello, there!": ["Hello, there!"], "No, really click me!": ["No, really click me!"], "<b>Hello World</b> (html)": ["<b>Hello World</b> (html)"], "Hello World (label)": ["Hello World (label)"], "Click me": ["Click me"], "%(num)d single": ["%(num)d single", "%(num)d plural"], "Hello from %s": ["Hello from %s"]}
View
1 examples/gettext/public/lang/Gettext_nl_NL.json
@@ -0,0 +1 @@
+{"": {"PO-Revision-Date": "2012-06-29 17:10+0200", "Language": "nl_NL", "Content-Transfer-Encoding": "8bit", "Plural-Forms": "nplurals=2; plural=n!=1;", "Project-Id-Version": "0.1", "Report-Msgid-Bugs-To": "yourself", "Last-Translator": "Kees Bos <cornelis.bos@gmail.com>", "Language-Team": "Kees Bos <cornelis.bos@gmail.com>", "POT-Creation-Date": "2012-06-28 17:10+0200", "Content-Type": "text/plain; charset=UTF-8", "MIME-Version": "1.0"}, "Hello, there!": ["Hallo daar!"], "No, really click me!": ["Nee, klik echt op mij"], "<b>Hello World</b> (html)": ["<b>Hallo wereld</b> (html)"], "Hello World (label)": ["Hallo wereld (etiket)"], "Click me": ["Klik mij"], "%(num)d single": ["%(num)d enkelvoud", "%(num)d meervoud"], "Hello from %s": ["Hallo van %s"]}
View
9 examples/gettext/update_json.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+PYJSBASE="../.."
+
+cd lang
+for f in *.po ; do
+ b=`basename $f .po`
+ ../${PYJSBASE}/contrib/mo2json.py $b.mo
+ cp $b.json ../public/lang/
+done
View
7 examples/gettext/update_mo.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+cd lang
+for f in *.po ; do
+ b=`basename $f .po`
+ msgfmt -o $b.mo $f
+done
View
5 examples/gettext/update_po.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+for f in `ls lang/*.po` ; do
+ xgettext --omit-header -j -o $f Gettext.py
+done
View
89 library/pyjamas/JSONTranslations.py
@@ -0,0 +1,89 @@
+# Copyright (C) 2012 Kees Bos <cornelis.bos@gmail.com>
+# LISENCE : Apache 2.0 or WTFPL, choose what suits your needs
+#
+
+from gettext import NullTranslations
+import re
+from JSONService import loads
+from HTTPRequest import HTTPRequest
+
+try:
+ from gettext import c2py
+except ImportError:
+ from __pyjamas__ import JS
+ def c2py(plural):
+ f = None
+ JS('''eval("@{{f}}=function(n){return " + @{{plural}} + ";}")''')
+ return f
+
+
+class JSONTranslations(NullTranslations):
+ re_nplurals = re.compile('nplurals *= *(\d+)')
+ re_plural = re.compile('plural *= *([^;]+)')
+
+ def __init__(self, *args, **kwargs):
+ NullTranslations.__init__(self, *args, **kwargs)
+ self._catalog = {}
+ self.plural = lambda n: int(n != 1) # germanic plural by default
+
+ def load(self, base_url, domain=None, lang=None, onCompletion=None, onError=None):
+ url = base_url
+ if domain is not None and lang is not None:
+ url = "%s/%s_%s.json" % (url, domain, lang)
+ self._catalog = {}
+ self.plural = lambda n: int(n != 1) # germanic plural by default
+ self._onCompletion = onCompletion
+ self._onError = onError
+ HTTPRequest().asyncGet(url, self)
+
+ def onCompletion(self, text):
+ self.parse_json(text)
+ if self._onCompletion is not None:
+ self._onCompletion(text)
+
+ def onError(self, text, code):
+ if self._onError is not None:
+ self._onError(text, code)
+ raise RuntimeError(code)
+
+ def onTimeout(self, text):
+ pass
+
+ def onProgress(self, event):
+ pass
+
+ def parse_json(self, text):
+ json = loads(text)
+ self._catalog.update(json)
+ for k, v in self._catalog[""].iteritems():
+ k = k.lower()
+ if k == 'plural-forms':
+ self.nplurals = int(self.re_nplurals.search(v).group(1))
+ self.plural = c2py(self.re_plural.search(v).group(1))
+
+ def _parse(self, url):
+ self.load(url)
+
+ def gettext(self, message):
+ tmsg = self._catalog.get(message)
+ if tmsg is None:
+ if self._fallback:
+ return self._fallback.gettext(message)
+ return message
+ return tmsg[0]
+
+ def ngettext(self, msgid1, msgid2, n):
+ tmsg = self._catalog.get(msgid1)
+ if tmsg is None:
+ if self._fallback:
+ return self._fallback.ngettext(msgid1, msgid2, n)
+ if self.plural(n):
+ return msgid2
+ return msgid1
+ else:
+ return tmsg[self.plural(n)]
+
+ lgettext = gettext
+ lngettext = ngettext
+ ugettext = gettext
+ ungettext = ngettext
View
88 pyjs/src/pyjs/lib/gettext.py
@@ -0,0 +1,88 @@
+#
+# This is taken from the python module gettext
+# Some things won't work (ugettext/ungettext/install)
+# These might work in a subclass of NullTranslations
+
+class NullTranslations:
+ def __init__(self, fp=None):
+ self._info = {}
+ self._charset = None
+ self._output_charset = None
+ self._fallback = None
+ if fp is not None:
+ self._parse(fp)
+
+ def _parse(self, fp):
+ pass
+
+ def add_fallback(self, fallback):
+ if self._fallback:
+ self._fallback.add_fallback(fallback)
+ else:
+ self._fallback = fallback
+
+ def gettext(self, message):
+ if self._fallback:
+ return self._fallback.gettext(message)
+ return message
+
+ def lgettext(self, message):
+ if self._fallback:
+ return self._fallback.lgettext(message)
+ return message
+
+ def ngettext(self, msgid1, msgid2, n):
+ if self._fallback:
+ return self._fallback.ngettext(msgid1, msgid2, n)
+ if n == 1:
+ return msgid1
+ else:
+ return msgid2
+
+ def lngettext(self, msgid1, msgid2, n):
+ if self._fallback:
+ return self._fallback.lngettext(msgid1, msgid2, n)
+ if n == 1:
+ return msgid1
+ else:
+ return msgid2
+
+ def ugettext(self, message):
+ if self._fallback:
+ return self._fallback.ugettext(message)
+ return unicode(message)
+
+ def ungettext(self, msgid1, msgid2, n):
+ if self._fallback:
+ return self._fallback.ungettext(msgid1, msgid2, n)
+ if n == 1:
+ return unicode(msgid1)
+ else:
+ return unicode(msgid2)
+
+ def info(self):
+ return self._info
+
+ def charset(self):
+ return self._charset
+
+ def output_charset(self):
+ return self._output_charset
+
+ def set_output_charset(self, charset):
+ self._output_charset = charset
+
+ def install(self, unicode=False, names=None):
+ import __builtin__
+ __builtin__.__dict__['_'] = unicode and self.ugettext or self.gettext
+ if hasattr(names, "__contains__"):
+ if "gettext" in names:
+ __builtin__.__dict__['gettext'] = __builtin__.__dict__['_']
+ if "ngettext" in names:
+ __builtin__.__dict__['ngettext'] = (unicode and self.ungettext
+ or self.ngettext)
+ if "lgettext" in names:
+ __builtin__.__dict__['lgettext'] = self.lgettext
+ if "lngettext" in names:
+ __builtin__.__dict__['lngettext'] = self.lngettext
+

0 comments on commit 56e9173

Please sign in to comment.
Something went wrong with that request. Please try again.