With so many blogs and descriptive how-to's out there1, 2, 3, 4, 5, one may be wondering as to why another post on Pelican static site generator. The purpose of this blog is to document building a static web site in Windows environment with Anaconda Python distribution.
This tutorial assumes very little, so we will cover each step in a little more details. Chances are that you have already heard about the the Python-powered micro web frameworks, static page generators, and even about Pelican, Nikola, or Flask. If not, this blog4 has a nice introduction.
Before we can get started, we’ll need to have a functioning installation of Python, and of course, Pelican. The following are the minimum requirements:
- Python 2.7.x or Python 3 (Python 2.7 is still preferred on Windows due to several dependencies, such as 'pycrypto', not available for Py3.6)
- Pelican package
- Text editor (e.g., Notepad++, Markdown Pad, Sublime Text)
- Web server for the web hosting
First, we need a Python installation. I recommend Anaconda or Miniconda Python Distribution from the Continuum Analytics.
Miniconda are free and the former comes with many pre-installed Python packages and libraries such as Pandas, NumPy, matplotlib, and others. However, the default packages do not include Pelican site generator.
If you already have
Python installed, skip to the section Virtual Environment.
To get Anaconda/Miniconda installed under the Windows, download the latest Anaconda and install the executable.
This tutorial is using Anaconda although steps with Miniconda are the same. The typical path to install Anaconda on Windows is:
C:\Anaconda. For more details on installation steps, see this YouTube video.
When installation completes, append the following string (without the quotes) into your system PATH:
" C:\Anaconda;C:\Anaconda\Lib;C:\Anaconda\DLLs;C:\Anaconda\Lib\lib-tk;C:\Anaconda\Scripts; "
To check that Anaconda has installed successfully, launch the Windows command shell (cmd.exe) and execute the command:
conda info --all
A typical output follows:
Current conda install: platform : win-32 conda version : 3.11.0-dirty conda-build version : 1.2.0 python version : 2.7.6.final.0 requests version : 2.7.0 root environment : C:\Anaconda (writable) default environment : C:\Anaconda envs directories : C:\Anaconda\envs package cache : C:\Anaconda\pkgs channel URLs : http://repo.continuum.io/pkgs/gpl/win-32/ http://repo.continuum.io/pkgs/gpl/noarch/ http://repo.continuum.io/pkgs/free/win-32/ http://repo.continuum.io/pkgs/free/noarch/ config file : $HOME\.condarc is foreign system : False conda environments: - envs listed here- root * C:\Anaconda sys.version: 2.7.6 |Anaconda 1.9.1 (32-bit)| (default... sys.prefix: C:\Anaconda sys.executable: C:\Anaconda\python.exe conda location: C:\Anaconda\lib\site-packages\conda conda-build: C:\Anaconda\Scripts\conda-build.bat conda-convert: C:\Anaconda\Scripts\conda-convert.bat conda-env: C:\Anaconda\Scripts\conda-env.exe conda-index: C:\Anaconda\Scripts\conda-index.bat conda-skeleton: C:\Anaconda\Scripts\conda-skeleton.bat
Set up a virtual environment
To avoid potential Python library/package dependency conflicts, it is a good practice to install new projects into their own development environment. Such environment includes a fresh copy of the Python binary together with a copy of the entire Python standard library. Let's create a virtual environment called
conda create -n pelican1 python=2
The expected response is shown in Figure 1 and Figure 2.
Fig. 1. Creating virtual environment
Fig. 2. Packages installed in the virt env
Activate the new environment as:
> activate pelican1
if everything went as expected, you should see the following text at the command prompt:
[pelican1] c:\Anaconda >pip install pelican
The progress will look similar to the following output.
Downloading pelican-3.6.2-py2.py3-none-any.whl (129kB) Downloading Pygments-2.0.2-py2-none-any.whl (672kB) Downloading feedgenerator-1.7.tar.gz Downloading Unidecode-0.04.18.tar.gz (206kB) Downloading pytz-2015.4-py2.py3-none-any.whl (475kB) Downloading python_dateutil-2.4.2-py2.py3-none-any.whl (188kB) Downloading six-1.9.0-py2.py3-none-any.whl Downloading Jinja2-2.8-py2.py3-none-any.whl (263kB) Downloading docutils-0.12.tar.gz (1.6MB) Downloading blinker-1.4.tar.gz (111kB) Downloading MarkupSafe-0.23.tar.gz Installing collected packages: pygments, pytz, six, feedgenerator, unidecode, py thon-dateutil, markupsafe, jinja2, docutils, blinker, pelican
Other Python packages
Following are packages that I found useful when developing and publishing Pelican blog site. To make their installation easier, we will use the
Open a text editor and type (copy/paste) the following content.
beautifulsoup4~=4.3.2 feedgenerator~=1.7 html5lib~=0.999 Markdown~=2.5.2 Pygments~=2.0.2 pyreadline~=2.0 smartypants~=1.8.6 typogrify~=2.0.7 gitpython
Save the file as
Requirements.txt into the folder
Next, from the shell, issue the following command:
[pelican1] c:\Anaconda>pip install -r c:\Anaconda\envs\pelican1\requirements.txt
To build, publish, and maintain the site, I use the Fabric Python library. To avoid complications with C++ compiler on Windows, use the Binstar package:
[pelican1] c:\Anaconda>conda install -c https://conda.binstar.org/binstar fabric
The following packages will be installed.
Note that pycrypto package may require compilation of C++ source, on Windows use MinGW or search for pycrypto binaries for your Python version.
ecdsa: 0.11-py27_0 fabric: 1.10.1-py27_0 paramiko: 1.15.2-py27_0 pycrypto: 2.6.1-py27_3
At this point, the size of
pelican1 environment is about 100Mb.
So far, all packages were installed in the
C:\Anaconda\env\pelican1\ folder. The actual blog files require different drive/folder location from which the site is managed. Let's create such directory, for example,
Now, while still in the
pelican1 virtual environment, cd into this directory:
[pelican1] c:\Anaconda\envs\pelican1 >cd c:\demo\pelicanblog
To initiate this new blog/web site, run the quickstart script and answer the setup questions. Note that I have chosen not to use GitHub Pages and secure SSH protocol for upload. The latter will be addressed below.
[pelican1] C:\demo\pelicanblog> pelican-quickstart
> Where do you want to create your new web site? [.] (just press enter; it will be in the /pelicalblog directory; in this case c:\demo\pelicanblog) > What will be the title of this web site? Blogging with Pelican > Who will be the author of this web site? your name > What will be the default language of this web site? [en] > Do you want to specify a URL prefix? e.g., http://example.com (Y/n) y > What is your URL prefix? (see above example; no trailing slash) http://www.yourdomain.com/blog > Do you want to enable article pagination? (Y/n) y > How many articles per page do you want?  8 > What is your time zone? [Europe/Paris] America/Phoenix > Do you want to generate a Fabfile/Makefile to automate generation and publishing? (Y/n) y (create fabfile.py) > Do you want an auto-reload & simpleHTTP script to assist with theme and site development? (Y/n) y > Do you want to upload your website using FTP? (y/N) y > What is the hostname of your FTP server? [localhost] ftp.yourdomain.com > What is your username on that server? [anonymous] username > Where do you want to put your web site on that server? [/] /blog > Do you want to upload your website using SSH? (y/N) n > Do you want to upload your website using Dropbox? (y/N) n > Do you want to upload your website using S3? (y/N) n > Do you want to upload your website using Rackspace Cloud Files? (y/N) n > Do you want to upload your website using GitHub Pages? (y/N) n
A little more explanation on the "URL prefix" question. Answer yes and enter URL in the next step only if you have external web hosting site.
Let’s take a look at the just created folder structure within the
c:\demo\pelicanblog directory. Now if you type the tree command within your blog's main directory, you should see a directory tree similar to this one:
pelicanblog/ ├── content │ └── firstblog.md ├── output │ ├── author/ │ ├── category/ │ ├── tag/ │ ├── theme/ │ ├── archives.html │ ├── authors.html │ ├── Blogging with Pelican.html │ ├── categories.html │ ├── index.html │ └── tags.html ├── fabfile.py ├── pelicanconf.py └── publishconf.py
Breaking down each of these files:
- content/firstblog.md: A content file in Markdown syntax. This is where you start writing your blog.
- output/: Content of this folder is automatically generated and later uploaded to a server.
- fabfile.py: Is a configuration file for
Fabric, which allows you to generate your site using the fab command.
- pelicanconf.py: Is a Pelican configuration file containing the site settings.
- publishconf.py: Similar to pelicanconfig.py file, but is not intended to be used for local development.
Building the site
Now let's build the default look of the blog. In your terminal, type the
fab command after the > character:
[pelican1] C:\demo\pelicanblog>fab build
[pelican1] C:\demo\pelicanblog>fab serve
We've just launched a local webserver on the port 8000. Open your browser and navigate to http://localhost:8000 the default skeleton and template should display in your browser.
Fig. 3. Final view of the site.
To avoid repetitive typing in the terminal, set up a batch file, which will get you directly to the [pelican1] C:\demo\pelican environment and directory.
Save the following script as
pelican.batand place the file into C:\Windows\System32 directory.
@echo off REM add this batch file into C:/windows/system32 REM run upon opening cmd as >pelican.bat set SERVE=C:\demo\pelicanblog cd /D %SERVE% activate pelican1
Next time, upon launching the command line terminal (cmd.exe), just type
pelican.bat and the script will execute.
To change or tweak the site settings, edit files
fabfile.py created in the main
# pelicanconf.py from __future__ import unicode_literals AUTHOR = u'yourname' # Change it here SITENAME = u'Blogging with Pelican' # Change it here SITEURL = '' PATH = 'output' # This is where you write blogs, keep images, css, .. TIMEZONE = 'America/Phoenix' # Change it here DEFAULT_LANG = u'en' # other functions (default)
# fabfile.py # default variables and functions follow # ... # Added site upload function to circumvent setup of rsync on Windows env.hosts = ['ftp.yourdomain.com'] env.user = "username" env.password = "serverpassword" # or just entered it when connecting from fabric.context_managers import cd def sftp(): # run from the parent directory /pelicanblog/ with lcd('output'): # cd into output directory local("dir") # list files and directories to be uploaded put('*', './public_html/yourblogdirectory/') # change here
sftp() function added at the end of the
fabfile.py. The default
publish() function is based on
rsync utility that is not that easy to install on Windows. Instead, we can use the SSH File Transfer Protocol (sftp) protocol, which is also secure an simple to implement.
Markdown .md file
Title: First Blog Post Date: 2015-8-08 13:10 Category: Blogging Tags: blogging, markup Slug: Blogging with Pelican Author: yourname Summary: Collection of notes related to programming and scripting. Latex: # Work in progress # Following are examples of Pelican markup. This is a **first** attempt to create static page with the help of _Pelican_.
Rendering and uploading the site
At this point, we will move back to the terminal and issue the following commands.
[pelican1] C:\demo\pelicanblog>fab build [pelican1] C:\demo\pelicanblog>fab serve
Now, in the browser type http://localhost:8000 and our modified (local) site should load.
To upload it to a web-server, make sure that you create your blog directory at the remote site first. Note the path to it, e.g. /public_html/yourblogdirectory. Enter your host name and user name into the
fabfile.py file. In your terminal, enter:
[pelican1] C:\demo\pelicanblog>fab sftp
Upload process should start immediately with a list of files to be uploaded and a prompt for your password. After the upload is done, head to the site and check its accessibility.
And we are done
This concludes the process of setting up a simple Pelican site on Windows and Python Anaconda environment. We have built the skeleton of Pelican static web-site in Python virtual environment, modified its configuration files, and uploaded the site to our hosting server. Pelicanblog files can be downloaded from here. This blog is built with Pelican as well and it is styled with customized Pelican-bootstrap3 theme.