Static blog generator from markdown files.

What is it again?

It's a simple script that takes your markdown files and converts them to HTML and CSS only blog. No backend, no JS. Pure bliss.

Why, tho?

I been rewriting my blog base so much, and I never was satisfied. First I made my whole blogging platform in PHP 5. Then I did what I did right now, but in PHP 5 again. But it was in PHP and was server-side. I didn't want that.

Then I made blogging platform on django, but the deploy and updates were painful. I didn't like that.

Blogs are supposed to be simple text + images, no? Why bother with all of that? Just write markdown, run python turblog.py, copy the html to your server and voila, that is that.

Who is this for?

This is not intended for non-programming users. The script doesn't allow for much customization, it is designed to read a folder structure with your posts and pages in .md, CSS and images (and if you want to, JavaScript) and convert that to another folder filled with html and your static stuff.

It serves one simple purpose and that's that.

How do I install it?

It's just one file. A script. It's not a library. Not a framework. Just a script.

It does have dependencies though:

  • python-markdown2 - for parsing markdown;
  • Pygments - for colorful code in your blog;
  • PyRSS2Gen - for RSS feed generation.

Use pip or whatever else to install those.

So, wait, I just execute it?

One of the first thing you'll see inside the script are a bunch of vars that serve as minimal config.

# ==================================
# Main config
# ==================================

PROJECT_DIR  = "project"
POSTS_DIR    = "posts"
PAGES_DIR    = "pages"
TEMPLATE_DIR = "templates"
WWW_DIR      = "www"
COPY_DIRS    = ["css", "img"]

SITE_TITLE   = "blog"
SITE_URL     = "http://localhost/"
SITE_DESC    = "my blog"
SITE_AUTHOR  = "your-name-here"
BASE_URL     = "/blog"

The script expects a project directory where all the other relevant directories reside.

  • posts directory are where you store the markdown blog posts, the script parses them and creates proper folder structure (based on date) and puts them there;
  • pages are where you store your static pages. Stuff like "About me" and such;
  • templates is where you store your html templates. More on them later;
  • www is the directory the script will put the built site;
  • You can put any static stuff that doesn't need processing into COPY_DIRS list, like CSS and images.

Then there are some basic configs that will effect links in the templates and RSS feed. I think they are self-explanatory.

MAX_POSTS_IN_INDEX decided how many posts are shown on main page before the link to archive is shown.


Templates are pretty simple and easy. Write anything between <% and %>, and you can replace it in code using template(text, dict) function. The dict is a key-value container where key is what you wrote inside the tag, and value has the text to replace it with. You can have multiple tags with the same name, they all will be replaced with the same text.






vals = {"TEXT": "My text goes here!"}
html = template(my_template_text, vals)


And that will produce, you guessed it:

<p>My text goes here!<p>


Posts have a bit of special syntax. First two lines are reserved. 1st line is the title of the post, 2nd is the date in YYYY-MM-DD format. After that feel free to write your markdown.


Pages too have special syntax. First two lines are reserved. 1st is the title of the page, 2nd is the type.

There are 3 types supported:

  • markdown - the page will be parsed with markdown, and html written.
  • html - the page will be written as is.
  • link - the body of the page is assumed to be pre-sanitized link. And will be just passed as is.


Go check my website, https://codebite.xyz/ You can also check the repo at: redpanda_ua/codebite-2018


If you really want to tell me something, shoot me an email at: dmytro.v.kaclhenko at gmail.com Otherwise feel free to open an issue, fork or do whatever you want.

Made by me, @redgek (C) 2018

Licensed under MIT license (see LICENSE for full text)