implement correct-by-construction relative links

This commit is contained in:
Valentin Gagarin 2024-11-13 15:24:41 +01:00 committed by Valentin Gagarin
parent 29839f82d7
commit 6c84b9dae0
3 changed files with 26 additions and 6 deletions

View file

@ -7,7 +7,7 @@ in
collections.news.type = config.content-types.article; collections.news.type = config.content-types.article;
pages.index = { pages.index = { link, ... }: {
title = "Fediversity"; title = "Fediversity";
locations = [ locations = [
"index.html" "index.html"
@ -21,13 +21,13 @@ in
${pages.fediversity.summary} ${pages.fediversity.summary}
[Learn more about Fediversity](${pages.fediversity}) [Learn more about Fediversity](${link pages.fediversity})
# Fediversity grants # Fediversity grants
${pages.grants.summary} ${pages.grants.summary}
[Learn more about Fediversity grants](${pages.grants}) [Learn more about Fediversity grants](${link pages.grants})
# Consortium # Consortium
@ -38,7 +38,7 @@ in
${partner.description} ${partner.description}
[Read more about ${partner.title}](${partner}) [Read more about ${partner.title}](${link partner})
'') (with pages; [ nlnet oid tweag nordunet ]))} '') (with pages; [ nlnet oid tweag nordunet ]))}
# News # News

View file

@ -46,6 +46,25 @@ rec {
(map (x: if x == "" then x else "${prefix}${x}") (tail lines)) (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 { types = rec {
collection = elemType: collection = elemType:
let let

View file

@ -14,7 +14,8 @@ in
}; };
}; };
config.content-types = { config.content-types = {
document = { name, config, ... }: { document = { name, config, link, ... }: {
config._module.args.link = config.link;
options = { options = {
name = mkOption { name = mkOption {
description = "Symbolic name, used as a human-readable identifier"; description = "Symbolic name, used as a human-readable identifier";
@ -37,7 +38,7 @@ in
link = mkOption { link = mkOption {
description = "Helper function for transparent linking to other pages"; description = "Helper function for transparent linking to other pages";
type = with types; functionTo str; 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 # TODO: may not need it when using `link`; could repurpose it to render the default template
outPath = mkOption { outPath = mkOption {