Начало

This commit is contained in:
2022-01-15 16:41:37 +03:00
commit 7e8c591b51
59 changed files with 2790 additions and 0 deletions

48
series/Readme.md Normal file
View File

@ -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 %}
<p>This post is part {{ article.series.index }} of the "{{ article.series.name }}" series:</p>
<ol class="parts">
{% for part_article in article.series.all %}
<li {% if part_article == article %}class="active"{% endif %}>
<a href='{{ SITEURL }}/{{ part_article.url }}'>{{ part_article.title }}</a>
</li>
{% endfor %}
</ol>
{% endif %}

1
series/__init__.py Normal file
View File

@ -0,0 +1 @@
from .series import *

72
series/series.py Normal file
View File

@ -0,0 +1,72 @@
# -*- coding: utf-8 -*-
"""
This plugin extends the original series plugin
by FELD Boris <lothiraldan@gmail.com>
Copyright (c) Leonardo Giordani <giordani.leonardo@gmail.com>
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)