forked from Fediversity/fediversity.eu
separate DOM mapping and generic templating
the templates collection will soon only be there for reusable snippets, while the HTML representation of document types will be attached to those types directly.
This commit is contained in:
parent
2eeb7e5bcc
commit
4160b6e976
|
@ -37,47 +37,38 @@ in
|
|||
type = recursiveAttrs (with types; functionTo (functionTo str));
|
||||
};
|
||||
|
||||
config.templates.html =
|
||||
let
|
||||
commonmark = name: markdown: pkgs.runCommand "${name}.html"
|
||||
{
|
||||
buildInputs = [ pkgs.cmark ];
|
||||
} ''
|
||||
cmark ${builtins.toFile "${name}.md" markdown} > $out
|
||||
config.templates.html = {
|
||||
markdown = name: text:
|
||||
let
|
||||
commonmark = pkgs.runCommand "${name}.html"
|
||||
{
|
||||
buildInputs = [ pkgs.cmark ];
|
||||
} ''
|
||||
cmark ${builtins.toFile "${name}.md" text} > $out
|
||||
'';
|
||||
in
|
||||
builtins.readFile commonmark;
|
||||
nav = menu: page:
|
||||
let
|
||||
render-item = item:
|
||||
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>''
|
||||
else ''<li><a href="${item.link.url}">${item.link.label}</a></li>''
|
||||
;
|
||||
in
|
||||
''
|
||||
<nav>
|
||||
<ul>
|
||||
${with lib; indent " " (join "\n" (map render-item menu.items))}
|
||||
</ul>
|
||||
</nav>
|
||||
'';
|
||||
in
|
||||
{
|
||||
nav = lib.mkDefault templates.nav;
|
||||
page = lib.mkDefault (config: page: render-html {
|
||||
html = {
|
||||
head = {
|
||||
title.text = page.title;
|
||||
meta.description = page.description;
|
||||
link.canonical = lib.head page.locations;
|
||||
};
|
||||
body.content = [
|
||||
(config.menus.main.outputs.html page)
|
||||
{ section.heading.content = page.title; }
|
||||
(builtins.readFile (commonmark page.name page.body))
|
||||
];
|
||||
};
|
||||
});
|
||||
article = lib.mkDefault (config: page: render-html {
|
||||
html = {
|
||||
head = {
|
||||
title.text = page.title;
|
||||
meta.description = page.description;
|
||||
meta.authors = if lib.isList page.author then page.author else [ page.author ];
|
||||
link.canonical = lib.head page.locations;
|
||||
};
|
||||
body.content = [
|
||||
(config.menus.main.outputs.html page)
|
||||
{ section.heading.content = page.title; }
|
||||
(builtins.readFile (commonmark page.name page.body))
|
||||
];
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
options.files = mkOption {
|
||||
description = ''
|
||||
|
@ -86,6 +77,8 @@ in
|
|||
By default, all elements in `option`{pages} are converted to files using their template or the default template.
|
||||
Add more files to the output by assigning to this attribute set.
|
||||
'';
|
||||
# TODO: this should be attrsOf string-coercible instead.
|
||||
# we can convert this to file at the very end.
|
||||
type = with types; attrsOf path;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
{ lib }:
|
||||
rec {
|
||||
nav = menu: page:
|
||||
let
|
||||
render-item = item:
|
||||
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>''
|
||||
else ''<li><a href="${item.link.url}">${item.link.label}</a></li>''
|
||||
;
|
||||
in
|
||||
''
|
||||
<nav>
|
||||
<ul>
|
||||
${with lib; indent " " (join "\n" (map render-item menu.menu.items))}
|
||||
</ul>
|
||||
</nav>
|
||||
'';
|
||||
}
|
|
@ -5,6 +5,14 @@ let
|
|||
types
|
||||
;
|
||||
cfg = config;
|
||||
render-html = document:
|
||||
let
|
||||
eval = lib.evalModules {
|
||||
class = "DOM";
|
||||
modules = [ document (import ../presentation/dom.nix) ];
|
||||
};
|
||||
in
|
||||
toString eval.config;
|
||||
in
|
||||
{
|
||||
content-types.article = { config, collection, ... }: {
|
||||
|
@ -27,6 +35,20 @@ in
|
|||
};
|
||||
};
|
||||
config.name = lib.slug config.title;
|
||||
config.outputs.html = lib.mkForce (cfg.templates.html.article cfg config);
|
||||
config.outputs.html = lib.mkForce (render-html {
|
||||
html = {
|
||||
head = {
|
||||
title.text = config.title;
|
||||
meta.description = config.description;
|
||||
meta.authors = if lib.isList config.author then config.author else [ config.author ];
|
||||
link.canonical = lib.head config.locations;
|
||||
};
|
||||
body.content = [
|
||||
(cfg.menus.main.outputs.html config)
|
||||
{ section.heading.content = config.title; }
|
||||
(cfg.templates.html.markdown config.name config.body)
|
||||
];
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
|
|
|
@ -45,13 +45,13 @@ in
|
|||
# names is soft.
|
||||
default = target: with lib; "${relativePath (head config.locations) (head target.locations)}.html";
|
||||
};
|
||||
outputs = mkOption {
|
||||
# TODO: figure out how to make this overridable at any granularity.
|
||||
# it should be possible with the DOM module now.
|
||||
outputs.html = mkOption {
|
||||
# TODO: make this of type DOM and convert to string at the output.
|
||||
# the output aggregator then only needs something string-coercible
|
||||
description = ''
|
||||
Representations of the document in different formats
|
||||
'';
|
||||
type = with types; attrsOf str;
|
||||
type = with types; str;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -56,7 +56,7 @@ in
|
|||
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; };
|
||||
default.html = cfg.templates.html.nav config;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -5,6 +5,14 @@ let
|
|||
types
|
||||
;
|
||||
cfg = config;
|
||||
render-html = document:
|
||||
let
|
||||
eval = lib.evalModules {
|
||||
class = "DOM";
|
||||
modules = [ document (import ../presentation/dom.nix) ];
|
||||
};
|
||||
in
|
||||
toString eval.config;
|
||||
in
|
||||
{
|
||||
content-types.page = { name, config, ... }: {
|
||||
|
@ -34,6 +42,19 @@ in
|
|||
type = types.str;
|
||||
};
|
||||
};
|
||||
config.outputs.html = cfg.templates.html.page cfg config;
|
||||
config.outputs.html = render-html {
|
||||
html = {
|
||||
head = {
|
||||
title.text = config.title;
|
||||
meta.description = config.description;
|
||||
link.canonical = lib.head config.locations;
|
||||
};
|
||||
body.content = [
|
||||
(cfg.menus.main.outputs.html config)
|
||||
{ section.heading.content = config.title; }
|
||||
(cfg.templates.html.markdown config.name config.body)
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
Reference in a new issue