implement sourcing of timestamp files
This commit is contained in:
parent
73d1920b62
commit
c86ece1433
5
Types.hs
5
Types.hs
|
@ -58,6 +58,7 @@ data SiteState =
|
||||||
, _redirectTemplate :: FilePath -- ^ Name of the template for redirect pages
|
, _redirectTemplate :: FilePath -- ^ Name of the template for redirect pages
|
||||||
, _tagTemplate :: FilePath -- ^ Name of the template for category pages
|
, _tagTemplate :: FilePath -- ^ Name of the template for category pages
|
||||||
, _listTemplate :: FilePath -- ^ Name of the template for listing pages
|
, _listTemplate :: FilePath -- ^ Name of the template for listing pages
|
||||||
|
, _timestampSuffix :: FilePath -- ^ File to search for a timestamp (e.g., if the prefix is ".ts", a timestamp for file "page.md" will be looked for in "page.md.ts"). These are best autogenerated with a script that sources the data from git or so.
|
||||||
, _urlBase :: FilePath -- ^ "Root route" to prepend to all absolute links.
|
, _urlBase :: FilePath -- ^ "Root route" to prepend to all absolute links.
|
||||||
, _dumpFinalState :: Bool -- ^ Triggers printing out the structure when the processing finishes.
|
, _dumpFinalState :: Bool -- ^ Triggers printing out the structure when the processing finishes.
|
||||||
}
|
}
|
||||||
|
@ -128,6 +129,10 @@ siteOptions' = do
|
||||||
strOption $
|
strOption $
|
||||||
long "url-base" <>
|
long "url-base" <>
|
||||||
short 'u' <> help "Base absolute URL" <> value "/" <> showDefault
|
short 'u' <> help "Base absolute URL" <> value "/" <> showDefault
|
||||||
|
_timestampSuffix <-
|
||||||
|
strOption $
|
||||||
|
long "timestamp-prefix" <>
|
||||||
|
help "Timestamp file suffix for markdowns" <> value ".timestamp" <> showDefault
|
||||||
_dumpFinalState <-
|
_dumpFinalState <-
|
||||||
switch $
|
switch $
|
||||||
long "dump-state" <>
|
long "dump-state" <>
|
||||||
|
|
|
@ -11,6 +11,7 @@ executable site
|
||||||
, bytestring
|
, bytestring
|
||||||
, containers
|
, containers
|
||||||
, data-default
|
, data-default
|
||||||
|
, directory
|
||||||
, extra
|
, extra
|
||||||
, filepath
|
, filepath
|
||||||
, hakyll == 4.16.*
|
, hakyll == 4.16.*
|
||||||
|
@ -23,8 +24,8 @@ executable site
|
||||||
, pandoc
|
, pandoc
|
||||||
, pandoc-types
|
, pandoc-types
|
||||||
, parsec
|
, parsec
|
||||||
, SHA
|
|
||||||
, scientific
|
, scientific
|
||||||
|
, SHA
|
||||||
, text
|
, text
|
||||||
, transformers
|
, transformers
|
||||||
, yaml
|
, yaml
|
||||||
|
|
31
site.hs
31
site.hs
|
@ -4,7 +4,7 @@
|
||||||
module Main where
|
module Main where
|
||||||
|
|
||||||
import Control.Monad ((>=>), filterM, join, unless, when)
|
import Control.Monad ((>=>), filterM, join, unless, when)
|
||||||
import Control.Monad.Extra (whenM)
|
import Control.Monad.Extra (ifM, whenM)
|
||||||
import Control.Monad.Trans.State.Lazy
|
import Control.Monad.Trans.State.Lazy
|
||||||
import qualified Data.Aeson as AE
|
import qualified Data.Aeson as AE
|
||||||
import qualified Data.Aeson.Key as K
|
import qualified Data.Aeson.Key as K
|
||||||
|
@ -27,10 +27,13 @@ import Lens.Micro
|
||||||
import Lens.Micro.Aeson
|
import Lens.Micro.Aeson
|
||||||
import Lens.Micro.Mtl
|
import Lens.Micro.Mtl
|
||||||
import qualified Options.Applicative
|
import qualified Options.Applicative
|
||||||
|
import System.Directory (doesFileExist)
|
||||||
import System.FilePath
|
import System.FilePath
|
||||||
( (</>)
|
( (</>)
|
||||||
, isAbsolute
|
, isAbsolute
|
||||||
|
, joinPath
|
||||||
, splitDirectories
|
, splitDirectories
|
||||||
|
, splitFileName
|
||||||
, splitPath
|
, splitPath
|
||||||
, takeDirectory
|
, takeDirectory
|
||||||
, takeFileName
|
, takeFileName
|
||||||
|
@ -171,6 +174,24 @@ addGlobalMeta (Y.Object m) = do
|
||||||
r <- fromString <$> use urlBase
|
r <- fromString <$> use urlBase
|
||||||
pure . Y.Object $ KM.insert "root" r m
|
pure . Y.Object $ KM.insert "root" r m
|
||||||
|
|
||||||
|
-- | Get the expected timestamp file for a given filepath
|
||||||
|
timestampFile :: FilePath -> Site FilePath
|
||||||
|
timestampFile fp = do
|
||||||
|
sfx <- use timestampSuffix
|
||||||
|
pure . uncurry (</>) . fmap (++ sfx) . splitFileName $ fp
|
||||||
|
|
||||||
|
-- | If a timestamp file for the page exists, add the timestamp metadata.
|
||||||
|
addTimeMeta :: PageInfo -> Y.Value -> Site Y.Value
|
||||||
|
addTimeMeta pi m'@(Y.Object m) = do
|
||||||
|
tspath <- timestampFile $ pi ^. pagePath
|
||||||
|
io $
|
||||||
|
ifM
|
||||||
|
(doesFileExist tspath)
|
||||||
|
(do putStrLn $ "timestamp <- " ++ tspath
|
||||||
|
ts <- Y.String <$> TIO.readFile tspath
|
||||||
|
pure . Y.Object $ KM.insert "timestamp" ts m)
|
||||||
|
(pure m')
|
||||||
|
|
||||||
-- | Add page-specific information to the metadata. In this instance, this just
|
-- | Add page-specific information to the metadata. In this instance, this just
|
||||||
-- expands the tags for rendering. Eventually would be nice to have the timestamps
|
-- expands the tags for rendering. Eventually would be nice to have the timestamps
|
||||||
-- and possibly other info sourced right here.
|
-- and possibly other info sourced right here.
|
||||||
|
@ -182,7 +203,7 @@ addPageMeta pi (Y.Object m) = do
|
||||||
_String .
|
_String .
|
||||||
to T.unpack .
|
to T.unpack .
|
||||||
to splitDirectories
|
to splitDirectories
|
||||||
pure . Y.Object $ KM.insert "htags" (Y.array htagMeta) m
|
addTimeMeta pi . Y.Object $ KM.insert "htags" (Y.array htagMeta) m
|
||||||
|
|
||||||
-- | If viable for a page (by config), add the TOC field
|
-- | If viable for a page (by config), add the TOC field
|
||||||
addTOC :: PageInfo -> Text.Pandoc.Definition.Pandoc -> Y.Value -> Site Y.Value
|
addTOC :: PageInfo -> Text.Pandoc.Definition.Pandoc -> Y.Value -> Site Y.Value
|
||||||
|
@ -358,7 +379,7 @@ listFilename tag = indexFilename $ "list" </> tag
|
||||||
|
|
||||||
-- | Fold the hierarchical tag bits to a slashed path.
|
-- | Fold the hierarchical tag bits to a slashed path.
|
||||||
tagPath :: [String] -> FilePath
|
tagPath :: [String] -> FilePath
|
||||||
tagPath = foldr (</>) ""
|
tagPath = joinPath
|
||||||
|
|
||||||
-- | Make a link to the tag page
|
-- | Make a link to the tag page
|
||||||
tagLink :: [String] -> Site FilePath
|
tagLink :: [String] -> Site FilePath
|
||||||
|
@ -366,11 +387,11 @@ tagLink = rootUrl . ("tag" </>) . tagPath
|
||||||
|
|
||||||
-- | Fold the hierarchical tag bits to a slashed path.
|
-- | Fold the hierarchical tag bits to a slashed path.
|
||||||
listPath :: [String] -> FilePath
|
listPath :: [String] -> FilePath
|
||||||
listPath = foldr (</>) ""
|
listPath = joinPath
|
||||||
|
|
||||||
-- | Make a link to the tag page
|
-- | Make a link to the tag page
|
||||||
listLink :: [String] -> Site FilePath
|
listLink :: [String] -> Site FilePath
|
||||||
listLink = rootUrl . ("list" </>) . tagPath
|
listLink = rootUrl . ("list" </>) . listPath
|
||||||
|
|
||||||
-- | Make metadata for printing out a single hierarchical tag (all levels clickable)
|
-- | Make metadata for printing out a single hierarchical tag (all levels clickable)
|
||||||
makeHTagMeta :: ([String] -> Site FilePath) -> [String] -> Site Y.Value
|
makeHTagMeta :: ([String] -> Site FilePath) -> [String] -> Site Y.Value
|
||||||
|
|
|
@ -22,33 +22,5 @@
|
||||||
<main>
|
<main>
|
||||||
<div class="flex-sidefill-l"></div>
|
<div class="flex-sidefill-l"></div>
|
||||||
<div class="content-holder">
|
<div class="content-holder">
|
||||||
<div class="sidebox">
|
{{> sidebox.html}}
|
||||||
<div class="sidebox-right">
|
|
||||||
<a href="{{root}}">Home</a>
|
|
||||||
|
|
|
||||||
<a href="{{root}}tag">Categories</a>
|
|
||||||
|
|
|
||||||
<a href="{{root}}search">Search</a>
|
|
||||||
</div>
|
|
||||||
{{?htags}}
|
|
||||||
<div class="sidebox-header">
|
|
||||||
Card categories
|
|
||||||
</div>
|
|
||||||
<div class="sidebox-values">
|
|
||||||
<ul>
|
|
||||||
{{#htags}}
|
|
||||||
<li class="sidebox-tag">{{#.}}<a href="{{href}}">{{^tag}}all{{/tag}}{{?tag}} » {{tag}}{{/tag}}{{/.}}</a></li>
|
|
||||||
{{/htags}}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
{{/htags}}
|
|
||||||
{{?toc}}
|
|
||||||
<div class="sidebox-header">
|
|
||||||
Card outline
|
|
||||||
</div>
|
|
||||||
<div class="sidebox-values sidebox-toc">
|
|
||||||
{{{toc}}}
|
|
||||||
</div>
|
|
||||||
{{/toc}}
|
|
||||||
</div>
|
|
||||||
<div class="content width-content">
|
<div class="content width-content">
|
||||||
|
|
37
templates/sidebox.html
Normal file
37
templates/sidebox.html
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<div class="sidebox">
|
||||||
|
<div class="sidebox-right">
|
||||||
|
<a href="{{root}}">Home</a>
|
||||||
|
|
|
||||||
|
<a href="{{root}}tag">Categories</a>
|
||||||
|
|
|
||||||
|
<a href="{{root}}search">Search</a>
|
||||||
|
</div>
|
||||||
|
{{?htags}}
|
||||||
|
<div class="sidebox-header">
|
||||||
|
Card categories
|
||||||
|
</div>
|
||||||
|
<div class="sidebox-values">
|
||||||
|
<ul>
|
||||||
|
{{#htags}}
|
||||||
|
<li class="sidebox-tag">{{#.}}<a href="{{href}}">{{^tag}}all{{/tag}}{{?tag}} » {{tag}}{{/tag}}{{/.}}</a></li>
|
||||||
|
{{/htags}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{{/htags}}
|
||||||
|
{{?toc}}
|
||||||
|
<div class="sidebox-header">
|
||||||
|
Card outline
|
||||||
|
</div>
|
||||||
|
<div class="sidebox-values sidebox-toc">
|
||||||
|
{{{toc}}}
|
||||||
|
</div>
|
||||||
|
{{/toc}}
|
||||||
|
{{?timestamp}}
|
||||||
|
<div class="sidebox-header">
|
||||||
|
Last modification
|
||||||
|
</div>
|
||||||
|
<div class="sidebox-values sidebox-toc">
|
||||||
|
{{timestamp}}
|
||||||
|
</div>
|
||||||
|
{{/timestamp}}
|
||||||
|
</div>
|
Loading…
Reference in a new issue