- 2020-04-26
New Site powered by Spress - Part II
This blog post continues on part one in which I went into detail about what I think is great about having statically generated webpages. In this post I want explain how working with Spress felt like.
So I fired up Spress without much confidence, ready to stop and try the next generator the moment it would start bothering me too much. I didn't stop. This may be the first good sign or it proves that I'm more persistent than I thought.
The main reason I tried Spress first was that I'm familiar with the technology stack from my professional daily bread and butter. It's implemented in PHP and runs off Symfony components and Twig as a templating engine. That made me hope I would be able to start working quickly and understand how it works and how I can extend it.
An easy way to use Spress is to download a PHAR file which is a package for the PHP application.
CLI
From here there are basically three important console commands to keep in memory:
spress.phar new:site
... You only need to run this once to create a page scaffold from an existing template.spress.phar site:build
... This generates the pages in the build directory, copies all assets and can also be used as a server that rebuilds the page on every change with the--server --watch
options.spress.phar new:post
... This is a nice wizard-like shortcut that guides you through creating the skeleton for a blog post. This is not necessary though as you can easily create the files in the right format on your own if you have seen some.Basics
Blog Post
The main element is a blog post. It has a specific file name (e.g. 2020-05-27-new-site-powered-by-spress-ii.md) and is comprised of a header in YAML syntax separated by a line from a body that contains Markdown text.
For every post you need to defines a layout which is the Twig template that is used to render the blog page on its own. As you can define your own meta data in the header and as you can have individual templates this is quite a powerful tool. For example my photo posts don't contain a body at all. All the information is given in structured data in the header and the DOM is specified entirely in the template.
Here is an example:
--- layout: photo-post title: "Photo #8" categories: [photos] tags: [] author: name: "Marcel Pfeiffer" images: 20140101: date: "2014-01-01" name: ~ url: "/assets/img/photos/20140101.jpg" ---
A minor inconvenience is the fact that pages are by default ordered by date but there is no standard way to include the time into the page ordering. That's why my photo posts are scrambled here.
Pages
Pages are a bit tricky. They are supposed to be Markdown files saved as HTML files in the project root. Again you can define a layout to be use. I use this for my simple Impressum page (impressum.html). But for some reason this doesn't work if you use pagination. In this case I had to save the file as words/index.html.
Categories, Tags and Generators
There are the concepts of categories and tags to group posts by. But there is no intrinsic difference between those apart from how you handle them.
Spless offers generators and pagination that you can use to browse through a list of posts or other collections that you have defined. That said, the documentation about those was not very understandable. But the given examples were enough for me to be able to use them.
Template
The documentation guides you into using an existing template or creating your own from scratch. As the default template doesn't look that great and the second option is badly documented this seems overwhelming at first. If you dig a bit deeper into the documentation you also notice that you can overwrite individual template assets in your layouts and includes folder. That is the route I took. I had a look at a template I wanted to change, copied it into the general directory and made my edits (or more specifically copied my existing template into it and changed the syntax to work with Twig).
The nice thing about Twig templates is that there is an easy import/include mechanism. That way I could write a base template for how an individual post should look like with header, date, author and content and then re-use this snippet through importing it into the post page, the list or the category-filtered list.
Troubleshooting
During development if you ever want to know what's inside a variable in a Twig template a trick is to transform it into a JSON string that can be written into the page.
{{ page|json_encode }}
Documentation and other flaws
Even though I got this page ported in more or less a single evening the documentation left a bad impression. Some things were badly phrased or text snippets scrambled in a paragraph (I already sent a pull request for a correction). On many page you are prominently asked to run a command first that creates an entirely new site even though you have most likely already done this if you seek out help for how to include pagination into your page.
Another thing that suprised me is the fact that there is no helping construct of how to link internal pages. You need to know into what filename and into which folder a page is going to be compiled to be able to link to it.
And the last small problem that I didn't think about beforehand is the fact that all pages are generated every time you change something or add a page or post. This is inevitable but leads to the problem that when you need to upload your page via FTP you always have to overwrite everything. Skipping mechanisms like only newer (it's always newer) or different size (my photo posts compile to the exact same number of bytes) don't help here.
New Site powered by Spress
For years this blog lay sleeping on the internet and I just couldn't get myself to work on content even though I had lots of ideas and opportunities. Part of the reason I guess was that the management of content never suited the iterative process I'm used to work in.
This site was first implemented with CMSMS and later with Anchor CMS. Though I tried to choose a solution as little complex as possible and got the basic layout and integration done with little effort, what was lacking all the time for me was the ability to have a 1-to-1 copy of the blog in my development environment. So I was hesitant to try things out and make little adjustments and wasn't able to have source control of everything I needed for this site.
During the last couple of years more and more information about static site generation crossed my attention and I was intrigued by the idea. I know there are many competitors but in quite a spontaneously act I browsed a small list of providers and choose the first one that looked promising. Because with no experience in the topic it's impossible to pick the right one.
So I gave Spress a try (http://spress.yosymfony.com/ , https://github.com/spress/spress).
Static site generation in general
Static site generation works in a way where you create your site in a development environment - this may be just plain files, an application or a whole CMS - and compile this into linked static HTML and asset files. Those files that browsers are great in displaying. There will be no database requests or backend requests for additional content. Everything that you see is baked into the file your browser downloads.
So what's so appealing about statically generated sites in general?
- They don't need cookies
All CMS that I have tried have some kind of user management. Even if you're only browsing the site it keeps track of your guest status saved in a cookie in your browser that is exchanged with every page within a site. As those cookies are often used for things the user is not aware of, the GDPR or DSGVO made the confirmation of cookie usage mandatory. This is a good thing but leads to those annoying popups and bars where you learn to blindly press Confirm. This site doesn't need one such thing. - No code injection
You don't have to be concerned about bots that browse buggy unmaintained sites, inject some code through a security hole and make it part of their remote controlled bot net. Because there can't be security holes in static HTML files. That also means you don't have to care for constantly updating your CMS.
Of course if someone steals your FTP credentials they could do this anyways but this is a completely different issue. - Easy backup, automat-able deployment and version control-able
As you compile the site every time you add some content you need to have everything necessary in one place.
With the CMS I worked with before I edited some style sheets in an in-browser editor that wrote to the filesystem while many other configurations as well as the posts went into the database while a separate media manager kept track of the images or downloadable files you added to the site. Knowing where what information resided was in-transparent and highly vendor specific. This made backing up all of this an unpleasant job. With site generation you can fully automate and theoretically even test the pages that are created while being able to have the whole site under version control with full transparency about what changes you make to content and design.
The last points were some things I consider general advantages but there are also points why this workflow suits this site and my personal preferences as well.
- I want to do simple things
There are no plans to make this page very big and technical. I guess if you have thousands of posts and want to apply tag filtering to your page the whole system will collapse. - I'm the single author
Even though with a shared repository and some trust in your colleagues you could have lots of contributors, at some point it makes more sense to use a CMS that brings user and group management with it. - No comments section
In the past when this blog had comments turned on it was only used by spam bots. Even though I'd like to have exchanges with readers I don't need the functionality in-site. You can always write an email to me if you like. That said the default theme for Spress even comes with working Disqus integration that moves the commenting stuff to a third party service. - Markdown
Markdown is the markup language used to write those posts. You define what should appear italicized or what should be a link. It's not as feature rich as your favourite word processor, especially working with tables is ugly, but for everything that is planed so far it is fully sufficient for my writing needs.
In contrast, I don't quite like how formatting in in-browser WYSIWYG editors work and how you always have to double-check if the correct span of characters has the correct styling applied. - I can use an editor of choice
As an extension of my dislike for in-browser editors I just enjoy having all files - be it Markdown, YAML, CSS, Twig templates - in a nice IDE (currently Visual Studio Code for this site) and have the appropriate syntax highlighting and linters available.
With this post I tried to show how this style of creating a web site has its own set of benefits. For me it worked very well. I never before had that much fun creating content for this site. In a following blog post I will go into specifics about how well Spress does as a site generator.
- They don't need cookies
Photos Hoyerswerda
2019-10-122019-10-122019-10-122019-10-122019-10-122019-10-122019-10-12DONTCOMMIT: How I avoid committing debug code
- Sometimes while developing you want to try out a new idea and make a swift change to your code.
- Sometimes when you try to tackle a bug it's easier to add a short line that dumps a variable to the console to assure a piece of code is not the culprit before you swing the debugger hammer.
- Sometimes when you are working on your master thesis or a blog post you want to write down a short reminder or a new thought to be elaborated later.
All of those cases have in common that you're writing temporary code that you don't want anyone else to ever see. And here arises the problem of how to keep track of your changes especially if you have to edit multiple files at once. Later when you want to make the commit with hundreds of changed lines it's too easy to overlook a small debug statement.
A nice solution comes with the help of the phrase
DONTCOMMIT
and a fitting git pre-commit hook.Whenever I add a line I want myself to delete or change back later I put a
DONTCOMMIT
somewhere. Usually as a comment.Additionally my hook file
.git/hooks/pre-commit
looks this way:#!/bin/sh for FILE in `git diff --cached --name-only` ; do # Check if the file contains 'DONTCOMMIT' if grep -q 'DONTCOMMIT' "$FILE" then echo $FILE ' contains DONTCOMMIT!' exit 1 fi done exit
What it does is checking every staged file I want to commit for an occurrence of
DONTCOMMIT
and in the positive case returns an error code which makes git cancel the commit with an appropriate error message. As you see this is a bash script. In a Windows environment you will have to re-implement the hook accordingly.One challenge was to find a phrase that you are very sure you will never want to write down, that makes some sense, that is easily perceivable - in the end you want to find it yourself and that is easy enough to write down - if you misspell it it doesn't work. I settled with
DONTCOMMIT
. Which might be a little too long but I eased the pain a bit with the help of my IDE of choice: NetBeans. (You may lower your eye brows again.)I added a macro that I can trigger by pressing
Ctrl + Alt + D
that puts the cursor at the end of the line and inserts the kill phrase. I could make it add the commenting characters as well which would be//
in 95% of my cases but since I handle different file formats regularly this is only a small inconvenience.caret-end-line " DONTCOMMIT"
The downside of this great workflow is that I have to disable it for adding this post to source control.