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
You need to install markdown2
to use Pystable:
pip install markdown2
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.
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.config
to your web page.
Apart from markdown2
all packages are pure Python libraries.
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")
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.
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()
+-----------------------------------------+\
| 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 | | /
| +-----------------------------------+ |
+-----------------------------------------+/