-- |A simple feed generator: HTML generator -- -- Copyright (c) 2006 Manuel M T Chakravarty -- -- License: -- --- Description --------------------------------------------------------------- -- -- Language: Haskell 98 -- -- Docs ---------------------------------------------------------------------- -- -- Introduction to Text.Html: -- module HTML ( channelToHTML ) where -- hierachical libraries import Control.Monad ( mplus, liftM2) import Data.Maybe ( isJust) import Text.Html -- lambdaFeed import Config ( Config(..)) import Date ( Date, addMinutes) import Feed ( URL, Channel(..), Image(..), Category(..), Item(..), Enclosure(..), GUID(..), Source(..)) -- Render a channel to HTML. -- channelToHTML :: Config -> Channel [Item] -> String channelToHTML config chan = renderHtml $ header << concatHtml [ thetitle << titleChan chan , primHtml "" , meta ! [httpequiv "Content-Type", content "text/html; charset=iso-8859-1"] -- FIXME: We should be able to parametrise the charset!! , languageChan chan `optional` \lang -> meta ! [httpequiv "Content-Language", content lang] , (liftM2 addMinutes (lastBuildDateChan chan) (ttlChan chan)) `optional` \expiryDate -> meta ! [httpequiv "expires", content (show expiryDate)] , generatorChan chan `optional` \gen -> meta ! [name "generator", content gen] , copyrightChan chan `optional` \cr -> meta ! [name "copyright", content cr] , (pubDateChan chan `mplus` lastBuildDateChan chan) `optional` \date -> meta ! [name "date", content (show date)] -- NB: `pubDate' takes preference ] +++ body << concatHtml [ imageChan chan `optional` imageToHTML , h1 << titleChan chan , p << descriptionChan chan ] +++ map itemToHTML (itemsChan chan) -- Render an channel image element in HTML. -- imageToHTML :: Image -> Html imageToHTML img = anchor ! ([href (linkImage img)] ++ descriptionImage img `optionalAttr` title) << image ! ([ theclass "channel" , src (urlImage img) , alt (titleImage img) ] ++ ((widthImage img `mplus` Just 88) `optionalAttr` (width.show))++ ((heightImage img `mplus` Just 31) `optionalAttr` height)) -- defaults from RSS 2.0 spec -- Render an item in HTML. -- itemToHTML :: Item -> Html itemToHTML item = thediv ! [theclass "item"] << concatHtml [ titleItem item `optional` \title -> linkItem item `optionalHrefFor` (h2 << title) , descriptionItem item `optional` (p <<) , thediv ! [theclass "authorDate"] << concatHtml [ authorItem item `optional` toHtml , if isJust (authorItem item) && isJust (authorItem item) then bulletWithSpace else noHtml , pubDateItem item `optional` (toHtml . show) ] , thediv ! [theclass "commentsEnclosure"] << concatHtml [ enclosureItem item `optional` enclosureToHtml , if isJust (enclosureItem item) && isJust (commentsItem item) then bulletWithSpace else noHtml , commentsItem item `optional` \commentsLink -> anchor ! [href commentsLink] << "Comments" ] ] where bulletWithSpace = spaceHtml +++ bullet +++ spaceHtml -- Render an enclosure to HTML. -- enclosureToHtml :: Enclosure -> Html enclosureToHtml enc = anchor ! [href (urlEnclosure enc), thetype (typeEnclosure enc) ] << "Enclosure" -- Render an optional element. -- optional :: Maybe a -> (a -> Html) -> Html optional = flip (maybe noHtml) -- Render an optional attribute. -- optionalAttr :: Maybe a -> (a -> HtmlAttr) -> [HtmlAttr] optionalAttr Nothing _ = [] optionalAttr (Just x) attr = [attr x] -- An optional enclosing href. -- optionalHrefFor :: Maybe String -> Html -> Html optionalHrefFor Nothing inner = inner optionalHrefFor (Just link) inner = anchor ! [href link] << inner