generate the summary and the document objects from inside the webpage() function

This commit is contained in:
Jean-Marie 'Histausse' Mineau 2026-06-17 23:25:39 +02:00
parent 500a6ad181
commit f7db139b0d
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2
10 changed files with 234 additions and 144 deletions

View file

@ -2,7 +2,7 @@
#import "./html_body.typ": html-body
#import "./html_utils.typ": html-show, reset-page-states
#import "./summary.typ": summary, card-list
#import "./states.typ": current-page-label
#import "./states.typ": current-page-label, state-page-summaries
#import "./pyscript.typ": state-use-pyscript, state-pyscript-data-list, state-pyscript-version, state-pyscript-interpreters, state-pyscript-default-interpreter, pyscript-show, pyscript-data
#import "./rss.typ": rss
#import "./icons.typ"
@ -14,10 +14,18 @@
base-url: none,
/// The url path of the page (full url of the page is base-url + path), eg: "/index.html"
path: none,
/// Title of the page, default to document.title
/// Title of the page
title: none,
/// Use only for html 'lang' attribute.
lang: "en",
/// Date of publication
date: none,
/// Label of the page (for links)
page-label: none,
/// Preview image
preview-image: [],
/// The copyright for the preview image
preview-img-copyright: none,
//-- <head> only args --
/// Website icon, *needs* to be path (TODO: fix when typst support multi-file out)
icon: none,
@ -25,9 +33,9 @@
og-type: "website",
/// Name of the site for metadata of the page
site-name: none,
/// Description of the site for metadata, default to document.description
/// Description of the site for metadata
description: none,
/// Author of the site for metadata, default to document.author
/// Author of the site for metadata
author: none,
/// Tags describing the content of the page
tags: (),
@ -35,8 +43,6 @@
stylesheets: (),
/// List of related sites for metadata
me-links: (),
/// Label of the page (for links)
page-label: none,
/// Dictionnary of available pyscript-data for each versions of pyscript
/// expected in the form of ("<version>": pyscript-data-list("<url>", { html.link(...) }), ...)
pyscript-data-list: (:),
@ -63,42 +69,76 @@
) = {
assert(type(base-url) == str, message: "A page must have a base url")
assert(type(path) == str, message: "A page must have a path")
assert(type(title) == str or type(title) == content, message: "A page must have title")
//assert(type(preview-image) != none, message: "summary() must have a preview-image")
assert(author != none, message: "A page must have at least one author")
assert(description != none, message: "A page must have a description")
assert(date != none, message: "A page must have a date")
context {
state-pyscript-data-list.update(x => pyscript-data-list)
state-pyscript-interpreters.update(x => pyscript-interpreters)
state-pyscript-version.update(x => pyscript-version)
state-pyscript-default-interpreter.update(x => pyscript-default-interpreter)
if page-label == none {
page-label = label(path)
}
show: html-show
show raw.where(block: true, lang: "python-run"): pyscript-show
current-page-label.update(x => page-label)
html.html(lang: lang, {
html-head(
base-url,
path,
title,
page-label,
icon: icon,
og-type: og-type,
site-name: site-name,
description: description,
author: author,
tags: tags,
stylesheets: stylesheets,
me-links: me-links
)
html-body(
logo: logo,
header: header,
footer: footer,
nav-elements: nav-elements,
menu: menu,
[
#body
#metadata("end of page " + str(page-label)) #label(str(page-label) + "-end")
]
)
reset-page-states()
})
state-page-summaries.update(
x => x + (
summary(
url: base-url + path,
title: title,
preview-image: preview-image,
img-copyright: preview-img-copyright,
author: author,
description: description,
date: date,
tags: tags,
page-label: page-label,
)
,)
)
[#document(
path,
title: title,
//author: author,
description: description,
date: date,
{
context {
state-pyscript-data-list.update(x => pyscript-data-list)
state-pyscript-interpreters.update(x => pyscript-interpreters)
state-pyscript-version.update(x => pyscript-version)
state-pyscript-default-interpreter.update(x => pyscript-default-interpreter)
}
show: html-show
show raw.where(block: true, lang: "python-run"): pyscript-show
current-page-label.update(x => page-label)
html.html(lang: lang, {
html-head(
base-url,
path,
title,
page-label,
icon: icon,
og-type: og-type,
site-name: site-name,
description: description,
author: author,
tags: tags,
stylesheets: stylesheets,
me-links: me-links
)
html-body(
logo: logo,
header: header,
footer: footer,
nav-elements: nav-elements,
menu: menu,
[
#body
#metadata("end of page " + str(page-label)) #label(str(page-label) + "-end")
]
)
reset-page-states()
})
}
) #page-label]
}

View file

@ -63,12 +63,12 @@
).map(it => xml-tag(
"item",
children: (
xml-tag("title", body: it.document-args.title),
xml-tag("link", body: it.template-args.base-url + it.template-args.path),
xml-tag("guid", body: it.template-args.base-url + it.template-args.path),
xml-tag("description", body: it.document-args.description),
xml-tag("pubDate", body: it.document-args.date.display(date-format-rfc822)),
) + it.template-args.tags.map(tag => xml-tag("category", body: tag))
xml-tag("title", body: it.title),
xml-tag("link", body: it.url),
xml-tag("guid", body: it.url),
xml-tag("description", body: it.description),
xml-tag("pubDate", body: it.date.display(date-format-rfc822)),
) + it.tags.map(tag => xml-tag("category", body: tag))
))
xml-tag(
"rss",

View file

@ -61,3 +61,6 @@
reset-pyscript-page-states()
}
// Site wide state
#let state-page-summaries = state("state-page-summaries", ())

View file

@ -81,18 +81,18 @@
```
chtml.summary-card({
chtml.summary-card-preview({
link(summ.template-args.page-label, summ.preview-image)
link(summ.page-label, summ.preview-image)
if summ.img-copyright != none {
html.small[Image: #sym.copyright #summ.img-copyright]
}
})
chtml.summary-card-description({
heading(level: 2, link(summ.template-args.page-label, summ.document-args.title))
heading(level: 2, link(summ.page-label, summ.title))
link(summ.template-args.page-label, summ.document-args.description)
link(summ.page-label, summ.description)
chtml.summary-card-details(summ.document-args.date.display())
chtml.tag-box(for tag in summ.template-args.tags { html.span(class: ("tag",), "#" + tag) })
chtml.summary-card-details(summ.date.display())
chtml.tag-box(for tag in summ.tags { html.span(class: ("tag",), "#" + tag) })
})
})
}
@ -101,10 +101,8 @@
/// Store data form `set document(...)` and `show: webpage.with(...)` in `summ.document-args` and `summ.template-args`,
/// and generate a summary card that can be used as a link for the page.
#let summary(
/// The base url of the site (eg: "http://test.example.com")
base-url: none,
/// The url path of the page (full url of the page is base-url + path), eg: "/index.html"
path: none,
/// The url of the page
url: none,
/// The title of the page
title: none,
/// The image preview of the page.
@ -124,31 +122,24 @@
/// Label of the page (for links)
page-label: none,
) = {
assert(type(base-url) == str, message: "summary() must have a base url")
assert(type(path) == str, message: "summary() must have a path")
assert(type(url) == str, message: "summary() must have an url")
assert(type(title) == str or type(title) == content, message: "summary() must have title")
assert(type(preview-image) != none, message: "summary() must have a preview-image")
assert(type(author) != none, message: "summary() must have at least one author")
assert(type(description) != none, message: "summary() must have a description")
assert(type(date) != none, message: "summary() must have a date")
assert(author != none, message: "summary() must have at least one author")
assert(description != none, message: "summary() must have a description")
assert(date != none, message: "summary() must have a date")
if page-label == none {
page-label = label(path)
}
let summ = (
document-args: (
title: title,
author: author,
description: description,
date: date,
),
template-args: (
base-url: base-url,
path: path,
tags: tags,
page-label: page-label,
),
url: url,
title: title,
description: description,
date: date,
tags: tags,
page-label: page-label,
path: path,
preview-image: preview-image,
img-copyright: img-copyright,
@ -159,9 +150,9 @@
}
#let summary-sort-key(summ) = -(
summ.document-args.date.day()-1 + 31 * (
(summ.document-args.date.month()-1) +
12 * summ.document-args.date.year()
summ.date.day()-1 + 31 * (
(summ.date.month()-1) +
12 * summ.date.year()
)
)