Skip to content

Integrate Jinja2 Fragments support in Pelican templates #3535

@pauloxnet

Description

@pauloxnet
  • I have searched the issues (including closed ones) and believe that this is not a duplicate.
  • I have searched the documentation and believe that my question is not covered.
  • I am willing to lend a hand to help implement this feature.

Feature Request

I would like to propose integrating Jinja2 Fragments (@sponsfreixes/jinja2-fragments) support in Pelican templates.

This proposal is inspired by the new Template partials feature in Django 6.0, which introduces an efficient pattern for working with template fragments.

Jinja2 Fragments allows rendering individual blocks from Jinja2 templates. This library enables the Template Fragments pattern, allowing developers to render parts of a Jinja2 template independently, greatly improving reusability and maintainability.

Key advantages:

  • Enables rendering of single blocks from templates, following the Locality of Behavior design principle
  • Reduces the need for external files or duplicate code when reusing template blocks
  • Supports dynamic frontends or plugins that require partial updates to the site output

This is an exploratory proposal, but if adopted it could potentially simplify the organization of new themes, drastically reducing the number of files required to compose templates.

Jinja2 Fragments usage example with Pelican

Suppose we want to render just the article header (from base theme simple) as a fragment:

{% block article_header %}
  <h1>{{ article.title }}</h1>
{% endblock %}

Using jinja2-fragments, we can directly render this block:

from jinja2_fragments import render_block
from jinja2 import Environment, FileSystemLoader

env = Environment(loader=FileSystemLoader('path/to/templates'))
template = env.get_template('article.html')
html_header = render_block(template, 'article_header', article=article)

This enables reusing template pieces for AJAX updates, widgets etc. without splitting into extra files.

Concrete theme structure comparison

Current (Pelican simple theme):

  • article.html imports other files:
    • {% include 'header.html' %}
    • {% include 'article_header.html' %}
    • {% include 'footer.html' %}
    • (many small files for each block)

With Fragments:

  • article.html

    • Contains all relevant blocks as {% block ... %} instead of multiple files:

      {% block header %}<header>...</header>{% endblock %}
      {% block article_header %}<h1>{{ article.title }}</h1>{% endblock %}
      {% block footer %}<footer>...</footer>{% endblock %}
  • To render/update just article_header:

    • Use render_block(template, 'article_header', ...) directly
    • No need for an extra file article_header.html

This makes it easier to explore, maintain, and dynamically update portions of pages for plugins or dynamic frontends. Theme creators can group related fragments and reduce clutter. The theme directory can be much flatter and easier to navigate.

If this feature sounds interesting, I'm happy to help with implementation or testing.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions