From c5c4a1a73812f115fe330ae1b6447c24267da194 Mon Sep 17 00:00:00 2001 From: Ricardo Lafuente Date: Nov 21 2023 11:09:53 +0000 Subject: Activate series plugin --- diff --git a/website/plugins/series/Readme.md b/website/plugins/series/Readme.md new file mode 100644 index 0000000..fecb367 --- /dev/null +++ b/website/plugins/series/Readme.md @@ -0,0 +1,48 @@ +Series plugin +------------- + +**NOTE:** [This plugin has been moved to its own repository](https://github.com/pelican-plugins/series). Please file any issues/PRs there. Once all plugins have been migrated to the [new Pelican Plugins organization](https://github.com/pelican-plugins), this monolithic repository will be archived. + +The series plugin allows you to join different posts into a series. + +In order to mark posts as part of a series, use the `:series:` metadata: + + :series: NAME_OF_THIS_SERIES + +or, in Markdown syntax + + Series: NAME_OF_THIS_SERIES + +The plugin collects all articles belonging to the same series and provides +series-related variables that you can use in your template. + +#### Indexing +By default articles in a series are ordered by date and then automatically numbered. + +If you want to force a given order just specify the `:series_index:` metadata or in Markdown `series_index:`, +starting from 1. All articles with this enforced index are put at the beginning of +the series and ordered according to the index itself. All the remaining articles +come after them, ordered by date. + +The plugin provides the following variables to your templates + + * `article.series.name` is the name of the series as specified in the article metadata + * `article.series.index` is the index of the current article inside the series + * `article.series.all` is an ordered list of all articles in the series (including the current one) + * `article.series.all_previous` is an ordered list of the articles published before the current one + * `article.series.all_next` is an ordered list of the articles published after the current one + * `article.series.previous` is the previous article in the series (a shortcut to `article.series.all_previous[-1]`) + * `article.series.next` is the next article in the series (a shortcut to `article.series.all_next[0]`) + +For example: + + {% if article.series %} +

This post is part {{ article.series.index }} of the "{{ article.series.name }}" series:

+
    + {% for part_article in article.series.all %} +
  1. + {{ part_article.title }} +
  2. + {% endfor %} +
+ {% endif %} diff --git a/website/plugins/series/__init__.py b/website/plugins/series/__init__.py new file mode 100644 index 0000000..451ef23 --- /dev/null +++ b/website/plugins/series/__init__.py @@ -0,0 +1 @@ +from .series import * diff --git a/website/plugins/series/series.py b/website/plugins/series/series.py new file mode 100644 index 0000000..c183de6 --- /dev/null +++ b/website/plugins/series/series.py @@ -0,0 +1,72 @@ +# -*- 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 operator import itemgetter + +from pelican import signals + + +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)