on master help sign in
Added another tutorial.
commitac8e89cc1904d25e118c41b441bbb4008583b78a authorJasper Van der Jeugt <jaspervdj@gmail.com> dateSat 2 Jan 2010, 19:57 (17 years ago) parentef7a0df
22 files changed+340−6
examples/hakyll/css/default.css+3−2 examples/hakyll/examples/rssblog.zip examples/hakyll/hakyll.hs+2 examples/hakyll/index.markdown+3−2 examples/hakyll/templates/default.html+1−2 examples/hakyll/tutorial2.markdown+3 examples/hakyll/tutorial3.markdown+123 examples/hakyll/tutorials.markdown+12 examples/rssblog/css/default.css+17 examples/rssblog/hakyll.hs+34 examples/rssblog/index.html+14 examples/rssblog/posts.html+4 examples/rssblog/posts/2009-11-05-a-first-post.markdown+21 examples/rssblog/posts/2009-11-10-another-post.markdown+15 examples/rssblog/posts/2009-11-28-a-third-post.markdown+19 examples/rssblog/posts/2009-12-04-this-blog-aint-dead.markdown+12 examples/rssblog/posts/2009-12-23-almost-christmas.markdown+13 examples/rssblog/templates/default.html+22 examples/rssblog/templates/post.html+4 examples/rssblog/templates/postitem.html+4 examples/rssblog/templates/rss.xml+9 examples/rssblog/templates/rssitem.xml+5
examples/hakyll/css/default.css+3−2
@@ -85,8 +85,8 @@ div.column p {
8585
8686ul {
8787 list-style-type: square;
88− list-style-position: inside;
89− padding-left: 0px;
88+ padding-left: 1em;
89+ margin-left: 1em;
9090}
9191
9292code {
@@ -100,4 +100,5 @@ pre code {
100100 background-color: rgb(50, 50, 50);
101101 color: white;
102102 padding: 8px;
103+ margin-bottom: 2em;
103104}
examples/hakyll/examples/rssblog.zipnew file

Binary file not shown.

examples/hakyll/hakyll.hs+2
@@ -12,8 +12,10 @@ main = hakyll $ do
1212
1313 mapM_ render' [ "about.markdown"
1414 , "index.markdown"
15+ , "tutorials.markdown"
1516 , "tutorial1.markdown"
1617 , "tutorial2.markdown"
18+ , "tutorial3.markdown"
1719 ]
1820
1921 where render' = renderChain ["templates/default.html"] . createPagePath
examples/hakyll/index.markdown+3−2
@@ -22,8 +22,9 @@ It is written in a very configurable way and uses an
2222
2323## Getting Started
2424
25−You can get the latest version from hackage using `cabal install hakyll`. A
26−look in the [tutorial](tutorial1.html) is highly recommended. There are a few
25+You can get the latest version from hackage using `cabal install hakyll`. I
26+have written a few [tutorials](tutorials.html), and reading them is highly
27+recommended if you want to get started with hakyll. Also, there are a few
2728examples available in
2829[the github repo](http://github.com/jaspervdj/Hakyll/tree/master/examples/),
2930including this site.
examples/hakyll/templates/default.html+1−2
@@ -25,8 +25,7 @@
2525 <div id="navigation">
2626 <a href="index.html">home</a>
2727 <a href="about.html">about</a>
28− <a href="tutorial1.html">tutorial I</a>
29− <a href="tutorial2.html">tutorial II</a>
28+ <a href="tutorials.html">tutorials</a>
3029 </div>
3130 </div>
3231
examples/hakyll/tutorial2.markdown+3
@@ -159,3 +159,6 @@ Note that the `index.html` in the `renderChain` list is also a template.
159159
160160If you have any more questions, feel free to ask them on the
161161[google discussion group](http://groups.google.com/group/hakyll).
162+
163+There is a [next tutorial](tutorial3.html), explaining how to add an RSS feed
164+to our sample blog.
examples/hakyll/tutorial3.markdownnew file+123
@@ -0,0 +1,123 @@
1+---
2+title: Tutorial (Part III)
3+---
4+
5+## Adding RSS to our simple blog
6+
7+In this tutorial, we're going to add an RSS feed to the blog we wrote in
8+[the previous tutorial](tutorial2.html). Here is a
9+[zip file containing the source](examples/rssblog.zip).
10+
11+An RSS feed looks like this:
12+
13+~~~~~{.xml}
14+<?xml version="1.0" ?>
15+<rss version="2.0">
16+ <channel>
17+ <title>The SimpleBlog</title>
18+ <link>http://example.com/</link>
19+ <description>Simple blog in hakyll</description>
20+ <item>
21+ <title>Title goes here</title>
22+ <link>http://example.com/post.html</link>
23+ <description>
24+ A description is optional.
25+ </description>
26+ </item>
27+ </channel>
28+</rss>
29+~~~~~
30+
31+Note that, obviously, there can be more than one item. We're going to use a
32+template to render this. This is where `templates/rss.xml` comes in:
33+
34+~~~~~{.xml}
35+<?xml version="1.0" ?>
36+<rss version="2.0">
37+ <channel>
38+ <title>The SimpleBlog</title>
39+ <link>http://jaspervdj.be/</link>
40+ <description>Simple blog in hakyll</description>
41+ $items
42+ </channel>
43+</rss>
44+~~~~~
45+
46+We thus render our feed with the following code (no, I didn't define `rssPage`
47+yet - I'm going to work from bottom to top here, it's easier to explain it
48+that way).
49+
50+~~~~~{.haskell}
51+renderChain ["templates/rss.xml"] rssPage
52+~~~~~
53+
54+This, as you can see, is a regular render chain, once again. We need make a
55+`Renderable` that "fills in" the `$items` identifier. We're going to do this
56+using a [custom page](tutorial2.html#custom-pages).
57+
58+## Custom pages again
59+
60+Note that we do not have to include all posts in the rss feed - only a few
61+recent ones. We'll settle on the latest three here.
62+
63+We want to render every post using the following template,
64+`templates/rssitem.xml`:
65+
66+~~~~~{.haskell}
67+<item>
68+ <title>$title</title>
69+ <link>http://example.com/$url</link>
70+ <description>$title by $author</description>
71+</item>
72+~~~~~
73+
74+Since we build on the previous example, we still have our `renderablePosts`
75+list. We'll be using it again:
76+
77+~~~~~{.haskell}
78+let recentRSSItems = renderAndConcat "templates/rssitem.xml"
79+ (take 3 renderablePosts)
80+~~~~~
81+
82+We're using the `renderAndConcat` function again. Note that because of
83+hakyll/haskell laziness, this action isn't executed directly, and this helps
84+dependency handling.
85+
86+Now, the `rssPage` page. As you might remember, we use the `createCustomPage`
87+function to create a custom page. We first give the destination url, then a
88+list of dependencies, and then a list of `(key, value)` pairs.
89+
90+~~~~~{.haskell}
91+let rssPage = createCustomPage
92+ "rss.xml"
93+ ("templates/postitem.html" : take 3 postPaths)
94+ [("items", Right recentRSSItems)]
95+~~~~~
96+
97+## Adding a link to the feed
98+
99+According to the w3 organization,
100+[you should add \<link\> tags](http://www.w3.org/QA/Tips/use-links) to your
101+documents, so we'll do this. In `templates/default.html`:
102+
103+~~~~~~{.html}
104+<head>
105+ <title>SimpleBlog - $title</title>
106+ <link rel="stylesheet" type="text/css" href="/css/default.css" />
107+ <link rel="alternate"
108+ type="application/rss+xml"
109+ title="SimpleBlog"
110+ href="http://example.com/rss.xml" />
111+</head>
112+~~~~~~
113+
114+This makes most browsers see the rss feed, and show it in the address bar.
115+If you want, you can also add a pretty button to your blog linking to
116+`rss.xml`.
117+
118+## That's it!
119+
120+Yep, that's it. Feel free to play with the source code in
121+[the zip file](examples/rssblog.zip) and extend the blog further. As always,
122+all questions are welcome on the
123+[google discussion group](http://groups.google.com/group/hakyll).
examples/hakyll/tutorials.markdownnew file+12
@@ -0,0 +1,12 @@
1+---
2+title: Tutorials
3+---
4+
5+## Tutorials about hakyll
6+
7+Here is a list of tutorials I've written about hakyll:
8+
9+- [Tutorial 1](tutorial1.html) explains how to create a simple brochure site.
10+- [Tutorial 2](tutorial2.html) creates a simple blog.
11+- [Tutorial 3](tutorial3.html) adds an RSS feed to the blog from the previous
12+ tutorial.
examples/rssblog/css/default.cssnew file+17
@@ -0,0 +1,17 @@
1+body {
2+ width: 600px;
3+ margin: 0px auto 0px auto;
4+}
5+
6+div#navigation {
7+ text-align: center;
8+ border-bottom: 4px solid black;
9+}
10+
11+div#navigation a {
12+ color: white;
13+ text-decoration: none;
14+ background-color: black;
15+ padding: 3px 10px 3px 10px;
16+ margin: 0px 10px 0px 10px;
17+}
examples/rssblog/hakyll.hsnew file+34
@@ -0,0 +1,34 @@
1+module Main where
2+
3+import Text.Hakyll (hakyll)
4+import Text.Hakyll.Render (renderAndConcat, renderChain, css)
5+import Text.Hakyll.File (getRecursiveContents, directory)
6+import Text.Hakyll.Renderables (createPagePath, createCustomPage)
7+import Data.List (sort)
8+import Control.Monad (mapM_, liftM)
9+import Data.Either (Either(..))
10+
11+main = hakyll $ do
12+ -- Static directory.
13+ directory css "css"
14+
15+ -- Find all post paths.
16+ postPaths <- liftM (reverse . sort) $ getRecursiveContents "posts"
17+ let renderablePosts = map createPagePath postPaths
18+
19+ -- Render all posts list.
20+ let postItems = renderAndConcat "templates/postitem.html" $ renderablePosts
21+ renderChain ["posts.html", "templates/default.html"] $
22+ createCustomPage "posts.html" ("templates/postitem.html" : postPaths)
23+ [("title", Left "All posts"), ("posts", Right postItems)]
24+
25+ -- Render all posts.
26+ putStrLn "Generating posts..."
27+ mapM_ (renderChain ["templates/post.html", "templates/default.html"]) renderablePosts
28+
29+ -- Render rss feed
30+ let recentRSSItems = renderAndConcat "templates/rssitem.xml" $ take 3 renderablePosts
31+ let rssPage = createCustomPage "rss.xml"
32+ ("templates/postitem.html" : take 3 postPaths)
33+ [("items", Right recentRSSItems)]
34+ renderChain ["templates/rss.xml"] rssPage
examples/rssblog/index.htmlnew file+14
@@ -0,0 +1,14 @@
1+<div id="posts">
2+ <h1>Recent posts</h1>
3+ <ul>
4+ $posts
5+ </ul>
6+ <a href="/posts.html">All posts...</a>
7+</div>
8+
9+<div class="about">
10+ <h1>About</h1>
11+ <p>
12+ This is a sample blog for educational purposes.
13+ </p>
14+</div>
examples/rssblog/posts.htmlnew file+4
@@ -0,0 +1,4 @@
1+<h1>All posts</h1>
2+<ul>
3+ $posts
4+</ul>
examples/rssblog/posts/2009-11-05-a-first-post.markdownnew file+21
@@ -0,0 +1,21 @@
1+---
2+title: A first post
3+author: Julius Caesar
4+date: November 5, 2009
5+---
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
21+scelerisque mauris.
examples/rssblog/posts/2009-11-10-another-post.markdownnew file+15
@@ -0,0 +1,15 @@
1+---
2+title: Another post
3+author: Marcus Tullius Cicero
4+date: November 10, 2009
5+---
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
15+amet, consectetur adipiscing elit. Proin non aliquam nunc.
examples/rssblog/posts/2009-11-28-a-third-post.markdownnew file+19
@@ -0,0 +1,19 @@
1+---
2+title: A third post
3+author: Publius Ovidius Naso
4+date: November 28, 2009
5+---
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
19+consectetur blandit.
examples/rssblog/posts/2009-12-04-this-blog-aint-dead.markdownnew file+12
@@ -0,0 +1,12 @@
1+---
2+title: This blog ain't dead
3+author: Marcus Antonius
4+date: December 4, 2009
5+---
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
12+metus, in fermentum lorem.
examples/rssblog/posts/2009-12-23-almost-christmas.markdownnew file+13
@@ -0,0 +1,13 @@
1+---
2+title: Almost Christmas!
3+author: Publius Vergilius Maro
4+date: December 23, 2009
5+---
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
13+elementum at, cursus sit amet diam.
examples/rssblog/templates/default.htmlnew file+22
@@ -0,0 +1,22 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5+ <head>
6+ <title>SimpleBlog - $title</title>
7+ <link rel="stylesheet" type="text/css" href="/css/default.css" />
8+ <link rel="alternate"
9+ type="application/rss+xml"
10+ title="SimpleBlog"
11+ href="http://example.com/rss.xml" />
12+ </head>
13+ <body>
14+ <h1>SimpleBlog - $title</h1>
15+ <div id="navigation">
16+ <a href="/index.html">Home</a>
17+ <a href="/posts.html">All posts</a>
18+ </div>
19+
20+ $body
21+ </body>
22+</html>
examples/rssblog/templates/post.htmlnew file+4
@@ -0,0 +1,4 @@
1+<h1>$title</h1>
2+by <em>$author</em> on <strong>$date</strong>
3+
4+$body
examples/rssblog/templates/postitem.htmlnew file+4
@@ -0,0 +1,4 @@
1+<li>
2+ <a href="/$url">$title</a>
3+ - <em>$date</em> - by <em>$author</em>
4+</li>
examples/rssblog/templates/rss.xmlnew file+9
@@ -0,0 +1,9 @@
1+<?xml version="1.0" ?>
2+<rss version="2.0">
3+ <channel>
4+ <title>The SimpleBlog</title>
5+ <link>http://example.com</link>
6+ <description>Simple blog in hakyll</description>
7+ $items
8+ </channel>
9+</rss>
examples/rssblog/templates/rssitem.xmlnew file+5
@@ -0,0 +1,5 @@
1+<item>
2+ <title>$title</title>
3+ <link>http://example.com/$url</link>
4+ <description>$title by $author</description>
5+</item>