diff options
| -rw-r--r-- | src/components/NewsIndex/NewsPreviewLink.astro | 3 | ||||
| -rw-r--r-- | src/i18n/translations/pages/rss.xml.ts | 15 | ||||
| -rw-r--r-- | src/lib/newsUtils.ts | 19 | ||||
| -rw-r--r-- | src/pages/[locale]/rss.xml.ts | 44 |
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; +} |
