newest article on homepage

40 views
Skip to first unread message

Robb Seaton

unread,
Sep 4, 2011, 12:00:09 PM9/4/11
to hakyll
Hi, all,

I would like my homepage to include my most recently written article.
How would I accomplish this with Hakyll?

Thanks,
rps

Jasper Van der Jeugt

unread,
Sep 4, 2011, 1:53:29 PM9/4/11
to hak...@googlegroups.com
Hey Robb,

You just need a little tweaking of your hakyll.hs. For example, I
have, for my index page:

match "index.html" $ route idRoute
create "index.html" $ constA mempty
>>> ...
>>> setFieldPageList (take 3 . recentFirst)
"templates/postitem.html" "posts" "posts/*"
>>> ...

Where `setFieldPageList` takes 3 posts, renders them using the
`templates/postitem.html` template, and then sets them under the
`$posts$` key.

You can show the most recent article by modifying this to:

match "index.html" $ route idRoute
create "index.html" $ constA mempty
>>> ...
>>> setFieldPageList (head . recentFirst)
"templates/recent.html" "recent" "posts/*"
>>> ...

Then, you just have to make sure you include `$body$` in your
`templates/recent.html` template, and it should work out fine. Please
let me know if you require some more assistance.

Cheers,
Jasper

Robert Seaton

unread,
Sep 5, 2011, 1:47:35 PM9/5/11
to hak...@googlegroups.com
> Please let me know if you require some more assistance.

Hey, Jasper,

Thanks for the help, but I still can't seem to get my index.html to generate correctly. Would you mind taking a look at my website's source and see if you can point out what I'm doing wrong? 


Thanks,
rps

Jasper Van der Jeugt

unread,
Sep 5, 2011, 6:00:57 PM9/5/11
to hak...@googlegroups.com
Hello,

I've attached a patch which should fix the issue. What it does is,

- Before we start rendering an article, we copy the content to `$contents$`
- We can then apply the `templates/article.html` template, while still
having access to the original content
- This way, we can add the latest article to the home page

Feel free to drop another mail when something is not clear,

Hope this helps,
Cheers,
Jasper

rs.io.patch

Robert Seaton

unread,
Sep 5, 2011, 7:04:41 PM9/5/11
to hak...@googlegroups.com
Hey, Jasper,

That works great, thanks! 

Now I'm wondering how I can get the $date$ field to display on this page: http://rs.io/articles.html. I gather it has something to do with renderDateField, but I'm not sure how to integrate it with the following:

match "articles.html" $ route idRoute
     create "articles.html" $ constA mempty
            >>> arr (setField "title" "Articles")
            >>> setFieldPageList recentFirst
                "templates/postitem.html" "articles" "articles/*"
            >>> applyTemplateCompiler "templates/articles.html"
            >>> arr (setField "category" "articles")
            >>> applyTemplateCompiler "templates/default.html"

Jasper Van der Jeugt

unread,
Sep 6, 2011, 2:05:19 AM9/6/11
to hak...@googlegroups.com
Hello Robb,

The trick here is to add the metadata to the page. By default, a page
has a `$path$` field, from which the `$date$` field can be deduced. In
order to do this, the date output format needs to be specified.

The `renderDateField` function takes care of this -- it allows you to
render the parsed date to any field, in any format (it uses the same
format specifier as the `date` unix command).

The attached patch show how this applies to your website.

Cheers,
Jasper

date.patch

Robert Seaton

unread,
Sep 6, 2011, 2:27:42 PM9/6/11
to hak...@googlegroups.com
Hey, Jasper,

That fixed it, thanks. I've got a couple of final questions, and then
my website will be finished and I will stop bothering you. :)

For each of my posts, I plan on including an image. Now, I could
manually specify the images path in each markdown file with a field,
for example, "image: /img/2011-08-30-housekeeping.png", but it occurs
to me that it should be possible to define a renderImageField function
that automatically inserts this piece of metadata based on the post's
filepath. I don't have much experience with Haskell, so I'm not sure
exactly how to do this.

From looking at the definition of renderDateFieldWith, I think it
would look something like the following:

renderImageField :: String        -- ^ Destination key
                          -> Page a     -- ^ Target page
                          -> Page a     -- ^ Resulting page
renderImageField key = renderField "path" key renderImage'
    where
      renderImage' filePath =
      -- Somehow take the filepath and prefix it with "/img/"
      -- and replace the ".markdown" suffix with ".png"
      return $

I'm also wondering if it is possible to strip ".html" out of the links
in the generated site. I have set up a nginx rewrite rule so that URLs
such as http://rs.io/articles.html and http://rs.io/articles both
serve up the same page and I would like the site to default to a
link-style that doesn't include the .html suffix.

Last thing: have you considered setting up a page like
https://github.com/mojombo/jekyll/wiki/Sites, but for Hakyll? It'd be
interesting to see who is using Hakyll and how they are using it.

Thanks,
rps

Jasper Van der Jeugt

unread,
Sep 6, 2011, 4:53:34 PM9/6/11
to hak...@googlegroups.com
Hello,

> For each of my posts, I plan on including an image. Now, I could
> manually specify the images path in each markdown file with a field,
> for example, "image: /img/2011-08-30-housekeeping.png", but it occurs
> to me that it should be possible to define a renderImageField function
> that automatically inserts this piece of metadata based on the post's
> filepath. I don't have much experience with Haskell, so I'm not sure
> exactly how to do this.
>
> From looking at the definition of renderDateFieldWith, I think it
> would look something like the following:
>
> renderImageField :: String        -- ^ Destination key
>                           -> Page a     -- ^ Target page
>                           -> Page a     -- ^ Resulting page
> renderImageField key = renderField "path" key renderImage'
>     where
>       renderImage' filePath =
>       -- Somehow take the filepath and prefix it with "/img/"
>       -- and replace the ".markdown" suffix with ".png"
>       return $

Something like this should work:

import System.FilePath (replaceExtension)

renderImageField :: String -- ^ Destination key
-> Page a -- ^ Target page
-> Page a -- ^ Resulting page
renderImageField key = renderField "path" key renderImage'
where

renderImage' filePath = "/img" ++ replaceExtension filePath "png"

> I'm also wondering if it is possible to strip ".html" out of the links
> in the generated site. I have set up a nginx rewrite rule so that URLs
> such as http://rs.io/articles.html and http://rs.io/articles both
> serve up the same page and I would like the site to default to a
> link-style that doesn't include the .html suffix.

Inspired by your question, I've added some more utilities for URL
manipulation in Hakyll 3.2.0.6. If you update using cabal, you should
be able to use:

import Control.Arrow (arr)
import System.FilePath (takeExtension, dropExtension)

rewrite :: String -> String
rewrite url
-- isExternal detects URL's which start with "http://"
| isExternal url = url
| takeExtension url == ".html" = dropExtension url
| otherwise = url

rewrite' :: Compiler (Page String) (Page String)
rewrite' = arr (fmap rewrite)

And then you just apply the `rewrite'` compiler (actually,
`rewriteCompiler` might be a better name) to the pages you want.

> Last thing: have you considered setting up a page like
> https://github.com/mojombo/jekyll/wiki/Sites, but for Hakyll? It'd be
> interesting to see who is using Hakyll and how they are using it.

There's such a list here [1]. If you know any sites I can add, feel
free to drop you a mail. I can also add your site once it's finished.

[1] http://jaspervdj.be/hakyll/examples.html

Cheers,
Jasper

Robert Seaton

unread,
Sep 7, 2011, 11:36:40 AM9/7/11
to hak...@googlegroups.com
Hey,

> Inspired by your question, I've added some more utilities for URL
> manipulation in Hakyll 3.2.0.6. If you update using cabal, you should
> be able to use:
>
>    import Control.Arrow (arr)
>    import System.FilePath (takeExtension, dropExtension)
>
>    rewrite :: String -> String
>    rewrite url
>        -- isExternal detects URL's which start with "http://"
>        | isExternal url               = url
>        | takeExtension url == ".html" = dropExtension url
>        | otherwise                    = url
>
>    rewrite' :: Compiler (Page String) (Page String)
>    rewrite' = arr (fmap rewrite)
>
> And then you just apply the `rewrite'` compiler (actually,
> `rewriteCompiler` might be a better name) to the pages you want.

When I try to use that code, I get the following error:
[1 of 1] Compiling Main ( main.hs, main.o )

main.hs:68:1:
Illegal signature in pattern: String -> String rewrite url
Use -XScopedTypeVariables to permit it

main.hs:71:21: Not in scope: `url'

main.hs:71:41: Not in scope: `url'

main.hs:72:24: Not in scope: `url'

main.hs:72:55: Not in scope: `url'

main.hs:73:41: Not in scope: `url'

> There's such a list here [1]. If you know any sites I can add, feel
> free to drop you a mail. I can also add your site once it's finished.
>
> [1] http://jaspervdj.be/hakyll/examples.html

Please add http://rs.io (with the source at
https://github.com/robertseaton/rs.io) whenever you get a chance.

--
rps

Jasper Van der Jeugt

unread,
Sep 7, 2011, 12:30:16 PM9/7/11
to hak...@googlegroups.com
Looks like a formatting error, perhaps a mail tool messed it up. This
is the fragment I meant [1].

[1] http://hpaste.org/51052

Cheers,
Jasper

Robert Seaton

unread,
Sep 8, 2011, 11:37:19 AM9/8/11
to hak...@googlegroups.com
Hey, Jasper,

How would I go about applying the rewrite' compiler to this:
https://github.com/robertseaton/rs.io/blob/master/main.hs?
Specifically, I'm trying to rewrite the URLs on http://rs.io/articles.

Also, could you please add my site, http://rs.io, and its source,
https://github.com/robertseaton/rs.io/, to the examples page?

Thanks,

--
rps

Jasper Van der Jeugt

unread,
Sep 9, 2011, 2:20:16 AM9/9/11
to hak...@googlegroups.com
Oops! I made a mistake by forgetting to include `withUrls` in the
`rewrite'` compiler. My excuses. Note that you need the latest Hakyll
(3.2.0.6) for the `withUrls` compiler.

Hope this helps,
Cheers,
Jasper

rewrite.patch

Robert Seaton

unread,
Sep 9, 2011, 11:28:55 AM9/9/11
to hak...@googlegroups.com
Thanks, Jasper! Works great now. :)

--
rps

Reply all
Reply to author
Forward
0 new messages