From c2fe5da4699178a1dfa663676219c3e6f4ca7085 Mon Sep 17 00:00:00 2001 From: valentin gagarin Date: Wed, 13 Nov 2024 15:24:41 +0100 Subject: [PATCH] allow prefixing output paths of collection items --- content/default.nix | 5 ++++- content/navigation.nix | 4 +--- content/news/project-launch.nix | 4 ++-- lib.nix | 17 ++++++----------- presentation/default.nix | 13 +++---------- presentation/templates.nix | 8 ++++---- structure/article.nix | 5 +---- structure/default.nix | 24 ++++++++++++++++++------ structure/document.nix | 11 ++++++++--- structure/navigation.nix | 9 +++++++-- 10 files changed, 54 insertions(+), 46 deletions(-) diff --git a/content/default.nix b/content/default.nix index 8cc4daa9..c4d0f58c 100644 --- a/content/default.nix +++ b/content/default.nix @@ -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"; diff --git a/content/navigation.nix b/content/navigation.nix index f7577621..20ca4d91 100644 --- a/content/navigation.nix +++ b/content/navigation.nix @@ -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); } diff --git a/content/news/project-launch.nix b/content/news/project-launch.nix index bf86f221..05edc4c7 100644 --- a/content/news/project-launch.nix +++ b/content/news/project-launch.nix @@ -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"; diff --git a/lib.nix b/lib.nix index cedef3c9..5071c0b5 100644 --- a/lib.nix +++ b/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; diff --git a/presentation/default.nix b/presentation/default.nix index 7c472dd1..69fa34c2 100644 --- a/presentation/default.nix +++ b/presentation/default.nix @@ -41,7 +41,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)} ''; }); @@ -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 = '' diff --git a/presentation/templates.nix b/presentation/templates.nix index f412442b..f4567aa6 100644 --- a/presentation/templates.nix +++ b/presentation/templates.nix @@ -14,23 +14,23 @@ rec { ''; - nav = { menu }: + nav = { page, menu }: let render-item = item: if item ? menu then ''
  • ${item.menu.label} - ${lib.indent " " (nav { menu = item; })} + ${lib.indent " " (nav { inherit page; menu = item; })} '' else - if item ? page then ''
  • ${item.page.title}
  • '' + if item ? page then ''
  • ${item.page.title}
  • '' else ''
  • ${item.link.label}
  • '' ; in '' ''; diff --git a/structure/article.nix b/structure/article.nix index 2cc82c17..ca7495df 100644 --- a/structure/article.nix +++ b/structure/article.nix @@ -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); }; } diff --git a/structure/default.nix b/structure/default.nix index 4150f253..6c2f5419 100644 --- a/structure/default.nix +++ b/structure/default.nix @@ -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; + })); + }; }; })); }; diff --git a/structure/document.nix b/structure/document.nix index ba02c7fe..285e8ac7 100644 --- a/structure/document.nix +++ b/structure/document.nix @@ -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 { diff --git a/structure/navigation.nix b/structure/navigation.nix index 17bae29f..12670278 100644 --- a/structure/navigation.nix +++ b/structure/navigation.nix @@ -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 {