Switch to SubHandlerFor
This is much more consistent than suddenly using a ReaderT for subsites. Thanks to @jprider63 for the inspiration for this, I think it cleans things up a lot!
This commit is contained in:
parent
0f09393c34
commit
fa8e1ac00f
@ -52,7 +52,7 @@ authOAuth oauth mkCreds = AuthPlugin name dispatch login
|
|||||||
oauthSessionName = "__oauth_token_secret"
|
oauthSessionName = "__oauth_token_secret"
|
||||||
|
|
||||||
dispatch
|
dispatch
|
||||||
:: ( MonadSubHandler m
|
:: ( MonadHandler m
|
||||||
, master ~ HandlerSite m
|
, master ~ HandlerSite m
|
||||||
, Auth ~ SubHandlerSite m
|
, Auth ~ SubHandlerSite m
|
||||||
, MonadUnliftIO m
|
, MonadUnliftIO m
|
||||||
|
|||||||
@ -78,7 +78,7 @@ import Control.Monad (void)
|
|||||||
|
|
||||||
type AuthRoute = Route Auth
|
type AuthRoute = Route Auth
|
||||||
|
|
||||||
type MonadAuthHandler master m = (MonadSubHandler m, YesodAuth master, master ~ HandlerSite m, Auth ~ SubHandlerSite m, MonadUnliftIO m)
|
type MonadAuthHandler master m = (MonadHandler m, YesodAuth master, master ~ HandlerSite m, Auth ~ SubHandlerSite m, MonadUnliftIO m)
|
||||||
type AuthHandler master a = forall m. MonadAuthHandler master m => m a
|
type AuthHandler master a = forall m. MonadAuthHandler master m => m a
|
||||||
|
|
||||||
type Method = Text
|
type Method = Text
|
||||||
|
|||||||
@ -73,12 +73,6 @@ module Yesod.Core
|
|||||||
, guessApproot
|
, guessApproot
|
||||||
, guessApprootOr
|
, guessApprootOr
|
||||||
, getApprootText
|
, getApprootText
|
||||||
-- * Subsites
|
|
||||||
, MonadSubHandler (..)
|
|
||||||
, getSubYesod
|
|
||||||
, getRouteToParent
|
|
||||||
, getSubCurrentRoute
|
|
||||||
, SubsiteData
|
|
||||||
-- * Misc
|
-- * Misc
|
||||||
, yesodVersion
|
, yesodVersion
|
||||||
, yesodRender
|
, yesodRender
|
||||||
|
|||||||
@ -9,10 +9,8 @@ module Yesod.Core.Class.Dispatch where
|
|||||||
import qualified Network.Wai as W
|
import qualified Network.Wai as W
|
||||||
import Yesod.Core.Types
|
import Yesod.Core.Types
|
||||||
import Yesod.Core.Content (ToTypedContent (..))
|
import Yesod.Core.Content (ToTypedContent (..))
|
||||||
import Yesod.Core.Handler (sendWaiApplication, getYesod, getCurrentRoute)
|
import Yesod.Core.Handler (sendWaiApplication)
|
||||||
import Yesod.Core.Class.Handler
|
|
||||||
import Yesod.Core.Class.Yesod
|
import Yesod.Core.Class.Yesod
|
||||||
import Control.Monad.Trans.Reader (ReaderT (..))
|
|
||||||
|
|
||||||
-- | This class is automatically instantiated when you use the template haskell
|
-- | This class is automatically instantiated when you use the template haskell
|
||||||
-- mkYesod function. You should never need to deal with it directly.
|
-- mkYesod function. You should never need to deal with it directly.
|
||||||
@ -35,72 +33,20 @@ instance YesodSubDispatch WaiSubsiteWithAuth master where
|
|||||||
WaiSubsiteWithAuth set = ysreGetSub $ yreSite $ ysreParentEnv
|
WaiSubsiteWithAuth set = ysreGetSub $ yreSite $ ysreParentEnv
|
||||||
handlert = sendWaiApplication set
|
handlert = sendWaiApplication set
|
||||||
|
|
||||||
data SubsiteData child parent = SubsiteData
|
|
||||||
{ sdRouteToParent :: !(Route child -> Route parent)
|
|
||||||
, sdCurrentRoute :: !(Maybe (Route child))
|
|
||||||
, sdSubsiteData :: !child
|
|
||||||
}
|
|
||||||
|
|
||||||
class MonadHandler m => MonadSubHandler m where
|
|
||||||
type SubHandlerSite m
|
|
||||||
|
|
||||||
liftSubHandler :: ReaderT (SubsiteData (SubHandlerSite m) (HandlerSite m)) (HandlerFor (HandlerSite m)) a -> m a
|
|
||||||
|
|
||||||
getSubYesod :: MonadSubHandler m => m (SubHandlerSite m)
|
|
||||||
getSubYesod = liftSubHandler $ ReaderT $ return . sdSubsiteData
|
|
||||||
|
|
||||||
getRouteToParent :: MonadSubHandler m => m (Route (SubHandlerSite m) -> Route (HandlerSite m))
|
|
||||||
getRouteToParent = liftSubHandler $ ReaderT $ return . sdRouteToParent
|
|
||||||
|
|
||||||
getSubCurrentRoute :: MonadSubHandler m => m (Maybe (Route (SubHandlerSite m)))
|
|
||||||
getSubCurrentRoute = liftSubHandler $ ReaderT $ return . sdCurrentRoute
|
|
||||||
|
|
||||||
instance MonadSubHandler (HandlerFor site) where
|
|
||||||
type SubHandlerSite (HandlerFor site) = site
|
|
||||||
|
|
||||||
liftSubHandler (ReaderT x) = do
|
|
||||||
parent <- getYesod
|
|
||||||
currentRoute <- getCurrentRoute
|
|
||||||
x SubsiteData
|
|
||||||
{ sdRouteToParent = id
|
|
||||||
, sdCurrentRoute = currentRoute
|
|
||||||
, sdSubsiteData = parent
|
|
||||||
}
|
|
||||||
|
|
||||||
instance MonadSubHandler (WidgetFor site) where
|
|
||||||
type SubHandlerSite (WidgetFor site) = site
|
|
||||||
|
|
||||||
liftSubHandler (ReaderT x) = do
|
|
||||||
parent <- getYesod
|
|
||||||
currentRoute <- getCurrentRoute
|
|
||||||
liftHandler $ x SubsiteData
|
|
||||||
{ sdRouteToParent = id
|
|
||||||
, sdCurrentRoute = currentRoute
|
|
||||||
, sdSubsiteData = parent
|
|
||||||
}
|
|
||||||
|
|
||||||
instance (MonadSubHandler m, parent ~ SubHandlerSite m) => MonadSubHandler (ReaderT (SubsiteData child parent) m) where
|
|
||||||
type SubHandlerSite (ReaderT (SubsiteData child parent) m) = child
|
|
||||||
|
|
||||||
liftSubHandler (ReaderT f) = ReaderT $ \env -> do
|
|
||||||
toParent' <- getRouteToParent
|
|
||||||
liftHandler $ f env
|
|
||||||
{ sdRouteToParent = toParent' . sdRouteToParent env
|
|
||||||
}
|
|
||||||
|
|
||||||
subHelper
|
subHelper
|
||||||
:: ToTypedContent content
|
:: ToTypedContent content
|
||||||
=> ReaderT (SubsiteData child master) (HandlerFor master) content
|
=> SubHandlerFor child master content
|
||||||
-> YesodSubRunnerEnv child master
|
-> YesodSubRunnerEnv child master
|
||||||
-> Maybe (Route child)
|
-> Maybe (Route child)
|
||||||
-> W.Application
|
-> W.Application
|
||||||
subHelper (ReaderT f) YesodSubRunnerEnv {..} mroute =
|
subHelper (SubHandlerFor f) YesodSubRunnerEnv {..} mroute =
|
||||||
ysreParentRunner handler ysreParentEnv (fmap ysreToParentRoute mroute)
|
ysreParentRunner handler ysreParentEnv (fmap ysreToParentRoute mroute)
|
||||||
where
|
where
|
||||||
handler = fmap toTypedContent $ do
|
handler = fmap toTypedContent $ HandlerFor $ \hd ->
|
||||||
tm <- getRouteToParent
|
let rhe = handlerEnv hd
|
||||||
liftHandler $ f SubsiteData
|
rhe' = rhe
|
||||||
{ sdRouteToParent = tm . ysreToParentRoute
|
{ rheRoute = mroute
|
||||||
, sdCurrentRoute = mroute
|
, rheChild = ysreGetSub $ yreSite ysreParentEnv
|
||||||
, sdSubsiteData = ysreGetSub $ yreSite ysreParentEnv
|
, rheRouteToMaster = ysreToParentRoute
|
||||||
}
|
}
|
||||||
|
in f hd { handlerEnv = rhe' }
|
||||||
|
|||||||
@ -36,7 +36,9 @@ import qualified Control.Monad.Trans.Writer.Strict as Strict ( WriterT )
|
|||||||
-- FIXME should we just use MonadReader instances instead?
|
-- FIXME should we just use MonadReader instances instead?
|
||||||
class (MonadResource m, MonadLogger m) => MonadHandler m where
|
class (MonadResource m, MonadLogger m) => MonadHandler m where
|
||||||
type HandlerSite m
|
type HandlerSite m
|
||||||
|
type SubHandlerSite m
|
||||||
liftHandler :: HandlerFor (HandlerSite m) a -> m a
|
liftHandler :: HandlerFor (HandlerSite m) a -> m a
|
||||||
|
liftSubHandler :: SubHandlerFor (SubHandlerSite m) (HandlerSite m) a -> m a
|
||||||
|
|
||||||
liftHandlerT :: MonadHandler m => HandlerFor (HandlerSite m) a -> m a
|
liftHandlerT :: MonadHandler m => HandlerFor (HandlerSite m) a -> m a
|
||||||
liftHandlerT = liftHandler
|
liftHandlerT = liftHandler
|
||||||
@ -44,16 +46,38 @@ liftHandlerT = liftHandler
|
|||||||
|
|
||||||
instance MonadHandler (HandlerFor site) where
|
instance MonadHandler (HandlerFor site) where
|
||||||
type HandlerSite (HandlerFor site) = site
|
type HandlerSite (HandlerFor site) = site
|
||||||
|
type SubHandlerSite (HandlerFor site) = site
|
||||||
liftHandler = id
|
liftHandler = id
|
||||||
{-# INLINE liftHandler #-}
|
{-# INLINE liftHandler #-}
|
||||||
|
liftSubHandler (SubHandlerFor f) = HandlerFor f
|
||||||
|
{-# INLINE liftSubHandler #-}
|
||||||
|
|
||||||
|
instance MonadHandler (SubHandlerFor sub master) where
|
||||||
|
type HandlerSite (SubHandlerFor sub master) = master
|
||||||
|
type SubHandlerSite (SubHandlerFor sub master) = sub
|
||||||
|
liftHandler (HandlerFor f) = SubHandlerFor $ \hd -> f hd
|
||||||
|
{ handlerEnv =
|
||||||
|
let rhe = handlerEnv hd
|
||||||
|
in rhe
|
||||||
|
{ rheRoute = fmap (rheRouteToMaster rhe) (rheRoute rhe)
|
||||||
|
, rheRouteToMaster = id
|
||||||
|
, rheChild = rheSite rhe
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{-# INLINE liftHandler #-}
|
||||||
|
liftSubHandler = id
|
||||||
|
{-# INLINE liftSubHandler #-}
|
||||||
|
|
||||||
instance MonadHandler (WidgetFor site) where
|
instance MonadHandler (WidgetFor site) where
|
||||||
type HandlerSite (WidgetFor site) = site
|
type HandlerSite (WidgetFor site) = site
|
||||||
|
type SubHandlerSite (WidgetFor site) = site
|
||||||
liftHandler (HandlerFor f) = WidgetFor $ f . wdHandler
|
liftHandler (HandlerFor f) = WidgetFor $ f . wdHandler
|
||||||
{-# INLINE liftHandler #-}
|
{-# INLINE liftHandler #-}
|
||||||
|
liftSubHandler (SubHandlerFor f) = WidgetFor $ f . wdHandler
|
||||||
|
{-# INLINE liftSubHandler #-}
|
||||||
|
|
||||||
#define GO(T) instance MonadHandler m => MonadHandler (T m) where type HandlerSite (T m) = HandlerSite m; liftHandler = lift . liftHandler
|
#define GO(T) instance MonadHandler m => MonadHandler (T m) where type HandlerSite (T m) = HandlerSite m; type SubHandlerSite (T m) = SubHandlerSite m; liftHandler = lift . liftHandler; liftSubHandler = lift . liftSubHandler
|
||||||
#define GOX(X, T) instance (X, MonadHandler m) => MonadHandler (T m) where type HandlerSite (T m) = HandlerSite m; liftHandler = lift . liftHandler
|
#define GOX(X, T) instance (X, MonadHandler m) => MonadHandler (T m) where type HandlerSite (T m) = HandlerSite m; type SubHandlerSite (T m) = SubHandlerSite m; liftHandler = lift . liftHandler; liftSubHandler = lift . liftSubHandler
|
||||||
GO(IdentityT)
|
GO(IdentityT)
|
||||||
GO(ListT)
|
GO(ListT)
|
||||||
GO(MaybeT)
|
GO(MaybeT)
|
||||||
|
|||||||
@ -147,6 +147,10 @@ module Yesod.Core.Handler
|
|||||||
, setMessage
|
, setMessage
|
||||||
, setMessageI
|
, setMessageI
|
||||||
, getMessage
|
, getMessage
|
||||||
|
-- * Subsites
|
||||||
|
, getSubYesod
|
||||||
|
, getRouteToParent
|
||||||
|
, getSubCurrentRoute
|
||||||
-- * Helpers for specific content
|
-- * Helpers for specific content
|
||||||
-- ** Hamlet
|
-- ** Hamlet
|
||||||
, hamletToRepHtml
|
, hamletToRepHtml
|
||||||
@ -321,7 +325,7 @@ rbHelper' backend mkFI req =
|
|||||||
| otherwise = a'
|
| otherwise = a'
|
||||||
go = decodeUtf8With lenientDecode
|
go = decodeUtf8With lenientDecode
|
||||||
|
|
||||||
askHandlerEnv :: MonadHandler m => m (RunHandlerEnv (HandlerSite m))
|
askHandlerEnv :: MonadHandler m => m (RunHandlerEnv (HandlerSite m) (HandlerSite m))
|
||||||
askHandlerEnv = liftHandler $ HandlerFor $ return . handlerEnv
|
askHandlerEnv = liftHandler $ HandlerFor $ return . handlerEnv
|
||||||
|
|
||||||
-- | Get the master site application argument.
|
-- | Get the master site application argument.
|
||||||
@ -1593,3 +1597,12 @@ csrfErrorMessage expectedLocations = T.intercalate "\n"
|
|||||||
formatValue maybeText = case maybeText of
|
formatValue maybeText = case maybeText of
|
||||||
Nothing -> "(which is not currently set)"
|
Nothing -> "(which is not currently set)"
|
||||||
Just t -> T.concat ["(which has the current, incorrect value: '", t, "')"]
|
Just t -> T.concat ["(which has the current, incorrect value: '", t, "')"]
|
||||||
|
|
||||||
|
getSubYesod :: MonadHandler m => m (SubHandlerSite m)
|
||||||
|
getSubYesod = liftSubHandler $ SubHandlerFor $ return . rheChild . handlerEnv
|
||||||
|
|
||||||
|
getRouteToParent :: MonadHandler m => m (Route (SubHandlerSite m) -> Route (HandlerSite m))
|
||||||
|
getRouteToParent = liftSubHandler $ SubHandlerFor $ return . rheRouteToMaster . handlerEnv
|
||||||
|
|
||||||
|
getSubCurrentRoute :: MonadHandler m => m (Maybe (Route (SubHandlerSite m)))
|
||||||
|
getSubCurrentRoute = liftSubHandler $ SubHandlerFor $ return . rheRoute . handlerEnv
|
||||||
|
|||||||
@ -64,7 +64,7 @@ errFromShow x = do
|
|||||||
-- exceptions, but all other synchronous exceptions will be caught and
|
-- exceptions, but all other synchronous exceptions will be caught and
|
||||||
-- represented by the @HandlerContents@.
|
-- represented by the @HandlerContents@.
|
||||||
basicRunHandler :: ToTypedContent c
|
basicRunHandler :: ToTypedContent c
|
||||||
=> RunHandlerEnv site
|
=> RunHandlerEnv site site
|
||||||
-> HandlerFor site c
|
-> HandlerFor site c
|
||||||
-> YesodRequest
|
-> YesodRequest
|
||||||
-> InternalState
|
-> InternalState
|
||||||
@ -107,7 +107,7 @@ basicRunHandler rhe handler yreq resState = do
|
|||||||
}
|
}
|
||||||
|
|
||||||
-- | Convert an @ErrorResponse@ into a @YesodResponse@
|
-- | Convert an @ErrorResponse@ into a @YesodResponse@
|
||||||
handleError :: RunHandlerEnv site
|
handleError :: RunHandlerEnv sub site
|
||||||
-> YesodRequest
|
-> YesodRequest
|
||||||
-> InternalState
|
-> InternalState
|
||||||
-> Map.Map Text S8.ByteString
|
-> Map.Map Text S8.ByteString
|
||||||
@ -188,7 +188,7 @@ evalFallback contents val = catchAny
|
|||||||
-- | Function used internally by Yesod in the process of converting a
|
-- | Function used internally by Yesod in the process of converting a
|
||||||
-- 'HandlerT' into an 'Application'. Should not be needed by users.
|
-- 'HandlerT' into an 'Application'. Should not be needed by users.
|
||||||
runHandler :: ToTypedContent c
|
runHandler :: ToTypedContent c
|
||||||
=> RunHandlerEnv site
|
=> RunHandlerEnv site site
|
||||||
-> HandlerFor site c
|
-> HandlerFor site c
|
||||||
-> YesodApp
|
-> YesodApp
|
||||||
runHandler rhe@RunHandlerEnv {..} handler yreq = withInternalState $ \resState -> do
|
runHandler rhe@RunHandlerEnv {..} handler yreq = withInternalState $ \resState -> do
|
||||||
@ -255,6 +255,8 @@ runFakeHandler fakeSessionMap logger site handler = liftIO $ do
|
|||||||
RunHandlerEnv
|
RunHandlerEnv
|
||||||
{ rheRender = yesodRender site $ resolveApproot site fakeWaiRequest
|
{ rheRender = yesodRender site $ resolveApproot site fakeWaiRequest
|
||||||
, rheRoute = Nothing
|
, rheRoute = Nothing
|
||||||
|
, rheRouteToMaster = id
|
||||||
|
, rheChild = site
|
||||||
, rheSite = site
|
, rheSite = site
|
||||||
, rheUpload = fileUpload site
|
, rheUpload = fileUpload site
|
||||||
, rheLog = messageLoggerSource site $ logger site
|
, rheLog = messageLoggerSource site $ logger site
|
||||||
@ -329,6 +331,8 @@ yesodRunner handler' YesodRunnerEnv {..} route req sendResponse
|
|||||||
rheSafe = RunHandlerEnv
|
rheSafe = RunHandlerEnv
|
||||||
{ rheRender = yesodRender yreSite ra
|
{ rheRender = yesodRender yreSite ra
|
||||||
, rheRoute = route
|
, rheRoute = route
|
||||||
|
, rheRouteToMaster = id
|
||||||
|
, rheChild = yreSite
|
||||||
, rheSite = yreSite
|
, rheSite = yreSite
|
||||||
, rheUpload = fileUpload yreSite
|
, rheUpload = fileUpload yreSite
|
||||||
, rheLog = log'
|
, rheLog = log'
|
||||||
|
|||||||
@ -175,10 +175,12 @@ newtype WaiSubsite = WaiSubsite { runWaiSubsite :: W.Application }
|
|||||||
-- @since 1.4.34
|
-- @since 1.4.34
|
||||||
newtype WaiSubsiteWithAuth = WaiSubsiteWithAuth { runWaiSubsiteWithAuth :: W.Application }
|
newtype WaiSubsiteWithAuth = WaiSubsiteWithAuth { runWaiSubsiteWithAuth :: W.Application }
|
||||||
|
|
||||||
data RunHandlerEnv site = RunHandlerEnv
|
data RunHandlerEnv child site = RunHandlerEnv
|
||||||
{ rheRender :: !(Route site -> [(Text, Text)] -> Text)
|
{ rheRender :: !(Route site -> [(Text, Text)] -> Text)
|
||||||
, rheRoute :: !(Maybe (Route site))
|
, rheRoute :: !(Maybe (Route child))
|
||||||
|
, rheRouteToMaster :: !(Route child -> Route site)
|
||||||
, rheSite :: !site
|
, rheSite :: !site
|
||||||
|
, rheChild :: !child
|
||||||
, rheUpload :: !(RequestBodyLength -> FileUpload)
|
, rheUpload :: !(RequestBodyLength -> FileUpload)
|
||||||
, rheLog :: !(Loc -> LogSource -> LogLevel -> LogStr -> IO ())
|
, rheLog :: !(Loc -> LogSource -> LogLevel -> LogStr -> IO ())
|
||||||
, rheOnError :: !(ErrorResponse -> YesodApp)
|
, rheOnError :: !(ErrorResponse -> YesodApp)
|
||||||
@ -188,9 +190,9 @@ data RunHandlerEnv site = RunHandlerEnv
|
|||||||
, rheMaxExpires :: !Text
|
, rheMaxExpires :: !Text
|
||||||
}
|
}
|
||||||
|
|
||||||
data HandlerData site = HandlerData
|
data HandlerData child site = HandlerData
|
||||||
{ handlerRequest :: !YesodRequest
|
{ handlerRequest :: !YesodRequest
|
||||||
, handlerEnv :: !(RunHandlerEnv site)
|
, handlerEnv :: !(RunHandlerEnv child site)
|
||||||
, handlerState :: !(IORef GHState)
|
, handlerState :: !(IORef GHState)
|
||||||
, handlerResource :: !InternalState
|
, handlerResource :: !InternalState
|
||||||
}
|
}
|
||||||
@ -220,7 +222,7 @@ type ParentRunner parent
|
|||||||
-- | A generic handler monad, which can have a different subsite and master
|
-- | A generic handler monad, which can have a different subsite and master
|
||||||
-- site. We define a newtype for better error message.
|
-- site. We define a newtype for better error message.
|
||||||
newtype HandlerFor site a = HandlerFor
|
newtype HandlerFor site a = HandlerFor
|
||||||
{ unHandlerFor :: HandlerData site -> IO a
|
{ unHandlerFor :: HandlerData site site -> IO a
|
||||||
}
|
}
|
||||||
deriving Functor
|
deriving Functor
|
||||||
|
|
||||||
@ -248,7 +250,7 @@ newtype WidgetFor site a = WidgetFor
|
|||||||
|
|
||||||
data WidgetData site = WidgetData
|
data WidgetData site = WidgetData
|
||||||
{ wdRef :: {-# UNPACK #-} !(IORef (GWData (Route site)))
|
{ wdRef :: {-# UNPACK #-} !(IORef (GWData (Route site)))
|
||||||
, wdHandler :: {-# UNPACK #-} !(HandlerData site)
|
, wdHandler :: {-# UNPACK #-} !(HandlerData site site)
|
||||||
}
|
}
|
||||||
|
|
||||||
instance a ~ () => Monoid (WidgetFor site a) where
|
instance a ~ () => Monoid (WidgetFor site a) where
|
||||||
@ -446,7 +448,7 @@ instance Monad (HandlerFor site) where
|
|||||||
HandlerFor x >>= f = HandlerFor $ \r -> x r >>= \x' -> unHandlerFor (f x') r
|
HandlerFor x >>= f = HandlerFor $ \r -> x r >>= \x' -> unHandlerFor (f x') r
|
||||||
instance MonadIO (HandlerFor site) where
|
instance MonadIO (HandlerFor site) where
|
||||||
liftIO = HandlerFor . const
|
liftIO = HandlerFor . const
|
||||||
instance MonadReader (HandlerData site) (HandlerFor site) where
|
instance MonadReader (HandlerData site site) (HandlerFor site) where
|
||||||
ask = HandlerFor return
|
ask = HandlerFor return
|
||||||
local f (HandlerFor g) = HandlerFor $ g . f
|
local f (HandlerFor g) = HandlerFor $ g . f
|
||||||
|
|
||||||
@ -499,3 +501,42 @@ data Logger = Logger
|
|||||||
|
|
||||||
loggerPutStr :: Logger -> LogStr -> IO ()
|
loggerPutStr :: Logger -> LogStr -> IO ()
|
||||||
loggerPutStr (Logger ls _) = pushLogStr ls
|
loggerPutStr (Logger ls _) = pushLogStr ls
|
||||||
|
|
||||||
|
-- | A handler monad for subsite
|
||||||
|
--
|
||||||
|
-- @since 1.6.0
|
||||||
|
newtype SubHandlerFor sub master a = SubHandlerFor
|
||||||
|
{ unSubHandlerFor :: HandlerData sub master -> IO a
|
||||||
|
}
|
||||||
|
deriving Functor
|
||||||
|
|
||||||
|
instance Applicative (SubHandlerFor child master) where
|
||||||
|
pure = SubHandlerFor . const . return
|
||||||
|
(<*>) = ap
|
||||||
|
instance Monad (SubHandlerFor child master) where
|
||||||
|
return = pure
|
||||||
|
SubHandlerFor x >>= f = SubHandlerFor $ \r -> x r >>= \x' -> unSubHandlerFor (f x') r
|
||||||
|
instance MonadIO (SubHandlerFor child master) where
|
||||||
|
liftIO = SubHandlerFor . const
|
||||||
|
instance MonadReader (HandlerData child master) (SubHandlerFor child master) where
|
||||||
|
ask = SubHandlerFor return
|
||||||
|
local f (SubHandlerFor g) = SubHandlerFor $ g . f
|
||||||
|
|
||||||
|
-- | @since 1.4.38
|
||||||
|
instance MonadUnliftIO (SubHandlerFor child master) where
|
||||||
|
{-# INLINE askUnliftIO #-}
|
||||||
|
askUnliftIO = SubHandlerFor $ \r ->
|
||||||
|
return (UnliftIO (flip unSubHandlerFor r))
|
||||||
|
|
||||||
|
instance MonadThrow (SubHandlerFor child master) where
|
||||||
|
throwM = liftIO . throwM
|
||||||
|
|
||||||
|
instance MonadResource (SubHandlerFor child master) where
|
||||||
|
liftResourceT f = SubHandlerFor $ runInternalState f . handlerResource
|
||||||
|
|
||||||
|
instance MonadLogger (SubHandlerFor child master) where
|
||||||
|
monadLoggerLog a b c d = SubHandlerFor $ \sd ->
|
||||||
|
rheLog (handlerEnv sd) a b c (toLogStr d)
|
||||||
|
|
||||||
|
instance MonadLoggerIO (SubHandlerFor child master) where
|
||||||
|
askLoggerIO = SubHandlerFor $ return . rheLog . handlerEnv
|
||||||
|
|||||||
@ -21,13 +21,13 @@ import qualified Data.ByteString.Lazy.Char8 as L8
|
|||||||
getSubsite :: a -> Subsite
|
getSubsite :: a -> Subsite
|
||||||
getSubsite _ = Subsite $(mkYesodSubDispatch resourcesSubsite)
|
getSubsite _ = Subsite $(mkYesodSubDispatch resourcesSubsite)
|
||||||
|
|
||||||
getBarR :: MonadSubHandler m => m T.Text
|
getBarR :: MonadHandler m => m T.Text
|
||||||
getBarR = return $ T.pack "BarR"
|
getBarR = return $ T.pack "BarR"
|
||||||
|
|
||||||
getBazR :: (MonadSubHandler m, Yesod (HandlerSite m)) => m Html
|
getBazR :: (MonadHandler m, Yesod (HandlerSite m)) => m Html
|
||||||
getBazR = liftHandler $ defaultLayout [whamlet|Used Default Layout|]
|
getBazR = liftHandler $ defaultLayout [whamlet|Used Default Layout|]
|
||||||
|
|
||||||
getBinR :: (MonadSubHandler m, Yesod (HandlerSite m), SubHandlerSite m ~ Subsite) => m Html
|
getBinR :: (MonadHandler m, Yesod (HandlerSite m), SubHandlerSite m ~ Subsite) => m Html
|
||||||
getBinR = do
|
getBinR = do
|
||||||
routeToParent <- getRouteToParent
|
routeToParent <- getRouteToParent
|
||||||
liftHandler $ defaultLayout [whamlet|
|
liftHandler $ defaultLayout [whamlet|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user