TemplateFile rep

This commit is contained in:
Michael Snoyman 2009-12-14 23:41:20 +02:00
parent c23984b154
commit 12437533b6
5 changed files with 58 additions and 26 deletions

View File

@ -100,9 +100,9 @@ runHandler (Handler handler) eh rr y cts = do
Left e -> do Left e -> do
Response _ hs ct c <- runHandler (eh e) eh rr y cts Response _ hs ct c <- runHandler (eh e) eh rr y cts
return $ Response (getStatus e) hs ct c return $ Response (getStatus e) hs ct c
Right a -> Right a -> do
let (ct, c) = a cts (ct, c) <- a cts
in return $ Response 200 headers ct c return $ Response 200 headers ct c
{- FIXME {- FIXME
class ToHandler a where class ToHandler a where
toHandler :: a -> Handler toHandler :: a -> Handler

View File

@ -34,7 +34,7 @@ data AtomFeed = AtomFeed
} }
instance HasReps AtomFeed where instance HasReps AtomFeed where
reps = reps =
[ (TypeAtom, cs . show) [ (TypeAtom, return . cs . show)
] ]
data AtomFeedEntry = AtomFeedEntry data AtomFeedEntry = AtomFeedEntry

View File

@ -84,7 +84,7 @@ instance Show SitemapResponse where -- FIXME very ugly, use Text instead
instance HasReps SitemapResponse where instance HasReps SitemapResponse where
reps = reps =
[ (TypeXml, cs . show) [ (TypeXml, return . cs . show)
] ]
sitemap :: IO [SitemapUrl] -> Handler yesod SitemapResponse sitemap :: IO [SitemapUrl] -> Handler yesod SitemapResponse

View File

@ -36,6 +36,7 @@ module Yesod.Rep
, Plain (..) , Plain (..)
, plain , plain
, Template (..) , Template (..)
, TemplateFile (..)
#if TEST #if TEST
, testSuite , testSuite
#endif #endif
@ -105,21 +106,22 @@ instance ConvertSuccess String Content where
convertSuccess = Content . cs convertSuccess = Content . cs
type ContentPair = (ContentType, Content) type ContentPair = (ContentType, Content)
type RepChooser = [ContentType] -> ContentPair type RepChooser = [ContentType] -> IO ContentPair
-- | Any type which can be converted to representations. There must be at least -- | Any type which can be converted to representations. There must be at least
-- one representation for each type. -- one representation for each type.
class HasReps a where class HasReps a where
reps :: [(ContentType, a -> Content)] reps :: [(ContentType, a -> IO Content)]
chooseRep :: a -> RepChooser chooseRep :: a -> RepChooser
chooseRep a ts = chooseRep a ts = do
let (ct, c) = let (ct, c) =
case catMaybes $ map helper ts of case catMaybes $ map helper ts of
(x:_) -> x (x:_) -> x
[] -> case reps of [] -> case reps of
[] -> error "Empty reps" [] -> error "Empty reps"
(x:_) -> x (x:_) -> x
in (ct, c a) c' <- c a
return (ct, c')
where where
--helper :: ContentType -> Maybe ContentPair --helper :: ContentType -> Maybe ContentPair
helper ct = do helper ct = do
@ -132,7 +134,7 @@ instance HasReps RepChooser where
instance HasReps [(ContentType, Content)] where instance HasReps [(ContentType, Content)] where
reps = error "reps of [(ContentType, Content)]" reps = error "reps of [(ContentType, Content)]"
chooseRep a cts = chooseRep a cts = return $
case filter (\(ct, _) -> ct `elem` cts) a of case filter (\(ct, _) -> ct `elem` cts) a of
((ct, c):_) -> (ct, c) ((ct, c):_) -> (ct, c)
_ -> case a of _ -> case a of
@ -149,15 +151,28 @@ data Template = Template (StringTemplate String) HtmlObject
instance HasReps Template where instance HasReps Template where
reps = [ (TypeHtml, reps = [ (TypeHtml,
\(Template t h) -> \(Template t h) ->
cs $ toString $ setAttribute "o" h t) return $ cs $ toString $ setAttribute "o" h t)
, (TypeJson, \(Template _ ho) -> cs $ unJsonDoc $ cs ho) , (TypeJson, \(Template _ ho) ->
return $ cs $ unJsonDoc $ cs ho)
]
data TemplateFile = TemplateFile FilePath HtmlObject
instance HasReps TemplateFile where
reps = [ (TypeHtml,
\(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)
] ]
-- Useful instances of HasReps -- Useful instances of HasReps
instance HasReps HtmlObject where instance HasReps HtmlObject where
reps = reps =
[ (TypeHtml, cs . unHtmlDoc . cs) [ (TypeHtml, return . cs . unHtmlDoc . cs)
, (TypeJson, cs . unJsonDoc . cs) , (TypeJson, return . cs . unJsonDoc . cs)
] ]
#if TEST #if TEST
@ -167,10 +182,10 @@ caseChooseRepHO = do
a = toHtmlObject content a = toHtmlObject content
htmlbs = Content . cs . unHtmlDoc . cs $ toHtmlObject content htmlbs = Content . cs . unHtmlDoc . cs $ toHtmlObject content
jsonbs = Content . cs $ "\"" ++ content ++ "\"" jsonbs = Content . cs $ "\"" ++ content ++ "\""
chooseRep a [TypeHtml] @?= (TypeHtml, htmlbs) chooseRep a [TypeHtml] >>= (@?= (TypeHtml, htmlbs))
chooseRep a [TypeJson] @?= (TypeJson, jsonbs) chooseRep a [TypeJson] >>= (@?= (TypeJson, jsonbs))
chooseRep a [TypeHtml, TypeJson] @?= (TypeHtml, htmlbs) chooseRep a [TypeHtml, TypeJson] >>= (@?= (TypeHtml, htmlbs))
chooseRep a [TypeOther "foo", TypeJson] @?= (TypeJson, jsonbs) chooseRep a [TypeOther "foo", TypeJson] >>= (@?= (TypeJson, jsonbs))
caseChooseRepRaw :: Assertion caseChooseRepRaw :: Assertion
caseChooseRepRaw = do caseChooseRepRaw = do
@ -178,10 +193,10 @@ caseChooseRepRaw = do
foo = TypeOther "foo" foo = TypeOther "foo"
bar = TypeOther "bar" bar = TypeOther "bar"
hasreps = [(TypeHtml, content), (foo, content)] hasreps = [(TypeHtml, content), (foo, content)]
chooseRep hasreps [TypeHtml] @?= (TypeHtml, content) chooseRep hasreps [TypeHtml] >>= (@?= (TypeHtml, content))
chooseRep hasreps [foo, bar] @?= (foo, content) chooseRep hasreps [foo, bar] >>= (@?= (foo, content))
chooseRep hasreps [bar, foo] @?= (foo, content) chooseRep hasreps [bar, foo] >>= (@?= (foo, content))
chooseRep hasreps [bar] @?= (TypeHtml, content) chooseRep hasreps [bar] >>= (@?= (TypeHtml, content))
caseChooseRepTemplate :: Assertion caseChooseRepTemplate :: Assertion
caseChooseRepTemplate = do caseChooseRepTemplate = do
@ -193,15 +208,31 @@ caseChooseRepTemplate = do
res1 = cs "foo:&lt;fooval&gt;, bar:bar1bar2" res1 = cs "foo:&lt;fooval&gt;, bar:bar1bar2"
res2 = cs $ "{\"bar\":[\"bar1\",\"bar2\"]," ++ res2 = cs $ "{\"bar\":[\"bar1\",\"bar2\"]," ++
"\"foo\":\"&lt;fooval&gt;\"}" "\"foo\":\"&lt;fooval&gt;\"}"
(1, chooseRep hasreps [TypeHtml]) @?= (1, (TypeHtml, res1)) chooseRep hasreps [TypeHtml] >>= (@?= (TypeHtml, res1))
(2, chooseRep hasreps [TypeJson]) @?= (2, (TypeJson, res2)) chooseRep hasreps [TypeJson] >>= (@?= (TypeJson, res2))
(3, chooseRep hasreps [TypeHtml, TypeJson]) @?= (3, (TypeHtml, res1)) chooseRep hasreps [TypeHtml, TypeJson] >>= (@?= (TypeHtml, res1))
(4, chooseRep hasreps [TypeJson, TypeHtml]) @?= (4, (TypeJson, res2)) chooseRep hasreps [TypeJson, TypeHtml] >>= (@?= (TypeJson, res2))
caseChooseRepTemplateFile :: Assertion
caseChooseRepTemplateFile = do
let temp = "test/rep.st"
ho = toHtmlObject [ ("foo", toHtmlObject "<fooval>")
, ("bar", toHtmlObject ["bar1", "bar2"])
]
hasreps = TemplateFile temp ho
res1 = cs "foo:&lt;fooval&gt;, bar:bar1bar2"
res2 = cs $ "{\"bar\":[\"bar1\",\"bar2\"]," ++
"\"foo\":\"&lt;fooval&gt;\"}"
chooseRep hasreps [TypeHtml] >>= (@?= (TypeHtml, res1))
chooseRep hasreps [TypeJson] >>= (@?= (TypeJson, res2))
chooseRep hasreps [TypeHtml, TypeJson] >>= (@?= (TypeHtml, res1))
chooseRep hasreps [TypeJson, TypeHtml] >>= (@?= (TypeJson, res2))
testSuite :: Test testSuite :: Test
testSuite = testGroup "Yesod.Rep" testSuite = testGroup "Yesod.Rep"
[ testCase "caseChooseRep HtmlObject" caseChooseRepHO [ testCase "caseChooseRep HtmlObject" caseChooseRepHO
, testCase "caseChooseRep raw" caseChooseRepRaw , testCase "caseChooseRep raw" caseChooseRepRaw
, testCase "caseChooseRep Template" caseChooseRepTemplate , testCase "caseChooseRep Template" caseChooseRepTemplate
, testCase "caseChooseRep TemplateFile" caseChooseRepTemplateFile
] ]
#endif #endif

1
test/rep.st Normal file
View File

@ -0,0 +1 @@
foo:$o.foo$, bar:$o.bar$