Home > FireCore > HTML Abstraction (Building the MDB part 3)

HTML Abstraction (Building the MDB part 3)

Last week we built the first few pages for The Music Database, to show how everything hangs together. Before we delve a little deeper into some more complex pages, we’ll look at cleaning up the HTML.

We left our CD details page looking like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  [% META browser_title = "CD details" %]
  <h1>[% cd.title %]</h1>
  <h2>
    <a href="/show/artist/[% cd.artist.id %]">
     [% cd.artist.name %]
    </a>
  </h2>
  <p>Length: [% cd.length %]</p>
  <p>Tracks:
     <ol>
       [% FOREACH track = cd.tracks %]
       <li>track.title</li>
       [% END %]
     </ol>
  </p>
</code>

FireCore provides a set of macros specially designed for outputting HTML. Using these, the top half of our page above will now look like:

1
2
3
4
5
6
7
  [%
     META browser_title = "CD details";
     h1("cdTitle", cd.title);
     h2("artistName",
        a("artistLink", "/show/artist/$cd.artist.id", cd.artist));
     p("cdLength", cd.length);
  %]

So, why bother? What’s wrong with just using HTML.

Well, nothing really. If you prefer, you can just write your page in that manner. As we’ve already seen, it works just fine. But personally, I prefer a little abstraction.

As you’ll have noticed, the HTML we produced from this new version isn’t quite the same as the previous one. We didn’t say h1(cd.title) – we said h1(“cdTitle”, cd.title). If you’re actually trying out the examples as we go, you’ll have noticed that doesn’t generate the plain <h1> we had before, but adds a CSS class to it: <h1 class=”cdTitle”>. It’s always a good idea to add CSS to things so that you can style how they look in your stylesheet. But when I’m writing HTML I often forget. I’m too busy trying to ensure that I print all the right things to make sure that I print everything right.

So all our HTML macros will insist we add a CSS style by making it the first argument we pass. If we forget to pass it, and instead wrote something like [% h1("Title") %] this would become <h1 class="Title"></h1> and we’d notice that it was missing from the page and quickly fix the problem.

We can also nest tags easily and neatly:

3
4
     h2("artistName",
        link("artistLink", cd.artist.name, "/show/artist/$cd.artist.id"));

This approach also makes sure we write correct HTML. All the macros ensure that tags are correctly closed, in the correct order.

We also get the slight benefit that the HTML we generate is slightly future-proof. Our macros currently output XHTML 1.0. If XHTML 1.4 comes along in a few years time and changes how certain tags work, we should only need to change our macros file for this change to take effect across our entire site. Similarly if we wish to emit HMTL 4.2.

None of these reasons are probably enough to justify learning what is basically a new language (and a quite tricky one unless you’ve used Lisp or somesuch). But it gives us the grounding for more significant changes.

We’re probably going to be linking to artist pages quite often throughout the site. So, let’s create a macro just for that. FireCore always creates a macros/local file for us in the template tree, so we can just add it in there:

1
2
3
  MACRO link_artist(artist) BLOCK;
    link("artistLink", artist.name, "/show/artist/$artist.id"));
  END;

Now, anywhere we want to link to the artist, we can just call this template, passing it the artist object. So, we can change our CD details template accordingly:

3
     h2("artistName", link_artist(cd.artist));

Now that the link is suitably abstracted away we never need to remember what CSS class name we’re meant to use when we want a link. This small abstraction alone will probably save me hours over the lifetime of this project as I can never remember things like this and would have to always look it up when I wanted to create a new link. And if we want to change the CSS class name, or how an artist URL is constructed, or add a little icon to the link, it would now be trivial – a change we probably wouldn’t have considered before, unless it was really necessary, once the link was embedded in 30 different templates.

Now we’re starting to see the real benefits. Because setting up our Model and Controller are usually so simple, we’ll spend most of our time creating the View in Template Toolkit. So it’ll be important to find the correct abstractions there – not just of CSS styles and URLs, but of design elements. Good design is consistent across a web site, and by definition will appear on multiple pages. Whilst judicious use of CSS can help with this, many design elements are conceptually larger than a style-sheet rule. TT allows us to abstract these away also. Because I’m not a designer, I won’t be showing you much of this. But over the next few days I’ll show how keeping the templates as clean as possible will make life easier for a designer to make the site look much better than I ever could.

Tags:
  1. No comments yet.