|
1 | 1 | ---
|
2 | 2 | date created: 2024-06-06T22:54
|
3 |
| -date modified: 2025-03-18T16:24 |
| 3 | +date modified: 2025-03-18T22:25 |
4 | 4 | tags:
|
5 | 5 | - recents-exclude
|
6 | 6 | ---
|
@@ -41,6 +41,124 @@ Misc things to remember:
|
41 | 41 | > - [Credits and Readmes](https://morrowind-modding.github.io/credits-and-readmes/#eilleens-online-everything-notebook) on the Morrowind Modding Wiki
|
42 | 42 | > - [Quartz Cheatsheet](https://abi-is-here.github.io/niwa/software/quartz/quartz-cheatsheet) by abi-is-here
|
43 | 43 |
|
| 44 | +## Emitting a second RSS feed |
| 45 | + |
| 46 | +The normal one uses the default date type which for me is the modified date, which doesn't work well for me because I modify things all the time. So I'm emitting another one that sorts based on date created. |
| 47 | + |
| 48 | +> [!code]- contentIndex |
| 49 | +> ```tsx title="contentIndex.tsx" |
| 50 | +> function generateCreatedRSSFeed(cfg: GlobalConfiguration, idx: ContentIndexMap, limit?: number): string { |
| 51 | +> const base = cfg.baseUrl ?? "" |
| 52 | +> |
| 53 | +> const createURLEntry = (slug: SimpleSlug, content: ContentDetails): string => `<item> |
| 54 | +> <title>${escapeHTML(content.title)}</title> |
| 55 | +> <link>https://${joinSegments(base, encodeURI(slug))}</link> |
| 56 | +> <guid>https://${joinSegments(base, encodeURI(slug))}</guid> |
| 57 | +> <description>${content.richContent ?? content.description}</description> |
| 58 | +> <pubDate>${content.date?.toUTCString()}</pubDate> |
| 59 | +> </item>` |
| 60 | +> |
| 61 | +> const items = Array.from(idx) |
| 62 | +> .sort(([_, f1], [__, f2]) => { |
| 63 | +> const date1 = _getDateCustom(cfg, f1, 'created') |
| 64 | +> const date2 = _getDateCustom(cfg, f2, 'created') |
| 65 | +> if (date1 && date2) { |
| 66 | +> return date2.getTime() - date1.getTime() |
| 67 | +> } else if (date1 && !date2) { |
| 68 | +> return -1 |
| 69 | +> } else if (!date1 && date2) { |
| 70 | +> return 1 |
| 71 | +> } |
| 72 | +> |
| 73 | +> return f1.title.localeCompare(f2.title) |
| 74 | +> }) |
| 75 | +> .map(([slug, content]) => createURLEntry(simplifySlug(slug), content)) |
| 76 | +> .slice(0, limit ?? idx.size) |
| 77 | +> .join("") |
| 78 | +> |
| 79 | +> return `<?xml version="1.0" encoding="UTF-8" ?> |
| 80 | +> <rss version="2.0"> |
| 81 | +> <channel> |
| 82 | +> <title>${escapeHTML(cfg.pageTitle)}</title> |
| 83 | +> <link>https://${base}</link> |
| 84 | +> <description>${!!limit ? i18n(cfg.locale).pages.rss.lastFewNotes({ count: limit }) : i18n(cfg.locale).pages.rss.recentNotes} on ${escapeHTML( |
| 85 | +> cfg.pageTitle, |
| 86 | +> )}</description> |
| 87 | +> <generator>Quartz -- quartz.jzhao.xyz</generator> |
| 88 | +> ${items} |
| 89 | +> </channel> |
| 90 | +> </rss>` |
| 91 | +> } |
| 92 | +> |
| 93 | +> export const ContentIndex: QuartzEmitterPlugin<Partial<Options>> = (opts) => { |
| 94 | +> opts = { ...defaultOptions, ...opts } |
| 95 | +> return { |
| 96 | +> name: "ContentIndex", |
| 97 | +> async getDependencyGraph(ctx, content, _resources) { |
| 98 | +> const graph = new DepGraph<FilePath>() |
| 99 | +> |
| 100 | +> for (const [_tree, file] of content) { |
| 101 | +> const sourcePath = file.data.filePath! |
| 102 | +> |
| 103 | +> graph.addEdge( |
| 104 | +> sourcePath, |
| 105 | +> joinSegments(ctx.argv.output, "static/contentIndex.json") as FilePath, |
| 106 | +> ) |
| 107 | +> if (opts?.enableSiteMap) { |
| 108 | +> graph.addEdge(sourcePath, joinSegments(ctx.argv.output, "sitemap.xml") as FilePath) |
| 109 | +> } |
| 110 | +> if (opts?.enableRSS) { |
| 111 | +> graph.addEdge(sourcePath, joinSegments(ctx.argv.output, "index.xml") as FilePath) |
| 112 | +> graph.addEdge(sourcePath, joinSegments(ctx.argv.output, "index-created.xml") as FilePath) |
| 113 | +> } |
| 114 | +> } |
| 115 | +> |
| 116 | +> return graph |
| 117 | +> }, |
| 118 | +> ... |
| 119 | +> if (opts?.enableRSS) { |
| 120 | +> yield write({ |
| 121 | +> ctx, |
| 122 | +> content: generateRSSFeed(cfg, linkIndex, opts.rssLimit), |
| 123 | +> slug: (opts?.rssSlug ?? "index") as FullSlug, |
| 124 | +> ext: ".xml", |
| 125 | +> }) |
| 126 | +> yield write({ |
| 127 | +> ctx, |
| 128 | +> content: generateCreatedRSSFeed(cfg, linkIndex, opts.rssLimit), |
| 129 | +> slug: "index-created" as FullSlug, |
| 130 | +> ext: ".xml", |
| 131 | +> }) |
| 132 | +> } |
| 133 | +> ... |
| 134 | +> externalResources: (ctx) => { |
| 135 | +> if (opts?.enableRSS) { |
| 136 | +> return { |
| 137 | +> additionalHead: [ |
| 138 | +> <link |
| 139 | +> rel="alternate" |
| 140 | +> type="application/rss+xml" |
| 141 | +> title="RSS Feed" |
| 142 | +> href={`https://${ctx.cfg.configuration.baseUrl}/index.xml`} |
| 143 | +> />, |
| 144 | +> <link |
| 145 | +> rel="alternate" |
| 146 | +> type="application/rss+xml" |
| 147 | +> title="RSS Feed by Creation Time" |
| 148 | +> href={`https://${ctx.cfg.configuration.baseUrl}/index-created.xml`} |
| 149 | +> />, |
| 150 | +> ], |
| 151 | +> } |
| 152 | +> } |
| 153 | +> }, |
| 154 | +> } |
| 155 | +> } |
| 156 | +> ``` |
| 157 | +
|
| 158 | +## Upgrading to quartz 4.5 |
| 159 | +
|
| 160 | +[[Upgrading to quartz 4.5]] |
| 161 | +
|
44 | 162 | ## Superscript styling
|
45 | 163 |
|
46 | 164 | Sometimes a footnote will make the line spacing weird. [^1]
|
@@ -894,7 +1012,7 @@ async function mouseEnterHandler(
|
894 | 1012 |
|
895 | 1013 | I made a new solution for footnotes, inspired by aarnphm's site (e.g. [Attribution parameter decomposition](https://aarnphm.xyz/thoughts/Attribution-parameter-decomposition#user-content-fnref-alias)) The idea is to take just the content of the footnote, instead of showing the entire popover hint, so there's no duplicate `#user-content-fn` id on the page to jump to.
|
896 | 1014 |
|
897 |
| -**In `popovers.inline.ts`,** add this to the top: |
| 1015 | +In `popovers.inline.ts`, add this to the top: |
898 | 1016 |
|
899 | 1017 | ```ts
|
900 | 1018 | function isFootnoteLink(link: HTMLAnchorElement): boolean {
|
|
0 commit comments