hablo/src/DOM.hs

125 lines
4.1 KiB
Haskell
Raw Normal View History

2019-01-27 21:41:21 +01:00
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
module DOM (
HasContent(..)
, htmlDocument
2019-01-27 21:41:21 +01:00
) where
import Article (Article)
2019-02-15 14:13:43 +01:00
import qualified Article (preview)
import ArticlesList (
ArticlesList(..), description, getArticles, otherURL, rssLinkTexts
)
import Blog (Blog(..), Skin(..), URL(..), template)
import Control.Monad.Reader (ReaderT, asks)
import Data.Map as Map (Map, toList)
import Data.Text (Text, pack, empty)
import DOM.Card (HasCard)
import qualified DOM.Card as Card (make)
import Files (absoluteLink)
2020-03-25 19:47:28 +01:00
import Lucid (
HtmlT, a_, article_, body_, charset_, class_, div_, doctypehtml_, h1_, h2_
, head_, header_, href_, li_, link_, id_, meta_, pre_, rel_, script_, src_
, title_, toHtml, toHtmlRaw, type_, ul_
)
import Markdown (Markdown(..), MarkdownContent(..))
import Page (Page)
import Prelude hiding (head, lookup)
import Pretty ((.$))
import System.FilePath.Posix ((<.>))
type HtmlGenerator = HtmlT (ReaderT Blog IO)
2019-01-27 21:41:21 +01:00
class HasCard a => HasContent a where
content :: a -> HtmlGenerator ()
instance HasContent Article where
content = mDContent True . getMarkdown
instance HasContent Page where
content = mDContent True . getMarkdown
instance HasContent ArticlesList where
content al@(ArticlesList {full}) = do
preview <- Article.preview <$> (asks $skin.$previewLinesCount)
2020-03-25 19:47:28 +01:00
h2_ . toHtml =<< description al
ul_ $ do
asks hasRSS >>= rssLink
li_ . a_ [href_ . pack $ otherURL al, class_ "other"] =<< otherLink
2019-02-15 14:13:43 +01:00
div_ [class_ "articles"] (
mapM_ (mDContent False . preview) =<< getArticles al
2019-02-15 14:13:43 +01:00
)
2019-02-17 19:52:28 +01:00
where
otherLink =
toHtml <$> template (if full then "latestLink" else "allLink") []
rssLink :: Bool -> HtmlGenerator ()
rssLink True = do
(text, title) <- rssLinkTexts al
li_ . a_ [href_ "rss.xml", class_ "RSS", title_ title] $ toHtml text
rssLink False = return ()
2019-02-15 14:13:43 +01:00
mDContent :: Bool -> Markdown -> HtmlGenerator ()
mDContent raw markdown@(Markdown {key, body}) =
article_ [id_ $ pack key] (do
header_ . h1_ $ mDLink raw markdown
2019-02-15 14:13:43 +01:00
pre_ . toHtml $ unlines body
)
mDLink :: Bool -> Markdown -> HtmlGenerator ()
mDLink raw (Markdown {Markdown.path, title}) =
a_ [href_ $ pack url] $ toHtml title
where
url = absoluteLink $ path <.> (if raw then "md" else "html")
tag :: String -> HtmlGenerator ()
tag name =
a_ [href_ . pack $ absoluteLink name ++ "/", class_ "tag"] $ toHtml name
defaultBanner :: HtmlGenerator ()
defaultBanner =
div_ [id_ "header"] (
a_ [href_ "/"] (
h1_ . toHtml =<< asks name
)
)
2019-01-27 21:41:21 +01:00
faviconLink :: FilePath -> HtmlGenerator ()
faviconLink url = link_ [
rel_ "shortcut icon", href_ . pack $ absoluteLink url, type_ "image/x-icon"
]
optional :: (a -> HtmlGenerator ()) -> Maybe a -> HtmlGenerator ()
optional = maybe (return ())
navigationSection ::
Text -> String -> ((String, a) -> HtmlGenerator ()) -> Map String a -> HtmlGenerator ()
navigationSection sectionId templateKey generator collection
| null collection = return ()
| otherwise =
div_ [id_ sectionId, class_ "navigator"] (do
h2_ . toHtml =<< template templateKey []
ul_ . mapM_ (li_ . generator) $ Map.toList collection
)
htmlDocument :: HasContent a => a -> HtmlGenerator ()
htmlDocument someContent =
2019-01-27 21:41:21 +01:00
doctypehtml_ (do
head_ (do
meta_ [charset_ "utf-8"]
title_ . toHtml =<< asks name
2019-02-15 14:13:43 +01:00
script_ [src_ "/js/remarkable.min.js"] empty
script_ [src_ "/js/hablo.js"] empty
optional faviconLink =<< (asks $skin.$favicon)
optional (Card.make someContent) =<< (asks $urls.$cards)
optional toHtmlRaw =<< (asks $skin.$head)
2019-01-27 21:41:21 +01:00
)
body_ (do
maybe defaultBanner toHtmlRaw =<< (asks $skin.$banner)
asks tags >>= navigationSection "tags" "tagsList"
(\(key, _) -> tag key)
asks pages >>= navigationSection "pages" "pagesList"
(\(_, page) -> mDLink False $ getMarkdown page)
div_ [id_ "contents"] $ content someContent
2019-01-27 21:41:21 +01:00
)
)