Add a RSS module to generate feeds
This commit is contained in:
parent
42a8cd3b71
commit
11c9b3a068
2 changed files with 98 additions and 0 deletions
|
@ -8,6 +8,7 @@ import Data.Version (showVersion)
|
||||||
import qualified HTML (generate)
|
import qualified HTML (generate)
|
||||||
import qualified JS (generate)
|
import qualified JS (generate)
|
||||||
import qualified Paths_hablo as Hablo (version)
|
import qualified Paths_hablo as Hablo (version)
|
||||||
|
import qualified RSS (generate)
|
||||||
import System.Exit (exitSuccess)
|
import System.Exit (exitSuccess)
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
|
@ -18,4 +19,5 @@ main = do
|
||||||
config@(BlogConfig {}) -> Blog.build config >>= runReaderT (do
|
config@(BlogConfig {}) -> Blog.build config >>= runReaderT (do
|
||||||
HTML.generate
|
HTML.generate
|
||||||
JS.generate
|
JS.generate
|
||||||
|
RSS.generate
|
||||||
)
|
)
|
||||||
|
|
96
src/RSS.hs
Normal file
96
src/RSS.hs
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
{-# LANGUAGE NamedFieldPuns #-}
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
|
module RSS (
|
||||||
|
generate
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Article (Article(..))
|
||||||
|
import ArticlesList (ArticlesList(..))
|
||||||
|
import qualified ArticlesList (description, title)
|
||||||
|
import Blog (Blog(..), Path(..), Skin(..), URL(..))
|
||||||
|
import Collection (Collection(..), getAll)
|
||||||
|
import Control.Monad.IO.Class (MonadIO(..))
|
||||||
|
import Control.Monad.Reader (MonadReader, ReaderT, asks)
|
||||||
|
import Data.Text (Text)
|
||||||
|
import Data.Map ((!))
|
||||||
|
import qualified Data.Text.Lazy.IO as TextIO (writeFile)
|
||||||
|
import Data.Time (defaultTimeLocale, formatTime, rfc822DateFormat)
|
||||||
|
import Data.Time.Clock.POSIX (posixSecondsToUTCTime)
|
||||||
|
import Lucid (Attribute, HtmlT, Term, ToHtml(..), term, renderTextT)
|
||||||
|
import Lucid.Base (makeAttribute)
|
||||||
|
import Pretty ((.$))
|
||||||
|
import System.FilePath.Posix ((</>), (<.>))
|
||||||
|
|
||||||
|
prolog :: Monad m => HtmlT m ()
|
||||||
|
prolog = toHtmlRaw ("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" :: String)
|
||||||
|
|
||||||
|
version_ :: Text -> Attribute
|
||||||
|
version_ = makeAttribute "version"
|
||||||
|
|
||||||
|
xmlns_content_ :: Text -> Attribute
|
||||||
|
xmlns_content_ = makeAttribute "xmlns:content"
|
||||||
|
|
||||||
|
xmlns_atom_ :: Text -> Attribute
|
||||||
|
xmlns_atom_ = makeAttribute "xmlns:atom"
|
||||||
|
|
||||||
|
rss_ :: Term arg result => arg -> result
|
||||||
|
rss_ = term "rss"
|
||||||
|
|
||||||
|
channel_ :: Term arg result => arg -> result
|
||||||
|
channel_ = term "channel"
|
||||||
|
|
||||||
|
title_ :: Term arg result => arg -> result
|
||||||
|
title_ = term "title"
|
||||||
|
|
||||||
|
link_ :: Term arg result => arg -> result
|
||||||
|
link_ = term "link"
|
||||||
|
|
||||||
|
description_ :: Term arg result => arg -> result
|
||||||
|
description_ = term "description"
|
||||||
|
|
||||||
|
item_ :: Term arg result => arg -> result
|
||||||
|
item_ = term "item"
|
||||||
|
|
||||||
|
pubDate_ :: Term arg result => arg -> result
|
||||||
|
pubDate_ = term "pubDate"
|
||||||
|
|
||||||
|
articleItem :: MonadReader Blog m => String -> Article -> HtmlT m ()
|
||||||
|
articleItem siteURL (Article {key, metadata, title}) =
|
||||||
|
item_ $ do
|
||||||
|
title_ $ toHtml title
|
||||||
|
link_ . toHtml =<< link <$> (asks $path.$articlesPath)
|
||||||
|
pubDate_ . toHtml . rfc822Date $ metadata ! "date"
|
||||||
|
where
|
||||||
|
link path = siteURL </> path </> key <.> "html"
|
||||||
|
rfc822Date =
|
||||||
|
formatTime defaultTimeLocale rfc822DateFormat
|
||||||
|
. posixSecondsToUTCTime . fromIntegral . (read :: String -> Int)
|
||||||
|
|
||||||
|
feed :: MonadReader Blog m => String -> ArticlesList -> HtmlT m ()
|
||||||
|
feed siteURL al@(ArticlesList {tagged, featured}) = do
|
||||||
|
prolog
|
||||||
|
rss_ [version, content, atom] $ do
|
||||||
|
channel_ $ do
|
||||||
|
title_ . toHtml =<< ArticlesList.title al
|
||||||
|
link_ . toHtml $ siteURL </> maybe "" id tagged
|
||||||
|
description_ . toHtml =<< ArticlesList.description al
|
||||||
|
mapM_ (articleItem siteURL) featured
|
||||||
|
where
|
||||||
|
version = version_ "2.0"
|
||||||
|
content = xmlns_content_ "http://purl.org/rss/1.0/modules/content/"
|
||||||
|
atom = xmlns_atom_ "http://www.w3.org/2005/Atom"
|
||||||
|
|
||||||
|
generateCollection :: String -> Collection -> ReaderT Blog IO ()
|
||||||
|
generateCollection siteURL (Collection {articlesFeatured, basePath, tag}) = do
|
||||||
|
limit <- take <$> (asks $skin.$previewArticlesCount)
|
||||||
|
let articlesList = ArticlesList {
|
||||||
|
tagged = tag, full = False, featured = limit articlesFeatured
|
||||||
|
}
|
||||||
|
renderTextT (feed siteURL articlesList)
|
||||||
|
>>= liftIO . TextIO.writeFile (basePath </> "rss" <.> "xml")
|
||||||
|
|
||||||
|
generate :: ReaderT Blog IO ()
|
||||||
|
generate = (asks $urls.$rss) >>= maybe (return ()) generateAll
|
||||||
|
where
|
||||||
|
generateAll siteURL = Collection.getAll >>= mapM_ (generateCollection siteURL)
|
Loading…
Reference in a new issue