hakyll-4.11.0.0: A static website compiler library

Safe HaskellNone
LanguageHaskell2010

Hakyll.Web.Template

Description

This module provides means for reading and applying Templates.

Templates are tools to convert items into a string. They are perfectly suited for laying out your site.

Let's look at an example template:

<html>
    <head>
        <title>My crazy homepage - $title$</title>
    </head>
    <body>
        <div id="header">
            <h1>My crazy homepage - $title$</h1>
        </div>
        <div id="content">
            $body$
        </div>
        <div id="footer">
            By reading this you agree that I now own your soul
        </div>
    </body>
</html>

As you can see, the format is very simple -- $key$ is used to render the $key$ field from the page, everything else is literally copied. If you want to literally insert "$key$" into your page (for example, when you're writing a Hakyll tutorial) you can use

<p>
    A literal $$key$$.
</p>

Because of it's simplicity, these templates can be used for more than HTML: you could make, for example, CSS or JS templates as well.

Apart from interpolating $key$s from the Context you can also use the following macros:

  • $if(key)$
$if(key)$
 <b> Defined </b>
$else$
 <b> Non-defined </b>
$endif$

This example will print Defined if key is defined in the context and Non-defined otherwise. The $else$ clause is optional.

  • $for(key)$

The for macro is used for enumerating Context elements that are lists, i.e. constructed using the listField function. Assume that in a context we have an element listField "key" c itms. Then the snippet

$for(key)$
  $x$
$sep$,
$endfor$

would, for each item i in itms, lookup $x$ in the context c with item i, interpolate it, and join the resulting list with ,.

Another concrete example one may consider is the following. Given the context

listField "things" (field "thing" (return . itemBody))
   (sequence [makeItem "fruits", makeItem "vegetables"])

and a template

 I like
 $for(things)$
   fresh $thing$$sep$, and
 $endfor$

the resulting page would look like

<p>
 I like

  fresh fruits, and

  fresh vegetables
</p>

The $sep$ part can be omitted. Usually, you can get by using the applyListTemplate and applyJoinListTemplate functions.

  • $partial(path)$

Loads a template located in a separate file and interpolates it under the current context.

Assuming that the file test.html contains

<b>$key$</b>

The result of rendering

<p>
  $partial("test.html")$
</p>

is the same as the result of rendering

<p>
  <b>$key$</b>
</p>

That is, calling $partial$ is equivalent to just copying and pasting template code.

In the examples above you can see that the outputs contain a lot of leftover whitespace that you may wish to remove. Using $- or -$ instead of $ in a macro strips all whitespace to the left or right of that clause respectively. Given the context

listField "counts" (field "count" (return . itemBody))
   (sequence [makeItem "3", makeItem "2", makeItem "1"])

and a template

<p>
    $for(counts)-$
      $count$
      $-sep$...
    $-endfor$
</p>

the resulting page would look like

<p>
    3...2...1
</p>

Synopsis

Documentation

data Template Source #

Datatype used for template substitutions.

template :: [TemplateElement] -> Template Source #

Wrap the constructor to ensure trim is called.

templateBodyCompiler :: Compiler (Item Template) Source #

Read a template, without metadata header

templateCompiler :: Compiler (Item Template) Source #

Read complete file contents as a template

applyTemplate Source #

Arguments

:: Template

Template

-> Context a

Context

-> Item a

Page

-> Compiler (Item String)

Resulting item

loadAndApplyTemplate Source #

Arguments

:: Identifier

Template identifier

-> Context a

Context

-> Item a

Page

-> Compiler (Item String)

Resulting item

The following pattern is so common:

tpl <- loadBody "templates/foo.html"
someCompiler
    >>= applyTemplate tpl context

That we have a single function which does this:

someCompiler
    >>= loadAndApplyTemplate "templates/foo.html" context

applyAsTemplate Source #

Arguments

:: Context String

Context

-> Item String

Item and template

-> Compiler (Item String)

Resulting item

It is also possible that you want to substitute $key$s within the body of an item. This function does that by interpreting the item body as a template, and then applying it to itself.