How this site is generated
This is a first ever post on this site. They say writing helps you think and for quite some time I felt my thoughts were frequently scattered. Thus I have decided to start my blog.
As a software developer I admire simplicity and minimalism and therefore it is quite natural that the idea of minimal static website appealed to me. Of course I have stumbled upon the proclaimed static site generator HUGO that I considered trying as it seems like almost everyone uses it nowadays, but after the brief inspection of it’s source code and the documentation I have realized that for my specific needs this still would be an overkill and the time that would probably take me to read the HUGO docs and setup the site I would rather spend developing my own solution.
Developing my own static site generator has one obvious advantage: I can fix it and customize it easily. This way I will also avoid some unexpected problems such as new version of HUGO breaking a website.
The features that I want from my site generator are simple:
- A customizable home page, that contains a list of recent posts together with some other useful links.
- A blog page with an ordered list of all posts. By writing a blog post in a markdown file and then placing it to a specific directory the blog post will appear on the page after the site is rebuilt.
- An albums page that features a list of photo albums that contain my photos of various places. The individual images can be placed arbitrarily to the images folder and then an album can be introcuded simply by creating a subfolder under albums folder (it’s name = the name of the album) and then creating links to the files in images folder. One can also symlink a whole folder of course. The idea of an album is basically just to display images inside of a folder.
- Support of tags. Similarly as with the albums a user creates a subfolder under tags folder that represents a tag and then by simlinking files from the blog or directories from albums the posts and albums are tagged. The name of the subfolder defines the tag. The tags are added to the navigation menu (after the colon |) when the site is rebuilt. Each blog post and album will have the list of tags mentioned at the end of the page, if it has any.
- The last but not least: No Javascript. If I ever get to a point where my blog site is so big I might consider adding simple search functionality.
While searching the web I stumbled upon the idea of generating a website using pandoc. The simplest way to generate a single html page from a markdown is by issuing a command:
pandoc -s page.md -o page.htmlThe -s option stands for standalone. When the option is used pandoc uses a template to add a header and footer. If no template is provided, pandoc uses default template. To provide a template to the pandoc use –template option.
Inside a template file one can use variables, for loops, conditionals, partials (subtemplates stored as external files) and many more
To give you an example taken out of my static site generator here is a template file that is used when a blog post is generated.
<!doctype html>
<html>
${head.tmpl()}
<body>
${header.tmpl()}
<main>
<div class="subtitle">
<div style="flex: 1;"></div>
<h2>${title}</h2>
<div style="flex: 1;" class="post-date">
[$date$]
</div>
</div>
<div>
$body$
</div>
$if(tags)$
<h4>Tags</h4>
$for(tags)$
<span> [ </span>
<a href="$root$/$tags.tag$.html" style="font-size:14px;"> $tags.tag$ </a>
<span> ] </span>
$endfor$
$endif$
</main>
${footer.tmpl()}
</body>
</html>I would like to point out the special variable body designating the markdown file content.
Additionally the generator extracts some metadata from files such as dates. The dates of blog posts are primarily obtained from commit history. Thus the date of the first ever commit of a post file is equal to it’s published date and the date of the latest commit of the file is equal to it’s edited date.
As mentioned above, an album just displays images inside a folder, where the name of the folder is the name of the album. For albums a date range is displayed, where the dates are obtained from images using exiv2. For each image in the album the date is obtained likewise and the name of the image displayed is the name of the file. One can obviously create a blog post containing images and thus creating an album post, but in the context of the generator the idea of an album is slightly different from a blog post.
To add an image to a blog post use the :root: variable:

In a very special case if you need to use the literal :root: string you can type it as
::root::From a user’s perspective:
- creating a blog post means creating a markdown file and placing it inside the content/blog directory.
- creating an album (assuming existing images inside content/images directory) means creating a folder under content/albums directory and symlinking the images from the content/images directory
- tagging a blog post or an album is done by creating a symlink to either a md file inside content/blog directory or an album directory
- to edit the content of home page, edit content/home.md file
You can find the generator in my self hosted gitea repository.