My new Koriander CMS Open in new tab (full image size 78 KiB)
For the past few months I've been working on my own CMS called Koriander.
I like pasting pictures in my blog posts and prefer doing everything blog-related with one tool.
Publishing with Hugo
Working with Hugo has been a frustrating experience. Here's how I've been writing and publishing new posts with Hugo so far:
- Navigate to my blog at
$HOME/personal-website. - Run
hugo content newto create a new markdown file incontent/posts - Realize that Hugo won't render my post because you're in UTC+9 and it's 8:59. Hugo has some issues with timezones
- Run
hugo server -Dto serve a preview - Open my browser at
http://localhost:1313and find the blog post - Open the blog post in Neovim
- Edit the post
- Check the post preview in my browser
- Render the blog with the
hugocommand. - Publish my blog to my web server with
rsync. - Check that my blog renders correctly on https://www.justus.pw
These involve too many different tools and I've developed an aversion to this pile of UX misery.
If I want to add pictures, I need to do the following on top of the other steps:
- Copy or paste the picture into the post directory. I use pastify.nvim and it saves some time.
- Insert the picture path in my post's markdown.
- Check my browser and make sure that the picture renders correctly on my new post.
My ideal publishing workflow
WordPress and other web-based CMSes solve most web publishing needs without you having to leave your browser. With Koriander, my ideal publishing workflow should look like this:
- Start Koriander on my computer by typing
korianderin the terminal - Open my browser at
http://localhost:1313 - Press "New post"
- Start editing my post in markdown
- Press the save icon
- Run
koriander render - Publish my blog to https://www.justus.pw with
rsync - Check that my blog renders correctly on https://www.justus.pw
If I want to add pictures to my posts on Koriander, I want to drag and drop pictures into a markdown editor and call it a day.
What I've made so far
I've started writing a small Django-based CMS called Koriander that lets me write and publish blog posts. With Koriander, you can manage your post assets as binary blobs inside an SQLite database. The same SQLite database also manages your posts and tags.
Koriander lets you edit posts with EasyMDE which in turn is based on CodeMirror 5.
If you want to continue editing your Koriander site on another computer, the only file you need to carry over is your database.sqlite3 file.
There's a uv run ./manage.py render command that gives you a directory that you can upload to a web server. You can also host Koriander on a web server. I haven't spent time on hardening Koriander yet but I want to do that in the future and host Koriander somewhere.
Importing from Hugo
With Koriander, you can import your Hugo markdown posts into Koriander. I've implemented Koriander's page path structure based on Hugo's branch and leaf pages.
I've also spent some time on writing a Hugo template converter with lark. It's experimental and I hope to offer a one-stop Hugo import in the future.
What's left
Here are some features I want to implement for Koriander:
- Spellchecking support in the browser.
- Run
renderfrom browser and receive a compressed archive with the result. - Show page resources (images that you've added to a post) below the page editor.
- Harden Koriander so that you can host it on a web server.
- Add support for static files.
- Add button that lets you add a new page from anywhere on the site.
- Improve Go/Hugo to Django template conversion.
- Implement basic Wiki system
- Add page edit history
- Polish the source code and share
I've published Koriander's source code to CodeBerg.