Moved all StringTemplate support to own module
This commit is contained in:
parent
1ff54a574a
commit
097561b7aa
@ -4,7 +4,6 @@
|
|||||||
module Test.QuasiResource (testSuite) where
|
module Test.QuasiResource (testSuite) where
|
||||||
|
|
||||||
import Yesod
|
import Yesod
|
||||||
import Text.StringTemplate (nullGroup)
|
|
||||||
import Test.Framework (testGroup, Test)
|
import Test.Framework (testGroup, Test)
|
||||||
import Test.Framework.Providers.HUnit
|
import Test.Framework.Providers.HUnit
|
||||||
import Test.HUnit hiding (Test)
|
import Test.HUnit hiding (Test)
|
||||||
@ -67,7 +66,7 @@ ph ss h = do
|
|||||||
rr = error "No raw request"
|
rr = error "No raw request"
|
||||||
y = MyYesod
|
y = MyYesod
|
||||||
cts = [TypeHtml]
|
cts = [TypeHtml]
|
||||||
res <- runHandler h eh rr y nullGroup cts
|
res <- runHandler h eh rr y cts
|
||||||
res' <- myShow res
|
res' <- myShow res
|
||||||
mapM_ (helper res') ss
|
mapM_ (helper res') ss
|
||||||
where
|
where
|
||||||
|
|||||||
@ -38,7 +38,6 @@ module Yesod.Handler
|
|||||||
|
|
||||||
import Yesod.Request
|
import Yesod.Request
|
||||||
import Yesod.Response
|
import Yesod.Response
|
||||||
import Yesod.Template
|
|
||||||
import Web.Mime
|
import Web.Mime
|
||||||
|
|
||||||
import Control.Exception hiding (Handler)
|
import Control.Exception hiding (Handler)
|
||||||
@ -52,9 +51,11 @@ import System.IO
|
|||||||
import Data.Object.Html
|
import Data.Object.Html
|
||||||
import qualified Data.ByteString.Lazy as BL
|
import qualified Data.ByteString.Lazy as BL
|
||||||
|
|
||||||
|
data HandlerData yesod = HandlerData RawRequest yesod
|
||||||
|
|
||||||
------ Handler monad
|
------ Handler monad
|
||||||
newtype Handler yesod a = Handler {
|
newtype Handler yesod a = Handler {
|
||||||
unHandler :: (RawRequest, yesod, TemplateGroup)
|
unHandler :: HandlerData yesod
|
||||||
-> IO ([Header], HandlerContents a)
|
-> IO ([Header], HandlerContents a)
|
||||||
}
|
}
|
||||||
data HandlerContents a =
|
data HandlerContents a =
|
||||||
@ -83,32 +84,29 @@ instance MonadIO (Handler yesod) where
|
|||||||
instance Exception e => Failure e (Handler yesod) where
|
instance Exception e => Failure e (Handler yesod) where
|
||||||
failure e = Handler $ \_ -> return ([], HCError $ InternalError $ show e)
|
failure e = Handler $ \_ -> return ([], HCError $ InternalError $ show e)
|
||||||
instance RequestReader (Handler yesod) where
|
instance RequestReader (Handler yesod) where
|
||||||
getRawRequest = Handler $ \(rr, _, _) -> return ([], HCContent rr)
|
getRawRequest = Handler $ \(HandlerData rr _)
|
||||||
|
-> return ([], HCContent rr)
|
||||||
invalidParams = invalidArgs . map helper where
|
invalidParams = invalidArgs . map helper where
|
||||||
helper ((_pt, pn, _pvs), e) = (pn, show e)
|
helper ((_pt, pn, _pvs), e) = (pn, show e)
|
||||||
|
|
||||||
getYesod :: Handler yesod yesod
|
getYesod :: Handler yesod yesod
|
||||||
getYesod = Handler $ \(_, yesod, _) -> return ([], HCContent yesod)
|
getYesod = Handler $ \(HandlerData _ yesod) -> return ([], HCContent yesod)
|
||||||
|
|
||||||
instance HasTemplateGroup (Handler yesod) where
|
|
||||||
getTemplateGroup = Handler $ \(_, _, tg) -> return ([], HCContent tg)
|
|
||||||
|
|
||||||
runHandler :: Handler yesod ChooseRep
|
runHandler :: Handler yesod ChooseRep
|
||||||
-> (ErrorResponse -> Handler yesod ChooseRep)
|
-> (ErrorResponse -> Handler yesod ChooseRep)
|
||||||
-> RawRequest
|
-> RawRequest
|
||||||
-> yesod
|
-> yesod
|
||||||
-> TemplateGroup
|
|
||||||
-> [ContentType]
|
-> [ContentType]
|
||||||
-> IO Response
|
-> IO Response
|
||||||
runHandler (Handler handler) eh rr y tg cts = do
|
runHandler handler eh rr y cts = do
|
||||||
let toErrorHandler =
|
let toErrorHandler =
|
||||||
InternalError
|
InternalError
|
||||||
. (show :: Control.Exception.SomeException -> String)
|
. (show :: Control.Exception.SomeException -> String)
|
||||||
(headers, contents) <- Control.Exception.catch
|
(headers, contents) <- Control.Exception.catch
|
||||||
(handler (rr, y, tg))
|
(unHandler handler $ HandlerData rr y)
|
||||||
(\e -> return ([], HCError $ toErrorHandler e))
|
(\e -> return ([], HCError $ toErrorHandler e))
|
||||||
let handleError e = do
|
let handleError e = do
|
||||||
Response _ hs ct c <- runHandler (eh e) safeEh rr y tg cts
|
Response _ hs ct c <- runHandler (eh e) safeEh rr y cts
|
||||||
let hs' = headers ++ hs
|
let hs' = headers ++ hs
|
||||||
return $ Response (getStatus e) hs' ct c
|
return $ Response (getStatus e) hs' ct c
|
||||||
let sendFile' ct fp = do
|
let sendFile' ct fp = do
|
||||||
|
|||||||
@ -1,71 +1,59 @@
|
|||||||
-- FIXME this whole module needs to be rethought
|
|
||||||
{-# LANGUAGE DeriveDataTypeable #-}
|
{-# LANGUAGE DeriveDataTypeable #-}
|
||||||
{-# LANGUAGE FlexibleContexts #-}
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
module Yesod.Template
|
module Yesod.Template
|
||||||
( HasTemplateGroup (..)
|
( YesodTemplate (..)
|
||||||
, template
|
, template
|
||||||
, NoSuchTemplate
|
, NoSuchTemplate
|
||||||
|
, Template
|
||||||
, TemplateGroup
|
, TemplateGroup
|
||||||
, Template (..)
|
|
||||||
, TemplateFile (..)
|
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Data.Object.Html
|
import Data.Object.Html
|
||||||
import Data.Typeable (Typeable)
|
import Data.Typeable (Typeable)
|
||||||
import Control.Exception (Exception)
|
import Control.Exception (Exception)
|
||||||
import Control.Failure
|
|
||||||
import Data.Object.Text (Text)
|
import Data.Object.Text (Text)
|
||||||
import Text.StringTemplate
|
import Text.StringTemplate
|
||||||
import Data.Object.Json
|
import Data.Object.Json
|
||||||
import Web.Mime
|
import Web.Mime
|
||||||
import Yesod.Response
|
import Yesod.Response
|
||||||
|
import Yesod.Yesod
|
||||||
|
import Yesod.Handler
|
||||||
|
import Control.Monad (foldM)
|
||||||
|
import Data.ByteString.Lazy (toChunks)
|
||||||
|
|
||||||
|
type Template = StringTemplate Text
|
||||||
type TemplateGroup = STGroup Text
|
type TemplateGroup = STGroup Text
|
||||||
|
|
||||||
class HasTemplateGroup a where
|
class Yesod y => YesodTemplate y where
|
||||||
getTemplateGroup :: a TemplateGroup
|
getTemplateGroup :: y -> TemplateGroup
|
||||||
|
|
||||||
template :: (MonadFailure NoSuchTemplate t, HasTemplateGroup t)
|
getTemplateGroup' :: YesodTemplate y => Handler y TemplateGroup
|
||||||
|
getTemplateGroup' = getTemplateGroup `fmap` getYesod
|
||||||
|
|
||||||
|
template :: YesodTemplate y
|
||||||
=> String -- ^ template name
|
=> String -- ^ template name
|
||||||
-> String -- ^ object name
|
|
||||||
-> HtmlObject -- ^ object
|
-> HtmlObject -- ^ object
|
||||||
-> IO [(String, HtmlObject)] -- ^ template attributes
|
-> (HtmlObject -> Template -> IO Template)
|
||||||
-> t Template
|
-> Handler y ChooseRep
|
||||||
template tn on o attrs = do
|
template tn ho f = do
|
||||||
tg <- getTemplateGroup
|
tg <- getTemplateGroup'
|
||||||
t <- case getStringTemplate tn tg of
|
t <- case getStringTemplate tn tg of
|
||||||
Nothing -> failure $ NoSuchTemplate tn
|
Nothing -> failure $ NoSuchTemplate tn
|
||||||
Just x -> return x
|
Just x -> return x
|
||||||
return $ Template t on o attrs
|
return $ chooseRep
|
||||||
|
[ (TypeJson, cs $ unJsonDoc $ cs ho)
|
||||||
|
, (TypeHtml, tempToContent t ho f)
|
||||||
|
]
|
||||||
newtype NoSuchTemplate = NoSuchTemplate String
|
newtype NoSuchTemplate = NoSuchTemplate String
|
||||||
deriving (Show, Typeable)
|
deriving (Show, Typeable)
|
||||||
instance Exception NoSuchTemplate
|
instance Exception NoSuchTemplate
|
||||||
|
|
||||||
data Template = Template (StringTemplate Text)
|
tempToContent :: Template
|
||||||
String
|
-> HtmlObject
|
||||||
HtmlObject
|
-> (HtmlObject -> Template -> IO Template)
|
||||||
(IO [(String, HtmlObject)])
|
-> Content
|
||||||
instance HasReps Template where
|
tempToContent t ho f = ioTextToContent $ fmap render $ f ho t
|
||||||
chooseRep = defChooseRep [ (TypeHtml,
|
|
||||||
\(Template t name ho attrsIO) -> do
|
|
||||||
attrs <- attrsIO
|
|
||||||
return
|
|
||||||
$ cs
|
|
||||||
$ render
|
|
||||||
$ setAttribute name ho
|
|
||||||
$ setManyAttrib attrs t)
|
|
||||||
, (TypeJson, \(Template _ _ ho _) ->
|
|
||||||
return $ cs $ unJsonDoc $ cs ho)
|
|
||||||
]
|
|
||||||
|
|
||||||
data TemplateFile = TemplateFile FilePath HtmlObject
|
ioTextToContent :: IO Text -> Content
|
||||||
instance HasReps TemplateFile where
|
ioTextToContent iotext = Content $ \f a -> iotext >>= \t ->
|
||||||
chooseRep = defChooseRep [ (TypeHtml,
|
foldM f a $ toChunks $ cs t
|
||||||
\(TemplateFile fp h) -> do
|
|
||||||
contents <- readFile fp
|
|
||||||
let t = newSTMP contents
|
|
||||||
return $ cs $ toString $ setAttribute "o" h t
|
|
||||||
)
|
|
||||||
, (TypeJson, \(TemplateFile _ ho) ->
|
|
||||||
return $ cs $ unJsonDoc $ cs ho)
|
|
||||||
]
|
|
||||||
|
|||||||
@ -14,10 +14,8 @@ import Yesod.Response
|
|||||||
import Yesod.Request
|
import Yesod.Request
|
||||||
import Yesod.Definitions
|
import Yesod.Definitions
|
||||||
import Yesod.Handler
|
import Yesod.Handler
|
||||||
import Yesod.Template (TemplateGroup)
|
|
||||||
|
|
||||||
import Data.Maybe (fromMaybe)
|
import Data.Maybe (fromMaybe)
|
||||||
import Text.StringTemplate
|
|
||||||
import Web.Mime
|
import Web.Mime
|
||||||
import Web.Encodings (parseHttpAccept)
|
import Web.Encodings (parseHttpAccept)
|
||||||
|
|
||||||
@ -46,10 +44,6 @@ class Yesod a where
|
|||||||
errorHandler :: ErrorResponse -> Handler a ChooseRep
|
errorHandler :: ErrorResponse -> Handler a ChooseRep
|
||||||
errorHandler = defaultErrorHandler
|
errorHandler = defaultErrorHandler
|
||||||
|
|
||||||
-- | The template directory. Blank means no templates.
|
|
||||||
templateDir :: a -> FilePath
|
|
||||||
templateDir _ = ""
|
|
||||||
|
|
||||||
-- | Applies some form of layout to <title> and <body> contents of a page.
|
-- | Applies some form of layout to <title> and <body> contents of a page.
|
||||||
applyLayout :: a
|
applyLayout :: a
|
||||||
-> String -- ^ title
|
-> String -- ^ title
|
||||||
@ -109,7 +103,7 @@ defaultErrorHandler (InternalError e) =
|
|||||||
toHackApp :: Yesod y => y -> IO Hack.Application
|
toHackApp :: Yesod y => y -> IO Hack.Application
|
||||||
toHackApp a = do
|
toHackApp a = do
|
||||||
key <- encryptKey a
|
key <- encryptKey a
|
||||||
app' <- toHackApp' a
|
let app' = toHackApp' a
|
||||||
let mins = clientSessionDuration a
|
let mins = clientSessionDuration a
|
||||||
return $ gzip
|
return $ gzip
|
||||||
$ cleanPath
|
$ cleanPath
|
||||||
@ -118,22 +112,14 @@ toHackApp a = do
|
|||||||
$ clientsession encryptedCookies key mins
|
$ clientsession encryptedCookies key mins
|
||||||
$ app'
|
$ app'
|
||||||
|
|
||||||
toHackApp' :: Yesod y => y -> IO Hack.Application
|
toHackApp' :: Yesod y => y -> Hack.Env -> IO Hack.Response
|
||||||
toHackApp' y = do
|
toHackApp' y env = do
|
||||||
let td = templateDir y
|
|
||||||
tg <- if null td
|
|
||||||
then return nullGroup
|
|
||||||
else directoryGroupRecursiveLazy td
|
|
||||||
return $ toHackApp'' y tg
|
|
||||||
|
|
||||||
toHackApp'' :: Yesod y => y -> TemplateGroup -> Hack.Env -> IO Hack.Response
|
|
||||||
toHackApp'' y tg env = do
|
|
||||||
let (Right resource) = splitPath $ Hack.pathInfo env
|
let (Right resource) = splitPath $ Hack.pathInfo env
|
||||||
types = httpAccept env
|
types = httpAccept env
|
||||||
verb = cs $ Hack.requestMethod env
|
verb = cs $ Hack.requestMethod env
|
||||||
handler = handlers resource verb
|
handler = handlers resource verb
|
||||||
rr = cs env
|
rr = cs env
|
||||||
res <- runHandler handler errorHandler rr y tg types
|
res <- runHandler handler errorHandler rr y types
|
||||||
responseToHackResponse res
|
responseToHackResponse res
|
||||||
|
|
||||||
httpAccept :: Hack.Env -> [ContentType]
|
httpAccept :: Hack.Env -> [ContentType]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user