A Python-based static blog engine
Python CSS
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
example
src
themes
LICENSE
README.md

README.md

Pystable

Pystable is a static blog engine written in Python. It is inspired by Steve Kemp's Chronicle, a simple blog compiler, written in Perl with minimal dependencies.

Edit your posts as Markdown files, add some information, and Pystable converts everything into a complete static web page. An example web page can be found here

Requirements

You need to install markdown2 to use Pystable:

pip install markdown2

Configuration

In your posts directory you need a configuration file named site.config with the following content:

# This is the configuration file for our website
[info]
title = Blog Title
subtitle = Blog Subtitle
author = the Author
aboutme = Something about the author
info = Put some information about this site here 
[config]
theme = simple
syntax = markdown
url = http://www.example.com
output = ./
[contact]
twitter = <your twitter name | or empty>
email = <your email address | or empty>
facebook = <your facebook facebook URL suffix | or empty>
google+ = <your google+ account | or empty>
linkedin = <your linkedin user name | or empty>
github = <your github user name | or empty>

Configure this file to suit your needs.

Usage

After adding your individual posts as text files (*.txt) like in this example

date: 2014/11/25
title: My first post
tags: posts, first

First of all bla blubb.

you can run Pystable on your posts directory

python src/pystable.py my_posts

Now, you just need to upload the output directory as defined site.configto your web page.

How it works

Apart from markdown2 all packages are pure Python libraries.

The config file

To parse the configuration file we use SafeConfigParser provided by the ConfigParser package.

# Example
parser = SafeConfigParser()
parser.read('site.config')
site_title = parser.get("info","title")

The post file

In each text file that contains a post has the form

+------------------+
| meta information |
|                  | <- blank line
|     content      |
+------------------+

where the content is separated by a blank line from the meta information (title, date, and tags). Meta information is read into a Python dictionary:

meta_dict = { k.lower().strip():v.strip() for k, v in dict(s.split(':',1) for s in meta).iteritems()}

A post is then a Python dictionary with keys meta and content. We furthermore parse for tags and date (year and month) which we need later on for archive and tag cloud, part of the web page's sidebar.

Component layout

For our layout we define some HTML construction blocks: header.tmpl, post.tmpl, sidebar.tmpl, and footer.tmpl. From these blocks we create the elements of the full web page using main.html.tmpl and the parsed content of the individual posts provided. For parsing we use Template from the string package like this:

header_tmpl = open(theme+'/header.tmpl','r')
lines = header_tmpl.readlines()
header = ""
title = '<a href="url/to/index.html">'+site_title+'</a>'
for l in lines:
    s = Template(l)
    header += s.safe_substitute(title=title, subtitle=site_subtitle)
header_tmpl.close()

Structure of a pystable-generated web page

+-----------------------------------------+\
|            main.html.tmpl               |               +-----------+
|  +-----------------------------------+  |  \            |           |
|  |              header.tmpl          |  |               |  archive  |
|  +-----------------------------------+  |    \     +----------+     |
|  +------------------+ +--------------+  |          |          |     |
|  | +-post 1-------+ | |              |  |      \   |   tags   |     |-----+
|  | |   post.tmpl  | | | sidebar.tmpl |  |    +-----------+    |-----+     |
|  | +--------------+ | |              |  |    |           |    |  | post 1 |--+
|  | +-post 2-------+ | |              |  |    | main page |    |  |        |  |
|  | |   post.tmpl  | | |              |  |    |           |----+  |        |  |--+
|  | +--------------+ | |              |  |    |           |       |        |  |  |
|  |    ...           | |              |  |    |           |       +--------+  |  |
|  | +-post N-------+ | |              |  |    +-----------+           |       |  |
|  | |   post.tmpl  | | |              |  |      /                     +-------+  |
|  | +--------------+ | |              |  |                              |        |
|  +------------------+ +--------------+  |    /                         +--------+
|  +-----------------------------------+  |   
|  |            footer.tmpl            |  |  /
|  +-----------------------------------+  | 
+-----------------------------------------+/