---
title: More on compilers: load, and templates
author: Jasper Van der Jeugt
---
Loading items
-------------
The compiler Monad is a complex beast, but this is nicely hidden for the user of
the Hakyll library.
Suppose that you're generating `index.html` which shows your latest brilliant
blogpost. This requires `posts/foo.markdown` to be generated *before*
`index.html` (so we don't have to generate it twice). But you don't have to care
about any of that: Hakyll will sort this out for you automatically!
Let's see some quick examples. We can load a specific item:
```haskell
load "posts/foo.markdown" :: Compiler (Item String)
```
Or a whole bunch of them:
```haskell
loadAll "posts/*" :: Compiler [Item String]
```
Sometimes you just want the *contents* and not the `Item`:
```haskell
loadBody "posts/foo.markdown" :: Compiler String
```
This is all useful if we want to use Hakyll's templating system.
Basic templates
---------------
Let's have a look at a simple template:
$title$
Posted on $date$
$body$
As you can probably guess, template files just contain text and only the `$`
character has special meaning: text between dollar signs ("fields") is replaced
when the template is applied. If you want an actual dollar sign in the output,
use `$$`.
We can easily guess the meaning of `$title$`, `$date$`, and `$body$`, but these
are not hard-coded fields: they belong to a certain [Context]. A `Context`
determines how the fields are interpreted. It's a [Monoid] and therefore very
composable.
[Context]: /reference/Hakyll-Web-Template-Context.html
[Monoid]: http://learnyouahaskell.com/functors-applicative-functors-and-monoids
`field` allows us to create a `Context` for a single field:
```haskell
field :: String -> (Item a -> Compiler String) -> Context a
```
Let's try this out. Note that this is for illustration purposes only: you
shouldn't have to write complicated fields often. We can implement the `$body$`
field like this:
```haskell
field "body" $ \item -> return (itemBody item) :: Context String
```
And `$title$` like this:
```haskell
titleContext :: Context a
titleContext :: field "title" $ \item -> do
metadata <- getMetadata (itemIdentifier item)
return $ fromMaybe "No title" $ M.lookup "title" metadata
```
And compose them using the `Monoid` instance:
```haskell
context :: Context String
context = mconcat
[ titleContext
, field "body" $ return . itemBody
]
```
TODO: Write about defaultContext. Extend it with dateField.
You usually compile the templates from disk using the aptly named
`templateCompiler`:
match "templates/*" $ compile templateCompiler
Notice the lack of `route` here: this is because we don't need to write the
templates to your `_site` folder, we just want to use them elsewhere.
Using them elsewhere is easy: we just use `load`!
TODO: Full example: load template, apply. Then `loadAndApplyTemplate`.
TODO: Load a list of posts, demonstrate `applyTemplateList`.