From 4c33944bb92471f99b882bee3198e5bd3976237d Mon Sep 17 00:00:00 2001 From: Ondrej Grover Date: Wed, 5 Feb 2014 21:28:15 +0100 Subject: [PATCH] i18n_subsites: add lang_subsites template var, improve docs - the new variable makes it easier to implement language buttons - a short howto on language buttons is also provided - the dictionary mapping template vars are now OrderedDict for consistent-looking language buttons --- README.rst | 22 +++--- i18n_subsites.py | 18 +++-- implementing_language_buttons.rst | 113 ++++++++++++++++++++++++++++++ localizing_using_jinja2.rst | 39 ++++++++--- 4 files changed, 167 insertions(+), 25 deletions(-) create mode 100644 implementing_language_buttons.rst diff --git a/README.rst b/README.rst index 29a2e73..37ceef0 100644 --- a/README.rst +++ b/README.rst @@ -8,7 +8,7 @@ What it does ============ 1. The *\*_LANG_URL* and *\*_LANG_SAVE_AS* variables are set to their normal counterparts (e.g. *ARTICLE_URL*) so they don't conflict with this scheme. 2. While building the site for *DEFAULT_LANG* the translations of pages and articles are not generated, but their relations to the original content is kept via links to them. -3. For each non-default language a "sub-site" with a modified config [#conf]_ is created [#run]_, linking the translations to the originals (if available). The configured language code is appended to the *OUTPUT_PATH* and *SITEURL* of each sub-site. +3. For each non-default language a "sub-site" with a modified config [#conf]_ is created [#run]_, linking the translations to the originals (if available). The configured language code is appended to the *OUTPUT_PATH* and *SITEURL* of each sub-site. For each sub-site, *DEFAULT_LANG* is changed to the language of the sub-site so that articles in a different language are treated as translations. If *HIDE_UNTRANSLATED_CONTENT* is True (default), content without a translation for a language is generated as hidden (for pages) or draft (for articles) for the corresponding language sub-site. @@ -18,7 +18,9 @@ If *HIDE_UNTRANSLATED_CONTENT* is True (default), content without a translation Setting it up ============= -For each extra used language code, a language-specific variables overrides dictionary must be given (but can be empty) in the *I18N_SUBSITES* dictionary:: +For each extra used language code, a language-specific variables overrides dictionary must be given (but can be empty) in the *I18N_SUBSITES* dictionary + +.. code-block:: python PLUGINS = ['i18n_subsites', ...] @@ -40,18 +42,24 @@ Most importantly, this plugin can use localized templates for each sub-site. The - You can set a different *THEME* override for each language in *I18N_SUBSITES*, e.g. by making a copy of a theme ``my_theme`` to ``my_theme_lang`` and then editing the templates in the new localized theme. This approach means you don't have to deal with gettext ``*.po`` files, but it is harder to maintain over time. - You use only one theme and localize the templates using the `jinja2.ext.i18n Jinja2 extension `_. For a kickstart read this `guide <./localizing_using_jinja2.rst>`_. -It may be convenient to add language buttons to your theme in addition to the translation links. These buttons could, for example, point to the *SITEURL* of each (sub-)site. For this reason the plugin adds these variables to the template context: +It may be convenient to add language buttons to your theme in addition to the translation links of articles and pages. These buttons could, for example, point to the *SITEURL* of each (sub-)site. For this reason the plugin adds these variables to the template context: -extra_siteurls - A dictionary mapping languages to their *SITEURL*. The *DEFAULT_LANG* language of the current sub-site is not included, so this dictionary serves as a complement to current *DEFAULT_LANG* and *SITEURL*. This dictionary is useful for implementing global language buttons. main_lang The language of the top-level site — the original *DEFAULT_LANG* main_siteurl The *SITEURL* of the top-level site — the original *SITEURL* +lang_siteurls + An ordered dictionary, mapping all used languages to their *SITEURL*. The ``main_lang`` is the first key with ``main_siteurl`` as the value. This dictionary is useful for implementing global language buttons that show the language of the currently viewed (sub-)site too. +extra_siteurls + An ordered dictionary, subset of ``lang_siteurls``, the current *DEFAULT_LANG* of the rendered (sub-)site is not included, so for each (sub-)site ``set(extra_siteurls) == set(lang_siteurls) - set([DEFAULT_LANG])``. This dictionary is useful for implementing global language buttons that do not show the current language. + +If you don't like the default ordering of the ordered dictionaries, use a Jinja2 filter to alter the ordering. + +This short `howto <./implementing_language_buttons.rst>`_ shows two example implementations of language buttons. Usage notes =========== -- It is **mandatory** to specify *lang* metadata for each article and page as *DEFAULT_LANG* is later changed for each sub-site. +- It is **mandatory** to specify *lang* metadata for each article and page as *DEFAULT_LANG* is later changed for each sub-site, so content without *lang* metadata woudl be rendered in every (sub-)site. - As with the original translations functionality, *slug* metadata is used to group translations. It is therefore often convenient to compensate for this by overriding the content URL (which defaults to slug) using the *URL* and *Save_as* metadata. Future plans @@ -63,5 +71,3 @@ Development =========== - A demo and test site is in the ``gh-pages`` branch and can be seen at http://smartass101.github.io/pelican-plugins/ - -.. LocalWords: lang metadata diff --git a/i18n_subsites.py b/i18n_subsites.py index ec9a04a..2ae30e7 100644 --- a/i18n_subsites.py +++ b/i18n_subsites.py @@ -6,7 +6,7 @@ import os import six import logging from itertools import chain -from collections import defaultdict +from collections import defaultdict, OrderedDict import gettext @@ -22,6 +22,7 @@ from ._regenerate_context_helpers import regenerate_context_articles _main_site_generated = False _main_site_lang = "en" _main_siteurl = '' +_lang_siteurls = None logger = logging.getLogger(__name__) @@ -32,7 +33,7 @@ def disable_lang_vars(pelican_obj): e.g. ARTICLE_LANG_URL = ARTICLE_URL They would conflict with this plugin otherwise """ - global _main_site_lang, _main_siteurl + global _main_site_lang, _main_siteurl, _lang_siteurls s = pelican_obj.settings for content in ['ARTICLE', 'PAGE']: for meta in ['_URL', '_SAVE_AS']: @@ -40,7 +41,11 @@ def disable_lang_vars(pelican_obj): if not _main_site_generated: _main_site_lang = s['DEFAULT_LANG'] _main_siteurl = s['SITEURL'] - + _lang_siteurls = [(lang, _main_siteurl + '/' + lang) for lang in s.get('I18N_SUBSITES', {}).keys()] + # To be able to use url for main site root when SITEURL == '' (e.g. when developing) + _lang_siteurls = [(_main_site_lang, ('/' if _main_siteurl == '' else _main_siteurl))] + _lang_siteurls + _lang_siteurls = OrderedDict(_lang_siteurls) + def create_lang_subsites(pelican_obj): @@ -61,7 +66,7 @@ def create_lang_subsites(pelican_obj): for lang, overrides in orig_settings.get('I18N_SUBSITES', {}).items(): settings = orig_settings.copy() settings.update(overrides) - settings['SITEURL'] = _main_siteurl + '/' + lang + settings['SITEURL'] = _lang_siteurls[lang] settings['OUTPUT_PATH'] = os.path.join(orig_settings['OUTPUT_PATH'], lang, '') settings['DEFAULT_LANG'] = lang # to change what is perceived as translations settings['DELETE_OUTPUT_DIRECTORY'] = False # prevent deletion of previous runs @@ -150,10 +155,9 @@ def install_templates_translations(generator): """ generator.context['main_siteurl'] = _main_siteurl generator.context['main_lang'] = _main_site_lang - extra_siteurls = { lang: _main_siteurl + '/' + lang for lang in generator.settings.get('I18N_SUBSITES', {}).keys() } - # To be able to use url for main site root when SITEURL == '' (e.g. when developing) - extra_siteurls[_main_site_lang] = '/' if _main_siteurl == '' else _main_siteurl + generator.context['lang_siteurls'] = _lang_siteurls current_def_lang = generator.settings['DEFAULT_LANG'] + extra_siteurls = _lang_siteurls.copy() extra_siteurls.pop(current_def_lang) generator.context['extra_siteurls'] = extra_siteurls diff --git a/implementing_language_buttons.rst b/implementing_language_buttons.rst new file mode 100644 index 0000000..014cf1c --- /dev/null +++ b/implementing_language_buttons.rst @@ -0,0 +1,113 @@ +----------------------------- +Implementing language buttons +----------------------------- + +Each article with translations has translations links, but that's the only way to switch between language subsites. + +For this reason it is convenient to add language buttons to the top menu bar to make it simple to switch between the language subsites on all pages. + +Example designs +--------------- + +Language buttons showing other available languages +.................................................. + +The ``extra_siteurls`` dictionary is a mapping of all other (not the *DEFAULT_LANG* of the current (sub-)site) languages to the *SITEURL* of the respective (sub-)sites + +.. code-block:: jinja + + +