Merge branch 'mk-modification-timestamps' into 'master'
add a script for sourcing the timestamps from gits Closes #2 See merge request R3-core/websites-dev/reploy!3
This commit is contained in:
		
						commit
						2ea84315db
					
				| 
						 | 
					@ -18,6 +18,8 @@ build:
 | 
				
			||||||
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
 | 
					    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
 | 
				
			||||||
    - docker build -t $CI_REGISTRY_IMAGE:latest .
 | 
					    - docker build -t $CI_REGISTRY_IMAGE:latest .
 | 
				
			||||||
    - docker push $CI_REGISTRY_IMAGE:latest
 | 
					    - docker push $CI_REGISTRY_IMAGE:latest
 | 
				
			||||||
 | 
					    - docker tag $CI_REGISTRY_IMAGE:latest $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
 | 
				
			||||||
 | 
					    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
 | 
				
			||||||
  rules:
 | 
					  rules:
 | 
				
			||||||
    - if: '$CI_COMMIT_REF_NAME == "master"'
 | 
					    - if: '$CI_COMMIT_REF_NAME == "master"'
 | 
				
			||||||
  tags:
 | 
					  tags:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										6
									
								
								Types.hs
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								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,11 @@ 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" <>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,8 @@
 | 
				
			||||||
mount: /404
 | 
					mount: /404
 | 
				
			||||||
title: Page not found
 | 
					title: Page not found
 | 
				
			||||||
search: off
 | 
					search: off
 | 
				
			||||||
 | 
					toc: off
 | 
				
			||||||
 | 
					timestamp: null
 | 
				
			||||||
---
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Page not found!
 | 
					# Page not found!
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,6 +3,7 @@ mount: /
 | 
				
			||||||
title: Home
 | 
					title: Home
 | 
				
			||||||
template: index.html
 | 
					template: index.html
 | 
				
			||||||
toc: off
 | 
					toc: off
 | 
				
			||||||
 | 
					timestamp: null
 | 
				
			||||||
---
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#### What are How-To Cards?
 | 
					#### What are How-To Cards?
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,6 +4,7 @@ title: Search
 | 
				
			||||||
template: search.html
 | 
					template: search.html
 | 
				
			||||||
search: off
 | 
					search: off
 | 
				
			||||||
toc: off
 | 
					toc: off
 | 
				
			||||||
 | 
					timestamp: null
 | 
				
			||||||
---
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Search
 | 
					# Search
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,7 +11,7 @@
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Usage:
 | 
					 * Usage:
 | 
				
			||||||
 * site ....some args.... --search-data-output tmp/search-raw.json
 | 
					 * site ....some args.... --search-data-output tmp/search-raw.json
 | 
				
			||||||
 * node make-search-index.js tmp/search-raw.json _site/search-index.json _site/search-metadata.json
 | 
					 * node scripts/make-search-index.js tmp/search-raw.json _site/search-index.json _site/search-metadata.json
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lunr = require("lunr")
 | 
					lunr = require("lunr")
 | 
				
			||||||
							
								
								
									
										28
									
								
								scripts/source-timestamps.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										28
									
								
								scripts/source-timestamps.sh
									
									
									
									
									
										Executable file
									
								
							| 
						 | 
					@ -0,0 +1,28 @@
 | 
				
			||||||
 | 
					#!/bin/sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# change this with environment
 | 
				
			||||||
 | 
					DEFAULT_NOT_SOURCE_REGEX="/\\/assets\\//"
 | 
				
			||||||
 | 
					NOT_SOURCE_REGEX="${NOT_SOURCE_REGEX:-$DEFAULT_NOT_SOURCE_REGEX}"
 | 
				
			||||||
 | 
					TIMESTAMP_SUFFIX="${SUFFIX:-.timestamp}"
 | 
				
			||||||
 | 
					LOGFILE="${LOGFILE:-/dev/null}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[ -z "$1" ] && echo "$0: no inputs specified?" >/dev/stderr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					while [ -n "$1" ]
 | 
				
			||||||
 | 
					do
 | 
				
			||||||
 | 
						echo "sourcing directory '$1' ..." >> "$LOGFILE"
 | 
				
			||||||
 | 
						find "$1" -type f -name '*.md' | grep -v "$NOT_SOURCE_REGEX" | while read file ; do
 | 
				
			||||||
 | 
							fn=`basename "$file"`
 | 
				
			||||||
 | 
							dir=`dirname "$file"`
 | 
				
			||||||
 | 
							tsfn="$fn.timestamp"
 | 
				
			||||||
 | 
							(
 | 
				
			||||||
 | 
								echo "making timestamp in '$dir' for file '$fn' ..." >> "$LOGFILE"
 | 
				
			||||||
 | 
								cd "$dir"
 | 
				
			||||||
 | 
								if [ -f "$tsfn" ]
 | 
				
			||||||
 | 
								then echo "... but it already exists; skipping!" >> "$LOGFILE"
 | 
				
			||||||
 | 
								else git log -n 1 --pretty=format:%cs -- "$fn" > "$tsfn"
 | 
				
			||||||
 | 
								fi
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
						done
 | 
				
			||||||
 | 
						shift
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
							
								
								
									
										33
									
								
								site.hs
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								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,26 @@ 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)
 | 
				
			||||||
 | 
					  | "timestamp" `KM.member` m = pure m' -- do not overwrite the timestamp if present
 | 
				
			||||||
 | 
					  | otherwise = 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 +205,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 +381,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 +389,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