public
Description: A minimum web dev DSL in Haskell
Homepage:
Clone URL: git://github.com/nfjinjing/loli.git
nfjinjing (author)
Mon Oct 19 11:44:31 -0700 2009
commit  1f98c547394b3d14cea9804b5dec9744e0a20710
tree    e96a5ae0e4280c98d44c74e34ac7be753d0fc2e2
parent  f6140f0c155f81f7590cba5d37197834eb1b6f08 parent  950aa8e33ed0e8477e10a8a5cff7d5112326f298
loli /
name age message
file .gitignore Mon Jun 29 05:03:43 -0700 2009 add public resource [nfjinjing]
file LICENSE Loading commit data...
file Nemesis
file Setup.lhs Thu Jun 25 05:59:35 -0700 2009 init [nfjinjing]
file changelog.md
file known-issues.md Wed Jul 01 10:40:15 -0700 2009 fix safari bug, by setting default status to 200 [nfjinjing]
file loli.cabal
directory public/ Mon Jun 29 06:53:34 -0700 2009 no top line [nfjinjing]
file readme.md
file release.md
directory src/
directory views/ Mon Jun 29 06:53:34 -0700 2009 no top line [nfjinjing]
directory wiki/
readme.md

loli

A minimum web dev DSL

Example

First app

-- myapp.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 myapp.hs
./myapp

check: http://localhost:3000

Routes

Verbs

-- use - instead of $ for clarity
import MPS.Light ((-))
import Prelude hiding ((-))

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

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

put "/" - do
  -- put ..

delete "/" - do
  -- ..

Captures

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

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

Static

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

Views root

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

Template

Text Template

import Network.Loli.Template.TextTemplate

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

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

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

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
  partials 
    [ ("user", const_template "alex")
    , ("password", const_template "foo")
    ] - output (text_template "hello.html")

Layout

Local

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

-- in layout.html
<html>
<body>
  <h1>using a layout</h1>
  $content
</body>
</html>

Global

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"

Filters

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

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

Note

use the git version ...

Wiki

Reference