Thursday, March 6, 2008

To Template Or Not To Template

Since developing the tutorial in the last few posts, I have been working on developing a real web app in Haskell with HAppS. Now that I know my way around the basics of HAppS, I need to move on to generating actual HTML (as opposed to the plaint text messages that the tutorial used). Before starting, I had to decide what methodology I would use to generate the HTML. I'm new to web development, so I may be missing something, but as I see it there are three main possibilities:

  1. Serve static pages that use AJAX to load dynamic content
  2. Dynamically generate pages with Haskell and HAppS
  3. Use Haskell to populate static page templates with dynamic content

Let's first take a look at the last option, static templates. Most of the web frameworks that I've seen (ROR and several Python frameworks) use templates. The main argument for them seems to be that templates allow a separation (MVC style) of the view and controller. The page template defines the view and the Python code is the controller. This allows a nice separation between the work areas of the web designer and the programmer. The web designer works with the template, and the programmer works with the code. This is very appealing. HAppS does not have templating built in, but there is a Haskell library called HStringTemplate (based ond the Java StringTemplate library) that will work.

The second option is to avoid templates and use Haskell code to generate HTML. Mixing HTML strings with Haskell code could be ugly, but the Text.HTML or Text.XHTML libraries can be used to make generation relatively painless. The advantage here is that you have more of Haskell's power available at the HTML creation level. This can be used to create better abstractions that can eliminate repetition. It also can eliminate the need to keep variable names synchronized between a template and the code. This gives you better compile-time guarantees of correctness.

Many will argue that these benefits come at the expense of requiring the designer to understand Haskell code. However, after looking at sites like CSS Zen Garden, it seems to me that most of the designer's work can be done in the style sheet. This means that you can generate you can use an external style sheet in haskell-generated HTML and still avoid the need for the designer to understand Haskell. If this is the case and the HTML is carefully designed to properly represent semantic chunks, it seems like it might even be beneficial for the coder (who has to know about page semantics anyway) to generate the HTML.

Now let's look at option #1. The main page on happs.org advocates this approach. HAppS does not come with a server-side templating system. We prefer the pattern of developing static web pages and using AJAX to populate them with dynamic content. I think this is similar to how GMail works. You send one static page at start up that has JavaScript code that makes requests to the server for dynamic data and then does whatever transformation is necessary to display the data on the page.

This approach also allows for good separation of the work of the designer and coder. Additionally, it could reduce the bandwidth requirements for the site because the boilerplate code only has to be transferred once. After that only the dynamic data needs to go across the wire. And since the page is being built on the client, it should reduce the server's CPU load as well. This also makes it easy to separate static content from dynamic content. In a system like this, you could even use HAppS for dynamic content while serving static content with a completely different server like Apache or Lighttpd.

Because of my limited experience with web design, I think I will go with option #2 to start out. I like that it allows me to take advantage of Haskell's functional structures to aid in HTML generation. Since I don't use a graphical HTML tool, templates aren't a high priority. I think the AJAX approach would ultimately be a good one, but I've already got plenty of work cut out for me without adding JavaScript and all it's browser compatibility issues to the mix.

I'd love to hear readers' thoughts about these three approaches. Is there a significant benefit to page templates that I'm missing? I hope to learn more from readers who have more experience in this area.

10 comments:

Vagif Verdi said...

You missed another option. Go with RIA clients (flash flex etc.)

Flex is free and open source.
Flex Builder is commercial, but you do not need it, and if you like it, it is cheap ($250)

mightybyte said...

True. I'm not including RIA clients (although I have thought about them) because I think they're a little overkill for my app and because I'm focusing on server side infrastructure right now. Until I get the server side nailed down a little more, and then see a need for something like Flex on the client side, I prefer $0 to $250.

Andrea Vezzosi said...

Some additional points:
Solution 1) makes the page load time significantly longer, at least judging from happs.org

Solution 2) is nice but sometimes you might need to recompile your app just for a small graphical tweak. But this won't hopeful happen with a well designed html.

Solution 3) could really be a pain depending on the language.

What i'd prefer, but we don't have a library for this yet, is a widget based toolkit for html, a little like the one described here http://www.alpheccar.org/en/posts/show/89

Anonymous said...

One of the main points for option 3 is that, as av wrote, it will let you change templates without recompiling. StringTemplate is a really insanely powerful language for A) being sub-turing and B) therefore preventing the intermixing of view and logic. Of course, I got to really like the language as I was developing hstringtemplate, so I'm biased, but it should give you some suprisingly elegant power.

Also, a strike in favor of giving it a shot is the syb-with-class support that I built in, which should, in theory, let you pass all your fancy happs structures deriving data directly into the page where you can traverse them easily. this might, in fact, be somewhat cleaner than manipulating them in Haskell directly.

again, of course, i'm biased. :-)

migmit said...

I think that the first and the third options are not exactly opposite. Suppose you choose the first one; then your javascript should know where to put the information coming from the server via AJAX. It seems that one can use template system to generate both "static" web page AND javascript to fill it.
Hmmm... I should really think about this idea...

Anonymous said...

some thought coming from a css guy :
1)is terrible for accessibility reasons : if you user don't have javascript they cannot use your site

2) when you say most can be done by CSS, you need to realize that CSS Zen garden has no dynamic content. When you need maximum flexibility it is a bonus to be able to tweak the HTML as well as the CSS...
So that kind of rule out 2), I don't expect the average CSS guy to be willing to deal with Haskell

mightybyte said...

Yeah, I realize that CSS Zen Garden isn't dynamic, but I see no reason why the same thing couldn't be done with a dynamic application. The caveat is that you would have to have a very well-designed static structure for the dynamic HTML. If you can do it right, it would be great. If you can't then I agree that the CSS guys probably won't know Haskell. In that case, the Haskell developers and CSS designers would have to collaborate.

Anonymous said...

what I meant to say is, CSS layout is a lot easier when you know how much content you are dealing with beforehand - positioning becomes very tempting...

It's rarely an option with dynamic content. When using positioning, any column with too much content might run over your footer for instance... So you have to use floats, which depends on HTML order...

jeff said...

Using Javascript as a templating language is a horrible idea in my opinion. It's slow, it's ugly (worked with the DOM lately?), it's browser-dependent, and it doesn't work with people who have Javascript turned off (some people have it turned off for them and it isn't under their control, some people turn it off for security reasons, etc). Gmail does use javascript intensively, but it also offers a plain HTML option as an alternative.

Solution 2 is cool. I think you could make a DSL in haskell that a designer could understand. It's obviously not a good approach if you are designing a community site where end-users can write their own templates.

Solution 3 is my favorite. I'm waiting for (or maybe writing at some point) something like Python's Genshi-- an HTML template library (rather than a string template library).

Anonymous said...

If you're generating HTML, you should use a template. Try to keep markup separate from everything else. A good structuring principle is to keep content, styling and functionality separate. MVC is another good one. From another perspective, you definitely want a DSL for generating HTML (and templating languages are DSLs for this).

There's broadly two successful templating approaches - XSLT-like and velocity-like. Haskell can do both quite easily.