This is the second article in a series about setting up my own website using a Static Site Generator. For other articles in the series, click on the title of the article under the heading “Static Site Generators” on the right side of the webpage.


In the previous article, I decided that the Pelican Static Site Generator (SSG) was the right choice for me. This article goes through the steps that I took in setting up Pelican on my system, providing a play-by-play for anyone thinking of doing the same thing. Feel free to use this as a guide for setting up your own website to experiment with. If you are not using this as a guide, I hope it provides you with any details that you require for regarding Pelican and it’s setup.

From my experience, it is more important for me to make a small step forward and lay a good foundation for what comes next than it is to take leaps and bounds and miss things. Hence, I feel that focusing on the setup of Pelican is a good and properly scoped step.

Why Another Pelican How-To-Guide?

In looking around, there was a real mish-mash of articles out there:

The first thing that was obvious to me was that all of the Pelican posts I found were written in 2017 or earlier. This means that these articles refer to versions of Pelican before the current 4.0.1 release that I am running, so they are either out of date or inaccurate.

The second thing that was obvious was there were very few posts written about using Pelican on a Windows machine. According to the site, Windows machines account for over 87% of the desktop machines surveyed. While it is true (from experience) that developers prefer Macs over Windows, projects like WSL are starting to chip away at those reasons. And it still remains that for a non-developer, Windows is by far the most common machine type. As it is my primary environment, I want to make sure it is represented.

Component Versions

If you are using this as a guide, you may try versions of any listed component other than those specified, but note that Your Mileage May Vary. This article was written from my detailed notes of how I set up my website, using the component versions listed. As such, if you experience any issues, I would fall back to those versions as an established baseline.

If you would like to try other versions of components, I strongly encourage you to go to the baseline established in this article and commit it to your local repository (see Step 5: Committing the Changes below). Once you have that point set and committed, you can then try and use other versions of the components, having a known state to return to. Regardless, keep detailed notes about what you try, and if you find yourself in a bad state, fall back to one of your previous known states and try again.

Operating System Paths

From long experience as a developer, there is virtually no sematic difference between pathing that is meaningful. Windows uses a format of C:\this\is\my\directory and Linux systems use /my-mount/this/is/my/directory. I personally work on both types of systems equally and do not have any issues switching back and forth between them.

One reason that I enjoy using Python over PowerShell, Bat/Cmd, and *Sh shells, is that I can properly obfuscate any such issues in my code. Python scripts can easily be written that are platform agnostic, eliminating duplicated scripts to handle platform issues. Add in to that additional support from editors such as VSCode and PyCharm, and it becomes a powerful scripting language with some real muscle behind it.

While I realize others may feel differently, I expect the reader to be able to perform the same translation task while reading, with practice if required.

Step 1: Install Pre-requisites

There is one pre-requisite for Pelican itself, and that is having Python 3.7 installed with a current version of Pip. The information in this post was generated with Python 3.7.3 and Pip 19.1.1.

As I have a great habit of fat fingering commands, I prefer to keep most of my files in a version control system, specifically Git. While I use Source Tree as a graphical interface to Git, I realize most people use the command line. Therefore, for the purpose of any examples, I will use the Git command line interface, assuming that anyone reading this who uses a Git GUI can find the appropriate command in their GUI if needed.

The commands I will be using in this article are as follows:

  • git init - Create an empty git repository.
  • git status - Working tree status of the current repository.
  • git add - Add a new file to the working tree.
  • git commit - Commit any changes to the working tree to the repository.

If you are new to Git or need a refresher, please go to the links about and do some searching online for examples. These are some of the base concepts of Git, and should be understood before proceeding.

With respect to how to install Python and Git/SourceTree, there is plenty of information on how to install those programs for each platform. Please google Python install, Git install, and SourceTree install for the best installation instructions for a given platform. For the Windows system I am using, I simply downloaded the installations from the websites linked to in the previous 2 paragraphs.

After installing Python on my system, the installation of required packages was very simple. At the command prompt, I entered the following line:

pip install pip==19.1.1 virtualenv==16.6.0

The two packages installed were the Pip Package Manager itself and the virtualenv package. The first installed package, pip, makes sure that Python’s own package manager is at the specified version. While pip does not often change meaningfully and I am not planning on using any new features, it usually pays to keep things current.

The second one is a virtual environment system for Python. Virtualenv is a Python tool that allows you to isolate a given Python project. While it is not portable between different systems, it does provide for a manner in which to isolate different versions of Python and different versions of Python packages from each other. Using virtualenv will allow me to install a specific versions of Python and each package with no fear of any global changes affecting this project.

To verify that I have the correct version of pip and virtualenv installed, I executed each tool with the –version parameter, expecting to see output similar to the following:

XXX> pip --version
pip 19.1.1 from XXX\lib\site-packages\pip (python 3.7)
XXX> virtualenv --version

After these pre-requisites were installed, I was ready to create a directory to host the content for the website.

Step 2: Create a Project Directory For The Site

Before generating content, I needed to create a place to install Pelican that was isolated and self-contained. As mentioned in the previous section, that is exactly the use case that the Virtualenv program was created for. That is the first of the two tools that I needed to set up for the new directory.

The other tool is version control, to ensure I can replicate and version the website. For this purpose, I use Git. The first thing this accomplishes is to ensure that if the computer hosting the website content gets destroyed, I still have the latest information about the website. The other thing that this accomplishes is to ensure that if I make a change (or two, or three) to the website that I don’t like, I can always return back to previous versions of any of the documents.

That out of the way, I selected a directory as a location of the website. In my case, I keep all of my local Git repositories in a directory c:\enlistments, so I created the directory I wanted to keep the website in was c:\enlistments\blog-content. The location is totally arbitrary, so for the sake of clarity, if I refer to this directory indirectly, I will use the term base project directory. If I refer to this directory directly in a script, I will use the pattern %%%MY_DIRECTORY%%%.

To create the base project directory, I executed the following commands in order:

mkdir %%%MY_DIRECTORY%%%
git init
virtualenv virtualenv

In order of execution, the commands first create a directory and then changed the current directory to that directory. Once the base project directory was created, git init was used to create an empty Git repository with nothing in it, ready for the project to populate. Next, virtualenv virtualenv was used to create a virtual environment for the website, housing that environment in the virtualenv directory of the project.

Finally, the activate script of virtualenv was executed to enable the virtual environment. The script activate.bat on my Windows platform ( on Linux platforms) performs two simple tasks: change the shell’s path to use the virtual environment AND change the path to make sure that change is evident. To be sure, I checked the PATH environment variable to make sure it starts with the Python path of the project’s virtual environment and that the prompt started with (virtualenv).

Note that while I used git init to create a local repository, I was still getting started with the project. As such, I didn’t need to worry about ensuring that the local repository is reflected in a remote repository. At that point, the purpose of having the local repository was to ensure that I could see what changed and revert back to previous versions if needed.

If you are using this as a guide, please note that from this point forward, any commands that I entered were entered in the virtual environment shell. If for some reason you close your shell and need to restore the shell to where you were, you will need to open a new shell and submit the following commands:


I had a good directory ready to go, but I had one small issue to fix. When I submitted the git status -s command, I encounter the output:

?? virtualenv/

As mentioned above, the virtual environment is specific to a given operating system and version of Python. Because of this, committing the virtualenv directory to Git didn’t make sense, as it contains system specific information. Luckily, this issue was easily addressed by creating a file in the base directory called .gitignore with the contents:


The format of .gitignore is pretty simple to understand. In my case, I only wanted to ignore the virtualenv directory off the base project directory, so I just needed to add that directory to the .gitignore file. Submitting the git status -s command again, I then saw the output of:

?? .gitignore

This showed me that Git is ignoring the entire virtualenv directory, instead showing the .gitignore file that I just created. Since I have only done limited setup in the base project directory, having only the .gitignore file showing up as untracked is what I expected. To be safe, I used the git add and git commit commands to save these changes as follows:

git add .gitignore
git commit -m "initial commit"

The directory was ready, time to focus on Pelican.

Step 3: Install Pelican

Pelican itself is installed as a package using Python’s Pip program. Based on information from Pelican’s Installing page, both the markdown and typogrify package are useful, so I installed them as well.

The markdown package allows for content authoring with Pelican using using Markdown. Using a simple text file, special annotations can be placed in the text that alter how it will look when rendered with a Markdown processor. The full range of Markdown annotations and their effects are shown here. As this is one of the requirements I established in the previous page, this support was critical.

The Typogrify package “cleans” up the text to make it look more professional. It accomplishes this by wrapping certain blocks of text in HTML span tags to allow for CSS styling. In addition, it replaces certain sequences of characters with other sequences that add polish to the finished document. While not required to get the site up and running, I figured it would be of use later.

To install these three packages, I submitted the command:

pip install pelican==4.0.1 markdown==3.1.1 typogrify==2.0.7

This resulted in the installation of any dependent packages, is essence, going from the stock packages (displayed using pip list) of:

Package    Version
---------- -------
pip        19.1.1
setuptools 41.0.1
wheel      0.33.4


Package         Version
--------------- -------
blinker         1.4
docutils        0.14
feedgenerator   1.9
Jinja2          2.10.1
Markdown        3.1.1
MarkupSafe      1.1.1
pelican         4.0.1
pip             19.1.1
Pygments        2.4.2
python-dateutil 2.8.0
pytz            2019.1
setuptools      41.0.1
six             1.12.0
smartypants     2.0.1
typogrify       2.0.7
Unidecode       1.0.23
wheel           0.33.4

To make sure that I would be able to keep these libraries at their current versions in the future, I needed to take a snapshot and save it with the repository. Thankfully, this is a scenario that the Pip contributors though of. On the command line, I typed in:

pip freeze > requirements.txt

This command produces a terse list of each package and it’s version, which I redirected into the file requirements.txt. The benefit to doing this is that, at any time, I can execute the following command to restore the packages and versions:

pip install -r requirements.txt

Step 4: Create a Generic Web Site

Now that Pelican is installed and ready to go, I needed to enact the templating system of Pelican to form the basis of my website. The authors of Pelican have kept this simple. All I needed to do is run the command:


During the installation, I was asked a number of questions:

> Where do you want to create your new website? [.] website
> What will be the title of this website? Jack's Web Site
> Who will be the author of this website? Jack De Winter
> What will be the default language of this website? [English]
> Do you want to specify a URL prefix? e.g.,   (Y/n) n
> Do you want to enable article pagination? (Y/n)
> How many articles per page do you want? [10]
> What is your time zone? [Europe/Paris] America/Los Angeles
> Do you want to generate a to automate generation and publishing? (Y/n) n
Done. Your new project is available at %%%MY_DIRECTORY%%%\website

For a decent number of the questions, the defaults were sufficient. The questions that I answered specifically were:

  • website directory
  • keep the website isolated in a subdirectory, for future use
  • title
  • something simple for now
  • author
  • my name here
  • url prefix
  • No, we can change this later
  • time zone
  • I didn’t know this, so I entered in something silly, and it gave me an URL to a web page where I looked it up
  • generate
  • no, I will provide simple scripts for that

When this was completed, my base directory had a new directory website/ which contained 2 files and 2 directories. The first file had the settings that I entered using pelican-quickstart. The second file has any remaining settings that Pelican will use when publishing. If things change with the website, I just need to change the settings in these files, and the next time I publish, they will be in effect.

The 2 directories are the key here. The content directory was created to contain any files that are the source parts of the website. During the publishing action (covered in a subsequent post), Pelican will translate that content into output and place it in the other directory that was created, output directory.

Step 5: Committing the Changes

At this point, it was useful to use git add and git commit to commit what I did to the local Git repository, as there was useful progress. Entering the git status -s command, it reported that the only meaningful changes were that the website directory and the requirements.txt file were added. As both of these objects are considered source and configuration, I added them as follows:

git add requirements.txt
git add website
git commit -m "Base website"

If there was something that was added that was not part of source, configuration, or documentation for the website, I would have edited the .gitignore file to include a pattern that cleanly removed those changes from Git’s preview. When this comes up in future articles in this series, I will point out what I added and why.

What Was Accomplished

Having decided that SSGs were the correct paradigm for my website, and Pelican the correct SSG for me to use, it was time to set it up. I documented how I installed various components, as well as how I set up the base project directory for the website itself. Finally, I created a default website as a solid foundation for my purposes, and made sure that I committed the base project directory to Git for version control.

In my professional career, most of the time it is advantageous to build a foundation for your application, committing it to version control often. Having provided that foundation in this article, I can now proceed with the actual building of the website.

What’s Next?

Next, I will start with publishing a simple file to the website and make sure I check it online for any errors. By providing realistic samples and getting experience with the publishing workflows, I will get invaluable information on using Pelican. This task will be covered in the next post Posting My First Article.

Like this post? Share on: TwitterFacebookEmail


So what do you think? Did I miss something? Is any part unclear? Leave your comments below.

Reading Time

~12 min read


Static Site Generators


Integrating Technology


Stay in Touch