hakyll-contrib (empty) → 0.0.0.1
raw patch · 19 files changed
+580/−0 lines, 19 filesdep +basedep +directorydep +filepathsetup-changedbinary-added
Dependencies added: base, directory, filepath, hakyll, pandoc
Files
- LICENSE +30/−0
- Setup.hs +2/−0
- data/small-blog/contact.markdown +23/−0
- data/small-blog/css/screen.css +55/−0
- data/small-blog/hakyll.hs +15/−0
- data/small-blog/images/haskell-logo.png binary
- data/small-blog/index.markdown +25/−0
- data/small-blog/posts.html +8/−0
- data/small-blog/posts/2009-11-05-a-first-post.markdown +21/−0
- data/small-blog/posts/2009-11-10-another-post.markdown +15/−0
- data/small-blog/posts/2009-11-28-a-third-post.markdown +19/−0
- data/small-blog/posts/2009-12-04-this-blog-aint-dead.markdown +12/−0
- data/small-blog/posts/2009-12-23-almost-christmas.markdown +13/−0
- data/small-blog/templates/default.html +27/−0
- data/small-blog/templates/post-item.html +4/−0
- data/small-blog/templates/post.html +5/−0
- hakyll-contrib.cabal +56/−0
- src/Hakyll/Contrib/Main.hs +59/−0
- src/Hakyll/Contrib/SmallBlog.hs +191/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c)2011, Jasper Van der Jeugt <m@jaspervdj.be>++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Jasper Van der Jeugt <m@jaspervdj.be> nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ data/small-blog/contact.markdown view
@@ -0,0 +1,23 @@+---+title: Contact+---++# Contact me++This is another static page, with some contact information on it. You can add+any number of static pages in the top-level directory of your site.++Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eget velit diam,+ut varius purus. Phasellus convallis euismod commodo. Nam ac mattis augue.+Curabitur vitae enim dolor, vitae tristique nulla. Morbi tincidunt scelerisque+leo vitae lobortis. Cras et leo eget quam posuere euismod.++# Disclaimer++Nullam magna nibh, iaculis ac condimentum non, cursus sit amet risus. Ut dictum+ultricies nunc, sed euismod nunc consectetur tincidunt. Donec ullamcorper magna+vitae lectus pellentesque ultrices blandit neque ullamcorper. Quisque orci+felis, semper sed vehicula eu, lacinia eu nibh. Quisque cursus vestibulum+dignissim. Curabitur nec ante erat, ut rutrum tellus. Curabitur hendrerit lectus+sed odio varius in imperdiet magna pretium. Ut lorem quam, porttitor at iaculis+in, vehicula tempor turpis. Nulla facilisi.
+ data/small-blog/css/screen.css view
@@ -0,0 +1,55 @@+html {+ font-family: 'Helvetica', sans-serif;+ font-size: 14px;+ color: black;+}++body {+ width: 600px;+ margin: 10px auto 10px auto;+}++div#header {+ font-size: 16px;+ font-weight: bold;+}++div#navigation {+ float: right;+}++div#navigation a {+ margin-left: 10px;+}++div#footer {+ text-align: center;+ font-style: italic;+ font-size: 11px;+ margin-top: 30px;+}++h1 {+ color: rgb(150, 150, 150);+ border-bottom: 2px solid rgb(150, 150, 150);+ font-size: 22px;+ margin-top: 30px;+}++li {+ list-style-type: square;+}++a {+ color: rgb(30, 30, 130);+ font-weight: bold;+ text-decoration: none;+}++div.figure {+ text-align: center;+}++div.figure p.caption {+ font-style: italic;+}
+ data/small-blog/hakyll.hs view
@@ -0,0 +1,15 @@+{-# LANGUAGE OverloadedStrings #-}+module Main where++import Hakyll+import Hakyll.Contrib.SmallBlog++main :: IO ()+main = hakyll $ smallBlogWith defaultSmallBlogConfiguration+ { atomFeed = Just FeedConfiguration+ { feedTitle = "A simple blog"+ , feedDescription = "Certainly very enjoyable yes"+ , feedAuthorName = "Jasper Van der Jeugt"+ , feedRoot = "http://example.com"+ }+ }
+ data/small-blog/images/haskell-logo.png view
binary file changed (absent → 5674 bytes)
+ data/small-blog/index.markdown view
@@ -0,0 +1,25 @@+---+title: Home+---++# Recent posts++<ul>+ $recentPosts$+</ul>++[All posts...](/posts.html)++# About++This is a small blog generated by the Hakyll static site generator. We use the+`small-blog` premade configuration, which means we can set up our blog very+quickly, without the need to write much code.++++This site should serve as a good starting point for your own blog. If you want+to create a larger or more feature-rich site, you should consider learning+[Hakyll].++[Hakyll]: http://jaspervdj.be/hakyll
+ data/small-blog/posts.html view
@@ -0,0 +1,8 @@+---+title: Archive+---++<h1>All posts</h1>+<ul>+ $allPosts$+</ul>
+ data/small-blog/posts/2009-11-05-a-first-post.markdown view
@@ -0,0 +1,21 @@+---+title: A first post+author: Julius Caesar+date: November 5, 2009+---+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.
+ data/small-blog/posts/2009-11-10-another-post.markdown view
@@ -0,0 +1,15 @@+---+title: Another post+author: Marcus Tullius Cicero+date: November 10, 2009+---+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.
+ data/small-blog/posts/2009-11-28-a-third-post.markdown view
@@ -0,0 +1,19 @@+---+title: A third post+author: Publius Ovidius Naso+date: November 28, 2009+---+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.
+ data/small-blog/posts/2009-12-04-this-blog-aint-dead.markdown view
@@ -0,0 +1,12 @@+---+title: This blog ain't dead+author: Marcus Antonius+date: December 4, 2009+---+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.
+ data/small-blog/posts/2009-12-23-almost-christmas.markdown view
@@ -0,0 +1,13 @@+---+title: Almost Christmas!+author: Publius Vergilius Maro+date: December 23, 2009+---+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.
+ data/small-blog/templates/default.html view
@@ -0,0 +1,27 @@+<?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>+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />+ <title>SimpleBlog - $title$</title>+ <link rel="stylesheet" type="text/css" href="/css/screen.css" />+ </head>+ <body>+ <div id="header">+ SmallBlog - $title$++ <div id="navigation">+ <a href="/index.html">Home</a>+ <a href="/posts.html">All posts</a>+ <a href="/contact.html">Contact</a>+ </div>+ </div>++ $body$++ <div id="footer">+ Site generated using <a href="http://jaspervdj.be/hakyll">Hakyll</a>+ </div>+ </body>+</html>
+ data/small-blog/templates/post-item.html view
@@ -0,0 +1,4 @@+<li>+ <a href="$url$">$title$</a>+ - <em>$date$</em> - by <em>$author$</em>+</li>
+ data/small-blog/templates/post.html view
@@ -0,0 +1,5 @@+<h1>$title$</h1>++<p>by <em>$author$</em> on <strong>$date$</strong></p>++$body$
+ hakyll-contrib.cabal view
@@ -0,0 +1,56 @@+Name: hakyll-contrib+Version: 0.0.0.1+Synopsis: Extra modules for the hakyll website compiler+Homepage: http://jaspervdj.be/hakyll+License: BSD3+License-file: LICENSE+Author: Jasper Van der Jeugt <m@jaspervdj.be>+Maintainer: Jasper Van der Jeugt <m@jaspervdj.be>+Category: Web++Cabal-version: >=1.6+Build-type: Simple+Data-dir: data++Data-files:+ small-blog/contact.markdown+ small-blog/css/screen.css+ small-blog/hakyll.hs+ small-blog/images/haskell-logo.png+ small-blog/index.markdown+ small-blog/posts.html+ small-blog/posts/2009-11-05-a-first-post.markdown+ small-blog/posts/2009-11-10-another-post.markdown+ small-blog/posts/2009-11-28-a-third-post.markdown+ small-blog/posts/2009-12-04-this-blog-aint-dead.markdown+ small-blog/posts/2009-12-23-almost-christmas.markdown+ small-blog/templates/default.html+ small-blog/templates/post-item.html+ small-blog/templates/post.html++Source-Repository head+ Type: git+ Location: git://github.com/jaspervdj/hakyll-contrib.git++Library+ Ghc-options: -Wall+ Hs-source-dirs: src+ + Build-depends:+ base >= 4 && < 5,+ hakyll >= 3.2.0.2 && < 3.3,+ pandoc >= 1.6 && < 2++ Exposed-modules:+ Hakyll.Contrib.SmallBlog++Executable hakyll-contrib+ Ghc-options: -Wall+ Hs-source-dirs: src+ Main-is: Hakyll/Contrib/Main.hs+ + Build-depends:+ base >= 4 && < 5,+ hakyll >= 3.2.0.2 && < 3.3,+ directory >= 1.1 && < 1.3,+ filepath >= 1.1 && < 1.3
+ src/Hakyll/Contrib/Main.hs view
@@ -0,0 +1,59 @@+-- | Hakyll project starter+--+module Main+ ( main+ ) where++import Control.Monad (forM_)+import System.Environment (getArgs, getProgName)+import System.FilePath (splitPath, joinPath, (</>))+import System.Directory (copyFile)++import Hakyll.Core.Util.File (getRecursiveContents, makeDirectories)++import Paths_hakyll_contrib (getDataDir)++-- | Available projects+--+projects :: [String]+projects =+ [ "small-blog"+ ]++-- | Start a project: just copy the directory+--+startProject :: String -> String -> IO ()+startProject p d = do+ source <- fmap (</> p) getDataDir+ contents <- getRecursiveContents False $ source+ forM_ contents $ \file -> do+ let dest = d </> stripDir source file+ putStrLn $ "Creating " ++ dest+ makeDirectories dest+ copyFile file dest+ where+ stripDir dir = joinPath . (drop $ length $ splitPath dir) . splitPath++-- | Print usage information+--+usage :: IO ()+usage = do+ progName <- getProgName+ putStr $ unlines+ [ "hakyll-contrib project starter"+ , ""+ , "Usage: " ++ progName ++ " <project> [dirname]"+ , ""+ , "Where project is one of:"+ ]+ forM_ projects $ \p -> putStrLn $ " " ++ p++-- | Main function+--+main :: IO ()+main = do+ args <- getArgs+ case args of+ (p : d : _) -> if p `elem` projects then startProject p d else usage+ (p : _) -> if p `elem` projects then startProject p p else usage+ _ -> usage
+ src/Hakyll/Contrib/SmallBlog.hs view
@@ -0,0 +1,191 @@+-- | This module provides a simple default configuration which behaves similar+-- to a tool such as the Jekyll static site generator (<http://jekyllrb.com/>).+--+-- The idea is that you don't have to write your configuration yourself: you+-- just follow some conventions, and Hakyll does the rest.+--+-- You can generate a site which will serve as a good starting point by running+-- the command-line tool:+--+-- > hakyll-contrib small-blog+--+-- Hakyll will then generate a simple example site for you. The necessary+-- configuration is placed in the @hakyll.hs@ file. Compile and run it to create+-- the demo site:+--+-- > ghc --make hakyll.hs+-- > ./hakyll build+-- > ./hakyll preview+--+-- So, in order to get your site going, you need to follow the conventions for+-- the content on your site.+--+-- Images should be placed in the @images\/@ or @img\/@ folder. The are copied+-- directly. Other static files (but not images) can be placed in @static\/@ or+-- @files\/@. The @favicon.ico@ file is an exception, it is just placed in the+-- top-level directory.+--+-- CSS files should be placed in @css\/@, and JavaScript files in @js\/@.+--+-- Then, we arrive at pages. You can create any number of pages on your site:+-- just create files in one of the documents pandoc supports (@.html@,+-- @.markdown@, @.rst@, @.lhs@...) in the top-level directory.+--+-- These pages may use a number of preconfigured @$key$@'s:+--+-- * @$recentPosts$@: A list of recent posts, displayed from most recent to+-- oldest. By default, 3 posts are shown, altough this can be configured using+-- the 'numberOfRecentPosts' field.+--+-- * @$allPosts$@: A list of all posts, displayed from most recent to oldest.+-- This is very useful for creating an archive page.+--+-- * @$chronologicalPosts$@: Similar to @$allPosts$@, but displays the posts in+-- chronological order.+--+-- For example usage, look at the example site we generated using+-- @hakyll-contrib small-blog@.+--+-- Now, one can wonder where these posts come from. Simple: all pages in the+-- @posts\/@ directory are considered posts. Note that a naming format of+--+-- > posts/year-month-date-title.extension+--+-- is mandatory. An example:+--+-- > posts/2011-06-19-hello-world.markdown+--+-- This allows Hakyll to parse the date easily, among other things. Again, look+-- at the example site for some example posts.+--+-- Additionaly, there is the @templates\/@ folder. This folder holds the+-- templates for your site. For a @small-blog@ configuration, your site should+-- have /exactly/ three templates:+--+-- * @templates\/default.html@: The main template. This should contain your+-- HTML doctype, head, etc.+--+-- * @templates\/post.html@: A template which is applied to every post before+-- it is rendered using the default template.+--+-- * @templates\/post-item.html@: A template which is applied to posts in+-- listings (e.g. @$chronologicalPosts$@).+--+-- Again, the example should clarify things.+--+-- This configuration should be enough to create a small personal website. But,+-- we have only touched the surface of what is possible with Hakyll. For more+-- information, check out the tutorials at: <http://jaspervdj.be/hakyll>+--+{-# LANGUAGE OverloadedStrings #-}+{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}+module Hakyll.Contrib.SmallBlog+ ( SmallBlogConfiguration (..)+ , defaultSmallBlogConfiguration+ , smallBlog+ , smallBlogWith+ ) where++import Control.Arrow ((>>>))++import Text.Pandoc (ParserState, WriterOptions)++import Hakyll++-- | Configuration datatype for the 'smallBlog' ruleset+--+data SmallBlogConfiguration = SmallBlogConfiguration+ { -- | Number of recent posts that are available+ numberOfRecentPosts :: Int+ , -- | Parser state for pandoc, i.e. read options+ parserState :: ParserState+ , -- | Writer options for pandoc+ writerOptions :: WriterOptions+ , -- | Atom feed configuration+ atomFeed :: Maybe FeedConfiguration+ } deriving (Show)++-- | Defaults for 'SmallBlogConfiguration'+--+defaultSmallBlogConfiguration :: SmallBlogConfiguration+defaultSmallBlogConfiguration = SmallBlogConfiguration+ { numberOfRecentPosts = 3+ , parserState = defaultHakyllParserState+ , writerOptions = defaultHakyllWriterOptions+ , atomFeed = Nothing+ }++-- | A default configuration for a small blog+--+smallBlog :: Rules+smallBlog = smallBlogWith defaultSmallBlogConfiguration++-- | Version of 'smallBlog' which allows setting a config+--+smallBlogWith :: SmallBlogConfiguration -> Rules+smallBlogWith conf = do+ -- Images and static files+ ["favicon.ico"] --> copy+ ["img/**", "images/**"] --> copy+ ["static/**", "files/**"] --> copy+ ["js/**", "javascript/**"] --> copy++ -- CSS files+ ["css/*.css", "style/*.css", "stylesheets/*.css"] --> css++ -- All templates+ ["templates/*"] --> template++ -- "Dynamic" content+ ["posts/*"] --> post++ -- Top-level pages+ ["*.markdown", "*.html", "*.rst", "*.lhs"] --> topLevel++ -- Rss is optional+ case atomFeed conf of+ Nothing -> return ()+ Just f -> do+ match "atom.xml" $ route idRoute+ create "atom.xml" $ requireAll_ "posts/*" >>> renderAtom f+ return ()+ where+ -- Useful combinator here+ xs --> f = mapM_ (\p -> match p $ f) xs++ -- Completely static+ copy = route idRoute >> compile copyFileCompiler+ + -- CSS directories+ css = route (setExtension "css") >> compile compressCssCompiler++ -- Templates+ template = compile templateCompiler++ -- Posts+ post = do+ route $ setExtension "html"+ compile $ pageCompilerWith (parserState conf) (writerOptions conf)+ >>> applyTemplateCompiler "templates/post.html"+ >>> applyTemplateCompiler "templates/default.html"+ >>> relativizeUrlsCompiler++ -- Top-level pages+ topLevel = do+ route $ setExtension "html"+ compile $ pageCompilerWithFields (parserState conf)+ (writerOptions conf) id topLevelFields+ >>> applyTemplateCompiler "templates/default.html"+ >>> relativizeUrlsCompiler++ -- Add the fields we need to top-level pages+ topLevelFields = setFieldPostList recentFirst "allPosts"+ >>> setFieldPostList (take nRecent . recentFirst) "recentPosts"+ >>> setFieldPostList chronological "chronologicalPosts"++ -- Create a post list based on ordering/selection+ setFieldPostList f k = setFieldPageList f+ "templates/post-item.html" k "posts/*"++ -- Number of most recent posts to show+ nRecent = numberOfRecentPosts conf