Added tagblog example (tutorial coming up).

This commit is contained in:
Jasper Van der Jeugt 2010-01-08 12:41:58 +01:00
parent b403d35b08
commit 699bd0011e
17 changed files with 253 additions and 3 deletions

View file

@ -16,6 +16,12 @@ main = hakyll $ do
postPaths <- liftM (reverse . sort) $ getRecursiveContents "posts"
let renderablePosts = map createPagePath postPaths
-- Render index, including recent posts.
let recentPosts = renderAndConcat "templates/postitem.html" $ take 3 renderablePosts
renderChain ["index.html", "templates/default.html"] $
createCustomPage "index.html" ("templates/postitem.html" : take 3 postPaths)
[("title", Left "Home"), ("posts", Right recentPosts)]
-- Render all posts list.
let postItems = renderAndConcat "templates/postitem.html" $ renderablePosts
renderChain ["posts.html", "templates/default.html"] $

View file

@ -0,0 +1,17 @@
body {
width: 600px;
margin: 0px auto 0px auto;
}
div#navigation {
text-align: center;
border-bottom: 4px solid black;
}
div#navigation a {
color: white;
text-decoration: none;
background-color: black;
padding: 3px 10px 3px 10px;
margin: 0px 10px 0px 10px;
}

View file

@ -0,0 +1,69 @@
module Main where
import Text.Hakyll (hakyll)
import Text.Hakyll.Render
import Text.Hakyll.Tags (readTagMap, renderTagCloud, renderTagLinks)
import Text.Hakyll.File (getRecursiveContents, directory, removeSpaces)
import Text.Hakyll.Renderables (createPagePath, createCustomPage)
import Text.Hakyll.Context (ContextManipulation, renderDate)
import Data.List (sort)
import Data.Map (toList)
import Control.Monad (mapM_, liftM)
import Data.Either (Either(..))
main = hakyll $ do
-- Static directory.
directory css "css"
-- Find all post paths.
postPaths <- liftM (reverse . sort) $ getRecursiveContents "posts"
let renderablePosts = map createPagePath postPaths
-- Read tag map.
tagMap <- readTagMap postPaths
-- Render all posts list.
renderPostList "posts.html" "All posts" postPaths
-- Render post list per tag
mapM_ (\(tag, posts) -> renderPostList (tagToURL tag) ("Posts tagged " ++ tag) posts)
(toList tagMap)
-- Render index, including recent posts.
let recentPosts = renderAndConcatWith postManipulation
"templates/postitem.html"
(take 3 renderablePosts)
renderChain ["index.html", "templates/default.html"] $
createCustomPage "index.html" ("templates/postitem.html" : take 3 postPaths)
[("title", Left "Home"), ("posts", Right recentPosts)]
-- Render all posts.
mapM_ (renderChainWith postManipulation
["templates/post.html"
,"templates/default.html"
]) renderablePosts
-- Render rss feed
let recentRSSItems = renderAndConcat "templates/rssitem.xml" $ take 3 renderablePosts
let rssPage = createCustomPage "rss.xml"
("templates/postitem.html" : take 3 postPaths)
[("items", Right recentRSSItems)]
renderChain ["templates/rss.xml"] rssPage
-- Render index.
renderChain ["templates/default.html"] $ createPagePath "index.html"
where postManipulation :: ContextManipulation
postManipulation = renderDate "date" "%B %e, %Y" "Date unknown"
. renderTagLinks tagToURL
tagToURL tag = "/tags/" ++ removeSpaces tag ++ ".html"
renderPostList url title posts = do
let postItems = renderAndConcatWith postManipulation
"templates/postitem.html"
(map createPagePath posts)
customPage = createCustomPage url
("templates/postitem.html" : posts)
[("title", Left title), ("posts", Right postItems)]
renderChain ["posts.html", "templates/default.html"] customPage

View file

@ -0,0 +1,14 @@
<div id="posts">
<h1>Recent posts</h1>
<ul>
$posts
</ul>
<a href="/posts.html">All posts...</a>
</div>
<div class="about">
<h1>About</h1>
<p>
This is a sample blog for educational purposes.
</p>
</div>

View file

@ -0,0 +1,4 @@
<h1>$title</h1>
<ul>
$posts
</ul>

View file

@ -0,0 +1,21 @@
---
title: A first post
author: Julius Caesar
tags: caesar, random crap
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus pretium leo
adipiscing lectus iaculis lobortis. Vivamus scelerisque velit dignissim metus
gravida sit amet dapibus ligula tempor. Quisque sit amet viverra nunc.
Suspendisse cursus elementum ante, ut venenatis nisi dictum eu. Nulla diam
ligula, eleifend in varius quis, malesuada a nibh. Vivamus consequat
pellentesque erat non blandit. Nunc sit amet eros vel massa semper ullamcorper
quis iaculis magna. Vestibulum ullamcorper urna sit amet est elementum
pulvinar. Vestibulum consequat lacus ac quam hendrerit tincidunt. Praesent
bibendum vehicula diam, nec sagittis risus tempus a. Nulla quis odio sit amet
odio vehicula cursus ut id odio. Curabitur semper magna euismod magna mollis
venenatis. Nunc eget eleifend velit. Mauris sed posuere sem. Fusce id nunc
nisi, a aliquam orci. Suspendisse laoreet justo non enim laoreet eget consequat
velit porttitor. Aenean faucibus sodales metus at tincidunt. Donec vestibulum
leo pulvinar erat auctor ac ultrices massa euismod. Phasellus blandit cursus
magna, eget lacinia mi lobortis sed. Suspendisse ultricies enim ligula, vel
scelerisque mauris.

View file

@ -0,0 +1,15 @@
---
title: Another post
author: Marcus Tullius Cicero
tags: cicero, random crap
---
Vestibulum in ultrices urna. Etiam tempor enim dui, nec malesuada elit. Donec
tempor ligula et quam volutpat quis fermentum eros congue. Sed ut pulvinar sem.
Sed aliquam ipsum id purus sollicitudin vulputate. Cras et mauris dui, vel
hendrerit leo. Ut metus ipsum, fermentum ac malesuada id, tempus pharetra quam.
Donec diam felis, consequat ac scelerisque cursus, gravida non lectus. Sed
faucibus elit dapibus diam elementum id varius nisi tristique. Proin consequat
faucibus neque in aliquam. Vestibulum ligula odio, pulvinar vel hendrerit
vitae, egestas ut nibh. Praesent ut velit elit, in consequat dolor. Praesent
sem enim, commodo in gravida sed, adipiscing vel eros. Lorem ipsum dolor sit
amet, consectetur adipiscing elit. Proin non aliquam nunc.

View file

@ -0,0 +1,19 @@
---
title: A third post
author: Publius Ovidius Naso
tags: epic fail, ovidius
---
Pellentesque tempor blandit elit, vel ultricies arcu congue egestas. Fusce
vitae rutrum nisl. Fusce id mauris libero, a venenatis tellus. Fusce iaculis,
lorem et ornare molestie, mauris risus mollis nisi, non fermentum lacus lacus
sit amet ipsum. Praesent lobortis ullamcorper dolor, eget convallis ligula
dignissim a. Suspendisse nulla nisi, congue et pharetra vel, convallis non
libero. Ut a nulla ipsum. Phasellus cursus velit id neque viverra ut
pellentesque justo posuere. Curabitur laoreet enim et velit tempor consectetur.
Donec eu pretium urna. Suspendisse vitae nisi at metus vestibulum aliquam in
sit amet nisl. Donec convallis lacinia odio, vestibulum molestie nunc feugiat
a. Suspendisse vehicula, sapien id aliquet consectetur, sem sapien ullamcorper
arcu, scelerisque porttitor elit ipsum posuere ligula. Nulla at velit eu metus
tincidunt auctor ut sit amet enim. Donec placerat dapibus nisi id facilisis.
Maecenas pellentesque pulvinar auctor. Curabitur gravida quam sit amet purus
consectetur blandit.

View file

@ -0,0 +1,12 @@
---
title: This blog ain't dead
author: Marcus Antonius
tags: epic fail, antonius
---
Etiam non felis aliquet tellus dictum vestibulum. Aliquam accumsan mauris non
lacus ultricies nec lacinia enim rhoncus. Curabitur vel tortor massa, elementum
tincidunt elit. Maecenas venenatis luctus arcu ut ullamcorper. Donec interdum
dolor eu enim tristique vel vehicula risus mollis. Nunc nec tortor quam. Nulla
a mauris arcu. Phasellus venenatis tortor vel odio tincidunt consequat. Integer
venenatis nibh vitae lectus laoreet eu feugiat nunc pretium. Integer nec turpis
metus, in fermentum lorem.

View file

@ -0,0 +1,13 @@
---
title: Almost Christmas!
author: Publius Vergilius Maro
tags: christmas, random crap
---
Morbi tincidunt eleifend ante, eu gravida ante rutrum vel. Nunc bibendum nulla
tellus, eget egestas sapien. Nam rhoncus interdum libero, eget congue orci
imperdiet eu. Quisque pellentesque fringilla urna, ac venenatis ante ultricies
et. Pellentesque habitant morbi tristique senectus et netus et malesuada fames
ac turpis egestas. Mauris eleifend sagittis ultrices. Quisque ultrices accumsan
nisl, sed pellentesque metus porta vitae. Nulla facilisi. In et nibh tincidunt
mi volutpat pellentesque vitae nec sapien. Integer massa ipsum, pellentesque in
elementum at, cursus sit amet diam.

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>SimpleBlog - $title</title>
<link rel="stylesheet" type="text/css" href="/css/default.css" />
<link rel="alternate"
type="application/rss+xml"
title="SimpleBlog"
href="http://example.com/rss.xml" />
</head>
<body>
<h1>SimpleBlog - $title</h1>
<div id="navigation">
<a href="/index.html">Home</a>
<a href="/posts.html">All posts</a>
</div>
$body
</body>
</html>

View file

@ -0,0 +1,5 @@
<h1>$title</h1>
by <em>$author</em> on <strong>$date</strong>
<div>Tagged as: $tags.</div>
$body

View file

@ -0,0 +1,4 @@
<li>
<a href="/$url">$title</a>
- <em>$date</em> - by <em>$author</em>
</li>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" ?>
<rss version="2.0">
<channel>
<title>The SimpleBlog</title>
<link>http://example.com</link>
<description>Simple blog in hakyll</description>
$items
</channel>
</rss>

View file

@ -0,0 +1,5 @@
<item>
<title>$title</title>
<link>http://example.com/$url</link>
<description>$title by $author</description>
</item>

View file

@ -4,6 +4,7 @@ module Text.Hakyll.File
( toDestination
, toCache
, toURL
, removeSpaces
, makeDirectories
, getRecursiveContents
, havingExtension
@ -15,18 +16,31 @@ import System.Directory
import System.FilePath
import Control.Monad
-- | Auxiliary function to remove pathSeparators form the start. We don't deal
-- with absolute paths here.
removeLeadingSeparator :: FilePath -> FilePath
removeLeadingSeparator [] = []
removeLeadingSeparator p@(x:xs) | x `elem` pathSeparators = xs
| otherwise = p
-- | Convert a relative filepath to a filepath in the destination (_site).
toDestination :: FilePath -> FilePath
toDestination path = "_site" </> path
toDestination path = "_site" </> (removeLeadingSeparator path)
-- | Convert a relative filepath to a filepath in the cache (_cache).
toCache :: FilePath -> FilePath
toCache path = "_cache" </> path
toCache path = "_cache" </> (removeLeadingSeparator path)
-- | Get the url for a given page.
toURL :: FilePath -> FilePath
toURL = flip addExtension ".html" . dropExtension
-- | Swaps spaces for '-'.
removeSpaces :: FilePath -> FilePath
removeSpaces = map swap
where swap ' ' = '-'
swap x = x
-- | Given a path to a file, try to make the path writable by making
-- all directories on the path.
makeDirectories :: FilePath -> IO ()

View file

@ -56,5 +56,6 @@ renderTagCloud tagMap urlFunction minSize maxSize =
renderTagLinks :: (String -> String) -- ^ Function that produces an url for a tag.
-> ContextManipulation
renderTagLinks urlFunction = renderValue "tags" "tags" renderTagLinks'
where renderTagLinks' = B.pack . intercalate ", " . map urlFunction
where renderTagLinks' = B.pack . intercalate ", "
. map (\t -> link t $ urlFunction t)
. map trim . split "," . B.unpack