てっくらのーとは、触れた技術のメモと日常の記録が少し合わさった個人のサイトです。
RSSフィードを生成するようにした
https://tech.mkr-note.net/rss.xml
でRSSフィードを作成するようにした。未だ?にRSSフィードを愛用している自分用となっている。読みたいWebサイトの巡回とか皆どうしているのだろうか。今の時代だと「話題はSNSでキャッチアップ!」でどうたら…という話題になりそうな気もするけど、全てがSNSで完結するわけでもないと思うので、単純な疑問として存在している。そもそももう PC でWebサイトを巡回するしぐさがおじさん的な行為なのだろうか。
Astro の RSSフィード生成は @astrojs/rss
パッケージを使用して実装することができる。ドキュメントも用意されているので、基本的にはこちらに準じた。記事エントリの名前(title
)やエントリURL(link
)を詰める items
リストは基本的にファイル生成時に自動的に保管してもらうことを目指すことになる。ドキュメント内では glob
を使用するパターンと、コンテンツコレクション
を使用するパターンが紹介されていた。
glob を使用するパターン
pagesGlobToRssItems()
を利用して、ディレクトリに存在する md
or mdx
拡張子のファイルから Frontmatter の情報を収集し、そのまま RSS の items
として当てはめている動作だった。
最初はこれで実装しようかなと思っていたが、そのまま Frontmatter を引っ張ってくるため、Frontmatter の要素と RSS を構成する上で必須となる items 要素 が一致しなくてはいけない。ここで必須となる要素のうちの一つ、pubDate
が記事ファイルの Frontmatter に含まれていなかったため、単純に書くだけではダメそうだった。
コンテンツコレクションを使用するパターン
コンテンツコレクションは src/content
配下にフォルダを作成して、そのフォルダ配下の md
or mdx
ファイルに対してデータコレクションを作成し、そのコレクションから情報を引っ張り出して、他のものに使用していこうという機能らしい。以前ドキュメントを見たときに使ってみたいな、と思っていたことおあったのでこちらも試してみることにした。
コンテンツコレクションの作成
コンテンツコレクションは、src/content/config.ts
より作成する。コレクションとして作成したい情報をこちらに記載することになる。
- src/content/config.ts
import { z, defineCollection } from 'astro:content';
const blogCollection = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
date: z.date(),
}),
})
export const collections = {
'blog': blogCollection,
};
公式ドキュメントに記載されているものをほぼそのまま使用させてもらっている。JS/TSが全くわからないため import
の書き方に対して全くしっくり来ていない…。それは置いておいて、内容からなんとなくやりたいことはわかったのでよしとする。z
は TS のスキーマを検証するライブラリ colinhacks/zod
のようで、astro が内部的に使用しているものとのこと。
コンテンツコレクションのためのディレクトリ
src/content
に直接md
or mdx
ファイルを置くのではなく、コレクション毎にディレクトリを作成するよう記載があるのでそのようにする。上記のコードで blog
を指定しているので、src/content/blog/
ディレクトリを新しく切り、その中にmd
or mdx
ファイルを配置している。
RSSの生成
次に RSS を生成する。RSS は上述の @astrojs/rss
を使用して生成するために、src/pages/rss.xml.js
を作成する。
- src/pages/rss/xml.js
import rss from '@astrojs/rss';
import { getCollection } from 'astro:content';
export async function GET(context) {
const blog = await getCollection('blog');
return rss({
title: 'まっくらのーと',
description: 'ここは説明です。',
site: context.site,
items: blog.map((post) => ({
title: post.data.title,
pubDate: post.data.date,
link: `${post.slug}/`,
})),
customData: '<language>ja-JP</language>',
});
}
こちらも公式ドキュメントほぼそのまま。items
の要素を少しいじったくらい。何も分からない状態ではあるけど、getCollection()
で生成したコレクションを持ってきて、items
に要素を詰め込んでいることぐらいはわかるのでこちらもよしとする。
link で使用しているslug
は、こちらに説明がある。ファイル名からページURLにも使用される文字列を生成していてslug
に格納される。上記ではそれを直接 link に指定している。
RSSフィードのリンクの修正
astro.config.mjs
の site
を本ブログのURLに修正する。ここが <channel>><link>
の要素になる。
おわりに
自分用メモとして RSS 生成するためにやったことを整理した。いくつかのコードを記載する必要はあったがドキュメントに記載されていたおかげで、まあまあ楽に実装できたのでよかったよかった。