on master help sign in
Added renderAtom, feeds now validate.
commit45459c3a2086aa47f35b90ecc5e658fdc72e7982 authorJasper Van der Jeugt <jaspervdj@gmail.com> dateMon 8 Mar 2010, 21:42 (17 years ago) parent64b640f
7 files changed+157−86
data/templates/atom-item.xml+7 data/templates/atom.xml+13 data/templates/rss-item.xml+2 data/templates/rss.xml+4−1 hakyll.cabal+4−2 src/Text/Hakyll/Feed.hs+127 src/Text/Hakyll/Rss.hs−83
data/templates/atom-item.xmlnew file+7
@@ -0,0 +1,7 @@
1+<entry>
2+ <title>$title</title>
3+ <link href="$absolute/$url" />
4+ <id>$absolute/$url</id>
5+ <updated>$timestamp</updated>
6+ <summary>$description</summary>
7+</entry>
data/templates/atom.xmlnew file+13
@@ -0,0 +1,13 @@
1+<?xml version="1.0" encoding="utf-8"?>
2+<feed xmlns="http://www.w3.org/2005/Atom">
3+ <title>$title</title>
4+ <link href="$absolute/$url" rel="self" />
5+ <link href="$absolute" />
6+ <!-- We use the link as id. -->
7+ <id>$absolute/$url</id>
8+ <author>
9+ <name>$authorName</name>
10+ </author>
11+ <updated>$timestamp</updated>
12+ $body
13+</feed>
data/templates/rss-item.xml+2
@@ -3,4 +3,6 @@
33 <link>$absolute/$url</link>
44 <description>$description</description>
55 <pubDate>$timestamp</pubDate>
6+ <!-- We use the link as id. -->
7+ <guid>$absolute/$url</guid>
68</item>
data/templates/rss.xml+4−1
@@ -1,9 +1,12 @@
11<?xml version="1.0" encoding="utf8"?>
2−<rss version="2.0">
2+<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
33 <channel>
44 <title>$title</title>
55 <link>$absolute</link>
66 <description>$description</description>
7+ <atom:link href="$absolute/$url" rel="self"
8+ type="application/rss+xml" />
9+ <lastBuildDate>$timestamp</lastBuildDate>
710 $body
811 </channel>
912</rss>
hakyll.cabal+4−2
@@ -13,7 +13,9 @@ License-File: LICENSE
1313Category: Text
1414Cabal-Version: >= 1.6
1515Data-Dir: data
16−Data-Files: templates/rss.xml
16+Data-Files: templates/atom.xml
17+ templates/atom-item.xml
18+ templates/rss.xml
1719 templates/rss-item.xml
1820
1921build-type: Simple
@@ -51,7 +53,7 @@ library
5153 Text.Hakyll.Paginate
5254 Text.Hakyll.Util
5355 Text.Hakyll.Tags
54− Text.Hakyll.Rss
56+ Text.Hakyll.Feed
5557 Text.Hakyll.Internal.Cache
5658 Text.Hakyll.Internal.CompressCss
5759 Text.Hakyll.Internal.FileType
src/Text/Hakyll/Feed.hsnew file+127
@@ -0,0 +1,127 @@
1+-- | A Module that allows easy rendering of RSS feeds. If you use this module,
2+-- you must make sure you set the `absoluteUrl` field in the main Hakyll
3+-- configuration.
4+module Text.Hakyll.Feed
5+ ( FeedConfiguration (..)
6+ , renderRss
7+ , renderRssWith
8+ , renderAtom
9+ , renderAtomWith
10+ ) where
11+
12+import Control.Arrow ((>>>), second)
13+import Control.Monad.Reader (liftIO)
14+import Data.Maybe (fromMaybe)
15+import qualified Data.Map as M
16+
17+import Text.Hakyll.Context (ContextManipulation, renderDate)
18+import Text.Hakyll.Hakyll (Hakyll)
19+import Text.Hakyll.Render (render, renderChain)
20+import Text.Hakyll.Renderables (createListingWith)
21+import Text.Hakyll.RenderAction
22+
23+import Paths_hakyll
24+
25+-- | This is a data structure to keep the configuration of a feed.
26+data FeedConfiguration = FeedConfiguration
27+ { -- | Url of the feed (relative to site root). For example, @rss.xml@.
28+ feedUrl :: String
29+ , -- | Title of the feed.
30+ feedTitle :: String
31+ , -- | Description of the feed.
32+ feedDescription :: String
33+ , -- | Name of the feed author.
34+ feedAuthorName :: String
35+ }
36+
37+-- | This is an auxiliary function to create a listing that is, in fact, a feed.
38+-- The items should be sorted on date.
39+createFeedWith :: ContextManipulation -- ^ Manipulation to apply on the items.
40+ -> FeedConfiguration -- ^ Feed configuration.
41+ -> [Renderable] -- ^ Items to include.
42+ -> FilePath -- ^ Feed template.
43+ -> FilePath -- ^ Item template.
44+ -> Renderable
45+createFeedWith manipulation configuration renderables template itemTemplate =
46+ listing >>> render template
47+ where
48+ listing = createListingWith manipulation (feedUrl configuration)
49+ [itemTemplate] renderables additional
50+
51+ additional = map (second $ Left . ($ configuration))
52+ [ ("title", feedTitle)
53+ , ("description", feedDescription)
54+ , ("authorName", feedAuthorName)
55+ ] ++ updated
56+
57+ -- Take the first timestamp, which should be the most recent.
58+ updated = let action = createRenderAction $
59+ return . fromMaybe "foo" . M.lookup "timestamp"
60+ manip = createManipulationAction manipulation
61+ toTuple r = ("timestamp", Right $ r >>> manip >>> action)
62+ in map toTuple $ take 1 renderables
63+
64+
65+-- | Abstract function to render any feed.
66+renderFeedWith :: ContextManipulation -- ^ Manipulation to apply on the items.
67+ -> FeedConfiguration -- ^ Feed configuration.
68+ -> [Renderable] -- ^ Items to include in the feed.
69+ -> FilePath -- ^ Feed template.
70+ -> FilePath -- ^ Item template.
71+ -> Hakyll ()
72+renderFeedWith manipulation configuration renderables template itemTemplate = do
73+ template' <- liftIO $ getDataFileName template
74+ itemTemplate' <- liftIO $ getDataFileName itemTemplate
75+ let renderFeedWith' = createFeedWith manipulation configuration
76+ renderables template' itemTemplate'
77+ renderChain [] renderFeedWith'
78+
79+-- | Render an RSS feed with a number of items.
80+--
81+-- Note that the @Renderable@s should have the following fields:
82+--
83+-- - @$title@: Title of the item.
84+--
85+-- - @$description@: Description to appear in the feed.
86+--
87+-- - @$url@: URL to the item - this is usually set automatically.
88+--
89+renderRss :: FeedConfiguration -- ^ Feed configuration.
90+ -> [Renderable] -- ^ Items to include in the feed.
91+ -> Hakyll ()
92+renderRss = renderRssWith id
93+
94+-- | Render an RSS feed with a number of items. This function allows you to
95+-- specify a @ContextManipulation@ which will be applied on every
96+-- @Renderable@. Note that the given @Renderable@s should be sorted so the
97+-- most recent one is first.
98+renderRssWith :: ContextManipulation -- ^ Manipulation to apply on the items.
99+ -> FeedConfiguration -- ^ Feed configuration.
100+ -> [Renderable] -- ^ Items to include in the feed.
101+ -> Hakyll ()
102+renderRssWith manipulation configuration renderables =
103+ renderFeedWith manipulation' configuration renderables
104+ "templates/rss.xml" "templates/rss-item.xml"
105+ where
106+ manipulation' = manipulation . renderRssDate
107+
108+renderRssDate :: ContextManipulation
109+renderRssDate = renderDate "timestamp" "%a, %d %b %Y %H:%M:%S UT" "No date found."
110+
111+renderAtom :: FeedConfiguration
112+ -> [Renderable]
113+ -> Hakyll ()
114+renderAtom = renderAtomWith id
115+
116+renderAtomWith :: ContextManipulation -- ^ Manipulation to apply on the items.
117+ -> FeedConfiguration -- ^ Feed configuration.
118+ -> [Renderable] -- ^ Items to include in the feed.
119+ -> Hakyll ()
120+renderAtomWith manipulation configuration renderables =
121+ renderFeedWith manipulation' configuration renderables
122+ "templates/atom.xml" "templates/atom-item.xml"
123+ where
124+ manipulation' = manipulation . renderAtomDate
125+
126+renderAtomDate :: ContextManipulation
127+renderAtomDate = renderDate "timestamp" "%Y-%m-%dT%H:%M:%SZ" "No date found."
src/Text/Hakyll/Rss.hsdeleted−83
@@ -1,83 +0,0 @@
1−-- | A Module that allows easy rendering of RSS feeds. If you use this module,
2−-- you must make sure you set the `absoluteUrl` field in the main Hakyll
3−-- configuration.
4−module Text.Hakyll.Rss
5− ( RssConfiguration (..)
6− , renderRss
7− , renderRssWith
8− , renderRssDate
9− ) where
10−
11−import Control.Arrow ((>>>), second)
12−import Control.Monad.Reader (liftIO)
13−
14−import Text.Hakyll.Context (ContextManipulation, renderDate)
15−import Text.Hakyll.Hakyll (Hakyll)
16−import Text.Hakyll.Render (render, renderChain)
17−import Text.Hakyll.Renderables (createListingWith)
18−import Text.Hakyll.RenderAction (Renderable)
19−
20−import Paths_hakyll
21−
22−-- | This is a data structure to keep the configuration of an RSS feed.
23−data RssConfiguration = RssConfiguration
24− { -- | Url of the RSS feed (relative to site root). For example, @rss.xml@.
25− rssUrl :: String
26− , -- | Title of the RSS feed.
27− rssTitle :: String
28− , -- | Description of the RSS feed.
29− rssDescription :: String
30− }
31−
32−-- | This is an auxiliary function to create a listing that is, in fact, an RSS
33−-- feed.
34−createRssWith :: ContextManipulation -- ^ Manipulation to apply on the items.
35− -> RssConfiguration -- ^ Feed configuration.
36− -> [Renderable] -- ^ Items to include.
37− -> FilePath -- ^ RSS feed template.
38− -> FilePath -- ^ RSS item template.
39− -> Renderable
40−createRssWith manipulation configuration renderables template itemTemplate =
41− listing >>> render template
42− where
43− listing = createListingWith manipulation (rssUrl configuration)
44− [itemTemplate] renderables additional
45−
46− additional = map (second $ Left . ($ configuration))
47− [ ("title", rssTitle)
48− , ("description", rssDescription)
49− ]
50−
51−-- | Render an RSS feed with a number of items.
52−--
53−-- Note that the @Renderable@s should have the following fields:
54−--
55−-- - @$title@: Title of the item.
56−--
57−-- - @$description@: Description to appear in the feed.
58−--
59−-- - @$url@: URL to the item - this is usually set automatically.
60−--
61−renderRss :: RssConfiguration -- ^ Feed configuration.
62− -> [Renderable] -- ^ Items to include in the feed.
63− -> Hakyll ()
64−renderRss = renderRssWith id
65−
66−-- | Render an RSS feed with a number of items. This function allows you to
67−-- specify a @ContextManipulation@ which will be applied on every
68−-- @Renderable@.
69−renderRssWith :: ContextManipulation -- ^ Manipulation to apply on the items.
70− -> RssConfiguration -- ^ Feed configuration.
71− -> [Renderable] -- ^ Items to include in the feed.
72− -> Hakyll ()
73−renderRssWith manipulation configuration renderables = do
74− template <- liftIO $ getDataFileName "templates/rss.xml"
75− itemTemplate <- liftIO $ getDataFileName "templates/rss-item.xml"
76− let renderRssWith' = createRssWith manipulation' configuration
77− renderables template itemTemplate
78− renderChain [] renderRssWith'
79− where
80− manipulation' = manipulation . renderRssDate
81−
82−renderRssDate :: ContextManipulation
83−renderRssDate = renderDate "timestamp" "%a, %d %b %Y %H:%M:%S %Z" "No date found."