on master help sign in
ContextManipulations → Metadata
commitfef1172c77e510054fc9bf95d5d2b85b8a15478e authorJasper Van der Jeugt <jaspervdj@gmail.com> dateMon 13 Dec 2010, 22:02 (16 years ago) parent0da0dd4
3 files changed+57−66
src/Text/Hakyll/ContextManipulations.hs → src/Text/Hakyll/Metadata.hs+30−46 src/Text/Hakyll/Resource.hs+9−12 src/Text/Hakyll/Transformer.hs+18−8
src/Text/Hakyll/ContextManipulations.hs → src/Text/Hakyll/Metadata.hsrenamed+30−46
@@ -1,5 +1,6 @@
1−-- | This module exports a number of functions that produce @HakyllAction@s to
2−-- manipulate @Context@s.
1+-- | This module exports a number of functions to manipulate metadata of
2+-- resources
3+--
34module Text.Hakyll.ContextManipulations
45 ( renderValue
56 , changeValue
@@ -8,12 +9,8 @@ module Text.Hakyll.ContextManipulations
89 , renderDate
910 , renderDateWithLocale
1011 , changeExtension
11− , renderBody
12− , takeBody
1312 ) where
1413
15−import Control.Monad (liftM)
16−import Control.Arrow (arr)
1714import System.Locale (TimeLocale, defaultTimeLocale)
1815import System.FilePath (takeFileName, addExtension, dropExtension)
1916import Data.Time.Format (parseTime, formatTime)
@@ -22,8 +19,8 @@ import Data.Maybe (fromMaybe)
2219import qualified Data.Map as M
2320
2421import Text.Hakyll.Regex (substituteRegex)
25−import Text.Hakyll.HakyllAction (HakyllAction (..))
26−import Text.Hakyll.Context (Context (..))
22+import Text.Hakyll.Transformer (Transformer (..), transformMetadata)
23+import Text.Hakyll.Resource
2724
2825-- | Do something with a value in a @Context@, but keep the old value as well.
2926-- If the key given is not present in the @Context@, nothing will happen.
@@ -31,35 +28,37 @@ import Text.Hakyll.Context (Context (..))
3128renderValue :: String -- ^ Key of which the value should be copied.
3229 -> String -- ^ Key the value should be copied to.
3330 -> (String -> String) -- ^ Function to apply on the value.
34− -> HakyllAction Context Context
35−renderValue source destination f = arr $ \(Context context) -> Context $
36− case M.lookup source context of
37− Nothing -> context
38− (Just value) -> M.insert destination (f value) context
31+ -> Transformer a a -- ^ Resulting transformer
32+renderValue source destination f = transformMetadata $ \(Metadata m) ->
33+ Metadata $ case M.lookup source m of
34+ Nothing -> m
35+ (Just value) -> M.insert destination (f value) m
3936
40−-- | Change a value in a @Context@.
37+-- | Change a value in the metadata
4138--
4239-- > import Data.Char (toUpper)
4340-- > changeValue "title" (map toUpper)
4441--
4542-- Will put the title in UPPERCASE.
46−changeValue :: String -- ^ Key to change.
47− -> (String -> String) -- ^ Function to apply on the value.
48− -> HakyllAction Context Context
43+changeValue :: String -- ^ Key to change.
44+ -> (String -> String) -- ^ Function to apply on the value.
45+ -> Transformer a a
4946changeValue key = renderValue key key
5047
51−-- | Change the URL of a page. This requires a special function, so dependency
52−-- handling can happen correctly.
48+-- | Change the URL of a page. You should always use this function instead of
49+-- 'changeValue' for this, because using 'changeValue' might break dependency
50+-- handling when changing the @url@ field.
5351--
54−changeUrl :: (String -> String) -- ^ Function to change URL with.
55− -> HakyllAction Context Context -- ^ Resulting action.
56−changeUrl f = let action = changeValue "url" f
57− in action {actionUrl = Right $ liftM f}
52+changeUrl :: (String -> String) -- ^ Function to change URL with.
53+ -> Transformer a a -- ^ Resulting action.
54+changeUrl f = let t = changeValue "url" f
55+ in t {transformerUrl = return . f}
5856
59−-- | Copy a value from one key to another in a @Context@.
60−copyValue :: String -- ^ Source key.
61− -> String -- ^ Destination key.
62− -> HakyllAction Context Context
57+-- | Copy a metadata value from one key to another
58+--
59+copyValue :: String -- ^ Source key.
60+ -> String -- ^ Destination key.
61+ -> Transformer a a -- ^ Resulting transformer
6362copyValue source destination = renderValue source destination id
6463
6564-- | When the context has a key called @path@ in a
@@ -73,7 +72,7 @@ copyValue source destination = renderValue source destination id
7372renderDate :: String -- ^ Key in which the rendered date should be placed.
7473 -> String -- ^ Format to use on the date.
7574 -> String -- ^ Default key, in case the date cannot be parsed.
76− -> HakyllAction Context Context
75+ -> Transformer a a
7776renderDate = renderDateWithLocale defaultTimeLocale
7877
7978-- | This is an extended version of 'renderDate' that allows you to specify a
@@ -84,7 +83,7 @@ renderDateWithLocale :: TimeLocale -- ^ Output time locale.
8483 -> String -- ^ Destination key.
8584 -> String -- ^ Format to use on the date.
8685 -> String -- ^ Default key.
87− -> HakyllAction Context Context
86+ -> Transformer a a
8887renderDateWithLocale locale key format defaultValue =
8988 renderValue "path" key renderDate'
9089 where
@@ -102,23 +101,8 @@ renderDateWithLocale locale key format defaultValue =
102101-- > changeExtension "php"
103102--
104103-- Will render @test.markdown@ to @test.php@ instead of @test.html@.
105−changeExtension :: String -- ^ Extension to change to.
106− -> HakyllAction Context Context
104+changeExtension :: String -- ^ Extension to change to.
105+ -> Transformer a a -- ^ Resulting transformer
107106changeExtension extension = changeValue "url" changeExtension'
108107 where
109108 changeExtension' = flip addExtension extension . dropExtension
110−
111−-- | Change the body of a file using a certain manipulation.
112−--
113−-- > import Data.Char (toUpper)
114−-- > renderBody (map toUpper)
115−--
116−-- Will put the entire body of the page in UPPERCASE.
117−renderBody :: (String -> String)
118− -> HakyllAction Context Context
119−renderBody = renderValue "body" "body"
120−
121−-- | Get the resulting body text from a context
122−--
123−takeBody :: HakyllAction Context String
124−takeBody = arr $ fromMaybe "" . M.lookup "body" . unContext
src/Text/Hakyll/Resource.hs+9−12
@@ -1,21 +1,25 @@
11-- | A resource represents data for a website
22--
3−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
43module Text.Hakyll.Resource
54 ( Metadata (..)
65 , Resource (..)
76 , getData
87 , getMetadata
9− , getMetadataList
108 ) where
119
1210import Data.Monoid (Monoid, mempty, mappend)
1311import Control.Applicative (Applicative, (<*>), pure)
12+import Data.Map (Map)
13+import qualified Data.Map as M
1414
1515-- | Metadata for a resource
1616--
17−newtype Metadata = Metadata {unMetadata :: [(String, String)]}
18− deriving (Show, Eq, Ord, Monoid)
17+newtype Metadata = Metadata {unMetadata :: Map String String}
18+ deriving (Show, Eq, Ord)
19+
20+instance Monoid Metadata where
21+ mempty = Metadata M.empty
22+ (Metadata m1) `mappend` (Metadata m2) = Metadata $ m1 `M.union` m2
1923
2024-- | A resource represents a data source for the website. It contains a value
2125-- and a number of metadata fields
@@ -50,11 +54,4 @@ getData = resourceData
5054-- | Get a metadata field from a resource
5155--
5256getMetadata :: String -> Resource a -> Maybe String
53−getMetadata k (Resource m _) = lookup k $ unMetadata m
54−
55−-- | Get a metadata field from a resource. If multiple fields with the same name
56−-- exist, they will all be returned
57−--
58−getMetadataList :: String -> Resource a -> [String]
59−getMetadataList k = map snd . filter ((== k) . fst)
60− . unMetadata . resourceMetadata
57+getMetadata k (Resource m _) = M.lookup k $ unMetadata m
src/Text/Hakyll/Transformer.hs+18−8
@@ -5,17 +5,17 @@ module Text.Hakyll.Transformer
55 , transformResourceM
66 , transformData
77 , transformDataM
8− , transformMetaData
9− , transformMetaDataM
8+ , transformMetadata
9+ , transformMetadataM
1010 , runTransformer
1111 , runTransformerForced
1212 ) where
1313
14−import Data.Monoid (mappend, mempty)
14+import Data.Monoid (Monoid, mappend, mempty)
1515import Control.Arrow
1616import Control.Category
1717import Control.Applicative ((<$>))
18−import Control.Monad ((<=<), unless)
18+import Control.Monad ((<=<), unless, liftM2)
1919import Prelude hiding ((.), id)
2020
2121import Text.Hakyll.Resource
@@ -34,6 +34,16 @@ data Transformer a b = Transformer
3434 transformerFunction :: Resource a -> Hakyll (Resource b)
3535 }
3636
37+instance Monoid b => Monoid (Transformer a b) where
38+ mempty = arr (const mempty)
39+ mappend x y = Transformer
40+ { transformerDependencies =
41+ transformerDependencies x ++ transformerDependencies y
42+ , transformerUrl = transformerUrl x
43+ , transformerFunction = \r ->
44+ liftM2 mappend (transformerFunction x r) (transformerFunction y r)
45+ }
46+
3747instance Category Transformer where
3848 id = Transformer
3949 { transformerDependencies = []
@@ -70,11 +80,11 @@ transformDataM :: (a -> Hakyll b) -> Transformer a b
7080transformDataM f = transformResourceM $ \(Resource m x) ->
7181 f x >>= return . Resource m
7282
73−transformMetaData :: (Metadata -> Metadata) -> Transformer a a
74−transformMetaData = transformMetaDataM . (return .)
83+transformMetadata :: (Metadata -> Metadata) -> Transformer a a
84+transformMetadata = transformMetadataM . (return .)
7585
76−transformMetaDataM :: (Metadata -> Hakyll Metadata) -> Transformer a a
77−transformMetaDataM f = transformResourceM $ \(Resource m x) -> do
86+transformMetadataM :: (Metadata -> Hakyll Metadata) -> Transformer a a
87+transformMetadataM f = transformResourceM $ \(Resource m x) -> do
7888 m' <- f m
7989 return $ Resource m' x
8090