----------------------------------------------------------------------------- -- -- Module : Menu -- Copyright : -- License : BSD3 -- -- Maintainer : agocorona@gmail.com -- Stability : experimental -- Portability : -- -- | This is the menu shared by all the demo modules of demos-blaze.hs -- ----------------------------------------------------------------------------- {-# LANGUAGE DeriveDataTypeable, OverloadedStrings , QuasiQuotes #-} module Menu where import Data.Typeable import MFlow.Wai.Blaze.Html.All hiding (article, source,page,ask) import qualified MFlow.Wai.Blaze.Html.All as MF(page,ask) import Text.Blaze.Html5 as El hiding (article, source) import Text.Blaze.Html5.Attributes as At hiding (step) import Data.Monoid import Data.String import Data.TCache.Memoization import Data.TCache.IndexQuery import Data.List(isPrefixOf) import Language.Haskell.HsColour import Language.Haskell.HsColour.Colourise import Text.Hamlet import System.IO.Unsafe --import Debug.Trace --(!>) = flip trace newtype Filename= Filename String deriving Typeable adminname= "admin" edadmin= "editor" -- present the widget w decorated with the main menu on the left and the source code at the bottom page w= MF.ask $ do us <- getCurrentUser if us == anonymous then public else private filename <- getSessionData tFieldEd edadmin "head" "set Header" **> (El.div ! At.style "float:right" <<< wlogin ) <++ hr **> (divmenu <<< br ++> retry mainMenu) **> (El.div ! At.style "float:right;width:65%;overflow:auto;" <<< (insertForm $ widgetAndSource filename w)) divmenu= El.div ! At.style ("background-color:#EEEEEE;float:left\ \;width:30%;margin-left:10px;margin-right:10px;overflow:auto;") --topLogin= El.div ! At.style "float:right;top:5px;left:5px" -- <<< autoRefresh (pageFlow "login" wlogin) ask= page data Options= Wiki | CountI | CountS | Radio | Login | TextEdit |Grid | Autocomp | AutocompList | ListEdit |Shop | Action | Ajax | Select | CheckBoxes | PreventBack | Multicounter | Combination | ShopCart | MCounter | InitialConfig | SearchCart | FViewMonad | Counter | WDialog |Push |PushDec |Trace | RESTNav | Database | MFlowPersist | AcidState | DatabaseSamples |PushSamples | ErrorTraces | Flows | BasicWidgets | MonadicWidgets | DynamicWidgets | LoginLogout | Templates | RuntimeTemplates | LoginWidget | CacheDataset | ComplexThings | GenerateForm | GenerateFormUndo | GenerateFormUndoMsg | LazyLoad deriving (Bounded, Enum,Read, Show,Typeable) auto w= autoRefresh $ public >> maxAge 300 >> w mainMenu :: View Html IO Options mainMenu= pageFlow "" $ -- bad practice: pageflows should have a non null string -- but that would change the URLs of the options -- and they are published as such. -- that would produce collisions in identifiers with other -- widgets ul<<<(li << a ! href "/" << b "HOME" ++> tFieldEd "editor" "othermenu" "Other menu options" **> (li <<< (absLink Wiki << b "Wiki") ) <|> li << (b "About this menu" <> article cascade <> article menuarticle) ++> hr ++> ((auto $ li <<< do absLink BasicWidgets << b "Basic Widgets" ul <<< (hr ++>(li <<< (absLink CountI << b "Increase an Int") li <<< (absLink CountS << b "Increase a String") li <<< (absLink Select << b "Select options") li <<< (absLink CheckBoxes << b "Checkboxes") li <<< (absLink Radio << b "Radio buttons") (auto $ li <<< do absLink DynamicWidgets << b "Dynamic Widgets" <++ " Widgets with Ajax and containers of other widgets" ul <<< (hr ++>(li <<< (absLink Ajax << b "AJAX example") article ajaxl <|> li <<< (absLink Autocomp << b "autocomplete") li <<< (absLink AutocompList << b "autocomplete List") article editList <|> li <<< (absLink ListEdit << b "list edition") li <<< (absLink Grid << b "grid") article gridl <> hr))) <|> (auto $ li <<< do absLink MonadicWidgets << b "Monadic widgets, actions and callbacks" <++ " autoRefresh, page flows, dialogs etc" ul <<< (hr ++>(li <<< (absLink Action << b "Example of action") li <<< (absLink FViewMonad << b "in page flow: sum of three numbers") article pageflow <|> li <<< (absLink Counter << b "Counter") article callbacks <|> li <<< (absLink Multicounter << b "Multicounter") article callbacks <|> li <<< (absLink Combination << b "Combination of three dynamic widgets") article combinationl <|> li <<< (absLink WDialog << b "Modal dialog") hr))) <|> (auto $ li <<< do absLink DatabaseSamples << b "Database examples" <++ " with different backends" ul <<< (hr ++>(li <<< (absLink SearchCart << b "Shopping with data tier, queries and full text search") article searchcart <|> li <<< (absLink MFlowPersist << b "Persistent") li <<< (absLink Database << b "Database") article amazonarticle <|> li <<< (absLink AcidState << b "Acid State") (auto $ li <<< do absLink PushSamples << b "Push Samples" <++ " using long polling" ul <<< (hr ++>(li <<< (absLink Push << b "Push example") article pushl <|> li <<< (absLink PushDec << b "A push counter") article pushdec <> hr))) <|> (auto $ li <<< do absLink ErrorTraces << b "Error Traces" ul <<< (hr ++>(li <<< (absLink Trace << b " Execution traces for errors") article errorTrace <> hr))) <|> (auto $ li <<< do absLink Flows << b "Different kinds of flows" ul <<< (hr ++>(li <<< (absLink RESTNav << b " REST navigation") article navigation <|> li <<< (absLink ShopCart << b "Stateful persistent flow: shopping") i " getSessionData is read in the View monad to get the most recent shopping cart\ \even when the back button has been pressed" <> article stateful <|> li <<< (absLink SearchCart << b "Shopping with data tier, queries and full text search") article searchcart <|> li <<< (absLink MCounter << b "Persistent stateful flow: Counter") li <<< (absLink PreventBack << b "Prevent going back after a transaction") article preventbackl <|> li <<< (absLink InitialConfig $ b "Initial Configuration in session parameters") hr))) <|> (auto $ li <<< do absLink Templates << b "Runtime templates" <++ " Templates and content management modifiable at runtime" ul <<< (hr ++>(li <<< (absLink RuntimeTemplates << b "Runtime templates") li <<< (absLink TextEdit << b "Content Management") hr))) <|> (auto $ li <<< do absLink LoginLogout << b "Login/logout" ul <<< (hr ++> (li <<< (absLink Login << b "login/logout") hr))) <|> (li <<< (absLink CacheDataset << b "HTTP caching") <++ " Navigating an infinite dataset in the browser by caching javascript programs\ \ using the new composable caching directives") <|> li <<< absLink LazyLoad << b "Lazy loading of widgets, html, images etc" <|> (auto $ li <<< do absLink ComplexThings << b "Really complex things" <++ " Reference impementations for GUI-like apps" ul <<< (hr ++> (li <<< (absLink GenerateForm << b "A form generator and editor") (li <<< (absLink GenerateFormUndo << b "Form generator with undo") (li <<< (absLink GenerateFormUndoMsg << b "Form generator with no page refreshes") hr) )) <++ li << (a ! href "/noscript/wiki/webservices" $ b "Web Services")) <|> (El.div ! At.style "display:none" <<< mainMenu1)) -- for compatibility with older paths published that did not have two-step cascaded menus -- so that /noscript/databasesampes/mflowpersist and /noscript/mflowpersist produce the same page mainMenu1 :: View Html IO Options mainMenu1= wcached "menu" 0 $ wlink MFlowPersist mempty <|> wlink Database mempty <|> wlink Push mempty <|> wlink PushDec mempty <|> wlink Trace mempty <|> wlink RESTNav mempty <|> wlink ShopCart mempty <|> wlink MCounter mempty <|> wlink CountI mempty <|> wlink CountS mempty <|> wlink Select mempty <|> wlink CheckBoxes mempty <|> wlink Radio mempty <|> wlink Action mempty <|> wlink FViewMonad mempty <|> wlink Counter mempty <|> wlink Multicounter mempty <|> wlink Combination mempty <|> wlink WDialog mempty <|> wlink Ajax mempty <|> wlink Autocomp mempty <|> wlink AutocompList mempty <|> wlink ListEdit mempty <|> wlink Grid << b "grid" <|> wlink TextEdit << b "Content Management" <|> wlink Login << b "login/logout" <|> wlink PreventBack << b "Prevent going back after a transaction" article link= " " <> a ! At.class_ "_noAutoRefresh" ! href link << i "(article)" searchcart= "http://haskell-web.blogspot.com.es/2013/04/mflow-what-about-data-tier-adding-it-to.html" persistentarticle= "http://haskell-web.blogspot.com.es/2013/08/mflow-using-persistent-with-sqlite.html" yesodweb= "http://www.yesodweb.com/book/persistent" amazonarticle= "http://haskell-web.blogspot.com.es/2013/08/using-amazon-web-services-with-tcache.html" pushdec= "http://haskell-web.blogspot.com.es/2013/07/maxwell-smart-push-counter.html" pushl= "http://haskell-web.blogspot.com.es/2013/07/new-push-widgets-for-presentation-of.html" errorTrace= "http://haskell-web.blogspot.com.es/2013/07/automatic-error-trace-generation-in.html" navigation= "http://haskell-web.blogspot.com.es/2013/07/the-web-navigation-monad.html" combinationl= "http://haskell-web.blogspot.com.es/2013/06/and-finally-widget-auto-refreshing.html" pageflow= "http://haskell-web.blogspot.com.es/2013/06/the-promising-land-of-monadic-formlets.html" callbacks= "http://haskell-web.blogspot.com.es/2013/06/callbacks-in-mflow.html" gridl= "http://haskell-web.blogspot.com.es/2013/01/now-example-of-use-of-active-widget.html" editList= "http://haskell-web.blogspot.com.es/2012/12/on-spirit-of-mflow-anatomy-of-widget.html" stateful= "http://haskell-web.blogspot.com.es/2013/04/more-on-session-management-in-mflow.html" preventbackl= "http://haskell-web.blogspot.com.es/2013/04/controlling-backtracking-in-mflow.html" ajaxl= "http://hackage.haskell.org/packages/archive/MFlow/0.3.1.0/doc/html/MFlow-Forms.html#g:17" menuarticle= "http://haskell-web.blogspot.com.es/2013/08/how-to-handle-menus-and-other.html" cascade="http://haskell-web.blogspot.com.es/2013/10/a-cascade-menu-coded-in-pure.html" widgetAndSource Nothing w = w widgetAndSource (Just(Filename filename)) w = do source <- getSource filename El.div <<< tFieldEd edadmin (filename ++ "top") "top text" <++ hr **> h1 "Running example" ++> "(in the light red box):" ++> (divsample <<< w) -- <** tFieldEd edadmin (filename ++ "bottom") "botom text" <++ do -- Blaze-html monad br hr h1 $ "Source code:" source hr disquscript where host = "mflowdemo.herokuapp.com/" path = "http://" <> host <> "source/" <> filename download path= p $ "download " <> a ! href path << filename sty= "float:bottom\ \;width:100%\ \;margin-left:5px;margin-right:10px;overflow:auto;" divsample= El.div ! At.style ( "background-color:#FFEEEE;") stdheader c= docTypeHtml $ do El.head $ do El.title "MFlow examples" El.meta ! content "text/html; charset=UTF-8" ! httpEquiv "Content-Type" El.style $ "body {\n\ \font-family: \"rebuchet MS\", \"Helvetica\", \"Arial\", \"Verdana\", \"sans-serif\";\n\ \font-size: 90.5%;}\n\ \a:link {text-decoration:none;}\ \a:visited {text-decoration:none;}\ \a:hover {text-decoration:underline;}\ \a:active {text-decoration:underline;}" body $ do [shamlet|