implement raw assets

this allows adding files to the output as they are
This commit is contained in:
Valentin Gagarin 2024-11-13 15:24:41 +01:00
parent 4ec1cee08f
commit 4fdb56e436
5 changed files with 73 additions and 19 deletions

View file

@ -49,4 +49,17 @@ in
</nav>
'';
};
config.templates.files = fs: with lib;
foldl'
# TODO: create static redirects from `tail <collection>.locations`
(acc: elem: acc // (mapAttrs' (type: value: {
name = head elem.locations + optionalString (type != "") ".${type}";
value = builtins.toFile
(elem.name + optionalString (type != "") ".${type}")
(toString value);
}))
elem.outputs)
{ }
fs;
}

35
structure/assets.nix Normal file
View file

@ -0,0 +1,35 @@
{ config, lib, ... }:
let
inherit (lib)
mkOption
types
;
cfg = config;
in
{
options.assets = mkOption {
description = ''
Collection of assets, i.e. static files that can be linked to from within documents
'';
type = with types; attrsOf (submodule ({ config, ... }: {
imports = [ cfg.content-types.document ];
options.path = mkOption {
type = types.path;
};
config.name = builtins.baseNameOf config.path;
config.outputs."" = builtins.readFile config.path;
}));
default = { };
};
config.files = with lib;
let
flatten = attrs: mapAttrsToList
(name: value:
# HACK: we somehow have to distinguish a module value from regular attributes.
# arbitrary choice: the outputs attribute
if value ? outputs then value else mapAttrsToList value)
attrs;
in
cfg.templates.files (flatten cfg.assets);
}

View file

@ -61,15 +61,11 @@ in
};
}));
};
config.files =
# TODO: create static redirects from `tail <collection>.locations`
with lib;
let
collections = with lib; concatMap (collection: collection.entry) (attrValues config.collections);
collections = concatMap (collection: collection.entry) (attrValues config.collections);
in
with lib; foldl
(acc: elem: acc // {
"${head elem.locations}.html" = builtins.toFile "${elem.name}.html" "${elem.outputs.html}";
})
{ }
collections;
cfg.templates.files collections;
}

View file

@ -47,11 +47,28 @@ in
};
link = mkOption {
description = "Helper function for transparent linking to other pages";
type = with types; functionTo str;
type = with types; functionTo attrs;
# TODO: we may want links to other representations,
# and currently the mapping of output types to output file
# names is soft.
default = target: with lib; "${relativePath (head config.locations) (head target.locations)}.html";
default = with lib; target:
let
path = relativePath (head config.locations) (head target.locations);
links = mapAttrs
(type: output:
path + optionalString (type != "") ".${type}"
# ^^^^^^^^^^^^
# convention for raw files
)
target.outputs;
in
if length (attrValues links) == 0
then throw "no output to link to for '${target.name}'"
else if length (attrValues links) == 1
then links // {
__toString = _: head (attrValues links);
}
else links;
};
outputs = mkOption {
description = ''

View file

@ -14,15 +14,8 @@ in
'';
type = with types; attrsOf (submodule config.content-types.page);
};
config.files = with lib;
foldl'
(acc: elem: acc // {
# TODO: create static redirects from `tail page.locations`
# TODO: the file name could correspond to the canonical location in the HTML representation
"${head elem.locations}.html" = builtins.toFile "${elem.name}.html" "${elem.outputs.html}";
})
{ }
(attrValues config.pages);
config.files = with lib; cfg.templates.files (attrValues config.pages);
config.content-types.page = { name, config, ... }: {
imports = [ cfg.content-types.document ];