diff --git a/presentation/default.nix b/presentation/default.nix index 7410f3ca..a3435028 100644 --- a/presentation/default.nix +++ b/presentation/default.nix @@ -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 '' +
  • ${item.menu.label} + ${lib.indent " " (item.menu.outputs.html page)} +
  • + '' + else if item ? page then ''
  • ${item.page.title}
  • '' + else ''
  • ${item.link.label}
  • '' + ; + in + '' + ''; - 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; }; diff --git a/presentation/templates.nix b/presentation/templates.nix deleted file mode 100644 index c0d7f652..00000000 --- a/presentation/templates.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ lib }: -rec { - nav = menu: page: - let - render-item = item: - if item ? menu then '' -
  • ${item.menu.label} - ${lib.indent " " (item.menu.outputs.html page)} -
  • - '' - else if item ? page then ''
  • ${item.page.title}
  • '' - else ''
  • ${item.link.label}
  • '' - ; - in - '' - - ''; -} diff --git a/structure/article.nix b/structure/article.nix index ca7495df..aac3a398 100644 --- a/structure/article.nix +++ b/structure/article.nix @@ -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) + ]; + }; + }); }; } diff --git a/structure/document.nix b/structure/document.nix index 8af04c36..dd3718d5 100644 --- a/structure/document.nix +++ b/structure/document.nix @@ -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; }; }; }; diff --git a/structure/navigation.nix b/structure/navigation.nix index a3d78360..97ae9480 100644 --- a/structure/navigation.nix +++ b/structure/navigation.nix @@ -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; }; }; }; diff --git a/structure/page.nix b/structure/page.nix index d76954e1..a4352f12 100644 --- a/structure/page.nix +++ b/structure/page.nix @@ -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) + ]; + }; + }; }; }