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);
+ };
}