add favicons to every page

This commit is contained in:
tristan 2024-01-01 08:10:32 +00:00
parent 30ffa6c9b3
commit d723140f84
6 changed files with 129 additions and 32 deletions

View file

@ -9,7 +9,7 @@
in nixite // {
packages.${system} = {
raw = nixite.mkSite (let
site = (nixite.site.extractPaths {
markup = {
"test" = with nixite.elems;
let
blue = nixite.style.tag "span" "blue" {
@ -19,14 +19,7 @@
style = { text-decoration = "underline"; };
};
in (Doc { } [
[
(title { } "Nixite")
(link {
rel = "shortcut icon";
type = "image/png";
href = ./testing/src/favicon.png;
} "")
]
[ (title { } "Nixite") ]
(main { } [
(a "/readme" "Readme")
(a "/blog" "blog")
@ -41,10 +34,11 @@
]);
blog = nixite.md.readDir ./testing/blog;
"index.html" = nixite.md.mdToPage ./README.md;
});
styles = # nixite.site.getStyles site;
nixite.style.getStyles site.test;
in nixite.site.applyStyle styles site);
};
styles = nixite.site.getStyles markup;
site = (nixite.site.extractPaths (nixite.site.applyStyle styles
(nixite.site.applyFavicon ./testing/src/favicon.png markup)));
in site);
default = nixite.serve self.packages.${system}.raw;

View file

@ -14,8 +14,8 @@ in rec {
else if builtins.isList elem then
builtins.toString (map toHTML elem)
else
"<${elem.tag} ${writeAttrs elem.attrs}>${
toHTML elem.child
"<${elem.tag} ${writeAttrs elem.attrs or { }}>${
toHTML elem.child or ""
}</${elem.tag}>";
writeAttrs = attrs:
@ -30,11 +30,13 @@ in rec {
tag = tag: {
inherit tag;
__toString = self: toString (self { } "");
__functor = self: attrs:
if !(builtins.isAttrs attrs) then
throw "HTML tag requires attribute set"
else {
inherit tag attrs;
__toString = self: toString (self "");
__functor = self: child:
if !(isTag child) then
throw "tag child must be tag, list, or string, got ${

View file

@ -1,24 +1,45 @@
let
html = import ./html.nix;
elems = import ./elems.nix;
style = import ./style.nix;
in rec {
getStyles = site:
builtins.zipAttrsWith (name: value: builtins.elemAt value 0)
(map style.getStyles ( flatten site ));
flatten = site: map (
page: if builtins.isAttrs page && page ? "__toString" then
page
else if builtins.isAttrs page then
flatten page
else
page
) (builtins.attrValues site);
applyStyle = style: site: (linkStyle site) // { "style.css" = style; };
getStyles = site: ''
.blue {
color: blue;
}
'';
linkStyle = site:
eachPage site
(content: html.addToHead content [ (elems.Stylesheet "/style.css") ]);
eachPage = site: callback:
(builtins.mapAttrs (name: content:
if builtins.isAttrs content && content ? "__toString" then
html.addToHead content [ (elems.Stylesheet "/style.css") ]
callback content
else if builtins.isAttrs content then
linkStyle content
eachPage content callback
else
content) site);
applyFavicon = icon: site:
eachPage site (content:
html.addToHead content [
(elems.link {
rel = "shortcut icon";
href = icon;
})
]);
extractPaths = content: switchPaths content // { static = getPaths content; };
switchPaths = content:

View file

@ -69,6 +69,18 @@ in with html; [
actual = (para "").attrs.style;
}))
(it "needs no args to make string" (let p = tag "p";
in {
actual = toString p;
expected = "<p ></p>";
}))
(it "needs no content to make string" (let p = tag "p";
in {
actual = toString (p { class = "foobar"; });
expected = ''<p class="foobar"></p>'';
}))
(it "works recursively" (let
attrs = { style = { foo = "bar"; }; };
para = (tag "p" attrs);

View file

@ -1,15 +1,24 @@
msg:
{ actual, expected, asString ? false, asJSON ? false, removeDunders ? false, }:
if (if asString then
toString actual == toString expected
else if asJSON then
builtins.toJSON actual == builtins.toJSON expected
else if removeDunders then
builtins.removeAttrs actual [ "__toString" "__functor" ] == expected
else
actual == expected) then ''
let
preProcess = v:
if removeDunders then
builtins.removeAttrs v [ "__toString" "__functor" ]
else if asString then
toString v
else if asJSON then
builtins.toJSON v
else v;
a = preProcess actual;
e = preProcess expected;
in
if (a == e) then ''
echo 'it ${msg}'
'' else ''
''
else
''
echo 'FAILED: ${msg}'
echo '${builtins.toJSON expected}'
echo '${builtins.toJSON actual}'

View file

@ -2,6 +2,7 @@ let
html = import ../nixite/html.nix;
elems = import ../nixite/elems.nix;
site = import ../nixite/site.nix;
style = import ../nixite/style.nix;
it = import ./it.nix;
in with site; [
(it "applies a style" {
@ -42,6 +43,64 @@ in with site; [
};
asJSON = true;
})
(it "applies a favicon" {
expected = {
"index.html" = elems.html { } [
(elems.head { } [
(elems.title { } "foobar")
(elems.link {
rel = "shortcut icon";
href = ./src/favicon.png;
})
])
(elems.main { } "something")
];
blog = {
"index.html" = elems.html { } [
(elems.head { } [
(elems.title { } "foobar")
(elems.link {
rel = "shortcut icon";
href = ./src/favicon.png;
})
])
(elems.main { } "something")
];
};
};
actual = applyFavicon ./src/favicon.png {
"index.html" = elems.html { } [
(elems.head { } [ (elems.title { } "foobar") ])
(elems.main { } "something")
];
blog = {
"index.html" = elems.html { } [
(elems.head { } [ (elems.title { } "foobar") ])
(elems.main { } "something")
];
};
};
asJSON = true;
})
(it "extracts all styles" {
expected = {
"p.class" = {color = "blue";};
"a.class2" = {color = "green";};
};
actual = getStyles (let
p = style.tag "p" "class" {style = {color = "blue";};};
g = style.tag "a" "class2" {style = {color = "green";};};
in {
"index.html" = p "";
blog = {
"index.html" = g "";
};
});
removeDunders = true;
})
(it "extracts top level paths" {
actual = getPaths {
something = "";