packages feed

snap-web-routes 0.3.0.0 → 0.3.0.1

raw patch · 4 files changed

+117/−102 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

README.md view
@@ -1,7 +1,109 @@-# snap-web-routes: Type safe URLs for Snap+# snap-web-routes -`snap-web-routes` provides type safe URLs for Snap using [`web routes`](http://hackage.haskell.org/package/web-routes).+## Type safe URLs for Snap -# How to use+[`Snap web routes`](http://hackage.haskell.org/package/snap-web-routes) provides type safe URLs for Snap using [`web routes`](http://hackage.haskell.org/package/web-routes). -See `Snap.Web.Routes` for instructions.+## How to use++The tutorial assumes you have a standard Snap app layout with an Application.hs and Site.hs. If your setup differs you'll need to adapt the instructions accordingly.++### `Application.hs`++To get going, you'll need to add a few things to `Application.hs`. This includes creating the URL data type and adding the routing function to our `App` data type.++    -- Enable a few extensions+    {-# LANGUAGE FlexibleInstances #-} -- Needed by+    {-# LANGUAGE TypeFamilies      #-} -- web-routes+    {-# LANGUAGE DeriveGeneric     #-} -- Needed to derive Generic+                                       -- for our URL data type++    -- Paths and params use Text.+    import Data.Text (Text)++    -- Snap.Web.Routes.Types exports everything you need to+    -- define your PathInfo and MonadRoute instances.+    import Snap.Web.Routes.Types++    -- Your URL data type.  Deriving a `Generic` instance gives+    -- you a `PathInfo` instance for free.+    data AppUrl+        = Count Int+        | Echo Text+        | Paths [Text]+          deriving (Generic)++    -- Extend your App type to include a routing function.+    data App = App+        { _routeFn :: AppUrl -> [(Text, Maybe Text)] -> Text+        }++    -- Thanks to the wonders of Generic, an empty instance+    -- definition is all we need. Alternately, you can implement+    -- toPathSegments and fromPathSegments yourself or use+    -- web-routes-th.+    instance PathInfo AppUrl++    -- Set URL (Handler App App) to your URL data type defined above+    -- and askRouteFn must point to the routing function you added to+    -- your App.+    instance MonadRoute (Handler App App) where+       type URL (Handler App App) = AppUrl+       askRouteFn = gets _routeFn++### `Site.hs`++Moving on to `Site.hs`, we'll setup handlers for each URL, as well initialise our app with a routing function.++    -- Snap.Web.Routes provides routing functions+    import Snap.Web.Routes++    -- Add your new routes using routeWith+    routes :: [(ByteString, Handler App App ())]+    routes = [ ("", routeWith routeAppUrl)+             , ("", serveDirectory "static")+             ]++    -- Define handlers for each value constructor in your URL data type.+    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++    -- You'll note that these are normal Snap handlers, except they can take+    -- values from the value constructor as arguments. This is a lot nicer than+    -- having to use getParam.+    echo :: T.Text -> Handler App App ()+    echo msg = heistLocal (bindString "message" msg) $ render "echo"++    -- Add the routing function to your app.+    app :: SnapletInit App App+    app = makeSnaplet "app" "An example snap-web-routes app." Nothing $ do+        addRoutes routes+        return $ App renderRoute++If you prefixed the routes in routeWith (e.g. `("/prefix", routeWith routeAppUrl)`) then use `renderRouteWithPrefix` instead:++    return . App $ renderRouteWithPrefix "/prefix"++If you are having trouble figuring out why a particular request isn't routing as expected, try replacing `routeWith` with `routeWithDebug`. It'll display the available routes, as well as any failed route parses. Just remember that it's **not suitable for production** use.++### Rendering URLs++Helper functions are provided for rendering URLs:++    echo :: T.Text -> Handler App App ()+    echo msg = do+        url <- showUrl $ Echo "this is a test"+        if msg == "test" then redirect (encodeUtf8 url) else renderEcho+      where+        renderEcho = heistLocal (I.bindSplices echoSplices) $ render "echo"+        echoSplices = do+            "message"  ## I.textSplice msg+            "countUrl" ## urlSplice (Count 10)++In the example above you'll find we use `urlSplice` to turn a URL into a splice, and `showUrl` to render a URL as Text.++
changelog view
@@ -1,3 +1,12 @@+2014-05-06 0.3.0.1++* Move tutorial to readme as it didn't show up on Hackage++2014-05-06 0.3.0.0++* Rename heistUrl to urlSplice+* Add convenience functions to render routes as Text+ 2014-05-06 0.2.0.0  * Document functions properly
snap-web-routes.cabal view
@@ -1,10 +1,10 @@ name:                snap-web-routes-version:             0.3.0.0+version:             0.3.0.1 synopsis:            Type safe URLs for Snap description:     Type safe URL generation and routing for Snap using web-routes.     .-    To get started, run through the tutorial in Snap.Web.Routes.+    To get started, there is a __<https://github.com/lukerandall/snap-web-routes/blob/master/README.md tutorial on GitHub>__.     .     This builds on <https://github.com/stepcut/snap-web-routes-demo work>     done by Jeremy Shaw. Thanks Jeremy!
src/Snap/Web/Routes.hs view
@@ -1,102 +1,6 @@ -- | -- This module provides a ready to use implementation of `web-routes` for Snap. ----- The tutorial assumes you have a standard Snap app with an Application.hs and--- Site.hs.------ To get going, you'll need to add a few things to Application.hs------ @--- -- Enable a few extensions------ \-\- Needed to derive a generic instance for our URL data type--- \{\-\# LANGUAGE DeriveGeneric     \#\-\}------ \-\- Needed by web-routes--- \{\-\# LANGUAGE FlexibleInstances \#\-\}--- \{\-\# LANGUAGE TypeFamilies      \#\-\}------ \-\- Paths and params are of type Text.--- import Data.Text (Text)------ \-\- Snap.Web.Routes.Types exports everything you need to--- \-\- define your PathInfo and MonadRoute instances.--- import Snap.Web.Routes.Types------ \-\- Your URL data type.  Deriving a `Generic` instance gives--- \-\- you a `PathInfo` instance for free.--- data AppUrl---     = Count Int---     | Echo Text---     | Paths [Text]---       deriving (Generic)------ \-\- Extend your App type to include a routing function.--- data App = App---     { _routeFn :: AppUrl -> [(Text, Maybe Text)] -> Text---     }------ \-\- Thanks to the wonders of Generic, an empty instance--- \-\- definition is all we need. Alternately, you can implement--- \-\- toPathSegments and fromPathSegments yourself or use--- \-\- web-routes-th.--- instance PathInfo AppUrl------ \-\- Set URL (Handler App App) to your URL data type defined above--- \-\- and askRouteFn must point to the routing function you added to--- \-\- your App.--- instance MonadRoute (Handler App App) where---    type URL (Handler App App) = AppUrl---    askRouteFn = gets _routeFn--- @------ Moving on to Site.hs.------ @--- \-\- Snap.Web.Routes provides routing functions--- import Snap.Web.Routes------ \-\- Add your new routes using routeWith--- routes :: [(ByteString, Handler App App ())]--- routes = [ ("", routeWith routeAppUrl)---          , ("", serveDirectory "static")---          ]------ \-\- Define handlers for each value constructor in your URL data type.--- 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------ \-\- You'll note that these are normal Snap handlers, except they can take--- \-\- values from the value constructor as arguments. This is a lot nicer than--- \-\- having to use getParam.--- echo :: T.Text -> Handler App App ()--- echo msg = heistLocal (bindString "message" msg) $ render "echo"------ \-\- Add the routing function to your app.--- app :: SnapletInit App App--- app = makeSnaplet "app" "An example snap-web-routes app." Nothing $ do---     addRoutes routes---     return $ App renderRoute--- @------ If you prefixed the routes in routeWith------ > ("/prefix", routeWith routeAppUrl)------ then use `renderRouteWithPrefix` instead:------ > return . App $ renderRouteWithPrefix "/prefix"------ If you are having trouble figuring out why a particular request isn't routing--- as expected, try replacing 'routeWith' with 'routeWithDebug'. It'll display--- the available routes, as well as any failed route parses. Just remember that--- it's not suitable for production use.-- module Snap.Web.Routes   ( routeWith   , routeWithDebug