2019-02-02 23:23:05 +01:00
|
|
|
{-# LANGUAGE NamedFieldPuns #-}
|
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
module HTML (
|
|
|
|
generate
|
|
|
|
) where
|
|
|
|
|
|
|
|
import Article(Article(..))
|
2019-02-03 22:56:21 +01:00
|
|
|
import ArticlesList (ArticlesList(..))
|
2019-02-15 15:11:31 +01:00
|
|
|
import Blog (Blog(..), Path(..), Skin(..))
|
2019-02-03 22:56:21 +01:00
|
|
|
import qualified Blog (get)
|
|
|
|
import Control.Monad (forM)
|
2019-02-02 23:23:05 +01:00
|
|
|
import Control.Monad.IO.Class (MonadIO(..))
|
|
|
|
import Control.Monad.Reader (MonadReader(..), ReaderT)
|
|
|
|
import Data.List (sortOn)
|
2019-02-15 14:16:21 +01:00
|
|
|
import Data.Map ((!))
|
2019-02-02 23:23:05 +01:00
|
|
|
import qualified Data.Map as Map (elems, filterWithKey, toList)
|
|
|
|
import Data.Ord (Down(..))
|
|
|
|
import qualified Data.Set as Set (member)
|
|
|
|
import qualified Data.Text.Lazy.IO as TextIO (writeFile)
|
2019-02-04 15:50:35 +01:00
|
|
|
import Dom (page)
|
2019-02-02 23:23:05 +01:00
|
|
|
import Lucid
|
2019-02-07 17:51:06 +01:00
|
|
|
import Pretty ((.$))
|
2019-02-02 23:23:05 +01:00
|
|
|
import System.Directory (createDirectoryIfMissing)
|
2019-02-03 22:56:21 +01:00
|
|
|
import System.FilePath.Posix ((</>), (<.>))
|
2019-02-02 23:23:05 +01:00
|
|
|
|
2019-02-03 22:56:21 +01:00
|
|
|
data Collection = Collection {
|
|
|
|
articlesFeatured :: [Article]
|
|
|
|
, basePath :: FilePath
|
|
|
|
, tag :: Maybe String
|
|
|
|
}
|
|
|
|
|
|
|
|
collection :: Monad m => [Article] -> Maybe String -> ReaderT Blog m Collection
|
|
|
|
collection articlesFeatured tag = do
|
2019-02-15 15:11:31 +01:00
|
|
|
root <- Blog.get $path.$root
|
2019-02-03 22:56:21 +01:00
|
|
|
return $ Collection {
|
|
|
|
articlesFeatured = sortByDate articlesFeatured
|
|
|
|
, basePath = maybe root (root </>) tag
|
|
|
|
, tag
|
|
|
|
}
|
2019-02-02 23:23:05 +01:00
|
|
|
where
|
2019-02-15 14:16:21 +01:00
|
|
|
sortByDate = sortOn (Down . (! "date") . metadata)
|
2019-02-03 22:56:21 +01:00
|
|
|
|
|
|
|
articlesLists :: Monad m => Collection -> ReaderT Blog m [(FilePath, ArticlesList)]
|
|
|
|
articlesLists (Collection {articlesFeatured, basePath, tag}) = do
|
2019-02-07 17:51:06 +01:00
|
|
|
limit <- take <$> (Blog.get $skin.$previewArticlesCount)
|
2019-02-03 22:56:21 +01:00
|
|
|
return [
|
|
|
|
(basePath </> "index.html", ArticlesList {
|
|
|
|
tagged = tag
|
|
|
|
, full = False
|
|
|
|
, featured = limit articlesFeatured
|
|
|
|
})
|
|
|
|
, (basePath </> "all.html", ArticlesList {
|
|
|
|
tagged = tag
|
|
|
|
, full = True
|
|
|
|
, featured = articlesFeatured
|
|
|
|
})
|
|
|
|
]
|
|
|
|
|
|
|
|
generateArticles :: [Article] -> ReaderT Blog IO ()
|
|
|
|
generateArticles = mapM_ $ \article -> do
|
2019-02-15 18:07:59 +01:00
|
|
|
baseDir <- (</>) <$> (Blog.get $path.$root) <*> (Blog.get $path.$articlesPath)
|
2019-02-04 15:50:35 +01:00
|
|
|
(renderTextT $ page article)
|
2019-02-15 18:07:59 +01:00
|
|
|
>>= liftIO . TextIO.writeFile (baseDir </> key article <.> "html")
|
2019-02-03 22:56:21 +01:00
|
|
|
|
|
|
|
generateCollection :: Collection -> ReaderT Blog IO ()
|
|
|
|
generateCollection (Collection {articlesFeatured = []}) = return ()
|
|
|
|
generateCollection aCollection = do
|
|
|
|
liftIO . createDirectoryIfMissing False $ basePath aCollection
|
|
|
|
articlesLists aCollection
|
|
|
|
>>= (mapM_ $ \(filePath, articlesList) ->
|
2019-02-04 15:50:35 +01:00
|
|
|
(renderTextT $ page articlesList)
|
2019-02-03 22:56:21 +01:00
|
|
|
>>= liftIO . TextIO.writeFile filePath
|
|
|
|
)
|
2019-02-02 23:23:05 +01:00
|
|
|
|
|
|
|
generate :: ReaderT Blog IO ()
|
|
|
|
generate = do
|
2019-02-03 22:56:21 +01:00
|
|
|
Blog {articles, tags} <- ask
|
|
|
|
generateArticles $ Map.elems articles
|
|
|
|
collection (Map.elems articles) Nothing >>= generateCollection
|
|
|
|
forM (Map.toList tags) $
|
|
|
|
\(tag, tagged) -> collection (getArticles tagged articles) $ Just tag
|
|
|
|
>>= mapM_ generateCollection
|
2019-02-02 23:23:05 +01:00
|
|
|
where
|
|
|
|
getArticles tagged = Map.elems . Map.filterWithKey (\k _ -> Set.member k tagged)
|