2019-01-27 21:41:21 +01:00
|
|
|
{-# LANGUAGE NamedFieldPuns #-}
|
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
module Dom (
|
2019-02-04 15:50:35 +01:00
|
|
|
page
|
2019-01-27 21:41:21 +01:00
|
|
|
) where
|
|
|
|
|
2019-02-02 23:23:05 +01:00
|
|
|
import Article (Article(..))
|
2019-02-15 14:13:43 +01:00
|
|
|
import qualified Article (preview)
|
2019-02-03 22:56:21 +01:00
|
|
|
import ArticlesList (ArticlesList(..), otherLink, otherUrl, pageTitle)
|
2019-02-15 18:07:59 +01:00
|
|
|
import Blog (Blog(..), Path(..), Skin(..))
|
2019-02-03 22:56:21 +01:00
|
|
|
import qualified Blog (get)
|
|
|
|
import Control.Monad.Reader (ReaderT)
|
2019-02-02 23:23:05 +01:00
|
|
|
import qualified Data.Map as Map (keys)
|
2019-02-06 12:57:57 +01:00
|
|
|
import Data.Monoid ((<>))
|
2019-01-27 21:41:21 +01:00
|
|
|
import Data.Text (pack, empty)
|
|
|
|
import Lucid
|
2019-02-06 12:57:57 +01:00
|
|
|
import Lucid.Base (makeAttribute)
|
2019-02-07 17:51:06 +01:00
|
|
|
import Prelude hiding (head)
|
|
|
|
import Pretty ((.$))
|
2019-02-03 22:56:21 +01:00
|
|
|
import System.FilePath.Posix ((</>), (<.>))
|
2019-02-02 23:23:05 +01:00
|
|
|
|
|
|
|
type HtmlGenerator = HtmlT (ReaderT Blog IO)
|
2019-01-27 21:41:21 +01:00
|
|
|
|
2019-02-04 15:50:35 +01:00
|
|
|
class Page a where
|
2019-02-06 12:57:57 +01:00
|
|
|
card :: a -> HtmlGenerator ()
|
2019-02-04 22:50:41 +01:00
|
|
|
content :: a -> HtmlGenerator ()
|
2019-02-04 15:50:35 +01:00
|
|
|
|
|
|
|
instance Page Article where
|
2019-02-06 12:57:57 +01:00
|
|
|
card (Article {title}) =
|
|
|
|
("A new article on " <>) <$> Blog.get name
|
|
|
|
>>= makeCard title
|
|
|
|
|
2019-02-15 14:13:43 +01:00
|
|
|
content = article True
|
2019-02-04 15:50:35 +01:00
|
|
|
|
|
|
|
instance Page ArticlesList where
|
2019-02-06 12:57:57 +01:00
|
|
|
card al = do
|
|
|
|
blogName <- Blog.get name
|
|
|
|
makeCard (maybe blogName ((blogName ++ " - ") ++) $ tagged al) (pageTitle al)
|
|
|
|
|
2019-02-06 17:46:12 +01:00
|
|
|
content al@(ArticlesList {featured}) = do
|
2019-02-15 14:13:43 +01:00
|
|
|
preview <- Article.preview <$> (Blog.get $skin.$previewLinesCount)
|
2019-02-06 17:46:12 +01:00
|
|
|
h2_ . toHtml . pack $ pageTitle al
|
2019-02-06 17:49:28 +01:00
|
|
|
p_ . navigationA [href_ . pack $ otherUrl al] . toHtml . pack $ otherLink al
|
2019-02-15 14:13:43 +01:00
|
|
|
div_ [class_ "articles"] (
|
|
|
|
mapM_ (article False . preview) featured
|
|
|
|
)
|
|
|
|
|
|
|
|
article :: Bool -> Article -> HtmlGenerator ()
|
2019-02-15 18:07:59 +01:00
|
|
|
article raw (Article {key, body, title}) = do
|
|
|
|
url <- ("/" </>) . (</> key <.> extension) <$> (Blog.get $path.$articlesPath)
|
2019-02-15 14:13:43 +01:00
|
|
|
article_ (do
|
|
|
|
header_ (do
|
2019-02-15 18:07:59 +01:00
|
|
|
aElem [href_ . pack $ url] . h1_ $ toHtml title
|
2019-02-15 14:13:43 +01:00
|
|
|
)
|
|
|
|
pre_ . toHtml $ unlines body
|
|
|
|
)
|
|
|
|
where
|
|
|
|
(aElem, extension) = if raw then (a_, "md") else (navigationA, "html")
|
2019-02-04 15:50:35 +01:00
|
|
|
|
2019-02-06 12:57:57 +01:00
|
|
|
makeCard :: String -> String -> HtmlGenerator ()
|
|
|
|
makeCard title description = do
|
|
|
|
og "title" title
|
|
|
|
og "description" description
|
2019-02-07 17:51:06 +01:00
|
|
|
og "image" =<< (Blog.get $skin.$cardImage)
|
|
|
|
og "site_name" =<< Blog.get name
|
2019-02-06 12:57:57 +01:00
|
|
|
where
|
|
|
|
og attribute value = meta_ [makeAttribute "property" $ "og:" <> attribute , content_ $ pack value]
|
|
|
|
|
2019-02-06 17:49:28 +01:00
|
|
|
navigationA :: Term arg result => arg -> result
|
|
|
|
navigationA = "a" `termWith` [class_ "navigation"]
|
|
|
|
|
2019-02-02 23:23:05 +01:00
|
|
|
tag :: String -> HtmlGenerator ()
|
2019-02-06 17:49:28 +01:00
|
|
|
tag tagName = li_ (navigationA [href_ $ pack ("/" </> tagName)] $ toHtml tagName)
|
2019-02-02 23:23:05 +01:00
|
|
|
|
|
|
|
defaultBanner :: HtmlGenerator ()
|
|
|
|
defaultBanner = do
|
|
|
|
div_ [id_ "header"] (
|
2019-02-06 17:49:28 +01:00
|
|
|
navigationA [href_ "/"] (
|
2019-02-03 22:56:21 +01:00
|
|
|
h1_ . toHtml =<< Blog.get name
|
2019-02-02 23:23:05 +01:00
|
|
|
)
|
|
|
|
)
|
2019-01-27 21:41:21 +01:00
|
|
|
|
2019-02-07 17:51:06 +01:00
|
|
|
faviconLink :: FilePath -> HtmlGenerator ()
|
|
|
|
faviconLink url = link_ [rel_ "shortcut icon", href_ $ pack url, type_ "image/x-icon"]
|
|
|
|
|
2019-02-04 15:50:35 +01:00
|
|
|
page :: Page a => a -> HtmlGenerator ()
|
|
|
|
page aPage =
|
2019-01-27 21:41:21 +01:00
|
|
|
doctypehtml_ (do
|
|
|
|
head_ (do
|
|
|
|
meta_ [charset_ "utf-8"]
|
2019-02-03 22:56:21 +01:00
|
|
|
title_ . toHtml =<< Blog.get name
|
2019-02-15 14:13:43 +01:00
|
|
|
script_ [src_ "/js/unit.js"] empty
|
|
|
|
script_ [src_ "/js/remarkable.min.js"] empty
|
2019-02-06 17:16:52 +01:00
|
|
|
script_ [src_ "/js/hablo.js"] empty
|
2019-02-07 17:51:06 +01:00
|
|
|
maybe (toHtml empty) faviconLink =<< (Blog.get $skin.$favicon)
|
2019-02-06 12:57:57 +01:00
|
|
|
card aPage
|
2019-02-07 17:51:06 +01:00
|
|
|
(Blog.get $skin.$head) >>= maybe (toHtml empty) toHtmlRaw
|
2019-01-27 21:41:21 +01:00
|
|
|
)
|
|
|
|
body_ (do
|
2019-02-07 17:51:06 +01:00
|
|
|
(Blog.get $skin.$banner) >>= maybe defaultBanner toHtmlRaw
|
2019-01-27 21:41:21 +01:00
|
|
|
div_ [id_ "navigator"] (do
|
2019-02-02 23:23:05 +01:00
|
|
|
h2_ "Tags"
|
2019-02-03 22:56:21 +01:00
|
|
|
ul_ . mapM_ tag . Map.keys =<< Blog.get tags
|
2019-01-27 21:41:21 +01:00
|
|
|
)
|
2019-02-04 15:50:35 +01:00
|
|
|
div_ [id_ "contents"] $ content aPage
|
2019-01-27 21:41:21 +01:00
|
|
|
)
|
|
|
|
)
|