forked from Fediversity/Fediversity
override page template for articles
This commit is contained in:
parent
00e3cfcb52
commit
9b74458a8c
|
@ -9,6 +9,7 @@
|
|||
let
|
||||
cfg = config;
|
||||
inherit (lib) mkOption types;
|
||||
inherit (types) submodule;
|
||||
|
||||
# https://html.spec.whatwg.org/multipage/dom.html#content-models
|
||||
# https://html.spec.whatwg.org/multipage/dom.html#kinds-of-content
|
||||
|
@ -43,7 +44,7 @@ let
|
|||
|
||||
# options with types for all the defined DOM elements
|
||||
element-types = lib.mapAttrs
|
||||
(name: value: mkOption { type = types.submodule value; })
|
||||
(name: value: mkOption { type = submodule value; })
|
||||
elements;
|
||||
|
||||
# attrset of categories, where values are module options with the type of the
|
||||
|
@ -52,7 +53,7 @@ let
|
|||
genAttrs
|
||||
content-categories
|
||||
(category:
|
||||
(mapAttrs (_: e: mkOption { type = types.submodule e; })
|
||||
(mapAttrs (_: e: mkOption { type = submodule e; })
|
||||
# HACK: don't evaluate the submodule types, just grab the config directly
|
||||
(filterAttrs (_: e: elem category (e { name = "dummy"; config = { }; }).config.categories) elements))
|
||||
);
|
||||
|
@ -118,7 +119,7 @@ let
|
|||
|
||||
mkAttrs = attrs: with lib;
|
||||
mkOption {
|
||||
type = types.submodule {
|
||||
type = submodule {
|
||||
options = global-attrs // attrs;
|
||||
};
|
||||
default = { };
|
||||
|
@ -147,12 +148,21 @@ let
|
|||
|
||||
print-element = name: attrs: content:
|
||||
with lib;
|
||||
# TODO: be smarter about content to save some space and repetition at the call sites
|
||||
squash (trim ''
|
||||
<${name}${print-attrs attrs}>
|
||||
${lib.indent " " content}
|
||||
</${name}>
|
||||
'');
|
||||
|
||||
toString-unwrap = e:
|
||||
with lib;
|
||||
if isAttrs e
|
||||
then toString (head (attrValues e))
|
||||
else if isList e
|
||||
then toString (map toString-unwrap e)
|
||||
else e;
|
||||
|
||||
elements = rec {
|
||||
document = { ... }: {
|
||||
imports = [ element ];
|
||||
|
@ -206,7 +216,7 @@ let
|
|||
# https://developer.mozilla.org/en-US/docs/Web/HTML/Viewport_meta_tag#viewport_width_and_screen_width
|
||||
# this should not exist and no one should ever have to think about it
|
||||
meta.viewport = mkOption {
|
||||
type = types.submodule ({ ... }: {
|
||||
type = submodule ({ ... }: {
|
||||
# TODO: figure out how to render only non-default values
|
||||
options = {
|
||||
width = mkOption {
|
||||
|
@ -422,21 +432,13 @@ let
|
|||
|
||||
config.categories = [ ];
|
||||
config.__toString = self: with lib;
|
||||
print-element name self.attrs (
|
||||
join "\n" (map
|
||||
(e:
|
||||
if isAttrs e
|
||||
then toString (lib.head (attrValues e))
|
||||
else e
|
||||
)
|
||||
self.content)
|
||||
);
|
||||
print-element name self.attrs (join "\n" (map toString-unwrap self.content));
|
||||
};
|
||||
|
||||
section = { config, name, ... }: {
|
||||
imports = [ element ];
|
||||
options = {
|
||||
# setting to an attribute set will wrap the section in <section>
|
||||
# setting to an attribute set will wrap the section in `<section>`
|
||||
attrs = mkOption {
|
||||
type = with types; nullOr (submodule { options = global-attrs; });
|
||||
default = null;
|
||||
|
@ -450,14 +452,18 @@ let
|
|||
# such an outline is rather meaningless without headings for navigation,
|
||||
# which is why we enforce headings in sections.
|
||||
# arguably, and this is encoded here, a section *is defined* by its heading.
|
||||
type = with types; submodule ({ ... }: {
|
||||
type = with types; submodule ({ config, ... }: {
|
||||
imports = [ element ];
|
||||
options = {
|
||||
attrs = mkAttrs { };
|
||||
# TODO: make `before`/`after` wrap the heading in `<hgroup>` if non-empty
|
||||
# setting to an attribute set will wrap the section in `<hgroup>`
|
||||
hgroup.attrs = mkOption {
|
||||
type = with types; nullOr (submodule { options = global-attrs; });
|
||||
default = with lib; mkIf (!isNull config.before || !isNull config.after) { };
|
||||
};
|
||||
# https://html.spec.whatwg.org/multipage/sections.html#the-hgroup-element
|
||||
before = mkOption {
|
||||
type = with types; listOf (attrTag ({ inherit p; } // categories.scripting));
|
||||
type = with types; listOf (attrTag ({ inherit (element-types) p; } // categories.scripting));
|
||||
default = [ ];
|
||||
};
|
||||
content = mkOption {
|
||||
|
@ -466,7 +472,7 @@ let
|
|||
};
|
||||
after = mkOption {
|
||||
type = with types;
|
||||
listOf (attrTag ({ inherit p; } // categories.scripting));
|
||||
listOf (attrTag ({ inherit (element-types) p; } // categories.scripting));
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
|
@ -489,20 +495,32 @@ let
|
|||
__toString = self: with lib;
|
||||
let
|
||||
n = toString config.heading-level;
|
||||
content = ''<h${n}${print-attrs self.heading.attrs}>${self.heading.content}</h${n}>
|
||||
'' + join "\n" (map
|
||||
(e:
|
||||
if isAttrs e
|
||||
then toString (lib.head (attrValues e))
|
||||
else e
|
||||
)
|
||||
self.content);
|
||||
heading = ''<h${n}${print-attrs self.heading.attrs}>${self.heading.content}</h${n}>'';
|
||||
hgroup = with lib; print-element "hgroup" self.heading.hgroup.attrs (squash ''
|
||||
${optionalString (!isNull self.heading.before) (toString-unwrap self.heading.before)}
|
||||
${heading}
|
||||
${optionalString (!isNull self.heading.after) (toString-unwrap self.heading.after)}
|
||||
'');
|
||||
content = if isNull self.heading.hgroup.attrs then heading else hgroup
|
||||
+ join "\n" (map toString-unwrap self.content);
|
||||
in
|
||||
if !isNull self.attrs
|
||||
then print-element name self.attrs content
|
||||
else content;
|
||||
};
|
||||
};
|
||||
|
||||
p = { name, ... }: {
|
||||
imports = [ element ];
|
||||
options = {
|
||||
attrs = mkAttrs { };
|
||||
content = mkOption {
|
||||
type = with types; either str (listOf (attrTag categories.phrasing));
|
||||
};
|
||||
};
|
||||
config.categories = [ "flow" "palpable" ];
|
||||
config.__toString = self: print-element name self.attrs (toString self.content);
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
|
|
|
@ -27,17 +27,21 @@ in
|
|||
};
|
||||
};
|
||||
config.name = lib.slug config.title;
|
||||
config.outputs.html = lib.mkForce (cfg.templates.html.dom {
|
||||
config.outputs.html = lib.mkForce ((cfg.templates.html.page config).override {
|
||||
html = {
|
||||
head = {
|
||||
title.text = config.title;
|
||||
meta.description = config.description;
|
||||
meta.authors = if lib.isList config.author then config.author else [ config.author ];
|
||||
link.canonical = lib.head config.locations;
|
||||
};
|
||||
body.content = [
|
||||
# TODO: make authors always a list
|
||||
head.meta.authors = if lib.isList config.author then config.author else [ config.author ];
|
||||
body.content = lib.mkForce [
|
||||
(cfg.menus.main.outputs.html config)
|
||||
{ section.heading.content = config.title; }
|
||||
{
|
||||
section.heading = {
|
||||
# TODO: i18n support
|
||||
# TODO: structured dates
|
||||
before = [{ p.content = "Published ${config.date}"; }];
|
||||
content = config.title;
|
||||
after = [{ p.content = "Written by ${config.author}"; }];
|
||||
};
|
||||
}
|
||||
(cfg.templates.html.markdown { inherit (config) name body; })
|
||||
];
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue