From ad8b758cee9c2ea86bf8e0bb7df101e567249884 Mon Sep 17 00:00:00 2001 From: valentin gagarin Date: Wed, 13 Nov 2024 15:24:41 +0100 Subject: [PATCH] implement navigation --- website/content/navigation.nix | 21 ++++++++++++++++ website/presentation/default.nix | 10 ++++++-- website/presentation/templates.nix | 22 ++++++++++++++++- website/structure/content-types.nix | 38 ++++++++++++++++++++++++++++- website/structure/default.nix | 6 +++++ 5 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 website/content/navigation.nix diff --git a/website/content/navigation.nix b/website/content/navigation.nix new file mode 100644 index 00000000..f62263e7 --- /dev/null +++ b/website/content/navigation.nix @@ -0,0 +1,21 @@ +{ config, ... }: +let + inherit (config) pages; +in +{ + menus.main = { + label = "Main"; + items = [ + { + menu.label = "Consortium"; + menu.items = map (page: { inherit page; }) (with pages; [ nlnet oid tweag nordunet ]); + } + { + page = pages.fediversity; + } + { + page = pages.grants; + } + ]; + }; +} diff --git a/website/presentation/default.nix b/website/presentation/default.nix index ca49c9a7..d3f3ef6f 100644 --- a/website/presentation/default.nix +++ b/website/presentation/default.nix @@ -37,7 +37,10 @@ in ''; - body = builtins.readFile (commonmark page.name page.body); + body = '' + ${templates.nav { menu = { menu = config.menus.main; }; }} + ${builtins.readFile (commonmark page.name page.body)} + ''; }); }); article = lib.mkDefault (config: page: { @@ -48,7 +51,10 @@ in ''; - body = builtins.readFile (commonmark page.name page.body); + body = '' + ${templates.nav { menu = { menu = config.menus.main; }; }} + ${builtins.readFile (commonmark page.name page.body)} + ''; }); }); }; diff --git a/website/presentation/templates.nix b/website/presentation/templates.nix index 2de9d107..f412442b 100644 --- a/website/presentation/templates.nix +++ b/website/presentation/templates.nix @@ -1,5 +1,5 @@ { lib }: -{ +rec { html = { head, body }: '' @@ -14,4 +14,24 @@ ''; + nav = { menu }: + let + render-item = item: + if item ? menu then + '' +
  • ${item.menu.label} + ${lib.indent " " (nav { menu = item; })} + '' + else + if item ? page then ''
  • ${item.page.title}
  • '' + else ''
  • ${item.link.label}
  • '' + ; + in + '' + + ''; } diff --git a/website/structure/content-types.nix b/website/structure/content-types.nix index 22b07962..7ff42151 100644 --- a/website/structure/content-types.nix +++ b/website/structure/content-types.nix @@ -17,7 +17,7 @@ in page = { name, config, ... }: { options = { name = mkOption { - description = "Symbolic name for the page, used as a human-readable identifier"; + description = "Symbolic name, used as a human-readable identifier"; type = types.str; default = name; }; @@ -93,5 +93,41 @@ in config.outPath = "${collectionName}/${lib.head config.locations}"; config.template = cfg.templates.article; }; + + named-link = { ... }: { + options = { + label = mkOption { + description = "Link label"; + type = types.str; + }; + url = mkOption { + description = "Link URL"; + type = types.str; + }; + }; + }; + + navigation = { name, ... }: { + options = { + name = mkOption { + description = "Symbolic name, used as a human-readable identifier"; + type = types.str; + default = name; + }; + label = mkOption { + description = "Menu label"; + type = types.str; + default = name; + }; + items = mkOption { + description = "List of menu items"; + type = with types; listOf (attrTag { + menu = mkOption { type = submodule cfg.content-types.navigation; }; + page = mkOption { type = submodule cfg.content-types.page; }; + link = mkOption { type = submodule cfg.content-types.named-link; }; + }); + }; + }; + }; }; } diff --git a/website/structure/default.nix b/website/structure/default.nix index 01148eb4..df80b94c 100644 --- a/website/structure/default.nix +++ b/website/structure/default.nix @@ -54,4 +54,10 @@ in })); }; + options.menus = mkOption { + description = '' + Collection navigation menus + ''; + type = with types; attrsOf (submodule config.content-types.navigation); + }; }