feat(sterni/nix/html): make <html> also emit doctype

This makes the awkward withDoctype utility obsolete which is much nicer.
Technically, this is a BREAKING CHANGE since it was possible to create
valid documents without an <html> tag before:

    withDoctype (lib.concatStrings [ (<head> { } …) (<body> { } …) ])

I don't think this usecase is worth preserving since this can just be
written as

    <html> { } [ (<head> { } …) (<body> { } …) ]

and omitting the <html> tag is not recommended since it should be used
to set the language of the document (which we didn't in the example
above).

Change-Id: Idc5104ce88fe8bee965c076229b79387915c3605
Reviewed-on: https://cl.tvl.fyi/c/depot/+/12907
Autosubmit: sterni <sternenseemann@systemli.org>
Reviewed-by: sterni <sternenseemann@systemli.org>
Tested-by: BuildkiteCI
Reviewed-by: tazjin <tazjin@tvl.su>
This commit is contained in:
sterni 2024-12-25 00:53:08 +01:00 committed by clbot
parent 9fa198f9ae
commit d47c7fa12b
5 changed files with 20 additions and 24 deletions

View file

@ -3,7 +3,6 @@
let let
inherit (depot.users.sterni.nix.html) inherit (depot.users.sterni.nix.html)
__findFile __findFile
withDoctype
; ;
in in
@ -19,13 +18,13 @@ in
root = pkgs.writeTextFile { root = pkgs.writeTextFile {
name = "sterni.lv-http-root"; name = "sterni.lv-http-root";
destination = "/index.html"; destination = "/index.html";
text = withDoctype (<html> { } [ text = <html> { } [
(<head> { } [ (<head> { } [
(<meta> { charset = "utf-8"; } null) (<meta> { charset = "utf-8"; } null)
(<title> { } "no thoughts") (<title> { } "no thoughts")
]) ])
(<body> { } "🦩") (<body> { } "🦩")
]); ];
}; };
# TODO(sterni): tmp.sterni.lv # TODO(sterni): tmp.sterni.lv
locations."/tmp/".root = toString /srv/http; locations."/tmp/".root = toString /srv/http;

View file

@ -11,10 +11,10 @@ let
htmlNix = import ./path/to/html.nix { }; htmlNix = import ./path/to/html.nix { };
# make the magic work # make the magic work
inherit (htmlNix) __findFile esc withDoctype; inherit (htmlNix) __findFile esc;
in in
pkgs.writeText "example.html" (withDoctype (<html> {} [ pkgs.writeText "example.html" (<html> {} [
(<head> {} [ (<head> {} [
(<meta> { charset = "utf-8"; } null) (<meta> { charset = "utf-8"; } null)
(<title> {} (esc "hello world")) (<title> {} (esc "hello world"))
@ -35,7 +35,7 @@ pkgs.writeText "example.html" (withDoctype (<html> {} [
]) ])
]) ])
]) ])
])) ])
``` ```
Convince yourself it works: Convince yourself it works:

View file

@ -1,4 +1,4 @@
# Copyright © 2021 sterni # SPDX-FileCopyrightText: Copyright © 2021, 2024 sterni
# SPDX-License-Identifier: MIT # SPDX-License-Identifier: MIT
# #
# This file provides a cursed HTML DSL for nix which works by overloading # This file provides a cursed HTML DSL for nix which works by overloading
@ -58,6 +58,9 @@ let
calls, we can't escape it automatically. Instead this must be done manually calls, we can't escape it automatically. Instead this must be done manually
using `esc`. using `esc`.
If the tag is "html", e.g. in case of `<html> { } `, "<!DOCTYPE html> will
be prepended to the normal rendering of the text.
Type: string -> attrs<string> -> (list<string> | string | null) -> string Type: string -> attrs<string> -> (list<string> | string | null) -> string
Example: Example:
@ -98,20 +101,16 @@ let
then builtins.concatStringsSep "" (flatten content) then builtins.concatStringsSep "" (flatten content)
else content; else content;
in in
if content == null (if tag == "html" then "<!DOCTYPE html>" else "") +
(if content == null
then "<${tag}${attrs'}/>" then "<${tag}${attrs'}/>"
else "<${tag}${attrs'}>${content'}</${tag}>"; else "<${tag}${attrs'}>${content'}</${tag}>");
/* Prepend "<!DOCTYPE html>" to a string. /* Deprecated, does nothing.
Type: string -> string
Example:
withDoctype (<body> {} (esc "hello"))
=> "<!DOCTYPE html><body>hello</body>"
*/ */
withDoctype = doc: "<!DOCTYPE html>" + doc; withDoctype = doc: builtins.trace
"WARN: withDoctype no longer does anything, `<html> { } [ ]` takes care of rendering <!DOCTYPE html>"
doc;
/* Taken from <nixpkgs/lib/lists.nix>. */ /* Taken from <nixpkgs/lib/lists.nix>. */
flatten = x: flatten = x:

View file

@ -4,10 +4,9 @@ let
inherit (depot.users.sterni.nix.html) inherit (depot.users.sterni.nix.html)
__findFile __findFile
esc esc
withDoctype
; ;
exampleDocument = withDoctype (<html> { lang = "en"; } [ exampleDocument = <html> { lang = "en"; } [
(<head> { } [ (<head> { } [
(<meta> { charset = "utf-8"; } null) (<meta> { charset = "utf-8"; } null)
(<title> { } "html.nix example document") (<title> { } "html.nix example document")
@ -78,7 +77,7 @@ let
]) ])
]) ])
]) ])
]); ];
in in
pkgs.runCommand "html.nix.html" pkgs.runCommand "html.nix.html"

View file

@ -4,7 +4,6 @@ let
inherit (depot.users.sterni.nix.html) inherit (depot.users.sterni.nix.html)
__findFile __findFile
esc esc
withDoctype
; ;
# CGI envvars: https://www.instanet.com/cgi/env.html # CGI envvars: https://www.instanet.com/cgi/env.html
@ -24,7 +23,7 @@ let
default = let { default = let {
hasQuery = if builtins.length (builtins.attrNames query) > 0 then "?" else ""; hasQuery = if builtins.length (builtins.attrNames query) > 0 then "?" else "";
body = (withDoctype (<html> { lang = "en"; } [ body = <html> { lang = "en"; } [
(<head> { } [ (<head> { } [
(<title> { } "some cursed nix") (<title> { } "some cursed nix")
]) ])
@ -33,7 +32,7 @@ let
(<p> { } [ method " " path hasQuery rawQuery ]) (<p> { } [ method " " path hasQuery rawQuery ])
(<p> { } (builtins.toJSON query)) (<p> { } (builtins.toJSON query))
]) ])
])); ];
}; };
greeter = withDoctype (<html> { lang = "en"; } [ greeter = withDoctype (<html> { lang = "en"; } [