|
@@ -6,8 +6,11 @@ import os
|
|
|
import six
|
|
|
import logging
|
|
|
from itertools import chain
|
|
|
+from collections import defaultdict
|
|
|
|
|
|
-from pelican import signals, Pelican
|
|
|
+import gettext
|
|
|
+
|
|
|
+from pelican import signals
|
|
|
from pelican.contents import Page, Article
|
|
|
|
|
|
from ._regenerate_context_helpers import regenerate_context_articles
|
|
@@ -17,6 +20,7 @@ from ._regenerate_context_helpers import regenerate_context_articles
|
|
|
# Global vars
|
|
|
_main_site_generated = False
|
|
|
_main_site_lang = "en"
|
|
|
+_main_siteurl = ''
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
@@ -27,13 +31,17 @@ 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
|
|
|
s = pelican_obj.settings
|
|
|
for content in ['ARTICLE', 'PAGE']:
|
|
|
for meta in ['_URL', '_SAVE_AS']:
|
|
|
s[content + '_LANG' + meta] = s[content + meta]
|
|
|
+ if not _main_site_generated:
|
|
|
+ _main_site_lang = s['DEFAULT_LANG']
|
|
|
+ _main_siteurl = s['SITEURL']
|
|
|
|
|
|
|
|
|
-
|
|
|
+
|
|
|
def create_lang_subsites(pelican_obj):
|
|
|
"""For each language create a subsite using the lang-specific config
|
|
|
|
|
@@ -42,22 +50,21 @@ def create_lang_subsites(pelican_obj):
|
|
|
and set DELETE_OUTPUT_DIRECTORY to False to prevent deleting output from previous runs
|
|
|
Then generate the subsite using a PELICAN_CLASS instance and its run method.
|
|
|
"""
|
|
|
- global _main_site_generated, _main_site_lang
|
|
|
+ global _main_site_generated
|
|
|
if _main_site_generated: # make sure this is only called once
|
|
|
return
|
|
|
else:
|
|
|
_main_site_generated = True
|
|
|
|
|
|
orig_settings = pelican_obj.settings
|
|
|
- _main_site_lang = orig_settings['DEFAULT_LANG']
|
|
|
for lang, overrides in orig_settings.get('I18N_SUBSITES', {}).items():
|
|
|
settings = orig_settings.copy()
|
|
|
settings.update(overrides)
|
|
|
- settings['SITEURL'] = orig_settings['SITEURL'] + '/' + lang
|
|
|
+ settings['SITEURL'] = _main_siteurl + '/' + 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
|
|
|
-
|
|
|
+ settings['DELETE_OUTPUT_DIRECTORY'] = False # prevent deletion of previous runs
|
|
|
+
|
|
|
cls = settings['PELICAN_CLASS']
|
|
|
if isinstance(cls, six.string_types):
|
|
|
module, cls_name = cls.rsplit('.', 1)
|
|
@@ -105,22 +112,22 @@ def update_generator_contents(generator, *args):
|
|
|
else: # is an article generator
|
|
|
for article in chain(generator.articles, generator.drafts):
|
|
|
move_translations_links(article)
|
|
|
-
|
|
|
+
|
|
|
if not generator.settings.get('HIDE_UNTRANSLATED_CONTENT', True):
|
|
|
return
|
|
|
contents = generator.pages if is_pages_gen else generator.articles
|
|
|
- hidden_contents = generator.hidden_pages if is_pages_gen else generator.drafts
|
|
|
+ hidden_contents = generator.hidden_pages if is_pages_gen else generator.drafts
|
|
|
default_lang = generator.settings['DEFAULT_LANG']
|
|
|
for content_object in contents:
|
|
|
if content_object.lang != default_lang:
|
|
|
if isinstance(content_object, Page):
|
|
|
content_object.status = 'hidden'
|
|
|
elif isinstance(content_object, Article):
|
|
|
- content_object.status = 'draft'
|
|
|
+ content_object.status = 'draft'
|
|
|
contents.remove(content_object)
|
|
|
hidden_contents.append(content_object)
|
|
|
if not is_pages_gen: # regenerate categories, tags, etc. for articles
|
|
|
- if hasattr(generator, '_generate_context_aggregate'): # if implemented
|
|
|
+ if hasattr(generator, '_generate_context_aggregate'): # if implemented
|
|
|
# Simulate __init__ for fields that need it
|
|
|
generator.dates = {}
|
|
|
generator.tags = defaultdict(list)
|
|
@@ -131,8 +138,40 @@ def update_generator_contents(generator, *args):
|
|
|
regenerate_context_articles(generator)
|
|
|
|
|
|
|
|
|
+
|
|
|
+def install_templates_translations(generator):
|
|
|
+ """Install gettext translations for current DEFAULT_LANG in the jinja2.Environment
|
|
|
+
|
|
|
+ if the 'jinja2.ext.i18n' jinja2 extension is enabled
|
|
|
+ adds some useful variables into the template context
|
|
|
+ """
|
|
|
+ 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() }
|
|
|
+ extra_siteurls[_main_site_lang] = _main_siteurl
|
|
|
+ extra_siteurls.pop(generator.settings['DEFAULT_LANG'])
|
|
|
+ generator.context['extra_siteurls'] = extra_siteurls
|
|
|
+
|
|
|
+ if 'jinja2.ext.i18n' not in generator.settings['JINJA_EXTENSIONS']:
|
|
|
+ return
|
|
|
+ domain = generator.settings.get('I18N_GETTEXT_DOMAIN', 'messages')
|
|
|
+ localedir = generator.settings.get('I18N_GETTEXT_LOCALEDIR')
|
|
|
+ if localedir is None:
|
|
|
+ localedir = os.path.join(generator.theme, 'translations/')
|
|
|
+ languages = [generator.settings['DEFAULT_LANG']]
|
|
|
+ try:
|
|
|
+ translations = gettext.translation(domain, localedir, languages)
|
|
|
+ except (IOError, OSError):
|
|
|
+ logger.error("Cannot find translations for language '{}' in '{}' with domain '{}'. Installing NullTranslations.".format(languages[0], localedir, domain))
|
|
|
+ translations = gettext.NullTranslations()
|
|
|
+ newstyle = generator.settings.get('I18N_GETTEXT_NEWSTYLE', True)
|
|
|
+ generator.env.install_gettext_translations(translations, newstyle)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
def register():
|
|
|
signals.initialized.connect(disable_lang_vars)
|
|
|
+ signals.generator_init.connect(install_templates_translations)
|
|
|
signals.article_generator_finalized.connect(update_generator_contents)
|
|
|
signals.page_generator_finalized.connect(update_generator_contents)
|
|
|
signals.finalized.connect(create_lang_subsites)
|