From 2d9312b49f4fc200d45301ee0d57372c65cc6f07 Mon Sep 17 00:00:00 2001 From: Oscar Otero Date: Fri, 28 Apr 2023 21:34:06 +0200 Subject: [PATCH] improved feed plugin --- plugins/feed.ts | 54 +++++++++++++++------------ plugins/utils.ts | 32 ++++++++++------ tests/__snapshots__/feed.test.ts.snap | 20 +++++----- 3 files changed, 62 insertions(+), 44 deletions(-) diff --git a/plugins/feed.ts b/plugins/feed.ts index 58c01d5e..25cc941a 100644 --- a/plugins/feed.ts +++ b/plugins/feed.ts @@ -46,11 +46,11 @@ export const defaults: Options = { generator: true, }, items: { - title: "title", - description: "description", - date: "date", - content: "children", - lang: "lang", + title: "=title", + description: "=description", + date: "=date", + content: "=children", + lang: "=lang", }, }; @@ -81,7 +81,7 @@ export default (userOptions?: DeepPartial) => { return (site: Site) => { const search = new Search(site, true); - site.addEventListener("afterRender", () => { + site.addEventListener("beforeSave", () => { const output = Array.isArray(options.output) ? options.output : [options.output]; @@ -91,30 +91,31 @@ export default (userOptions?: DeepPartial) => { options.sort, options.limit, ) as Data[]; - const { info } = options; + + const { info, items } = options; + const rootData = site.source.data.get("/") || {}; const feed: FeedData = { - title: info.title, - description: info.description, - date: info.date, - lang: info.lang, + title: getDataValue(rootData, info.title), + description: getDataValue(rootData, info.description), + date: getDataValue(rootData, info.date), + lang: getDataValue(rootData, info.lang), url: site.url("", true), generator: info.generator === true ? defaultGenerator : info.generator || undefined, items: pages.map((data): FeedItem => { + const content = getDataValue(data, items.content)?.toString(); + const pageUrl = site.url(data.url as string, true); + const fixedContent = fixUrls(new URL(pageUrl), content || ""); + return { - title: options.items.title && - getDataValue(data, `=${options.items.title}`), + title: getDataValue(data, items.title), url: site.url(data.url as string, true), - description: options.items.description && - getDataValue(data, `=${options.items.description}`), - date: options.items.date && - getDataValue(data, `=${options.items.date}`), - content: options.items.content && - getDataValue(data, `=${options.items.content}`)?.toString(), - lang: options.items.lang && - getDataValue(data, `=${options.items.lang}`), + description: getDataValue(data, items.description), + date: getDataValue(data, items.date), + content: fixedContent, + lang: getDataValue(data, items.lang), }; }), }; @@ -142,6 +143,13 @@ export default (userOptions?: DeepPartial) => { }; }; +function fixUrls(base: URL, html: string): string { + return html.replaceAll( + /\s(href|src)="([^"]+)"/g, + (_match, attr, value) => ` ${attr}="${new URL(value, base).href}"`, + ); +} + function generateRss(data: FeedData, file: string): string { const feed = { [$XML]: { cdata: [["rss", "channel", "item", "content:encoded"]] }, @@ -166,7 +174,7 @@ function generateRss(data: FeedData, file: string): string { "@type": "application/rss+xml", }, description: data.description, - lastBuildDate: data.date.toISOString(), + lastBuildDate: data.date.toUTCString(), language: data.lang, generator: data.generator, item: data.items.map((item) => ({ @@ -178,7 +186,7 @@ function generateRss(data: FeedData, file: string): string { }, description: item.description, "content:encoded": item.content, - pubDate: item.date.toISOString(), + pubDate: item.date.toUTCString(), })), }, }, diff --git a/plugins/utils.ts b/plugins/utils.ts index 997abd0c..f580d84d 100644 --- a/plugins/utils.ts +++ b/plugins/utils.ts @@ -7,23 +7,33 @@ import type { Data } from "../core.ts"; /** * Get the value of a page data * For example, if the value is "=title", it will return the value of the page data "title" + * If the value is "$.title", it will return the value of the element with the selector ".title" */ export function getDataValue(data: Data, value?: unknown) { // Get the value from the page data - if (typeof value === "string" && value.startsWith("=")) { - const key = value.slice(1); + if (typeof value === "string") { + if (value.startsWith("=")) { + const key = value.slice(1); - if (!key.includes(".")) { - return data[key]; + if (!key.includes(".")) { + return data[key]; + } + + const keys = key.split("."); + let val = data; + for (const key of keys) { + val = val?.[key]; + } + return val; } - const keys = key.split("."); - let val = data; - for (const key of keys) { - val = val[key]; + if (value.startsWith("$")) { + const document = data.page?.document; + const query = value.slice(1); + const element = document?.querySelector(query); + return element?.innerHTML; } - return val; - } else { - return value; } + + return value; } diff --git a/tests/__snapshots__/feed.test.ts.snap b/tests/__snapshots__/feed.test.ts.snap index 2e020dee..cc8aa548 100644 --- a/tests/__snapshots__/feed.test.ts.snap +++ b/tests/__snapshots__/feed.test.ts.snap @@ -108,7 +108,7 @@ snapshot[`RSS plugin 5`] = ` https://example.com/ - 2020-01-01T00:00:00.000Z + Wed, 01 Jan 2020 00:00:00 GMT en https://lume.land @@ -117,7 +117,7 @@ snapshot[`RSS plugin 5`] = ` https://example.com/pages/subpage/page7/ - 2022-01-02T00:00:00.000Z + Sun, 02 Jan 2022 00:00:00 GMT Page 6 @@ -128,7 +128,7 @@ snapshot[`RSS plugin 5`] = ` Content of Page 6

]]> - 2022-01-01T00:00:00.000Z + Sat, 01 Jan 2022 00:00:00 GMT
Page 4 @@ -136,7 +136,7 @@ snapshot[`RSS plugin 5`] = ` https://example.com/pages/page4/ - 2021-01-02T18:32:00.000Z + Sat, 02 Jan 2021 18:32:00 GMT Page 2 @@ -144,7 +144,7 @@ snapshot[`RSS plugin 5`] = ` https://example.com/overrided-page2/ - 2020-06-21T00:00:00.000Z + Sun, 21 Jun 2020 00:00:00 GMT ', @@ -157,7 +157,7 @@ snapshot[`RSS plugin 5`] = ` https://example.com/ - 2020-01-01T00:00:00.000Z + Wed, 01 Jan 2020 00:00:00 GMT en https://lume.land @@ -166,7 +166,7 @@ snapshot[`RSS plugin 5`] = ` https://example.com/pages/subpage/page7/ - 2022-01-02T00:00:00.000Z + Sun, 02 Jan 2022 00:00:00 GMT Page 6 @@ -177,7 +177,7 @@ snapshot[`RSS plugin 5`] = ` Content of Page 6

]]> - 2022-01-01T00:00:00.000Z + Sat, 01 Jan 2022 00:00:00 GMT
Page 4 @@ -185,7 +185,7 @@ snapshot[`RSS plugin 5`] = ` https://example.com/pages/page4/ - 2021-01-02T18:32:00.000Z + Sat, 02 Jan 2021 18:32:00 GMT Page 2 @@ -193,7 +193,7 @@ snapshot[`RSS plugin 5`] = ` https://example.com/overrided-page2/ - 2020-06-21T00:00:00.000Z + Sun, 21 Jun 2020 00:00:00 GMT ',