Since having switched from the PHP world to the Python world about 2 years ago, I thought about relaunching my Blog using Python instead of PHP. At first, I thought about creating an application with Django and PostgreSQL, but never really had the time and motivation to finally implement it. But today I stumbled over rstblog by Armin Ronacher.
Meet rstblog
It is basically a static reStructuredText to HTML converter. You create a year/month/day folder structure, create .rst files in there, add metadata to them in YAML format and run the generator-script.
Because it's static, you don't need any dynamic webserver or interpreter, it's just plain HTML files that you can serve practically everywhere. You can even track them using a source control system. And last but not least – you'll never have to update your Wordpress installation again, yay!
rstblog supports everything a blog needs: detail pages, archive pages, tags, atom feeds and comments (using Disqus). You can create custom stylesheets and templates.
You can also embed syntax highlighted code using pygments:
class Bar(object):
def foo(bar):
print 'I don\'t like spam!'
And LaTeX formulas:
There's even more to like. If you want to know more, take a look at the repository and the sourcecode. That's also one of the downsides – there's no official documentation and the project seems pretty inactive, pull requests aren't being merged.
To get started, here are some related blogposts:
Publishing Content
To easily publish content, I use Fabric and rsync. Some easy fab tasks simplify the workflow:
import time
from fabric.api import local, env
from fabric.contrib.project import rsync_project
env.hosts = ['dbrgn.ch']
env.path = '/var/www/dbrgn/blog/'
def push():
local('git push')
def serve():
local('run-rstblog serve')
def build():
# Build HTML
local('rm -rf _build/ && run-rstblog build')
# Generate sitemaps
local('python gensitemap.py > _build/sitemap.xml')
# Minify CSS
local('cssmin < _build/static/style.css > _build/static/style.min.css')
local('mv _build/static/style.min.css _build/static/style.css')
local('cssmin < _build/static/_pygments.css > _build/static/_pygments.min.css')
local('mv _build/static/_pygments.min.css _build/static/_pygments.css')
# Add timestamp to css files
local('find _build -type f -exec sed -i "s/\(link.*\)' + \
'style.css/\\1style.css?%s/g" {} \;' % int(time.time()))
local('find _build -type f -exec sed -i "s/\(link.*\)' + \
'_pygments.css/\\1_pygments.css?%s/g" {} \;' % int(time.time()))
def sync():
rsync_project(remote_dir=env.path,
local_dir='_build/',
delete=True,
exclude=['*.py', '*.pyc', 'requirements.txt'])
def deploy():
build()
sync()
def publish():
deploy()
push()
You can see the entire fabfile on Github. The sitemaps are generated by gensitemap.py.
By issueing a simple fab publish in the root directory, the following steps are taken:
- The _build directory is (re)built
- Sitemaps are generated for each .html file
- CSS files are minified in-place
- A timestamp is appended to all CSS file names to make browsers reload cached content
- The _build directory is deployed to the server
- The git repository is pushed to Github
This Blog
Besides the blog-related technical details, this blog will from now on focus mostly on technical content, usually written in English, mostly about Python / Django / Linux / Programming related things.
The blog repository is published on Github. Content is under a CC by-sa 3.0 license.