MFlow  Create and maintain dynamic Web applications as easy and fast as console applications
Thou shall not write request handlers
 This release: 11/06/2014. (@agocorona) <>< . issues & bugs .  Mflow Source code,     source code of this site

REST navigation: The Web Navigation Monad

The MFlow app server can express routes within normal Haskell monadic code. The FlowM monad backtrack and goes forward to track the URL of any page within the monadic flow.

To make a web application program more close to a plain console application, I created runNavigation, that get the port from the first execution parameter. If not, it read it from the PORT environment variable. If it does not exist, it uses the por 80. 

runNavigation executes a persistent navigation (whose state is logged and later recovered when the process has a timeout).  If the flow is not persistent, it must be prefixed with transientNav.

The result is a more close visualization of what the FlowM monad is: a navigation monad.

This example has two routes (letters and numbers). Each one has a simple succession of pages. The user can navigate forward and backward, introduce any url and the program will track the code of he page to be executed and generated.

Running example

(in the light red box):

Choose between:

letters or numbers

Source code:

{-# OPTIONS  -XCPP #-}
module TestREST(testREST) where
import Data.Monoid
import Data.String

-- to execute it alone, uncomment this
-- #define ALONE
#ifdef ALONE
import MFlow.Wai.Blaze.Html.All
main= runNavigation "" $  transientNav testREST
import MFlow.Wai.Blaze.Html.All hiding(retry, page)
import Menu

-- A menu with two branches, each one is a sucession of pages

-- 9 pages , each page has a restful link (pagem = ask)

-- to run it alone,  delete "import Menu" and uncomment the next lines

-- main= runNavigation "" $ transientNav testREST

-- pagem= page

testREST= do
  option <- page options

  case option  of
    "1" -> do
          page $ wlink "2" << contentFor "1" 
          page $ wlink "3" << contentFor "2"
          page $ wlink "4" << contentFor "3"
          page $ optionsorexit
          return () 
    "a" -> do
          page $ wlink "b" << contentFor "a"
          page $ wlink "c" << contentFor "b"
          page $ wlink "d" << contentFor "c"
          page $ optionsorexit
          return ()

options= h2 << "Choose between:"
         ++> absLink "a" << b << "letters " <++ i << " or "
         <|> absLink "1" << b << "numbers"

optionsorexit= options <|> wlink "home" << p << " or go to home"
          -- if home is pressed, will return(). Otherwise, it will backtrack to one of the
          -- two options since they are abslinks.

contentFor x= do
        p << "page for"
        b << x
        p << "goto next page"
        p << "or press the back button for the previous page"

comments powered by Disqus