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;
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

View file

@ -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

View file

@ -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 {