forked from Fediversity/fediversity.eu
allow prefixing output paths of collection items
This commit is contained in:
parent
c3774eb1f6
commit
c2fe5da469
|
@ -5,7 +5,10 @@ in
|
|||
{
|
||||
imports = lib.nixFiles ./.;
|
||||
|
||||
collections.news.type = config.content-types.article;
|
||||
collections.news = {
|
||||
type = config.content-types.article;
|
||||
prefixes = [ "news" ];
|
||||
};
|
||||
|
||||
pages.index = { link, ... }: {
|
||||
title = "Fediversity";
|
||||
|
|
|
@ -18,9 +18,7 @@ in
|
|||
in
|
||||
map
|
||||
(page: {
|
||||
page = lib.recursiveUpdate page {
|
||||
title = "${page.date}: ${page.title}";
|
||||
};
|
||||
page = lib.recursiveUpdate page { title = "${page.date}: ${page.title}"; };
|
||||
})
|
||||
(lib.take 3 sorted);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{ ... }:
|
||||
{ config, lib, ... }:
|
||||
{
|
||||
collections.news.entry = {
|
||||
collections.news.entry = { link, ... }: {
|
||||
title = "Fediversity project publicly announced";
|
||||
description = "The Fediversity project has officially been announced";
|
||||
date = "2024-01-01";
|
||||
|
|
17
lib.nix
17
lib.nix
|
@ -52,16 +52,17 @@ rec {
|
|||
inherit (lib) lists;
|
||||
|
||||
path1 = subpath.components path1';
|
||||
prefix1 = with lib; take (length path1 - 1) path1;
|
||||
path2 = subpath.components path2';
|
||||
prefix2 = with lib; take (length path1 - 1) path2;
|
||||
|
||||
commonPrefixLength = with lists;
|
||||
findFirstIndex (i: i.fst != i.snd)
|
||||
{ fst = null; snd = null; }
|
||||
(zipLists path1 path2);
|
||||
(length prefix1)
|
||||
(zipLists prefix1 prefix2);
|
||||
|
||||
relativeComponents = with lists;
|
||||
[ "." ] ++ (replicate (length path1 - commonPrefixLength - 1) "..") ++
|
||||
(drop commonPrefixLength path2);
|
||||
[ "." ] ++ (replicate (length prefix1 - commonPrefixLength) "..") ++ (drop commonPrefixLength path2);
|
||||
in
|
||||
join "/" relativeComponents;
|
||||
|
||||
|
@ -98,13 +99,7 @@ rec {
|
|||
merge = loc: defs:
|
||||
map
|
||||
(def:
|
||||
let
|
||||
merged = lib.mergeDefinitions
|
||||
(loc ++ [ "[definition ${toString def.file}]" ])
|
||||
elemType
|
||||
[{ inherit (def) file; value = def.value; }];
|
||||
in
|
||||
if merged ? mergedValue then merged.mergedValue else merged.value
|
||||
elemType.merge (loc ++ [ "[definition ${toString def.file}]" ]) [{ inherit (def) file; value = def.value; }]
|
||||
)
|
||||
defs;
|
||||
check = elemType.check;
|
||||
|
|
|
@ -41,7 +41,7 @@ in
|
|||
<link rel="canonical" href="${page.outPath}" />
|
||||
'';
|
||||
body = ''
|
||||
${templates.nav { menu = { menu = config.menus.main; }; }}
|
||||
${templates.nav { inherit page; menu = { menu = config.menus.main; }; }}
|
||||
${builtins.readFile (commonmark page.name page.body)}
|
||||
'';
|
||||
});
|
||||
|
@ -55,7 +55,7 @@ in
|
|||
}
|
||||
'';
|
||||
body = ''
|
||||
${templates.nav { menu = { menu = config.menus.main; }; }}
|
||||
${templates.nav { inherit page; menu = { menu = config.menus.main; }; }}
|
||||
${builtins.readFile (commonmark page.name page.body)}
|
||||
'';
|
||||
});
|
||||
|
@ -76,20 +76,13 @@ in
|
|||
let
|
||||
pages = lib.attrValues config.pages;
|
||||
collections = with lib; concatMap (collection: collection.entry) (attrValues config.collections);
|
||||
collections' = with lib; map
|
||||
(
|
||||
entry: recursiveUpdate entry {
|
||||
locations = map (l: "${entry.collection.name}/${l}") entry.locations;
|
||||
}
|
||||
)
|
||||
collections;
|
||||
in
|
||||
with lib; foldl
|
||||
(acc: elem: acc // {
|
||||
"${head elem.locations}" = builtins.toFile "${elem.name}.html" elem.outputs.html;
|
||||
})
|
||||
{ }
|
||||
(pages ++ collections');
|
||||
(pages ++ collections);
|
||||
|
||||
options.build = mkOption {
|
||||
description = ''
|
||||
|
|
|
@ -14,23 +14,23 @@ rec {
|
|||
<body>
|
||||
</html>
|
||||
'';
|
||||
nav = { menu }:
|
||||
nav = { page, menu }:
|
||||
let
|
||||
render-item = item:
|
||||
if item ? menu then
|
||||
''
|
||||
<li>${item.menu.label}
|
||||
${lib.indent " " (nav { menu = item; })}
|
||||
${lib.indent " " (nav { inherit page; menu = item; })}
|
||||
''
|
||||
else
|
||||
if item ? page then ''<li><a href="${item.page}">${item.page.title}</a></li>''
|
||||
if item ? page then ''<li><a href="${page.link item.page}">${item.page.title}</a></li>''
|
||||
else ''<li><a href="${item.link.url}">${item.link.label}</a></li>''
|
||||
;
|
||||
in
|
||||
''
|
||||
<nav>
|
||||
<ul>
|
||||
${with lib; indent " " (join "\n" (map render-item menu.menu.items))}
|
||||
${with lib; indent " " (join "\n" (map render-item menu.menu.items))}
|
||||
</ul>
|
||||
</nav>
|
||||
'';
|
||||
|
|
|
@ -7,7 +7,7 @@ let
|
|||
cfg = config;
|
||||
in
|
||||
{
|
||||
content-types. article = { config, collection, ... }: {
|
||||
content-types.article = { config, collection, ... }: {
|
||||
imports = [ cfg.content-types.page ];
|
||||
options = {
|
||||
collection = mkOption {
|
||||
|
@ -27,9 +27,6 @@ in
|
|||
};
|
||||
};
|
||||
config.name = lib.slug config.title;
|
||||
# TODO: this should be covered by the TBD `link` function instead,
|
||||
# taking a historical list of collection names into account
|
||||
config.outPath = "${collection.name}/${lib.head config.locations}";
|
||||
config.outputs.html = lib.mkForce (cfg.templates.html.article cfg config);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -52,13 +52,25 @@ in
|
|||
type = types.str;
|
||||
default = name;
|
||||
};
|
||||
entry = mkOption {
|
||||
description = "An entry in the collection";
|
||||
type = types.collection (types.submodule ({
|
||||
_module.args.collection = config;
|
||||
imports = [ config.type ];
|
||||
}));
|
||||
prefixes = mkOption {
|
||||
description = ''
|
||||
List of historic output locations for files in the collection
|
||||
|
||||
The first element is the canonical location.
|
||||
All other elements are used to create redirects to the canonical location.
|
||||
'';
|
||||
type = with types; nonEmptyListOf str;
|
||||
example = [ "." ];
|
||||
};
|
||||
entry = mkOption
|
||||
{
|
||||
description = "An entry in the collection";
|
||||
type = types.collection (types.submodule ({
|
||||
imports = [ config.type ];
|
||||
_module.args.collection = config;
|
||||
process-locations = ls: with lib; concatMap (l: map (p: "${p}/${l}") config.prefixes) ls;
|
||||
}));
|
||||
};
|
||||
};
|
||||
}));
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@ let
|
|||
;
|
||||
in
|
||||
{
|
||||
content-types.document = { name, config, link, ... }: {
|
||||
content-types.document = { name, config, options, link, ... }: {
|
||||
config._module.args.link = config.link;
|
||||
options = {
|
||||
name = mkOption {
|
||||
|
@ -17,7 +17,6 @@ in
|
|||
# TODO: reconsider using `page.outPath` and what to put into `locations`.
|
||||
# maybe we can avoid having ".html" suffixes there.
|
||||
# since templates can output multiple files, `html` is merely one of many things we *could* produce.
|
||||
# TODO: make `apply` configurable so one can programmatically modify locations
|
||||
locations = mkOption {
|
||||
description = ''
|
||||
List of historic output locations for the resulting file
|
||||
|
@ -26,11 +25,17 @@ in
|
|||
All other elements are used to create redirects to the canonical location.
|
||||
'';
|
||||
type = with types; nonEmptyListOf str;
|
||||
apply = config.process-locations;
|
||||
};
|
||||
process-locations = mkOption {
|
||||
description = "Function to post-process the output locations of contained document";
|
||||
type = types.functionTo options.locations.type;
|
||||
default = lib.id;
|
||||
};
|
||||
link = mkOption {
|
||||
description = "Helper function for transparent linking to other pages";
|
||||
type = with types; functionTo str;
|
||||
default = target: with lib; relativePath (head config.locations) (head target.locations);
|
||||
default = target: with lib; relativePath config.outPath target.outPath;
|
||||
};
|
||||
# TODO: may not need it when using `link`; could repurpose it to render the default template
|
||||
outPath = mkOption {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{ config, lib, ... }:
|
||||
{ config, options, lib, ... }:
|
||||
let
|
||||
inherit (lib)
|
||||
mkOption
|
||||
|
@ -7,7 +7,12 @@ let
|
|||
cfg = config;
|
||||
subtype = baseModule: types.submodule [
|
||||
baseModule
|
||||
{ _module.freeformType = types.attrs; }
|
||||
{
|
||||
_module.freeformType = types.attrs;
|
||||
# XXX: this is supposed to be used with a finished value,
|
||||
# and we don't want to process locations again.
|
||||
process-locations = lib.mkForce lib.id;
|
||||
}
|
||||
];
|
||||
in
|
||||
{
|
||||
|
|
Reference in a new issue