# -*- coding: utf-8 -*- """ This plugin extends the original series plugin by FELD Boris Copyright (c) Leonardo Giordani Joins articles in a series and provides variables to manage the series in the template. """ from collections import defaultdict from pelican import signals from logging import warning from operator import itemgetter def aggregate_series(generator): series = defaultdict(list) # This cycles through all articles in the given generator # and collects the 'series' metadata, if present. # The 'series_index' metadata is also stored, if specified for article in generator.articles: if 'series' in article.metadata: article_entry = ( article.metadata.get('series_index', None), article.metadata['date'], article ) series[article.metadata['series']].append(article_entry) # This uses items() which on Python2 is not a generator # but we are dealing with a small amount of data so # there shouldn't be performance issues =) for series_name, series_articles in series.items(): # This is not DRY but very simple to understand forced_order_articles = [ art_tup for art_tup in series_articles if art_tup[0] is not None] date_order_articles = [ art_tup for art_tup in series_articles if art_tup[0] is None] forced_order_articles.sort(key=itemgetter(0)) date_order_articles.sort(key=itemgetter(1)) all_articles = forced_order_articles + date_order_articles ordered_articles = [art_tup[2] for art_tup in all_articles] enumerated_articles = enumerate(ordered_articles) for index, article in enumerated_articles: article.series = dict() article.series['name'] = series_name article.series['index'] = index + 1 article.series['all'] = ordered_articles article.series['all_previous'] = ordered_articles[0: index] article.series['all_next'] = ordered_articles[index + 1:] if index > 0: article.series['previous'] = ordered_articles[index - 1] else: article.series['previous'] = None try: article.series['next'] = ordered_articles[index + 1] except IndexError: article.series['next'] = None def register(): signals.article_generator_finalized.connect(aggregate_series)