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 [RSS] [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.5.19), hack-contrib (>=2009.6.25), mps (>=2009.6.25), mtl, template, utf8-string [details]
License BSD-3-Clause
Author Wang, Jinjing
Maintainer Wang, Jinjing <>
Category Web
Home page
Uploaded by JinjingWang at 2009-06-29T14:14:05Z
Distributions NixOS:2011.6.24
Downloads 6527 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.6.29

[back to package description]


A minimum web dev DSL


First app

-- myloli.hs

import Network.Loli
import Hack.Handler.Happstack

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

Install and compile:

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

ghc --make myloli.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

-- template
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

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"

Hack integration

Use hack middleware

import Hack.Contrib.Middleware.ETag
import Hack.Contrib.Middleware.ShowStatus

middleware etag
middleware show_status

Convert loli into a hack application

-- in Network.Loli.Engine

loli :: Unit -> Application


If you see this, use the git version!