« /home/rc

you (probably) don't need a Static Site Generator

19/08/2022

You probably don't need a static site generator, I learned it the hard way with this website. It is currently at its 7th version, before I used a lot of SSGs (Jekyll, Hugo, Gatsby, Astro, 11ty) and ultimately I think the experience with using such tools is just bad. The only thing I always liked is they have proven to be a good way to start your journey in having a blog and in web-development. You can take a theme/template and start hacking it to your liking, however soon you will be facing the harsh reality. The theme isn't exactly what you need. You need to add somethin custom. You want to access that variable. Customizing such complex sites is hard and requires a good understanding of the tool generating HTML pages. Static Site Generators are huge programs providing a whole lot of functionality, I found out that (once again) simplicity is a feature while writing a blog or a personal website.

I mentioned that SSGs are way too complex for a blog, so let's start by listing the features a tool to build a blog should provide:

This is all it's needed to provide the beforementioned features:

@app.route("/")
def index():
    posts = []
    for post in listdir("posts"):
        post = getMetadata(post)
        if post["draft"] is False:
            posts.append(post)
    posts = sorted(
        posts, key=lambda d: datetime.strptime(d["date"], "%d/%m/%Y"), reverse=True
    )
    return render_template("index.html", posts=posts)


@app.route("/posts/<path:path>/")
def posts(path):
    f = open(f"./posts/{path}.md", "r")
    htmlmarkdown = markdown.Markdown(
        extensions=["fenced_code", "codehilite", "meta", "footnotes", "toc", "tables"]
    )
    post = htmlmarkdown.convert(f.read())
    return render_template("post.html", post=post, meta=htmlmarkdown.Meta)

The code is pretty simple to understand and tweak, I encourage you to try to fork the repo and hack stuff around.

Essentially this is a Flask website, to obtain a bunch of static files I am using Frozen-Flask, Python-Markdown is used to convert markdown to HTML, and the content is then injected in Jinja templates.

Additionally tailwindcss is supported, so styling custom parts should be straightforward. Code syntax highlighting is performed by Python-Markdown using Pygments, so changing the theme is simply a matter of using a Pygments-compatible theme and editing static/pygments.css.

Publishing a post is simply a matter of creating a markdown file in /posts and adding the required metadata in YAML format, ike in the examples/

Deployment is a simple process, a configuration file for netlify is provided, so the site can be deployed simply by connecting netlify and github (or similar). Additional configuration is required to use a custom domain, but this is beyond the scope of the post. Netlify isn't strictly needed, you can build the website using python3 app.py prod and then upload the build/ directory with rsync or similar tools to a box and then simply use a webserver to serve files. However I find it convenient because it allows to publish simply by committing to version control, automagically manages TLS certificates and moreover the website is served behind a CDN. It should also be trivial to write a custom action to deploy using GitHub Pages.

Customizing the website is simply a matter of creating a new file in /templates directory and adding a route in app.py, like this:

@app.route("/custom/")
def custom():
    return render_template("custom.html", optionalParam=optionalParam)

Of course it is possible fetch data externally (with requests for example), or from local files and pass it as a parameter to the template.

I am pretty sure that if you know a little bit of HTML you will find this to be a simpler solution than other fully-fledged static site generators. Jinja has a simple syntax while being very powerful.

Bonus: this project does not have a CMS, this is intended for technical people comfortable with git and with writing markdown files, this can conveniently be done using github.dev, so it is possible to publish a post only using a browser.

Speaking of deployment speed: the build process, as mentioned by Netlify, only takes 16 seconds:

11:43:16 PM: Finished processing build request in 15.140751656s

Happy blogging everyone! Let me know if you plan on using ydnassg! What are you waiting for? Fork it and start using it!