This repository is private.
All pages are served over SSL and all pushing and pulling is done over SSH.
No one may fork, clone, or view it unless they are added as a member.
Every repository with this icon (
) is private.
Every repository with this icon (
This repository is public.
Anyone may fork, clone, or view it.
Every repository with this icon (
) is public.
Every repository with this icon (
loli /
| name | age | message | |
|---|---|---|---|
| |
.gitignore | Mon Jun 29 05:03:43 -0700 2009 | |
| |
LICENSE | Wed Sep 16 09:47:35 -0700 2009 | |
| |
Nemesis | Sun Nov 22 12:39:41 -0800 2009 | |
| |
Setup.lhs | Thu Jun 25 05:59:35 -0700 2009 | |
| |
changelog.md | Tue Oct 13 06:59:39 -0700 2009 | |
| |
known-issues.md | Wed Jul 01 10:40:15 -0700 2009 | |
| |
loli.cabal | Tue Oct 13 06:59:39 -0700 2009 | |
| |
public/ | Mon Jun 29 06:53:34 -0700 2009 | |
| |
readme.md | Sun Oct 25 23:45:55 -0700 2009 | |
| |
release.md | Sun Aug 16 08:54:17 -0700 2009 | |
| |
src/ | Sun Nov 22 12:39:41 -0800 2009 | |
| |
views/ | Mon Jun 29 06:53:34 -0700 2009 | |
| |
wiki/ | Fri Jul 03 16:14:57 -0700 2009 |
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 ((-))
import Network.Loli
import Hack.Handler.Happstack
main = run . loli - do
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 ...







