Archive for the 'essay' Category

I wish XML were becoming obsolete faster

XML sucks at (almost) everything it’s used for. Google has open-sourced Protocol Buffer, a typed, backwards compatible, compact, binary data-interchange format. Combined with YAML for configuration and data-persistence files that need to be human readable, there’s even less reason to use XML for any data-serialization.

XML, in the form of (x)HTML, is ok for is markup, and the XML-based (x)HTML templating in Genshi is the best templating language I’ve ever used (and I’ve used XSLT, Mako, Mighty, PHP, and a few others). I wonder if the reason that HTML templating is so difficult, and templating language code is often so ugly, is because XML is actually a poor solution for markup too. HTML is obviously here to stay, but it would be an interesting thought experiment to design a successor markup language that is not strictly hierarchical, more human-readable, and designed with templating in mind.

What reading Tufte won’t teach you: Interface design guidelines

Edward Tufte’s books do a beautiful job of illustrating how to present huge amounts of information clearly and simply. Well presented information is critical to good interface design, but it’s not the whole story. Guidelines on how to present complex functionality clearly and simply are harder to find.

I’ve just spent two months carrying a terrible, ancient cellular phone and a mediocre non-Apple music player around the planet, and interacting almost exclusively with Windows XP terminals at internet cafes and hostels. As my frustration with these poor interfaces grew, I started a rough list of interface design guidelines. Here they are:

Read on for explanations and examples of good and bad design related to each one of these rules. There is a great deal of overlap between some of them, and that’s OK — they’re just guidelines. (Perhaps I, or someone else, will someday condense them into eight or nine fundamental principles of good interface design.)

The application interface should be fast and non-blocking. If it cannot be fast or non-blocking, it should appear fast and non-blocking by being immediately responsive. Many old-school web applications had disclaimers next to submit buttons saying “Click this button only once.” Submitting data over the network wasn’t fast back in the days of 56.6kbps modems, and it’s still not fast enough today. Most web applications now deal with this by disabling the submit button (good) or by changing it to a progress spinner (better) with JavaScript the first time it’s clicked. The application isn’t fast or non-blocking, but it imitates immediate responsiveness.

The application interface should be consistent. The phone I traveled with had the standard five buttons between the screen and the numeric keypad. When navigating through and controlling various applications, sometimes the left top button meant “select”, and sometimes it was the right top button. And sometimes the center menu button also meant “select,” but not always. This lack of consistency made it just plain impossible to develop a motor memory for “select” on the phone — I constantly had to think about how to select an item or confirm an action. The cross-platform widget toolkit wxWidgets ensures that dialog boxes it creates match the standard order of OK, Cancel, Yes, and No buttons on whichever platform the application is running on.

Don’t interrupt users in the middle of common, nondestructive tasks. The basic, core functionality of the application should be free from confirmations, interruptions, dialog boxes, configuration questions, multiple steps, wizards, and other garbage. Get out of the way and let users do what they need to do. Windows XP’s information bubbles that pop up out of the system tray, on top of other windows, are particularly egregious violators of this rule. Dialog boxes in Windows and on Linux also break this rule, as an error in a background application can interrupt the user mid-task in another application. Mac OS X’s design that puts dialogs into “sheets” attached to the parent window ensures that a dialog box never interrupts a task in a different application. If one application, or the operating system, violates this rule, it can interrupt users while they are using a different application and therefore affect the usability of the entire system. Websites for DTF publications like the New Yorker violate this rule when they split their articles up into multiple pages — maybe this is motivated by some weird desire to mimic turning of a page, but more likely it’s to track readers and increase ad views. Don’t do it. Reload ads and track readers with JavaScript if necessary.

Avoid notifying users of success. In general, an application should allow users to assume that everything is successful unless they hear otherwise. If a delayed or background process or command has completed, and notification of its success will help users to continue their work, then that notification must be radically different than failure notification. Windows’ information bubbles are a serious violator of this rule too. When plugging a new device into a Windows machine, it will often emit three or four info bubbles, with a sequence of messages like this: “New hardware connected,” “CanonSony XJ-4000 PowerCyberShot found,” and then “Your new hardware is ready to use.” OS X gets this right; plug in a camera and iPhoto launches, ready to import the photos. It doesn’t say, three times, that a camera has been connected. iPhoto launching is an implicit indication of a successful connection with the camera. Lots of web applications are doing the right thing by putting success notifications in the page, in little unobtrusive boxes, and putting error messages in red, in a different place on the page. Using dialog boxes for errors, confirmations, and informative messages, as most applications did for years, just trained users to always click “OK.”

Avoid giving users information that they cannot use. Users still must read, think about, and decide that the information is useless. If the information is useless to begin with, why risk confusing them? Why slow them down to read it? Every time I plug my USB CF card reader into a Windows machine, it gives me an info bubble that says “This device could function faster if it were plugged into a USB 2.0 port.” And it says this even if the computer has no USB 2.0 ports at all. What are users supposed to do with this information? Run out and buy a USB 2.0 card? Or a new computer? How many non-technical users actually know what “USB 2.0″ means, and can correctly decide to discard this information? The information bubbles in the previous example fail here too. Users don’t need to know that new hardware has been connected, or what model of camera they just connected, because, he or she is the person who plugged the camera in. When people are working together on a project, they don’t call each other every thirty seconds to tell the rest of the team that they successfully typed another word into the report or entered another figure into the spreadsheet.

Rare, destructive actions should be harder to complete than nondestructive ones, but always possible. Closing a file without saving or emptying the trash are examples of destructive actions. If most of the actions in an application are destructive, consider building an action history with an “undo” command or a back button into it. Make as many actions as possible nondestructive. And don’t just skip implementing destructive actions — building a web application without a “delete account” command is criminal. For a long time, one of the t-shirt sites that I’d used didn’t have a way to delete a shirt — just a blurb saying to email customer support with the shirt ID. In the rare case where users do want to perform a destructive action, they are positive that they want to perform it. If it’s missing, the application seems ten times more unfinished and underpowered.

Give the user the chance to ask for forgiveness rather than forcing them to confirm a (destructive) action. Gmail and other web applications are pioneering this one.  Rather than asking something like “Are you sure you want to delete this conversation?” they provide a success notification “The conversation has been deleted” with an “undo” button next to it.  The insight here is that, although the application must provide a way to immediately abort a destructive action like this, 99% of the time, users actually intended to perform the destructive action. That should be the easy, one-click case, and aborting the destructive action should be the rarer, two-click case.

If the application pesters users with a confirmation dialog for destructive actions, users memorize a multi-step destructive command: click delete, then click OK — and when they accidentally delete the wrong thing, they miss the chance to abort. Many, many applications are guilty of this.

Deal with application failure gracefully. Don’t lock users out or lose state in the event of an application failure. Users witnessing an application failure are in the most stressful and worried mental state they will ever be in while using the application. The interface for alerting users about an application failure and recovering from it should be the smoothest, simplest, most comforting part of the interface.

Preserve state, mode, and user input for as long as it is relevant, until the user saves or discards it. Never make users answer the same question or enter the same information twice. Was there an error when saving? Show the form again with everything the user entered. Did the user switch the telephone keypad to Title Case? Stay on title case when the word isn’t in the predictive text dictionary and the user has to spell it. Take advantage of the fact that computers are better at remembering than anything else.

Provide multiple, complete navigation paradigms. Keyboard and mouse control, back and forward buttons, search and choose, scroll and jump, broad and deep, fast and slow. Digital bedside clocks and watches are particularly bad violators of this.  Often they provide, to set the time, just “up” and “down” buttons, or “fast up” and “slow up” buttons. With these two-button interfaces, users must hold down one of the buttons and watch the time change. While performing boring, slow tasks like this it’s easy for humans (your users) to get distracted, miss the target time, and have to go all the way around again, or back in the other direction, slowly. A speed sensitive knob, like on analog watches, or even just ten numeric buttons, would be a much superior navigation interface.

The iPhone lets the user scroll slowly through their address book, or click on a letter and jump ahead in the alphabet. The speed of the scroll when dropping an item into a long list in a scrolled window should depend on how far from the edge the item is being dropped. Would an e-commerce site succeed with just browse-by-category and no search? The phone I carried had one button to cycle to the next word in the group of words offered by the predictive text system, but no way to go back to the previous word. Press next too many times? Sorry, you have to cycle through all nine words all over again.

Design the interface before starting to code. Even just a sketch will help — what commands and what functionality is going to be accessible? When and where? What will need extra heuristics? What will need custom widgets? What are the trouble spots? And don’t just copy what some other application has done. Even great interfaces have problems — copy what’s good and improve what isn’t. Didn’t design the interface before starting to code? Stop now and design it.

If the application violates one of these rules because its design makes implementation of a better interface too complex or too difficult, then the application needs to be refactored until it supports a better interface. This one is sometimes the hardest to swallow — how could an application with a mathematically perfect algorithm and beautifully coded implementation of it need to be re-engineered? If the excuse for not implementing a powerful new feature is a back-end that can’t support it, then that back-end, no matter how awesome it is, is not good enough, and rewriting is the only option. A better UI is one of the most powerful new features that can be added to an application, so if it requires a redesign and a rewrite, so be it.

Officer Google, the frothy-mouthed robot trademark cop

I just sent this to Google AdWords tech support. It’s self-explanatory. I’ll post the response from Officer Darth Google (if there is any).

Yesterday, I edited and changed only the URL in Google ads I was running for a t-shirt I made on RedBubble. The text of my ad remained unchanged. Yet suddenly Google has decided that my ads, whose text has not changed, are now in violation of a supposed trademark on the word “angels.” I fail to see how changing the URL in my ads suddenly makes the ad content infringing.

An “angel” is a Judeo-Christian mythological creature that predates U.S. trademark law, and in fact the entire nation, by at least two thousand years. It appears in a book called The Bible which you may have heard of.

The only corporation that I can think of which might have a trademark on anything having to do with angels is the Anaheim Angels baseball franchise. My ads are for t-shirts which say “The angels have the phone box” and are wholly and completely unrelated to Anaheim Angels, baseball, or in fact the entire continent of North America. If you follow the link and look at the shirts, you will see there is nothing related to the team or the sport on the t-shirts. Heck, they’re not even related to the great sport of cricket.

The phrase on my t-shirts is from, and targeted at, the fan community around a British television show called Doctor Who. I fail to see how the word “angel” could be infringing on anyone’s trademark.

I wonder, does Robbie Williams’ song “Angels,” or the book and movie “Angels in America” by Tony Kuchner infringe on this same supposed trademark? What about the lyric “I see angels in the architecture” from the song “You can call me Al” by Paul Simon? What about the street named “Angel Kanchev” in downtown Sofia, the capital of the great nation of Bulgaria?

I’m no expert in trademark law, but I’m reasonably sure that it would be my neck or other body part on the line, not Google’s, if the supposed holder of this trademark on “angel” (possibly it is The Vatican?) decided to sue. Thanks for looking out for me, Google, but that’s a risk I’m willing to take. I wonder if they also have a trademark on the word “phone,” “box,” or maybe on “have” or “the.”

I’m not changing the text of my ad. That would be like requiring a toilet paper company to remove the word “paper” from their ad because Paper, Inc. held a trademark. And my t-shirts are a lot cooler than toilet paper anyway. So you can either re-approve my perfectly reasonable ad, or I just won’t run Google ads for my t-shirt, and you won’t get any money from me. Your call. I suppose you’re not really hurting for money over there at Google anyway. Let me know what you decide, and thanks for listening.

Why RedBubble kicks ass

I’m always looking for clever t-shirt ideas, and ever since reading Alvin Toffler’s The Third Wave back in 1997, I’ve wanted to make my own custom t-shirts. I’ve made CafePress, Spreadshirt, and Zazzle stores for my own designs, plus a CafePress store for the Neighborhood Project, a Spreadshirt store for Mosuki, and a Zazzle store for my Burning Man camp. All three of these websites suck, in various ways.

RedBubble is the new kid on the custom t-shirt design block, and it kicks these three competitors to the curb1. I’ve moved all my designs there. To explain what they’re doing right, first I’ll explain what these three competitors are doing wrong.

CafePress is dog slow and riddled with quirks. Browsing through my private designs, a few of the product previews show up as broken images. Background images and UI graphics re-load on every page change, slowly. Designing a new product is a complex, multi-step process. First you choose blank apparel or household items and add them to your shop. Then dig through pages and pages of FAQs to find the exact DPI and pixel dimensions for the particular item. Then fire up your image editor and resize your graphic to match. Upload the image to your “media basket.” Then go find your blank item, and add the graphic to it. If you add a graphic of the wrong size — like putting the 200DPI version of your graphic designed for a coffee cup onto a 300 DPI t-shirt instead — there’s no warning and no visual feedback. You, or your customer, will just get a badly pixelated product. And worse, if you upload an image that’s too large — it will be badly down-sampled, and look almost as bad as an image that was too small. They added support for dark apparel at least as far back as 2006 — yet their product previews still don’t look right. This is basic image manipulation, not rocket science.

Spreadshirt has two different printing techniques. The better-quality one, “flock print,” can’t print designs that are too detailed, so they require you to wait several days for each design to be approved by a human at Spreadshirt. Like CafePress, creating a shirt involves first uploading a design, and then adding it to a product. Their shirt designer is a pure flash widget in a pop-up window which takes over a minute to load on my fast net connection and has all the standard Flash problems; high CPU usage, no keyboard navigation, no scroll wheel support, etc., etc. It has a bunch of controls and widgets, some of which I have never needed and others which I don’t understand. I ordered this shirt from Spreadshirt, after their customer service confirmed that the black in the image, around the diamond with rounded corners, would not be printed. The shirt had a salmon color in place of red — that’s #ff0000 red — and the design’s edges had been sloppily cut, totally ignoring the rounded corners. It was so hilariously bad that I didn’t bother asking for a replacement. Each shop even has a bunch of settings and fields, including “title,” and “shop name,” (only one of which actually appears inside your <title> tag — the other appears to be ignored), two different “description” fields (one of which also appears to be ignored) and the cryptic “Product choice-Display category type.”

Zazzle replicates the multi-step product creation process of CafePress and Spreadshirt. Their product design UI is, thankfully, AJAX and not Flash, and you can upload an image to your “gallery” inside the product design process, although it takes three clicks and about two minutes of waiting for the UI to load before you actually get to the HTML file upload widget. Like Spreadshirt, their product designer has a suite of widgets to position and transform your image, and it takes several clicks to get the final product up on your store. I’ve ordered three shirts from Zazzle - the first I sent back because it was printed at such low quality I assumed their printer was running out of juice. I was wrong; when I received the replacement, it was just a tad bit better. The second was a retro design; I was planning on the poor printing adding to the retro charm, and it did.

So what makes RedBubble so much better?

RedBubble’s print quality is superior. If all these sites are screwing it up so bad, full color, digital printing on fabric must be a really difficult problem, right? If it is, RedBubble has solved it. I bought two designs on RedBubble that were too good to pass up, despite the poor print quality I’d come to expect from design-your-own t-shirt sites. And guess what? The shirts look great — you have to look really close to see that they’re not actually silk-screened in five different colors.

Maybe designing t-shirts on the web is just a complicated, difficult process? Nope. RedBubble’s t-shirt design process is extremely simple and quick. You select a 2400×3200 image to upload, and click save, and you have a t-shirt ready for sale. What about positioning, scaling, adding text, and compositing multiple images, like you can do on these other sites? RedBubble doesn’t provide any on-site UI to help you do these things. And they shouldn’t. People who design t-shirts — especially the good designers — are using Photoshop, Illustrator (or GIMP & Inkscape) and their ilk, to begin with. Those programs are going to do a much better job at tweaking your image than some Flash or AJAX web app coded by that nerdy intern from last summer with a 250×250 product preview window and a bunch of buttons with icons your users haven’t seen before. Rather than maintaining their own inferior design and preview widget, RedBubble gets out of the user’s way.

In RedBubble’s shirt design process, you can also pick the default shirt type, the available colors, and the default colors, and add a title, description, and tags, but all those items are optional. You can design a t-shirt in three clicks.

The theme here is that RedBubble’s superiority is distinguished as much by things that it does better as by those it doesn’t waste time with. There’s no “store,” and no concept of multiple stores on a single account, just a bare-bones profile. There’s no site-wide marketplace in addition to your store. There’s no way to customize your product list’s colors, logos, or background. Custom layout is not necessary, since (unlike it’s competitors) RedBubble’s default site colors are clean, simple, and don’t detract from your designs.

RedBubble doesn’t let you make hats, sweatshirts, panties, aprons, mousepads, buttons, magnets, coffee mugs, dog t-shirts2, baby aprons, pet bowls, or light switch covers. Just t-shirts, posters, prints, and calendars. Their interface, and the underlying code, is vastly simpler because of this — there are no “choose product” or “add products to store” steps. And I bet t-shirts, posters, prints, and calendars make up a very large percentage — like 70% — of CafePress’, Spreadshirt’s, and Zazzle’s revenue. Doing less gets RedBubble to market quicker, gives them a simpler product, and makes them a more agile competitor.

RedBubble has also built a community, and channels to keep users on the site and bring them back. You can give people positive feedback for their work by “favoriting” it or by “watching” them. You get summary emails with new work by people you’re watching, comments related to your work, and so on, drawing users back to the site over time. I was overwhelmed when I got even one comment on the first design I posted. I’ve now got thirteen comments on sixteen designs; compared to just two comments on my entire Zazzle store. And the comments, favorites, tags, and watchlists mean there are more users and t-shirts on every page to click on, making their site almost annoyingly sticky.

There’s only one thing that RedBubble is missing. They need to let you print on the front and back of a shirt. And I bet they’re working on that.

RedBubble is following all of those pithy little maxims for building a successful website:

  • Keep it simple — your product, your message, and your interface.
  • Do one thing and do it well.
  • Get out of the user’s way.
  • Build a community and keep it happy.
  • Always have something cool for the user to click on and look at.

So long, CafePress! Farewell, Spreadshirt! See ya later, Zazzle! Me and my custom t-shirt designs will be hanging out over here on RedBubble from now on.

  1. Threadless and Oddica, although good sites with very good printing, live in a different neighborhood because they both only print a small set of submitted designs. And my designs are generally too weird to win any beauty contests.
  2. What kind of person buys a custom dog t-shirt, anyway?

The third flavor of focus-follows-mouse

Steve Yegge’s excellent Settling the OS X focus-follows-mouse debate explains why OS X’s application-centric paradigm, with its application-global menu bar, doesn’t work so well with focus following the mouse but no automatic window raising. Background windows, attached to background applications, can’t, and aren’t expected to, listen for modifier+key events, because the application’s menu isn’t active.

The lack of focus-follows-mouse on OS X is one of the biggest reasons that I stick with Linux and Xorg on my main machines. Whenever I use one of my Macs for an exended period of time, I feel like a marathon runner who’s had to trade in his sleek running shoes for a pair of swimmer’s flippers. If there was a third-party tool to provide focus-follows-mouse on OS X that worked properly, I’d install it in a heartbeat.1

Yegge also points out that the auto-raise flavor of focus-follows-mouse is a taste only an epileptic could love. Set the auto-raise delay too low, and moving your mouse across big windows towards a smaller target window, or moving it too slowly, causes a cascade of ugly, annoying window raises and destroys your carefully crafted window tabbing order. Set the auto-raise delay too high, and you’re waiting too long for windows to focus once you’ve got the mouse there. In my experience, there’s no delay setting that works — every setting is too high, too low, or both.

But there’s another flavor of focus-follows-mouse, that, as far as I know, is only available via a third-party plug-in to the semi-abandoned and deeply buggy Sawfish window manager. It’s a flavor that is evocative of ripe nectarines and raspberries on a summer afternoon. And it’s so good it’s kept me using Sawfish despite its abandonedness and bugginess.

It’s called stop-focus, and it works like this:

  1. While the mouse is moving, don’t raise windows.
  2. Once the mouse has stopped, raise the window it stopped on.

“Stopped” is defined as below a certain configurable velocity (ten pixels per second works for me), and windows are only raised after a short (200ms) delay. Stop focus lacks the cascading window raising behavior of auto-raise. Moving the mouse across slowly across several large interim windows doesn’t raise them or screw up window tabbing order. Starting to move the mouse to another window, and then stopping and moving it back to the currently focused window, which you and I do more often than we care to admit, doesn’t cause any window raises at all.

So, while focus-follows-mouse without raise-on-focus (Yegge’s preferred autofocus), may not be feasible on OS X right now, there is a variant on focus-follows-mouse, with sane rules about when to raise the window under the pointer, that might make all us old focus-follows-mouse Unix relics happy.

If I were an OS X hacker, I’d probably just go code this up right now. But I’m not, because, among other things, OS X’s mandatory click-to-focus bugs me too much. Chicken, meet egg; Egg, meet chicken.

  1. One of the other big reasons I don’t want to switch to OS X is that, for reasons I won’t get into here, the global menu bar really bugs me. Funny that these two gripes of mine turn out to be intimately connected.

Ruby’s not ready: comments, corrections, and clarifications

Some good discussion on this one. It’s nice to see Ruby people saying things like this (5th message from the top, from Song Ma):

Interesting. But what I am thinking about is not the attitude of the author, but the points he was trying to make. The deep review and discussion will benefit the language insights.

Or this one (from Trans, on the same forum):

Why is everyone getting so worked up? It’s a critique. Biased it may be, but that in itself does not make it worthless. In fact, it can be very constructive b/c it uncovers “attack points” with the language. With each point we can ask ourselves objectively is this a misconception or a fair point? In either case we have an opportunity, to address misconceptions in our Ruby evangelizing blogs and to work to improve Ruby where a point has merit.

Bias can work both ways. But I think the Ruby community can rise above it, and Ruby will be all the better for it.

And from Peter Cooper at Ruby Inside:

As it is, I think he’s missing the point a lot of the time (he tends to think Python’s better because he likes its conventions more than Ruby’s - not a compelling argument), but it’s an interesting read none the less. Anything that keeps our minds open to the fact that Ruby != perfection is worth a look.

And a comment on the same post:

Let’s take his best points and incorporate them into future versions of Ruby.

Sounds like a plan.

I saw a few counterarguments like this:

Everything he’s saying is well known.

Just because a problem is well known inside a community doesn’t make it any less of a problem.

Everybody who mentioned documentation, even those who disagreed strongly with the rest of my post, agreed that Ruby’s documentation is seriously lacking. In fact, a lot of the mistakes in my original post are due to me not being able to easily find an explanation of something on the various Ruby doc sites. Which leads me to…

(more…)

Ruby’s not ready

Introduction

A few weeks ago, I learned Ruby and Ruby on Rails to compare them head-to-head against Python and Pylons, in preparation for a new project. When I began, I knew nothing about Ruby or Ruby on Rails. I have tried to be as objective as possible: before beginning this project, I wrote in email on March 5th:

I promise we’ll be as objective as humanly possible; if Ruby and Ruby on Rails truly is better, we’ll happily use RoR and never look back. I want to know that I’m using the absolute best tool for the job.

Since then, I have reimplemented one complex nine-hundred line Python library, PottyMouth, in Ruby. Another team member has also reimplemented parts the Pylons web application Spydentify in Ruby on Rails.

The best tool for the job is Python & Pylons. While Rails and Pylons are similar, shortcomings in Ruby compared to Python make Python & Pylons the clear choice. I make three basic arguments against using Ruby:

(more…)

If programming were like building a house…

I’m always coming up with metaphors to explain to non-technical people what I do. The point of this one was to explain to people why I prefer Python:

  • Programming in C is like building a four-story mansion out of 1×2 Lego bricks.
  • Programming in Python is like building a house out of Lego Technic parts.
  • Programming in Perl is like building a house with duct tape, a flat of cinder-blocks, some left-over lumber, pipe cleaners, crazy glue, fishing line, and chicken wire. You also get a bunch of re-bar that you can bend into whatever shape you want, and truck full of spray-on concrete.
  • Programming in PHP is like building a house with just chicken wire, coat hangers, and aluminum foil. Luckily, if you use enough aluminum foil, it will shield your brain from the alien transmissions from outer space, so you don’t have to wear your aluminum foil hat while you’re at home.
  • Programming in Java is like buying a one-piece, hyper-modern, injection-molded plastic house unit, and then having your lawyer write a letter to the house manufacturer asking for permission to cut a one-meter by two-meter hole in the living room wall into which you’ll install the front door, since the house doesn’t come with one. Your lawyer promises in the letter not to sue the house manufacturer for problems with the door.
  • Programming in Ruby1 is like building a house out of two different brands of cheap knock-off Legos, made of flimsy, low-quality plastic, which don’t fit together quite snugly enough. You also get a handful of puke-green pipe-cleaners left over from Perl.
  • Programming in JavaScript is like building a house out of Jell-O that has to stand up on three different lots, one flat, one downhill, and one uphill. Just when you’re finished building the house, Bill Cosby rides up on a stallion, ready to start filming a Jell-O commercial.
  • Programming in XSLT is like hiring an architect who speaks only Icelandic, an engineer who speaks only Bantu, and a bunch of Nepalese sherpas as the construction team. The architect thinks you’re building a supermarket, and the engineer thinks you’re inventing a new kind of refrigerator, and the sherpas think you’re doing performance art. The engineer builds a catapult to fling 2×4s into the air while the sherpas fire high-powered nail-guns at them, and when it’s all done you’ve got an ordinary two bedroom suburban house that’s completely upside-down.

That’s all! Happy April Fools!

  1. I’ll be posting a larger article about my recent experiences learning Ruby in a few days. Subscribe here if you want to read it when it’s posted.

SuperCache not so much with the “Super”

In reaction to the more than 34,000 visitors that Why your Flash website sucks generated (and is still generating) Jeremy enabled WordPress’s SuperCache for me.

Turns out SuperCache does a less than super job with non-ASCII characters, failing to encode them to HTML entities, and instead writing them out as multi-byte UTF-8 sequences:

Alphabet Soup ported to Inkscape/SVG

I got this email Tuesday from Joel Holdsworth, announcing that he had ported my Alphabet Soup pseudo-letter-generator from a bitmap to a vector model, and turned it into an Inkscape plug-in. He tells me that the extension will likely be included with Inkscape v0.47.

I cannot begin to express how phenomenally awesome this is. This is the kind of news that keeps me writing, and releasing, little free software projects. Six years ago I wrote Alphabet Soup as a little art project; it was fun. I released it under an open source license, and then never got around to improving it to output a vector format. Then somebody I’ve never met comes along, and not only improves it, but integrates it into a bigger free software project and it will soon be available to thousands of users in a greatly improved form.

You can pull the extension out of Inkscape’s SVN here. You’ll need these files:

share/extensions/render_alphabetsoup.inx
share/extensions/render_alphabetsoup.py
share/extensions/render_alphabetsoup_config.py
share/extensions/alphabet_soup/*.svg

Thanks Joel. Thanks Inkscape. I’m feeling pretty damn freetarded right now, and it feels good.