Personal tools

Webwire

From HaskellWiki

(Difference between revisions)
Jump to: navigation, search
(New page: Examples ======== As multiple people have asked for examples now, I'm providing some. Here is the obligatory Hello World application, which just displays a text/plain string: <haskell> ...)
 
(Examples: Added categories)
 
(One intermediate revision by one user not shown)
Line 1: Line 1:
Examples
+
== Examples ==
========
 
   
 
As multiple people have asked for examples now, I'm providing some. Here is the obligatory Hello World application, which just displays a text/plain string:
 
As multiple people have asked for examples now, I'm providing some. Here is the obligatory Hello World application, which just displays a text/plain string:
Line 78: Line 78:
 
session defSessionCfg home -< ()
 
session defSessionCfg home -< ()
 
</haskell>
 
</haskell>
  +
  +
[[Category:Packages]]
  +
[[Category:FRP]]
  +
[[Category:Web]]
  +
[[Category:Tutorials]]

Latest revision as of 18:13, 16 September 2011

[edit] Examples

As multiple people have asked for examples now, I'm providing some. Here is the obligatory Hello World application, which just displays a text/plain string:

import Network.Wai.Handler.Warp
import WebWire
 
main :: IO ()
main =
    simpleWire (run 4000) $ proc _ ->
        render -< "Hello world!" :: String

Here is a slightly more interesting example showing how to use widgets:

main :: IO ()
main =
    simpleWire (run 4000) $ proc _ -> do
        addWidget -< cssW "html { background: #aaa; }"
        addWidget -< bodyW (He.h1 (toHtml ("Hello world!" :: String)))
        renderDef -< ()

Routing works through wire combination and signal inhibition. A wire can inhibit the output signal. This normally corresponds to a 404 error, though other errors are possible. Multiple wires can be combined. If one wire inhibits, the next is tried. If all wires inhibit, their sum inhibits. On its surface this is similar to how Happstack handles routing, but has a different underlying machinery. Also here I'm using Hamlet, Lucius and the 'time' wire to demonstrate how state is managed in this FRP-based framework:

home :: WebWire site a Response
home =
    rootDir $ proc _ -> do
        t <- time -< ()
        addWidget <<< cssLinkW ^<< pathAbs -< ["style", "test.css"]
        addWidget -< hamletW [hamlet|
            <h1>Hello world!
            <p>This server has been running for #{t} seconds.|]
        renderDef -< ()
 
 
style :: WebWire site a Response
style =
    directory "style" . file "test.css" $ proc _ -> do
        render -< [lucius| html { background: #aaa; } |] (\_ _ -> "")
 
 
main :: IO ()
main =
    let apps = style <+> home in
    simpleWire (run 4000) $ proc _ -> do
        setRoot -< ["http://localhost:4000"]
        apps -< ()

For sessions you use the 'session' wire transformer. This is one of the most interesting features. The following website allows each session a maximum request rate of 10 requests per second:

home :: WebWire site a Response
home =
    rootDir $ proc _ -> do
        t <- time -< ()
        fps <- avgFps 10 -< ()
        require_ -< fps <= 10
 
        fpsHi <- highPeak -< fps
        fpsLo <- lowPeak -< fps
 
        addWidget -< hamletW [hamlet|
            <h1>Hello world!
            <p>This session has been running for #{t} seconds.
            <p>Requests per second: #{fps} (high peak: #{fpsHi}) (low peak: #{fpsLo})|]
        renderDef -< ()
 
 
main :: IO ()
main =
    simpleWire (run 4000) $ proc _ -> do
        setRoot -< ["http://localhost:4000"]
        session defSessionCfg home -< ()