For the past few months, I'd been looking to start a mostly-tech blog.
I already have my dusty ol' movie review blog, and I have my ragingly active book review sorta-blog on Goodreads but I also wanted a place to document and share what I'm learning along my Journey to the Center of the Machine. Given how much I've benefitted from other tech blogs - Julia Evans's or daiyi's or Peter Norvig or Ned Batchelder's - it also seemed like giving back to the community was a good thing and something I should do.
In looking for a blog framework, I knew I wanted to:
- Automate as much as possible. The above, plus could I haz scripts?
- Markdown support. Plz, so lazy.
- Python. I once attended a one-day workshop where we built little blogs using GitHub Pages and Jekyll. Unfortunately, Jekyll's in Ruby - but surely there was something in Python?
Pelican is a static site generator, written in Python.
Static site generators take your content, pour it into your templates and output the result as static pre-generated HTML, CSS, JS & image files. You can then just upload the resulting folder of output to your server and you’re done.
To get started, I followed Pelican's quickstart and, after fussing over where to put it (my directory structure is a mess, please send help) and fussing over keeping my Python environment clean (please send more help), I just said "whatevs" and pip installed it onto my base Python like a maniac:
pip install pelican markdown mkdir ~/some/file/path/pelican_hello_world cd ~/some/file/path/pelican_hello_world pelican-quickstart
pelican-quickstart runs you through a bunch of questions on how you'd like to set up your project: for example, the title, author, and so on. (This is for convenience; you can change your answers later by editing your
pelicanconf.py file.) Once you've finished, you'll have some pre-populated files and a directory structure like this:
pelican_hello_world/ -- content/ -- output/ -- develop_server.sh -- fabfile.py -- Makefile -- pelicanconf.py -- publishconf.py
The money bits are in
content/ (where you'll draft your blog posts) and
output/ (where Pelican will dump the static site, ready to be published to the internet). You can change where Pelican dumps your site - I changed the
$OUTPUT_DIR variable in the
pelicanconf.py, per this issue) to where the rest of my website is.
You can write your blog posts in Markdown (or
.html) and stick them in
content/. You can then run
make html and
make serve to launch a local server and see the changes at
localhost:8000 in your browser.
There are some "meta" fields at the top of a blog post in
content/, which Pelican's (magical?) (CSS?) something parses to auto-populate the resulting
At this point, I had a few things I wanted to figure out:
What does Pelican want from me? (
According to the docs:
Title: My super title Date: 2010-12-03 10:20 Modified: 2010-12-05 19:30 Category: Python Tags: pelican, publishing Slug: my-super-post Authors: Alexis Metaireau, Conan Doyle Summary: Short version for index and feeds This is the content of my super blog post.
How do I make it look pretty? (
There is a frankenrepo over on GitHub of 120+ themes. Following their instructions, you can
git clone the entire repo to your home directory, and then - in the
pelicanconf.py config file, add:
THEME = /path/to/pelican/repo/clone/some-theme-name
I didn't love this. First, there's a LOT of themes. (You can browse an endless scroll of them here). Second, it seemed like grabbing a gnarly giant repo - with tons of devilish
git submodules (ack) - was not a super efficient way to grab one or two themes. Third, as a Pelican noob, I wanted to make something look like my existing website - and customizing an existing theme didn't seem much easier than just customizing base Pelican.
The docs discuss creating a theme:
- Basically, you follow a directory structure, where you have a
images/and whatever other assets you want to just port across to
output/), and then a bunch of
.htmltemplates for each of the different pages Pelican's
- Ah ha! This could be where, if one wanted, one could dump their Bootstrap navbar, stylish fonts, and soothing CSS.
I spent a lot of time on this, way more than I wanted or intended. One of my specs is "minimize front end"! But, argh, it had to be done. What I ended up doing was:
- Using the
pelican-bootstrap3theme as my base.
- Rewriting a bunch of that theme's
style.cssto look like my original website.
- Doing a lot of (fun) fussing over widgets and doo-dads.
Syntactic Scriptastic sugar
This blog by Nafiul Islam had a pretty awesome/handy example script -
make_entry.py - which you can use to automate your posts. I fiddled with it, added
argparse and a few more options, and modified it to output
.md formatted blog templates. I've been using that now to auto-create drafts.
Chris Albon also has a cool Jupyter -> .md -> Pelican workflow script, though I haven't played around with it yet. But it looks cool.
How do I integrate it with my existing website? (
Subdomains are so cool. After I created the
blog.angelaambroz.com subdomain on my webhost, I thought I would just have to dump the
output contents into it, remember to link to it from the rest of the site, and - voila! Now I have a tech blog! Wooo.
Unfortunately, tying it all together took a bit more pain and fiddling. First, there was the problem of relative paths. I had used the
ARTICLE_URL options in my config file to auto-create year and month archives of posts (and also clean up the
blog/ directory structure). Unfortunately, this messed up a bunch of things: I now had
index.html files every which way, and I was referencing up and down directory paths. It was a giant, giant pain.
Also, the CSS didn't line up at first; though I think this had more to do with running a local server. But there are still some annoying disparities (e.g. the navbar on my blog has slightly dimmer font-color than the navbar on the rest of the site - argh) that, after N hours, I am too pooped to resolve. I also don't love the idea of maintaining two distinct CSS files.