Jinja Post Index Template

The Index Template

This is the Jinja template used to produce the page with the latest posts. The number of posts on the page is set in conf.py using the INDEX_DISPLAY_POST_COUNT variable (10 is the default). I'm overriding the default because I want to be able to add p5 code to posts. Using a special template works when you look at single posts (see the p5.tmpl template) but the index template won't pick up on that so I'm inserting a macro call to get p5 into the main page (if there's a p5 post on it).

This overrides the built-in index.tmpl found at <virtualenv>/lib/python3.11/site-packages/nikola/data/themes/base-jinja/templates/.

In Beach Pig Thigh it's located at themes/custom-jinja/templates/index.tmpl.

This is needed for two templates:

  • p5.tmpl
  • altair.tmpl

The Tangle

Here's the tangle that creates the template. It's written in noweb syntax so anything written with double angle brackets (like <<default-imports>>) will be replace by one of the sections defined later.

{#  -*- coding: utf-8 -*- #}
<<default-imports>>

<<monkey-imports>>

{% extends 'base.tmpl' %}

{% block extra_head %}
    {{ super() }}
    {% if posts and (permalink == '/' or permalink == '/' + index_file) %}
        <link rel="prefetch" href="{{ posts[0].permalink() }}" type="text/html">
    {% endif %}
    {{ math.math_styles_ifposts(posts) }}
    <<monkey-posts-check>>
{% endblock %}

{% block content %}
{% block content_header %}
    {{ feeds_translations.translation_link(kind) }}
{% endblock %}
{% if 'main_index' in pagekind %}
    {{ front_index_header }}
{% endif %}
{% if page_links %}
    {{ pagination.page_navigation(current_page, page_links, prevlink, nextlink, prev_next_links_reversed) }}
{% endif %}
<div class="postindex">
{% for post in posts %}
    <article class="h-entry post-{{ post.meta('type') }}" itemscope="itemscope" itemtype="http://schema.org/Article">
    <header>
      <h1 class="p-name entry-title"><a href="{{ post.permalink() }}" class="u-url">{{ post.title()|e }}</a></h1>
        <div class="metadata">
            <p class="byline author vcard"><span class="byline-name fn" itemprop="author">
            {% if author_pages_generated and multiple_authors_per_post %}
                {% for author in post.authors() %}
                    <a href="{{ _link('author', author) }}">{{ author|e }}</a>
                {% endfor %}
            {% elif author_pages_generated %}
                <a href="{{ _link('author', post.author()) }}">{{ post.author()|e }}</a>
            {% else %}
                {{ post.author()|e }}
            {% endif %}
            </span></p>
            <p class="dateline">
            <a href="{{ post.permalink() }}" rel="bookmark">
            <time class="published dt-published" datetime="{{ post.formatted_date('webiso') }}" itemprop="datePublished" title="{{ post.formatted_date(date_format)|e }}">{{ post.formatted_date(date_format)|e }}</time>
            {% if post.updated and post.updated != post.date %}
                <span class="updated"> ({{ messages("updated") }}
                    <time class="dt-updated" datetime="{{ post.formatted_updated('webiso') }}" itemprop="dateUpdated" title="{{ post.formatted_updated(date_format)|e }}">{{ post.formatted_updated(date_format)|e }}</time>)</span>
            {% endif %}
            </a>
            </p>
            {% if not post.meta('nocomments') and site_has_comments %}
                <p class="commentline">{{ comments.comment_link(post.permalink(), post._base_path) }}
            {% endif %}
        </div>
    </header>
    {% if index_teasers %}
    <div class="p-summary entry-summary">
    {{ post.text(teaser_only=True) }}
    {% else %}
    <div class="e-content entry-content">
    {{ post.text(teaser_only=False) }}
    {% endif %}
    </div>
    </article>
{% endfor %}
</div>
{{ helper.html_pager() }}
{{ comments.comment_link_script() }}
{{ math.math_scripts_ifposts(posts) }}
{% endblock %}

Imports

The Defaults

These imports were already in the built-in template, but I'm hoping to eventually break the whole template up so there's a little more documentation so I'll start with these.

{% import 'index_helper.tmpl' as helper with context %}
{% import 'math_helper.tmpl' as math with context %}
{% import 'comments_helper.tmpl' as comments with context %}
{% import 'pagination_helper.tmpl' as pagination with context %}
{% import 'feeds_translations_helper.tmpl' as feeds_translations with context %}

This will go where <<default-imports>> is in the tangle up above.

Monkey Imports

This is what I'm adding, it will go where <<monkey-imports>> is in the tangle. This assumes that these template-files exist in themes/custom-jinja/templates/.

{# -*- Monkey Templates -*- #}
{% import 'p5_helper.tmpl' as p5 with context %}
{% import 'altair_helper.tmpl' as altair with context %}

Checking If There Are Posts

This is where we call the macro to insert (or not) a tag to pull in the p5 library or the vega libraries. I originally tried putting it next to where the mathjax macro gets called (at the end of the template) but this caused an error saying that the p5 object was undefined. Putting it in the head seems to fix it. These need to be defined in the templates imported in the previous section.

{{ p5.p5_scripts_ifposts(posts) }}
{{ altair.altair_scripts_ifposts(posts)}}

This will be substituted into the <<monkey-posts-check>> section of the tangle.