PTI891: Deklarative Programmierung → Web-Applikation mit Happstack Framework Lizenz: BSD3 Author: Happstack team, HAppS LLC Verfechter: Happstack team <[email protected]> Home page: http://happstack.com Dokumentation: http://www.happstack.com/c/view-pageslug/3/documentation/ Package & repositories Hackage - Darcs 15.01.2013 © Erik Seidel 2013 Hallo Welt! module Main where import Happstack.Server (nullConf, simpleHTTP, toResponse, ok) main :: IO () main = simpleHTTP nullConf $ ok "Hello, World!" 15.01.2013 © Erik Seidel 2013 Hallo Welt! Was ist Passiert? Die Funktion Simple HTTP lauscht auf einen Request, ab den Moment, wo das Programm gestartet wird. simpleHTTP :: (ToMessage a) => Conf -> ServerPartT IO a -> IO () 15.01.2013 © Erik Seidel 2013 Hallo Welt! Was ist Passiert? Die Funktion Simple HTTP lauscht auf einen Request, ab den Moment, wo das programm gestartet wird. simpleHTTP :: (ToMessage a) => Conf -> ServerPartT IO a -> IO () Die Konfiguration setzt die Eigenschaften des Servers: data Conf = Conf { port :: Int , validator :: Maybe (Response -> IO Response) , logAccess :: forall t. FormatTime t => Maybe (String -> String -> t -> String -> Int -> Integer -> String -> String -> IO ()) , timeout :: Int } 15.01.2013 © Erik Seidel 2013 Statische Routen I module Main where import Control.Monad import Happstack.Server (nullConf, simpleHTTP, ok, dir) main :: IO () main = simpleHTTP nullConf $ msum [ ok "Hello, World!", ok "Unreachable ServerPartT" ] 15.01.2013 © Erik Seidel 2013 Statische Routen II module Main where import Control.Monad (msum) import Happstack.Server (nullConf, simpleHTTP, ok, dir) main :: IO () main = simpleHTTP nullConf $ msum [ dir "hello" $ ok "Hello, World!", dir "goodbye" $ dir "world" ] 15.01.2013 © Erik Seidel 2013 $ ok "Goodbye, World!" Statische Routen II module Main where import Control.Monad (msum) import Happstack.Server (nullConf, simpleHTTP, ok, dir) main :: IO () main = simpleHTTP nullConf $ msum [ dir "hello" $ ok "Hello, World!", dir "goodbye" $ dir "world" dirs "hello/haskell" $ ok "Hello, Haskell!" ] 15.01.2013 $ ok "Goodbye, World!" © Erik Seidel 2013 Statiche Routen III module Main where import Control.Monad (msum) import Happstack.Server (nullConf, simpleHTTP, ok, dir, path) main :: IO () main = simpleHTTP nullConf $ msum [ dir "hello" $ path $ \s -> ok $ "Hello, " ++ s ] 15.01.2013 © Erik Seidel 2013 Request unterscheiden module Main where import Control.Monad (msum) import Happstack.Server (Method(GET, POST), dir, methodM, nullConf, ok, simpleHTTP) main :: IO () main = simpleHTTP nullConf $ msum [ do methodM GET ok $ "You did a GET request.\n" , do methodM POST ok $ "You did a POST request.\n" , dir "foo" $ do methodM GET ok $ "You did a GET request on /foo\n" ] 15.01.2013 © Erik Seidel 2013 HTML <html> <head> <title>Hello, HSP!</title> <meta content="text/html;charset=utf-8" http-equiv="Content-Type"> </head> <body> <h1>Hello HSP!</h1> <p>We can insert Haskell expression such as this: <% sum [1 .. (10 :: Int)] %></p> <p>We can use the ServerPartT monad too. Your request method was: <% getMethod %></p> </body> </html> 15.01.2013 H.html $ do H.head $ do H.title "Hello Blaze HTML!" H.meta ! A.httpEquiv "Content-Type" ! A.content "text/html;charset=utf-8" sequence_ headers H.body $ do H.h1 $ "Hello Blaze HTML!" H.p $ "We can insert Haskell expression such as this: <% sum [1 .. (10 :: Int)] %>" H.p $ "Symbols like & or > will be escape!" © Erik Seidel 2013 HTML HSX/HSP BlazeHtml <html> <head> <title>Hello, HSP!</title> <meta content="text/html;charset=utf-8" http-equiv="Content-Type"> </head> <body> <h1>Hello HSP!</h1> <p>We can insert Haskell expression such as this: <% sum [1 .. (10 :: Int)] %></p> <p>We can use the ServerPartT monad too. Your request method was: <% getMethod %></p> </body> </html> 15.01.2013 H.html $ do H.head $ do H.title "Hello Blaze HTML!" H.meta ! A.httpEquiv "Content-Type" ! A.content "text/html;charset=utf-8" sequence_ headers H.body $ do H.h1 $ "Hello Blaze HTML!" H.p $ "We can insert Haskell expression such as this: <% sum [1 .. (10 :: Int)] %>" H.p $ "Symbols like & or > will be escape!" © Erik Seidel 2013 HTML HSX/HSP BlazeHtml <html> <head> <title>Hello, HSP!</title> <meta content="text/html;charset=utf-8" http-equiv="Content-Type"> </head> <body> <h1>Hello HSP!</h1> <p>We can insert Haskell expression such as this: <% sum [1 .. (10 :: Int)] %></p> <p>We can use the ServerPartT monad too. Your request method was: <% getMethod %></p> </body> </html> H.html $ do H.head $ do H.title "Hello Blaze HTML!" H.meta ! A.httpEquiv "Content-Type" ! A.content "text/html;charset=utf-8" sequence_ headers H.body $ do H.h1 $ "Hello Blaze HTML!" H.p $ "We can insert Haskell expression such as this: <% sum [1 .. (10 :: Int)] %>" H.p $ "Symbols like & or > will be escape!" Es gibt noch aber auch noch: Hamlet, HStringTemplate, Heist, ... 15.01.2013 © Erik Seidel 2013 HSX/HSP Durch das Vorkompiliren wandelt "trhsx" den XML-Code in Haskell-Ausdrücke um: aus: foo :: XMLGenT (ServerPartT IO) XML foo = <span class="bar">foo</span> wird: foo :: XMLGenT (ServerPartT IO) XML foo = genElement (Nothing, "span") [ asAttr ("class" := "bar") ] [asChild ("foo")] 15.01.2013 © Erik Seidel 2013 MVC Controller Model 15.01.2013 View © Erik Seidel 2013 MVC Controller Model 15.01.2013 View © Erik Seidel 2013 MVC – Controller main :: IO () main = simpleHTTP nullConf $ msum [ -- Seiten-Navigation dir "helloworld" helloWorld, dir "mvc" mvc, dir "defaultlayout" defaultLayout, dir "login" login, startPage ] 15.01.2013 © Erik Seidel 2013 MVC – View startPage :: ServerPart Response startPage = ok $ toResponse $ appTemplate "Deklarative Programmierung!" [H.meta ! A.name "keywords" ! A.content "happstack, StartUp, html"] (H.img !A.class_ "teaser" !A.src "/public/image/dual_neurons.png" !A.alt "teaser") (H.div !A.class_ "content" $ "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. \ \Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla laoreet dolore magna aliquam erat volutpat." ) 15.01.2013 © Erik Seidel 2013 Template (default Layout) appTemplate :: String -> [H.Html] -> H.Html -> H.Html appTemplate title headers body = H.html $ do H.head $ do H.title (H.toHtml title) H.meta ! A.httpEquiv "Content-Type" ! A.content "text/html;charset=utf-8" sequence_ headers H.body $ do body 15.01.2013 © Erik Seidel 2013 Quellen ● ● ● ● ● ● http://happstack.com/clck/view-page-slug/3/doc umentation http://www.haskell.org/haskellwiki/Web/Framew orks http://jaspervdj.be/blaze/docs/index.html http://www.haskell.org/pipermail/haskell-cafe/2 010-April/076856.html http://google.de ... 15.01.2013 © Erik Seidel 2013