Once you have model and routes in place and constrained, the last piece of the puzzle is to write a function that takes both as arguments and returns file content (lazy bytestring, to be exact) to generate. This function can be as simple as the following:
render :: MyModel -> Route -> Asset ByteString render model route = AssetGenerated Html "<b>Hello</b>, world!"
AssetGenerated Html tells Ema that you are generating HTML content, which will be appropriately handled by the Hot Reload of the live server.
Of course we want it to be real, by using our model value, as well as generate the HTML based on the route. We will also use the blaze-html library to make writing HTML in Haskell palatable. A more realistic starting point (if not the finishing product) would be:
render :: MyModel -> Route -> Asset ByteString render model route = AssetGenerated Html . Blaze.renderHtml $ H.html $ do H.head $ do H.title "My site" H.base ! A.href "/" -- This is important H.body $ do H.h1 "My site" case route of Index -> H.h1 "Welcome to my website!" H.p $ do "Checkout the" H.a ! A.href (H.toValue $ Ema.routeUrl About) $ "About" " page." About -> H.div $ H.p "This website is managed by yours truly" H.footer $ do A.a ! A.href "https://github.com/user/repo" $ "Source on GitHub"
Note that Ema provides a
routeUrl helper function that serializes your route to the final URL (here,
/about) for linking to. There is also a
routeUrlWith function which allows you to disable pretty URLs, to get back the
.html suffix for deployments to traditional web servers like Nginx, Gitlab, etc.
Spend a few moments trying to appreciate how this is much simpler to write than dealing with HTML template files spread across the disk as is the case with traditional static site generators. If you choose to go the DSL route, Haskell’s type-safety now applies to your HTML as well. On top of it, Ema’s hot reload will instantly update the dev server’s browser view whenever you change your HTML (or any of the Haskell source code).
Next, you might want to peruse Howto.