このサイトのベーステーマには、Astro Boilerplateを使用しています。
このテーマは、記事にタグを付与する事は可能ですが、その他のタグに関する機能を装備していません。そのため、自分で調べて実装してみようと思います。
前回は、記事に付与されたタグや、タグ一覧ページの実装を行いました。詳細は、こちら の記事を参照して下さい。
よくある機能なので、みなさんも見た事はあると思います。今回実装したものを例に説明すると、下記のようなものです。
よくあるこの機能ですが、どのように実装されているのか、私には知見がありません。多分、下記のようなもの感じだと思います。
どちらの知見も殆ど無い私は、はじめは前者で検討していましたが、前回で動的な事は大体Astroで解決出来る事が判りました。後者で実装します。
全ての記事を取得する
const allPosts = await Astro.glob<IFrontmatter>('../pages/posts/*.md');
取得した記事からタグをカウントする
const tagCounts = allPosts.reduce((acc, post) => {
if (post.frontmatter.tags) {
post.frontmatter.tags.forEach((tag) => {
acc[tag] = (acc[tag] || 0) + 1;
});
}
return acc;
}, {});
よく使用する順番にソートする
const sortedTags = Object.entries(tagCounts).sort((a, b) => b[1] - a[1]).map(entry => entry[0]);
[Optional] 表示する上限を設定する
const popularTags = sortedTags.slice(0, 18);
表示
<Section>
<div slot="title" class="flex items-baseline justify-between">
<div>Popular Tags</div>
<div class="text-sm">
<a href="/tags/">View all Tags →</a>
</div>
</div>
{popularTags.map(tag => (
<a href={`/tags/${tag}/`}>
<button type="button">
#{tag} ({tagCounts[tag]})
</button>
</a>
))}
</Section>
良い感じにタグ機能が充実してきました。まだまだタグに関する事でやりたい事があるので、モチベーションがある時にでも実装してみます。