From 6c84b9dae055c8ed7173f6c97e3ca7a84b5f4cc4 Mon Sep 17 00:00:00 2001 From: valentin gagarin Date: Wed, 13 Nov 2024 15:24:41 +0100 Subject: [PATCH] implement correct-by-construction relative links --- website/content/default.nix | 8 ++++---- website/lib.nix | 19 +++++++++++++++++++ website/structure/content-types.nix | 5 +++-- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/website/content/default.nix b/website/content/default.nix index 397ffb7..fd14018 100644 --- a/website/content/default.nix +++ b/website/content/default.nix @@ -7,7 +7,7 @@ in collections.news.type = config.content-types.article; - pages.index = { + pages.index = { link, ... }: { title = "Fediversity"; locations = [ "index.html" @@ -21,13 +21,13 @@ in ${pages.fediversity.summary} - [Learn more about Fediversity](${pages.fediversity}) + [Learn more about Fediversity](${link pages.fediversity}) # Fediversity grants ${pages.grants.summary} - [Learn more about Fediversity grants](${pages.grants}) + [Learn more about Fediversity grants](${link pages.grants}) # Consortium @@ -38,7 +38,7 @@ in ${partner.description} - [Read more about ${partner.title}](${partner}) + [Read more about ${partner.title}](${link partner}) '') (with pages; [ nlnet oid tweag nordunet ]))} # News diff --git a/website/lib.nix b/website/lib.nix index 7e81147..4423cbf 100644 --- a/website/lib.nix +++ b/website/lib.nix @@ -46,6 +46,25 @@ rec { (map (x: if x == "" then x else "${prefix}${x}") (tail lines)) ); + relativePath = path1': path2': + let + inherit (lib.path) subpath; + inherit (lib) lists; + + path1 = subpath.components path1'; + path2 = subpath.components path2'; + + commonPrefixLength = with lists; + findFirstIndex (i: i.fst != i.snd) + { fst = null; snd = null; } + (zipLists path1 path2); + + relativeComponents = with lists; + [ "." ] ++ (replicate (length path1 - commonPrefixLength - 1) "..") ++ + (drop commonPrefixLength path2); + in + join "/" relativeComponents; + types = rec { collection = elemType: let diff --git a/website/structure/content-types.nix b/website/structure/content-types.nix index cd9a471..ec30efc 100644 --- a/website/structure/content-types.nix +++ b/website/structure/content-types.nix @@ -14,7 +14,8 @@ in }; }; config.content-types = { - document = { name, config, ... }: { + document = { name, config, link, ... }: { + config._module.args.link = config.link; options = { name = mkOption { description = "Symbolic name, used as a human-readable identifier"; @@ -37,7 +38,7 @@ in link = mkOption { description = "Helper function for transparent linking to other pages"; type = with types; functionTo str; - default = target: "TODO: compute the relative path based on `locations`"; + default = target: with lib; relativePath (head config.locations) (head target.locations); }; # TODO: may not need it when using `link`; could repurpose it to render the default template outPath = mkOption {