{-# LANGUAGE OverloadedStrings #-} {- | Module : Web.RBB.Templates.Default Description : The default blog template Copyright : (c) Sebastian Witte License : BSD3 Maintainer : woozletoff@gmail.com Stability : experimental -} module Web.RBB.Templates.Default where import qualified Data.IxSet as IxSet import qualified Data.Set as Set import qualified Data.Text as Text import Data.Time import System.Locale import Text.Blaze.Html5 as H import Text.Blaze.Html5.Attributes as A import qualified Web.RBB.Config as Config import Web.RBB.Types.Entry as E import Web.RBB.Util entryRenderer :: Monad m => Config.BlogConfig m -> [(Entry, Html)] -> m Html entryRenderer cfg filteredEntries = case filteredEntries of [] -> return $ return () [(d, m)] -> let metaTable = renderMetaTable (Config.timeFormatter cfg) d in return $ withBlogHeader [metaTable, m] es -> do bURL <- Config.baseURL cfg return . forM_ es $ \(d,m) -> do let metaBox = renderMetaBox (Config.timeFormatter cfg) bURL d withBlogHeader [metaBox, m] cssFileName :: Text cssFileName = "default.css" timeFormatter :: UTCTime -> Text timeFormatter = pack . formatTime defaultTimeLocale (iso8601DateFormat Nothing) renderMetaTable :: (UTCTime -> Text) -> Entry -> Html renderMetaTable tf = renderMetaDataForEntry where renderMetaDataForEntry ed = H.div ! class_ "meta-table" $ table $ tbody $ mapM_ trow [ ("Title:", ed^.E.title) , ("Author:", ed^.author) , ("Tags:", (Text.unwords . Set.toList) (ed^.tags)) , ("Last Update:", (tf . entryUpdateTime) (ed^.lastUpdate)) ] trow :: (Text, Text) -> Html trow (l,r) = tr $ td (toHtml l) >> td (toHtml r) renderMetaBox :: (UTCTime -> Text) -> Text -> Entry -> Html renderMetaBox tf baseURL ed = let url = Text.concat [baseURL, "?id=", (pack . show) (ed^.entryId)] in H.a ! class_ "meta" ! href (toValue url) $ do H.span $ (toHtml . tf . entryUpdateTime . Set.findMax . IxSet.toSet) (ed^.updates) br H.span $ toHtml $ "by " <> ed^.author -- | Wrap the given 'Html' fragments inside a: -- @
Html fragments
@ withBlogHeader :: [Html] -> Html withBlogHeader es = H.div ! class_ "blog-with-metadata" $ section ! class_ "blog" $ sequence_ es -- | Given the path to the blog entries, create a 'BlogConfig' value that can -- be used as an overrideable template with most fields using default values. createDefaultBlogConfig :: (Monad m) => FilePath -> Config.BlogConfig m createDefaultBlogConfig ep = Config.BlogConfig { Config.baseURL = return "http://127.0.0.1/blog" , Config.entryRenderer = entryRenderer , Config.timeFormatter = timeFormatter , Config.entryPath = ep , Config.updateInterval = 10 }