Week 16 of 2026
Development log of Tad Lispy website
8 items
- Keep the dates in output paths
- Import some sample data for the devlog
- Convert featured projects to pages in works section
- Port an improved rendering context inspector from escco.eu
- Fix the GitLab link
- Edit a devlog entry
- Display devlog under a project description
- Turn TBB logo diff into an actual SVG
Keep the dates in output paths
On by
By default Zola removes the date prefix from the path, so
/content/blog/2025-03-16-tad-co-op-and-manifesto.md becomes
https://tad-lispy.com/blog/tad-co-op-and-manifesto/
I don't think it's good in general, but also it can't work with the
upcoming devlog section. Files there don't have unique slugs except
for dates, so the paths would collide and Zola complains about it.
So now the aformentioned page will be served at
https://tad-lispy.com/blog/2025-03-16-tad-co-op-and-manifesto/
That's better, but I don't want to break existing links (people might riot in the streets should that happen!), so I provided aliases for the old content.
index 1855ae9..e276ece 100644
--- a/config.toml
+++ b/config.toml
@@ -18,12 +18,15 @@ feed_filenames = ["atom.xml", "rss.xml"]
=bottom_footnotes = false
=
=[markdown.highlighting]
-light_theme = "solarized-light"
+light_theme = "solarized-light"
=dark_theme = "solarized-dark"
=
=[link_checker]
=# Seems like some services (e.g. stackoverflow) are blocking connections from CI servers
=external_level = "warn"
=
+[slugify]
+paths_keep_dates = true
+
=[extra]
=# Put all your custom variables hereindex 2e7898c..53dc76b 100644
--- a/content/blog/2015-04-28-npm-install-coffee-from-git/index.md
+++ b/content/blog/2015-04-28-npm-install-coffee-from-git/index.md
@@ -1,5 +1,6 @@
=---
=title: How to Install NPM Packages Written in CoffeeScript from a Git Repo
+aliases: [/blog/npm-install-coffee-from-git]
=---
=
=> 2024 Update: Some links to external content are unfortunately outdated. The content in this post doesn't seem relevant to me anymore, except for archival reasons, so I'm not going to update those broken links.index 8ceabb9..35ab460 100644
--- a/content/blog/2015-07-12-an-idea-for-a-blog/index.md
+++ b/content/blog/2015-07-12-an-idea-for-a-blog/index.md
@@ -1,5 +1,6 @@
=---
=title: An idea for a blog
+aliases: [/blog/an-idea-for-a-blog]
=---
=
=Obviously I have this, or some other idea for a long while. Now it's time to pinpoint it.index e7d1032..48679d6 100644
--- a/content/blog/2015-07-29-react-component-testing/index.md
+++ b/content/blog/2015-07-29-react-component-testing/index.md
@@ -1,5 +1,6 @@
=---
=title: How to Test if a Given Value is a React.js Component
+aliases: [/blog/react-component-testing]
=---
=
=> 2024 Update: Some links to external content are unfortunately outdated. The content in this post doesn't seem relevant to me anymore, except for archival reasons, so I'm not going to update those broken links.index ef18572..5b016a3 100644
--- a/content/blog/2017-06-29-managing-access-to-npm-private-packages/index.md
+++ b/content/blog/2017-06-29-managing-access-to-npm-private-packages/index.md
@@ -1,5 +1,6 @@
=---
=title: Managing access to private NPM repositories
+aliases: [/blog/managing-access-to-npm-private-packages]
=---
=
=Make private package accessible to members of deployment team from command line:index c5bed44..1817e7e 100644
--- a/content/blog/2017-07-20-how-to-setup-ssh-key-limited-to-creating-a-tunnel/index.md
+++ b/content/blog/2017-07-20-how-to-setup-ssh-key-limited-to-creating-a-tunnel/index.md
@@ -1,5 +1,6 @@
=---
=title: How to Setup SSH Key limited to Creating a Tunnel
+aliases: [/blog/how-to-setup-ssh-key-limited-to-creating-a-tunnel]
=---
=
=For a given key I was intending to prevent **any** interaction **except** for starting an SSH tunnel to a particular local port. Turns out that for each key in `~/.ssh/authorized_keys` you can add so called *login options*, by preppending them to the key, like that:index 84dc779..82a88df 100644
--- a/content/blog/2017-07-21-facebook-flow-in-an-alpine-node-docker-container/index.md
+++ b/content/blog/2017-07-21-facebook-flow-in-an-alpine-node-docker-container/index.md
@@ -1,5 +1,6 @@
=---
=title: Running Facebook's Flow in an Alpine Node Container
+aliases: [/blog/facebook-flow-in-an-alpine-node-docker-container]
=---
=
=Create a `Dockerfile` and an `npmrc` templateindex 7272fc7..3b04099 100644
--- a/content/blog/2017-08-04-node-promise-race-timeout/index.md
+++ b/content/blog/2017-08-04-node-promise-race-timeout/index.md
@@ -1,5 +1,6 @@
=---
=title: Using `Promise.race` in Node.js to enforce a timeout
+aliases: [/blog/node-promise-race-timeout]
=---
=
=It is a little bit more tricky than this:index d51c438..8cbc5cd 100644
--- a/content/blog/2017-08-04-promise-then-undefined/index.md
+++ b/content/blog/2017-08-04-promise-then-undefined/index.md
@@ -1,5 +1,6 @@
=---
=title: Passing `undefined` to a JavaScript promise
+aliases: [/blog/promise-then-undefined]
=---
=
=Consider this simple snippet:index 6954bbd..e3a7608 100644
--- a/content/blog/2017-08-04-weird-aws-region-bug/index.md
+++ b/content/blog/2017-08-04-weird-aws-region-bug/index.md
@@ -1,5 +1,6 @@
=---
=title: Weird AWS region bug
+aliases: [/blog/weird-aws-region-bug]
=---
=
=I've been fighting a weird error coming from AWS SDK for Node.js:index 383f82d..029a91c 100644
--- a/content/blog/2019-08-27-shape-up-by-ryan-singer/index.md
+++ b/content/blog/2019-08-27-shape-up-by-ryan-singer/index.md
@@ -1,5 +1,6 @@
=---
=title: Shape Up by Ryan Singer from Basecamp
+aliases: [/blog/shape-up-by-ryan-singer]
=---
=
=> 2024 Update: To large extent [Software Garden](https://software.garden/) was an attempt to implement the ideas from Singer's book, but adapted to working with clients.index 45957f0..72aedd0 100644
--- a/content/blog/2020-01-16-why-is-this-so-terrible/index.md
+++ b/content/blog/2020-01-16-why-is-this-so-terrible/index.md
@@ -1,5 +1,6 @@
=---
=title: Why is `this` so terrible
+aliases: [/blog/why-is-this-so-terrible]
=---
=
=Recently at a meetup in Utrecht I gave a short presentation: *Elements of Functional Programming for React.js Developers*. See [the slides](https://tad-lispy.gitlab.io/why-is-this-so-terrible/).index 9abf1ce..cce52ae 100644
--- a/content/blog/2025-03-16-tad-co-op-and-manifesto/index.md
+++ b/content/blog/2025-03-16-tad-co-op-and-manifesto/index.md
@@ -1,5 +1,6 @@
=---
=title: Tad Co-op
+aliases: [/blog/tad-co-op-and-manifesto]
=---
=
=I wrote the following manifesto as a guide to how and with whom I want to work. It's my personal statement, and I have no right to impose it on anyone else, but if you significantly disagree with any part of it, then we probably shouldn't work together. That is unless you can change my mind first.index 940a5cc..042828f 100644
--- a/content/blog/2025-03-20-guiding-principles-for-a-co-op/index.md
+++ b/content/blog/2025-03-20-guiding-principles-for-a-co-op/index.md
@@ -1,5 +1,6 @@
=---
=title: Guiding principles for a co-op
+aliases: [/blog/guiding-principles-for-a-co-op]
=---
=
=So it really seems like [I am starting a business](/blog/the-plan-for-a-co-op/) with a bunch of beautiful strangers. What a fantastic feeling! The kind and sometimes weird interactions I had with you over the past two weeks inspired me to get to work early every morning. And now that we are going to work together, we need to figure out how to do it.index 21dd128..ac7de8c 100644
--- a/content/blog/2025-03-21-the-plan-for-a-co-op/index.md
+++ b/content/blog/2025-03-21-the-plan-for-a-co-op/index.md
@@ -1,5 +1,6 @@
=---
=title: The plan for a co-op
+aliases: [/blog/the-plan-for-a-co-op]
=---
=
=A hopeful sci-fi story in which I invite you to join a network of smart and kind professionals, who support one another both in their work and personally 🧑‍🚀 We want to set up a co-operative sometime within the next 12 months and conquer the world with our kindness within 10 years. What brings us together and guides our efforts is our shared desire for fairness and freedom, and our concern about dependence on big tech oligopolies 👾 That's why we want to support businesses in a transition to free software and European digital services.index 161aef4..25d0e65 100644
--- a/content/blog/_index.md
+++ b/content/blog/_index.md
@@ -1,5 +1,5 @@
=---
-title: "Tad Lispy Blog"
+title: "Tad Blog"
=sort_by: "date"
=template: "blog.html"
=page_template: "blog-post.html"index cc271e4..be6be4e 100644
--- a/templates/blog.html
+++ b/templates/blog.html
@@ -17,7 +17,7 @@
= <nav aria-label="breadcrumb">
= <ul>
= <li><a href="{{ get_url(path='@/_index.md') }}">Tad Lispy</a></li>
- <li><strong>Blog</strong></li>
+ <li><strong>{{ section.title }}</strong></li>
= </ul>
= </nav>
= {{ section.content | safe }}Import some sample data for the devlog
On by
These are logs excavated from some projects I've been working on over the last 3 weeks, using Devlog Excavator - itself one of the projects (how meta!).
More is to follow, but for now I want to focus on the Zola side of things. Once I have good templates and taxonomy handling, I'll bring more.
new file mode 100644
index 0000000..c2414f3
Binary files /dev/null and b/content/devlog/2026-04-02-tad-better-behavior.md differnew file mode 100644
index 0000000..a3ba4f7
Binary files /dev/null and b/content/devlog/2026-04-07-better-tech-club-website.md differnew file mode 100644
index 0000000..78af26e
Binary files /dev/null and b/content/devlog/2026-04-08-better-tech-club-website.md differnew file mode 100644
index 0000000..9f5d3d5
Binary files /dev/null and b/content/devlog/2026-04-08-tad-better-behavior.md differnew file mode 100644
index 0000000..17c5bff
Binary files /dev/null and b/content/devlog/2026-04-09-better-tech-club-website.md differnew file mode 100644
index 0000000..bb69070
Binary files /dev/null and b/content/devlog/2026-04-10-better-tech-club-website.md differnew file mode 100644
index 0000000..77eddcb
Binary files /dev/null and b/content/devlog/2026-04-11-better-tech-club-website.md differnew file mode 100644
index 0000000..d8c4970
Binary files /dev/null and b/content/devlog/2026-04-11-devlog-excavator.md differnew file mode 100644
index 0000000..c2bd98a
Binary files /dev/null and b/content/devlog/2026-04-13-devlog-excavator.md differnew file mode 100644
index 0000000..b50488b
Binary files /dev/null and b/content/devlog/2026-04-14-better-tech-club-website.md differnew file mode 100644
index 0000000..15947e4
Binary files /dev/null and b/content/devlog/2026-04-14-devlog-excavator.md differnew file mode 100644
index 0000000..9360a72
Binary files /dev/null and b/content/devlog/2026-04-15-devlog-excavator.md differnew file mode 100644
index 0000000..928595e
Binary files /dev/null and b/content/devlog/2026-04-15-tad-better-behavior.md differnew file mode 100644
index 0000000..68868da
Binary files /dev/null and b/content/devlog/2026-04-16-devlog-excavator.md differnew file mode 100644
index 0000000..2db1eb6
Binary files /dev/null and b/content/devlog/2026-04-17-devlog-excavator.md differnew file mode 100644
index 0000000..41e3abd
Binary files /dev/null and b/content/devlog/2026-04-18-devlog-excavator.md differnew file mode 100644
index 0000000..bc3ac1b
--- /dev/null
+++ b/content/devlog/_index.md
@@ -0,0 +1,7 @@
+---
+title: Tad Devlog
+template: blog.html
+---
+
+I write as I work as I write.
+Convert featured projects to pages in works section
On by
I want to add fancy icons, technologies, techniques, disciplines and devlogs. So I need a place to put metadata, like the fornt-matter of a markdown document.
index 3201b16..2efbc94 100644
--- a/content/works/_index.md
+++ b/content/works/_index.md
@@ -1,6 +1,6 @@
=---
=title: "Tad Works"
-sort_by: "date"
+sort_by: "weight"
=template: "works.html"
=description: "Featured works of Tad Lispy"
=---
@@ -46,84 +46,6 @@ Here is what some of my clients have to say about me:
=> <cite>Neyts Zupan, Open Source geek & founder, Niteo</cite>
={% end %}
=
-Most of my work revolves around software development - custom work for clients, free software projects or training. Except for proprietary client projects, I publish most of it on [Codeberg](https://codeberg.org/tad-lispy), [GitLab](https://gitlab.com/dashboard/projects/member) or [GitHub](https://github.com/tad-lispy?tab=repositories). Below are selected examples of my work.
-
-# Lead Studio
-
- - data engineering
- - business process automation
- - web extensions
- - user experience
- - internal tooling
- - LinkedIn Sales Navigator
- - Google Cloud
- - Elm programming
- - JavaScript programming
-
-In 2021, we promised our client, Saleslift Studio, to deliver a working software solution to improve prospecting performance within a fixed time and at a fixed price. In just 6 weeks (a single development cycle), we provided them with a useful solution - Lead Studio. Further incremental development enabled them to improve a number of key performance indicators. Thanks to their partnership with Software Garden, prospecting specialists at Saleslift Studio are now able to enrich leads 20⨉ faster than before.
-
-[Read our case study](https://software.garden/lead-studio.html)
-
-
-# Agile Plan Exporter
-
- - agile software development
- - Rust programming
- - collaboration
- - free / open source software
- - markdown processing
- - iCalendar
-
-At Software Garden we attempted to create a work environment where we can be efficient and happy at the same time. Part of it was agile planning - a simple and collaborative process where everyone had a chance to catch up with all the latest developments and choose the priorities they will work on. To facilitate it, we created several tools, including this one. It exports our schedule from a Markdown document, to iCalendar format. Markdown is a flexible and lightweight plain text format, ideal for taking notes while planning, while iCalendar is the industry standard for calendaring data. This enabled every team member to synchronize their personal calendars with our shared plan!
-
-The tool might still be useful for you. [Learn how you can use it too](https://gitlab.com/software-garden/markdown-to-icalendar-export).
-
-
-# Elm Springs
-
- - Elm programming
- - physics simulation
- - animations
- - free / open source software
-
-An Elm package implementing a rough model of a physical mass attached to a spring, as described in physics by Hooke's law. Good for making smooth and organic looking animations or modeling oscillating values (for example emotions). High physical accuracy is not a priority - performance and API simplicity is more important.
-
-[See the package](https://package.elm-lang.org/packages/tad-lispy/springs/latest/).
+# Featured Projects
=
-
-# Ethical Software Garden
-
- - collaboration
- - digital ethics
- - CMS
- - GitLab API
- - free / open source software
- - GraphQL
-
-
-After taking part in the Offsite Sustainability meetup hosted by [Railslove](https://railslove.com/) we realized that resources about digital ethics are very scattered. This website uses our GitLab GraphQL API and Elm Pages static site generator to produce a catalogue of articles, videos, websites etc. about digital ethics. The idea is to use GitLab issues, comments, reactions (up and down votes) and moderation to generate web content. The webpage is re-generated daily in a CI/CD pipeline for fast loading, but the content is also loaded live.
-
-[See the catalogue](https://ethical.software.garden/)
-
-
-# Elm Tree Workshop
-
- - teaching
- - Elm programming
- - web development
-
-A workshop that will give you a glimpse into the way software is created. It is intended for people with no prior experience in programming and doesn’t require any technical knowledge. Everybody is welcome! During this 5 days workshop (3 hours each day) you will learn to solve problems using a functional programming language. Together, we will build a program that simulates growth of a tree. In 2019 the workshop was presented to students of Utrecht University.
-
-[Visit the website](https://elm-tree.software.garden/)
-
-
-# Word Snake
-
- - game development
- - web development
- - education technology
- - Elm programming
-
-Think fast - guess a password, collect letters and save the snake from a fire trap! In this simple word puzzle game you control a snake while guessing a password. Challenges are designed to let players learn various facts about the world or improve their arithmetic and logical thinking while playing. It's extra fun to play in a group on a phone or a tablet - one player controls the snake while others help to guess the password. It can be a nice family exercise that brings people together.
-
-[Play the game](https://word-snake.software.garden/ "Play Word Snake in your browser")
+Most of my work revolves around software development - custom work for clients, free software projects or training. Except for proprietary client projects, I publish most of it on [Codeberg](https://codeberg.org/tad-lispy), [GitLab](https://gitlab.com/dashboard/projects/member) or [GitHub](https://github.com/tad-lispy?tab=repositories). Below are selected examples of my work.new file mode 100644
index 0000000..cb5136c
--- /dev/null
+++ b/content/works/agile-planner/index.md
@@ -0,0 +1,18 @@
+---
+title: Agile Planner
+weight: 3
+---
+
+
+# Agile Plan Exporter
+
+ - agile software development
+ - Rust programming
+ - collaboration
+ - free / open source software
+ - markdown processing
+ - iCalendar
+
+At Software Garden we attempted to create a work environment where we can be efficient and happy at the same time. Part of it was agile planning - a simple and collaborative process where everyone had a chance to catch up with all the latest developments and choose the priorities they will work on. To facilitate it, we created several tools, including this one. It exports our schedule from a Markdown document, to iCalendar format. Markdown is a flexible and lightweight plain text format, ideal for taking notes while planning, while iCalendar is the industry standard for calendaring data. This enabled every team member to synchronize their personal calendars with our shared plan!
+
+The tool might still be useful for you. [Learn how you can use it too](https://gitlab.com/software-garden/markdown-to-icalendar-export).new file mode 100644
index 0000000..154cb72
--- /dev/null
+++ b/content/works/ehtical-software-garden/elm-tree-worksho/index.html
@@ -0,0 +1,14 @@
+---
+title: Elm Tree Workshop
+weight: 2
+---
+
+# Elm Tree Workshop
+
+ - teaching
+ - Elm programming
+ - web development
+
+A workshop that will give you a glimpse into the way software is created. It is intended for people with no prior experience in programming and doesn’t require any technical knowledge. Everybody is welcome! During this 5 days workshop (3 hours each day) you will learn to solve problems using a functional programming language. Together, we will build a program that simulates growth of a tree. In 2019 the workshop was presented to students of Utrecht University.
+
+[Visit the website](https://elm-tree.software.garden/)new file mode 100644
index 0000000..8812b5b
--- /dev/null
+++ b/content/works/ehtical-software-garden/index.md
@@ -0,0 +1,18 @@
+---
+title: Ethical Software Garden
+weight: 3
+---
+
+# Ethical Software Garden
+
+ - collaboration
+ - digital ethics
+ - CMS
+ - GitLab API
+ - free / open source software
+ - GraphQL
+
+
+After taking part in the Offsite Sustainability meetup hosted by [Railslove](https://railslove.com/) we realized that resources about digital ethics are very scattered. This website uses our GitLab GraphQL API and Elm Pages static site generator to produce a catalogue of articles, videos, websites etc. about digital ethics. The idea is to use GitLab issues, comments, reactions (up and down votes) and moderation to generate web content. The webpage is re-generated daily in a CI/CD pipeline for fast loading, but the content is also loaded live.
+
+[See the catalogue](https://ethical.software.garden/)new file mode 100644
index 0000000..bc59274
--- /dev/null
+++ b/content/works/elm-springs/index.md
@@ -0,0 +1,16 @@
+---
+title: Elm Springs
+weight: 2
+---
+
+# Elm Springs
+
+ - Elm programming
+ - physics simulation
+ - animations
+ - free / open source software
+
+An Elm package implementing a rough model of a physical mass attached to a spring, as described in physics by Hooke's law. Good for making smooth and organic looking animations or modeling oscillating values (for example emotions). High physical accuracy is not a priority - performance and API simplicity is more important.
+
+[See the package](https://package.elm-lang.org/packages/tad-lispy/springs/latest/).
+new file mode 100644
index 0000000..154cb72
--- /dev/null
+++ b/content/works/elm-tree-worksho/index.md
@@ -0,0 +1,14 @@
+---
+title: Elm Tree Workshop
+weight: 2
+---
+
+# Elm Tree Workshop
+
+ - teaching
+ - Elm programming
+ - web development
+
+A workshop that will give you a glimpse into the way software is created. It is intended for people with no prior experience in programming and doesn’t require any technical knowledge. Everybody is welcome! During this 5 days workshop (3 hours each day) you will learn to solve problems using a functional programming language. Together, we will build a program that simulates growth of a tree. In 2019 the workshop was presented to students of Utrecht University.
+
+[Visit the website](https://elm-tree.software.garden/)new file mode 100644
index 0000000..b7a52b8
--- /dev/null
+++ b/content/works/lead-studio/index.md
@@ -0,0 +1,23 @@
+---
+title: Lead Studio
+weight: 1
+---
+
+# Lead Studio
+
+ - data engineering
+ - business process automation
+ - web extensions
+ - user experience
+ - internal tooling
+ - LinkedIn Sales Navigator
+ - Google Cloud
+ - Elm programming
+ - JavaScript programming
+
+In 2021, we promised our client, Saleslift Studio, to deliver a working software solution to improve prospecting performance within a fixed time and at a fixed price. In just 6 weeks (a single development cycle), we provided them with a useful solution - Lead Studio. Further incremental development enabled them to improve a number of key performance indicators. Thanks to their partnership with Software Garden, prospecting specialists at Saleslift Studio are now able to enrich leads 20⨉ faster than before.
+
+[Read our case study](https://software.garden/lead-studio.html)
+
+
+new file mode 100644
index 0000000..f55c819
--- /dev/null
+++ b/content/works/tad-better-behavior/index.md
@@ -0,0 +1,9 @@
+---
+title: Tad Better Behavior
+weight: 0
+---
+
+# TBB: Tad Better Behavior
+
+A <abbrev title="Behhavior Driven Development">BDD</abbrev> tool that works well on Unix.
+new file mode 100644
index 0000000..431d6d1
--- /dev/null
+++ b/content/works/word-snake/index.md
@@ -0,0 +1,15 @@
+---
+title: Word Snake
+weight: 2
+---
+
+# Word Snake
+
+ - game development
+ - web development
+ - education technology
+ - Elm programming
+
+Think fast - guess a password, collect letters and save the snake from a fire trap! In this simple word puzzle game you control a snake while guessing a password. Challenges are designed to let players learn various facts about the world or improve their arithmetic and logical thinking while playing. It's extra fun to play in a group on a phone or a tablet - one player controls the snake while others help to guess the password. It can be a nice family exercise that brings people together.
+
+[Play the game](https://word-snake.software.garden/ "Play Word Snake in your browser")index 335ae7d..d5d8c82 100644
--- a/sass/style.scss
+++ b/sass/style.scss
@@ -42,9 +42,13 @@ html.home {
= }
= }
= }
+}
=
-
-
+html.works-index {
+ h1 {
+ font-size: 1rem;
+ border-bottom: solid 2px currentColor;
+ }
=}
=
=nav.main-nav {index dcead87..ec1694f 100644
--- a/templates/works.html
+++ b/templates/works.html
@@ -24,6 +24,15 @@
=
=<main>
= {{ section.content | safe }}
+
+ <section id="featured-projects">
+ {% for project in section.pages %}
+ <article>
+ <h2>{{ project.title }}</h2>
+ <p><a href="{{ project.path }}">Read more about {{ project.title }}</a> </p>
+ </article>
+ {% endfor %}
+ </section>
=</main>
=
={% include "includes/footer.html" %}Port an improved rendering context inspector from escco.eu
On by
Key features:
-
Always visible on development builds
No more tweaking the template comment to toggle it. No chance to accidentally push it to live deployment.
-
Uses modern
dialogAPIRich interaction model without JS. Doesn't mess with the page layout.
-
Slick floating action button to open the modal
-
Keyboard shortcuts to open and close it
alt+shift+i to open the first time. space to toggle (once opened) esc to close
index cbbde5c..4e92e3d 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -37,16 +37,6 @@
= {% block content %}
= {% endblock content %}
=
- {# Fix the closing comment bracket on this line to dump available data # }
- {%- if config.mode == "serve" %}
- <article>
- <header>Template context</header>
- <pre><code>
- {{- __tera_context -}}
- </code></pre>
- </article>
- {% endif -%}
- {# #}
-
+ {% include "shortcodes/debug.html" %}
= </body>
=</html>new file mode 100644
index 0000000..4414dbd
--- /dev/null
+++ b/templates/shortcodes/debug.html
@@ -0,0 +1,35 @@
+{%- if config.mode == "serve" %}
+<dialog id="rendering-context-dialog" modal>
+ <article style="padding-bottom: 0">
+ <header style="margin-bottom: 1rem">
+ <button
+ aria-label="Close"
+ class="close outline"
+ command="close"
+ commandfor="rendering-context-dialog"
+ ></button>
+ Rendering context
+ </header>
+ <pre style="max-height: 60vh; overflow: scroll">{{ __tera_context | escape | safe }}</pre>
+ </article>
+</dialog>
+
+<button
+ command="show-modal"
+ commandfor="rendering-context-dialog"
+ accesskey="i"
+ title="Open rendering context dialog"
+ class="outline"
+ style="
+ position: fixed;
+ bottom: 2rem;
+ left: 2rem;
+ width: 2rem;
+ height: 2rem;
+ padding: 0;
+ margin: 0;
+ border-radius: 50%;
+ font-weight: 900;
+ "
+>{}</button>
+{% endif -%}Fix the GitLab link
On by
I've accidentally used a link to my profile that only works for me when I'm logged in 🤦
index 2efbc94..e3a354d 100644
--- a/content/works/_index.md
+++ b/content/works/_index.md
@@ -48,4 +48,4 @@ Here is what some of my clients have to say about me:
=
=# Featured Projects
=
-Most of my work revolves around software development - custom work for clients, free software projects or training. Except for proprietary client projects, I publish most of it on [Codeberg](https://codeberg.org/tad-lispy), [GitLab](https://gitlab.com/dashboard/projects/member) or [GitHub](https://github.com/tad-lispy?tab=repositories). Below are selected examples of my work.
+Most of my work revolves around software development - custom work for clients, free software projects or training. Except for proprietary client projects, I publish most of it on [Codeberg](https://codeberg.org/tad-lispy), [GitLab](https://gitlab.com/tad-lispy "Tad Lispy on GitLab") or [GitHub](https://github.com/tad-lispy?tab=repositories). Below are selected examples of my work.Edit a devlog entry
On by
Mostly I want to see what's the experience of editing the entry emitted by Devlog Excavator. It's fine, but I see some operations that could have been already performed by Excavator:
-
If the file is new (and not binary), then emit the file contents, not the diff.
-
Group all the new binary files and emit a list of them.
-
Modified binary files should also form a list.
-
Modified files don't need the
index <hex>..<hex>line at the beginning. It's not useful and can be distracting. -
All operations should be explained, like:
Modified
index.html:Deleted
dont-touch-this.exe.New file at
fonts/caveat/caveat.css:Renamed
big.txttotad.txt: (colon only if contents modified - then also diff).Modified binary files: (take singular and plural into account)
Deleted binary files:
New binary files:
-
The order of operations should be as illustrated above.
So basically Excavator needs to be much smarter about processing patch.
index 17c5bff..1d68057 100644
Binary files a/content/devlog/2026-04-09-better-tech-club-website.md and b/content/devlog/2026-04-09-better-tech-club-website.md differDisplay devlog under a project description
On by
I introduced the project.html template, used by all pages in the
works section. The template queries pages in the devlog section,
(i.e. devlog entries). Only the entries that include the given project
name in extra.projects are rendered.
Many project don't have a devlog yet. Others are confidential client
projects and will never have a public devlog. In those cases the
"Devlog" section heading is hidden. It's not easy with Zola, but quite
simple using modern CSS with :not and :has pseudo-classes.
Because entries are sometimes long, I decided to make the date heading of each entry a sticky element.
Speaking of headings, devlog entry documents contain heading hierarchy
starting at h1. When embeded in a project page, the heading have to be
de-moted by 3 levels, so that each commit subject is in an h4
element (following project name (h1), Devlog section heading (h2) and
the date heading (h3)). For this I brought the demote-headings macro,
that I've developed last year for similar purpose in the Escco website.
index e3a354d..1cb38af 100644
--- a/content/works/_index.md
+++ b/content/works/_index.md
@@ -2,6 +2,7 @@
=title: "Tad Works"
=sort_by: "weight"
=template: "works.html"
+page_template: "project.html"
=description: "Featured works of Tad Lispy"
=---
=index d5d8c82..e5f6040 100644
--- a/sass/style.scss
+++ b/sass/style.scss
@@ -51,6 +51,26 @@ html.works-index {
= }
=}
=
+html.project {
+ #devlog-heading {
+ color: var(--muted-color);
+ }
+
+ #devlog-heading:not(:has(+ .devlog-entry)) {
+ display: none;
+ }
+
+ .devlog-entry {
+ h3 {
+ font-size: 1rem;
+ border-bottom: solid 2px currentColor;
+ position: sticky;
+ top: 0;
+ background: var(--background-color);
+ }
+ }
+}
+
=nav.main-nav {
= justify-content: start;
=new file mode 100644
index 0000000..8184f40
--- /dev/null
+++ b/templates/components.html
@@ -0,0 +1,16 @@
+{% macro demote_headings (content, levels=1) %}
+ {% set_global demoted = content %}
+ {% for i in range(start=1, end=6) %}
+ {% set n = 6 - i %}
+ {% set m = n + levels %}
+ {% set from_opening = "<h" ~ n %}
+ {% set into_opening = "<h" ~ m %}
+ {% set from_closing = "</h" ~ n %}
+ {% set into_closing = "</h" ~ m %}
+ {% set_global demoted = demoted
+ | replace (from=from_opening, to=into_opening)
+ | replace (from=from_closing, to=into_closing)
+ %}
+ {% endfor %}
+ {{ demoted | safe }}
+{% endmacro table_of_contents %}new file mode 100644
index 0000000..d80af22
--- /dev/null
+++ b/templates/project.html
@@ -0,0 +1,45 @@
+{% extends "base.html" %}
+
+{% import "components.html" as components %}
+
+{% block variables %}
+{{ super() }}
+{% set page_class = "page project" %}
+{% set title = page.title | markdown(inline=true) | striptags %}
+{% set description = page.summary | default(value="A project by Tad Lispy.") | striptags %}
+{% set devlog = get_section(path="devlog/_index.md") %}
+{% endblock variables %}
+
+{% block content %}
+<header>
+ <nav aria-label="breadcrumb">
+ <ul>
+ <li><a href="{{ get_url(path='@/_index.md') }}">Tad Lispy</a></li>
+ <li><a href="{{ get_url(path='@/works/_index.md') }}">Works</a></li>
+ <li><strong>{{ page.title | markdown(inline=true) | safe }}</strong></li>
+ </ul>
+ </nav>
+</header>
+
+<main>
+
+ {{ page.content | safe }}
+
+ {# NOTE: If there is no devlog, then the heading will be hidden using CSS #}
+ <h2 id="devlog-heading">Devlog</h2>
+
+ {% for entry in devlog.pages %}
+ {% if entry.extra.projects is containing(page.title) %}
+ <section class="devlog-entry">
+ <h3><time datetime="{{ entry.date }}">{{ entry.date | date(format="%A, %F")}}</time></h3>
+
+ {{- components::demote_headings (content=entry.content, levels=3)
+ | safe
+ -}}
+ </section>
+ {% endif %}
+ {% endfor %}
+</main>
+
+{% include "includes/footer.html" %}
+{% endblock content %}Turn TBB logo diff into an actual SVG
On by
So instead of reading a diff with all additions, readers can see the graphic.
Maybe images and other multimedia should be excavated along the markdown entries? Modified images should be presented side by side.
index 9f5d3d5..12ee7eb 100644
Binary files a/content/devlog/2026-04-08-tad-better-behavior.md and b/content/devlog/2026-04-08-tad-better-behavior.md differ