summaryrefslogtreecommitdiff
path: root/README.markdown
diff options
context:
space:
mode:
authorJasper Van der Jeugt <jaspervdj@gmail.com>2009-12-28 18:21:03 +0100
committerJasper Van der Jeugt <jaspervdj@gmail.com>2009-12-28 18:21:03 +0100
commit533f2c3b60ef3d3629543045fa308a82ebdcb089 (patch)
tree32103ca01184ac8b92396c545599de17a735494e /README.markdown
parent4561887cf459ca9c06067180a979e996b029dcdf (diff)
downloadhakyll-533f2c3b60ef3d3629543045fa308a82ebdcb089.tar.gz
Some more changes for the 0.3 release.
Diffstat (limited to 'README.markdown')
-rw-r--r--README.markdown215
1 files changed, 4 insertions, 211 deletions
diff --git a/README.markdown b/README.markdown
index 1b1080d..fbab8ef 100644
--- a/README.markdown
+++ b/README.markdown
@@ -9,216 +9,9 @@ reference.
## Installation
- cabal install hakyll
+cabal install hakyll
-## Configuration
+## Tutorial and information
-Inspired by [xmonad](http://xmonad.org), a small Haskell program is used as
-configuration file. In this file, you give instructions on how the site should
-be generated. In the rest of this document, we will examine a small example.
-
-This is our directory layout:
-
- |-- _cache
- |-- _site
- |-- favicon.ico
- |-- hakyll.hs
- |-- images
- | `-- foo.png
- |-- templates
- | |-- default.html
- | `-- sample.html
- `-- text.markdown
-
-The `_cache` and `_site` directories will be automatically created by hakyll.
-
-## Static files
-
-Static files can be rendered using the `static` function. This function
-ensures the files will copied when you compile the site. Hakyll is smart enough
-to know when files have changed, and will check the modification time of a file
-before copying.
-
-For convenience reasons, there is also a `staticDirectory` function, which works
-recursively.
-
- main = do
- static "favicon.ico"
- staticDirectory "images"
- staticDirectory "css"
-
-## Pages
-
-Pages can be written in html, markdown, LaTeX, and basically anything pandoc
-supports. They can also contain metadata, which are always key-value mappings.
-
- ---
- author: Jasper Van der Jeugt
- title: A sample markdown post
- ---
- # A sample markdown post
-
- This is a sample markdown post. It supports pandoc extensions
- like code highlighting. For example:
-
- ~~~~{.haskell}
- main = putStrLn "Hello World!"
- ~~~~
-
-Metadata is always placed in the header of a file, and is delimited by a `---`
-string. The metadata can only contain simple key-value pairs. We can now read
-in this page using the `Text.Hakyll.Page.readPage` function. This will return a
-`Page`, which is actually just a `Map String ByteString`. In this example, the
-map would consist of the following key-value pairs:
-
-- `author`: `Jasper Van der Jeugt`
-- `title`: `A sample markdown post`
-- `body`: The rest of the file (rendered to html).
-- `url`: `text.html` (the original filename was `text.markdown`, the extension
- was changed to html).
-
-## Templates
-
-In hakyll, there is a strict separation between pages and templates. Templates,
-for example, cannot contain metadata.
-
- <h2> $title </h2>
- by <strong> $author </strong>
-
- $body
-
-Templates are rendered using the Haskell `Text.Template` library. This means
-that in your template, you can use `$identifier`, and it will be replaced by
-the value of `identifier`.
-
-With this template we could, for example, render the file we saw in the
-previous section. It would go like this:
-
- page <- readPage "text.markdown"
- rendered <- render "templates/sample.html" page
- writePage rendered
-
-This reads in `text.markdown`, renders it and writes it to the site destination
-(`_site/text.html`). The result of a `render` action is an `IO Page`, the
-metadata will be copied from the original page, and the body will be replaced by
-the rendering result. This means we can combine rendering actions. Given another
-template `templates/default.html`:
- <html>
- <head>
- <title> $title </title>
- </head>
- <body>
- $body
- </body>
- </html>
-
-We can now combine the rendering actions (I use `>>=` notation here):
- readPage "text.markdown" >>=
- render "templates/sample.html" >>=
- render "templates/default.html" >>=
- writePage
-
-Jolly good fun and all that, but you can imagine that when we render over nine
-thousand posts, our generator will be busy for a while. That's why we have the
-`depends` function. It takes a url and a list of dependencies as arguments, and
-an IO action. The trick is that this IO action will only be executed if any of
-the dependencies is newer than the url given. In our example, we would write:
-
- depends "text.html" ["text.markdown", "templates/sample.html", "templates/default.html"]
- (readPage "text.markdown" >>= render "templates/sample.html" >>=
- render "templates/default.html" >>= writePage)
-
-Not exactly the prettiest code I've ever seen. Because rendering a page with a
-number of templates is very common, there's a `renderChain` function to do this
-for us. The above can be replaced by
-
- renderChain ["templates/sample.html", "templates/default.html"] $
- createPagePath "text.markdown"
-
-The `renderChain` function will automatically check dependencies and write the
-page. In fact, it is recommended that you __always__ use this, even when there's
-only one template in the chain.
-
-## More advanced things
-
-Sometimes, you want to create a `Page` from scratch, without reading from a
-file. There are functions to do that for you, and I suggest you read the
-documentation of `Text.Hakyll.Page`. As a more advanced example, I will explain
-the RSS system I wrote for my website.
-
- |-- generate.hs
- |-- posts
- | `-- 2009-12-02-a-first-post.markdown
- `-- templates
- |-- rss.xml
- `-- rssitem.xml
-
-Our post contains some metadata:
-
- ---
- title: A first post
- date: December 2, 2009
- about: A post describing the why and the how of the technical setup of this blog.
- ---
-
- # A first post
-
- A first post describing the technical setup of this blog, for that is
-
-The `templates/rssitem.xml` file is a template for rendering one post to an rss
-item:
-
- <item>
- <title> $title </title>
- <link>http://jaspervdj.be/$url</link>
- <description> $about </description>
- </item>
-
-Now a template for rendering the whole rss feed, `templates/rss.xml`:
-
- <?xml version="1.0"?>
- <rss version="2.0">
- <channel>
- <title>jaspervdj - a personal blog</title>
- <link>http://jaspervdj.be/</link>
- <description>Personal blog of jaspervdj</description>
- $items
- </channel>
- </rss>
-
-Alright, let's get coding. We first want a list of all posts, sorted so the most
-recent entries are first in the list.
-
- postPaths <- liftM (L.reverse . L.sort) $ getRecursiveContents "posts"
-
-Note that this sorting works because the posts have a
-`yyyy-mm-dd-title.extension` naming scheme. We want the paths as `PagePath` and
-not as `FilePath` or `String`, because `PagePath` is an instance of
-`Renderable`. Also, we only want the 5 most recent posts.
-
- let renderablePosts = map createPagePath postPaths
- let recentItems = renderAndConcat "templates/postitem.html" $ take 5 renderablePosts
-
-The `renderAndConcat` function takes a template and a list of `Renderable`
-items. It renders all renderables with the given template, and concatenates the
-result. Note that the concating and reading of pages is not executed yet,
-because of laziness. This helps us, since we want to use the modification
-timestamps of files, and not render everything every time.
-
- let rssPage = createCustomPage "rss.xml"
- ("templates/rssitem.xml" : postPaths) [("items", Right recentItems)]
-
-We now created the custom rss page. The `createCustomPage` is a function that
-produces a `CustomPage`, which is an instance of `Renderable`. `"rss.xml"` is
-our destination url. We then give a list of extra dependencies that were used
-to generate the custom page, so Hakyll can check modification stamps. The last
-argument is the key-value mapping of our `CustomPage`. Note that the type for
-values is `Either String (IO ByteString)`. So, we can either give a simple
-string, or an IO action that results in a `ByteString`. The benefit of this is
-that the IO action will not be executed if the page in `_site/` is already
-up-to-date. Now, we only need to render it using our rss template.
-
- renderChain ["templates/rss.xml"] rssPage
-
-That's it. Now we have a rss feed that is generated only when it is not already
-up-to-date.
+More information can be found on
+[the hakyll homepage](http://jaspervdj.be/hakyll).