skell-0.1.0.0: src/Web/Skell/Saferoute.hs
{-# LANGUAGE OverloadedStrings #-}
-- |
-- Module : Web.Skell.Saferoute
-- Description : Saferoutes for things
-- Copyright : 2014, Peter Harpending.
-- License : BSD3
-- Maintainer : Peter Harpending <pharpend2@gmail.com>
-- Stability : experimental
-- Portability : archlinux
--
module Web.Skell.Saferoute where
import Control.Applicative
import qualified Data.ByteString.Lazy as B
import qualified Data.Map.Lazy as M
import Data.Monoid
import qualified Data.Text as S
import qualified Data.Text.Lazy as L
import Data.Monoid
import Network.Wai (Response)
import qualified Text.Blaze.Html5 as H
import qualified Web.Skell.MimeTypes as Mt
import Web.Skell.Responsible
-- |The type for a route - just an alias for 'L.Text'
type Route = S.Text
type RoutePart = S.Text
type RouteParts = [S.Text]
type ForeignResource = H.AttributeValue
-- |The type class for a resource.
class Eq r => Resource r where
{-# MINIMAL getRoute, (resourceList | routeResourceMap) #-}
-- Get the 'Route' for a 'Resource'. This is in place to avoid
-- @fmap@ stuff. Giving a 'Resource' to this function will
-- invariably return a 'Route', as opposed to 'Maybe Route', which
-- would be the case if I used a 'M.Map' lookup.
getRoute :: r -> Route
-- |A list of all of the constructors for your resource type.
resourceList :: [r]
resourceList = M.elems routeResourceMap
-- |A map from a route to it's resource.
routeResourceMap :: M.Map Route r
routeResourceMap = M.fromList [(route, resource) | resource <- resourceList,
let route = getRoute resource ]
-- |Given a 'Route', find the 'Resource' behind it. If the route
-- isn't associated with any 'Resource', this returns 'Nothing'.
lookupRoute :: Route -> Maybe r
lookupRoute route = M.lookup route routeResourceMap
-- |Lookup a set of route parts
lookupRouteParts :: RouteParts -> Maybe r
lookupRouteParts = lookupRoute . slashPrependJoin
getUrl :: Resource r => r -> H.AttributeValue
getUrl = H.toValue . getRoute
-- |Intercalate slashes, and add one to the front
slashPrependJoin :: RouteParts -> Route
slashPrependJoin parts = "/" <> S.intercalate "/" parts
-- |Error pages,
data ErrorPage = Status403
| Status404
| Status405
bootstrapCss :: ForeignResource
bootstrapCss = "//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"
bootstrapJs :: ForeignResource
bootstrapJs = "//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"
jQueryJs :: ForeignResource
jQueryJs = "//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"