Fork me on GitHub

Tutorial: Using Clay with Hakyll

Clay is a nice CSS preprocesser written in Haskell. There are multiple options to use this together with Hakyll, but in this short tutorial I focus on what I think is the best way.

This method requires every Clay file to have a main function which just prints the CSS. This would be an example of such a file:

{-# LANGUAGE OverloadedStrings #-}
import           Clay

test :: Css
test = ...

main :: IO ()
main = putCss test

If you prefer the compact version, you’re going to have an extra import:

import qualified Data.Text.Lazy.IO as T

main :: IO ()
main = T.putStr $ renderWith compact test

Let’s assume such a file is called css/foo.hs. In our compiled site, we want to map this to css/foo.css. Hence, the route is a simple setExtension. For compilation, we simply pass the Clay file through runghc with no options.

match "css/*.hs" $ do
    route   $ setExtension "css"
    compile $ getResourceString >>= withItemBody (unixFilter "runghc" [])

-- cabal sandbox users can use (unixFilter "cabal" ["exec", "runghc"])
-- given that you've added cabal to your PATH

The major advantage of using this method (as opposed to importing the Clay files in site.hs) is that now Hakyll will only recompile the Clay files when necessary, and you don’t have to manually recompile your site.hs each time you want to tweak your CSS a little.

Other tutorials

Find links to other tutorials.

Documentation inaccurate or out-of-date? Found a typo?

Hakyll is an open source project, and one of the hardest parts is writing correct, up-to-date, and understandable documentation. Therefore, the authors would really appreciate it if you would give feedback about the tutorials, and especially report errors or difficulties you encountered. If you have a github account, you can use the issue system. Thanks! If you run into any problems, all questions are welcome in the above google group, or you could try the IRC channel, #hakyll on irc.libera.chat (we do not have a channel on Freenode anymore).