packages feed

snap-web-routes (empty) → 0.1.0.0

raw patch · 6 files changed

+215/−0 lines, 6 filesdep +basedep +heistdep +mtlsetup-changed

Dependencies added: base, heist, mtl, snap, snap-core, text, web-routes, xmlhtml

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2014, Luke Randall++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Luke Randall nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,7 @@+# snap-web-routes: Type safe URLs for Snap++`snap-web-routes` provides type safe URLs for Snap using [`web routes`](http://hackage.haskell.org/package/web-routes).++# How to use++See `Snap.Web.Routes` for instructions.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ snap-web-routes.cabal view
@@ -0,0 +1,35 @@+name:                snap-web-routes+version:             0.1.0.0+synopsis:            Type safe URLs for Snap+description:         Type safe URL generation and routing for Snap using web-routes+homepage:            http://github.com/lukerandall/snap-web-routes+license:             BSD3+license-file:        LICENSE+author:              Luke Randall+maintainer:          luke.randall@gmail.com+category:            Web, Snap+build-type:          Simple+cabal-version:       >=1.10++extra-source-files:+  LICENSE,+  README.md++library+  hs-source-dirs:      src++  exposed-modules:+    Snap.Web.Routes+    Snap.Web.Routes.Heist++  build-depends:+    base                      >= 4.4     && < 5,+    heist                     >= 0.13    && < 0.14,+    mtl                       >= 2       && < 3,+    snap-core                 >= 0.9     && < 0.11,+    snap                      >= 0.13    && < 0.14,+    text                      >= 0.11    && < 1.2,+    web-routes                >= 0.27    && < 0.28,+    xmlhtml                   >= 0.1++  default-language:    Haskell2010
+ src/Snap/Web/Routes.hs view
@@ -0,0 +1,129 @@+{-|++This module provides a ready to use implementation of `web-routes` for Snap.++To get going, you'll need to add a few things to `Application.hs`.++> {-# LANGUAGE DeriveGeneric     #-}+> {-# LANGUAGE FlexibleInstances #-}+> {-# LANGUAGE TypeFamilies      #-}++DeriveGeneric is used to derive the `PathInfo` instance for your URL data type,+the rest are needed by `web-routes`.++> import Data.Text (Text)+> import Snap.Web.Routes++"Snap.Web.Routes" exports the data types needed to define your `PathInfo` and+`MonadRoute` instances below.++> data AppUrl+>     = Count Int+>     | Echo Text+>     | Paths [Text]+>       deriving (Generic)++Define your application's URL data type. Deriving a `Generic` instance gives+you a `PathInfo` instance for free.++> data App = App+>     { _routeFn :: AppUrl -> [(Text, Maybe Text)] -> Text+>     }++Extend your App type to include a routing function.++> instance PathInfo AppUrl++Get your free PathInfo instance. Alternatives are to use `web-routes-th` or+implement PathInfo yourself.++> instance MonadRoute (Handler App App) where+>    type URL (Handler App App) = AppUrl+>    askRouteFn = gets _routeFn++Define your MonadRoute instance. In particular, `type URL (Handler App App)`+must be set to your URL data type defined above and `askRouteFn` should point+to the routing function you added to your App type.++Moving on to `Site.hs`.++> import Snap.Web.Routes++Snap.Web.Routes provides a convenience router function you'll need.++> routes :: [(ByteString, Handler App App ())]+> routes = [ ("",          serveDirectory "static")+>          , ("",          routeWith routeAppUrl)+>          ]++Add your routes to the bottom of the routes list using routeWith.++> routeAppUrl :: AppUrl -> Handler App App ()+> routeAppUrl appUrl =+>     case appUrl of+>       (Count n)   -> writeText $ ("Count = " `T.append` (T.pack $ show n))+>       (Echo text) -> echo text+>       (Paths ps)  -> writeText $ T.intercalate " " ps++> echo :: T.Text -> Handler App App ()+> echo msg = heistLocal (bindString "message" msg) $ render "echo"++Define the handler for each data constructor in your URL data type.++> app :: SnapletInit App App+> app = makeSnaplet "app" "An example application with snap-web-routes." Nothing $ do+>     addRoutes routes+>     return $ App renderRoute++Lastly, add the routing function to your app. If you prefixed the routes in routeWith:++>          , ("/prefix",          routeWith routeAppUrl)++then use `renderRouteWithPrefix` instead:++>     return . App $ renderRouteWithPrefix "/prefix"++|-}++{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeFamilies      #-}++module Snap.Web.Routes+  ( renderRoute+  , renderRouteWithPrefix+  , routeWith+  , heistUrl+  , gets+  , Generic+  , MonadRoute(..)+  , PathInfo(..)+  ) where++import Control.Monad.State (lift, gets)+import Data.Text (Text, append, pack)+import Heist (HeistT)+import Snap.Core+import Snap.Web.Routes.Heist+import Snap.Snaplet+import Web.Routes+++instance (MonadRoute m) => MonadRoute (HeistT n m) where+    type URL (HeistT n m) = URL m+    askRouteFn = lift askRouteFn+++routeWith :: (PathInfo url, MonadSnap m) => (url -> m ()) -> m ()+routeWith router =+    do rq <- getRequest+       case fromPathInfo $ rqPathInfo rq of+         (Left e) -> writeText (pack e)+         (Right url) -> router url+++renderRoute :: PathInfo url => url -> [(Text, Maybe Text)] -> Text+renderRoute = renderRouteWithPrefix ""+++renderRouteWithPrefix :: PathInfo url => Text -> url -> [(Text, Maybe Text)] -> Text+renderRouteWithPrefix prefix url params = prefix `append` toPathInfoParams url params
+ src/Snap/Web/Routes/Heist.hs view
@@ -0,0 +1,12 @@+module Snap.Web.Routes.Heist+  ( heistUrl+  ) where++import Text.XmlHtml hiding (render)+import Web.Routes+++heistUrl :: MonadRoute m => URL m -> m [Node]+heistUrl u =+    do t <- showURL u+       return [TextNode t]