Discussion:
[hakyll] time format support
Yun
2015-04-22 16:19:44 UTC
Permalink
Hello,

I am new to Haskell, so this question may be stupid. But I really need some
help.

My problem is:

I would like to use time format like: 2015-02-03 14:23, because I have some
old posts using this format and I don't want to change them.

I guess I should modify the `getItemUTC` function for this purpose. So I
add the following lines to my `site.hs`

```haskell
myDateField :: String -> String -> Context a
myDateField key format = field key $ \i -> do
time <- myGetItemUTC locale $ itemIdentifier i
return $ formatTime locale format time
where
locale = defaultTimeLocale

myGetItemUTC :: MonadMetadata m => TimeLocale -> Identifier -> m UTCTime
myGetItemUTC locale id' = do
metadata <- getMetadata id'
let tryField k fmt = M.lookup k metadata >>= parseTime' fmt
paths = splitDirectories $ toFilePath id'
maybe empty' return $ msum $
[tryField "published" fmt | fmt <- formats] ++
[tryField "date" fmt | fmt <- formats] ++
[parseTime' "%Y-%m-%d" $ intercalate "-" $ take 3 $ splitAll "-"
fnCand | fnCand <- reverse paths]
where
empty' = fail $ "myGetItemUTC: " ++
"could not parse time for " ++ show id'
parseTime' = parseTime locale
formats =
[ "%a, %d %b %Y %H:%M:%S %Z"
, "%Y-%m-%dT%H:%M:%S%Z"
, "%Y-%m-%d %H:%M:%S%Z"
, "%Y-%m-%d %H:%M"
, "%Y-%m-%d"
, "%B %e, %Y %l:%M %p"
, "%B %e, %Y"
, "%b %d, %Y"
]

----------------------------------------------------------

updateDateField :: String -- ^ Key in which the rendered date should be
placed
-> String -- ^ Format to use on the date
-> Context a -- ^ Resulting context
updateDateField = updateDateFieldWith defaultTimeLocale

updateDateFieldWith :: TimeLocale -- ^ Output time locale
-> String -- ^ Destination key
-> String -- ^ Format to use on the date
-> Context a -- ^ Resulting context
updateDateFieldWith locale key format = field key $ \i -> do
time <- getUpdatedTime locale $ itemIdentifier i
return $ formatTime locale format time

getUpdatedTime :: MonadMetadata m
=> TimeLocale -- ^ Output time locale
-> Identifier -- ^ Input page
-> m UTCTime -- ^ Parsed UTCTime
getUpdatedTime locale id' = do
metadata <- getMetadata id'
let tryField k fmt = M.lookup k metadata >>= parseTime' fmt

maybe empty' return $ msum $
[tryField "updated" fmt | fmt <- formats] ++
[tryField "edited" fmt | fmt <- formats]
where
empty' = fail $ "getUpdatedTime: " ++
"could not parse time for " ++ show id'
parseTime' = parseTime locale
formats =
[ "%a, %d %b %Y %H:%M:%S %Z"
, "%Y-%m-%dT%H:%M:%S%Z"
, "%Y-%m-%d %H:%M:%S%Z"
, "%Y-%m-%d %H:%M"
, "%Y-%m-%d"
, "%B %e, %Y %l:%M %p"
, "%B %e, %Y"
, "%b %d, %Y"
]
```

In fact I did noting but change the name of the functions and add

, "%Y-%m-%d %H:%M"

to the `formats`.

Of course, I changed the `dateField` to `myDateField` in the block
`postCtx` and also added `updateDateField` to it.

But now it comes the problem.

The function `updateDateField` works fine for me. If I have a metadata
`updated: 2015-04-25 14:30`, I would get my desired result in my page.
However, If I use `published: 2015-04-25 14:30`, I will get an error:

Hakyll.Web.Template.Context.getItemUTC: could not parse time for posts

But as far as I know, I didn't use the original `getItemUTC` function. I
don't know why it still called that function. I thought if there is
something wrong it will give me the error

myGetItemUTC: could not parse time for posts

because I have changed the error message in my `myGetItemUTC` function. I
really cannot understand what's wrong with my code.


Please help me! Thank you!

Best regards,
Y
--
You received this message because you are subscribed to the Google Groups "hakyll" group.
To unsubscribe from this group and stop receiving emails from it, send an email to hakyll+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Yun
2015-04-23 00:01:23 UTC
Permalink
Finally I solved the problem myself.

The problem is the `recentFirst` uses the original `getItemUTC`. So I have
to modify this function too,.
Post by Yun
Hello,
I am new to Haskell, so this question may be stupid. But I really need
some help.
I would like to use time format like: 2015-02-03 14:23, because I have
some old posts using this format and I don't want to change them.
I guess I should modify the `getItemUTC` function for this purpose. So I
add the following lines to my `site.hs`
```haskell
myDateField :: String -> String -> Context a
myDateField key format = field key $ \i -> do
time <- myGetItemUTC locale $ itemIdentifier i
return $ formatTime locale format time
where
locale = defaultTimeLocale
myGetItemUTC :: MonadMetadata m => TimeLocale -> Identifier -> m UTCTime
myGetItemUTC locale id' = do
metadata <- getMetadata id'
let tryField k fmt = M.lookup k metadata >>= parseTime' fmt
paths = splitDirectories $ toFilePath id'
maybe empty' return $ msum $
[tryField "published" fmt | fmt <- formats] ++
[tryField "date" fmt | fmt <- formats] ++
[parseTime' "%Y-%m-%d" $ intercalate "-" $ take 3 $ splitAll "-"
fnCand | fnCand <- reverse paths]
where
empty' = fail $ "myGetItemUTC: " ++
"could not parse time for " ++ show id'
parseTime' = parseTime locale
formats =
[ "%a, %d %b %Y %H:%M:%S %Z"
, "%Y-%m-%dT%H:%M:%S%Z"
, "%Y-%m-%d %H:%M:%S%Z"
, "%Y-%m-%d %H:%M"
, "%Y-%m-%d"
, "%B %e, %Y %l:%M %p"
, "%B %e, %Y"
, "%b %d, %Y"
]
----------------------------------------------------------
updateDateField :: String -- ^ Key in which the rendered date should
be placed
-> String -- ^ Format to use on the date
-> Context a -- ^ Resulting context
updateDateField = updateDateFieldWith defaultTimeLocale
updateDateFieldWith :: TimeLocale -- ^ Output time locale
-> String -- ^ Destination key
-> String -- ^ Format to use on the date
-> Context a -- ^ Resulting context
updateDateFieldWith locale key format = field key $ \i -> do
time <- getUpdatedTime locale $ itemIdentifier i
return $ formatTime locale format time
getUpdatedTime :: MonadMetadata m
=> TimeLocale -- ^ Output time locale
-> Identifier -- ^ Input page
-> m UTCTime -- ^ Parsed UTCTime
getUpdatedTime locale id' = do
metadata <- getMetadata id'
let tryField k fmt = M.lookup k metadata >>= parseTime' fmt
maybe empty' return $ msum $
[tryField "updated" fmt | fmt <- formats] ++
[tryField "edited" fmt | fmt <- formats]
where
empty' = fail $ "getUpdatedTime: " ++
"could not parse time for " ++ show id'
parseTime' = parseTime locale
formats =
[ "%a, %d %b %Y %H:%M:%S %Z"
, "%Y-%m-%dT%H:%M:%S%Z"
, "%Y-%m-%d %H:%M:%S%Z"
, "%Y-%m-%d %H:%M"
, "%Y-%m-%d"
, "%B %e, %Y %l:%M %p"
, "%B %e, %Y"
, "%b %d, %Y"
]
```
In fact I did noting but change the name of the functions and add
, "%Y-%m-%d %H:%M"
to the `formats`.
Of course, I changed the `dateField` to `myDateField` in the block
`postCtx` and also added `updateDateField` to it.
But now it comes the problem.
The function `updateDateField` works fine for me. If I have a metadata
`updated: 2015-04-25 14:30`, I would get my desired result in my page.
Hakyll.Web.Template.Context.getItemUTC: could not parse time for posts
But as far as I know, I didn't use the original `getItemUTC` function. I
don't know why it still called that function. I thought if there is
something wrong it will give me the error
myGetItemUTC: could not parse time for posts
because I have changed the error message in my `myGetItemUTC` function. I
really cannot understand what's wrong with my code.
Please help me! Thank you!
Best regards,
Y
--
You received this message because you are subscribed to the Google Groups "hakyll" group.
To unsubscribe from this group and stop receiving emails from it, send an email to hakyll+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Yun
2015-04-22 16:40:12 UTC
Permalink
I am sorry that I posted the wrong code for my `myDateField`. What I just
posted is is a modification from
http://david.sferruzza.fr/posts/2014-06-18-new-blog-with-hakyll.html. But
the result was the same. (If I understood correctly, this code just makes
`dateField` and `dateFieldWith` into one function. so there won't be any
difference)

my own code is exact the same as `myUpdateField` i just posted, but with
the corresponding function names changed:

myDateField :: String -- ^ Key in which the rendered date should be
placed
-> String -- ^ Format to use on the date
-> Context a -- ^ Resulting context
myDateField = dateFieldWith defaultTimeLocale

myDateFieldWith :: TimeLocale -- ^ Output time locale
-> String -- ^ Destination key
-> String -- ^ Format to use on the date
-> Context a -- ^ Resulting context
myDateFieldWith locale key format = field key $ \i -> do
time <- getItemUTC locale $ itemIdentifier i
return $ formatTime locale format time

myGetItemUTC :: MonadMetadata m
=> TimeLocale -- ^ Output time locale
-> Identifier -- ^ Input page
-> m UTCTime -- ^ Parsed UTCTime
myGetItemUTC locale id' = do
metadata <- getMetadata id'
let tryField k fmt = M.lookup k metadata >>= parseTime' fmt
paths = splitDirectories $ toFilePath id'

maybe empty' return $ msum $
[tryField "published" fmt | fmt <- formats] ++
[tryField "date" fmt | fmt <- formats] ++
[parseTime' "%Y-%m-%d" $ intercalate "-" $ take 3 $ splitAll "-"
fnCand | fnCand <- reverse paths]
where
empty' = fail $ " myGetItemUTC: " ++
"could not parse time for " ++ show id'
parseTime' = parseTime locale
formats =
[ "%a, %d %b %Y %H:%M:%S %Z"
, "%Y-%m-%dT%H:%M:%S%Z"
, "%Y-%m-%d %H:%M:%S%Z"
, "%Y-%m-%d %H:%M"
, "%Y-%m-%d"
, "%B %e, %Y %l:%M %p"
, "%B %e, %Y"
, "%b %d, %Y"
]
--
You received this message because you are subscribed to the Google Groups "hakyll" group.
To unsubscribe from this group and stop receiving emails from it, send an email to hakyll+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...