Начало
This commit is contained in:
48
series/Readme.md
Normal file
48
series/Readme.md
Normal 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
1
series/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from .series import *
|
72
series/series.py
Normal file
72
series/series.py
Normal 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)
|
Reference in New Issue
Block a user