A simple Python 3 blogging system.
Simpleblog is a simple Python 3 blogging system. I use it to write and publish my own blog at http://blog.peterdonis.com. I wrote it because I couldn’t find an existing blogging system that made it sufficiently easy to write, format, and publish my blog.
My chief goal with simpleblog is for the system to stay out of my way; I want to be able to add features easily, but other than when I’m actually doing that, I want simpleblog to “just work”, so I don’t even have to think about it at all. That way I can think about what I’m writing instead. With the existing systems I’ve tried, I have ended up spending too much time figuring out the internals of the system in order to get things the way I want them. Admittedly, I have not tried many existing systems; but what I have read about the ones I haven’t tried has not encouraged me that any of them would work any better for me. So here we are.
If you just want to start using simpleblog, without digging into its internal details, then once you’ve installed it, you can copy the contents of one of the example blogs to a directory of your choice, and start writing your blog there. The layout of the example blogs, and the files in them, will give you a start. Before writing any entries, you will want to at least edit the blog.json or blog.yaml file to customize your blog’s metadata, and the template files in the templates subdirectory, which give extremely plain HTML pages by default.
Note that in order to use simpleblog, you will need to have installed plib3.stdlib (my library of useful Python 3 stuff, which is used in a number of places in simpleblog). It is available at http://pypi.python.org/pypi/plib3.stdlib. If you want to use YAML instead of JSON for your config and blog metadata files (I certainly find YAML much easier to type since I hate typing delimiters, as you will know if you read my blog), you will also need to have installed PyYAML, the YAML parsing library for Python (which in my opinion should be in the Python standard library).
Note: simpleblog3 is the Python 3 version of simpleblog. If you are using Python 2, see https://pypi.python.org/pypi/simpleblog.
The structure of simpleblog is simple (no, that wasn’t intended to be humor, it’s just the way it naturally came out). There are five core object types: the config, the blog, pages, containers, and entries. The config lets you define or customize the internal behavior of the code, and all the other objects have a reference to it. The other object types fall into a simple hierarchy:
It’s important to note that the above is all that the core objects implement, and it is completely general. Everything specific, such as what actual “sources” there are, which entries are in which containers, etc., is all defined in extensions. (Strictly speaking, there is one default container in every blog, which simply contains all its entries, and every blog has an index page, which uses that container as its “source”, plus a page for every individual entry. But that’s all that is in the blog by default. Of course, that by itself is enough to have a simple blog, which is part of the point.)
Simpleblog uses Python’s built-in string templating and formatting to render entries and pages. The example blogs illustrate the basics of how this works. This is one area where I do not have any items on my To Do list; the various fancy templating engines out there have their uses for highly dynamic web applications, but for a simple blog they are, in my opinion, extreme overkill. But the extension mechanism is there for anyone who disagrees and wants to use their favorite templating engine.
Extensions allow pretty much every behavior of the four blog object types–everything above except the config–to be changed, and even allow new behaviors to be added. (I say “pretty much” only because I can’t be absolutely positive I have allowed for every possibility; but that’s my goal.) This is done with a simple (yes, you’ll see that word cropping up a lot…) but powerful mechanism. You write a Python module that contains a subclass of the BlogExtension class, and implements your desired changed or added behaviors, and add its name to the list of extensions in your config file. That’s it. Or, of course, you can use one of the extensions that come with simpleblog, listed below. I use all of them for my blog. They give good examples of how the extension mechanism can be used.
(Note: Strictly speaking, since extension names will be looked up as Python module names, they must be valid identifiers, which means they can’t include hyphens. However, simpleblog allows you to use hyphens when referring to extensions, as in the render-markdown extension; it converts the hyphens to underscores before looking up the module name. Command names are handled the same way–see below.)
Note that in some cases the order in which extensions are declared in your config file matters. The order in which extensions are listed in the config determines the order in which they are loaded, which determines the order in which they get to process whatever data they are processing, which can obviously make a difference if multiple extensions process the same data. The cases you are most likely to encounter are extensions that process the raw entry source data (the title, tags, and folding extensions all do, and the ordering that is known to work is the order in which I just gave them), and extensions that add sources in the form of new containers (the archives, categories, and tags extensions) vs. extensions that need to know all the containers in the blog (the links extension is the key one, and needs to be loaded after the ones listed just now).
Entry metadata is often useful for putting entries into containers and ordering them properly. It is nice to be able to do this without having to actually ask the filesystem for any data on individual entries, by either statting or opening and reading the entry source files. Simpleblog provides a caching mechanism for entry metadata to make this simple. Just use the cached decorator on any property that represents metadata you want cached, and provide the name of the file the cache should be stored in.
All of the above is nice, but in order to actually use it, you have to have some kind of front end. The simpleblog-run script provides one. If run without any command at all, the script simply puts you into the Python interactive shell, with the simpleblog package loaded; I find this extremely useful for testing and debugging. But the script can also be enhanced with commands, by a mechanism similar to the extension mechanism.
(Note: As with extension names, hyphens in command names are converted to underscores before looking up the module, so you can use hyphens, as is done below, if you find them easier to type, as I do.)
For quick help on usage, use the --help option to the simpleblog-run script. If a command name is provided, help specific to that command will be shown; otherwise, general help will be shown.
Simpleblog supports defining your own commands or extensions, separate from the ones supplied with simpleblog itself. All you have to do is set the command_dir or extension_dir config and supply Python modules that match the command or extension name you want to use. The command and extension loading mechanism will look in your user-defined directories first, so you can even define a command or extension with the same name as a pre-packaged one, and it will take precedence.
Add fancier example blogs to show how the various extensions work.
Add documentation other than this README file, both for users and for developers.
Add support for comments while still allowing the blog to be statically generated.