问题
I'm using the Pelican static site generator to create a high-volume blog. Pelican themes paginate the index page, showing a list of post titles and summaries, sorting the posts by date. Here's an example of how this is accomplished, from the bootstrap theme:
{% if articles %}
{% for article in (articles_page.object_list if articles_page else articles) %}
<div class='article'>
<h2>{{ article.title }}</h2>
<div class="well small">{% include "metadata.html" %}</div>
<div class="summary">{{ article.summary }} <a class="btn primary xsmall" href="{{ SITEURL }}/{{ article.url }}">more…</a>
</div>
</div>
{% endfor %}
{%endif%}
And here's the also-pretty-standard code for the pagination navigation:
{% if articles_page and articles_paginator.num_pages > 1 %}
<div class="pagination">
<ul>
{% if articles_page.has_previous() %}
{% set num = articles_page.previous_page_number() %}
<li class="prev"><a href="{{ SITEURL }}/{{ page_name }}{{ num if num > 1 else '' }}.html">← Previous</a></li>
{% else %}
<li class="prev disabled"><a href="#">← Previous</a></li>
{% endif %}
{% for num in range( 1, 1 + articles_paginator.num_pages ) %}
<li class="{{ 'active' if num == articles_page.number else '' }}"><a href="{{ SITEURL }}/{{ page_name }}{{ num if num > 1 else '' }}.html">{{ num }}</a></li>
{% endfor %}
{% if articles_page.has_next() %}
<li class="next"><a href="{{ SITEURL }}/{{ page_name }}{{ articles_page.next_page_number() }}.html">Next →</a></li>
{% else %}
<li class="next disabled"><a href="#">→ Next</a></li>
{% endif %}
Since my site has lots of information to share in a small space--sometimes 20 articles a day--I've written summaries fit in a single line. Instead of listing the date with each post, I'd like the index page to group posts by date, like this:
February 1, 2014
Post 1
Post 2
Post 3
February 2, 2014
Post 1
Post 2
Here's a way to group articles by date with Jinja2:
{% if articles %}
{% for year, year_articles in articles|groupby('date.year')|sort(reverse=True) %}
{% for month, month_articles in year_articles|groupby('date.month')|sort(reverse=True) %}
{% for day, day_articles in month_articles|groupby('date.day')|sort(reverse=True) %}
<dl>
<dt>{{ day_articles[0].date.strftime('%d %B %Y') }}</dt>
{% for article in day_articles %}
<dd>
<a href="{{ SITEURL }}/{{ article.url }}" rel="bookmark" title="Permalink to {{ article.title|striptags }}">{{ article.title }}</a>
</dd>
{% endfor %}
</dl>
{% endfor %}
{% endfor %}
{% endfor %}
{% endif %}
I want to combine these features so that the articles are grouped by date and paginated. So far my admitted-guesswork has failed. I'm using 100 articles to start with, set to show 10 articles per page; in my attempts, the index lists 10 pages of articles but it shows all of the articles on each page. I'd be happy with any working solution. Any ideas how to proceed?
Further thoughts
Maybe instead of all the grouping, a Jinja if-loop could identify the first article listed for that date and write the date, then the linked article title, etc. For all subsequent articles, it would skip printing the date and write the linked article title, etc. I'm not sure how to do that, and that if-loop would still have to avoid knocking the paginator off its game. But if it works, creating a nice-looking list is a CSS job instead of a Jinja job.
回答1:
Use the dates_page variable instead of articles, see details here: http://pelican.readthedocs.org/en/latest/themes.html#index-html
- dates_paginator A paginator object for the article list, ordered by date, ascending.
- dates_page The current page of articles, ordered by date, ascending.
回答2:
Probably far too late to be helpful, but I'm sharing because I just spent an evening fighting with this and finally got it working in Pelican 4.2. I'm not grouping by individual date, but this should still work with an extra inner loop for the day:
{% for year, year_group in dates_page.object_list|groupby('date.year')|reverse %}
{% for month, month_group in year_group|groupby('date.month')|reverse %}
<h1>{{ (month_group|first).date|strftime('%B %Y') }}</h1>
{% for article in month_group %}
... do stuff with individual article here ...
{% endfor %}
{% endfor %}
{% endfor %}
{% if dates_page.has_other_pages() %}
{% include 'pagination.html' %}
{% endif %}
The key thing is to the start outer loop with dates_page.object_list; dates_page provides the paged list of articles ordered by date, and object_list
is the iterable that provides the actual list of articles used by the template. Other examples I was trying to use omitted object_list
and causing various errors.
The block of code at the bottom loads the pagination template as needed.
来源:https://stackoverflow.com/questions/21814797/how-can-i-use-jinja2-to-group-articles-by-date-and-paginate-in-pelican