on master help sign in
Update tagblog example to work with Hakyll 3.
commit356191fcc743b9dace8d938a1556e22bbed50a10 authorBenedict Eastaugh <benedict@eastaugh.net> dateMon 28 Mar 2011, 21:59 (16 years ago) parentc288567
12 files changed+163−123
examples/tagblog/hakyll.hs+86−53 examples/tagblog/posts.html−4 examples/tagblog/posts/2009-11-05-a-first-post.markdown+16−15 examples/tagblog/posts/2009-11-10-another-post.markdown+10−9 examples/tagblog/posts/2009-11-28-a-third-post.markdown+14−13 examples/tagblog/posts/2009-12-04-this-blog-aint-dead.markdown+7−6 examples/tagblog/posts/2009-12-23-almost-christmas.markdown+8−7 examples/tagblog/templates/default.html+7−7 examples/tagblog/index.html → examples/tagblog/templates/index.html+5−3 examples/tagblog/templates/post.html+4−4 examples/tagblog/templates/postitem.html+2−2 examples/tagblog/templates/posts.html+4
examples/tagblog/hakyll.hs+86−53
@@ -1,71 +1,104 @@
1+{-# LANGUAGE OverloadedStrings #-}
12module Main where
23
3−import Control.Arrow ((>>>))
4−import Text.Hakyll (hakyll)
5−import Text.Hakyll.Render
6−import Text.Hakyll.Tags (readTagMap, renderTagCloud, renderTagLinks, withTagMap)
7−import Text.Hakyll.Feed (FeedConfiguration (..), renderRss)
8−import Text.Hakyll.File (getRecursiveContents, directory, removeSpaces)
9−import Text.Hakyll.CreateContext (createPage, createCustomPage, createListing)
10−import Text.Hakyll.ContextManipulations (renderDate, copyValue)
11−import Data.List (sort)
12−import Data.Map (toList)
13−import Control.Monad (forM_, liftM)
14−import Data.Either (Either(..))
4+import Prelude hiding (id)
5+import Control.Arrow ((>>>), (***), arr)
6+import Control.Category (id)
7+import Control.Monad (forM_)
8+import qualified Data.Map as M
9+import Data.Monoid (mempty, mconcat)
1510
16−main = hakyll "http://example.com" $ do
17− -- Static directory.
18− directory css "css"
11+import Hakyll
1912
20− -- Find all post paths.
21− postPaths <- liftM (reverse . sort) $ getRecursiveContents "posts"
22− let renderablePosts = map ((>>> postManipulation) . createPage) postPaths
13+main :: IO ()
14+main = hakyll $ do
15+ -- Compress CSS
16+ route "css/*" idRoute
17+ compile "css/*" compressCssCompiler
2318
24− -- Read tag map.
25− let tagMap = readTagMap "postTags" postPaths
19+ -- Render posts
20+ route "posts/*" $ setExtension ".html"
21+ compile "posts/*" $
22+ pageCompiler
23+ >>> arr (renderDateField "date" "%B %e, %Y" "Date unknown")
24+ >>> renderTagsField "prettytags" (fromCaptureString "tags/*")
25+ >>> applyTemplateCompiler "templates/post.html"
26+ >>> applyTemplateCompiler "templates/default.html"
27+ >>> relativizeUrlsCompiler
2628
27− -- Render all posts list.
28− renderPostList "posts.html" "All posts" renderablePosts
29+ -- Render posts list
30+ route "posts.html" $ idRoute
31+ create "posts.html" $
32+ constA mempty
33+ >>> arr (setField "title" "All posts")
34+ >>> requireAllA "posts/*" addPostList
35+ >>> applyTemplateCompiler "templates/posts.html"
36+ >>> applyTemplateCompiler "templates/default.html"
37+ >>> relativizeUrlsCompiler
2938
30− -- Render post list per tag
31− let renderListForTag tag posts =
32− renderPostList (tagToUrl tag) ("Posts tagged " ++ tag)
33− (map (>>> postManipulation) posts)
34− withTagMap tagMap renderListForTag
39+ -- Index
40+ route "index.html" $ idRoute
41+ create "index.html" $
42+ constA mempty
43+ >>> arr (setField "title" "Home")
44+ >>> requireA "tags" (setFieldA "tagcloud" (renderTagCloud'))
45+ >>> requireAllA "posts/*" (id *** arr (take 3 . reverse . sortByBaseName) >>> addPostList)
46+ >>> applyTemplateCompiler "templates/index.html"
47+ >>> applyTemplateCompiler "templates/default.html"
48+ >>> relativizeUrlsCompiler
3549
36− -- Render index, including recent posts.
37− let tagCloud = tagMap >>> renderTagCloud tagToUrl 100 200
38− index = createListing "index.html"
39− ["templates/postitem.html"]
40− (take 3 renderablePosts)
41− [ ("title", Left "Home")
42− , ("tagcloud", Right tagCloud)
43− ]
44− renderChain ["index.html", "templates/default.html"] index
50+ -- Tags
51+ create "tags" $
52+ requireAll "posts/*" (\_ ps -> readTags ps :: Tags String)
4553
46− -- Render all posts.
47− forM_ renderablePosts $ renderChain [ "templates/post.html"
48− , "templates/default.html"
49− ]
54+ -- Add a tag list compiler for every tag
55+ route "tags/*" $ setExtension ".html"
56+ metaCompile $ require_ "tags"
57+ >>> arr (M.toList . tagsMap)
58+ >>> arr (map (\(t, p) -> (tagIdentifier t, makeTagList t p)))
5059
51− -- Render rss feed
52− renderRss myFeedConfiguration $
53− map (>>> copyValue "body" "description") (take 3 renderablePosts)
60+ -- Render RSS feed
61+ route "rss.xml" $ idRoute
62+ create "rss.xml" $
63+ requireAll_ "posts/*"
64+ >>> renderRss feedConfiguration
5465
66+ -- Read templates
67+ compile "templates/*" templateCompiler
68+
69+ -- End
70+ return ()
5571 where
56− postManipulation = renderDate "date" "%B %e, %Y" "Date unknown"
57− >>> renderTagLinks tagToUrl
72+ renderTagCloud' :: Compiler (Tags String) String
73+ renderTagCloud' = renderTagCloud tagIdentifier 100 120
74+
75+ tagIdentifier :: String -> Identifier
76+ tagIdentifier = fromCaptureString "tags/*"
5877
59− tagToUrl tag = "$root/tags/" ++ removeSpaces tag ++ ".html"
78+-- | Auxiliary compiler: generate a post list from a list of given posts, and
79+-- add it to the current page under @$posts@
80+--
81+addPostList :: Compiler (Page String, [Page String]) (Page String)
82+addPostList = setFieldA "posts" $
83+ arr (reverse . sortByBaseName)
84+ >>> require "templates/postitem.html" (\p t -> map (applyTemplate t) p)
85+ >>> arr mconcat
86+ >>> arr pageBody
6087
61− renderPostList url title posts = do
62− let list = createListing url ["templates/postitem.html"]
63− posts [("title", Left title)]
64− renderChain ["posts.html", "templates/default.html"] list
88+makeTagList :: String
89+ -> [Page String]
90+ -> Compiler () (Page String)
91+makeTagList tag posts =
92+ constA (mempty, posts)
93+ >>> addPostList
94+ >>> arr (setField "title" ("Posts tagged &#8216;" ++ tag ++ "&#8217;"))
95+ >>> applyTemplateCompiler "templates/posts.html"
96+ >>> applyTemplateCompiler "templates/default.html"
6597
66−myFeedConfiguration = FeedConfiguration
67− { feedUrl = "rss.xml"
68− , feedTitle = "SimpleBlog RSS feed."
98+feedConfiguration :: FeedConfiguration
99+feedConfiguration = FeedConfiguration
100+ { feedTitle = "SimpleBlog RSS feed."
69101 , feedDescription = "A simple demo of an RSS feed created with Hakyll."
70102 , feedAuthorName = "Jasper Van der Jeugt"
103+ , feedRoot = "http://example.com"
71104 }
examples/tagblog/posts.htmldeleted−4
@@ -1,4 +0,0 @@
1−<h1>$title</h1>
2−<ul>
3− $body
4−</ul>
examples/tagblog/posts/2009-11-05-a-first-post.markdown+16−15
@@ -2,20 +2,21 @@
22title: A first post
33author: Julius Caesar
44tags: caesar, random crap
5+description: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
56---
6−Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus pretium leo
7−adipiscing lectus iaculis lobortis. Vivamus scelerisque velit dignissim metus
8−gravida sit amet dapibus ligula tempor. Quisque sit amet viverra nunc.
9−Suspendisse cursus elementum ante, ut venenatis nisi dictum eu. Nulla diam
10−ligula, eleifend in varius quis, malesuada a nibh. Vivamus consequat
11−pellentesque erat non blandit. Nunc sit amet eros vel massa semper ullamcorper
12−quis iaculis magna. Vestibulum ullamcorper urna sit amet est elementum
13−pulvinar. Vestibulum consequat lacus ac quam hendrerit tincidunt. Praesent
14−bibendum vehicula diam, nec sagittis risus tempus a. Nulla quis odio sit amet
15−odio vehicula cursus ut id odio. Curabitur semper magna euismod magna mollis
16−venenatis. Nunc eget eleifend velit. Mauris sed posuere sem. Fusce id nunc
17−nisi, a aliquam orci. Suspendisse laoreet justo non enim laoreet eget consequat
18−velit porttitor. Aenean faucibus sodales metus at tincidunt. Donec vestibulum
19−leo pulvinar erat auctor ac ultrices massa euismod. Phasellus blandit cursus
20−magna, eget lacinia mi lobortis sed. Suspendisse ultricies enim ligula, vel
7+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus pretium leo
8+adipiscing lectus iaculis lobortis. Vivamus scelerisque velit dignissim metus
9+gravida sit amet dapibus ligula tempor. Quisque sit amet viverra nunc.
10+Suspendisse cursus elementum ante, ut venenatis nisi dictum eu. Nulla diam
11+ligula, eleifend in varius quis, malesuada a nibh. Vivamus consequat
12+pellentesque erat non blandit. Nunc sit amet eros vel massa semper ullamcorper
13+quis iaculis magna. Vestibulum ullamcorper urna sit amet est elementum
14+pulvinar. Vestibulum consequat lacus ac quam hendrerit tincidunt. Praesent
15+bibendum vehicula diam, nec sagittis risus tempus a. Nulla quis odio sit amet
16+odio vehicula cursus ut id odio. Curabitur semper magna euismod magna mollis
17+venenatis. Nunc eget eleifend velit. Mauris sed posuere sem. Fusce id nunc
18+nisi, a aliquam orci. Suspendisse laoreet justo non enim laoreet eget consequat
19+velit porttitor. Aenean faucibus sodales metus at tincidunt. Donec vestibulum
20+leo pulvinar erat auctor ac ultrices massa euismod. Phasellus blandit cursus
21+magna, eget lacinia mi lobortis sed. Suspendisse ultricies enim ligula, vel
2122scelerisque mauris.
examples/tagblog/posts/2009-11-10-another-post.markdown+10−9
@@ -2,14 +2,15 @@
22title: Another post
33author: Marcus Tullius Cicero
44tags: cicero, random crap
5+description: Vestibulum in ultrices urna.
56---
6−Vestibulum in ultrices urna. Etiam tempor enim dui, nec malesuada elit. Donec
7−tempor ligula et quam volutpat quis fermentum eros congue. Sed ut pulvinar sem.
8−Sed aliquam ipsum id purus sollicitudin vulputate. Cras et mauris dui, vel
9−hendrerit leo. Ut metus ipsum, fermentum ac malesuada id, tempus pharetra quam.
10−Donec diam felis, consequat ac scelerisque cursus, gravida non lectus. Sed
11−faucibus elit dapibus diam elementum id varius nisi tristique. Proin consequat
12−faucibus neque in aliquam. Vestibulum ligula odio, pulvinar vel hendrerit
13−vitae, egestas ut nibh. Praesent ut velit elit, in consequat dolor. Praesent
14−sem enim, commodo in gravida sed, adipiscing vel eros. Lorem ipsum dolor sit
7+Vestibulum in ultrices urna. Etiam tempor enim dui, nec malesuada elit. Donec
8+tempor ligula et quam volutpat quis fermentum eros congue. Sed ut pulvinar sem.
9+Sed aliquam ipsum id purus sollicitudin vulputate. Cras et mauris dui, vel
10+hendrerit leo. Ut metus ipsum, fermentum ac malesuada id, tempus pharetra quam.
11+Donec diam felis, consequat ac scelerisque cursus, gravida non lectus. Sed
12+faucibus elit dapibus diam elementum id varius nisi tristique. Proin consequat
13+faucibus neque in aliquam. Vestibulum ligula odio, pulvinar vel hendrerit
14+vitae, egestas ut nibh. Praesent ut velit elit, in consequat dolor. Praesent
15+sem enim, commodo in gravida sed, adipiscing vel eros. Lorem ipsum dolor sit
1516amet, consectetur adipiscing elit. Proin non aliquam nunc.
examples/tagblog/posts/2009-11-28-a-third-post.markdown+14−13
@@ -2,18 +2,19 @@
22title: A third post
33author: Publius Ovidius Naso
44tags: epic fail, ovidius
5+description: Pellentesque tempor blandit elit, vel ultricies arcu congue egestas.
56---
6−Pellentesque tempor blandit elit, vel ultricies arcu congue egestas. Fusce
7−vitae rutrum nisl. Fusce id mauris libero, a venenatis tellus. Fusce iaculis,
8−lorem et ornare molestie, mauris risus mollis nisi, non fermentum lacus lacus
9−sit amet ipsum. Praesent lobortis ullamcorper dolor, eget convallis ligula
10−dignissim a. Suspendisse nulla nisi, congue et pharetra vel, convallis non
11−libero. Ut a nulla ipsum. Phasellus cursus velit id neque viverra ut
12−pellentesque justo posuere. Curabitur laoreet enim et velit tempor consectetur.
13−Donec eu pretium urna. Suspendisse vitae nisi at metus vestibulum aliquam in
14−sit amet nisl. Donec convallis lacinia odio, vestibulum molestie nunc feugiat
15−a. Suspendisse vehicula, sapien id aliquet consectetur, sem sapien ullamcorper
16−arcu, scelerisque porttitor elit ipsum posuere ligula. Nulla at velit eu metus
17−tincidunt auctor ut sit amet enim. Donec placerat dapibus nisi id facilisis.
18−Maecenas pellentesque pulvinar auctor. Curabitur gravida quam sit amet purus
7+Pellentesque tempor blandit elit, vel ultricies arcu congue egestas. Fusce
8+vitae rutrum nisl. Fusce id mauris libero, a venenatis tellus. Fusce iaculis,
9+lorem et ornare molestie, mauris risus mollis nisi, non fermentum lacus lacus
10+sit amet ipsum. Praesent lobortis ullamcorper dolor, eget convallis ligula
11+dignissim a. Suspendisse nulla nisi, congue et pharetra vel, convallis non
12+libero. Ut a nulla ipsum. Phasellus cursus velit id neque viverra ut
13+pellentesque justo posuere. Curabitur laoreet enim et velit tempor consectetur.
14+Donec eu pretium urna. Suspendisse vitae nisi at metus vestibulum aliquam in
15+sit amet nisl. Donec convallis lacinia odio, vestibulum molestie nunc feugiat
16+a. Suspendisse vehicula, sapien id aliquet consectetur, sem sapien ullamcorper
17+arcu, scelerisque porttitor elit ipsum posuere ligula. Nulla at velit eu metus
18+tincidunt auctor ut sit amet enim. Donec placerat dapibus nisi id facilisis.
19+Maecenas pellentesque pulvinar auctor. Curabitur gravida quam sit amet purus
1920consectetur blandit.
examples/tagblog/posts/2009-12-04-this-blog-aint-dead.markdown+7−6
@@ -2,11 +2,12 @@
22title: This blog ain't dead
33author: Marcus Antonius
44tags: epic fail, antonius
5+description: Etiam non felis aliquet tellus dictum vestibulum.
56---
6−Etiam non felis aliquet tellus dictum vestibulum. Aliquam accumsan mauris non
7−lacus ultricies nec lacinia enim rhoncus. Curabitur vel tortor massa, elementum
8−tincidunt elit. Maecenas venenatis luctus arcu ut ullamcorper. Donec interdum
9−dolor eu enim tristique vel vehicula risus mollis. Nunc nec tortor quam. Nulla
10−a mauris arcu. Phasellus venenatis tortor vel odio tincidunt consequat. Integer
11−venenatis nibh vitae lectus laoreet eu feugiat nunc pretium. Integer nec turpis
7+Etiam non felis aliquet tellus dictum vestibulum. Aliquam accumsan mauris non
8+lacus ultricies nec lacinia enim rhoncus. Curabitur vel tortor massa, elementum
9+tincidunt elit. Maecenas venenatis luctus arcu ut ullamcorper. Donec interdum
10+dolor eu enim tristique vel vehicula risus mollis. Nunc nec tortor quam. Nulla
11+a mauris arcu. Phasellus venenatis tortor vel odio tincidunt consequat. Integer
12+venenatis nibh vitae lectus laoreet eu feugiat nunc pretium. Integer nec turpis
1213metus, in fermentum lorem.
examples/tagblog/posts/2009-12-23-almost-christmas.markdown+8−7
@@ -2,12 +2,13 @@
22title: Almost Christmas!
33author: Publius Vergilius Maro
44tags: christmas, random crap
5+description: Morbi tincidunt eleifend ante, eu gravida ante rutrum vel.
56---
6−Morbi tincidunt eleifend ante, eu gravida ante rutrum vel. Nunc bibendum nulla
7−tellus, eget egestas sapien. Nam rhoncus interdum libero, eget congue orci
8−imperdiet eu. Quisque pellentesque fringilla urna, ac venenatis ante ultricies
9−et. Pellentesque habitant morbi tristique senectus et netus et malesuada fames
10−ac turpis egestas. Mauris eleifend sagittis ultrices. Quisque ultrices accumsan
11−nisl, sed pellentesque metus porta vitae. Nulla facilisi. In et nibh tincidunt
12−mi volutpat pellentesque vitae nec sapien. Integer massa ipsum, pellentesque in
7+Morbi tincidunt eleifend ante, eu gravida ante rutrum vel. Nunc bibendum nulla
8+tellus, eget egestas sapien. Nam rhoncus interdum libero, eget congue orci
9+imperdiet eu. Quisque pellentesque fringilla urna, ac venenatis ante ultricies
10+et. Pellentesque habitant morbi tristique senectus et netus et malesuada fames
11+ac turpis egestas. Mauris eleifend sagittis ultrices. Quisque ultrices accumsan
12+nisl, sed pellentesque metus porta vitae. Nulla facilisi. In et nibh tincidunt
13+mi volutpat pellentesque vitae nec sapien. Integer massa ipsum, pellentesque in
1314elementum at, cursus sit amet diam.
examples/tagblog/templates/default.html+7−7
@@ -4,20 +4,20 @@
44<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
55 <head>
66 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
7− <title>SimpleBlog - $title</title>
8− <link rel="stylesheet" type="text/css" href="$root/css/default.css" />
7+ <title>SimpleBlog - $title$</title>
8+ <link rel="stylesheet" type="text/css" href="/css/default.css" />
99 <link rel="alternate"
1010 type="application/rss+xml"
1111 title="SimpleBlog"
12− href="http://example.com/rss.xml" />
12+ href="/rss.xml" />
1313 </head>
1414 <body>
15− <h1>SimpleBlog - $title</h1>
15+ <h1>SimpleBlog - $title$</h1>
1616 <div id="navigation">
17− <a href="$root/index.html">Home</a>
18− <a href="$root/posts.html">All posts</a>
17+ <a href="/">Home</a>
18+ <a href="/posts.html">All posts</a>
1919 </div>
2020
21− $body
21+ $body$
2222 </body>
2323</html>
examples/tagblog/index.html → examples/tagblog/templates/index.htmlrenamed+5−3
@@ -1,11 +1,13 @@
11<div id="posts">
22 <h1>Recent posts</h1>
33 <ul>
4− $body
4+ $posts$
55 </ul>
6− <a href="$root/posts.html">All posts...</a>
6+ <p><a href="/posts.html">All posts&hellip;</a></p>
7+
8+ <h1>Tags</h1>
79 <div>
8− $tagcloud
10+ $tagcloud$
911 </div>
1012</div>
1113
examples/tagblog/templates/post.html+4−4
@@ -1,5 +1,5 @@
1−<h1>$title</h1>
2−by <em>$author</em> on <strong>$date</strong>
3−<div>Tagged as: $tags.</div>
1+<h1>$title$</h1>
2+by <em>$author$</em> on <strong>$date$</strong>
3+<div>Tagged as: $prettytags$.</div>
44
5−$body
5+$body$
examples/tagblog/templates/postitem.html+2−2
@@ -1,4 +1,4 @@
11<li>
2− <a href="$root/$url">$title</a>
3− - <em>$date</em> - by <em>$author</em>
2+ <a href="$url$">$title$</a>
3+ - <em>$date$</em> - by <em>$author$</em>
44</li>
examples/tagblog/templates/posts.htmlnew file+4
@@ -0,0 +1,4 @@
1+<h1>$title$</h1>
2+<ul>
3+ $posts$
4+</ul>