Added basic XML support

This commit is contained in:
Michael Snoyman 2009-12-28 23:52:10 +02:00
parent dc355edf7d
commit 579583c1d2
4 changed files with 84 additions and 93 deletions

View File

@ -20,6 +20,9 @@ module Data.Object.Html
Html (..)
, HtmlDoc (..)
, HtmlObject
-- * XML helpers
, XmlDoc (..)
, cdata
-- * Standard 'Object' functions
, toHtmlObject
, fromHtmlObject
@ -85,26 +88,47 @@ showAttribs = TL.concat . map helper where
, cs "\""
]
instance ConvertSuccess Html Text where
convertSuccess (Html t) = t
convertSuccess (Text t) = encodeHtml t
convertSuccess (Tag n as content) = TL.concat
htmlToText :: Bool -- ^ True to close empty tags like XML, False like HTML
-> Html
-> Text
htmlToText _ (Html t) = t
htmlToText _ (Text t) = encodeHtml t
htmlToText xml (Tag n as content) = TL.concat
[ cs "<"
, cs n
, showAttribs as
, cs ">"
, cs content
, htmlToText xml content
, cs "</"
, cs n
, cs ">"
]
convertSuccess (EmptyTag n as) = TL.concat
htmlToText xml (EmptyTag n as) = TL.concat
[ cs "<"
, cs n
, showAttribs as
, cs ">"
, cs $ if xml then "/>" else ">"
]
htmlToText xml (HtmlList l) = TL.concat $ map (htmlToText xml) l
instance ConvertSuccess Html Text where
convertSuccess = htmlToText False
-- | Not fully typesafe. You must make sure that when converting to this, the
-- 'Html' starts with a tag.
newtype XmlDoc = XmlDoc { unXmlDoc :: Text }
instance ConvertSuccess Html XmlDoc where
convertSuccess h = XmlDoc $ TL.concat
[ cs "<?xml version='1.0' encoding='utf-8' ?>\n"
, htmlToText True h
]
-- | Wrap an 'Html' in CDATA for XML output.
cdata :: Html -> Html
cdata h = HtmlList
[ Html $ cs "<![CDATA["
, h
, Html $ cs "]]>"
]
convertSuccess (HtmlList l) = TL.concat $ map cs l
instance ConvertSuccess Html String where
convertSuccess = cs . (cs :: Html -> Text)

View File

@ -22,11 +22,8 @@ module Yesod.Helpers.AtomFeed
) where
import Yesod
import Data.Text.Lazy (Text)
import qualified Data.Text.Lazy as TL
import Data.Time.Clock
import Web.Encodings
import Data.Time.Clock (UTCTime)
import Web.Encodings (formatW3)
data AtomFeedResponse = AtomFeedResponse AtomFeed Approot
@ -55,47 +52,26 @@ data AtomFeedEntry = AtomFeedEntry
}
instance ConvertSuccess AtomFeedResponse Content where
convertSuccess = (cs :: Text -> Content) . cs
instance ConvertSuccess AtomFeedResponse Text where
convertSuccess (AtomFeedResponse f ar) = TL.concat
[ cs "<?xml version='1.0' encoding='utf-8' ?>\n"
, cs "<feed xmlns='http://www.w3.org/2005/Atom'>"
, cs "<title>"
, encodeHtml $ cs $ atomTitle f
, cs "</title>"
, cs "<link rel='self' href='"
, encodeHtml $ cs $ showLocation ar $ atomLinkSelf f
, cs "'/>"
, cs "<link href='"
, encodeHtml $ cs $ showLocation ar $ atomLinkHome f
, cs "'/>"
, cs "<updated>"
, cs $ formatW3 $ atomUpdated f
, cs "</updated>"
, cs "<id>"
, encodeHtml $ cs $ showLocation ar $ atomLinkHome f
, cs "</id>"
, TL.concat $ map cs $ zip (atomEntries f) $ repeat ar
, cs "</feed>"
convertSuccess = cs . (cs :: Html -> XmlDoc) . cs
instance ConvertSuccess AtomFeedResponse Html where
convertSuccess (AtomFeedResponse f ar) =
Tag "feed" [("xmlns", "http://www.w3.org/2005/Atom")] $ HtmlList
[ Tag "title" [] $ cs $ atomTitle f
, EmptyTag "link" [ ("rel", "self")
, ("href", showLocation ar $ atomLinkSelf f)
]
, EmptyTag "link" [ ("href", showLocation ar $ atomLinkHome f)
]
, Tag "updated" [] $ cs $ formatW3 $ atomUpdated f
, Tag "id" [] $ cs $ showLocation ar $ atomLinkHome f
, HtmlList $ map cs $ zip (atomEntries f) $ repeat ar
]
instance ConvertSuccess (AtomFeedEntry, Approot) Text where
convertSuccess (e, ar) = TL.concat
[ cs "<entry>"
, cs "<id>"
, encodeHtml $ cs $ showLocation ar $ atomEntryLink e
, cs "</id>"
, cs "<link href='"
, encodeHtml $ cs $ showLocation ar $ atomEntryLink e
, cs "' />"
, cs "<updated>"
, cs $ formatW3 $ atomEntryUpdated e
, cs "</updated>"
, cs "<title>"
, encodeHtml $ cs $ atomEntryTitle e
, cs "</title>"
, cs "<content type='html'><![CDATA["
, cs $ atomEntryContent e
, cs "]]></content>"
, cs "</entry>"
instance ConvertSuccess (AtomFeedEntry, Approot) Html where
convertSuccess (e, ar) = Tag "entry" [] $ HtmlList
[ Tag "id" [] $ cs $ showLocation ar $ atomEntryLink e
, EmptyTag "link" [("href", showLocation ar $ atomEntryLink e)]
, Tag "updated" [] $ cs $ formatW3 $ atomEntryUpdated e
, Tag "title" [] $ cs $ atomEntryTitle e
, Tag "content" [("type", "html")] $ cdata $ atomEntryContent e
]

View File

@ -23,15 +23,9 @@ module Yesod.Helpers.Sitemap
, SitemapResponse (..)
) where
import Yesod.Definitions
import Yesod.Handler
import Yesod.Rep
import Web.Encodings
import Yesod
import Web.Encodings (formatW3)
import Data.Time (UTCTime)
import Data.Convertible.Text
import Data.Text.Lazy (Text)
import qualified Data.Text.Lazy as TL
import Yesod.Yesod
data SitemapChangeFreq = Always
| Hourly
@ -48,6 +42,8 @@ instance ConvertSuccess SitemapChangeFreq String where
convertSuccess Monthly = "monthly"
convertSuccess Yearly = "yearly"
convertSuccess Never = "never"
instance ConvertSuccess SitemapChangeFreq Html where
convertSuccess = (cs :: String -> Html) . cs
data SitemapUrl = SitemapUrl
{ sitemapLoc :: Location
@ -57,26 +53,19 @@ data SitemapUrl = SitemapUrl
}
data SitemapResponse = SitemapResponse [SitemapUrl] Approot
instance ConvertSuccess SitemapResponse Content where
convertSuccess = cs . (cs :: SitemapResponse -> Text)
instance ConvertSuccess SitemapResponse Text where
convertSuccess (SitemapResponse urls ar) = TL.concat
[ cs "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
, cs "<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">"
, TL.concat $ map helper urls
, cs "</urlset>"
]
convertSuccess = cs . (cs :: Html -> XmlDoc) . cs
instance ConvertSuccess SitemapResponse Html where
convertSuccess (SitemapResponse urls ar) =
Tag "urlset" [("xmlns", sitemapNS)] $ HtmlList $ map helper urls
where
helper (SitemapUrl loc modTime freq pri) = cs $ concat
-- FIXME use HTML?
[ "<url><loc>"
, encodeHtml $ showLocation ar loc
, "</loc><lastmod>"
, formatW3 modTime
, "</lastmod><changefreq>"
, cs freq
, "</changefreq><priority>"
, show pri
, "</priority></url>"
sitemapNS = "http://www.sitemaps.org/schemas/sitemap/0.9"
helper :: SitemapUrl -> Html
helper (SitemapUrl loc modTime freq pri) =
Tag "url" [] $ HtmlList
[ Tag "loc" [] $ cs $ showLocation ar loc
, Tag "lastmod" [] $ cs $ formatW3 modTime
, Tag "changefreq" [] $ cs freq
, Tag "priority" [] $ cs $ show pri
]
instance HasReps SitemapResponse where

View File

@ -111,6 +111,8 @@ instance ConvertSuccess String Content where
convertSuccess = Content . cs
instance ConvertSuccess Html Content where
convertSuccess = Content . cs
instance ConvertSuccess XmlDoc Content where
convertSuccess = cs . unXmlDoc
type ContentPair = (ContentType, Content)
type RepChooser = [ContentType] -> IO ContentPair