split tags and ehtags, separate listings from hierarchical views
This commit is contained in:
parent
3b13dd8353
commit
4a7dcc2dbe
14
Types.hs
14
Types.hs
|
@ -36,6 +36,9 @@ data SiteState =
|
||||||
-- | Map of tags, assigning to each tag sequence a list of
|
-- | Map of tags, assigning to each tag sequence a list of
|
||||||
-- tagged page mounts
|
-- tagged page mounts
|
||||||
, _htags :: M.Map [String] [FilePath]
|
, _htags :: M.Map [String] [FilePath]
|
||||||
|
-- | Map of tags, assigning to each tag sequence a list of tagged page
|
||||||
|
-- mounts. This one is expanded (tags imply parent categories).
|
||||||
|
, _ehtags :: M.Map [String] [FilePath]
|
||||||
-- | List of installed files (enables sharing)
|
-- | List of installed files (enables sharing)
|
||||||
, _installs :: S.Set (String, FilePath)
|
, _installs :: S.Set (String, FilePath)
|
||||||
-- | List of installed files (prevents overwriting)
|
-- | List of installed files (prevents overwriting)
|
||||||
|
@ -50,7 +53,8 @@ data SiteState =
|
||||||
, _templateDir :: FilePath -- ^ Path to template directory
|
, _templateDir :: FilePath -- ^ Path to template directory
|
||||||
, _defaultTemplate :: FilePath -- ^ Name of the default template
|
, _defaultTemplate :: FilePath -- ^ Name of the default template
|
||||||
, _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 tag listing pages
|
, _tagTemplate :: FilePath -- ^ Name of the template for category pages
|
||||||
|
, _listTemplate :: FilePath -- ^ Name of the template for listing pages
|
||||||
, _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.
|
||||||
}
|
}
|
||||||
|
@ -105,8 +109,13 @@ siteOptions' = do
|
||||||
_tagTemplate <-
|
_tagTemplate <-
|
||||||
strOption $
|
strOption $
|
||||||
long "tag-template" <>
|
long "tag-template" <>
|
||||||
help "Template for making tag-listing pages" <>
|
help "Template for making category view pages" <>
|
||||||
value "tag.html" <> showDefault
|
value "tag.html" <> showDefault
|
||||||
|
_listTemplate <-
|
||||||
|
strOption $
|
||||||
|
long "list-template" <>
|
||||||
|
help "Template for making tag-listing pages" <>
|
||||||
|
value "list.html" <> showDefault
|
||||||
_urlBase <-
|
_urlBase <-
|
||||||
strOption $
|
strOption $
|
||||||
long "url-base" <>
|
long "url-base" <>
|
||||||
|
@ -121,6 +130,7 @@ siteOptions' = do
|
||||||
{ _pages = M.empty
|
{ _pages = M.empty
|
||||||
, _redirects = M.empty
|
, _redirects = M.empty
|
||||||
, _htags = M.empty
|
, _htags = M.empty
|
||||||
|
, _ehtags = M.empty
|
||||||
, _installs = S.empty
|
, _installs = S.empty
|
||||||
, _targets = S.empty
|
, _targets = S.empty
|
||||||
, _templates = M.empty
|
, _templates = M.empty
|
||||||
|
|
|
@ -13,9 +13,8 @@ redirects:
|
||||||
- internal/internal/publication/codeCheck
|
- internal/internal/publication/codeCheck
|
||||||
tags:
|
tags:
|
||||||
- publication/ppc/code
|
- publication/ppc/code
|
||||||
- code/conventions
|
- it/conventions
|
||||||
- code/licensing
|
- it/licensing
|
||||||
- tto/code
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# How-to: Pass a PPC code check
|
# How-to: Pass a PPC code check
|
||||||
|
|
|
@ -5,11 +5,10 @@ redirects:
|
||||||
- mypage
|
- mypage
|
||||||
- old:mypage
|
- old:mypage
|
||||||
tags:
|
tags:
|
||||||
- yyy
|
- about/test
|
||||||
- topic1/xxx
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# My Page
|
# My Testing Page
|
||||||
|
|
||||||
something something
|
something something
|
||||||
|
|
||||||
|
|
109
site.hs
109
site.hs
|
@ -91,7 +91,8 @@ pageTemplates :: Site [FilePath]
|
||||||
pageTemplates = do
|
pageTemplates = do
|
||||||
rt <- use redirectTemplate
|
rt <- use redirectTemplate
|
||||||
tt <- use tagTemplate
|
tt <- use tagTemplate
|
||||||
nub . ([rt, tt] ++) <$>
|
lt <- use listTemplate
|
||||||
|
nub . ([rt, tt, lt] ++) <$>
|
||||||
(gets (^.. pages . traverse) >>= traverse pageTemplate)
|
(gets (^.. pages . traverse) >>= traverse pageTemplate)
|
||||||
|
|
||||||
-- | Compile a single template in a directory
|
-- | Compile a single template in a directory
|
||||||
|
@ -166,7 +167,8 @@ addGlobalMeta (Y.Object m) = do
|
||||||
addPageMeta :: PageInfo -> Y.Value -> Site Y.Value
|
addPageMeta :: PageInfo -> Y.Value -> Site Y.Value
|
||||||
addPageMeta pi (Y.Object m) = do
|
addPageMeta pi (Y.Object m) = do
|
||||||
htagMeta <-
|
htagMeta <-
|
||||||
traverse makeHTagMeta . sort $ pi ^.. pageMeta . key "tags" . values .
|
traverse (makeHTagMeta tagLink) . sort $ pi ^.. pageMeta . key "tags" .
|
||||||
|
values .
|
||||||
_String .
|
_String .
|
||||||
to T.unpack .
|
to T.unpack .
|
||||||
to splitDirectories
|
to splitDirectories
|
||||||
|
@ -272,18 +274,27 @@ sourceTags = do
|
||||||
(^.. pageMeta . key "tags" . values . _String . to T.unpack)) .
|
(^.. pageMeta . key "tags" . values . _String . to T.unpack)) .
|
||||||
M.assocs <$>
|
M.assocs <$>
|
||||||
use pages
|
use pages
|
||||||
|
ehtags .= M.fromList (invExpandTags sgat)
|
||||||
htags .= M.fromList (invTags sgat)
|
htags .= M.fromList (invTags sgat)
|
||||||
|
|
||||||
-- | Organize a list of pages with hierarchical tags to a list with
|
-- | Organize a list of pages with hierarchical tags to a list with
|
||||||
-- hierarchical tags with pages attached.
|
-- hierarchical tags with pages attached; with tags implying parents.
|
||||||
invTags :: [(FilePath, [[String]])] -> [([String], [FilePath])]
|
invExpandTags :: [(FilePath, [[String]])] -> [([String], [FilePath])]
|
||||||
invTags x =
|
invExpandTags x =
|
||||||
map (fmap nub) $ groupSort [(t, p) | (p, htl) <- x, ht <- htl, t <- inits ht]
|
map (fmap nub) $ groupSort [(t, p) | (p, htl) <- x, ht <- htl, t <- inits ht]
|
||||||
|
|
||||||
|
-- | Like `invExpandTags` but without the expansion.
|
||||||
|
invTags :: [(FilePath, [[String]])] -> [([String], [FilePath])]
|
||||||
|
invTags x = map (fmap nub) $ groupSort [(t, p) | (p, htl) <- x, t <- htl]
|
||||||
|
|
||||||
-- | Get the destination for the tag page.
|
-- | Get the destination for the tag page.
|
||||||
tagFilename :: FilePath -> Site FilePath
|
tagFilename :: FilePath -> Site FilePath
|
||||||
tagFilename tag = indexFilename $ "tag" </> tag
|
tagFilename tag = indexFilename $ "tag" </> tag
|
||||||
|
|
||||||
|
-- | Get the destination for the tag page.
|
||||||
|
listFilename :: FilePath -> Site FilePath
|
||||||
|
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 = foldr (</>) ""
|
||||||
|
@ -292,21 +303,22 @@ tagPath = foldr (</>) ""
|
||||||
tagLink :: [String] -> Site FilePath
|
tagLink :: [String] -> Site FilePath
|
||||||
tagLink = rootUrl . ("tag" </>) . tagPath
|
tagLink = rootUrl . ("tag" </>) . tagPath
|
||||||
|
|
||||||
|
-- | Fold the hierarchical tag bits to a slashed path.
|
||||||
|
listPath :: [String] -> FilePath
|
||||||
|
listPath = foldr (</>) ""
|
||||||
|
|
||||||
|
-- | Make a link to the tag page
|
||||||
|
listLink :: [String] -> Site FilePath
|
||||||
|
listLink = rootUrl . ("list" </>) . tagPath
|
||||||
|
|
||||||
-- | 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 Y.Value
|
makeHTagMeta :: ([String] -> Site FilePath) -> [String] -> Site Y.Value
|
||||||
makeHTagMeta tag = do
|
makeHTagMeta lf tag = do
|
||||||
links <-
|
links <-
|
||||||
zip (Y.Null : map fromString tag) . map fromString <$>
|
zip (Y.Null : map fromString tag) . map fromString <$>
|
||||||
traverse tagLink (inits tag)
|
traverse lf (inits tag)
|
||||||
pure . Y.array $ map (\(t, p) -> Y.object [("tag", t), ("href", p)]) links
|
pure . Y.array $ map (\(t, p) -> Y.object [("tag", t), ("href", p)]) links
|
||||||
|
|
||||||
-- | Make metadata for printing out a single tag as-is, without levels
|
|
||||||
makeHTagLinkMeta :: [String] -> Site Y.Value
|
|
||||||
makeHTagLinkMeta tag = do
|
|
||||||
link <- tagLink tag
|
|
||||||
pure $
|
|
||||||
Y.object [("href", fromString link), ("tags", Y.array $ map fromString tag)]
|
|
||||||
|
|
||||||
-- | Make metadata for printing out a link to a page
|
-- | Make metadata for printing out a link to a page
|
||||||
makePageLinkMeta :: FilePath -> Site Y.Value
|
makePageLinkMeta :: FilePath -> Site Y.Value
|
||||||
makePageLinkMeta mount = do
|
makePageLinkMeta mount = do
|
||||||
|
@ -314,20 +326,55 @@ makePageLinkMeta mount = do
|
||||||
meta <- use $ pages . to (M.! mount) . pageMeta
|
meta <- use $ pages . to (M.! mount) . pageMeta
|
||||||
pure $ Y.object [("href", fromString link), ("meta", meta)]
|
pure $ Y.object [("href", fromString link), ("meta", meta)]
|
||||||
|
|
||||||
-- | Create the complete metadata structure for the template that renders a given tag page
|
-- | Create the complete metadata structure for the template that renders a given categorical tag pages
|
||||||
makeTagMeta :: [String] -> Site Y.Value
|
makeTagMeta :: [String] -> Site Y.Value
|
||||||
makeTagMeta tag = do
|
makeTagMeta tag = do
|
||||||
taggedPages <- use $ htags . to (M.! tag)
|
taggedPages <- use $ htags . to (M.!? tag) . to (maybe [] id)
|
||||||
subtags <-
|
subtags <-
|
||||||
gets
|
gets
|
||||||
(^.. htags . to M.keys . each . filtered (not . null) .
|
(^.. ehtags . to M.keys . each . filtered (not . null) .
|
||||||
filtered ((== tag) . init))
|
filtered ((== tag) . init))
|
||||||
htagMeta <- makeHTagMeta tag
|
htagMeta <- makeHTagMeta tagLink tag
|
||||||
subtagsMeta <- Y.array <$> traverse makeHTagLinkMeta subtags
|
subtagsMeta <- Y.array <$> traverse makeTagMeta subtags
|
||||||
pagesMeta <- Y.array <$> traverse makePageLinkMeta taggedPages
|
pagesMeta <- Y.array <$> traverse makePageLinkMeta taggedPages
|
||||||
|
link <- tagLink tag
|
||||||
|
listlink <- listLink tag
|
||||||
addGlobalMeta $
|
addGlobalMeta $
|
||||||
Y.object
|
Y.object
|
||||||
[("htag", htagMeta), ("subtags", subtagsMeta), ("pages", pagesMeta)]
|
[ ("href", fromString link)
|
||||||
|
, ("tags", Y.array $ map fromString tag)
|
||||||
|
, ("htag", htagMeta)
|
||||||
|
, ("subtags", subtagsMeta)
|
||||||
|
, ("pages", pagesMeta)
|
||||||
|
, ("listhref", fromString listlink)
|
||||||
|
]
|
||||||
|
|
||||||
|
-- | Make metadata for printing out a single tag as-is, without levels
|
||||||
|
makeHTagLinkMeta :: [String] -> Site Y.Value
|
||||||
|
makeHTagLinkMeta tag = do
|
||||||
|
link <- listLink tag
|
||||||
|
pure $
|
||||||
|
Y.object [("href", fromString link), ("tags", Y.array $ map fromString tag)]
|
||||||
|
|
||||||
|
-- | Create the structure for rendering a complete listing of one hierarchical tag.
|
||||||
|
makeListMeta :: [String] -> Site Y.Value
|
||||||
|
makeListMeta tag = do
|
||||||
|
taggedPages <- use $ ehtags . to (M.! tag)
|
||||||
|
subtags <-
|
||||||
|
gets
|
||||||
|
(^.. ehtags . to M.keys . each . filtered (not . null) .
|
||||||
|
filtered ((== tag) . init))
|
||||||
|
htagMeta <- makeHTagMeta listLink tag
|
||||||
|
subtagsMeta <- Y.array <$> traverse makeHTagLinkMeta subtags
|
||||||
|
pagesMeta <- Y.array <$> traverse makePageLinkMeta taggedPages
|
||||||
|
tl <- tagLink tag
|
||||||
|
addGlobalMeta $
|
||||||
|
Y.object
|
||||||
|
[ ("htag", htagMeta)
|
||||||
|
, ("subtags", subtagsMeta)
|
||||||
|
, ("pages", pagesMeta)
|
||||||
|
, ("taghref", fromString tl)
|
||||||
|
]
|
||||||
|
|
||||||
-- | Render a site for a given tag string.
|
-- | Render a site for a given tag string.
|
||||||
renderTag :: [String] -> Site ()
|
renderTag :: [String] -> Site ()
|
||||||
|
@ -344,7 +391,24 @@ renderTag tag = do
|
||||||
|
|
||||||
-- | Render all tag sites.
|
-- | Render all tag sites.
|
||||||
renderTags :: Site ()
|
renderTags :: Site ()
|
||||||
renderTags = use (htags . to M.keys) >>= traverse_ renderTag
|
renderTags = use (ehtags . to M.keys) >>= traverse_ renderTag
|
||||||
|
|
||||||
|
-- | Render a site for a given tag string.
|
||||||
|
renderList :: [String] -> Site ()
|
||||||
|
renderList tag = do
|
||||||
|
tname <- use listTemplate
|
||||||
|
templ <- use $ templates . to (M.! fromString tname)
|
||||||
|
file <- listFilename (listPath tag)
|
||||||
|
checkTarget file
|
||||||
|
meta <- makeListMeta tag
|
||||||
|
io $ do
|
||||||
|
putStrLn $ "* -> " ++ file
|
||||||
|
makeDirectories file
|
||||||
|
checkedSubstitute templ meta >>= TIO.writeFile file
|
||||||
|
|
||||||
|
-- | Render all tag sites.
|
||||||
|
renderLists :: Site ()
|
||||||
|
renderLists = use (ehtags . to M.keys) >>= traverse_ renderList
|
||||||
|
|
||||||
-- | Transform one mounted PageInfo to the base search data
|
-- | Transform one mounted PageInfo to the base search data
|
||||||
mkSearchData :: FilePath -> PageInfo -> Site [Y.Value]
|
mkSearchData :: FilePath -> PageInfo -> Site [Y.Value]
|
||||||
|
@ -388,6 +452,7 @@ main = do
|
||||||
use templateDir >>= sourceTemplates
|
use templateDir >>= sourceTemplates
|
||||||
use pages >>= traverse (uncurry installPage) . M.assocs
|
use pages >>= traverse (uncurry installPage) . M.assocs
|
||||||
renderTags
|
renderTags
|
||||||
|
renderLists
|
||||||
renderSearchData
|
renderSearchData
|
||||||
io $ putStrLn "OK"
|
io $ putStrLn "OK"
|
||||||
whenM (use dumpFinalState) $ get >>= io . print
|
whenM (use dumpFinalState) $ get >>= io . print
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
<div class="footer-lcsb"></div>
|
<div class="footer-lcsb"></div>
|
||||||
<div class="footer-text">
|
<div class="footer-text">
|
||||||
<div>
|
<div>
|
||||||
The contents are available under the <a href="{root}license">Creative Commons Attribution-ShareAlike License (CC-BY-SA 4.0)</a>.
|
The contents are available under the <a href="{{root}}license">Creative Commons Attribution-ShareAlike License (CC-BY-SA 4.0)</a>.
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<a href="{root}privacy-policy">Privacy Policy</a> (Only necessary cookies accepted — <a href="#">change</a>)
|
<a href="{{root}}privacy-policy">Privacy Policy</a> (Only necessary cookies accepted — <a href="#">change</a>)
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-fill"></div>
|
<div class="flex-fill"></div>
|
||||||
|
|
|
@ -4,32 +4,55 @@
|
||||||
<body>
|
<body>
|
||||||
{{> header.html}}
|
{{> header.html}}
|
||||||
<h1>
|
<h1>
|
||||||
{{?htag}}
|
Cards in category:
|
||||||
Category:
|
{{#htag}}
|
||||||
{{#htag}}
|
<a class="cards-tagpiece" href="{{href}}">
|
||||||
<a class="cards-tagpiece" href="{{href}}">
|
{{^tag}}all{{/tag}}
|
||||||
{{^tag}}all{{/tag}}
|
{{?tag}}» {{tag}}{{/tag}}
|
||||||
{{?tag}}» {{tag}}{{/tag}}
|
</a>
|
||||||
</a>
|
|
||||||
{{/htag}}
|
|
||||||
{{/htag}}
|
{{/htag}}
|
||||||
{{^htag}}All cards{{/htag}}
|
|
||||||
</h1>
|
</h1>
|
||||||
{{?subtags}}<h2>Sub-categories</h2>
|
<p>See the <a href="{{listhref}}">complete listing of all pages in this category</a>.</p>
|
||||||
<ul class="cards-subcategories">
|
<ul class="cards-list">
|
||||||
{{#subtags}}
|
|
||||||
<li><a href="{{href}}">{{#tags}} » {{.}} {{/tags}}</a></li>
|
|
||||||
{{/subtags}}
|
|
||||||
</ul>
|
|
||||||
{{/subtags}}
|
|
||||||
{{?pages}}
|
{{?pages}}
|
||||||
<h2>Cards</h2>
|
|
||||||
<ul class="cards-list">
|
|
||||||
{{#pages}}
|
{{#pages}}
|
||||||
<li><a href="{{href}}">{{meta.title}}</a></li>
|
<li><a href="{{href}}">{{meta.title}}</a></li>
|
||||||
{{/pages}}
|
{{/pages}}
|
||||||
</ul>
|
|
||||||
{{/pages}}
|
{{/pages}}
|
||||||
|
{{?subtags}}
|
||||||
|
{{#subtags}}
|
||||||
|
<li>
|
||||||
|
<a href="{{href}}">{{#tags}} » {{.}} {{/tags}}</a>
|
||||||
|
<ul>
|
||||||
|
{{?pages}}
|
||||||
|
{{#pages}}
|
||||||
|
<li><a href="{{href}}">{{meta.title}}</a></li>
|
||||||
|
{{/pages}}
|
||||||
|
{{/pages}}
|
||||||
|
{{?subtags}}
|
||||||
|
{{#subtags}}
|
||||||
|
<li>
|
||||||
|
<a href="{{href}}">{{#tags}} » {{.}} {{/tags}}</a>
|
||||||
|
<ul>
|
||||||
|
{{?pages}}
|
||||||
|
{{#pages}}
|
||||||
|
<li><a href="{{href}}">{{meta.title}}</a></li>
|
||||||
|
{{/pages}}
|
||||||
|
{{/pages}}
|
||||||
|
{{?subtags}}
|
||||||
|
{{#subtags}}
|
||||||
|
<li><a href="{{href}}">{{#tags}} » {{.}} {{/tags}}</a> (click to expand)</li>
|
||||||
|
{{/subtags}}
|
||||||
|
{{/subtags}}
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
{{/subtags}}
|
||||||
|
{{/subtags}}
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
{{/subtags}}
|
||||||
|
{{/subtags}}
|
||||||
|
</ul>
|
||||||
{{> footer.html}}
|
{{> footer.html}}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in a new issue