Falling Leaves: the Ardes blog

Why I Love Safari Tidy

Ray Drainville

Recently I mentioned that I use Safari Tidy—a plugin for Apple’s Safari browser. I thought I’d shed a little light on why I think it’s so great.

For years now individuals—Jeffrey Zeldman most prominent among them—have been evangelising the use of standards-based (X)HTML. There are vague reasons for supporting standards, like getting the warm & fuzzies for doing so; there are abstract reasons, such as preparing work properly to be handed over to a successor; but a very real & immediate reason is that you have a very firm basis upon which to work. It’s all too easy to make mistakes in the semantic properties of HTML, which can yield disastrous rendering results in browsers. And it’s all too easy to not see the problem until late in your design process.

Safari Tidy is unobtrusive & always on: you’ll see that an error has arisen immediately, so you can go fix it. Other implementations of Tidy aren’t so automatic—you have to physically check your markup’s validity, which often means that you don’t check—this is what makes Safari Tidy so fantastic.

I’ll illustrate with a real-world example (one upon which I’m currently working, in fact):

Many out there will be aware of the generating capabilities of Ruby on Rails. A good explanation of this is beyond the scope of this article, but suffice to say you can build the general building-blocks of a web application very quickly, such as setting up a new user in a system. Here’s a rudimentary example of a ready-built form (linked to the users controller). It’s to be rendered in XHTML:

  <% form_for(@user) do |f| %>

    <p>
      Login:<br />
      <%= f.text_field :login %>
    </p>

    <p>
      Email:<br />
      <%= f.text_field :email %>
    </p>

    <p>
      Password:<br />
      <%= f.text_field :password %>
    </p>

    <p>
      <%= submit_tag %>
    </p>

  <% end %>

The result of all that <%= f.text_field :foo %> is to create form tags, such as input. Here’s what the above gets with the Login example:

  <p>
    Login:<br />
    <input id="user_login" name="user[login]" size="30" />
  </p>

So far, so good. But what if the user hasn’t filled out a field & you have to display associated errors? Simple in Ruby on Rails. Assuming validation has been set up in your users controller, just add the following bit in front of your form:

  <%= error_messages_for :users %>

With this in place, if your user doesn’t enter a required field, or enters a required field incorrectly, then Rails will automatically inform the user of what was wrong (in the location of the <%= error_messages_for :users %>). Moreover, it’ll wrap the offending field to highlight the user’s attention to it. It will look like this:

  <p>
    Login:<br />
    <div class="fieldWithErrors">
      <input id="user_login" name="user[login]" size="30" />
    </div>
  </p>

And now we have a problem. A div can contain a p, but cannot be contained within it. This is where Safari Tidy comes in really handy. When you test your error message (as above) by viewing it in Safari, Safari Tidy will inform you of an error in your markup. The error it makes is somewhat cryptic:

  <p>
    Login:<br />
    <div class="fieldWithErrors">
      <input id="user_login" name="user[login]" size="30" type="text" value="" />
    </div>
  </p>
  -----
  Line 85  Warning: inserting implicit <p>
  Line 89  Warning: trimming empty  <p>

What’s going on here? Since a p can’t contain a div, Tidy thinks you’ve not closed your p tag before you started your div. In addition, it thinks you haven’t opened your p after you’ve closed your div tag. Certainly, knowing your XHTML helps in this situation, since the error it throws is otherwise cryptic; but Tidy gives the clue where to find the error. On a form with a lots of fields, this is really helpful.

Safari Tidy helped me note there was a problem before I even realised that there was a problem—and there really was, the error screwed up my pretty design horribly.

Update: What a wally—I got so wrapped up in Safari Tidy that I didn’t explain how to fix the error! There’s a simple solution: convert your p tags to divs throughout. I don’t know why Rails screws this up in the first place—Rails seems to have been designed pretty well & this is a glaring oversight. It’s really bothersome to have to fix every automatically-generated form.