Moving from Drupal 7 to flat file CMS Grav

Screenshot of the top part of starting page/front page of new merviemilia.com

When I first set up this site in 2010, I built it with Drupal 6. Back then I decided it was time to get back into blogging, since my lengthy break from it. Before my Drupal site I had been using either some self developed blogging systems (first with flat files and php, then with PHP and database), or I had different simple static websites without a blog or other dynamic and structured content.

I chose Drupal because it seemed flexible enough with loads of interesting features. It comes with custom content types, and can be extended with many modules (Drupal's version of extensions or "plugins").

During this time Drupal turned for me from nice and flexible to bloated and complicated. Somewhere along the line I did a huge job migrating from Drupal 6 to 7, and I recall the migration being a pain in the ass. When it became clear I would have to move on from Drupal 7, I wasn't sure what to do.

Throughout the years Drupal and its modules had grown increasingly dependant on Drush, a command line scripting interface for Drupal. Because I hadn't originally built my site with Drush, installing it afterwards was risky. It could be done, but it could completely destroy the site and clean it empty of all the content. Another thing to annoy me about Drupal.

Migrating from 7 to 8 seemed like a huge project, which basically meant building the site from scratch and then importing the content. Besides, it didn't seem like most of the modules I was using weren't yet upgraded to 8 or were still in beta.

So I procrastinated long enough for Drupal 8 to become obsolete and Drupal 9 becoming the thing. Still, the migration was a huge project and still, not all the modules were upgraded.

I seriously started to look elsewhere.

I am, unfortunately, very familiar with WordPress. And while I cautiously recommend it to those who don't have much technical understanding and just want to add content, I don't want to build my site with it. WP is also too bloated and it's very stiff when it comes to such things as custom content types. I didn't want to move from a bloated system to another.

This made me decide I wanted to move to something completely else. From a heavy database system to something lightweight, without database.

For me this meant two options, a static site generator or a flat file CMS.

Static site generators surely are interesting, but early on in my research I found them a bit... much, somehow. A static site generator is installed somewhere, either on your own computer or somewhere on your hosting where public cannot access. Then the generator is given the raw data and templates you want it to turn into a static site and then the newly created or updated site is deployed to public. This creates usually very fast websites, because each site is pre-built, rather than in a system where content is pulled from a database for each website visitor.

But the whole thing seems like a hassle to me. I get the intrigue, but it's just not my cup of tea right now. Also many static site generators are paid, and my budget is a very round zero.

Flat file CMS is similar to Drupal or WordPress in the sense it pulls content to the website dynamically. However, instead of using database, in a flat file CMS content is stored in text files, such as Markdown, HTML or basic text. Markdown appears to be the most common formatting option. (Markdown is also often used of content data in static site generators.)

As mentioned before, I have built a flat file blogging system before. This was 20+ years ago, and what I did was a pretty simple text file + PHP setup. I think I even used static pages for the rest of the site back then, only using the flat file system for the blog. So I considered building something like that now too. Before going into that I did another round of research in existing flat file systems.

This is when I found out about Grav. Grav is an open source flat file CMS which utilises Markdown for content and Twig for templating. What drew me to Grav was it has a pretty okay documentation, and in addition to Markdown you can use plain HTML in formatting your content. Grav thrives to be simple, fast and flexible, which sounds good. I like simple.

Additionally Grav comes with basic caching and other performance related settings without the need to add extra plugins. Plus there's a pretty easy way to create redirects and such.

To extend Grav, there are quite many plugins available. And if you aren't into creating a theme from scratch, you can use on of many ready made themes. For those who want a super easy solution, there are so called skeletons, which are all-in-one packages containing Grav, certain plugins, theme, configuration and sample pages.

If you want, you can use the Administration Panel plugin, a graphical user interface for configuring Grav, and creating and modifying content. It can be helpful addition for configuration and updating also for those who are okay with creating content in files.

Speaking of updating, it's such a breeze. It's simple as clicking a button in the admin panel or with simple command through a CLI. So far every update has been really fast. I haven't had to upgrade to a next version (current version is 1.7.x), so I don't know how that works.

I wasn't familiar with Twig, a template engine for PHP. It's idea is to be fast, secure and flexible way to create templates. I felt a bit antagonist about Twig, considering that I'm quite good with PHP. Learning another way, when I had already learned one. Also having to learn Markdown gave me a pause, but since Grav allows using HTML too, I chose to not make it into an issue.

In spite of my doubts with Twig and Markdown, I went ahead and formed a plan. I would give Grav a try, but this meant I would have to get my Drupal 7 content in the proper folder and Markdown file format. Easier said than done.

Grav utilises a folder structure for the content data. Each page you see on this site is a folder named after the page slug. For example, this post is a folder called from-drupal-to-grav in a folder called 04.blog. The number before the blog folder's name tells Grav that the page in question is to be featured in the menu, as the fourth link. (This can be overridden, but it's the easiest way and feels logical.)

Inside the page folder is a Markdown file (.md). The file's name tells the content management system which Twig template to use. If you had a file called blog.md in a content folder, Grav would check if there's a template called blog.html.twig. If the template would exist, it would be used to format the content in the blog.md file and if it didn't exist, then the default.html.twig would be used instead.

Additionally the folder can contain other files, such as images, that can be pulled in the page in different ways, either automatically through the Twig template or by linking to them in the Markdown file.

I decided I wouldn't need to migrate the other content than the blog posts from my Drupal 7 site to Grav format. Everything else I could either recreate or create something completely new in their place.

This turned out to be lots of work. I went ahead and deleted quite a lot of the old blog posts. Deleting old blog posts was something I had thought about doing for a while. I think I had already cleaned away a few of them before, but now I went in with a big broom.

I wanted to make the migration as fast as possible and also to make the site a bit lighter in content. During over ten years of blogging, there were many posts that didn't make sense any more. And lots of broken links or broken video embeds. All those had to go.

Additionally I removed most of the images from the blog posts. I didn't think migrating the images from Drupal 7 system would be an easy project and didn't want to just dump the tragically messy files folder of the old site to the new site as is. I took a note of the blog posts that required images, such as the tutorial on about how to draw a braid, and saved those images for later.

At this point I was hitting a wall. I found a couple of modules for Drupal which were supposed to help to save content in Markdown files. One I couldn't use because it required Drush, which I wasn't going to install just to migrate away from Drupal. One that appeared to work turned out not to be working at all. I still don't know what went wrong, because it didn't give any sort of error message. It just created empty Markdown files.

On top of this, none of these modules would have created the required folder structure. I tried to fix that module which created empty .md files, and also make it to create the folder structure. I did succeed in turning it to create the folders, but unfortunately it still continued to create empty files. A win and a loss at the same time.

A Drupal 7 to Grav migration module exists, but it also requires Drush. At the moment of writing this there doesn't appear to be a simple way to migrate from WordPress to Grav, but maybe someone someday will build such plugin.

Fortunately I stumbled upon a How to migrate a Drupal 7 site to Markdown files by Guido F. Robertone from weKnow. The post includes a nifty little node migration PHP file, which I was able to modify for my needs. On top of changing into folder structure, headers and frontmatter creation had to be tweaked as well as a few other little details. I'm not posting my tweaks here, because they were crude and quick and I don't want someone to come and explain me how I could have done it better. It worked, it's done. Let's move on.

Of course these modifications couldn't had been done without some knowledge in PHP, Drupal 7 and MySQL databases. So the migration file won't work for you in migrating to Grav if you don't have that knowledge. It works as is though, if you just need to export your Drupal 7 site content to basic Markdown files.

Because this was such a success, I also bulk exported some other content, such as the webcomic. Some of these exported files I ended up keeping as backups, some I tweaked further to work with my new site.

I created my own custom theme from scratch, including a bit of code, recipes and solutions I found from Grav documentation and searching through the forum. The documentation is a bit lacking, so you have to just go ahead and search (and maybe ask), plus go with trial and error if you need to create anything fancy.

That said, Grav is surprisingly flexible. And if you aren't, as I am, determined to do everything your way and make advanced stuff, I think it can work out fine for a less technical person too. Unless you need to migrate your old blog.

I'm not a huge fan of Markdown, but I can work with it. Plus I can use HTML when needed in my .md files, so it's not an issue. I try to keep most content as pure Markdown as possible, in case I ever want to move to another CMS or static site generator. Especially blog posts and other content which I might like to bulk migrate later.

For the new theme I cannibalised some stuff from my old theme, but mostly I just started over with everything new. The front page, about page, and some other pages I created from ground up, copying only some of the old texts, and creating them in a whole new structure.

After I had themed and rebuilt most of the site on Grav in such a way I felt it could be published, I took backups and deleted the Drupal 7 site, and then replaced it with my new Grav site.

After publishing the site I have been working on it quite a lot and changed how some things work. At first I created a simple lightbox style gallery/portfolio. But because I wanted to be able to link straight to each image and possibly add extra information alongside them, I redid the gallery as separate pages for each image. Now I can share this recent ink drawing of a birch on Twitter or Pinterest easily. Plus I can include it straight in my other content, and link to its own gallery page. Like so (click the image to open its gallery page):

Birch, a black and white ink drawing of an old, life seen birch without leaves by Mervi Emilia Eskelinen

There are still lots of things that may not work, especially on the blog. There may be broken links. This is an ongoing project. I learn. The site evolves.

I haven't decided if I need a search function for the site. I believe I was the only one using it on my old site. Right now I don't have any website analytics or similar visitor monitoring, other than the basic ones that came with my hosting (which I haven't check in a long time). On the old site I used different analytics but usually ended up forgetting to check them. No point, then.

My site is pretty image heavy, due to my work as an artist, illustrator and designer. This takes a toll on performance. I have tried to optimise the images as much as possible without compromising the quality too much. Because the "next generation" image file formats such as WebP aren't yet compatible with all the browsers, I'm still relying to the old, heavier formats. (Please, don't feel free to tell me how to improve the performance unless I ask!)

Speaking of image sizes and quality, I have tried to get into responsive images, but in all honesty they are a bit difficult. Especially for a more complex site like mine, where images are placed and sized in many different ways. Grav has in built way for media processing, including for creating responsive sizes. But right now my personal processing gets stuck on trying to get it work properly.

Overall, the site appears to be faster than it was on Drupal 7. Because I started fresh, I have less plugins and other extra stuff on the site. I have tried to limit the amount of JavaScript and make sure basic stuff works without it. JS is only for enhancements.

What I truly enjoy is, the Grav doesn't feel as bulky and bloated as Drupal (or Wordpress) did. At least not yet. There's always a chance this will change in time, unfortunately. For now, everything seems nice and lightweight. And simple. I do like simple.

Perhaps some day I will move on to a static site generator. Or something else. Who knows what the future brings.

Meanwhile I hope you enjoy my new Grav site!

Mervi Eskelinen

Hello,
I'm Mervi Eskelinen!

An artist, nerd and business sorcerer, dedicated to make world beautiful and strange, and to get you to make more art. Make art, change the world!

Become a patron