Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions stacklets/memory/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ COPY quartz/components/FamilyCrumbs.tsx ./quartz/components/FamilyCrumbs.tsx
COPY quartz/components/scripts/familyNav.inline.ts ./quartz/components/scripts/familyNav.inline.ts
COPY quartz/plugins/familyLists.tsx ./quartz/plugins/emitters/familyLists.tsx
COPY quartz/plugins/vaultLinks.ts ./quartz/plugins/transformers/vaultLinks.ts
COPY quartz/plugins/listTitles.ts ./quartz/plugins/transformers/listTitles.ts
# The shipped ontology, for the topic areas a vault installed earlier
# does not name yet (see readOntology in familyModel.ts).
COPY seeds/ontology.toml ./ontology.seed.toml
Expand Down
22 changes: 22 additions & 0 deletions stacklets/memory/quartz/components/familyModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ const LABELS = {
menu: "Menu",
start: "Start",
recent: "Recent",
lists: "Lists",
list: "List",
diary: "Diary",
people: "People",
topics: "Topics",
Expand Down Expand Up @@ -75,6 +77,8 @@ const LABELS = {
menu: "Menü",
start: "Start",
recent: "Aktuell",
lists: "Listen",
list: "Liste",
diary: "Tagebuch",
people: "Personen",
topics: "Themen",
Expand Down Expand Up @@ -118,6 +122,11 @@ const LABELS = {

export const L = LABELS[lang]

// A list is often named for what it is about ("Camping"), which reads as
// the topic. Its title says it is a list, unless the family's name for it
// already does ("Einkaufsliste", "Packing list").
export const listTitle = (title: string) => (/list/i.test(title) ? title : `${title} ${L.list}`)

export const locale = lang === "de" ? "de-DE" : "en-US"
const dateFormat = new Intl.DateTimeFormat(locale, { day: "numeric", month: "short", year: "numeric" })
export const fmtDate = (d: Date) => dateFormat.format(d)
Expand Down Expand Up @@ -392,6 +401,7 @@ function build(ctx: BuildCtx, allFiles: QuartzPluginData[]): Model {
const records: Rec[] = []
const recTopics = new Map<string, Topic[]>()
const people: NavNode[] = []
const familyLists: NavNode[] = []
const diaryYears = new Map<string, { slug: string; label: string; months: NavNode[] }>()
let diaryRoot: string | undefined

Expand Down Expand Up @@ -419,6 +429,16 @@ function build(ctx: BuildCtx, allFiles: QuartzPluginData[]): Model {
continue
}

// family lists: <bucket>/lists/<slug>, counted by their open items;
// the archive of ticked items below it is not a list of its own
if (segs[0] === bucket && segs[1] === "lists") {
if (segs.length === 3 && meta.type === "list") {
const open = openTasks(readText(ctx, f)).length
familyLists.push({ label: String(meta.title ?? segs[2]), slug, count: open || undefined })
}
continue
}

// topic folders: about page and task list
if (segs[0] === bucket && segs.length === 3 && !KIND_FOLDERS.has(segs[1])) {
const t = folderTopic(segs[1])
Expand Down Expand Up @@ -632,6 +652,8 @@ function build(ctx: BuildCtx, allFiles: QuartzPluginData[]): Model {
// ── assemble, in the agreed order ──
const nav: NavNode[] = [{ key: "start", label: L.start, slug: "index" }]
if (recent.length) nav.push({ key: "recent", label: L.recent, open: true, children: recent.map(topicNode) })
if (familyLists.length)
nav.push({ key: "lists", label: L.lists, children: familyLists.sort((a, b) => a.label.localeCompare(b.label, lang)) })
if (diaryRoot || diaryYears.size) {
const yearsDesc = [...diaryYears.values()].sort((a, b) => Number(b.label) - Number(a.label))
nav.push({
Expand Down
22 changes: 22 additions & 0 deletions stacklets/memory/quartz/plugins/listTitles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { QuartzTransformerPlugin } from "../types"
import { listTitle } from "../../components/familyModel"

// NEW TRANSFORMER (not an upstream override).
//
// A family list is titled the way the family named it, often for what it
// is about: "Camping". On its own page that reads as the topic, so a list
// page says it is a list ("Camping Liste"). The title is set here, once,
// so the page heading, the browser tab, search and the menu all agree.
// The file in the vault keeps the family's own title.

export const ListTitles: QuartzTransformerPlugin = () => ({
name: "ListTitles",
markdownPlugins() {
return [
() => (_tree, file) => {
const fm = file.data.frontmatter
if (fm?.type === "list" && typeof fm.title === "string") fm.title = listTitle(fm.title)
},
]
},
})
3 changes: 3 additions & 0 deletions stacklets/memory/quartz/quartz.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { QuartzConfig } from "./quartz/cfg"
import * as Plugin from "./quartz/plugins"
import { FamilyLists } from "./quartz/plugins/emitters/familyLists"
import { VaultLinks } from "./quartz/plugins/transformers/vaultLinks"
import { ListTitles } from "./quartz/plugins/transformers/listTitles"

// Runtime env. `WIKI_HOST` is "memory.<domain>" in domain mode and
// the empty-domain rendering "memory." in port mode — we treat the
Expand Down Expand Up @@ -123,6 +124,8 @@ const config: QuartzConfig = {
plugins: {
transformers: [
Plugin.FrontMatter(),
// A list page's title says it is a list; needs the frontmatter read.
ListTitles(),
// The vault is a git repo — let git timestamps win over
// filesystem mtime so a fresh clone shows real commit dates.
Plugin.CreatedModifiedDate({
Expand Down
Loading