Compare commits

..

No commits in common. "3689353603ec040e7b7165d1b36c351f12150fd0" and "7581ed936855bc5902ed356fe1d2c528b6741db6" have entirely different histories.

6 changed files with 26 additions and 54 deletions

View file

@ -55,7 +55,7 @@ in
sorted = with lib; reverseList (sortOn (entry: entry.date) config.collections.news.entry); sorted = with lib; reverseList (sortOn (entry: entry.date) config.collections.news.entry);
in in
lib.join "\n" (map (article: '' lib.join "\n" (map (article: ''
- ${article.date} [${article.title}](${link article}) - ${article.date} [${article.title}](${article})
'') sorted) '') sorted)
} }
''; '';

27
lib.nix
View file

@ -113,32 +113,5 @@ rec {
}; };
nestedTypes.elemType = elemType; nestedTypes.elemType = elemType;
}; };
listOfUnique = elemType:
let
baseType = lib.types.listOf elemType;
in
baseType // {
merge = loc: defs:
let
# Keep track of which definition each value came from
defsWithValues = map
(def:
map (v: { inherit (def) file; value = v; }) def.value
)
defs;
flatDefs = lib.flatten defsWithValues;
# Check for duplicates while preserving source info
seen = builtins.foldl'
(acc: def:
if lib.lists.any (v: v.value == def.value) acc
then throw "The option `${lib.options.showOption loc}` has duplicate values (${toString def.value}) defined in ${def.file}"
else acc ++ [ def ]
) [ ]
flatDefs;
in
map (def: def.value) seen;
};
}; };
} }

View file

@ -21,9 +21,6 @@ in
Each template function takes the complete site `config` and the document's data structure. Each template function takes the complete site `config` and the document's data structure.
''; '';
# TODO: this function should probably take a single attrs,
# otherwise it's quite inflexible.
# named parameters would also help with readability at the call site
type = recursiveAttrs (with types; functionTo (functionTo str)); type = recursiveAttrs (with types; functionTo (functionTo str));
}; };
@ -37,15 +34,14 @@ in
''; '';
in in
{ {
nav = lib.mkDefault templates.nav;
page = lib.mkDefault (config: page: templates.html { page = lib.mkDefault (config: page: templates.html {
head = '' head = ''
<title>${page.title}</title> <title>${page.title}</title>
<meta name="description" content="${page.description}" /> <meta name="description" content="${page.description}" />
<link rel="canonical" href="${lib.head page.locations}" /> <link rel="canonical" href="${page.outPath}" />
''; '';
body = '' body = ''
${config.menus.main.outputs.html page} ${templates.nav { inherit page; menu = { menu = config.menus.main; }; }}
${builtins.readFile (commonmark page.name page.body)} ${builtins.readFile (commonmark page.name page.body)}
''; '';
}); });
@ -59,7 +55,7 @@ in
} }
''; '';
body = '' body = ''
${config.menus.main.outputs.html page} ${templates.nav { inherit page; menu = { menu = config.menus.main; }; }}
${builtins.readFile (commonmark page.name page.body)} ${builtins.readFile (commonmark page.name page.body)}
''; '';
}); });

View file

@ -14,15 +14,16 @@ rec {
<body> <body>
</html> </html>
''; '';
nav = menu: page: nav = { page, menu }:
let let
render-item = item: render-item = item:
if item ? menu then '' if item ? menu then
<li>${item.menu.label}
${lib.indent " " (item.menu.outputs.html page)}
</li>
'' ''
else if item ? page then ''<li><a href="${page.link item.page}">${item.page.title}</a></li>'' <li>${item.menu.label}
${lib.indent " " (nav { inherit page; menu = item; })}
''
else
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>'' else ''<li><a href="${item.link.url}">${item.link.label}</a></li>''
; ;
in in

View file

@ -14,6 +14,9 @@ in
type = types.str; type = types.str;
default = name; default = name;
}; };
# 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.
locations = mkOption { locations = mkOption {
description = '' description = ''
List of historic output locations for the resulting file List of historic output locations for the resulting file
@ -43,7 +46,15 @@ in
# TODO: we may want links to other representations, # TODO: we may want links to other representations,
# and currently the mapping of output types to output file # and currently the mapping of output types to output file
# names is soft. # names is soft.
default = target: with lib; "${relativePath (head config.locations) (head target.locations)}.html"; default = target: with lib; "${relativePath config.outPath target.outPath}.html";
};
# TODO: may not need it when using `link`; could repurpose it to render the default template
outPath = mkOption {
description = ''
Location of the page, used for transparently creating links
'';
type = types.str;
default = lib.head config.locations;
}; };
outputs = mkOption { outputs = mkOption {
description = '' description = ''

View file

@ -29,7 +29,7 @@ in
}; };
}; };
content-types.navigation = { name, config, ... }: { content-types.navigation = { name, ... }: {
options = { options = {
name = mkOption { name = mkOption {
description = "Symbolic name, used as a human-readable identifier"; description = "Symbolic name, used as a human-readable identifier";
@ -49,15 +49,6 @@ in
link = mkOption { type = submodule cfg.content-types.named-link; }; link = mkOption { type = submodule cfg.content-types.named-link; };
}); });
}; };
outputs = mkOption {
description = ''
Representations of the navigation structure in different formats
It must be a function that takes the page on which the navigation is to be shown, such that relative links get computed correctly.
'';
type = with types; attrsOf (functionTo str);
default.html = cfg.templates.html.nav { menu = config; };
};
}; };
}; };
} }