summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJasper Van der Jeugt <jaspervdj@gmail.com>2010-03-08 21:42:56 +0100
committerJasper Van der Jeugt <jaspervdj@gmail.com>2010-03-08 21:42:56 +0100
commit45459c3a2086aa47f35b90ecc5e658fdc72e7982 (patch)
tree2f0598c3aea058ebff9029dd8b55f1ec9907c36e
parent64b640f97d00c119ef4ed4c8ccf8e588226bfcad (diff)
downloadhakyll-45459c3a2086aa47f35b90ecc5e658fdc72e7982.tar.gz
Added renderAtom, feeds now validate.
-rw-r--r--data/templates/atom-item.xml7
-rw-r--r--data/templates/atom.xml13
-rw-r--r--data/templates/rss-item.xml2
-rw-r--r--data/templates/rss.xml5
-rw-r--r--hakyll.cabal6
-rw-r--r--src/Text/Hakyll/Feed.hs127
-rw-r--r--src/Text/Hakyll/Rss.hs83
7 files changed, 157 insertions, 86 deletions
diff --git a/data/templates/atom-item.xml b/data/templates/atom-item.xml
new file mode 100644
index 0000000..78bdac7
--- /dev/null
+++ b/data/templates/atom-item.xml
@@ -0,0 +1,7 @@
+<entry>
+ <title>$title</title>
+ <link href="$absolute/$url" />
+ <id>$absolute/$url</id>
+ <updated>$timestamp</updated>
+ <summary>$description</summary>
+</entry>
diff --git a/data/templates/atom.xml b/data/templates/atom.xml
new file mode 100644
index 0000000..578f54f
--- /dev/null
+++ b/data/templates/atom.xml
@@ -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>
diff --git a/data/templates/rss-item.xml b/data/templates/rss-item.xml
index 794a036..fcfc2a5 100644
--- a/data/templates/rss-item.xml
+++ b/data/templates/rss-item.xml
@@ -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>
diff --git a/data/templates/rss.xml b/data/templates/rss.xml
index 3a58d08..cbf0b16 100644
--- a/data/templates/rss.xml
+++ b/data/templates/rss.xml
@@ -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>
diff --git a/hakyll.cabal b/hakyll.cabal
index 7977e91..93aa07a 100644
--- a/hakyll.cabal
+++ b/hakyll.cabal
@@ -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
@@ -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
diff --git a/src/Text/Hakyll/Feed.hs b/src/Text/Hakyll/Feed.hs
new file mode 100644
index 0000000..08f246d
--- /dev/null
+++ b/src/Text/Hakyll/Feed.hs
@@ -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."
diff --git a/src/Text/Hakyll/Rss.hs b/src/Text/Hakyll/Rss.hs
deleted file mode 100644
index 992e965..0000000
--- a/src/Text/Hakyll/Rss.hs
+++ /dev/null
@@ -1,83 +0,0 @@
--- | 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.Rss
- ( RssConfiguration (..)
- , renderRss
- , renderRssWith
- , renderRssDate
- ) where
-
-import Control.Arrow ((>>>), second)
-import Control.Monad.Reader (liftIO)
-
-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 (Renderable)
-
-import Paths_hakyll
-
--- | This is a data structure to keep the configuration of an RSS feed.
-data RssConfiguration = RssConfiguration
- { -- | Url of the RSS feed (relative to site root). For example, @rss.xml@.
- rssUrl :: String
- , -- | Title of the RSS feed.
- rssTitle :: String
- , -- | Description of the RSS feed.
- rssDescription :: String
- }
-
--- | This is an auxiliary function to create a listing that is, in fact, an RSS
--- feed.
-createRssWith :: ContextManipulation -- ^ Manipulation to apply on the items.
- -> RssConfiguration -- ^ Feed configuration.
- -> [Renderable] -- ^ Items to include.
- -> FilePath -- ^ RSS feed template.
- -> FilePath -- ^ RSS item template.
- -> Renderable
-createRssWith manipulation configuration renderables template itemTemplate =
- listing >>> render template
- where
- listing = createListingWith manipulation (rssUrl configuration)
- [itemTemplate] renderables additional
-
- additional = map (second $ Left . ($ configuration))
- [ ("title", rssTitle)
- , ("description", rssDescription)
- ]
-
--- | 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 :: RssConfiguration -- ^ 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@.
-renderRssWith :: ContextManipulation -- ^ Manipulation to apply on the items.
- -> RssConfiguration -- ^ Feed configuration.
- -> [Renderable] -- ^ Items to include in the feed.
- -> Hakyll ()
-renderRssWith manipulation configuration renderables = do
- template <- liftIO $ getDataFileName "templates/rss.xml"
- itemTemplate <- liftIO $ getDataFileName "templates/rss-item.xml"
- let renderRssWith' = createRssWith manipulation' configuration
- renderables template itemTemplate
- renderChain [] renderRssWith'
- where
- manipulation' = manipulation . renderRssDate
-
-renderRssDate :: ContextManipulation
-renderRssDate = renderDate "timestamp" "%a, %d %b %Y %H:%M:%S %Z" "No date found."