Skip to content

Commit

Permalink
Allow specifying a metadata provider
Browse files Browse the repository at this point in the history
In addition to parsing metadata header & metadata files it will
allow any custom routing to extract metadata from the resource files,
for example with Pandoc
  • Loading branch information
ip1981 committed Jun 4, 2020
1 parent 8afbb62 commit 35997f6
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 17 deletions.
20 changes: 13 additions & 7 deletions lib/Hakyll/Core/Configuration.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ module Hakyll.Core.Configuration


--------------------------------------------------------------------------------
import Data.Default (Default (..))
import Data.List (isPrefixOf, isSuffixOf)
import System.Directory (canonicalizePath)
import System.Exit (ExitCode)
import System.FilePath (isAbsolute, normalise, takeFileName)
import System.IO.Error (catchIOError)
import System.Process (system)
import Data.Default (Default (..))
import Data.List (isPrefixOf, isSuffixOf)
import System.Directory (canonicalizePath)
import System.Exit (ExitCode)
import System.FilePath (isAbsolute, normalise, takeFileName)
import System.IO.Error (catchIOError)
import System.Process (system)

import Hakyll.Core.Metadata

--------------------------------------------------------------------------------
data Configuration = Configuration
Expand Down Expand Up @@ -78,6 +79,10 @@ data Configuration = Configuration
-- One can also override the port as a command line argument:
-- ./site preview -p 1234
previewPort :: Int
, -- | Function to extract metadata from the files
--
-- By default it returns empty metadata
provideMetadata :: FilePath -> IO Metadata
}

--------------------------------------------------------------------------------
Expand All @@ -98,6 +103,7 @@ defaultConfiguration = Configuration
, inMemoryCache = True
, previewHost = "127.0.0.1"
, previewPort = 8000
, provideMetadata = const (return mempty)
}
where
ignoreFile' path
Expand Down
16 changes: 13 additions & 3 deletions lib/Hakyll/Core/Provider.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module Hakyll.Core.Provider
( -- * Constructing resource providers
Internal.Provider
, newProvider
, newProvider'

-- * Querying resource properties
, Internal.resourceList
Expand All @@ -24,20 +25,29 @@ module Hakyll.Core.Provider


--------------------------------------------------------------------------------
import Hakyll.Core.Metadata
import qualified Hakyll.Core.Provider.Internal as Internal
import qualified Hakyll.Core.Provider.MetadataCache as Internal
import Hakyll.Core.Store (Store)


--------------------------------------------------------------------------------
-- | Create a resource provider
-- | Create a resource provider with the void metadata provider
newProvider :: Store -- ^ Store to use
-> (FilePath -> IO Bool) -- ^ Should we ignore this file?
-> FilePath -- ^ Search directory
-> IO Internal.Provider -- ^ Resulting provider
newProvider store ignore directory = do
newProvider store ignore = newProvider' store ignore (const $ return mempty)

-- | Create a resource provider
newProvider' :: Store -- ^ Store to use
-> (FilePath -> IO Bool) -- ^ Should we ignore this file?
-> (FilePath -> IO Metadata) -- ^ Metadata provider
-> FilePath -- ^ Search directory
-> IO Internal.Provider -- ^ Resulting provider
newProvider' store ignore metadata directory = do
-- Delete metadata cache where necessary
p <- Internal.newProvider store ignore directory
p <- Internal.newProvider store ignore metadata directory
mapM_ (Internal.resourceInvalidateMetadataCache p) $
filter (Internal.resourceModified p) $ Internal.resourceList p
return p
10 changes: 7 additions & 3 deletions lib/Hakyll/Core/Provider/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import System.Time (formatCalendarTime, toCalendarTime)

--------------------------------------------------------------------------------
import Hakyll.Core.Identifier
import Hakyll.Core.Metadata
import Hakyll.Core.Store (Store)
import qualified Hakyll.Core.Store as Store
import Hakyll.Core.Util.File
Expand Down Expand Up @@ -95,16 +96,19 @@ data Provider = Provider
providerOldFiles :: Map Identifier ResourceInfo
, -- | Underlying persistent store for caching
providerStore :: Store
} deriving (Show)
-- | A custom function to extract metadata from files
, providerMetadata :: FilePath -> IO Metadata
}


--------------------------------------------------------------------------------
-- | Create a resource provider
newProvider :: Store -- ^ Store to use
-> (FilePath -> IO Bool) -- ^ Should we ignore this file?
-> (FilePath -> IO Metadata) -- ^ Metadata provider
-> FilePath -- ^ Search directory
-> IO Provider -- ^ Resulting provider
newProvider store ignore directory = do
newProvider store ignore metadata directory = do
list <- map fromFilePath <$> getRecursiveContents ignore directory
let universe = S.fromList list
files <- fmap (maxmtime . M.fromList) $ forM list $ \identifier -> do
Expand All @@ -116,7 +120,7 @@ newProvider store ignore directory = do
oldFiles <- fromMaybe mempty . Store.toMaybe <$> Store.get store oldKey
oldFiles `deepseq` Store.set store oldKey files

return $ Provider directory files oldFiles store
return $ Provider directory files oldFiles store metadata
where
oldKey = ["Hakyll.Core.Provider.Internal.newProvider", "oldFiles"]

Expand Down
5 changes: 3 additions & 2 deletions lib/Hakyll/Core/Provider/Metadata.hs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import Hakyll.Core.Identifier
import Hakyll.Core.Metadata
import Hakyll.Core.Provider.Internal
import System.IO as IO
import System.IO.Error (modifyIOError, ioeSetLocation)
import System.IO.Error (ioeSetLocation, modifyIOError)


--------------------------------------------------------------------------------
Expand All @@ -42,7 +42,8 @@ loadMetadata p identifier = do
Nothing -> return mempty
Just mi' -> loadMetadataFile $ resourceFilePath p mi'

return (md <> emd, body)
mdp <- providerMetadata p fp
return (md <> emd <> mdp, body)
where
normal = setVersion Nothing identifier
fp = resourceFilePath p identifier
Expand Down
4 changes: 2 additions & 2 deletions lib/Hakyll/Core/Runtime.hs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ run config logger rules = do
Logger.message logger "Creating store..."
store <- Store.new (inMemoryCache config) $ storeDirectory config
Logger.message logger "Creating provider..."
provider <- newProvider store (shouldIgnoreFile config) $
providerDirectory config
provider <- newProvider' store (shouldIgnoreFile config) (provideMetadata config)
(providerDirectory config)
Logger.message logger "Running rules..."
ruleSet <- runRules rules provider

Expand Down

0 comments on commit 35997f6

Please sign in to comment.