There was a point where I was very into dynamic systems, dynamic sites, a lot of moving parts, etc. Large amounts of dynamic elements and user-interaction on everything little thing was ultimately what I wanted to achieve. At that point I hadn't really figured out how much time and effort something like that takes, and how little it ultimately matters.

It took a long time for me to figure this out, but when I did, I realized that the only way to satisfy the need for templating and dynamic elements that are present in dynamic sites is by using a static site generator. There are a few options for generating static sites, and for anyone who actually wants to do it for themselves, I suggest Hugo. I haven't used it, but it seems like a good choice for people who don't want to build their own solution since it has a lot of features and is pretty fast.

So what'd I do to solve my problem?

I built my own, of course. And not only did I build my own, but I built it in my own programming language Rtfl. Why did I do that? Because it's fun, and there's not really much of another reason. I guess that I know my own system entirely, from inside to outside? Not a great habit to get into, but it worked and ended up being a lot of fun to create. In fact, this blog itself was actually just originally an exercise in creating a proper site "dynamic" site with a static site generator. One of the most important things in software engineering (using that word specifically for engineering, not just programming) is to have an application, implementation, etc for whatever you're building. It ties into the concept of dogfooding in how it requires you to use your own software to improve it. It gives purpose as well, so you will have more motivation to improve it and use its features thoroughly.

So what does this static site generator look like?

It looks like if you mixed EJS with Rtfl. This is what the syntax looks like:
##name my_page
##arg name
##begin
<h1>Hello world!</h1>
<?rtfl if true { ?>
    <p>Something conditional</p>
<?rtfl } ?>
<p>Your name is <?rtfl= name ?>!</p>
As I said above, it shares a lot of similarities with EJS, like IF statements having markup inside. This is because before render time, templates are translate into actual Rtfl functions. So the template above would be translated into:
func template_my_page(name) {
    local __tmp = ""

    __tmp = concat(__tmp, "<h1>Hello world!</h1>\n")

    if true { 
        __tmp = concat(__tmp, "\n    <p>Something conditional</p>\n")
    }

    __tmp = concat(__tmp, "\n<p>Your name is ")
    __tmp = concat(__tmp,  name )
    __tmp = concat(__tmp, "!</p>\n")

    return __tmp
}
(Note, I added proper whitespace and indentation manually.)
As can be seen, the template was translated into an actual Rtfl function. These functions are called at render time, but can also be called by templates themselves, in order to re-use components and provide utilities. All templates share the same global functions and global variables, so they are also able to share data and utilities between eachother. For instance, all blogs that are enumerated on the blog homepage are available to other templates, so I can report right from this page that there are a total of 2 posts on the site right now.

Another example of this is when I linked to Wikipedia. The code I wrote looked like this:
<?rtfl= template_wikipedia("Eating_your_own_dog_food", "dogfooding") ?>
Re-using components in a centralized fashion makes sites easier to build and especially to maintain. Imagine trying to update all headers on a site that uses no import, just consider how time-consuming that'd be.

Using a static site generator lets you have the best of both worlds: not have a dynamic backend, and not have to deal with tedious tasks that editing static HTML requires.