Skip to content

Commit

Permalink
Added renderAtom, feeds now validate.
Browse files Browse the repository at this point in the history
  • Loading branch information
jaspervdj committed Mar 8, 2010
1 parent 64b640f commit 45459c3
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 86 deletions.
7 changes: 7 additions & 0 deletions data/templates/atom-item.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<entry>
<title>$title</title>
<link href="$absolute/$url" />
<id>$absolute/$url</id>
<updated>$timestamp</updated>
<summary>$description</summary>
</entry>
13 changes: 13 additions & 0 deletions data/templates/atom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>$title</title>
<link href="$absolute/$url" rel="self" />
<link href="$absolute" />
<!-- We use the link as id. -->
<id>$absolute/$url</id>
<author>
<name>$authorName</name>
</author>
<updated>$timestamp</updated>
$body
</feed>
2 changes: 2 additions & 0 deletions data/templates/rss-item.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@
<link>$absolute/$url</link>
<description>$description</description>
<pubDate>$timestamp</pubDate>
<!-- We use the link as id. -->
<guid>$absolute/$url</guid>
</item>
5 changes: 4 additions & 1 deletion data/templates/rss.xml
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
<?xml version="1.0" encoding="utf8"?>
<rss version="2.0">
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>$title</title>
<link>$absolute</link>
<description>$description</description>
<atom:link href="$absolute/$url" rel="self"
type="application/rss+xml" />
<lastBuildDate>$timestamp</lastBuildDate>
$body
</channel>
</rss>
6 changes: 4 additions & 2 deletions hakyll.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ License-File: LICENSE
Category: Text
Cabal-Version: >= 1.6
Data-Dir: data
Data-Files: templates/rss.xml
Data-Files: templates/atom.xml
templates/atom-item.xml
templates/rss.xml
templates/rss-item.xml

build-type: Simple
Expand Down Expand Up @@ -51,7 +53,7 @@ library
Text.Hakyll.Paginate
Text.Hakyll.Util
Text.Hakyll.Tags
Text.Hakyll.Rss
Text.Hakyll.Feed
Text.Hakyll.Internal.Cache
Text.Hakyll.Internal.CompressCss
Text.Hakyll.Internal.FileType
Expand Down
127 changes: 127 additions & 0 deletions src/Text/Hakyll/Feed.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
-- | A Module that allows easy rendering of RSS feeds. If you use this module,
-- you must make sure you set the `absoluteUrl` field in the main Hakyll
-- configuration.
module Text.Hakyll.Feed
( FeedConfiguration (..)
, renderRss
, renderRssWith
, renderAtom
, renderAtomWith
) where

import Control.Arrow ((>>>), second)
import Control.Monad.Reader (liftIO)
import Data.Maybe (fromMaybe)
import qualified Data.Map as M

import Text.Hakyll.Context (ContextManipulation, renderDate)
import Text.Hakyll.Hakyll (Hakyll)
import Text.Hakyll.Render (render, renderChain)
import Text.Hakyll.Renderables (createListingWith)
import Text.Hakyll.RenderAction

import Paths_hakyll

-- | This is a data structure to keep the configuration of a feed.
data FeedConfiguration = FeedConfiguration
{ -- | Url of the feed (relative to site root). For example, @rss.xml@.
feedUrl :: String
, -- | Title of the feed.
feedTitle :: String
, -- | Description of the feed.
feedDescription :: String
, -- | Name of the feed author.
feedAuthorName :: String
}

-- | This is an auxiliary function to create a listing that is, in fact, a feed.
-- The items should be sorted on date.
createFeedWith :: ContextManipulation -- ^ Manipulation to apply on the items.
-> FeedConfiguration -- ^ Feed configuration.
-> [Renderable] -- ^ Items to include.
-> FilePath -- ^ Feed template.
-> FilePath -- ^ Item template.
-> Renderable
createFeedWith manipulation configuration renderables template itemTemplate =
listing >>> render template
where
listing = createListingWith manipulation (feedUrl configuration)
[itemTemplate] renderables additional

additional = map (second $ Left . ($ configuration))
[ ("title", feedTitle)
, ("description", feedDescription)
, ("authorName", feedAuthorName)
] ++ updated

-- Take the first timestamp, which should be the most recent.
updated = let action = createRenderAction $
return . fromMaybe "foo" . M.lookup "timestamp"
manip = createManipulationAction manipulation
toTuple r = ("timestamp", Right $ r >>> manip >>> action)
in map toTuple $ take 1 renderables


-- | Abstract function to render any feed.
renderFeedWith :: ContextManipulation -- ^ Manipulation to apply on the items.
-> FeedConfiguration -- ^ Feed configuration.
-> [Renderable] -- ^ Items to include in the feed.
-> FilePath -- ^ Feed template.
-> FilePath -- ^ Item template.
-> Hakyll ()
renderFeedWith manipulation configuration renderables template itemTemplate = do
template' <- liftIO $ getDataFileName template
itemTemplate' <- liftIO $ getDataFileName itemTemplate
let renderFeedWith' = createFeedWith manipulation configuration
renderables template' itemTemplate'
renderChain [] renderFeedWith'

-- | Render an RSS feed with a number of items.
--
-- Note that the @Renderable@s should have the following fields:
--
-- - @$title@: Title of the item.
--
-- - @$description@: Description to appear in the feed.
--
-- - @$url@: URL to the item - this is usually set automatically.
--
renderRss :: FeedConfiguration -- ^ Feed configuration.
-> [Renderable] -- ^ Items to include in the feed.
-> Hakyll ()
renderRss = renderRssWith id

-- | Render an RSS feed with a number of items. This function allows you to
-- specify a @ContextManipulation@ which will be applied on every
-- @Renderable@. Note that the given @Renderable@s should be sorted so the
-- most recent one is first.
renderRssWith :: ContextManipulation -- ^ Manipulation to apply on the items.
-> FeedConfiguration -- ^ Feed configuration.
-> [Renderable] -- ^ Items to include in the feed.
-> Hakyll ()
renderRssWith manipulation configuration renderables =
renderFeedWith manipulation' configuration renderables
"templates/rss.xml" "templates/rss-item.xml"
where
manipulation' = manipulation . renderRssDate

renderRssDate :: ContextManipulation
renderRssDate = renderDate "timestamp" "%a, %d %b %Y %H:%M:%S UT" "No date found."

renderAtom :: FeedConfiguration
-> [Renderable]
-> Hakyll ()
renderAtom = renderAtomWith id

renderAtomWith :: ContextManipulation -- ^ Manipulation to apply on the items.
-> FeedConfiguration -- ^ Feed configuration.
-> [Renderable] -- ^ Items to include in the feed.
-> Hakyll ()
renderAtomWith manipulation configuration renderables =
renderFeedWith manipulation' configuration renderables
"templates/atom.xml" "templates/atom-item.xml"
where
manipulation' = manipulation . renderAtomDate

renderAtomDate :: ContextManipulation
renderAtomDate = renderDate "timestamp" "%Y-%m-%dT%H:%M:%SZ" "No date found."
83 changes: 0 additions & 83 deletions src/Text/Hakyll/Rss.hs

This file was deleted.

0 comments on commit 45459c3

Please sign in to comment.