Something those have in common: they are not particularly data oriented excepting the log file query engine. The rest are concerned with data but anyone seeing them from the outside of development would probably think of them as services, not data models. I think it would benefit developers to start thinking about models that way. Services encourage you to think through your API deeply and make it open for reuse outside your web application. The idea of services promotes thin controllers. It promotes creativity and there is no better language for exploration of creativity than Perl.

Today we are doing a modelservice to write text into images. One of the most annoying things about HTML is that it is barely rendered predictably and in the case of fonts it can not even come close because it’s dependent on the client’s machine. Plus most users have the trash heap of faces that come with Windows so you can’t even hope to use nice faces and have it work. If you have a brand to support, you’re in even worst straits. You probably have a face that cost you a hundred if not several thousand dollars and no way to use it in web pages without making it flat in PDFs or dynamic but hostile to SEO in Flash.

Here is the way! Well, limited use anyway. Meant for headers mostly. It makes no sense to render the real content as images though some would have you believe otherwise. It’s also messing with your SEO to even do the titles, so be aware and make sure your alt attributes are set and your images are backgrounds of heading level tags.

./script/myapp_create.pl model Title

Requirements

Imager and the FreeType2 lib underneath it. Installing FreeType2 is up to you if you don’t have it already.

Configuration, add to myapp.yml

You'll need a typeface to run this. I am pretty sure—please correct me if I’m wrong!—the font used in the example, Cuprum, has an open source style license so you can download it here: Cuprum.otf.

Note we configure a larger heading size than is set as the default in the model: 40 v 24.

The file path stuff is tricky because we are configuring two different root paths. One real one for the files to be written and one for the web path to find relative to where MyApp is serving image files. We can verify the real file path for writing files. It’s not trivial to validate the web paths—we’d write a test to do it—so we’re skipping it here.

Create a directory for the generated images. We want one set aside from regular files so we can exclude it from revision control and reset it by erasing it any time. We make the web dir relative to our static file root which is root/static (set up that way in the introduction with this–

file_root: __path_to(root/static/img/title)__

Requests to /img/title/ will resolve to the real path we’re writing.

mkdir root/static/img/title

That directory must be fully writable by the user running the application so it can create new directories and the image files.

This approach is already fairly efficient because it’s caching the images to disk. Perhaps permanently. If you really wanted to do something like this in a high traffic site though you’d need to be sure that either the paths were written to the templates too or that they were cached in the application so the model wouldn’t be asked to generate it again.

A problem with the current implementation is the filename transformation is naïve and will cause collisions in differing strings. “Code?,” “Code!,” and “Code…” for example will all end up: “code_.png.” But it’s a straightforward, human readable compromise. Something more bomb-proof should be done for a production version.

I recommend playing around with this one. It’s nearly tactile and a lot of fun. You can tweak the API. Add colors, sizes, and more. Imager can do all kinds of transforms and effects as well. Try adding a feature via config and making the API your own.

Screen shot of some titles in action

Go crazy–

./script/myapp_server.pl -d -r -p 3000

Tomorrow, the Lords of Sleep willing, we do TheSchwartz. It’s not written yet though so don’t count on it publishing early.