Posted on the 21st of Jan 2021 · By Sidharth Shanmugam · In Programming Adventures

How I Built This Website Using Wagtail CMS

I have finally rewritten from the ground up (again) and completely redesigned this website, implementing Wagtail CMS.

In my previous blog post, I spoke about how eager I was to move away from WordPress and how I built a new website using Django, a powerful, fast and secure web framework. I also mentioned how I wanted to implement the Wagtail CMS.

In the future, I will start to implement Wagtail CMS

Well, it has finally happened. Although you can integrate Wagtail into an existing Django project, I decided to start from scratch. Mainly because of the fact that it would be a better learning experience building everything again, and partly because of the fact that I wasn’t happy with the quality of my code from the old Django website.

Why Wagtail?

It’s simple

It has an UI intuitive, and it's surprising easy to code. It handles a lot of the tasks, such as image uploading and editing, elegantly, and it doesn’t take a lot of time to install and set-up. The documentation is quite easy to understand and there are many free tutorials out there, such as AccordBox and Learn Wagtail.

It's powerful

Not only does Wagtail come with additional extra features such as StreamFields, auto sitemap generation and a really nice WYSIWYG (“what you see is what you get”) text editor, Wagtail is powered by Django. This gives you limitless flexibility to scale your website to whatever you want it to be.

What are StreamFields?

StreamFields are basically the building blocks for the content of a page. They allow for the creation of “blocks”, such as headings, paragraphs, blockquotes, images, etc.

Screenshot of StreamFields in the admin interface

These have their own HTML templates, styling and logic. Placed on any page, reused and even ordered. It’s a godsend for building a library of reusable components incredibly easily.

Here is an example of the blockquote block that I have written and use on my site:

# streams/

class BlockquoteBlock(blocks.StructBlock):
    """Blockquote block."""

    quote = blocks.RichTextBlock(
        help_text="Add the quote here"

    source = blocks.CharBlock(
        help_text="Add the quote source",

    class Meta:
        template = "streams/blockquote_block.html"
        icon = "openquote"
        label = "Blockquote"

Blocks can have their own templates and styling.

<!-- sidsidsid/templates/streams/blockquote_block.html -->

<blockquote class="my-1">
    {{ self.quote }}
    <span>{{ self.source }}</span>

StreamFields are quite similar to WordPress’ Block Editor, a.k.a Gutenberg. The only key difference is that the WordPress Block Editor comes with a bunch of blocks, whereas, you have to program them yourself on Wagtail.

The Project Structure

Structuring a Django/Wagtail project is incredibly easy because everything is done for you. Django can create new apps, it handles static directories, it handles all the template directories, and the list goes on.

Your website directory will be set up for you by simply entering the following in the terminal:

pip install wagtail
wagtail start mysite
cd mysite
pip install -r requirements.txt
python migrate
python createsuperuser
python runserver

Its super easy to scale up a website, you can easily add more “apps” to your project with:

python startapp a_new_app
Picture 2.png

This is my project’s structure. The “blog” app contains the models and logic for the blog feature of my website.

The “dashboard” app is quite simply just for customising the admin UI of Wagtail with some custom logos, text, etc.

The “flex” app contains the models and logic for a generic page (not a blog post), The “home” app is actually the same as the “flex” app, but I’ve decided to separate the two, if in the future I decide that I want my homepage to be totally different.

The “menus” app contains the logic and models for the navigation menus you can see around this website. I’ve registered snippets so I can easily add more pages through the admin interface.

The “settings” app contains different site settings such as favicons, logos, footer, etc.

The “social” app is pretty much just the code for the snippet which I use to add links to my social accounts through the UI, these social links can be found in the footer.

The “streams” app contains all of my StreamField blocks.

Screenshot of the registered settings in the admin interface.

Deploying the Project

There are many ways of deploying a website, the hosting stack that I have chosen is Apache2 (hosting this Django project using mod_wsgi) running on a Raspberry Pi Model 1 B+, with the Debian OS.

Although it is one of the ways to do it, the stack I have chosen isn’t the fastest or most efficient. I did try Gunicorn with Nginx, however, I found this to be incredibly slow, the server response times were upwards of 15 seconds. This is mainly due to the fact that I am not that experienced with either Gunicorn of Nginx and I didn’t really tinker with the config.

I am using Cloudflare too, I always try to incorporate it in all of the websites that I publish, not only does it cache and speed up the website, but it also provides an added layer of security and protection (they even provide SSL certificates and automatic https redirecting).

Looking into the Future

The Raspberry Pi, with its 512MB of RAM does in fact struggle, due to this I am thinking about buying a newer Raspberry Pi, the model 4 B which can be configured with up to 8GB of RAM.

I will try to sort out server-side caching, but I am planning to hold back until I invest in a new computer with slightly more RAM. I am also planning to host an email server using MailCow, it’ll be nice to have an email on this domain.