異なった領域のタグ検索

(2024-04-14)

コンテンツが増えてくると当然ながらタグもどんどん増えてきます。

このブログのように、一般的なブログと医学的なコンテンツが混在していると別々に検索をした方が効率がいいはずです。

そこで、異なった領域のタグ検索を設定してそれを両方とも表示したいと思います。

index.astro の変更

ブログ領域と医学領域の両方のタグ一覧を別々にリストアップします。

/src/pages/tags/index.astro
---
import BaseLayout from '/src/layouts/BaseLayout.astro';
import Search from "/src/components/Search.astro";
const allPosts = await Astro.glob('/src/pages/posts/*/*.{md,mdx}');
const allPosts2 = await Astro.glob('/src/pages/medicine/*/*.{md,mdx}');
const tags = [...new Set(allPosts.map((post) => post.frontmatter.tags).flat())];
const tags2 = [...new Set(allPosts2.map((post) => post.frontmatter.tags).flat())];
const pageTitle = "検索";
---
<BaseLayout pageTitle={pageTitle}>
<h2>ブログタグ検索</h2>
<div class="tags">
{tags.map((tag) => (
<p class="tag"><a href={`/tags/${tag}`}>{tag}</a></p>
))}
</div>
<h2>医学タグ検索</h2>
<div class="tags">
{tags2.map((tag2) => (
<p class="tag"><a href={`/tags/${tag2}`}>{tag2}</a></p>
))}
</div>
<h2>全文検索</h2>
<p>
以下のウィンドウにキーワード入力すると検索されます。
</p>
<Search />
</BaseLayout>
<style>
a {
color: #00539F;
}
.tags {
display: flex;
flex-wrap: wrap;
}
.tag {
margin: 0.25em;
border: solid 1px #a1a1a1;
border-radius: .2em;
padding: .1em 0.5em;
font-size: 1em;
background-color: #F8FCFD;
}
</style>

[tag].astro の編集

[tag].astro も変更します。

/src/pages/tags/[tag].astro
---
import BaseLayout from '/src/layouts/BaseLayout.astro';
import BlogPost from '/src/components/BlogPost.astro';
export async function getStaticPaths() {
const allPosts1 = await Astro.glob('/src/pages/posts/*/*.md');
const allPosts2 = await Astro.glob('/src/pages/medicine/*/*.md');
const uniqueTags1 = [...new Set(allPosts1.map((post) => post.frontmatter.tags).flat())];
const uniqueTags2 = [...new Set(allPosts2.map((post) => post.frontmatter.tags).flat())];
const paths1 = [];
const paths2 = [];
uniqueTags1.forEach((tag) => {
const filteredPosts = allPosts1.filter((post) => post.frontmatter.tags.includes(tag));
paths1.push({
params: { tag },
props: { posts: filteredPosts },
});
});
uniqueTags2.forEach((tag) => {
const filteredPosts = allPosts2.filter((post) => post.frontmatter.tags.includes(tag));
paths2.push({
params: { tag },
props: { posts: filteredPosts },
});
});
return [...paths1, ...paths2]; // 配列を結合して返す
}
const { tag } = Astro.params ;
const { posts } = Astro.props;
---
<BaseLayout pageTitle={tag}>
<div>
<h2>検索結果</h2>
<ol class="list-decimal mx-3">
{posts.map((post) => <BlogPost key={post.url} url={post.url} title={post.frontmatter.title}/>)}
</ol>
</div>
</BaseLayout>