servant-stache-0.1.0.0: Content-Types for rendering Mustache in servant

Copyright(c) Tatsuya Hirose 2018
Maintainertatsuya.hirose.0804@gmail.com
Stabilityexperimental
Safe HaskellNone
LanguageHaskell2010

Servant.Mustache

Contents

Description

Rendering Mustache templates with servant using stache. This package is heavily inspired by servant-ede.

This package provides two Content-Types with servant (i.e just like JSON), HTML and Template.

  • HTML takes a filename as parameter and lets you render the template with that name against the data returned by a request handler using the text/html;charset=utf-8 MIME type, XSS-sanitizing the said data along the way.
  • Template does the same except that it's parametrized over the content type to be sent along with the rendered template. Any type that has an Accept instance will do.
Synopsis

Content-Types

data HTML (file :: Symbol) Source #

HTML content type. HTML takes a type-level string which is a filename for the template you want to use to render values. Types used with the HTML content type (like User below) must provide a ToJSON instance.

The filename doesn't contain any extension. For example, if the template filename is user.mustache, HTML takes user as filename.

data User = User { name :: String, age :: Int } deriving (Generic, ToJSON)

type UserAPI = "user" :> Get '[HTML "user"] User

userAPI :: Proxy UserAPI
userAPI = Proxy

server :: Server API
server = pure (User "lambdabot" 31)

main :: IO ()
main = do
  loadTemplates "./templates"
  run 8080 (serve userAPI server)

This will look for a template at ./templates/user.mustache, which could for example be:

<ul>
  <li><strong>Name:</strong> {{ name }}</li>
  <li><strong>Age:</strong> {{ age }}</li>
</ul>

IMPORTANT: it XSS-sanitizes every bit of text in the Value passed to the template.

Instances
Accept (HTML file :: *) Source #
text/html;charset=utf-8
Instance details

Defined in Servant.Mustache

(KnownSymbol file, ToJSON a) => MimeRender (HTML file :: *) a Source #

XSS-sanitizes data before rendering it

Instance details

Defined in Servant.Mustache

Methods

mimeRender :: Proxy (HTML file) -> a -> ByteString #

data Template (ct :: *) (file :: Symbol) Source #

A generic template for any content, parametrized over the content-type (or MIME) associated to the template.

The first parameter is the content-type you want to send along with rendered templates (must be an instance of Accept). The second parameter is the name of (or path to) the template file. Any type used with this content-type (like CSSData below) must have an instance of the ToJSON class.

Here is how you could render and serve, say, CSS (Cascading Style Sheets) templates that make use of some CSSData data type to tweak the styling.

data CSS

instance Accept CSS where
  contentType _ = "text" // "css"

data CSSData = CSSData
  { darken :: Bool
  , pageWidth :: Int
  } deriving (Generic, ToJSON)

type StyleAPI = "style.css" :> Get '[Template CSS "style"] CSSData

style.mustache could for example be:

body {
  {{#darken}}
  background-color: #222;
  color: blue;
  {{/darken}}
  {{^darken}}
  background-color: white;
  color: back;
  {{/darken}}
}

#content {
  width: {{pageWidth}}px;
  margin: 0 auto;
}

A complete, runnable version of this can be found in the examples folder of the git repository

Instances
Accept ct => Accept (Template ct file :: *) Source #

use ct's content-type

Instance details

Defined in Servant.Mustache

(KnownSymbol file, Accept ct, ToJSON a) => MimeRender (Template ct file :: *) a Source #

render the contents of file in the global template store

Instance details

Defined in Servant.Mustache

Methods

mimeRender :: Proxy (Template ct file) -> a -> ByteString #

Loading template files

loadTemplates :: MonadIO io => FilePath -> io () Source #

This function initializes a global template store and fills it with the resulting compiled templates. This function does not scan the directory recursively.

IMPORTANT: Must always be called before starting your servant application.