Building your own static website has several advantages over a traditional website that uses a database to store content. Static websites are faster because pages are rendered in advance and deliver the same content to all visitors. They are cheaper to host and are more secure since the website has no database. No advanced programming knowledge is required to build one: HTML & CSS will do.

Creating each page in a static website one-by-one and updating them when something changes would be very time consuming. Static site generators take a website's content, apply it to HTML-based templates and generate all of the required files ready-to-upload. There are many static website generators available on the web and which one you choose will depend on the language you are most comfortable with. I chose Pelican because of my preference for Python but Jekyll (Ruby) and Hugo (Go) are perfectly acceptable solutions as well.

This tutorial is part of a series which will walkthrough all the steps from installing Pelican to deployment on Github Pages (for free). I decided to create these tutorials after making my own website with Pelican.

Prequisites

All you need to know is a little bit of Python and have a basic understanding of HTML & CSS. We will be testing our website locally in this section so no knowledge of how to deploy to the web is required.

Goals

  • Install Pelican
  • Generate a static website
  • Setup the pelican-bootstrap3 theme

Creating A Project Skeleton

Let's begin by creating a new folder called blog. Then create two new folders inside the blog folder called output and source as shown below. Our Pelican project will be stored in the source folder. The static website generated by Pelican will be placed in the output folder.

blog
  └── output
  └── source

Next we need to install Pelican and Markdown. Markdown is a plain-text markup language we will be using to write the content for our website. Open the command line and type the following commands:

pip install pelican
pip install markdown

With our basic file structure in-place and Pelican/Markdown installed we are now ready to create our Pelican project. Navigate to the source folder using the command line and type:

pelican-quickstart

Pelican starts by asking us a series of interview questions to customize our website.

Where do you want to create your new web site? [.] .
What will be the title of this web site? Matthew Devaney's Blog
Who will be the author of this web site? Matthew Devaney
What will be the default language of this web site? [English] en
Do you want to specify a URL prefix? e.g., https://example.com   (Y/n) n
Do you want to enable article pagination? (Y/n) n
What is your time zone? [Europe/Paris] America/Winnipeg
Do you want to generate a tasks.py/Makefile to automate generation and publishing? (Y/n) n

How you choose to answer some of these questions will differ from myself:

  • Default language: choose any 2 letter code for languages from the ISO 639.1 guide.

  • Time zone: select your timezone from the Wikipedia list of tz database time zones.

  • Generate Tasks.py/Makefile: Mac and Linux machines can use the make command to automate deployment. However, I am using a Windows machine make is not available on Windows by default. You can try to install it but getting make to work on Windows is a non-trival exercise.

After answering the pelican-quickstart interview questions your source folder will look like this:

blog
  ├──  output
  └── source
       ├── content (folder)
       ├── output (folder)
       ├── pelicanconf.py
       └── publishconf.py

Here's what each of the newly created files do:

  • content (folder) - where website content will be stored
  • output (folder) - default location where static website files are generated to
  • pelicanconf.py - website settings file
  • publishconf.py - additional website settings used only when the website is published

Now that our basic project skeleton is setup we should generate our website and preview what it looks like. First, we must tell Pelican which folder to output the website to. By default it will be generated to blog/source/output but we wanted them to appear in blog/output instead. Delete the folder blog/source/output. Now open pelicanconf.py and add the following line:

OUTPUT_PATH = '../output'

Generate the website by using the following command while in the source folder. Ignore the warning that appears. It displays because we haven't written any articles for our website yet:

pelican content

Finally, run the following command while in the source folder. It will setup an http server on our local machine that will allow us to preview the website.

pelican --listen

To view our website open your web browser and go to the the address. http://127.0.0.1:8000.

some text

We have now successfully setup our basic Pelican project.

Installing The Pelican Bootstrap 3 Theme

In my opinion the standard theme that comes with Pelican has one huge flaw: it does not display properly on mobile devices. More than half of the world's internet traffic is mobile so we will want to use a theme that incorporates responsive web design principles. To accomplish this we will change our website to use the excellent pelican-bootstrap3 theme. To view the full listing of Pelican themes click here.

Start by creating a new folder called theme in the source folder.

blog
  └── source
       ├── content
       └── theme (new)

Now we need to tell Pelican where it can find the custom theme we will be using. Open pelicanconf.py and add the following line:

THEME = 'theme'

Next, go to GitHub and download the pelican-bootstrap3 theme. Place all pelican-bootstrap3 files into the blog/source/theme folder so it looks like this:

blog
  └── source
       ├── content
       └── theme
           ├── static
           ├── templates
           ├── translations
           | ...(more files)

With the theme in place now let's attempt to generate the site.

pelican content

Unfortunately, an error occurs.

CRITICAL: UndefinedError: '_' is undefined

The error is caused by a missing plugin i18n_subsites which is used by pelican-bootstrap3 to provide support for internationalization (i.e. i18n). We must download the i18n_subsistes plugin from Github and in include it in our project. To view the full listing of available Pelican plugins click here.

Add another folder inside the source called plugins. Place the i18n_subsites folder and files you downloaded from Github into the plugins folder:

blog
  └── source
       ├── content
       ├── plugins (new)
       |   └── i18n_subsites (new)
       └── theme

We must tell Pelican where the plugins folder is located just as we did for the theme folder. Open pelicanconf.py and add the following line.

PLUGIN_PATHS = ['plugins/', ]

A typical Pelican website will utilize many different plugins to extend its capabilities. Each plugin must be setup individually within pelicanconf.py. The PLUGINS variable contains all plugins being used by the website. Open pelicanconf.py and add the following line.

PLUGINS = ['i18n_subsites', ]

Try to generate the website once again. You will get a different error this time.

pelican content

CRITICAL: UndefinedError: 'gettext' is undefined

The i18n_subsites plugin relies on a language called Jinja2. To properly configure the i18n_subsites plugin we must also add the JINJA_ENVIRONMENT variable to pelicanconf.py as shown below.

JINJA_ENVIRONMENT = {
    'extensions': ['jinja2.ext.i18n'],
}

Now that we have properly configured the bootstrap3 theme and its dependencies our website will generate successfully.

pelican content
pelican --listen

View the latest version of our website at http://127.0.0.1:8000. Notice when you expand and shrink the width of the web browser window the website layout changes to fit? By selecting a theme that incorporates responsive web design principles our website will be viewable on screens of all shapes and sizes.

some text

The pelican-bootstrap3 theme comes with several options to change the style of our website. To view the full list of available themes go the folder blog/source/theme/css. You will see several files with the filename bootstrap.(some name).min.css. We will be using the the bootstrap.flatly.min.css file to style our website. Open pelicanconf.py* and add the following line. Take a moment to try out some other options if you'd like to see what's available.

BOOTSTRAP_THEME = 'flatly'

At this time we can also change the style for code blocks we may write in our blog posts. Pelican displays code blocks using the Pygments code highlighter. To view a full list of the available Pygments styles go to the folder blog/source/theme/css/pygments. Our website will use monokai.css to style code blocks. Add the following line to pelicanconf.py.

PYGMENTS_STYLE = 'monokai'

Let's update the sidebar too with our own preferred links and social pages. You can use the websites shown below or choose your own. Update the following line in pelicanconf.py

LINKS = (('Ars Technica', 'https://arstechnica.com/'),
     ('Wikipedia', 'https://wikipedia.org'),)

SOCIAL = (('Twitter', 'https://twitter.com/mbdevaney'),
         ('Github', 'https://github.com/yourekittenme'),)

Regenerate the website to see the impact of changing the style. Not all of the changes we made to the style are apparent at this time because our website does not yet have any content. In the next section of this tutorial we will learn how create articles and pages for our blog.

pelican content
pelican --listen

some text

Next Steps

In this tutorial we learned how to install Pelican, generate a static website and apply the pelican-bootstrap3 theme. Take a quick break then head on over to the next lesson to learn how to create content.

Series

This article is part of a series of tutorials that will show you how to create static websites with Pelican And Python


Comments

comments powered by Disqus