tutorial grav has gone through many iterations, and most recently migrated from GetSimple CMS to Grav. This page documents some of the hardships and learnings from the migration.'s Technical History

Server Side Includes has been around in various static page incarnations since 2002, but really received definition in 2009 during my Austrailia travels. With some basic server side includes I wrote the entire theme from scratch. CSS provided a modern styling but the content was not dynamic, and a lot of manual work went into each page. I wrote scripts to parse folders of images into web-ready format and automatically generate HTML pages which just needed captions for the images, however the manual aspect still made edits inconvinet and generated inconsisitencies between pages.

GetSimple CMS

In 2013 I had a new job and freetime to work on my webpage. I explored different Content Managment Systems available at the time and had major difficulities with one critical feature: easy migration of my existing website. For example, attempting to upload the previous years of images to a Wordpress site generates a folder for that day with thousands of images. The number of files in an individual directory caused issues with GoDaddy. Realizing that my simple, relatively static site did not need a full featured CMS I found GetSimple CMS. The XML file structure allowed me to write a quick script to migrate my existing static HTML pages to GetSimple style XML pages rapidly. Additionally, being a flat file CMS the performance remained excellent when I migrated from GoDaddy to a self-hosted first generation Raspberry Pi.

However, I encountered some difficulties with GetSimple. The web-based file upload is flash based, so it is incompatible with mobile devices and many modern platforms. While blogging features exist, tag support is limited, so the contents of the site need to be organized by hand. Probably most importantly, there is only one person developing the CMS, and the slow development ground to a halt when medical issues arose.


In 2017 I had a number of projects I wanted to catalog, however the difficulties with GetSimple CMS above made edits to the website a chore. I started looking for a replacement to GetSimple with similar requirements to before: continue without a database so my data is easily reachable with a file explorer, web based interface for quick edits, and I want to use tags on posts for more dynamic content sorting. Grav was selected also because it is open source and it has a developement team with commercial goals behind it. This should translate into consistant development and long term support for the platform. Since I have adopted Grav I appreciate the editing of pages occurs in Markdown. The way the site is structured a human easily could open a page in a text editor and read the content, and see any relevant media in the same folder. Much of this website is archiving my personal experiences, so being able to access the content without the CMS is crucial.


Plugins are what takes Grav from a relatively boring Markdown based static CMS to a modern dynamic system. Here is a quick list of plugins I use beyond the standard list:

  • Admin Addon Media Sort
  • Archive Plus
  • Auto Author
  • Auto Date
  • External Links
  • Page TOC
  • QR Code
  • Related Pages
  • Tagcloud

Admin Addon Media Sort

Remeber: the first image in the "Page Media" is the image automatically used for automated blog posts. This plugin allows click and drag of images

Archive Plus

Archive Plus is a dropin replacement for the Archive plugin. It is what generates the post list on the right hand side of the Archive page. Because of the expandable nature of the plugin, I want all posts to be available all the time. It was counter-intuitive to me, but all of the "limits" in the plugin should be increased (Month = 12 is not enough).


Grav uses the Twig template engine for theming. By using a pre-built theme only a handful of customizations were required to achive the desired look and feel. So reading Twig's documentation to become an expert was not nessicary, however some basic commands were required.

Defining Variables

In Twig, a variable is defined by . For, the primary use of this is to overwrite global variables when incorrectly applied. For example, the variable base_url returns the page's base URL (eg. /blog or /archive). As dynamic content is located under /blog, links generated on the /archive page would break. Adding a simple at the beginning of the /archive page fixed these links without re-writing all of the affected templates.

I also needed to perform basic string manipulations in Twig. With a variable defined, concatinating the variable is used with tilde, for example

Previous Post Next Post