From e37d2614e2a1d623ae3b93860881b83be7a3d4c3 Mon Sep 17 00:00:00 2001 From: Julien Malik Date: Wed, 17 Feb 2016 12:51:05 +0100 Subject: [PATCH 1/6] [wip] internationalization --- prosopopee/prosopopee.py | 91 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 4 deletions(-) diff --git a/prosopopee/prosopopee.py b/prosopopee/prosopopee.py index 8340078..c197a1c 100644 --- a/prosopopee/prosopopee.py +++ b/prosopopee/prosopopee.py @@ -5,6 +5,7 @@ import json import yaml import shutil +import collections from jinja2 import Environment, FileSystemLoader @@ -18,6 +19,83 @@ CACHE_VERSION = 1 +class ListTranslateViewIterator(object): + def __init__(self, lang, l): + self.lang = lang + self.it = iter(l) + + def next(self): + return _(self.lang, self.it.next()) + + def __iter__(self): + return self + +class ListTranslateView(collections.Sequence): + def __init__(self, lang, l): + self.lang=lang + self.proxified_list = l + + def __len__(self): + return len(self.proxified_list) + + def __getitem__(self, i): + return _(self.lang, self.proxified_list[i]) + + def __iter__(self): + return ListTranslateViewIterator(self.lang, self.proxified_list) + + def __str__(self): + # TODO: fails with unicode input, but we don't use it... + return "[%s]" % (", ".join(["%s" % x for x in self])) + +class DictTranslateViewIterator(object): + def __init__(self, lang, d): + self.lang = lang + self.it = iter(d) + + def next(self): + return _(self.lang, self.it.next()) + + def __iter__(self): + return self + +class DictTranslateView(collections.Mapping): + def __init__(self, lang, d): + self.lang=lang + self.proxified_dict = d + + def __len__(self): + return len(self.proxified_dict) + + def __getitem__(self, key): + if key in ('title', 'sub_title', 'text'): + try: + return self.proxified_dict[key][self.lang] + except(KeyError, TypeError): + # KeyError : when text is actually a dict (e.g. full-picture) + # TypeError : when value is a string and not a locales dict (monolingual case) + pass + return _(self.lang, self.proxified_dict[key]) + + def __iter__(self): + return DictTranslateViewIterator(self.lang, self.proxified_dict) + + def __str__(self): + # TODO: fails with unicode input, but we don't use it... + return "{%s}" % (", ".join(["'%s': '%s'" % (k,v) for (k,v) in self.iteritems()])) + +def _(lang, o): + # TODO: should support iterators too + # TODO: testing for isinstance(o, collections.Mapping) creates an infinite recursion loop + t = type(o) + if isinstance(o, dict): + return DictTranslateView(lang, o) + elif isinstance(o, list): + return ListTranslateView(lang, o) + else: + return o + + class Cache(object): cache_file_path = os.path.join(os.getcwd(), ".prosopopee_cache") @@ -130,6 +208,8 @@ def main(): error(isinstance(settings, dict), "Your settings.yaml should be a dict") error(settings.get("title"), "You should specify a title in your main settings.yaml") + langs = settings.get("multilingual", [None]) + front_page_galleries_cover = [] dirs = filter(lambda x: x not in (".", "..") and os.path.isdir(x) and os.path.exists(os.path.join(os.getcwd(), x, "settings.yaml")), os.listdir(os.getcwd())) @@ -173,16 +253,19 @@ def main(): Image.target_dir = os.path.join(os.getcwd(), "build", gallery) template_to_render = page_template if gallery_settings.get("static") else gallery_index_template - open(os.path.join("build", gallery, "index.html"), "w").write(template_to_render.render(settings=settings, gallery=gallery_settings, Image=Image).encode("Utf-8")) + for lang in langs: + filename = "index.%s.html" % lang if lang else "index.html" + open(os.path.join("build", gallery, filename), "w").write(template_to_render.render(settings=_(lang,settings), gallery=_(lang,gallery_settings), Image=Image).encode("Utf-8")) - front_page_galleries_cover = reversed(sorted(front_page_galleries_cover, key=lambda x: x["date"])) + front_page_galleries_cover = list(reversed(sorted(front_page_galleries_cover, key=lambda x: x["date"]))) # this should probably be a factory Image.base_dir = os.getcwd() Image.target_dir = os.path.join(os.getcwd(), "build") - open(os.path.join("build", "index.html"), "w").write(index_template.render(settings=settings, galleries=front_page_galleries_cover, Image=Image).encode("Utf-8")) - + for lang in langs: + filename = "index.%s.html" % lang if lang else "index.html" + open(os.path.join("build", filename), "w").write(index_template.render(settings=_(lang,settings), galleries=_(lang,front_page_galleries_cover), Image=Image).encode("Utf-8")) if __name__ == '__main__': main() From d6dc14978b57faff88d9020176834b605ae0c8c6 Mon Sep 17 00:00:00 2001 From: Julien Malik Date: Wed, 17 Feb 2016 15:05:00 +0100 Subject: [PATCH 2/6] [enh] switch language when browsing --- prosopopee/prosopopee.py | 5 +++-- prosopopee/templates/base.html | 1 + prosopopee/templates/gallery-index.html | 1 + prosopopee/templates/locales.html | 28 +++++++++++++++++++++++++ 4 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 prosopopee/templates/locales.html diff --git a/prosopopee/prosopopee.py b/prosopopee/prosopopee.py index c197a1c..0790f9f 100644 --- a/prosopopee/prosopopee.py +++ b/prosopopee/prosopopee.py @@ -209,6 +209,7 @@ def main(): error(settings.get("title"), "You should specify a title in your main settings.yaml") langs = settings.get("multilingual", [None]) + main_lang = langs[0] front_page_galleries_cover = [] @@ -254,7 +255,7 @@ def main(): template_to_render = page_template if gallery_settings.get("static") else gallery_index_template for lang in langs: - filename = "index.%s.html" % lang if lang else "index.html" + filename = "index.%s.html" % lang if lang and lang != main_lang else "index.html" open(os.path.join("build", gallery, filename), "w").write(template_to_render.render(settings=_(lang,settings), gallery=_(lang,gallery_settings), Image=Image).encode("Utf-8")) front_page_galleries_cover = list(reversed(sorted(front_page_galleries_cover, key=lambda x: x["date"]))) @@ -264,7 +265,7 @@ def main(): Image.target_dir = os.path.join(os.getcwd(), "build") for lang in langs: - filename = "index.%s.html" % lang if lang else "index.html" + filename = "index.%s.html" % lang if lang and lang != main_lang else "index.html" open(os.path.join("build", filename), "w").write(index_template.render(settings=_(lang,settings), galleries=_(lang,front_page_galleries_cover), Image=Image).encode("Utf-8")) if __name__ == '__main__': diff --git a/prosopopee/templates/base.html b/prosopopee/templates/base.html index a62bd68..5583af7 100644 --- a/prosopopee/templates/base.html +++ b/prosopopee/templates/base.html @@ -27,6 +27,7 @@

{{ settings.title }}

{% block content %} {% endblock %} + {% include "locales.html" %} diff --git a/prosopopee/templates/gallery-index.html b/prosopopee/templates/gallery-index.html index 1902c60..4e4c64e 100644 --- a/prosopopee/templates/gallery-index.html +++ b/prosopopee/templates/gallery-index.html @@ -42,6 +42,7 @@ }); }); + {% include "locales.html" %} diff --git a/prosopopee/templates/locales.html b/prosopopee/templates/locales.html new file mode 100644 index 0000000..5feb843 --- /dev/null +++ b/prosopopee/templates/locales.html @@ -0,0 +1,28 @@ + {% if settings.multilingual -%} + + + {% endif -%} From ab44f41fa2b89bcace00fc3ff653e03074d750ea Mon Sep 17 00:00:00 2001 From: Julien Malik Date: Wed, 17 Feb 2016 15:05:55 +0100 Subject: [PATCH 3/6] [style] remove unused code. this can work without jquery --- prosopopee/templates/locales.html | 1 - 1 file changed, 1 deletion(-) diff --git a/prosopopee/templates/locales.html b/prosopopee/templates/locales.html index 5feb843..bf5879f 100644 --- a/prosopopee/templates/locales.html +++ b/prosopopee/templates/locales.html @@ -1,5 +1,4 @@ {% if settings.multilingual -%} - {% endif -%} From 160566fa01df80a42641211241f72a846159b0b4 Mon Sep 17 00:00:00 2001 From: Julien Malik Date: Wed, 17 Feb 2016 15:33:48 +0100 Subject: [PATCH 5/6] [enh] redirect in the header section (is it really better?) --- prosopopee/templates/base.html | 2 +- prosopopee/templates/gallery-index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/prosopopee/templates/base.html b/prosopopee/templates/base.html index 5583af7..7749ed0 100644 --- a/prosopopee/templates/base.html +++ b/prosopopee/templates/base.html @@ -8,6 +8,7 @@ {{ settings.title }} + {% include "locales.html" %} @@ -27,7 +28,6 @@

{{ settings.title }}

{% block content %} {% endblock %} - {% include "locales.html" %} diff --git a/prosopopee/templates/gallery-index.html b/prosopopee/templates/gallery-index.html index 4e4c64e..236d31c 100644 --- a/prosopopee/templates/gallery-index.html +++ b/prosopopee/templates/gallery-index.html @@ -11,6 +11,7 @@ {{ gallery.title }} · {{ settings.title }} + {% include "locales.html" %} @@ -42,7 +43,6 @@ }); }); - {% include "locales.html" %} From b0a8d16471a464f9996e20bf4ad11a5f5d50aea9 Mon Sep 17 00:00:00 2001 From: Julien Malik Date: Wed, 17 Feb 2016 16:26:18 +0100 Subject: [PATCH 6/6] [enh] more generic approach for modifying a dict --- prosopopee/prosopopee.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/prosopopee/prosopopee.py b/prosopopee/prosopopee.py index 0790f9f..d6b981e 100644 --- a/prosopopee/prosopopee.py +++ b/prosopopee/prosopopee.py @@ -68,14 +68,10 @@ def __len__(self): return len(self.proxified_dict) def __getitem__(self, key): - if key in ('title', 'sub_title', 'text'): - try: - return self.proxified_dict[key][self.lang] - except(KeyError, TypeError): - # KeyError : when text is actually a dict (e.g. full-picture) - # TypeError : when value is a string and not a locales dict (monolingual case) - pass - return _(self.lang, self.proxified_dict[key]) + if isinstance(self.proxified_dict[key], dict) and self.proxified_dict[key].has_key(self.lang): + return self.proxified_dict[key][self.lang] + else: + return _(self.lang, self.proxified_dict[key]) def __iter__(self): return DictTranslateViewIterator(self.lang, self.proxified_dict)