nix template engine
Find a file
2024-09-13 11:04:54 +02:00
branding add button and site list to readme 2024-05-25 18:21:40 +02:00
example use correct html terminology in test post in example 2024-09-12 23:11:58 +02:00
.gitignore add example site 2024-05-22 21:55:06 +02:00
changelog.md update changelog for 0.3.0 2024-09-12 23:15:37 +02:00
engine.nix swap applyTemplate arguments 2024-09-13 11:02:03 +02:00
flake.lock add nix-system 2024-09-12 22:10:08 +02:00
flake.nix update example to use mkNteDerivation 2024-09-12 23:09:29 +02:00
LICENSE init 2024-05-22 21:19:37 +02:00
nte-drv.nix fix outDir creation 2024-09-12 22:54:09 +02:00
README.md improve getEntry docs 2024-09-13 11:04:54 +02:00
stdlib.nix init 2024-05-22 21:19:37 +02:00


nte

nix template engine - takes some templates, entries and applies the templates to the entries

nte's main repository is on my forgejo instance

mirrors are available on github and codeberg, I accept contributions from anywhere

sites written in nte

https://jacekpoz.pl

if your site (or anything else) is written in nte, let me know and I'll add you to this list

you can also use this button on your site and link to one of the repos

examples

check example/ for a static website written in nte

build and run it using

nix shell nixpkgs#darkhttpd --command sh -c "nix build -L .#examples.x86_64-linux.default && darkhttpd ./result"

the site will be available at http://localhost:8080

the example is a cut down version of my own website

usage

first add nte as an input in your project's flake

nte = {
  url = "git+https://git.jacekpoz.pl/jacekpoz/nte";
  inputs.nixpkgs.follows = "nixpkgs";
};

then use the mkNteDerivation wrapper over stdenv.mkDerivation available under

inputs.nte.functions.${system}.mkNteDerivation

it accepts an attrset of:

  • name, version, src - passthrough to stdenv.mkDerivation
  • extraArgs - an attrset of additional arguments passed to all entries and templates
  • entries - a list of all entry files to be processed
  • templates - a list of all template files to be applied
  • extraFiles - a list of attrsets of source and destination:
    • source - a path, if relative $PWD is $src in the installPhase
    • destination - a path, never absolute, appended to $out in the installPhase

example usage of the wrapper function:

mkNteDerivation {
  name = "nte-example";
  version = "0.1";
  src = ./.;

  extraArgs = {
    foo = 2137;
    bar = "dupa";
    baz = arg1: arg2: ''
      here's arg1: ${arg1}
      and here's arg2: ${arg2}
    '';
  };

  entries = [
    ./entry1.nix
    ./foo/entry2.nix
    ./foo/entry3.nix
    ./bar/entry4.nix
    ./bar/entry5.nix
    ./bar/entry6.nix
  ];

  templates = [
    ./template1.nix
    ./template2.nix
  ];

  extraFiles = [
    { source = ./image.png; destination = "/assets/"; }
    { source = ./image2.png; destination = "/assets/dupa.png"; }
    { source = "./data/*"; destination = "/assets/data/"; }
    { source = fetchurl { ... }; destination = "/"; }
  ];
}

nte will handle creating directories if your source file structure isn't flat

if the mkNteDerivation wrapper isn't enough for you, you can do things the old way - by putting the output of inputs.nte.functions.${system}.engine in a derivation's buildPhase:

mkDerivation {
  # ...

  buildPhase = ''
    runHook preBuild

    ${engine {inherit extraArgs entries templates;}}

    runHook postBuild
  '';
}

in that case if you wish to replicate the functionality of extraFiles you can use the derivation's installPhase, manually mkdir the needed directories and cp your files into $out

nte offers a standard library that contains nixpkgs, a getEntry function that gives you access to the entry's attributes and utility functions found in stdlib.nix

templates

a template can take an arbitrary number of arguments and returns { name, format, output }:

  • name - used as a template ID for the entries
  • format - the extension of the output file (ignored if an entry defines file)
  • output - string if in a base template, entry to another template otherwise

example template:

{
  name,
  location,
  info,
  ...
}: {
  name = "greeting";
  format = "txt";

  output = ''
    Hello ${name}! Welcome to ${location}.

    Here's some more information:
    ${info}
  '';
}

a template's output can also be an entry to another template:

{
  name,
  location,
  date,
  time,
  ...
}: {
  name = "greeting-with-date";
  output = {
    template = "greeting";

    inherit name location;

    info = ''
      You're visiting ${location} on ${date} at ${time}!
    '';
  };
}

a template that's inherited from a different template also inherits its format - no need to define it again

entries

an entry can take an arbitrary number of arguments and returns { template, ... }, the ... being the desired template's arguments (sans extraArgs, those are passed either way)

example entries (using the previous example templates):

_: {
  template = "greeting";

  name = "Jacek";
  location = "Wrocław";
  info = ''
    As of 2023, the official population of Wrocław is 674132 making it the third largest city in Poland.
  '';
}

an entry using the stdlib:

{
  run,
  ...
}: {
  template = "greeting-with-date";

  name = "Rafał";
  location = "Osieck";
  date = run "date +%F";
  time = run "date +%T";
}

if a binary isn't in $PATH, remember that each entry gets pkgs:

{
  pkgs,
  run,
  ...
}: let
  date = "${pkgs.coreutils-full}/bin/date";
in {
  # ...
  date = run "${date} +%F";
  time = run "${date} +%T";
}

nte by default will follow your source file structure, if you want to specify the output location yourself use file:

_: {
  # ...
  file = "foo/bar.txt";
}

in this example the output of this entry will end up at $out/foo/bar.txt instead of the default location - a base template's format will also be ignored

thanks

raf for helping me out with some of the nix and setting up mirrors

license

MIT