Your homepage, the index.html
file, is just another template from the DIRECT_TEMPLATES
list. It'll depend on your theme exactly how it is generated, but you can always override specific templates locally, or you can create a new template for your homepage to replace it (and optionally redirect the original index.html
generated page to a different location).
Either way, you can then generate a section that shows the articles from a single category. All template pages are given the same basic variables, which includes the articles
list, as well as a categories
list with (Category, list_of_articles)
tuples.
The easiest way to get all articles for a single, specific category is to filter the articles
list directly with the Jinja2 selectattr
filter. selectattr('category', '==', categoryname)
is matched both against the category name or the slug (whatever you set categoryname
to is converted to a slug for you). So if your category is named News
, then both 'News'
or 'news'
works:
<h2>News:</h2>
<ol id="posts-list" class="hfeed">
{% for article in articles | selectattr('category', '==', 'news') %}
<li><article class="hentry">
<header>
<h1><a href="{{ SITEURL }}/{{ article.url }}" rel="bookmark"
title="Permalink to {{ article.title|striptags }}">{{ article.title }}</a></h1>
</header>
<div class="entry-content">
{% include 'article_infos.html' %}
{{ article.summary }}
<a class="readmore" href="{{ SITEURL }}/{{ article.url }}">read more</a>
{% include 'comments.html' %}
</div><!-- /.entry-content -->
</article></li>
{% endfor %}
</ol>
The above reuses the simple theme article markup. You may want to limit the number of news articles; in that case use the batch(size)
filter together with first
:
<h2>News:</h2>
<ol id="posts-list" class="hfeed">
{% for article in articles | selectattr('category', '==', 'news') | batch(5) | first %}
<!-- render article, etc. -->
The above takes the first 5 articles with News
as the category.
Since the basic theme reuses the index.html
template for all of the individual archive pages too (for each category, author or tag page), I'd not override the index
direct template here. Instead, I'd create a new homepage
template (in the pages directory) and write that to index.html
and. You need to add the template in the TEMPLATE_PAGES
dictionary, where your template pages should live in a separate directory that is configured not to be treated as articles or pages.
Create a new directory for template pages in your content directory; you'll need to make sure Pelican doesn't try to treat files there as articles, so add it to the ARTICLE_EXCLUDES
list. So if all your Pelican your content lives in content/
, and you have a file homepage.html
in the directory output/templates/
, you'd use:
ARTICLE_EXCLUDES = ['templates']
TEMPLATE_PAGES = {
'templates/homepage.html': 'index.html',
}
This will overwrite the default index.html
generated for articles, there is no need to remove anything from DIRECT_TEMPLATES
but you could do so to avoid generating a file you never keep.
The homepage.html
template can make full use of any existing templates in the theme, so you can just extend base.html
that most themes will have defined:
{% extends "base.html" %}
{% block content %}
<section id="content">
<h2>Recent news:</h2>
<ol>
{% for article in articles | selectattr('category', 'equalto', 'news') | batch(5) | first %}
<!-- markup for each news item -->
{% endfor %}
</ol>
</section><!-- /#content -->
{% endblock content %}
Instead of overwriting the default index
, you can also set INDEX_SAVE_AS
to direct the original index.html
file elsewhere:
ARTICLE_EXCLUDES = ['templates']
TEMPLATE_PAGES = {
'pages/homepage.html': 'index.html',
}
# move the original article index elsewhere:
INDEX_SAVE_AS = 'all_articles.html'
If you use a theme that doesn't reuse the index.html
template for more pages or you want to try to make the template work for in those contexts anyway, then you can override the template used for index
instead. To override the default index.html
from your theme, create a local directory (overrides
perhaps) to put your local version into, then add that directory to the THEME_TEMPLATES_OVERRIDES
list in your configuration:
THEME_TEMPLATES_OVERRIDES = ['overrides']
Now when Pelican tries to load the index.html
template to render the index
direct template, it'll look for overrides/index.html
first. So in overrides/
add your own index.html
:
{% extends "base.html" %}
{% block content %}
<section id="content">
<!-- put your desired content here -->
</section><!-- /#content -->
{% endblock content %}
A word on pagination: all templates, except for the special per-archive-type pages (categories, authors, tags, periods), are paginated on the full articles
list, this isn't something that is further configurable. This means you can't paginate a homepage on a single category of articles.
This means that if you override the index.html
template and removed the full article listing, then you may want to remove index
from the PAGINATED_TEMPLATES
dictionary so it isn't re-generated multiple times to match your article list.