In the last three entries in this blog I've explained the thought process behind developing the tooling to build this static site [1] [2] [3]. The tooling is now considered complete, since all of the original design principles are met:
vars/posts.yml
generator.yml
reports a successfull run, a very strong assumption can be made about everything being in order.In order to provide a neat interface to read the blog, an RSS feed is required. I made the decision to exclusively leverage the same data and files that are used to generate the site itself. This makes it so that the feed comes "for free", as long as there is a single static template file that's baked into the feed.xml.
The RSS feed did however trigger the need for being more strict on the data organization, and prompted a complete refactoring of the site templates. This proved useful very quickly, and paid itself back by enabling a pretty simple data validation setup.
Initially, the setup simply ensured that all generated HTML was valid. This worked well, but had a few shortcomings: Firstly, it required manually updating the same information in several places, which was prone to manual errors, as listed in the the blog post about the site generator. Secondly, the HTML validation doesn't cover validating the generated RSS feed.
As all the information about the posts was eventually consolidated into a simple dictionary, the input data was simple to validate by simple ansible modules. Practically all there is to do is checking that the relevant values are unique. Additionally the value of the individual post path is checked to actually exist in the repository. After the site has been generated, the feed timestamps and directory structure of the site is checked. The workflow of adding a blog posts is as simple as first appending the dictionary with the new post details, and then adding the actual content to a new file.
To conclude, a succesfull generation guarantees that:
Lighttpd is replaced with caddy. This was initially done due to debugging images not being served correctly, as debugging the lighttpd configuration was a bit cumbersome. The lighttpd-based setup worked well, but it is a bit easier to use a well maintained and documented server in the container.
Initially, a hidden post was generated by simply omitting the post link from the blog index.
This proved cumbersome as the blog index generation was automated alongside the RSS feed, so the post inclusion is now simply controlled by a post-specific variable, which has to be explicitly set for each post.
Simply declaring the post to have the public: false
attribute will exclude it from the blog index and the RSS feed.
A simple variable in the generator playbook determines the base URL of the site.
For local development, it is convenient to be able to set the URL to simply be http://localhost:3000
, and automatically update everywhere with ansible-playbook generator.yml --extra-vars "base_url=http://localhost:3000"
.
The default value remains the public URL of the site.
I really liked this project, and am pretty happy about the eventual outcome. I learned quite a lot of small morsels of new information, and managed to complete this project in less than three weeks.
I most likely won't really add new features to the site generator, but I might do several non-functional refactorings and other similar additions, such as moving all the modules to a new purpose-made ansible collection.