Comment by mikepurvis

Comment by mikepurvis 20 hours ago

8 replies

As a nix person, I like this a lot and could see myself using it. My only criticism would be I don't love this kind of thing:

    "<!DOCTYPE html>\n"
    +
      html
        [ (attrs.lang metadata.lang) ]
        [
          (head [ ] [ (partials.head context) ])
          (body
            [
              (attrs.classes [
                "font-sans"
                "bg-white"
              ])
I understand that this is very flexible and powerful, but it immediately makes the templates highly non-portable and requiring of hand-authorship— fine for a personal blog by a code nerd, but a non-starter for when a designer is involved who will want to use visual tools. I see that right below that there's also a "normal string templating" option that's closer to conventional jinja2 or the like, but it's ultimately still pretty nix-ified.

It might be worth some ifd [1] to allow a step that pre-processes conventional html + tags template files into the form that can be consumed by nixtml.

[1]: or the still-experimental dynamic derivations: https://fzakaria.com/2025/03/10/an-early-look-at-nix-dynamic...

granra 20 hours ago

I'm the author of nixtml. It's already doing IFD by using python to parse markdown content + metadata and superhtml to format the final HTML (a bit unnecessary, but I liked it while developing it).

I really wanted the templates to just be nix functions. It shouldn't be an issue to pass the context to an external program with `pkgs.runCommand` or something and then read the result (IFD like you mentioned).

Edit: I'm glad to hear you like it :)

  • mikepurvis 19 hours ago

    Yeah, it feels like the more conventional way would be doing the template-filling as a build step, so it's Nix just for the overall structure managing a fixed build graph, and then a per-page Python run to actually fill templates and generate the snippets/pages.

    However, if you did want it to be nix all the way down and get more of that juicy dependency granularity, it could be more of a model where content and templates are transformed upfront into Nix source, which is then transformed and combined during evaluation. Obviously this is fairly slow in an IFD world where all that pre-work has to be serialized, but it would be interesting to experiment with what it looks like in a dynamic derivations context.

    • granra 18 hours ago

      Yeah it would probably be more efficient to do the templating as a build step in the derivation that parses the markdown. But after making nixidy[1] I wanted to have a crack at making a static site generator _in nix_. I'm open to expanding it though of course :)

      [1]: https://github.com/arnarg/nixidy

      • mikepurvis 18 hours ago

        Oh I can totally understand the impulse on that score. I guess going the way you have at the very least gets you out of some of the annoying handoffs of data between the two worlds, for example putting nix attrsets through toJSON so that they can be picked up on the Python side as template-fill variables.

        The ROS 1 world was full of this kind of thing for getting values between Python and CMake and it's truly gross, eg: https://github.com/ros/catkin/blob/noetic-devel/cmake/templa...

  • lloeki 19 hours ago

    > I really wanted the templates to just be nix functions

    This feels like Ruby template engines like haml† and slim†† a lot, or the various xml builders††† too

    https://github.com/haml/haml

    †† https://slim-template.github.io

    ††† https://nokogiri.org/rdoc/Nokogiri/XML/Builder.html#class-No...