> home / projects / Simple SSG Script



A look at the very simple, messy, wholy hobbyist script bashed to gether to generate this site.


For the past two months I’ve been playing around with the idea of making a webpage. A place to collect all the links, articles, ideas, thoughts and ramblings that seem to be cluttering up my harddrive.

Wordpress seemed like the obvious choice—having used it in the past to run the University newspaper site—only one problem: time and security. With the plethora of botnets, security issues, and “things that just break when you update them” it would be an incredible hassle. The last thing I want is for my slice of the server to be used to sell herbal viagra and timeshares. Secondly, I wanted something that was easy to backup, easy to re-deploy and 100%-ish within my current level of technological knowledge. A static site in other words, a collection of HTML pages served up as is. Only thing is it is a pain-in-the-neck to go the 90s route and write it all by hand.

I looked into using a static site generator such as Jekyll or Pelican — both of which I tried in the past and found not entirely to my liking (I’m a fickle spoiled nerd). Enter the insane plan of making my own static site generator — closely followed by the realization I would need a much simpler script to just tide me over until the ssg is done (as I’ve spent the last month bashing out poorly formatted python code and getting frustrated trying to get it right).


The script is written in Python (as it is the only language I am comfortable using) and, in the interest of making it quick and simple, relies on the Linux commandline and Pandoc to do all the heavy lifting. The final ssg is (hopefully) going to rely entirely on Python libraries.

There are a lot of features I would like for the site, such as a blog with tag support, some form of comment section and an automated menu system for navigating around the site. None of these are in the script however as it’s only purpose is “get something functional up and running asap”.


The script is actually two scripts: - new_page.py - simple_gen.py

The new_page.py script simply makes a new directory, copies the simple_gen.py script into the new directory, and creates the first markdown file.

simple_gen.py is the script that does the heavy lifting. It gets a list of all markdown files in the directory, then organizes them in order (hence why the filenames start with 1_, then 2_, 3_, etc) and run them through pandoc to get the finalized html document. This enables me to split a larger page into sections, for quicker editing and changes. Not to mention it makes it easier to automate adding new bits (just an idea for now, may implement it if I make another version of the script). When the script is run, you enter the title of the page, and the anchor-link back to the home page

The Pandoc command uses a template I made and put in the Pandoc template directory (/usr/share/pandoc/data/templates/), it lacks pretty much all the functionality of the default pandoc html template but it works. I’ve been trying to get the –data-dir= command to work, so the templates could be stored in the same folder as the scripts, but haven’t managed to get it right yet.


The new_page.py script:

import os
new_name = str(raw_input(str('Please enter the page name:')))
new_name = new_name.replace(' ','-')
os.system('cp simple_gen.py ' + new_name)
os.system('touch 1_.md')
os.system('mv 1_.md ' + new_name)

The simple_gen.py script:

# coding: utf-8
# Simplest generator.
# Just put the file to be generated in the same directory as the script and go.

# IMPORTANT: currently only makes "pages". There are no blog posts yet.

import os

# :: declaring global stack used for all variables
stk = dict()
# :: get the title and html filename
stk['title'] = str(raw_input('HTML safe (spaces allowed) page title (just enter if index.html): '))
if stk['title'] == '' or stk['title'] == '\n':
   stk['title'] = 'index'
stk['html-title'] =  str(stk['title']).replace(' ', '-') + '.html'
# :: generate the metadata to be used for the page generation
if stk['title'] != 'index':
   stk['metadata_title'] = '\"title:%s\"' % (str(stk['title']).replace('-', ' '))

# :: add custom markdown to the top of the page
if stk['title'] != 'index': # no need for a menu back home on the home page.
   if os.path.isfile('0_menu.md') == True:
      os.system('rm 0_menu.md')
   with open('0_menu.md','w') as ofile:
      ofile.write('<div id="menu"> &gt; [home](/index.html)')
      # :: index.html anchor link
      ln = raw_input('[type:anchorlink in index.html]: ')
      ln = ln.split(':')
      ln = ' / [%s](/index.html#%s)' % (ln[0], ln[1])
      ln = raw_input('page title: ')
      ln = ' / [%s](./%s)</div>' % (str(ln),str(stk['html-title']))

# :: get a list of the markdown files in the directory (assuming a 1_, 2_, 3_ naming scheme)
tmp = os.popen('ls -R |grep "\.md$"').read().split('\n')
# :: remove empty item as assuming one empty item in list.
if '' in tmp:
# :: add the markdown filelist to the stack and delete the tmp variable
stk['md_f_list'] = tmp
del tmp

# :: sort the markdown list 

# :: setup the pandoc command
# :: add the formatting for the list items
tmp = ''
for item in stk['md_f_list']:
   tmp = tmp + str(item) + ' '
if stk['title'] != 'index':
   cmd = ' pandoc --smart -s --template="klab/page_template.html" --metadata=%s %s -o %s' \
   % (str(stk['metadata_title']), str(tmp), str(stk['html-title']))
   cmd = ' pandoc --smart -s --template="klab/page_template.html" %s -o %s' \
   % (str(tmp), str(stk['html-title']))  
# :: generate the html
if os.path.isfile(stk['html-title']) == True:
   cmd_r = 'rm %s' % (str(stk['html-title']))


It would be simpler to have the script read the title from the directory the markdown files are stored in, but I have this habbit of naming directories differently than the final html file. for example the markdown files that make up the index.html document are kept in a directory called “home” not “index”.

That being said, I am thinking of having it store the menu setup in a separate file and offer it to the user as a default for the page when the page is re-generated — saving having to remember the tags and titles and such.

That’s it for now. If you want to copy the script, use it or build on it, feel free (just keep in mind that, as the above code has shown, I am a hobbyist — so use it at your own risk).