Haskell implementation of Liquid templating by Shopify
Haskell Ruby
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
src/Text
test
Gemfile
Gemfile.lock
Guardfile
README.md
liquid.cabal

README.md

Liquid Haskell

Haskell implementation of Liquid templating by Shopify.

Installation

$ git clone https://github.com/pbrisbin/liquid && cd liquid
$ cabal sandbox init
$ cabal install --dependencies-only -- enable-tests

Usage

Generally speaking, the function liquid takes an object with a valid ToJSON instance and template content as Text. It returns either Left error-message or Right processed-template.

How you come about this jsonify-able object or the textual template is your business, but here is an example of how I might do things:

{-# LANGUAGE OverloadedStrings #-}

import Data.Aeson
import Data.Text (Text)
import Text.Liquid

import qualified Data.Text as T

data Post = Post { postTitle :: Text }

data User = User
    { userName  :: Text
    , userAge   :: Int
    , userPosts :: [Post]
    }

instance ToJSON Post where
    toJSON (Post title) = object ["title" .= title]

instance ToJSON User where
    toJSON (User name age posts) =
      object [ "name"  .= name
             , "age"   .= age
             , "posts" .= map toJSON posts
             ]

liquid (User "Pat" 28 [Post "Post one", Post "Post two"]) $
    T.unlines [ "Name: {{name}}"
              , "Age:  {{age}}"
              , "Posts:"
              , "{% for post in posts %}"
              , "  * {{post.title}}"
              , "{% endfor %}"
              ]

This may seem verbose as a standalone example, but in a framework-using web application (like Yesod), you'll likely already have models with ToJSON instances.

A more realistic use case may simply be:

myHandler :: UserId -> Handler Html
myHandler userId = do
    user     <- get404 userId
    template <- T.readFile "templates/user.html"

    return . preEscapedToMarkup
           $ either errorHandler id
           $ liquid user template

Testing

Running all specs:

$ cabal test

Running one spec:

$ cabal exec -- ghc -isrc -itest -e main test/Text/Liquid/RenderSpec.hs

Continuously run specs as files are edited:

$ gem install bundler
$ bundle
$ bundle exec guard