The following example highlights the basics of mixing XML and Haskell together. This example uses HSP, but not HAppS.
The first thing to notice is the extra options we pass to GHC, namely -F -pgmF trhsx
. This tells GHC (and GHCi) to call trhsx
to pre-process the source code before trying to compile it. trhsx
will automatically translate the XML syntax into normal Haskell code which the compiler can understand.
Next we see how to write a simple function which generates XML using the special XML syntax as well as dynamically creating some of the XML using ordinary Haskell expressions.
> > -- |hello creates a simple helloHello, <% map toUpper noun %>
> > >To use the XML syntax, we just use it -- no special escaping is required to insert XML in the middle of a Haskell expression. On the other hand, if we want to evaluate a Haskell expression and insert it into the XML, then we need the special <% %>
escape clause. If we had just written, <title> Hello, noun</title> then the title
would have been Hello, noun. Likewise, if we did not have the <% %>
around map toUpper noun
, the page would say, "Hello map toUpper noun" instead of evaluating map toUpper noun
and substituting the result in.
We can evaluate any arbitrary expression inside the <% %>
, provided HSP knows how to turn the result into an XML value. By default, HSP knows how to handle String
, Char
, numbers, and some other common Haskell data-types. You can add additional class instances if you want to convert other datatypes (including your own) to XML automatically.
Next we have a simple main
. The first line evaluates
hello
and gets back the generated XML. The second
line uses renderAsHtml
to turn the XML into
HTML. renderAsHtml
expects you to pass in valid XHTML
which it will transform into valid HTML. However, it does not check
the validity of the input or output. We will do that using a more
general mechanism in the HAppS code.
If we run this example, we get the following output:
<html ><head ><title >Hello, World</title ></head ><body ><p >Hello, WORLD</p ></body ></html >
The formatting probably looks a bit funny to you -- but the web browser will read it fine. In HTML, the whitespace between the open and close tags is sometimes significant. However, the whitespace inside the open or close tag itself is never significant. The rendering algorithm is designed to exploit those properties to ensure it never adds significant whitespace where you didn't explicit have it in the input file.