From a4e35942fee745e64db5d0099ba2582e0fb4417e Mon Sep 17 00:00:00 2001 From: Dennis Fink Date: Thu, 18 Jun 2026 17:57:51 +0200 Subject: Build the first usable version of the blog This adds the Lektor project structure, models, templates, styling, feeds, categories, tags, archives, custom Markdown heading handling, and the initial content needed to make the blog usable. --- templates/.djlintrc | 14 +++ templates/about.html | 11 ++ templates/base.html | 167 +++++++++++++++++++++++++++++ templates/blog-month-index.html | 54 ++++++++++ templates/blog-post.html | 31 ++++++ templates/blog-year-index.html | 54 ++++++++++ templates/blog.html | 15 +++ templates/categories.html | 53 ++++++++++ templates/category.html | 51 +++++++++ templates/index.html | 15 +++ templates/macros/blog.html | 100 ++++++++++++++++++ templates/macros/pagination.html | 221 +++++++++++++++++++++++++++++++++++++++ templates/page.html | 3 + templates/tag.html | 59 +++++++++++ 14 files changed, 848 insertions(+) create mode 100644 templates/.djlintrc create mode 100644 templates/about.html create mode 100644 templates/base.html create mode 100644 templates/blog-month-index.html create mode 100644 templates/blog-post.html create mode 100644 templates/blog-year-index.html create mode 100644 templates/blog.html create mode 100644 templates/categories.html create mode 100644 templates/category.html create mode 100644 templates/index.html create mode 100644 templates/macros/blog.html create mode 100644 templates/macros/pagination.html create mode 100644 templates/page.html create mode 100644 templates/tag.html (limited to 'templates') diff --git a/templates/.djlintrc b/templates/.djlintrc new file mode 100644 index 0000000..5882faa --- /dev/null +++ b/templates/.djlintrc @@ -0,0 +1,14 @@ +{ +"blank_line_before_tag": "macro", +"blank_line_after_tag": "endmacro,extends,import,from", +"profile": "jinja", +"format_css": true, +"css": { +"indent_size": 2 +}, +"format_js": true, +"js": { +"indent_size": 2 +}, +"indent": "2" +} diff --git a/templates/about.html b/templates/about.html new file mode 100644 index 0000000..55a0778 --- /dev/null +++ b/templates/about.html @@ -0,0 +1,11 @@ +{% extends "base.html" %} + +{% block meta %} + {{ super() }} + + + +{% endblock %} +{% block content %} +
{{ this.body }}
+{% endblock %} diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..1000014 --- /dev/null +++ b/templates/base.html @@ -0,0 +1,167 @@ + + + + {% block head %} + {% block meta %} + + + + + + + + + + + + + + + {% endblock meta %} + {% block styles %} + + + + {% endblock styles %} + {% block meta_links %} + + + + + {% endblock meta_links %} + + {% block meta_title %} + {%- if (this.title or title) -%}{{ (this.title or title) | safe }} — + {% endif -%} + {{ bag("blog.name") }} — dennisfink.me + {% endblock meta_title %} + + {% endblock head %} + + + {% block body %} + +
+ {% block site_header %} +
+
+

+ {{ bag("blog.name") }} +

+

{{ bag("blog.tagline") }}

+
+ + + +
+
+ +
+ Color theme + + + +
+
+ {% endblock site_header %} +
+
+ {% block content required %} + {% endblock content %} +
+ + {% endblock body %} + + diff --git a/templates/blog-month-index.html b/templates/blog-month-index.html new file mode 100644 index 0000000..d114628 --- /dev/null +++ b/templates/blog-month-index.html @@ -0,0 +1,54 @@ +{% extends "base.html" %} + +{% from "macros/pagination.html" import render_month_archive_navigation %} + +{% block meta %} + {{ super() }} + +{% endblock %} +{% block styles %} + {{ super() }} + +{% endblock %} +{% set title = "Monthly archive: " + this.date | dateformat('MMMM y') %} +{% block content %} + {% set post_count = this.children.count() %} +
+
+
+

Monthly archive: {{ this.date | dateformat("MMMM y") }}

+

+ ({{ post_count }} + {% if post_count > 1 %} + posts) + {% else %} + post) + {% endif %} +

+
+
+ + + + + + + + + {% for post in this.children.order_by('-publication_date') %} + + + + + {% endfor %} + +
DateTitle
+ + + {{ post.title }} +
+ {{ render_month_archive_navigation(this) }} +
+{% endblock %} diff --git a/templates/blog-post.html b/templates/blog-post.html new file mode 100644 index 0000000..6ffb600 --- /dev/null +++ b/templates/blog-post.html @@ -0,0 +1,31 @@ +{% extends "base.html" %} + +{% from "macros/blog.html" import render_blog_post %} + +{% block meta %} + {{ super() }} + + + {% if this.publication_date %} + + {% endif %} + {% if this.updated_date %} + + {% endif %} + {% if this.category %} + {% set category = site.get("/categories/" + this.category) %} + + {% endif %} + {% for t in this.tags %} + + {% endfor %} +{% endblock %} +{% block styles %} + {{ super() }} + +{% endblock %} +{% block content %}{{ render_blog_post(this) }}{% endblock %} diff --git a/templates/blog-year-index.html b/templates/blog-year-index.html new file mode 100644 index 0000000..138cc86 --- /dev/null +++ b/templates/blog-year-index.html @@ -0,0 +1,54 @@ +{% extends "base.html" %} + +{% from "macros/pagination.html" import render_year_archive_navigation %} + +{% block meta %} + {{ super() }} + +{% endblock %} +{% block styles %} + {{ super() }} + +{% endblock %} +{% set title = "Yearly archive: " + this.key %} +{% block content %} + {% set post_count = this.children.count() %} +
+
+
+

Yearly archive: {{ this.key }}

+

+ ({{ post_count }} + {% if post_count > 1 %} + posts) + {% else %} + post) + {% endif %} +

+
+
+ + + + + + + + + {% for post in this.children.order_by('-publication_date') %} + + + + + {% endfor %} + +
DateTitle
+ + + {{ post.title }} +
+ {{ render_year_archive_navigation(this) }} +
+{% endblock %} diff --git a/templates/blog.html b/templates/blog.html new file mode 100644 index 0000000..0ee96c7 --- /dev/null +++ b/templates/blog.html @@ -0,0 +1,15 @@ +{% extends "base.html" %} + +{% from "macros/blog.html" import render_blog_index %} + +{% block meta %} + {{ super() }} + +{% endblock %} +{% block styles %} + {{ super() }} + +{% endblock %} +{% block content %}{{ render_blog_index(this.pagination) }}{% endblock %} diff --git a/templates/categories.html b/templates/categories.html new file mode 100644 index 0000000..4dbdf1a --- /dev/null +++ b/templates/categories.html @@ -0,0 +1,53 @@ +{% extends "base.html" %} + +{% block meta %} + {{ super() }} + +{% endblock %} +{% block styles %} + {{ super() }} + +{% endblock %} +{% set title = "Categories" %} +{% block content %} +
+
+

Categories

+
+ +
+{% endblock %} diff --git a/templates/category.html b/templates/category.html new file mode 100644 index 0000000..9d6b35d --- /dev/null +++ b/templates/category.html @@ -0,0 +1,51 @@ +{% extends "base.html" %} + +{% block meta %} + {{ super() }} + +{% endblock %} +{% block styles %} + {{ super() }} + +{% endblock %} +{% set title = "Category " + this.name %} +{% block content %} + {% set post_count = this.children.count() %} +
+
+
+

Category: {{ this.name }}

+

+ ({{ post_count }} + {% if post_count > 1 %} + posts) + {% else %} + post) + {% endif %} +

+
+
+ + + + + + + + + {% for post in this.children.order_by('-publication_date') %} + + + + + {% endfor %} + +
DateTitle
+ + + {{ post.title }} +
+
+{% endblock %} diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..0ee96c7 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,15 @@ +{% extends "base.html" %} + +{% from "macros/blog.html" import render_blog_index %} + +{% block meta %} + {{ super() }} + +{% endblock %} +{% block styles %} + {{ super() }} + +{% endblock %} +{% block content %}{{ render_blog_index(this.pagination) }}{% endblock %} diff --git a/templates/macros/blog.html b/templates/macros/blog.html new file mode 100644 index 0000000..b4caafe --- /dev/null +++ b/templates/macros/blog.html @@ -0,0 +1,100 @@ +{% from "macros/pagination.html" import render_pagination %} + +{% macro render_toc(toc, maxdepth=2) %} + +{% endmacro %} + +{% macro render_blog_post(post, show_toc=True) %} +
+
+
+

+ {{ post.title }} +

+
+ {% if post.publication_date %} +
+
Posted:
+
+ + + +
+
+ {% else %} + + {% endif %} + {% if post.updated_date and post.publication_date and (post.updated_date > post.publication_date) %} +
+
Last updated:
+
+ +
+
+ {% endif %} + {% if post.category %} +
+
Category:
+
+ {% set category = site.get('/categories/'+post.category) %} + {{ category.name }} +
+
+ {% endif %} +
+
+ {% if show_toc and post.render_toc %} + {% set toc = post.body.toc|default([]) %} + {{ render_toc(toc) }} + {% endif %} +
+ {{ post.body }} + {% if post.tags %} + + {% endif %} +
+{% endmacro %} + +{% macro render_blog_index(pagination) %} + {% for post in pagination.items %} + {{ render_blog_post(post, False) }} + {% if not loop.last %} +
+ {% endif %} + {% endfor %} + {% if pagination.pages > 1 %} + + {% endif %} +{% endmacro %} diff --git a/templates/macros/pagination.html b/templates/macros/pagination.html new file mode 100644 index 0000000..adb1b5c --- /dev/null +++ b/templates/macros/pagination.html @@ -0,0 +1,221 @@ +{% macro render_pagination(pagination, pagination_window=2) %} + {% set current = pagination.page %} + {% set total = pagination.pages %} + {% set window_start = [current - pagination_window, 1] | max %} + {% set window_end = [current + pagination_window, total] | min %} + +{% endmacro %} + +{% macro render_year_archive_navigation( + current_year_page, + archive_window=2 + ) %} + {% set current_year = current_year_page.year %} + {% set first_year_page = current_year_page.first_year_page %} + {% set last_year_page = current_year_page.last_year_page %} + {% set previous_year_page = current_year_page.previous_year_page %} + {% set next_year_page = current_year_page.next_year_page %} + {% set first_year = first_year_page.year %} + {% set last_year = last_year_page.year %} + {% set window_start = [current_year - archive_window, first_year] | max %} + {% set window_end = [current_year + archive_window, last_year] | min %} + +{% endmacro %} + +{% macro render_month_archive_navigation( + current_month_page, + archive_window=2 + ) %} + {% set year_pages = index_pages('year') | sort(attribute='year') %} + {% set ns = namespace( + month_pages=[], + current_position=none + ) %} + {% for year_page in year_pages %} + {% set ns.month_pages = ns.month_pages + (year_page.subindexes | sort(attribute='month')) %} + {% endfor %} + {% for month_page in ns.month_pages %} + {% if month_page.year == current_month_page.year + and month_page.month == current_month_page.month %} + {% set ns.current_position = loop.index0 %} + {% endif %} + {% endfor %} + {% set total = ns.month_pages | length %} + {% set current_position = ns.current_position %} + {% set window_start = [current_position - archive_window, 0] | max %} + {% set window_end = [current_position + archive_window, total - 1] | min %} + {% set first_month_page = ns.month_pages[0] %} + {% set last_month_page = ns.month_pages[total - 1] %} + {% set previous_month_page = none %} + {% set next_month_page = none %} + {% if current_position > 0 %} + {% set previous_month_page = ns.month_pages[current_position - 1] %} + {% endif %} + {% if current_position < total - 1 %} + {% set next_month_page = ns.month_pages[current_position + 1] %} + {% endif %} + +{% endmacro %} diff --git a/templates/page.html b/templates/page.html new file mode 100644 index 0000000..dd20955 --- /dev/null +++ b/templates/page.html @@ -0,0 +1,3 @@ +{% extends "base.html" %} + +{% block content %}
{{ this.body }}
{% endblock %} diff --git a/templates/tag.html b/templates/tag.html new file mode 100644 index 0000000..b433616 --- /dev/null +++ b/templates/tag.html @@ -0,0 +1,59 @@ +{% extends "base.html" %} + +{% block meta %} + {{ super() }} + +{% endblock %} +{% block styles %} + {{ super() }} + +{% endblock %} +{% set title = "Tag " + this.tag %} +{% block content %} + {% set post_count = this.items.count() %} +
+
+
+

Tag: {{ this.tag }}

+

+ ({{ post_count }} + {% if post_count > 1 %} + posts) + {% else %} + post) + {% endif %} +

+
+
+ + + + + + + + + {% for post in this.items %} + + + + + {% else %} + + + + {% endfor %} + +
DateTitle
+ {% if post.publication_date %} + + {% endif %} + + {{ post.title }} +
+ No posts for this tag. +
+
+{% endblock %} -- cgit v1.3.1