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. 😛 ]