Links und Funktionen
Sprachumschaltung

Navigationspfad
Sie sind hier: Startseite / Lehre / WS 2014/15 / Fortgeschrittene Funktionale Programmierung / Material / Codebeispiel: Yesod Routing


Inhaltsbereich

Codebeispiel: Yesod Routing

Beispiel zu Routing & Handling mit Yesod

Haskell source code icon YesodRoute.hs — Haskell source code, 3 KB (3144 bytes)

Dateiinhalt

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TemplateHaskell, QuasiQuotes #-}
{-# LANGUAGE ViewPatterns #-}

{- Code aus der Vorlesung 
    Fortgeschrittene Funktionale Programmierung, 
    Wintersemester 2014/15,
    von Steffen Jost, Institut für Informatik, LMU München
    
   Code ist größtenteils entlehnt aus dem Buch
   "Haskell and Yesod" von Michael Snoyman, O'Reilly Verlag 
-}

module Main where

import Yesod
import Data.Text

data App = App
instance Yesod App

data MyPath = MyPath Int Int Int | MyOtherPath Text Text
    deriving (Show,Eq, Read)

maybeRead :: Read a => String -> Maybe a
maybeRead (reads -> [(x,"")]) = Just x
maybeRead _ = Nothing

instance PathMultiPiece MyPath where
    fromPathMultiPiece [x,y,z] = case (rx,ry,rz) of
        (Just v1, Just v2, Just v3) -> Just $ MyPath v1 v2 v3
        _  -> Nothing   
      where
        rx = maybeRead $ unpack x
        ry = maybeRead $ unpack y
        rz = maybeRead $ unpack z
    fromPathMultiPiece [x,y]   = Just $ MyOtherPath x y       
    fromPathMultiPiece _       = Nothing
    
    toPathMultiPiece (MyPath x y z) = Prelude.map (pack.show) [x,y,z]
    toPathMultiPiece (MyOtherPath x y)  = [x,y]
    
mkYesod "App" [parseRoutes|
/               HomeR       GET
/test/*MyPath   MultiR      GET
!/fib/help      FibHelpR    GET
!/fib/#Int      FibR        GET
|]

fib :: Int -> Int
fib n | n < 2     = 1
      | otherwise = fib (n-1) + fib (n-2)
    

toHome = [whamlet|
    <div>
        <a href=@{HomeR}>Back to main page
    |]

getHomeR :: Handler Html
getHomeR = do 
    renderer <- getUrlRender
    defaultLayout $ do
        let foo = fib 20
        setTitle "Tag"
        [whamlet|
<h2>Hello World!!!
Some text that is <i>displayed</i> here.

Geht es Euch gut???!

Der Wert von foo ist #{foo} sonst nix.

<h2>Sitemap:
  <ul>
    $forall r <- routes
      <li>
        <a href=@{r}>#{show r}
        <p>Rendered as #{renderer r}
|]

-- Ein paar Links als Beispiel
routes = [HomeR, FibR 1, FibR 20, FibR 30, FibHelpR, MultiR $ MyPath 1 2 3, MultiR $ MyOtherPath (pack "Foo") "Bar", MultiR $ MyPath 4 5 6]

getMultiR :: MyPath -> Handler Html
getMultiR (MyPath x y z) = defaultLayout $ do   
    setTitle "Tag"
    toWidget [whamlet|
<h2>Werte anzeigen:
<p> Der Wert von x ist #{x} sonst nix.
<p> Der Wert von y ist #{y} sonst nix.
<p> Der Wert von z ist #{z} sonst nix.
|]
    toHome

getMultiR inp@(MyOtherPath x y) = defaultLayout $ do   
    setTitle "Tag"
    toWidget [whamlet|
<h2>Werte anzeigen:
<p> Der Wert von x ist #{x} sonst nix.
<p> Der Wert von y ist #{y} sonst nix.
<p> Der Wert von inp ist #{show inp} sonst nix.
|]
    toHome

getFibR :: Int -> Handler Html
getFibR i = defaultLayout $ do
    [whamlet|
    <h1>Fibonacci 
    <p> #{i}. Fibonacci Number = #{fi}
|]
    toHome
    where
        fi = fib i

getFibHelpR :: Handler Html
getFibHelpR = defaultLayout $ do 
    [whamlet|
    <h2>Help Page
    <p> Just specify a number in the URL-Path!
|]
    toHome

main :: IO ()
main = warp 3000 App

demo (fib -> 1) = "First"
demo (fib -> 2) = "Second"
demo (fib -> 3) = "Third"
demo (fib -> x) = show x

Artikelaktionen


Funktionsleiste