home

This blog is a Joplin Notebook

I have given up on blogging more times than the number of blog posts I've written. I had to stop every time because I spent more time maintaining the blog than writing anything. No matter which solution you start with, give it enough time and you will find an essential feature that it doesn't support. Here's a non-exhaustive list of solutions that I've tried before:

I have spent a lot of time trying to find the perfect stack for a blog. There isn't one.

Why Joplin works

When I stumbled upon Joplin, I had to give it a try. Joplin is easy to use, has a great markdown editor, and allows import/export. I write all blog posts in a notebook and export it as an HTML directory. I have written a small GO binary to do a bit of "preprocessing" on these static files:

I have set up a static file server that serves these files. With the HTTP server I can:

func main() {
    mux := http.NewServeMux()
    fileServer := http.FileServer(http.Dir("./public"))
    mux.Handle("/", customHandler(fileServer))
    log.Fatal(http.ListenAndServe(":8080", mux))
}

func customHandler(next http.Handler) http.Handler {
    return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
        # add redirects and headers here
        next.ServeHTTP(rw, r)
    })
}
func main() {
    mux := http.NewServeMux()
    fileServer := http.FileServer(http.Dir("./public"))
    mux.Handle("/", customHandler(fileServer))
    log.Fatal(http.ListenAndServe(":8080", mux))
}

func customHandler(next http.Handler) http.Handler {
    return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
        # add redirects and headers here
        next.ServeHTTP(rw, r)
    })
}

The file server and preprocessor is less than 100 lines of code combined and has 0 external dependencies.
This "stack" provides me with a good interface while writing and total control over how the content is served. Next time I find a feature that Joplin does not support, I can implement it with 5-10 lines of Go instead of scrambling to find a workaround.