Part 1: Creating a Blog on Sphinx

🙋🏻‍♀️ What you are going to do in this tutorial

  1. Install and setup Sphinx, ablog and pydata_sphinx_theme.

  2. Basic configuration of Pydata Sphinx Theme.

  3. Create your first post with reStructuredText.

  4. Create a static page about yourself.

After you complete all three parts you should end up with an end result that looks like this:

../../../_images/ruby-hammerhead-0.jpg

📓 Prerequisites

  • Be sure you have Python 3.6+ installed with access to pipenv or pip.

  • PyCharm Community Edition, Visual Studio Code, Sublime, Atom, or another IDE of your choice.

  • Basic knowledge of Python.

Hint

If you’re using Windows with WSL2 I’ve had some people unable to access the ablog web server from Windows when using WSL2 to create the Python environment.

🐍 Installing Everything

In this tutorial we will be using a few key packages to get our Sphinx blog up and running these are:

  • Sphinx: A documentation engine written and used by the Python community.

  • ablog: A Sphinx extension that converts any documentation or personal website into a blog.

  • pydata_sphinx_theme: A simple, Bootstrap-based Sphinx theme made by the PyData community.

  • sphinx_panels: A Sphinx extension for creating panels in a grid layout or as drop-downs.

Tip

I’d encourage for the purposes of this tutorial you stick with the pydata_sphinx_theme and once you are feeling a bit more confident branching out to other themes that may require additional package managers or requirements.

If you just want a working version, you can fork the template repo I have on my GitHub page, this will allow you to dive right into blogging without messing around with internals! 🙌

../../../_images/ruby-hammerhead-github.jpg

🚀 Let’s Get Started

To install all of these libraries run one of the following commands:

pip install sphinx ablog pydata_sphinx_theme sphinx_panels
pipenv install sphinx ablog pydata_sphinx_theme sphinx_panels

Once all the packages are installed we’re ready to start configuring our website!

The easiest way to get started is by running sphinx-quickstart, a script that comes with Sphinx and sets up a source directory and creates a default conf.py which is where we specify how Sphinx should operate. To use sphinx-quickstart, run:

 1sphinx-quickstart
 2...
 3> Root path for the documentation [.]: .
 4You have two options for placing the build directory for Sphinx output.
 5Either, you use a directory "_build" within the root path, or you separate
 6"source" and "build" directories within the root path.
 7> Separate source and build directories (y/n) [n]: n
 8...
 9The project name will occur in several places in the built documentation.
10> Project name: Ruby Hammerhead
11> Author name(s): errbufferoverfl
12> Project version []: 1.0
13...
14For a list of supported codes, see
15http://sphinx-doc.org/config.html#confval-language.
16> Project language [en]: en
17...
18Finished: An initial directory structure has been created.
19
20You should now populate your master file ./source/index.rst and create other documentation

Presuming sphinx-quickstart completed successfully and you have answered the questions in a similar way to the example above, you should have a document structure like:

project-directory
    _build/
    _static/
    _templates/
    conf.py
    index.rst
    make.bat
    Makefile

⚙️ Sphinx Configuration

Now we can start to configure out new blog! 📝 Sphinx, ablog and our theme pydata_sphinx_theme have a lot of different features and ways you can configure them so I highly encourage you go out of your way to read the documents and have a play around, but for today I will focus on what I found to be core settings!

First, we’ll start with getting Sphinx ready to work with ablog to build our website, to do this we need to change our conf.py so the extensions list includes our new plugins like so:

extensions = [
]
extensions = [
"ablog",
"sphinx.ext.intersphinx",
"sphinx_panels",
]

Tip

You can also add these extensions to an existing Sphinx project to convert it into a blog!

You can test that everything is working as expected by running the following command to make our website and then serve it locally on localhost:8000:

ablog build
ablog serve

If everything worked as expected you should see something similar when your browse to localhost:8000:

../../../_images/ruby-hammerhead-1.jpg

This version of the website is using a theme known as “Alabaster” it’s quite popular in the Python community and is the default theme for Sphinx. While Alabaster is a pretty good theme, we want to use the one we installed earlier, so the next step is to update that in our conf.py like so:

html_theme = "alabaster"
html_theme = "pydata_sphinx_theme"

Because we have made some significant changes, we should now run a new command clean before building and serving our website, this command cleans our blog build folder and just makes sure no old versions get served, while not needed, I find it helpful in avoiding debugging not existent problems:

ablog clean

If you’re sick of running each of these as an individual command you can also use an && which will execute each command sequentially, in Windows you will want to use a single &.

ablog clean && ablog build && ablog serve
ablog clean & ablog build & ablog serve

If your theme is configured correctly, your website should now look something like this:

../../../_images/ruby-hammerhead-2.jpg

🎨 Blog Configuration

Now our website has all the dependencies installed and the theme configured, now it’s time to start customising our blog and making it look the way we want!

While we won’t cover ever single setting, I’ll cover off the more important ones so you can get started quickly, I highly encourage you to checkout the documentation for Sphinx, ablog and Pydata Sphinx Theme as they are highly flexible and have lots of options avaliable.

The first thing we will start with is getting the index.rst configured, by default it should look something like:

.. Ruby Hammerhead documentation master file, created by
sphinx-quickstart on Sun Nov 22 13:57:22 2020.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.

Welcome to Ruby Hammerhead's documentation!
===========================================

.. toctree::
   :maxdepth: 2
   :caption: Contents:



Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

To set this up to resemble a typical blog that shows the most recent posts, we want to remove the “Indices and tables” block so our file looks like so:

.. Ruby Hammerhead documentation master file, created by
sphinx-quickstart on Sun Nov 22 13:57:22 2020.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.

Welcome to Ruby Hammerhead's documentation!
===========================================

.. toctree::
   :maxdepth: 2
   :caption: Contents:

Tip

In reStructuredText any line that starts with a .. and does not include a directive such as toctree:: is a comment and can be removed.

You can also change the “Welcome to Ruby Hammerhead’s documentation!” which is the heading on your index page. You can also remove it all together if you prefer.

Welcome to Ruby Hammerhead's documentation!
===========================================

.. toctree::
   :maxdepth: 2
   :caption: Contents:
.. toctree::
   :maxdepth: 2
   :caption: Contents:

Note

If you do remove the title from your index page, or any others you will notice in your browser tab the page has no title like so:

../../../_images/ruby-hammerhead-2point5.jpg

You can now rebuild your website, like we have done in previous steps (make sure you run the clean command first) and it should look something like this:

../../../_images/ruby-hammerhead-3.jpg

Right now it’s looking a bit plain so we should probably add in the code we need to show out blog posts and static pages later on. This is also done in the index.rst file and is fairly straight forward, all we need to do is add the following code snippet:

.. postlist:: 10
   :author: errbufferoverfl
   :date: %Y-%m-%d
   :format: {date} - {title}
   :list-style: none
   :excerpts:

Let’s take a movement to go through what each of these options does:

  • postlist: Tells Sphinx we want to generate a list of all out posts, you can add this to multiple pages if you want to filter posts based on author, category or a few other qualities - by specifying the number 10 after this directive, we are telling ablog to show the first ten posts on the index.

  • author: Filters posts written by the author specified here after the directive, so in your version you should put the name you plan to write under.

  • date: How you want the date formatted, in it’s current state it will render the date like: 2020-11-22.

  • format: The way post titles should be formatted, in this case all posts will be rendered “2020-11-22 - My Awesome Blog Post!”.

  • list-style: Controls the unordered list bullet style, other options include circle, disk, and none (which is the default).

  • excerpts: ABlog, by default, uses first paragraph of the document as a post excerpt, this can be configured in the conf.py which we will get a little later.

There are many more options available in ablog which you can read about in the Posting and Listing - Postlist Directives page.

Tip

Sphinx will warn you if you don’t have an empty new line at the end of the file.

Because we haven’t created any content our website is still going to look pretty boring, so now is a good time, to create a quick blog post.

Before we do that though, we’ll need to create a place to store them, this should be a directory called blog.

It doesn’t need to be called blog, you can also call it posts, or something else but it will make up part of your URL later, so when people visit a post they will go to https://domain.com/WORD/myamazingpost.

You can also create a subdirectory for the year if you like, but this step is optional. So now at the very least you should have a directory called, blog.

Next we want to create a blog post (as an .rst file) and save it to our posts directory. If you don’t want to think something up you can use the following sample:

Are you crazy? I can't swallow that.
=====================================

.. post:: 20, July 2020
    :tags: futurama, humans, dating, bender
    :category: Category One
    :author: errbufferoverfl

Now what? Humans dating robots is sick. You people wonder why I'm still single? It's 'cause all the fine robot sisters are dating humans! Bender, being God isn't easy. If you do too much, people get dependent on you, and if you do nothing, they lose hope. You have to use a light touch. Like a safecracker, or a pickpocket.

Tell them I hate them. Spare me your space age technobabble, Attila the Hun! You mean while I'm sleeping in it? __Ummm…to eBay?__ *No!* The cat shelter's on to me.

That's a popular name today. Little "e", big "B"?
---------------------------------------------------

Large bet on myself in round one. Yes! In your face, Gandhi! With a warning label this big, you know they gotta be fun! And so we say goodbye to our beloved pet, Nibbler, who's gone to a place where I, too, hope one day to go. The toilet.

1. But I've never been to the moon!
2. You're going to do his laundry?
3. You, minion. Lift my arm. AFTER HIM!

Moving along…
~~~~~~~~~~~~~~~

I guess because my parents keep telling me to be more ladylike. As though! Oh, I always feared he might run off like this. Why, why, why didn't I break his legs? Why, those are the Grunka-Lunkas! They work here in the Slurm factory.

* Oh Leela! You're the only person I could turn to; you're the only person who ever loved me.
* OK, this has gotta stop. I'm going to remind Fry of his humanity the way only a woman can.
* Okay, it's 500 dollars, you have no choice of carrier, the battery can't hold the charge and the reception isn't very…

Kif, I have mated with a woman. Inform the men. Quite possible. We live long and are celebrated poopers. Look, last night was a mistake. Yes, if you make it look like an electrical fire. When you do things right, people won't be sure you've done anything at all.

That's the ONLY thing about being a slave. Check it out, y'all. Everyone who was invited is here. Hey! I'm a porno-dealing monster, what do I care what you think? For the last time, I don't like lilacs! Your 'first' wife was the one who liked lilacs!

Oh, how awful. Did he at least die painlessly? …To shreds, you say. Well, how is his wife holding up? …To shreds, you say. Why did you bring us here? No, I'm Santa Claus! Say what?

It doesn't look so shiny to me. Daylight and everything. I don't 'need' to drink. I can quit anytime I want! Well, then good news! It's a suppository.

What are their names? Ugh, it's filthy! Why not create a National Endowment for Strip Clubs while we're at it? We'll need to have a look inside you with this camera. They're like sex, except I'm having them!

Tell her you just want to talk. It has nothing to do with mating. Stop it, stop it. It's fine. I will 'destroy' you! I decline the title of Iron Cook and accept the lesser title of Zinc Saucier, which I just made up. Uhh… also, comes with double prize money.

Tell them I hate them. Soon enough. That's the ONLY thing about being a slave. Yeah, I do that with my stupidness.

I am Singing Wind, Chief of the Martians. Yeah, and if you were the pope they'd be all, "Straighten your pope hat." And "Put on your good vestments." You, a bobsleder!? That I'd like to see! Stop! Don't shoot fire stick in space canoe! Cause explosive decompression!

I'll tell them you went down prying the wedding ring off his cold, dead finger. No. We're on the top. Yep, I remember. They came in last at the Olympics, then retired to promote alcoholic beverages! There's one way and only one way to determine if an animal is intelligent. Dissect its brain!

In your time, yes, but nowadays shut up! Besides, these are adult stemcells, harvested from perfectly healthy adults whom I killed for their stemcells. Oh Leela! You're the only person I could turn to; you're the only person who ever loved me.

You, a bobsleder!? That I'd like to see! For the last time, I don't like lilacs! Your 'first' wife was the one who liked lilacs! What kind of a father would I be if I said no? Oh yeah, good luck with that.

Tip

Make sure to change the author on the post so your postlist picks it up!

We tell Sphinx this is a blog post by including the ..post:: directive. This is the only thing you have to include but like the postlist directive you can include more options which you can find detailed on the Posting and Listing - Post Directives page.

Save that in your posts directory, and rebuild your website! Now we should have some content available:

../../../_images/ruby-hammerhead-6.jpg

️🎒 Adding a Static Page

While we are adding content, let’s also add a static page that we can introduce ourselves! To do this, all we need to do is add a page called about.rst in the root of our directory, so our directory tree will look like:

project-directory
    _build/
    _static/
    _templates/
    blog
        sample-blog.rst
    about.rst
    conf.py
    index.rst
    make.bat
    Makefile

Unlike the blog post we don’t need to include any special directives, we can put our content straight into the file! Here’s an example that you can build off:

A Little Bit About Me
=======================

Hello everyone 👋🏼! This page is a bit about me!

Before we can make and build out website we need to add it to our index page, otherwise we won’t be able to navigate to it like so:

Recent Posts
=============

.. toctree::
   :maxdepth: 1
   :caption: Contents:

.. postlist:: 10
   :author: errbufferoverfl
   :date: %Y-%m-%d
   :format: {date} - {title}
   :list-style: none
   :excerpts:
Recent Posts
=============

.. toctree::
   :maxdepth: 1
   :caption: Contents:

    about

.. postlist:: 10
   :author: errbufferoverfl
   :date: %Y-%m-%d
   :format: {date} - {title}
   :list-style: none
   :excerpts:

Make sure you preserve the empty line between the :caption: Contents: and the about or Shpinx won’t include the link. 😢

Hint

A neat feature of Sphinx, is if you build your site and forget to include a reference to a page, Sphinx will warn you:

pickling environment... done
checking consistency... /Users/errbufferoverfl/ruby-hammerhead/about.rst: WARNING:
document isn't included in any toctree

Your site will now have an about tab in the top navigation bar:

../../../_images/ruby-hammerhead-7.jpg

🙌🏻 Congrats! You’ve now successfully started on your journey to making a blog using Sphinx and ablog! While you’ve reached the end of today’s tutorial, in the next entry I will walk through how we can apply some CSS and we’ll start to add some advanced Sphinx configuration.

👋🏻 Cya next time!