loli: A minimum web dev DSL in Haskell

[ bsd3, deprecated, library, web ] [ Propose Tags ]
Deprecated. in favor of miku

A simple library for fast web prototyping in Haskell.

[Skip to Readme]
Versions [faq] 2009.6.25, 2009.6.26, 2009.6.27, 2009.6.29, 2009.7.2, 2009.8.16, 2009.8.18, 2009.10.13, 2010.10.9, 2011.6.24
Change log
Dependencies base (>4 && <=5), bytestring, containers, data-default, hack (>=2009.7.15), hack-contrib (>=2009.8.18), mps (>=2009.8.18.1), mtl, template, utf8-string [details]
License BSD-3-Clause
Author Wang, Jinjing
Maintainer Wang, Jinjing <>
Category Web
Home page
Uploaded by JinjingWang at 2009-08-18T13:59:11Z
Distributions NixOS:2011.6.24
Downloads 6192 total (22 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Hackage Matrix CI
Docs uploaded by user
Build status unknown [no reports yet]




Maintainer's Corner

For package maintainers and hackage trustees

Readme for loli-2009.8.18

[back to package description]


A minimum web dev DSL


First app

-- myapp.hs

import Network.Loli
import Hack.Handler.Happstack
import MPS.Light ((-))
import Prelude hiding ((-))

main = run . loli - get "/" (text "loli power")

Install and compile:

cabal update
cabal install loli
cabal install hack-handler-happstack

ghc --make myapp.hs

check: http://localhost:3000



get "/" - do
  -- something for a get request

post "/" - do
  -- for a post request

put "/" - do
  -- put ..

delete "/" - do
  -- ..


get "/say/:user/:message" - do
  text . show =<< captures

-- /say/jinjing/hello will output
-- [("user","jinjing"),("message","hello")]


-- public serve, only allows `./src`
public (Just ".") ["/src"]

Views root

-- in `./views`, can be changed by
views "template"


Text Template

import Network.Loli.Template.TextTemplate

get "/hi/:user" - output (text_template "hello.html")

-- in hello.html
  <p>hello $user</p>

Local binding

get "/local-binding" - do
  bind "user" "alice" - output (text_template "hello.html")

Batched local bindings

get "/batched-local-binding" - do
  context [("user", "alice"), ("password", "foo")] - 
    text . show =<< locals


Partials are treated the same as user supplied bindings, i.e. the rendered text is available to the rest of templates, referenced by user supplied keywords.

with single partial

import Network.Loli.Template.ConstTemplate

get "/single-partial" - do
  partial "user" (const_template "const-user") - do
    text . show =<< template_locals

with batched partials

get "/group-partial" - do
    [ ("user", const_template "alex")
    , ("password", const_template "foo")
    ] - output (text_template "hello.html")



get "/with-layout" - do
  with_layout "layout.html" - do
    text "layout?"

-- in layout.html
  <h1>using a layout</h1>


layout "layout.html"

By passed

get "/no-layout" - do
  no_layout - do
    text "no-layout"

Mime types

-- treat .hs extension as text/plain
mime "hs" "text/plain"


-- before takes a function of type (Env -> IO Env)
before - \e -> do
  putStrLn "before called"
  return e

-- after takes that of type (Response -> IO Response)
after return

On the fly router switcher

The router can be switched at any time, it will effect any route path that follows.

router loli_router

Hack integration

Use hack middleware

import Hack.Contrib.Middleware.ETag
import Hack.Contrib.Middleware.Lambda

middleware etag
middleware lambda

Convert loli into a hack application

-- in Network.Loli.Engine

loli :: Unit -> Application


use the git version ...