diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,10 @@
 # Changelog for Shakebook
 
+## (v0.6.0.0)
+
+* Drop `Display` instances for `Within` and `Path`.
+* Introduce [ixset](https://hackage.haskell.org/package/ixset)
+
 ## (v0.5.1.0)
 
 * Add `tagIndex` and `monthIndex` instead of filter and partition functions.
diff --git a/shakebook.cabal b/shakebook.cabal
--- a/shakebook.cabal
+++ b/shakebook.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: f5bb0ca4ec7dfb075bca03025667a052ba4df3ca169c5d2746369855586f78fd
+-- hash: 04043d969a1442f47c137e5bc16334c189a9fd62153a924984b247d4ed9470f2
 
 name:           shakebook
-version:        0.5.1.0
+version:        0.6.0.0
 synopsis:       Shake-based technical documentation generator; HTML & PDF
 description:    Shakebook is a documentation generator aimed at covering all the bases for mathematical, technical and scientific diagrams and typesetting. Shakebook provides combinators for taking markdown files and combining them into documents, but allowing the user to control how. Shakebook provides general combinators for templating single pages, cofree comonads for representing tables of contents, and zipper comonads for representing pagers.
 category:       Web
@@ -37,24 +37,24 @@
   default-extensions: BangPatterns BinaryLiterals ConstraintKinds DataKinds DefaultSignatures DeriveDataTypeable DeriveFoldable DeriveFunctor DeriveGeneric DeriveTraversable DoAndIfThenElse EmptyDataDecls ExistentialQuantification FlexibleContexts FlexibleInstances FunctionalDependencies GADTs GeneralizedNewtypeDeriving InstanceSigs KindSignatures LambdaCase MultiParamTypeClasses MultiWayIf NamedFieldPuns NoImplicitPrelude OverloadedStrings PartialTypeSignatures PatternGuards PolyKinds RankNTypes RecordWildCards ScopedTypeVariables StandaloneDeriving TupleSections TypeFamilies TypeSynonymInstances ViewPatterns
   ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints
   build-depends:
-      aeson
-    , aeson-with
+      aeson >=1.5.2.0
+    , aeson-with >=0.1.0.0
     , base >=4.7 && <5
     , comonad
     , comonad-extras
     , doctemplates
     , feed
     , free
+    , ixset
     , lens
     , lens-aeson
     , mustache
-    , pandoc
+    , pandoc >=2.9.2.1
     , pandoc-types
-    , path-extensions
-    , relude
+    , path-extensions >=0.0.1.0
     , rio
-    , shake-plus
-    , slick
+    , shake-plus >=0.1.7.0
+    , slick >=1.0.1.1
     , split
     , text-time
     , zipper-extra
@@ -70,25 +70,25 @@
   default-extensions: BangPatterns BinaryLiterals ConstraintKinds DataKinds DefaultSignatures DeriveDataTypeable DeriveFoldable DeriveFunctor DeriveGeneric DeriveTraversable DoAndIfThenElse EmptyDataDecls ExistentialQuantification FlexibleContexts FlexibleInstances FunctionalDependencies GADTs GeneralizedNewtypeDeriving InstanceSigs KindSignatures LambdaCase MultiParamTypeClasses MultiWayIf NamedFieldPuns NoImplicitPrelude OverloadedStrings PartialTypeSignatures PatternGuards PolyKinds RankNTypes RecordWildCards ScopedTypeVariables StandaloneDeriving TupleSections TypeFamilies TypeSynonymInstances ViewPatterns
   ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints -threaded -rtsopts -with-rtsopts=-N
   build-depends:
-      aeson
-    , aeson-with
+      aeson >=1.5.2.0
+    , aeson-with >=0.1.0.0
     , base >=4.7 && <5
     , comonad
     , comonad-extras
     , doctemplates
     , feed
     , free
+    , ixset
     , lens
     , lens-aeson
     , mustache
-    , pandoc
+    , pandoc >=2.9.2.1
     , pandoc-types
-    , path-extensions
-    , relude
+    , path-extensions >=0.0.1.0
     , rio
-    , shake-plus
+    , shake-plus >=0.1.7.0
     , shakebook
-    , slick
+    , slick >=1.0.1.1
     , split
     , tasty
     , tasty-golden
diff --git a/src/Shakebook/Conventions.hs b/src/Shakebook/Conventions.hs
--- a/src/Shakebook/Conventions.hs
+++ b/src/Shakebook/Conventions.hs
@@ -43,21 +43,22 @@
 , genPageData
 , genTocNavbarData
 
-, dateSortPosts
-, monthIndex
-, tagIndex
+, Post(..)
+, Tag(..)
+, Posted(..)
+, YearMonth(..)
 ) where
 
 import           Control.Comonad.Cofree
 import           Control.Comonad.Store
 import           Control.Comonad.Zipper.Extra
-import           Control.Lens                 hiding ((:<))
+import           Control.Lens                 hiding ((:<), Indexable)
 import           Data.Aeson                   as A
 import           Data.Aeson.Lens
 import           Data.Aeson.With
+import           Data.IxSet                   as Ix
 import           Data.Text.Time
 import           RIO                          hiding (view)
-import qualified RIO.HashMap                  as HM
 import           RIO.List
 import           RIO.List.Partial
 import qualified RIO.Text                     as T
@@ -97,11 +98,11 @@
 withHighlighting = withStringField "highlighting-css" . T.pack . styleToCss
 
 -- | Add "next" field from input Value.
-withNext :: Maybe Value -> (Value -> Value)
-withNext = withValueMaybe "next"
+withNext :: ToJSON a => a -> Value -> Value
+withNext = withValue "next"
 
 -- | Add "pages" field from input [Value].
-withPages :: [Value] -> (Value -> Value)
+withPages :: ToJSON a => [a] -> Value -> Value
 withPages = withArrayField "pages"
 
 -- | Add "prettydate" field using input Text.
@@ -109,15 +110,15 @@
 withPrettyDate = withStringField "pretty-date"
 
 -- | Add "previous" field using input Value.
-withPrevious :: Maybe Value -> (Value -> Value)
-withPrevious = withValueMaybe "previous"
+withPrevious :: ToJSON a => a -> Value -> Value
+withPrevious = withValue "previous"
 
 -- | Add "posts" field based on input [Value].
-withPosts :: [Value] -> Value -> Value
+withPosts :: ToJSON a => [a] -> Value -> Value
 withPosts = withArrayField "posts"
 
 -- | Add "recent-posts" field using input Value.
-withRecentPosts :: [Value] -> Value -> Value
+withRecentPosts :: ToJSON a => [a] -> Value -> Value
 withRecentPosts = withArrayField "recent-posts"
 
 -- | Add "site-title" field from input Text.
@@ -125,19 +126,19 @@
 withSiteTitle = withStringField "site-title"
 
 -- | Add "social-links" field based on input [Value].
-withSocialLinks :: [Value] -> Value -> Value
+withSocialLinks :: ToJSON a => [a] -> Value -> Value
 withSocialLinks = withArrayField "social-links"
 
 -- | Add "subsections" field based on input [Value].
-withSubsections :: [Value] -> (Value -> Value)
+withSubsections :: ToJSON a => [a] -> Value -> Value
 withSubsections = withArrayField "subsections"
 
 -- | Add "tag-index" field based on input [Value].
-withTagIndex :: [Value] -> Value -> Value
+withTagIndex :: ToJSON a => [a] -> Value -> Value
 withTagIndex = withArrayField "tag-index"
 
 -- | Add "tag-links" field based on input [Value].
-withTagLinks :: [Value] -> Value -> Value
+withTagLinks :: ToJSON a => [a] -> Value -> Value
 withTagLinks  = withArrayField "tag-links"
 
 -- | Add "teaser" field based on input Text.
@@ -149,8 +150,8 @@
 withTitle = withStringField "title"
 
 -- | Assuming a "date" field, enrich using withPrettyDate and a format string.
-enrichPrettyDate :: (UTCTime -> String) -> Value -> Value
-enrichPrettyDate f v = withPrettyDate (T.pack . f . viewPostTime $ v) v
+enrichPrettyDate :: (UTCTime -> Text) -> Value -> Value
+enrichPrettyDate f v = withPrettyDate (f . viewPostTime $ v) v
 
 -- | Assuming a "tags" field, enrich using withTagLinks.
 enrichTagLinks :: (Text -> Text) -> Value -> Value
@@ -181,34 +182,44 @@
 genLinkData :: Text -> Text -> Value
 genLinkData x u = object ["id" A..= String x, "url" A..= String u]
 
--- | Create a `HashMap` of posts indexed by tag.
-tagIndex :: [Value] -> HashMap Text [Value]
-tagIndex xs = HM.fromList [(t, filter (elem t . viewTags) xs) | t <- viewAllPostTags xs]
+newtype Post = Post { unPost :: Value }
+  deriving (Show, Eq, Ord, Data, Typeable, ToJSON)
 
--- | Create a `HashMap` of posts indexed by year-month..
-monthIndex :: [Value] -> HashMap Text [Value]
-monthIndex xs = HM.fromList [(t, filter ((== t) . T.pack . formatTime defaultTimeLocale "%Y-%m" . viewPostTime) xs) | t <- nub (T.pack . formatTime defaultTimeLocale "%Y-%m" <$> viewAllPostTimes xs)]
+newtype Tag = Tag Text
+  deriving (Show, Eq, Ord, Data, Typeable)
 
--- | Sort a lists of posts by date.
-dateSortPosts :: [Value] -> [Value]
-dateSortPosts = sortOn (Down . viewPostTime)
+newtype Posted = Posted UTCTime
+  deriving (Show, Eq, Ord, Data, Typeable)
 
+newtype YearMonth = YearMonth (Integer, Int)
+  deriving (Show, Eq, Ord, Data, Typeable)
+
+newtype SrcFile = SrcFile Text
+  deriving (Show, Eq, Ord, Data, Typeable)
+
+instance Indexable Post where
+  empty = ixSet [ (ixFun (fmap Tag . viewTags . unPost))
+                , (ixFun (pure . Posted . viewPostTime . unPost))
+                , (ixFun (pure . YearMonth . (\(a,b,_) -> (a,b)) . toGregorian . utctDay . viewPostTime . unPost))
+                , (ixFun (pure . SrcFile . viewSrcPath . unPost))
+                ]
+
 -- | Create a blog navbar object for a posts section, with layers "toc1", "toc2", and "toc3".
 genBlogNavbarData :: Text -- ^ "Top level title, e.g "Blog"
-               -> Text -- ^ Root page, e.g "/posts"
-               -> (UTCTime -> Text) -- ^ Formatting function to a UTCTime to a title.
-               -> (UTCTime -> Text) -- ^ Formatting function to convert a UTCTime to a URL link
-               -> [Value]
-               -> Value
+                  -> Text -- ^ Root page, e.g "/posts"
+                  -> (UTCTime -> Text) -- ^ Formatting function to a UTCTime to a title.
+                  -> (UTCTime -> Text) -- ^ Formatting function to convert a UTCTime to a URL link
+                  -> IxSet Post
+                  -> Value
 genBlogNavbarData a b f g xs = object [ "toc1" A..= object [
                                         "title" A..= String a
                                       , "url"   A..= String b
-                                      , "toc2"  A..= Array (V.fromList $ map toc2 (HM.elems $ monthIndex xs)) ]
+                                      , "toc2"  A..= Array (V.fromList $ map (uncurry toc2) $ groupDescBy xs)]
                                      ] where
-       toc2 [] = object []
-       toc2 t@(x : _) = object [ "title" A..= String (f (viewPostTime x))
-                              , "url"   A..= String (g (viewPostTime x))
-                              , "toc3"  A..= Array (V.fromList t) ]
+       toc2 _ [] = object []
+       toc2 (YearMonth (_, _)) t@(x : _) = object [ "title" A..= String (f (viewPostTime . unPost $ x))
+                                                  , "url"   A..= String (g (viewPostTime . unPost $ x))
+                                                  , "toc3"  A..= Array (V.fromList $ sortOn (Down . viewPostTime) $ (unPost <$> t)) ]
 
 -- | Create a toc navbar object for a docs section, with layers "toc1", "toc2" and "toc3".
 genTocNavbarData :: Cofree [] Value -> Value
@@ -228,6 +239,6 @@
                  -> (Text -> Text)
                  -> Int
                  -> m (Zipper [] Value)
-genIndexPageData xs g h n = do 
- zs <- paginate' n xs
+genIndexPageData xs g h n = do
+ zs <- paginate' n $ sortOn (Down . viewPostTime) xs
  return $ extend (genPageData g h) zs
diff --git a/src/Shakebook/Data.hs b/src/Shakebook/Data.hs
--- a/src/Shakebook/Data.hs
+++ b/src/Shakebook/Data.hs
@@ -1,31 +1,17 @@
 {-# LANGUAGE TemplateHaskell #-}
 module Shakebook.Data where
 
-import           Control.Comonad.Env as E
-import           Control.Lens               hiding ((:<))
-import           Data.Aeson                 as A
+import           Control.Comonad.Env    as E
+import           Control.Lens           hiding ((:<))
+import           Data.Aeson             as A
 import           Data.Aeson.Lens
 import           Data.Aeson.With
 import           Development.Shake.Plus
 import           Path.Extensions
-import           RIO                        hiding (Lens', lens, view)
-import qualified RIO.Text                   as T
+import           RIO                    hiding (Lens', lens, view)
+import qualified RIO.Text               as T
 import           Shakebook.Pandoc
 import           Text.Pandoc
-
-newtype PathDisplay a t = PathDisplay (Path a t)
-
-instance Display (PathDisplay a t) where
-  display (PathDisplay f) = displayBytesUtf8 . fromString . toFilePath $ f
-
-newtype WithinDisplay a t = WithinDisplay (Within a t)
-
-instance Display (WithinDisplay a (Path b t)) where
-  display (WithinDisplay (WithinT (EnvT e (Identity a)))) = display (PathDisplay e) <> "[" <> display (PathDisplay a) <> "]"
-
-instance Display [WithinDisplay a (Path b t)] where
-  display [] = ""
-  display (x : xs) = display x <> " : " <> display xs
 
 -- | View the "content" field of a JSON value.
 viewContent :: Value -> Text
diff --git a/src/Shakebook/Defaults.hs b/src/Shakebook/Defaults.hs
--- a/src/Shakebook/Defaults.hs
+++ b/src/Shakebook/Defaults.hs
@@ -1,28 +1,28 @@
 {-# LANGUAGE TemplateHaskell #-}
 module Shakebook.Defaults where
 
-import           Data.Aeson                   as A
+import           Data.Aeson             as A
 import           Development.Shake.Plus
 import           RIO
-import qualified RIO.Map                      as M
-import qualified RIO.Text                     as T
+import qualified RIO.Map                as M
+import qualified RIO.Text               as T
 import           RIO.Time
 import           Shakebook.Conventions
 import           Text.DocTemplates
 import           Text.Pandoc.Definition
 import           Text.Pandoc.Options
 
-defaultMonthUrlFormat :: UTCTime -> String
-defaultMonthUrlFormat = formatTime defaultTimeLocale "%Y-%m"
+defaultMonthUrlFormat :: UTCTime -> Text
+defaultMonthUrlFormat = T.pack . formatTime defaultTimeLocale "%Y-%m"
 
-defaultPrettyMonthFormat :: UTCTime -> String
-defaultPrettyMonthFormat = formatTime defaultTimeLocale "%B, %Y"
+defaultPrettyMonthFormat :: UTCTime -> Text
+defaultPrettyMonthFormat = T.pack . formatTime defaultTimeLocale "%B, %Y"
 
-defaultPrettyTimeFormat :: UTCTime -> String
-defaultPrettyTimeFormat = formatTime defaultTimeLocale "%A, %B %d, %Y"
+defaultPrettyTimeFormat :: UTCTime -> Text
+defaultPrettyTimeFormat = T.pack . formatTime defaultTimeLocale "%A, %B %d, %Y"
 
 defaultMonthUrlFragment :: UTCTime -> Text
-defaultMonthUrlFragment t = T.pack $ "/posts/months/" <> defaultMonthUrlFormat t
+defaultMonthUrlFragment t = "/posts/months/" <> defaultMonthUrlFormat t
 
 defaultEnrichPost :: Value -> Value
 defaultEnrichPost = enrichTeaser "<!--more-->"
diff --git a/src/Shakebook/Feed.hs b/src/Shakebook/Feed.hs
--- a/src/Shakebook/Feed.hs
+++ b/src/Shakebook/Feed.hs
@@ -6,11 +6,12 @@
 import           Data.Aeson
 import           Development.Shake.Plus
 import           RIO
+import           RIO.List
 import           RIO.List.Partial
-import qualified RIO.Text.Lazy         as TL
+import qualified RIO.Text.Lazy          as TL
 import           Shakebook.Conventions
 import           Shakebook.Data
-import           Text.Atom.Feed        as Atom
+import           Text.Atom.Feed         as Atom
 import           Text.Atom.Feed.Export
 
 -- | Convert a Post to an Atom Entry
@@ -21,7 +22,7 @@
 -- | Build an Atom Feed from a list of posts.
 buildFeed :: MonadAction m => Text -> Text -> [Value] -> Path Rel File -> m ()
 buildFeed title baseUrl xs out = do
-  let fs = asAtomEntry <$> dateSortPosts xs
+  let fs = asAtomEntry <$> sortOn (Down . viewPostTime) xs
   let t = Atom.nullFeed baseUrl (Atom.TextString title) $ Atom.entryUpdated (head fs)
   case  textFeed (t { Atom.feedEntries = fs }) of
     Just a  -> writeFile' out $ TL.toStrict a
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -1,16 +1,17 @@
 {-# LANGUAGE TemplateHaskell #-}
 
-import           Control.Lens hiding ((:<))
+import           Control.Lens      hiding ((:<))
 import           Data.Aeson.With
+import qualified Data.IxSet        as Ix
 import           Data.List.Split
-import           Data.Text.Time
 import           Path.Extensions
 import           RIO
-import           RIO.Partial
-import qualified RIO.HashMap                  as HM
+import qualified RIO.HashMap       as HM
 import           RIO.List
 import           RIO.List.Partial
-import qualified RIO.Text                     as T
+import           RIO.Partial
+import qualified RIO.Text          as T
+import           RIO.Time
 import           Shakebook
 import           Test.Tasty
 import           Test.Tasty.Golden
@@ -54,47 +55,43 @@
 
   readMDC <- newCache $ loadMarkdownAsJSON defaultMarkdownReaderOptions defaultHtml5WriterOptions
 
-  postsC  <- newCache $ \w -> do
-    xs <- batchLoadWithin' w readMDC
-    return $ defaultEnrichPost <$> xs
-
-  sortedPosts <- newCache $ \fp -> do
-    allPosts <- postsC fp
-    return $  sortOn (Down . viewPostTime . snd) $ HM.toList allPosts
-
-  getRecentPosts <- newCache $ \fp -> do
-    xs <- sortedPosts fp
-    return $ take numRecentPosts (snd <$> xs)
+  postsIx <- newCache $ \fp -> do
+    xs <- batchLoadWithin' fp readMDC
+    return $ Ix.fromList $ Post <$> HM.elems (defaultEnrichPost <$> xs)
 
   getBlogNavbar <- newCache $ \fp -> do
-    allPosts <- postsC fp
-    return $ genBlogNavbarData "Blog" "/posts/"
-                  (T.pack . defaultPrettyMonthFormat)
-                  defaultMonthUrlFragment (HM.elems allPosts)
+    xs <- postsIx fp
+    return $ genBlogNavbarData "Blog" "/posts/" defaultPrettyMonthFormat defaultMonthUrlFragment xs
 
   postsZ <- newCache $ \fp -> do
-    xs <- sortedPosts fp
-    zs <- ifor xs $ \i (k, _) -> do
-      z <- zipper' (snd <$> xs)
-      return (k, seek i z)
+    xs <- postsIx fp
+    let ys = Ix.toDescList (Ix.Proxy :: Ix.Proxy Posted) xs
+    zs <- ifor ys $ \i v -> do
+      z <- zipper' (unPost <$> ys)
+      return (viewSrcPath (unPost v), seek i z)
     return $ HM.fromList zs
 
   blogIndexPageData <- newCache $ \fp -> do
-    xs <- sortedPosts fp
-    genIndexPageData (snd <$> xs) "Posts" ("/posts/pages/" <>) postsPerPage
+    xs <- postsIx fp
+    genIndexPageData (unPost <$> Ix.toList xs) "Posts" ("/posts/pages/" <>) postsPerPage
 
   blogTagIndexPageData <- newCache $ \fp -> do
-    xs <- sortedPosts fp
-    flip HM.traverseWithKey (tagIndex (snd <$> xs)) $ \t ys ->
-      genIndexPageData ys ("Posts tagged " <> t) (("/posts/tags/" <> t <> "/pages/") <>) postsPerPage
+    xs <- postsIx fp
+    k <- forM (Ix.groupDescBy xs) $ \((Tag t), ys) -> do
+      z <- genIndexPageData (unPost <$> ys) ("Posts tagged " <> t) (("/posts/tags/" <> t <> "/pages/") <>) postsPerPage
+      return (t, z)
+    return $ HM.fromList k
 
   blogMonthIndexPageData <- newCache $ \fp -> do
-    xs <- sortedPosts fp
-    flip HM.traverseWithKey (monthIndex (snd <$> xs)) $ \t ys ->
-      let t' = parseISODateTime t
-      in genIndexPageData ys
-                   (("Posts from " <>) . T.pack . defaultPrettyMonthFormat $ t')
-                   (("/posts/months/"  <> T.pack (defaultMonthUrlFormat t') <> "/pages/") <>) postsPerPage
+    xs <- postsIx fp
+    k <- forM (Ix.groupDescBy xs) $ \(YearMonth (y,m), ys) -> do
+      let t' = UTCTime (fromGregorian y m 1) 0
+      z <- genIndexPageData (unPost <$> ys)
+                            (("Posts from " <>) . defaultPrettyMonthFormat $ t')
+                            (("/posts/months/"  <> defaultMonthUrlFormat t' <> "/pages/") <>)
+                            postsPerPage
+      return (defaultMonthUrlFormat t', z)
+    return $ HM.fromList k
 
   let myPosts = ["posts/*.md"] `within` sourceFolder
 
@@ -102,11 +99,11 @@
       s' = (`within` sourceFolder)
 
       myBuildPage tmpl v out = do
-        rs <- getRecentPosts myPosts
+        rs <- postsIx myPosts
         let v' = withHighlighting pygments
                . withSocialLinks mySocial
                . withSiteTitle siteTitle
-               . withRecentPosts rs $ v
+               . withRecentPosts (take numRecentPosts $ Ix.toDescList (Ix.Proxy :: Ix.Proxy Posted) rs) $ v
         buildPageActionWithin (s' tmpl) v' out
 
       myBuildBlogPage tmpl v out = do
@@ -125,13 +122,13 @@
   o' "posts/*.html" %^> \out -> do
     src <- blinkAndMapM sourceFolder withMdExtension out
     xs <- postsZ myPosts
-    case HM.lookup src xs of
-      Nothing -> logError $ "Attempting to lookup non-existent post " <> display (WithinDisplay src)
+    case HM.lookup (T.pack . toFilePath . extract $ src) xs of
+      Nothing -> logError $ "Attempting to lookup non-existent post " <> displayShow src
       Just x  -> myBuildBlogPage $(mkRelFile "templates/post.html") (extract x) out
 
   toc' <- mapM (mapM withHtmlExtension) $ fmap o' tableOfContents
   void . sequence . flip extend toc' $ \xs -> (toFilePath <$> extract xs) %^> \out -> do
-    let getDoc = readMDC <=< blinkAndMapM sourceFolder withMdExtension 
+    let getDoc = readMDC <=< blinkAndMapM sourceFolder withMdExtension
     ys <- mapM getDoc toc'
     zs <- mapM getDoc (fmap extract . unwrap $ xs)
     v  <- getDoc out
@@ -145,7 +142,7 @@
     let n = (+ (-1)) . read . (!! 2) . splitOn "/" . toFilePath . extract $ out
     xs <- blogIndexPageData myPosts
     myBuildPostListPage (seek n xs) out
- 
+
   o' "posts/tags/*/index.html" %^> \out -> do
     let t = (!! 2) . splitOn "/" . toFilePath . extract $ out
     i <- parseRelFile $ "posts/tags/" <> t <> "/pages/1/index.html"
@@ -209,7 +206,7 @@
   phony "posts" $ simplePipeline withHtmlExtension ["posts/*.md"]
 
   phony "clean" $ do
-    logInfo $ "Cleaning files in " <> display (PathDisplay outputFolder)
+    logInfo $ "Cleaning files in " <> displayShow outputFolder
     removeFilesAfter outputFolder ["//*"]
 
 tests :: [FilePath] -> TestTree
