summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2020-06-03 22:14:24 +0200
committerIgor Pashev <pashev.igor@gmail.com>2020-06-04 11:05:30 +0200
commit6cf0ca7f96a3fba72bf42dab0e1add1b62e3f580 (patch)
tree3c5e87c301fb2fcd7c7d9adccfd0c00cb230aad1 /lib
parent0a6e7a246b64d066ae75156d3adeaa49633c5ee6 (diff)
downloadhakyll-6cf0ca7f96a3fba72bf42dab0e1add1b62e3f580.tar.gz
Allow specifying a metadata provider
In addition to parsing metadata header & metadata files it will allow any custom routine to extract metadata from the resource files, for example with Pandoc
Diffstat (limited to 'lib')
-rw-r--r--lib/Hakyll/Core/Configuration.hs20
-rw-r--r--lib/Hakyll/Core/Provider.hs16
-rw-r--r--lib/Hakyll/Core/Provider/Internal.hs10
-rw-r--r--lib/Hakyll/Core/Provider/Metadata.hs5
-rw-r--r--lib/Hakyll/Core/Runtime.hs4
5 files changed, 38 insertions, 17 deletions
diff --git a/lib/Hakyll/Core/Configuration.hs b/lib/Hakyll/Core/Configuration.hs
index 52b23ec..4e32caa 100644
--- a/lib/Hakyll/Core/Configuration.hs
+++ b/lib/Hakyll/Core/Configuration.hs
@@ -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
@@ -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
}
--------------------------------------------------------------------------------
@@ -98,6 +103,7 @@ defaultConfiguration = Configuration
, inMemoryCache = True
, previewHost = "127.0.0.1"
, previewPort = 8000
+ , provideMetadata = const (return mempty)
}
where
ignoreFile' path
diff --git a/lib/Hakyll/Core/Provider.hs b/lib/Hakyll/Core/Provider.hs
index 384f5b1..65e1507 100644
--- a/lib/Hakyll/Core/Provider.hs
+++ b/lib/Hakyll/Core/Provider.hs
@@ -5,6 +5,7 @@ module Hakyll.Core.Provider
( -- * Constructing resource providers
Internal.Provider
, newProvider
+ , newProvider'
-- * Querying resource properties
, Internal.resourceList
@@ -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
diff --git a/lib/Hakyll/Core/Provider/Internal.hs b/lib/Hakyll/Core/Provider/Internal.hs
index c298653..777decb 100644
--- a/lib/Hakyll/Core/Provider/Internal.hs
+++ b/lib/Hakyll/Core/Provider/Internal.hs
@@ -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
@@ -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
@@ -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"]
diff --git a/lib/Hakyll/Core/Provider/Metadata.hs b/lib/Hakyll/Core/Provider/Metadata.hs
index c74627b..1630b0c 100644
--- a/lib/Hakyll/Core/Provider/Metadata.hs
+++ b/lib/Hakyll/Core/Provider/Metadata.hs
@@ -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)
--------------------------------------------------------------------------------
@@ -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
diff --git a/lib/Hakyll/Core/Runtime.hs b/lib/Hakyll/Core/Runtime.hs
index 922b676..68970cd 100644
--- a/lib/Hakyll/Core/Runtime.hs
+++ b/lib/Hakyll/Core/Runtime.hs
@@ -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