Articles translations are enabled. To use this feature, you need to

add a Lang meta into the each article and set DEFAULT_LANG setting
which is 'en' by default.

Than, only articles in the default language (or without variant in
default language) will be shown in the index of the blog. And each
Article will have translations list.

The same is applicable to the static Pages.

Also, separate feeds are generated for each language except default.
This commit is contained in:
Alexander Artemenko 2010-12-19 00:32:43 +03:00
commit 3afdb8fcff
4 changed files with 79 additions and 8 deletions

View file

@ -12,6 +12,8 @@ class Page(object):
def __init__(self, content, metadatas={}, settings={}, filename=None):
self.content = content
self.translations = []
self.status = "published" # default value
for key, value in metadatas.items():
setattr(self, key, value)
@ -20,11 +22,20 @@ class Page(object):
if 'AUTHOR' in settings:
self.author = settings['AUTHOR']
default_lang = settings.get('DEFAULT_LANG', 'en').lower()
if not hasattr(self, 'lang'):
self.lang = default_lang
self.in_default_lang = (self.lang == default_lang)
if not hasattr(self, 'slug'):
self.slug = slugify(self.title)
if not hasattr(self, 'url'):
self.url = '%s.html' % self.slug
if self.in_default_lang:
self.url = '%s.html' % self.slug
else:
self.url = '%s-%s.html' % (self.slug, self.lang)
if filename:
self.filename = filename

View file

@ -1,11 +1,13 @@
from operator import attrgetter
from itertools import chain
from datetime import datetime
from collections import defaultdict
import os
from jinja2 import Environment, FileSystemLoader
from jinja2.exceptions import TemplateNotFound
from pelican.utils import update_dict, copytree
from pelican.utils import update_dict, copytree, process_translations
from pelican.contents import Article, Page, is_valid_content
from pelican.readers import read_file
@ -75,7 +77,8 @@ class ArticlesGenerator(Generator):
def __init__(self, *args, **kwargs):
"""initialize properties"""
self.articles = []
self.articles = [] # only articles in default language
self.translations = []
self.dates = {}
self.tags = {}
self.categories = {}
@ -100,6 +103,15 @@ class ArticlesGenerator(Generator):
self.settings['CATEGORY_FEED_RSS'] % cat,
feed_type='rss')
translations_feeds = defaultdict(list)
for article in self.translations:
translations_feeds[article.lang].append(article)
for lang, items in translations_feeds.items():
items.sort(key=attrgetter('date'), reverse=True)
writer.write_feed(items, self.context,
self.settings['TRANSLATION_FEED'] % lang)
def generate_pages(self, writer):
"""Generate the pages on the disk
@ -116,7 +128,7 @@ class ArticlesGenerator(Generator):
for cat in self.categories:
write('category/%s.html' % cat, templates['category'], self.context,
category=cat, articles=self.categories[cat])
for article in self.articles:
for article in chain(self.translations, self.articles):
write('%s' % article.url,
templates['article'], self.context, article=article,
category=article.category)
@ -126,6 +138,7 @@ class ArticlesGenerator(Generator):
# return the list of files to use
files = self.get_files(self.path, exclude=['pages',])
all_articles = []
for f in files:
content, metadatas = read_file(f)
@ -149,11 +162,17 @@ class ArticlesGenerator(Generator):
if not is_valid_content(article, f):
continue
update_dict(self.categories, article.category, article)
if hasattr(article, 'tags'):
for tag in article.tags:
update_dict(self.tags, tag, article)
self.articles.append(article)
all_articles.append(article)
self.articles, self.translations = process_translations(all_articles)
for article in self.articles:
# only main articles are listed in categories, not translations
update_dict(self.categories, article.category, article)
# sort the articles by date
self.articles.sort(key=attrgetter('date'), reverse=True)
@ -175,20 +194,23 @@ class PagesGenerator(Generator):
super(PagesGenerator, self).__init__(*args, **kwargs)
def generate_context(self):
all_pages = []
for f in self.get_files(os.sep.join((self.path, 'pages'))):
content, metadatas = read_file(f)
page = Page(content, metadatas, settings=self.settings,
filename=f)
if not is_valid_content(page, f):
continue
self.pages.append(page)
all_pages.append(page)
self.pages, self.translations = process_translations(all_pages)
self._update_context(('pages', ))
self.context['PAGES'] = self.pages
def generate_output(self, writer):
templates = self.get_templates()
for page in self.pages:
for page in chain(self.translations, self.pages):
writer.write_file('pages/%s' % page.url, templates['page'],
self.context, page=page)

View file

@ -10,6 +10,7 @@ _DEFAULT_CONFIG = {'PATH': None,
'THEME_STATIC_PATHS': ['static',],
'FEED': 'feeds/all.atom.xml',
'CATEGORY_FEED': 'feeds/%s.atom.xml',
'TRANSLATION_FEED': 'feeds/all-%s.atom.xml',
'SITENAME': 'A Pelican Blog',
'DISPLAY_PAGES_ON_MENU': True,
'PDF_GENERATOR': False,

View file

@ -4,6 +4,8 @@ import os
import shutil
from datetime import datetime
from codecs import open as _open
from itertools import groupby
from operator import attrgetter
def update_dict(mapping, key, value):
"""Update a dict intenal list
@ -147,3 +149,38 @@ def truncate_html_words(s, num, end_text='...'):
# Return string
return out
def process_translations(content_list):
""" Finds all translation and returns
tuple with two lists (index, translations).
Index list includes items in default language
or items which have no variant in default language.
Also, for each content_list item, it
sets attribute 'translations'
"""
grouped_by_slugs = groupby(content_list, attrgetter('slug'))
index = []
translations = []
for slug, items in grouped_by_slugs:
items = list(items)
# find items with default language
default_lang_items = filter(
attrgetter('in_default_lang'),
items
)
len_ = len(default_lang_items)
if len_ > 1:
print u' [warning] there are %s varianits of "%s"' % (len_, slug)
elif len_ == 0:
default_lang_items = items[:1]
index.extend(default_lang_items)
translations.extend(filter(
lambda x: x not in default_lang_items,
items
))
for a in items:
a.translations = filter(lambda x: x != a, items)
return index, translations