Raking Jekyll

I’ve never really touched rake before, but since switching to Jekyll I’m finding that it’s becoming an essential part of my workflow. In the limited area of blogging, at least.

rake is a version of make in which you define all your targets in Ruby. Because practically anything would be an improvement over Makefile syntax, this is pretty easy to work with. I’m not a huge fan of shell scripting at the best of times, so mixing it in with something else is… not desirable. I still find Ruby less intuitive than Python, but that’s my prejudices talking.

To elaborate… what does posting a new entry look like for me?

  1. rake server to start up an automatically-rebuilding local webserver copy of my blog
  2. rake post[raking-jekyll] to make a new post with the YAML front matter boilerplate
  3. Actually edit the newly created post in an editor
  4. rake deploy to rsync the local copy to my hosting over ssh

Any part of my routine which looks like it might be scriptable has been replaced with a rake target. For example, the post target:

  1. Copies a template file
  2. Names it according to the current date and provided title
  3. Adds an expanded version of the current date into its YAML front matter so sorting will work correctly if I post multiple times a day

Since I rarely know the current date without having to look it up, that certainly saves me some effort.

Here’s my Rakefile, if you want to use anything from it. It’s probably not properly idiomatic Ruby, but it does at least work.

Jekyll

I’ve just redone my website using Jekyll. It is now completely static. No PHP, no database, nothing like that.

Why did I do this?

  • It’s quite soothing knowing that all my content is version controlled.
  • I am now nigh-immune to traffic spikes. I was using caching with WordPress before, so it had never been an issue even when I was on the HN frontpage, but there’s some peace of mind in it.
  • WordPress had a history of security bugs which wasn’t comforting. Since nothing on this new site is executable I feel pretty secure now.
  • My site is now ridiculously flexible. Jekyll forces almost no structure on you, leaving you free to change things around as you please.

I’m happy with the end result, but the process of getting there was not without pain.

The initial difficulty came from Jekyll’s documentation being somewhat lacking. I found myself somewhat confused about minor details like “how does a layout work?”. After I’d cribbed that together by examining other sites posted with Jekyll, I discovered that the template data docs were inaccurate / misleading, implying the presence of a post variable which failed to exist. It turned out to be something that’s merged into page if you’re viewing a post.

I don’t completely blame Jekyll for this being opaque. Jekyll uses Liquid for its templating language, which claims to be aimed at designers… and I feel it would benefit from some sort of debugging mode that dumps the current scope for examination.

I resorted to reading Jekyll’s source, which cleared up a number of things. However, I view it as a bad sign that I felt I had to do this. Not that a command-line driven static website generator is ever likely to be a mainstream product, but still, it’s the principle of the thing.

Pagination worked, but was completely lacking in configuration. Since part of my goal was to have my URLs remain the same as they were in WordPress, I had to change this. I did so with a horrible monkey-patching hack of a plugin. Specifically, I made a copy of the pagination module from Jekyll’s core into my _plugins directory and selectively edited it to change the pagination urls.

In the process I noticed a bug in the core code, and submitted a pull request to fix it. So horrible monkey patching might at least pay off this time.

Also utterly broken was the related posts feature. No matter what, it always seems to think the most recent posts are the most related to anything. It’s possible that running with --lsi would have helped with this, via complex semantic analysis, but that takes forever and I’ve seen others complain that it doesn’t really help. So there’s more monkey patching going on via Lawrence Woodman’s related posts plugin, which I took and edited so it worked based on tags instead of categories.

One thing I haven’t fixed, which I’d like to, is making the automatic regeneration of your site during development / writing a lot smarter. Right now it notices a file has changed and so it regenerates every single bit of content on your site. This does mean that the live generated site always has recent/related posts up to date everywhere… but it’d be nice to have some sort of --quick option that ignored that stuff in favor of a faster development cycle.

Because of the utter staticness, I naturally cannot have my own comment system in use any more. So I’ve switched to Disqus, which adds commenting to the site via JavaScript. It feels sort of weird to be outsourcing a component of my user experience like this… but they seem to be trustable. Widely used, and their monetization plan is fairly transparent.

If you’re interested you can see the repo for my website on github. It contains, in its default / post templates, markup that’s compatible with any WordPress theme that’s based on Toolbox, which might be of use to some.

Like I said, I’m happy with how it turned out. I wouldn’t recommend this at all for a non-technical person, but if you want to dig in and get your hands dirty then Jekyll is quite workable.

Smart Home in TextMate

I really like “smart home” behavior in text editors. That is, I like it when pressing the “home” key first moves the cursor to the start of the indented text on that line, and then to the very beginning of the line on a second press.

I go out of my way to enable this behavior, where possible. For instance, I wrote a gedit plugin to get it working properly in gedit, the Gnome text editor.

Unfortunately, TextMate is a harder nut to crack. I worked out the following as a TextMate command, and bound it to command-left:

It works, but is far too slow to be usable for me. There’s a perceptible lag of probably around 100-200ms between hitting the shortcut and the cursor moving.

I think this is an unavoidable limitation of TextMate’s approach to letting commands navigate within the file. It has to spawn a process to run the command, and the command then spawns a process to run the OSX command open which handles a txmt:// protocol that TextMate has registered with the OS. There’s some inherent inefficiency there.

(Writing a command with pure shell scripting doesn’t help, incidentally. It’s slightly faster, but still not enough to be worth it.)

How to generate PDFs from XML using Apache FOP in Ruby on Rails

The title is a bit of a mouthful. Sorry.

Before we begin, I present the caveat that this code should not be used on a production system. It launches a java runtime for every single request, which would cripple you. This would need (a) output caching, and (b) some sort of persistent FOP server process before it could be considered usable.

But if you just need to generate PDFs on an intranet app, say, then this could be handy.

Step 1: Put FOP somewhere it can be found. Specifically, its “build” and “lib” folders. I created a “fop” directory in my project, and stuck everything in there. (I don’t promise that this is ideologically sound — I’m new to the whole Rails thing.)

Step 2: Add Mime::Type.register "application/pdf", :pdf to config/initializers/mime_types.rb (this gleaned from Dynamic Graphics with Rails 1.2).

Step 3: Use a controller action something like this:

Then whenever someone asks for “documents/17.pdf” it’ll make a PDF and serve it right on up. In the event that something goes wrong it’ll just display the command it ran, for some rough-and-ready debugging.

For a proof-of-concept you could try this with the example XML and XSLT that comes with FOP. Look for “projectteam2fo.xsl” in the examples directory.

As I said above, this works, but should not be put anywhere near a publicly accessible site.

Thoughts on Ruby on Rails after one day of work

I started looking at Rails (leading to my talking about scaffolding) because I wanted to try writing my next work-project in it.

I don’t know about others… but I hate learning a language/framework in isolation from a project. Writing an insipid tutorial project that I don’t care about doesn’t involve me, and so I don’t learn as well. Also, the applications written alongside tutorials tend to be very carefully chosen to hit all the good parts of a framework, while ignoring the rough spots. Thus I’ve historically viewed “prototyping my next project” as a great time to pick up something new.

So. I started Rails tutorials on Friday, didn’t touch it at all over the weekend, and by mid-morning on Monday I had my proof-of-concept app. I’m storing legal documents described in XML, allowing people to fill in some defined fields on them, then generating custom PDFs/RTFs/PNGs/whatevers using Apache FOP. (That sounds more complex than it is. I’ll post an example later.)

Rails itself is being reasonably unobtrusive, which I approve of. I had to do minor research into how to set up custom mime types for response formats, but it turned out to be quite simple.

Rails 2.0 Scaffolding

I’m learning Ruby on Rails starting with 2.0. This is occasionally problematic, as it was only released a few days ago, and the tutorials are still all for 1.2.

So, to help others, something not mentioned in the release notes, which causes errors if you’re following the official tutorial.

Scaffolding has changed.

The 1.2 way was to stick scaffold :modelname into a controller.

The 2.0 way is to run ./script/generate scaffold ModelName field1:type field2:type field3:type on the command line.

The new way is more useful, I think, as it reduces the initial hurdle of moving from a scaffolded controller to a slightly custom one. It gives you controllers filled with code ready to be tweaked, and sets up a migration to create your model. You’re left with a working site filled with examples of how to do things in rails, instead of a magical “scaffold :foo”.

It’s just that it’s a wee bit undocumented.

An aside: I felt that I needed to post this because googling for “rails 2.0 scaffolding” didn’t actually produce anything helpful on the first page or so. Lots of talk about whether it’s ideologically pure, but not so much on the “this is how to do it” front.

[Update: I get the impression, from seeing others talk about this, that it’s not so much that scaffolding has changed as that one scaffolding option has been removed. It looks like the scaffold generator was there pre-2.0, and the only change is that scaffold :Foo is no longer available. Still breaks every “getting started with Rails” article I’ve ever seen, though. 😛 ]