123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- """i18n_subsites plugin creates i18n-ized subsites of the default site"""
- import os
- import six
- import logging
- from itertools import chain
- from pelican import signals, Pelican
- from pelican.contents import Page, Article
- from ._regenerate_context_helpers import regenerate_context_articles
- # Global vars
- _main_site_generated = False
- _main_site_lang = "en"
- logger = logging.getLogger(__name__)
- def disable_lang_vars(pelican_obj):
- """Set lang specific url and save_as vars to the non-lang defaults
- e.g. ARTICLE_LANG_URL = ARTICLE_URL
- They would conflict with this plugin otherwise
- """
- s = pelican_obj.settings
- for content in ['ARTICLE', 'PAGE']:
- for meta in ['_URL', '_SAVE_AS']:
- s[content + '_LANG' + meta] = s[content + meta]
- def create_lang_subsites(pelican_obj):
- """For each language create a subsite using the lang-specific config
- for each generated lang append language subpath to SITEURL and OUTPUT_PATH
- and set DEFAULT_LANG to the language code to change perception of what is translated
- 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
- 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['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
-
- cls = settings['PELICAN_CLASS']
- if isinstance(cls, six.string_types):
- module, cls_name = cls.rsplit('.', 1)
- module = __import__(module)
- cls = getattr(module, cls_name)
- pelican_obj = cls(settings)
- logger.debug("Generating i18n subsite for lang '{}' using class '{}'".format(lang, str(cls)))
- pelican_obj.run()
- def move_translations_links(content_object):
- """This function points translations links to the sub-sites
- by prepending their location with the language code
- or directs an original DEFAULT_LANG translation back to top level site
- """
- for translation in content_object.translations:
- if translation.lang == _main_site_lang:
- # cannot prepend, must take to top level
- lang_prepend = '../'
- else:
- lang_prepend = translation.lang + '/'
- translation.override_url = lang_prepend + translation.url
- def update_generator_contents(generator, *args):
- """Update the contents lists of a generator
- Empty the (hidden_)translation attribute of article and pages generators
- to prevent generating the translations as they will be generated in the lang sub-site
- and point the content translations links to the sub-sites
- Hide content without a translation for current DEFAULT_LANG
- if HIDE_UNTRANSLATED_CONTENT is True
- """
- generator.translations = []
- is_pages_gen = hasattr(generator, 'pages')
- if is_pages_gen:
- generator.hidden_translations = []
- for page in chain(generator.pages, generator.hidden_pages):
- move_translations_links(page)
- 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
- 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'
- 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
- # Simulate __init__ for fields that need it
- generator.dates = {}
- generator.tags = defaultdict(list)
- generator.categories = defaultdict(list)
- generator.authors = defaultdict(list)
- generator._generate_context_aggregate()
- else: # fallback for Pelican 3.3.0
- regenerate_context_articles(generator)
- def register():
- signals.initialized.connect(disable_lang_vars)
- signals.article_generator_finalized.connect(update_generator_contents)
- signals.page_generator_finalized.connect(update_generator_contents)
- signals.finalized.connect(create_lang_subsites)
|