Yesterday, when I started conceptualising my first post, (which soon became two posts, and now probably three? š), I thought that I might get away with not starting a blog with a post called āHello, world!ā. Turns out, I couldnāt! š
In this post I am going to share with you, why I set up a new blog, and how I set it up.
The reason why I didnāt want to post a āHello, world!ā, was that I thought I had already done it so many times. The funny part is: I never did. Didnāt do it on my old blog, didnāt do it on Facebook, didnāt do it on Instagram, for sure didnāt do it on Twitter (didnāt check, though).
But from all these places, this is actually the one where it fits the best!
Titles
I had three other titles in mind. Two of them were:
I blog, again⦠therefore I am, again.
ā¦which would have been a nod to my very first blog post, back on 15 May 2018. By any chance: are you a recurring reader from my old blog? Then please, let me know Iād love to find out how many of you are still around! The second title I had in mind:
Oh, Blogosphere, Iām home!
which of course is a allusion to The Flintstones, and something that has burned itself into my brain. To this day I sometimes enter my home and just randomly say: āWilma, ich bin wieder zuhause!ā1
The third one will be used in one of the next posts, so Iāll keep that to myself for now š¼
Iām Finally Blogging Again
For all of my recurring readers, or friends who came over from Facebook or Instagram, this will be the place where all my future blogging will take place. You know what to expect: it will be basically the same olā from those sites, and from my old WordPress.com blog. And if you did come from the old blog: please drop me a line. Iām genuinely interested in hearing from you people, who are still following the old site. This blog will be in English again. Sorry to all of you German folks for whom this might be an issue; but I do believe in the internet being a means of global communication, and English just is the lingua franca of the world. I might think about going multi-lingual at some point. The software I am using should support it, but that is something for the future. I have several other things I want to achieve first, and even if I do go multi-lingual, I might be more interested in writing in some of my other languages that I am still learning⦠so chances are slim. Still: if the demand were high I might consider it.
For all of you who are new here: Welcome! Help yourself to some snacks and tea or coffe, take a seat and enjoy your stay! The next post will be a proper introduction to myself, the blogger. This one, however, is an introduction of the blog!
That is why I finally went with āHello, world!ā as a title: In programming, a āHello world!ā-program is the tiniest possible program: the first thing you write in a new language or environment to prove that the system works. A test run, so to speak. When everything goes well, you get the text āHello, world!ā printed somewhere (screen, printer, remote client, etc.)
And I now have a new blog, running a system Iāve never used before, using a process Iāve just finalised setting up. If you can read this, then everything worked:
Hello, world!
Issues with WordPress.com
One of the reasons I wasnāt blogging on WordPress.com anymore, was that I wasnāt too happy with the software and the constraints around it.
First, it forced me to work from the browser (which always felt dangerous). If thereās no robust āsave in-betweenā (or if autosave fails), you will lose things: accidental closing/reloading tabs, a browser crash, a machine crash⦠Browsers are for displaying stuff, not to work in them.
Second, I was limited to what the host allowed (or refused to allow) me to do. This included both, organisation and functionality of the blog, (plugins I couldnāt use, features I couldnāt disable), as well as design questions. I did hack my way around in the end, integrating three different blogs into one. But those kinds of limitations always meant compromises (like not having different content type, different views on content, multiple feeds, etc.).
Third,
it simply didnāt fit my working style.
I live in the terminal,
my main application is the
Vim editor,
as a developer I also know my way around
git,
and ever since
Markdown
became a thing,
I even ditched most of my
.odt files
for it.
Writing text in a form field of a browser,
then switching to a JavaScript-heavy HTML editor mode,
just to better control the outputā¦
thatās the opposite of fun.
Because switching to the HTML-mode meant
I had to write everything in HTML
(cumbersome),
as switching back and forth
often broke the formatting.
It works for people with lower requirements,
who donāt know HTML,
but it was a hassle for me,
someone who wats to control alt attributes on img tags,
or title attributes on links,
or use abbr-tags and definition lists,
which the
WYSIWYG editor
simply didnāt provide.
Last but not least, and this is something I started valuing more only in the last years, WordPress.com is a silo. Once I hit āpublishā, my text is āgoneā in the sense that it lives inside the platfrom. Yes, it is still there, on my blog for all of you to read. But I donāt own it anymore. and if WordPress.com was hacked, or were to decide to delete my account; if they decided to switch to a paid service; if they forced logins; if they changed what search engines can index; if they blocked certain IP ranges or countries; if they started selling all collected metadata; if they started training AIs on user content,⦠there would be nothing I could do. And the last months have shown that these previously āunthinkableā platform moves are not paranoid conspiracy theories. My blog is of course anything but crucial, but still: itās years of my writing, and WordPress.com doesnāt even provide me with a frictionless data dump option.
These are not the only reasons why my last blog post was from 2018 (more on that will also follow in one of my next posts), but they were sparking my desire even back then to either host my own instance of WordPress (which back then was primarily a financial issue, and secondary a time issue), or write my own blogging software (same issues). Until I found static site generators (SSGs).
My New Blog
SSGs seemed to be made exactly for me:
- You write your post in Markdow
- Once done you run a program on your Markdown files.
- The generator creates plain old HTML and CSS files, (and if needed, JavaScript)
- You just copy those files to a simple HTTP server directory.
No fancy dynamic PHP software (Java, Kotlin, Python, Ruby, you name it), no database that stores state and metadata. The downside is: this also means no ālikingā a post, no automatic backlink recognition across sites, no āfollowingā a post, no built-in comments. But I can live with most of that, most of these features werenāt used on my old blog anyway. The only thing I truly care about is feedback from my readers, so some way of comments.
Many static blogs use Disqus or Giscus for comments but I donāt want to use those services (reasons for another post). The best alternative Iāve found so far is, isso, and I might consider it for the future. However, to host it, I would need at least a service that runs a container for me and I havenāt picked a server or cloud setup yet. If I do, I might also move this blog there.
For now Iāve found a workaround:
- Email comments: Even with my old blog, some people would rather send me an email than use WordPress.com comments. Iāve simplified it: hit that envelope icon at the bottom of this post. It opens your mail client with recipient and subject pre-filled, so I can easily filter my inbox for comments.
- Fediverse replies: If you use Mastodon or basically any other federated service using ActivityPub you should be able to share your thoughts with me and others by replying to the post link I publish for each article. Itās a bit manual work for me (thereās no full automation yet), but Iām happy to do that if it brings actual conversation.
On the plus side, this also means I donāt have to worry about privacy (as no data is being logged anywhere), and I can host the blog nearly anywhere: a dedicated webserver, āPagesā services (Codeberg, GitHub, GitLab, SourceHut), or simple object storage/edge hosting, with deployment becoming as easy as committing a new file to my Git repository.
zola
As SSG
I decided to go with
Zola.
Zola is rather new on the market,2
but already fully functional.
It uses Markdown as content language,
Sass for styling,
and Tera for templating.
And itās a single binary,
written in Rust,
and configured via a single .toml file.
I hadnāt heard of Tera before,
but itās basically a template engine for Rust.
If you have worked with Django templates or Jinja2,
youāll feel right at home:
you have {% ... %} and {{ ... }}
as control flow and output delimiters,
reusable blocks and macros,
all in a readable syntax:
{% set_global uncategorized = [] %}
{% for post in blog.pages %}
{% if not post.taxonomies.categories %}
{% set_global uncategorized = uncategorized | concat(with=post) %}
{% endif %}
{% endfor %}
{% if uncategorized | length > 0 %}
<details>
<summary>Uncategorized ({{ uncategorized | length }})</summary>
<ul>
{% for post in uncategorized %}
<li><a href="{{ post.permalink }}">{{ post.title }}</a></li>
{% endfor %}
</ul>
</details>
{% endif %}
Zola is also very flexible about structure.
You can keep media separated from content
(i.e., use static/ directory for images,
while your posts are in content/),
or you can ācolocateā assets next to posts
in the same subdirectory of content/.
You can even mix and match both startegies:
shared images can live in static/,
while media-rich posts can keep everything together.
And I can also just mix and match Markdown and HTML:
# Some Heading
Sometimes I feel like I do link to [Wikipedia](https://en.wikipedia.org),
<abbr title="I do like the Wikipedia, though...">too much</abbr>.[^1]
[^1]: I used to do this on my old blog, as well.<br />
Did I btw. mention that I have a Wikipedia editor account?
Since *January 22<sup>nd</sup>, 2012*.
All in all, Zola was surprisingly easy to use. I spent about week setting it up completely from scratch, including creating my own template files and adding some extra functionality (not all of which Iāve revealed yet, you can take a peek at the repository if you are curious and cannot wait). I am pretty happy with how this turned out and how fast it went.
I did also consider other SSGs:
- Jekyll
- Battle-tested and great for GitHub Pages, but a Ruby dependency hell. Also, stricter conventions (e.g., no colocation) make it harder to use and can get annoying.
- Hugo
- Fast and popular, but the Go template syntax didnāt work for me.3
- Pelican
- If Zola didnāt exist, this would have been my pick, due to the Jinja templates. However, similar to Ruby, Python asks you to manage a dependency stack and virtual environments. Zola is just smaller, faster and easier to maintain.
Zola ended up being the best balance of simplicity, flexibility and a general āthis is nice to work withā feeling.
Codeberg
Codeberg.org is a service I wanted to try out as an alternative to GitHub, and so far I am pretty impressed. Under the hood it runs Forgejo, a community-driven fork from Gitea. The main focus of Codeberg.org: Provide services needed for Open Source development, that are not corporate-owned.
To achieve that, Codeberg.org is run by Codeberg e.V., a non-profit organisation based in Berlin, built around providing open and free services to facilitate open-source-development. As of late 2025, they have 1,200 members, more than 200,000 registered users and more than 300,000 repositories, with some of the bigger OpenSource projects (like Zig and Gentoo) already switching to it. In addition to Forgejo as a software forge they also provide:
- Codeberg Pages for static web hosting
- Weblate for collaborative translations
- Woodpecker CI for CI/CD
That stack made it a very natural home for a static blog: commit to the repository, triggering a CI to build and then publish via Pages.
The only caveat: for everything to work, you first have to activate Woodpecker for your account by opening a request with Codeberg. They do this to protect their infrastructure from misuse and spamming. In my experience, it was straightforward and felt more like a formality than an obstacle. But you have to know that, and following just the Zola documentation, I didnāt.
After that, the rough setup is:
- In your Codeberg under
SettingsāApplicationsāAccess tokensadd an access token for Woodpecker and copy it - Visit https://ci.codeberg.org to authorize Woodpecker to access Codeberg and activate it for the desired repository.
- In Woodpecker CI go to the repository,
then go to
SettingsāSecretand add that token ascodeberg_token. Add another secret that you namemail, with your Codeberg email address as value - Follow the instructions at zola
And thatās it.
For now I will use Codeberg Pages for my blog. It was a fast and easy solution, plus it gave me the opportunity to get to know Codeberg and Woodpecker CI. In the long run I am planning to move all my GitHub repositories to Codeberg, so this seemed like a first good learning opportunity. Regarding my blog, I might still look for a more dedicated hosting possibility, especially if I decide to run additional services like isso.
Design
Instead of using a ready-made template, I wanted to create my own design. I hope you enjoy it? If you have any suggestions or notice problems, please let me know. I havenāt worked in front-end development and design for a really long time, and it was actually a lot of fun. Iām glad I went for my own design instead of using a third-party design.
For the colours I used the colour palette that is provided by the Dracula Theme. Iāve been a fan of this theme for years, and use it wherever I can, so bringing it to my blog felt inevitable.
Other inspirations were:
- Scryfall for creating invisible titles above cover artworks to search them
- Trakt.tv for creating ranking numbers on cover artworks
- kytta.dev for the āReply via Mastodonā idea.
- Zola Terminus theme for the post navigation
- Zola Zap theme for using icons instead of links in the navbar
Starting point!
This is the starting post of my new blog, i.e., zola on Codeberg (or wherever this might be hosted in the future).
Anything that comes before this post, will have been transferred from other sources to this blog (with the original publication date kept as is).
But more on that in the next post.
-
ā¦which is the German dubbing of āOh, Wilma, Iām home!ā ā©
-
Arch provided me with
zola 0.22.1as the current version, the project started 2017. ā© -
It is personal preference of course, but to me
{% for post in blog.pages %}(zola) is more readable than{{- range (where .Site.RegularPages "Section" "blog") -}}(go) and{% if uncategorized | length > 0 %}(zola) more readable than{{- if gt (len $uncategorized) 0 -}}(go), to show just two examples. ā©
Any thoughts on this?
Share them with me via or with me and others via