From 890b076bf6a87763b4ca9ac5c9e2e6966100a79d Mon Sep 17 00:00:00 2001 From: "Thomas F. K. Jorna" Date: Fri, 6 Nov 2026 15:01:14 +0100 Subject: [PATCH] feat(site): article pages show the pub's image as a band behind the header, and the take-home message and purpose beside the text --- apps/site/src/components/ArticleNotes.astro | 58 +++++++++++++++++++++ apps/site/src/layouts/JournalArticle.astro | 22 +++++++- apps/site/src/lib/journal-article.ts | 35 +++++++++++-- 3 files changed, 110 insertions(+), 5 deletions(-) create mode 100644 apps/site/src/components/ArticleNotes.astro diff --git a/apps/site/src/components/ArticleNotes.astro b/apps/site/src/components/ArticleNotes.astro new file mode 100644 index 00000000..ad1690ec --- /dev/null +++ b/apps/site/src/components/ArticleNotes.astro @@ -0,0 +1,58 @@ +--- +import { Icon } from "astro-icon/components"; +import { stripHtml } from "~/lib/format"; +import type { ArticleNote } from "~/lib/journal-article"; +import { decodeEntities } from "~/lib/sources/journal"; + +/* + * The take-home message and purpose of an empirical article: about the + * article rather than part of it, so they sit beside the text. A long note + * shows its first lines and opens on click. + */ + +interface Props { + notes: ArticleNote[]; + /** Leave out the ids in the notes' HTML, for a second copy on the same page */ + copy?: boolean; + class?: string; +} + +const { notes, copy = false, class: className } = Astro.props; + +/** Notes longer than this many words start closed */ +const OPEN_UP_TO = 70; +const PREVIEW_WORDS = 28; + +const preview = (note: ArticleNote) => `${decodeEntities(stripHtml(note.html)).split(" ").slice(0, PREVIEW_WORDS).join(" ")}…`; +const html = (note: ArticleNote) => (copy ? note.html.replace(/\sid="[^"]*"/g, "") : note.html); +const text = "journal-body prose prose-sm max-w-none [--tw-prose-body:var(--color-ink)] prose-p:my-2 first:prose-p:mt-0 last:prose-p:mb-0"; +const title = "font-heading text-sm font-bold tracking-wide text-journal uppercase"; +--- + +{ + notes.length > 0 && ( +
+ {notes.map((note) => + note.words > OPEN_UP_TO ? ( +
+ + +

{note.title}

+
+ +
+
+
+ ) : ( +
+

{note.title}

+
+
+ ), + )} +
+ ) +} diff --git a/apps/site/src/layouts/JournalArticle.astro b/apps/site/src/layouts/JournalArticle.astro index ba1aa21e..f1443d63 100644 --- a/apps/site/src/layouts/JournalArticle.astro +++ b/apps/site/src/layouts/JournalArticle.astro @@ -1,8 +1,10 @@ --- import { Icon } from "astro-icon/components"; import ArticleCard from "~/components/ArticleCard.astro"; +import ArticleNotes from "~/components/ArticleNotes.astro"; import Downloads from "~/components/Downloads.astro"; import JournalNav from "~/components/JournalNav.astro"; +import Picture from "~/components/Picture.astro"; import SocialIcon from "~/components/SocialIcon.astro"; import { formatDate, listNames } from "~/lib/format"; import type { ArticleDetails } from "~/lib/journal-article"; @@ -78,8 +80,22 @@ const meta = { + { + // The pub's image from PubPub, as a band behind the top of the page + article.image && ( + + ) + } +
-
+
{article.kind && {article.kind}} { @@ -142,6 +158,7 @@ const meta = { ) } +