hablo/src/DOM/Card.hs

94 lines
3.2 KiB
Haskell
Raw Normal View History

{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
module DOM.Card (
HasCard(..)
, make
) where
import Article (Article(..))
2020-03-25 19:47:28 +01:00
import ArticlesList (ArticlesList(..))
import qualified ArticlesList (description)
import Blog (Blog(..), Renderer, Skin(..), template)
import Blog.URL (AbsoluteURL, checkURL, defaultOn, pathOn)
import Collection (Collection(..))
import qualified Collection (title)
import Control.Applicative ((<|>))
import Control.Monad.Reader (asks)
import qualified Data.Map as Map (lookup)
import Data.Text (Text, pack)
2021-07-01 09:01:08 +02:00
--import Lucid (HtmlT, content_, meta_)
--import Lucid.Base (makeAttribute)
import Markdown (MarkdownContent(..), metadata)
import Network.URL (URL)
import qualified Markdown (Markdown(..))
import Page (Page(..))
import Pretty ((.$))
import System.FilePath.Posix ((</>), (<.>))
2021-07-01 09:01:08 +02:00
import Text.Blaze.Html5 ((!), AttributeValue, Html, ToValue(..), meta, customAttribute)
import Text.Blaze.Html5.Attributes as A (content)
class HasCard a where
cardType :: Renderer m => a -> m Text
description :: Renderer m => a -> m Text
image :: Renderer m => a -> m (Maybe URL)
title :: Renderer m => a -> m String
urlPath :: Renderer m => a -> m String
2021-07-01 09:01:08 +02:00
og :: Applicative m => AttributeValue -> Text -> m Html
og attribute t =
pure $ meta
! (customAttribute "property" $ "og:" <> attribute)
! content (toValue t)
2021-07-01 09:01:08 +02:00
make :: (HasCard a, Renderer m) => a -> AbsoluteURL -> m Html
make element siteURL = do
og "url" . (pathOn siteURL) =<< urlPath element
og "type" =<< cardType element
og "title" . pack =<< title element
og "description" =<< description element
maybeImage =<< ((<|>) <$> image element <*> (asks $skin.$cardImage))
og "site_name" =<< (asks $name.$pack)
where
2021-07-01 09:01:08 +02:00
maybeImage = maybe (return mempty) (og "image" . defaultOn siteURL)
mDImage :: (Renderer m, MarkdownContent a) => a -> m (Maybe URL)
mDImage = mapM checkURL . Map.lookup "featuredImage" . metadata . getMarkdown
mDTitle :: (Renderer m, MarkdownContent a) => a -> m String
mDTitle = return . Markdown.title . getMarkdown
mDUrlPath :: (Renderer m, MarkdownContent a) => a -> m String
mDUrlPath a = return $ Markdown.path (getMarkdown a) <.> "html"
mDDescription :: (Renderer m, MarkdownContent a) => String -> a -> m Text
mDDescription key =
getDescription . Map.lookup "summary" . metadata . getMarkdown
where
getDescription = maybe defaultDescription (return . pack)
defaultDescription = asks name >>= template key . \v -> [("name", pack v)]
instance HasCard Article where
cardType _ = return "article"
description = mDDescription "articleDescription"
image = mDImage
title = mDTitle
urlPath = mDUrlPath
instance HasCard Page where
cardType _ = return "website"
description = mDDescription "pageDescription"
image = mDImage
title = mDTitle
urlPath = mDUrlPath
instance HasCard ArticlesList where
cardType _ = return "website"
description = ArticlesList.description
image _ = return Nothing
title (ArticlesList {collection}) = Collection.title collection
urlPath al@(ArticlesList {collection}) =
return $ maybe "" id (tag collection) </> file
where
file = (if full al then "all" else "index") <.> ".html"