diff --git a/hakyll.cabal b/hakyll.cabal
--- a/hakyll.cabal
+++ b/hakyll.cabal
@@ -1,5 +1,5 @@
 Name:    hakyll
-Version: 3.2.0.1
+Version: 3.2.0.2
 
 Synopsis: A static website compiler library
 Description:
@@ -29,13 +29,13 @@
   Additionally, there's the Haddock documentation in the different modules,
   meant as a reference.
 
-Author:       Jasper Van der Jeugt
-Maintainer:   jaspervdj@gmail.com
+Author:       Jasper Van der Jeugt <m@jaspervdj.be>
+Maintainer:   Jasper Van der Jeugt <m@jaspervdj.be>
 Homepage:     http://jaspervdj.be/hakyll
 Bug-Reports:  http://github.com/jaspervdj/Hakyll/issues
 License:      BSD3
 License-File: LICENSE
-Category:     Text
+Category:     Web
 
 Cabal-Version: >= 1.6
 Build-Type:    Simple
@@ -55,29 +55,27 @@
   Hs-Source-Dirs: src
 
   Build-Depends:
-    base >= 4 && < 5,
-    filepath == 1.*,
-    directory == 1.*,
-    containers == 0.*,
-    pandoc == 1.*,
-    regex-base >= 0.93,
-    regex-pcre >= 0.93,
-    mtl >= 1,
-    old-locale == 1.*,
-    old-time == 1.*,
-    time >= 1.1,
-    binary >= 0.5,
-    hamlet >= 0.7,
-    blaze-html >= 0.4,
-    snap-server >= 0.4,
-    snap-core >= 0.4,
-    bytestring >= 0.9,
-    utf8-string >= 0.3,
-    HTTP >= 4000,
-    tagsoup >= 0.12,
-    hopenssl >= 1.4,
-    unix >= 2.4,
-    strict-concurrency >= 0.2
+    base        >= 4     && < 5,
+    binary      >= 0.5   && < 1.0,
+    blaze-html  >= 0.4   && < 0.6,
+    bytestring  >= 0.9   && < 1.0,
+    containers  >= 0.3   && < 1.0,
+    directory   >= 1.0   && < 1.3,
+    filepath    >= 1.0   && < 2.0,
+    hamlet      >= 0.7   && < 0.9,
+    hopenssl    >= 1.4   && < 1.7,
+    mtl         >= 1     && < 3.0,
+    old-locale  >= 1.0   && < 2.0,
+    old-time    >= 1.0   && < 1.3,
+    pandoc      >= 1.6   && < 2.0,
+    process     >= 1.0   && < 1.4,
+    regex-base  >= 0.93  && < 1.0,
+    regex-pcre  >= 0.93  && < 1.0,
+    snap-core   >= 0.5.1 && < 0.6,
+    snap-server >= 0.5.1 && < 0.6,
+    tagsoup     >= 0.12  && < 0.13,
+    time        >= 1.1   && < 1.3,
+    unix        >= 2.4   && < 2.6
 
   Exposed-Modules:
     Hakyll
diff --git a/src/Hakyll/Core/Configuration.hs b/src/Hakyll/Core/Configuration.hs
--- a/src/Hakyll/Core/Configuration.hs
+++ b/src/Hakyll/Core/Configuration.hs
@@ -13,7 +13,7 @@
     { -- | Directory in which the output written
       destinationDirectory :: FilePath
     , -- | Directory where hakyll's internal store is kept
-      storeDirectory       :: FilePath
+      storeDirectory :: FilePath
     , -- | Function to determine ignored files
       --
       -- In 'defaultHakyllConfiguration', the following files are ignored:
@@ -28,7 +28,18 @@
       -- also be ignored. Note that this is the configuration parameter, if you
       -- want to use the test, you should use @shouldIgnoreFile@.
       --
-      ignoreFile           :: FilePath -> Bool
+      ignoreFile :: FilePath -> Bool
+    , -- | Here, you can plug in a system command to upload/deploy your site.
+      --
+      -- Example:
+      --
+      -- > rsync -ave 'ssh -p 2217' _site jaspervdj@jaspervdj.be:hakyll
+      --
+      -- You can execute this by using
+      --
+      -- > ./hakyll deploy
+      --
+      deployCommand :: String
     }
 
 -- | Default configuration for a hakyll application
@@ -38,6 +49,7 @@
     { destinationDirectory = "_site"
     , storeDirectory       = "_cache"
     , ignoreFile           = ignoreFile'
+    , deployCommand        = "echo 'No deploy command specified'"
     }
   where
     ignoreFile' path
diff --git a/src/Hakyll/Core/Logger.hs b/src/Hakyll/Core/Logger.hs
--- a/src/Hakyll/Core/Logger.hs
+++ b/src/Hakyll/Core/Logger.hs
@@ -15,8 +15,8 @@
 import Control.Monad.Trans (MonadIO, liftIO)
 import Control.Applicative (pure, (<$>), (<*>))
 import Control.Concurrent (forkIO)
-import Control.Concurrent.Chan.Strict (Chan, newChan, readChan, writeChan)
-import Control.Concurrent.MVar.Strict (MVar, newEmptyMVar, takeMVar, putMVar)
+import Control.Concurrent.Chan (Chan, newChan, readChan, writeChan)
+import Control.Concurrent.MVar (MVar, newEmptyMVar, takeMVar, putMVar)
 import Text.Printf (printf)
 
 import Data.Time (getCurrentTime, diffUTCTime)
diff --git a/src/Hakyll/Main.hs b/src/Hakyll/Main.hs
--- a/src/Hakyll/Main.hs
+++ b/src/Hakyll/Main.hs
@@ -8,8 +8,9 @@
 import Control.Applicative ((<$>))
 import Control.Concurrent (forkIO)
 import Control.Monad (when)
-import System.Environment (getProgName, getArgs)
 import System.Directory (doesDirectoryExist, removeDirectoryRecursive)
+import System.Environment (getProgName, getArgs)
+import System.Process (system)
 import qualified Data.Set as S
 
 import Hakyll.Core.Configuration
@@ -40,6 +41,7 @@
         ["rebuild"]    -> rebuild conf rules
         ["server"]     -> server conf 8000
         ["server", p]  -> server conf (read p)
+        ["deploy"]     -> deploy conf
         _              -> help
 
 -- | Build the site
@@ -80,6 +82,7 @@
         , name ++ " preview [port]  Run a server and autocompile"
         , name ++ " rebuild         Clean up and build again"
         , name ++ " server [port]   Run a local test server"
+        , name ++ " deploy          Upload/deploy your site"
         ]
 
 -- | Preview the site
@@ -109,3 +112,10 @@
     staticServer destination preServeHook port
   where
     preServeHook _ = return ()
+
+-- Upload the site
+--
+deploy :: HakyllConfiguration -> IO ()
+deploy conf = do
+    _ <- system $ deployCommand conf
+    return ()
diff --git a/src/Hakyll/Web/Feed.hs b/src/Hakyll/Web/Feed.hs
--- a/src/Hakyll/Web/Feed.hs
+++ b/src/Hakyll/Web/Feed.hs
@@ -47,7 +47,7 @@
       feedAuthorName  :: String
     , -- | Absolute root URL of the feed site (e.g. @http://jaspervdj.be@)
       feedRoot        :: String
-    }
+    } deriving (Show, Eq)
 
 -- | This is an auxiliary function to create a listing that is, in fact, a feed.
 -- The items should be sorted on date. The @$timestamp@ field should be set.
diff --git a/src/Hakyll/Web/Page.hs b/src/Hakyll/Web/Page.hs
--- a/src/Hakyll/Web/Page.hs
+++ b/src/Hakyll/Web/Page.hs
@@ -58,6 +58,7 @@
     , pageCompiler
     , pageCompilerWith
     , pageCompilerWithPandoc
+    , pageCompilerWithFields
     , addDefaultFields
     ) where
 
@@ -108,10 +109,24 @@
 pageCompilerWithPandoc :: ParserState -> WriterOptions
                        -> (Pandoc -> Pandoc)
                        -> Compiler Resource (Page String)
-pageCompilerWithPandoc state options f = cached "pageCompilerWithPandoc" $
-    readPageCompiler >>> addDefaultFields >>> arr applySelf
+pageCompilerWithPandoc state options f =
+    pageCompilerWithFields state options f id
+
+-- | This is another, even more advanced version of 'pageCompilerWithPandoc'.
+-- This function allows you to provide an arrow which is applied before the
+-- fields in a page are rendered. This means you can use this extra customizable
+-- stage to add custom fields which are inserted in the page.
+--
+pageCompilerWithFields :: ParserState -> WriterOptions
+                       -> (Pandoc -> Pandoc)
+                       -> Compiler (Page String) (Page String)
+                       -> Compiler Resource (Page String)
+pageCompilerWithFields state options f g = cached cacheName $
+    readPageCompiler >>> addDefaultFields >>> g >>> arr applySelf
                      >>> pageReadPandocWith state
                      >>> arr (fmap (writePandocWith options . f))
+  where
+    cacheName = "Hakyll.Web.Page.pageCompilerWithFields"
 
 -- | Add a number of default metadata fields to a page. These fields include:
 --
diff --git a/src/Hakyll/Web/Page/Metadata.hs b/src/Hakyll/Web/Page/Metadata.hs
--- a/src/Hakyll/Web/Page/Metadata.hs
+++ b/src/Hakyll/Web/Page/Metadata.hs
@@ -6,6 +6,7 @@
     , setField
     , trySetField
     , setFieldA
+    , setFieldPage
     , renderField
     , changeField
     , copyField
@@ -17,7 +18,7 @@
 
 import Prelude hiding (id)
 import Control.Category (id)
-import Control.Arrow (Arrow, (>>>), (***), arr)
+import Control.Arrow (Arrow, arr, (>>>), (***), (&&&))
 import Data.List (intercalate)
 import Data.Maybe (fromMaybe)
 import Data.Time.Clock (UTCTime)
@@ -28,6 +29,8 @@
 
 import Hakyll.Web.Page.Internal
 import Hakyll.Core.Util.String
+import Hakyll.Core.Identifier
+import Hakyll.Core.Compiler
 
 -- | Get a metadata field. If the field does not exist, the empty string is
 -- returned.
@@ -68,6 +71,13 @@
           -> a x String              -- ^ Value arrow
           -> a (Page b, x) (Page b)  -- ^ Resulting arrow
 setFieldA k v = id *** v >>> arr (uncurry $ flip $ setField k)
+
+-- | Set a field of a page to the contents of another page
+--
+setFieldPage :: String                      -- ^ Key to add the page under
+             -> Identifier (Page String)    -- ^ Page to add
+             -> Compiler (Page a) (Page a)  -- ^ Page compiler
+setFieldPage key page = id &&& require_ page >>> setFieldA key (arr pageBody)
 
 -- | Do something with a metadata value, but keep the old value as well. If the
 -- key given is not present in the metadata, nothing will happen. If the source
diff --git a/src/Hakyll/Web/Preview/Server.hs b/src/Hakyll/Web/Preview/Server.hs
--- a/src/Hakyll/Web/Preview/Server.hs
+++ b/src/Hakyll/Web/Preview/Server.hs
@@ -6,56 +6,27 @@
     ) where
 
 import Control.Monad.Trans (liftIO)
-import Control.Applicative ((<$>))
-import Codec.Binary.UTF8.String
-import Network.HTTP.Base (urlDecode)
-import System.FilePath ((</>))
-import System.Directory (doesFileExist)
 
-import qualified Data.ByteString as SB
-import Snap.Util.FileServe (serveFile)
-import Snap.Types (Snap, rqURI, getRequest, writeBS)
-import Snap.Http.Server ( httpServe, setAccessLog, setErrorLog, addListen
-                        , ConfigListen (..), emptyConfig
+import Snap.Types (Snap)
+import Snap.Util.FileServe ( DirectoryConfig (..), fancyDirectoryConfig
+                           , serveDirectoryWith
+                           )
+import Snap.Http.Server ( httpServe, setAccessLog, setErrorLog
+                        , setPort, emptyConfig
                         )
 
-import Hakyll.Core.Util.String (replaceAll)
-
--- | The first file in the list that actually exists is returned
---
-findFile :: [FilePath] -> IO (Maybe FilePath)
-findFile [] = return Nothing
-findFile (x : xs) = do
-    exists <- doesFileExist x
-    if exists then return (Just x) else findFile xs
-
 -- | Serve a given directory
 --
 static :: FilePath             -- ^ Directory to serve
        -> (FilePath -> IO ())  -- ^ Pre-serve hook
        -> Snap ()
-static directory preServe = do
-    -- Obtain the path
-    uri <- rqURI <$> getRequest
-    let filePath = replaceAll "\\?.*$"  (const "")  -- Remove trailing ?
-                 $ replaceAll "#[^#]*$" (const "")  -- Remove #section
-                 $ replaceAll "^/"      (const "")  -- Remove leading /
-                 $ urlDecode $ decode $ SB.unpack uri
-
-    -- Try to find the requested file
-    r <- liftIO $ findFile $ map (directory </>) $
-        [ filePath
-        , filePath </> "index.htm"
-        , filePath </> "index.html"
-        ]
-
-    case r of
-        -- Not found, error
-        Nothing -> writeBS "Not found"
-        -- Found, serve
-        Just f  -> do
-            liftIO $ preServe f
-            serveFile f
+static directory preServe =
+    serveDirectoryWith directoryConfig directory
+  where
+    directoryConfig :: DirectoryConfig Snap
+    directoryConfig = fancyDirectoryConfig
+        { preServeHook = liftIO . preServe
+        }
 
 -- | Main method, runs a static server in the given directory
 --
@@ -67,7 +38,7 @@
     httpServe config $ static directory preServe
   where
     -- Snap server config
-    config = addListen (ListenHttp "0.0.0.0" port)
+    config = setPort port
            $ setAccessLog Nothing
            $ setErrorLog Nothing
            $ emptyConfig
