1

I'm following the official instructions on the Hakyll site to get post teasers up and running on my site. Unfortunately, I've hit a snag, and the instructions aren't much help.

I'm getting an out-of-scope error for the item value referenced in this snippet:

loadAndApplyTemplate
     "template/postitem.html"
     (teaserField "teaser" "content" <> defaultContext)
     item

When embedding it into my site.hs. On a side note for reproducibility's sake, it also wasn't made clear where the <> operator came from; this required the import of one of Literate Haskell's modules.

It's completely unclear where this reference to item came from, and because it's a fairly common word, I have to sift through thousands of results even when using find and grep on my machine.

What should I declare or import to gain access to item here?

apaderno
  • 28,547
  • 16
  • 75
  • 90
Jules
  • 14,200
  • 13
  • 56
  • 101
  • `(<>)` is from [`Data.Monoid`](https://hackage.haskell.org/package/base-4.9.1.0/docs/Data-Monoid.html#v:-60--62-). – Jan Tojnar Jan 23 '17 at 16:09
  • @JanTojnar I looked it up on Hoogle, and it was available in both `template-haskell Language.Haskell.TH.PprLib` and `pretty Text.PrettyPrint.HughesPJ, pretty Text.PrettyPrint`. – Jules Jan 23 '17 at 21:58
  • Most often, you will see `(<>)` used as `mappend`. For example, it can be used for joining [`Text`](https://hackage.haskell.org/package/text-1.2.2.1/docs/Data-Text.html#t:Text) or, as in your example, for building [`Context`](https://hackage.haskell.org/package/hakyll-4.9.5.0/docs/Hakyll-Web-Template-Context.html#t:Context), both of which are `Monoid` instances. – Jan Tojnar Jan 24 '17 at 00:05
  • Actually, in modern Haskell, `(<>)` is an operation on [`Semigroup`](https://hackage.haskell.org/package/base-4.9.1.0/docs/Data-Semigroup.html#t:Semigroup) – Jan Tojnar Jan 24 '17 at 00:12
  • Honest question: is this particularly relevant beyond semantics? The operators from `Language.Haskell` and `Text.PrettyPrint` both seem to do what I need them to do. – Jules Jan 24 '17 at 00:23
  • They really should not work at all. They are defined to work on `Doc`: `(<>) :: Doc -> Doc -> Doc` – Jan Tojnar Jan 24 '17 at 02:38

1 Answers1

3

The tutorial page isn't a complete example. item isn't a reference to some function. It's just a placeholder name for an Item. Usually you'll get it from pandocCompiler or one of the many other "compilers". In this example, loadAndApplyTemplate is just like any other use of it. The only difference is that $teaser$ will be bound to the teaser text in the template.

That said, this isn't that great of an example since you usually want to use the teaser text on page listing multiple posts. This will probably involve using listField to make a collection of posts that you will iterate upon in the template. For example, this is the rule for my index page:

match "index.html" $ do
    route idRoute
    compile $ do
        posts <- fmap (take indexRecentPostCount) . recentFirst =<< loadAllSnapshots postsPattern "postContent"
        let indexCtx =
                constField "title" "Home" <>
                baseCtx

        getResourceBody
            >>= applyAsTemplate (listField "posts" (teaserField "teaser" "postContent" <> postCtx) (return posts) <> indexCtx)
            >>= loadAndApplyDefaultTemplate indexCtx
            >>= relativizeUrls

The "item" in this case is what getResourceBody returns, i.e. the body of index.html. This binds $posts$ to a list of posts. Ignoring the metadata, my index.html is just:

$for(posts)$
    $partial("templates/teaser.html")$
$endfor$

$teaser$ is then bound in the template/teaser.html template.

Derek Elkins left SE
  • 2,079
  • 12
  • 14