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
',