Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modifying the Hakyll example site

I wish to modify the following code so that, rather than producing links to the latest three posts on the site, it reproduces the body of the posts in their entirely, like in a traditional blog. I'm having a bit of difficulty understanding what's going on below, and what the necessary changes would be.

match "index.html" $ do
    route idRoute
    compile $ do
        let indexCtx = field "posts" $ \_ ->
                            postList $ fmap (take 3) . recentFirst

        getResourceBody
            >>= applyAsTemplate indexCtx
            >>= loadAndApplyTemplate "templates/default.html" postCtx
            >>= relativizeUrls
like image 563
pgay Avatar asked Apr 07 '13 08:04

pgay


2 Answers

This is not entirely trivial. A first step is introducing snapshots.

As explained in the tutorial, this ensures you can include the blogposts on your index without having the templates applied to the HTML first. So you'll get something like:

match "posts/*" $ do
    route $ setExtension "html"
    compile $ pandocCompiler
        >>= loadAndApplyTemplate "templates/post.html"    postCtx
        >>= saveSnapshot "content"
        >>= loadAndApplyTemplate "templates/default.html" postCtx
        >>= relativizeUrls

Now, in order to display the posts on the index page, you will be able to use the entire $body$ of the posts. In order to do this, you'll just have to update templates/post-item.html into something like:

<div>
    <a href="$url$"><h2>$title$</h2></a>
    $body$
</div>
like image 137
jaspervdj Avatar answered Sep 30 '22 14:09

jaspervdj


I know this post is a bit old but since it does not seem to be resolved here is how I went about it.

First save a snapshot as described by @jaspervdj:

match "posts/*" $ do
  route $ setExtension "html"
  compile $ pandocCompiler
    >>= loadAndApplyTemplate "templates/post.html"  postCtx
    >>= saveSnapshot "content"
    >>= loadAndApplyTemplate "templates/default.html" postCtx
    >>= relativizeUrls

Then for index.html load all the post snapshots with loadAllSnapshots:

match "index.html" $ do
  route idRoute
  compile $ do
    posts <- recentFirst =<< loadAllSnapshots "posts/*" "content"
    let indexCtx = listField "posts" postCtx (return posts) `mappend`
                   defaultContext

Since the snapshot was taken before applying default template, the value of $body$ within $for(posts)$ will be just the content of each post template without the default template applied.

like image 42
James Avatar answered Sep 30 '22 13:09

James