1. new in this version
  2. build a web 2.0 app in happstack
  3. why happstack is cool
  4. getting started with happstack
  5. prerequisites
  6. cabal install me
  7. first shot at happstack
  8. url handling
  9. basic HTML inclusion
  10. templates
  11. stringtemplate basics
  12. debugging
  13. form data: get and post
  14. form data: file uploads
  15. cookies
  16. introduction to macid
  17. first steps with macid
  18. scaling with multimaster
  19. using macid safely
  20. macid dummy data
  21. changing the data model
  22. macid stress test
  23. limitations of macid
  24. foreign characters
  25. IxSets
  26. cron jobs
  27. thanks
  28. appendix (floundering in ghci)

Templates -- So You Don't Repeat Yourself

Every page in this tutorial has certain things in common -- the header and menu bar for example. You wouldn't want to have have to change the menu bar on every single page if there was a new menu item.

This is why you need a templating system.

Again, Happstack doesn't care much what templating system you use. I use the HStringTemplate package to get the job done, so that's the syntax you'll be seeing in what follows.

A templating system also helps you individualize output. The way this works is by inserting variable text into placeholder templates. For instance, the menu bar in this tutorial displays "logout your_username" if you are logged in, rather than the login/register options. The line below does this too, just for teaching purposes. If you are logged in, it will display your username.

Logged In? Let's see:

Have a look at the template responsible for the content pane of this page. It's pretty boring, except the line above reads as

" Logged In? Let's see: $ loggedInUser $ "

Now, if you are running this tutorial locally, load up ghci by running ./hackInGhci

You can see the effect of rendering the current content pane by calling

*Main> :m +Misc View Text.StringTemplate
*Main Misc View Text.StringTemplate> do templates <- directoryGroup "templates" ; writeFile "output.html" $ renderTemplateGroup templates ([]::[(String,String)]) "templatesdontrepeatyourself"

and then opening the file output.html in firefox. (On ubuntu, in ghci, I just do ":! firefox output.html &" and the file opens in a new tab in firefox.)

To see how this page would look if you were logged in:

*Main Misc View Text.StringTemplate> do templates <- directoryGroup "templates" ; writeFile "output.html" $ renderTemplateGroup templates [("loggedInUser","DarthVader")] "templatesdontrepeatyourself"

and reopen output.html in your browser.

It's not too much fun to develop a web page by outputting a string to a static file and then opening it in a browser every time something changes, so the next thing you might want to try is actually modifying the current template (in ./templates/templates-dont-repeat-yourself.st) with some random text, reloading this actual page, and watching your changes appear.

We'll learn some StringTemplate basics next.