summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/components/NewsIndex/NewsPreviewLink.astro3
-rw-r--r--src/i18n/translations/pages/rss.xml.ts15
-rw-r--r--src/lib/newsUtils.ts19
-rw-r--r--src/pages/[locale]/rss.xml.ts44
4 files changed, 75 insertions, 6 deletions
diff --git a/src/components/NewsIndex/NewsPreviewLink.astro b/src/components/NewsIndex/NewsPreviewLink.astro
index aa8a371..d698a7a 100644
--- a/src/components/NewsIndex/NewsPreviewLink.astro
+++ b/src/components/NewsIndex/NewsPreviewLink.astro
@@ -2,6 +2,7 @@
import translate from '$i18n/translate';
import tComponent from '$i18n/translations/components/newsIndex';
import getLocaleFromPath from '$lib/getLocaleFromPath';
+import { getHref } from '$lib/newsUtils';
import type { CollectionEntry } from 'astro:content';
interface Props {
@@ -14,7 +15,7 @@ const locale = getLocaleFromPath(Astro.url.pathname);
const t = translate(locale);
---
-<a class="news-index__item group-hover" href={`/${locale}/news/${newsItem.slug.replace('/', '-')}`}>
+<a class="news-index__item group-hover" href={getHref(newsItem)}>
<Fragment
set:html={`
<${headingLevel}>${newsItem.data.title}</${headingLevel}>
diff --git a/src/i18n/translations/pages/rss.xml.ts b/src/i18n/translations/pages/rss.xml.ts
new file mode 100644
index 0000000..919110d
--- /dev/null
+++ b/src/i18n/translations/pages/rss.xml.ts
@@ -0,0 +1,15 @@
+import type { TranslationsDictionary } from '$types/TranslationsDictionary';
+
+const tFeed = {
+ title: {
+ sco: () => 'Scots Leid Associe News',
+ 'en-GB': () => 'Scots Language Society News',
+ },
+ description: {
+ sco: () => 'The latest updates frae the Scots Leid Associe',
+ 'en-GB': () => 'The latest updates from the Scots Language Society',
+ },
+};
+
+type Raw = typeof tFeed;
+export default tFeed as TranslationsDictionary<Raw>;
diff --git a/src/lib/newsUtils.ts b/src/lib/newsUtils.ts
index ededb52..aa711e3 100644
--- a/src/lib/newsUtils.ts
+++ b/src/lib/newsUtils.ts
@@ -11,15 +11,24 @@ export async function getMostRecentNewsItem(locale: Locale) {
return allNewsInLocale.reduce((prev, curr) => (isBefore(curr, prev) ? curr : prev), someNewsItem);
}
-export function isNewsItemInLocale(newsItem: CollectionEntry<'news'>, locale: Locale) {
+export function getLocale(newsItem: CollectionEntry<'news'>) {
const srcPath = newsItem.id;
- const newsItemLocale = srcPath.slice(0, srcPath.indexOf('/'));
+ return srcPath.slice(0, srcPath.indexOf('/'));
+}
+
+export function getHref(newsItem: CollectionEntry<'news'>) {
+ const locale = getLocale(newsItem);
+ return `/${locale}/news/${newsItem.slug.replace('/', '-')}`;
+}
+
+export function isNewsItemInLocale(newsItem: CollectionEntry<'news'>, locale: Locale) {
+ const newsItemLocale = getLocale(newsItem);
return newsItemLocale === locale;
}
function isBefore(item1: CollectionEntry<'news'>, item2: CollectionEntry<'news'>) {
- const date1 = dateOf(item1);
- const date2 = dateOf(item2);
+ const date1 = getDate(item1);
+ const date2 = getDate(item2);
if (!date2) {
return false;
}
@@ -29,7 +38,7 @@ function isBefore(item1: CollectionEntry<'news'>, item2: CollectionEntry<'news'>
return date1.valueOf() < date2.valueOf();
}
-function dateOf(newsItem: CollectionEntry<'news'>) {
+export function getDate(newsItem: CollectionEntry<'news'>) {
const match = newsItem.id.match(/(?<=(en-GB|sco))\/(\d\d\d\d-\d\d-\d\d)/)?.[2];
return match ? new Date(match) : null;
}
diff --git a/src/pages/[locale]/rss.xml.ts b/src/pages/[locale]/rss.xml.ts
new file mode 100644
index 0000000..be2cab6
--- /dev/null
+++ b/src/pages/[locale]/rss.xml.ts
@@ -0,0 +1,44 @@
+import rss, { RSSFeedItem } from '@astrojs/rss';
+import { CollectionEntry, getCollection } from 'astro:content';
+import { getDate, getHref, isNewsItemInLocale } from '$lib/newsUtils';
+import localeStaticPaths from '$lib/localeStaticPaths';
+import getLocaleFromPath from '$lib/getLocaleFromPath';
+import type { APIContext } from 'astro';
+import translate from '$i18n/translate';
+import tFeed from '$i18n/translations/pages/rss.xml';
+
+export async function get(context: APIContext) {
+ const locale = getLocaleFromPath(context.url.pathname);
+ const t = translate(locale);
+ const news = (await getCollection('news')).filter((item) => isNewsItemInLocale(item, locale));
+ const site = context.site;
+ if (!site) {
+ throw new Error('No site provided in Astro configuration');
+ }
+
+ return rss({
+ title: t(tFeed, { key: 'title' }),
+ description: t(tFeed, { key: 'description' }),
+ site,
+ items: news.map(newsItemToRssFeedItem),
+ customData: `<language>${locale}</language>`,
+ });
+}
+
+function newsItemToRssFeedItem(item: CollectionEntry<'news'>): RSSFeedItem {
+ const pubDate = getDate(item);
+ if (!pubDate) {
+ throw new Error(`Could not determine publication date of ${item}`);
+ }
+
+ return {
+ link: getHref(item),
+ title: item.data.title,
+ description: item.data.summary,
+ pubDate,
+ };
+}
+
+export async function getStaticPaths() {
+ return localeStaticPaths;
+}