From f7db139b0dcceb81dbbb884966287f72ba5de32e Mon Sep 17 00:00:00 2001 From: Jean-Marie 'Histausse' Mineau Date: Wed, 17 Jun 2026 23:25:39 +0200 Subject: [PATCH] generate the summary and the document objects from inside the webpage() function --- lib/main.typ | 124 ++++++++++++++++++++----------- lib/rss.typ | 12 +-- lib/states.typ | 3 + lib/summary.typ | 49 +++++------- test_template/lib.typ | 4 +- test_template/main.typ | 30 ++------ test_template/main/index.html | 90 +++++++++++++++++++++- test_template/pages/cards.typ | 28 +++---- test_template/pages/index.typ | 21 +++--- test_template/pages/pyscript.typ | 17 ++--- 10 files changed, 234 insertions(+), 144 deletions(-) diff --git a/lib/main.typ b/lib/main.typ index 63eb3d5..942ded2 100644 --- a/lib/main.typ +++ b/lib/main.typ @@ -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, //-- 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 ("": pyscript-data-list("", { 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] } diff --git a/lib/rss.typ b/lib/rss.typ index 3ac6ef5..039edcd 100644 --- a/lib/rss.typ +++ b/lib/rss.typ @@ -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", diff --git a/lib/states.typ b/lib/states.typ index eefb695..762450f 100644 --- a/lib/states.typ +++ b/lib/states.typ @@ -61,3 +61,6 @@ reset-pyscript-page-states() } +// Site wide state + +#let state-page-summaries = state("state-page-summaries", ()) diff --git a/lib/summary.typ b/lib/summary.typ index 10a512f..fec744c 100644 --- a/lib/summary.typ +++ b/lib/summary.typ @@ -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() ) ) diff --git a/test_template/lib.typ b/test_template/lib.typ index 609cfdd..d8f3756 100644 --- a/test_template/lib.typ +++ b/test_template/lib.typ @@ -1,12 +1,14 @@ #import "@local/template-web:0.0.1": webpage as webpage-org, icons #let webpage = webpage-org.with( + base-url: "http://test.example.com", logo: image( "/assets/platypus.png", alt: "A drawing of a blue-ish round-ish platypus with big eyes, holding a laptop. This platypus is quite cute, but I might be biased.", height: 100pt, width: 100pt, // TODO 0.15 regression? in 0.14 setting the height was enough ), + author: "Me!", footer: context [ #sym.copyright #document.date.display("[year]") Histausse \ @@ -22,7 +24,7 @@ height: 2em, ) ),*/ - html.a(href: "http://test.example.com", aria-label: "Home", icons.home-icon), // /!\ aria-label is important for accessibility /!\ + html.a(href: "/", aria-label: "Home", icons.home-icon), // /!\ aria-label is important for accessibility /!\ html.a(href: "/feed.rss", aria-label: "RSS feed", icons.rss-icon), ), menu: [ diff --git a/test_template/main.typ b/test_template/main.typ index 95571b7..c848295 100644 --- a/test_template/main.typ +++ b/test_template/main.typ @@ -1,26 +1,8 @@ -#import "@local/template-web:0.0.1": rss - -#import "pages/index.typ": summ as summ-index -#document( - "index.html", - ..summ-index.document-args, - include "/pages/index.typ" -) - -#import "pages/pyscript.typ": summ as summ-pyscript -#document( - "pycript.html", - ..summ-pyscript.document-args, - include "/pages/pyscript.typ" -) - -#import "pages/cards.typ": summ as summ-cards, summaries -#document( - "cards.html", - ..summ-cards.document-args, - include "/pages/cards.typ" -) +#import "@local/template-web:0.0.1": rss, state-page-summaries +#include "/pages/index.typ" +#include "/pages/pyscript.typ" +#include "/pages/cards.typ" #asset( "/img/platypus.png", @@ -35,14 +17,14 @@ read("assets/isn_s_cube-0.1.0-py3-none-any.whl", encoding: none), ) -#asset( +#context asset( "feed.rss", rss( "TeTyTe test typst template", "https://test.example.com", "Test of the TTT template", "https://test.example.com/rss.rss", - summaries, + state-page-summaries.final(), webmaster: "me@example.com (Me)", ) ) diff --git a/test_template/main/index.html b/test_template/main/index.html index adcdf3d..52d0a24 100644 --- a/test_template/main/index.html +++ b/test_template/main/index.html @@ -1,4 +1,4 @@ -TeTyTe