Astroチュートリアルメモ その5-1【投稿一覧の取得】
ブログでよくある記事一覧を作る。
投稿一覧のデータを取得する。
Next.jsのチュートリアルではfs.readdirSyncでファイル名を持ってきて、拡張子を除外して…という作業をしたが、AstroではAstro.glob()
で指定フォルダのurlを全て持ってくることができる。
Astro.glob()
で全URLを取得する
frontmatter部分でAstro.glob
を使いurlを配列で取得する。
---
import "../styles/global.css";
import BaseLayout from "../layouts/BaseLayout.astro";
const allPosts = await Astro.glob("../pages/posts/*.md");
const pageTitle = "My Astro Learning Blog";
---
<BaseLayout pageTitle={pageTitle}>
<p>This is where I will post about my journey learning Astro.</p>
<ul>
{
allPosts.map((post) => (
<li>
<a href={post.url}>{post.frontmatter.title}</a>
</li>
))
}
</ul>
</BaseLayout>
Astro.glob()
を使うと、urlだけでなく、frontmatter部分などのデータを持ってくることができる。ちなみにマークダウン自体を個別にimportすることも可能。
チュートリアルの例では、配列として複数のマークダウンファイルを読み込み、Reactでよくあるmapを使って記事一覧リストのHtmlを作るやつを使っている。
{post.url}
でurlを取得し、{post.frontmatter.title}
でマークダウンファイルのfrontmatter部分からタイトルを取得している。
チュートリアルでは、その後コンポーネントとして記事一覧を独立させている。
Astro.glob()
で呼んだデータをコンソールログで見てみる
こんな感じだった。
色々データが入ってるらしい。ちゃんと見てないので詳細はわかってない。
{
[__esModule]: true,
frontmatter: [Getter],
file: [Getter],
url: [Getter],
rawContent: [Getter],
compiledContent: [Getter],
getHeadings: [Getter],
getHeaders: [Getter],
Content: [Getter],
default: [AsyncFunction: Content] {
[length]: 0,
[name]: 'Content',
[Symbol(astro.needsHeadRendering)]: false,
[Symbol(Symbol.toStringTag)]: 'AsyncFunction'
},
[Symbol(Symbol.toStringTag)]: 'Module'
}
jsonにして表示してみたらこんな感じ。こちらはチュートリアルで作った記事三件分全てのデータ。
[
{
"frontmatter": {
"layout": "../../layouts/MarkdownPostLayout.astro",
"title": "My First Blog Post",
"pubDate": "2022-07-01T00:00:00.000Z",
"description": "This is the first post of my new Astro blog.",
"author": "Astro Learner",
"image": {
"url": "https://astro.build/assets/blog/astro-1-release-update/cover.jpeg",
"alt": "The Astro logo with the word One."
},
"tags": ["astro", "blogging", "learning in public"]
},
"file": "C:/dev/astro/tutorial/src/pages/posts/post-1.md",
"url": "/posts/post-1"
},
{
"frontmatter": {
"layout": "../../layouts/MarkdownPostLayout.astro",
"title": "My Second Blog Post",
"author": "Astro Learner",
"description": "After learning some Astro, I couldn't stop!",
"image": {
"url": "https://astro.build/assets/blog/astro-showcase/astro-showcase-screenshot.jpg",
"alt": "Thumbnails of websites from the Astro Showcase site."
},
"pubDate": "2022-07-08T00:00:00.000Z",
"tags": ["astro", "blogging", "learning in public", "successes"]
},
"file": "C:/dev/astro/tutorial/src/pages/posts/post-2.md",
"url": "/posts/post-2"
},
{
"frontmatter": {
"layout": "../../layouts/MarkdownPostLayout.astro",
"title": "My Third Blog Post",
"author": "Astro Learner",
"description": "I had some challenges, but asking in the community really helped!",
"image": {
"url": "https://astro.build/assets/blog/community-day/cover.jpg",
"alt": "The word community with a heart."
},
"pubDate": "2022-07-15T00:00:00.000Z",
"tags": ["astro", "learning in public", "setbacks", "community"]
},
"file": "C:/dev/astro/tutorial/src/pages/posts/post-3.md",
"url": "/posts/post-3"
}
]
frontmatter部分は全部文字列で取得できる。あとfileのパスとurlも。
コンテンツの本文を読んでデータをいじりたい時にどう呼ぶのかはわからない。Reactで簡易検索を作りたい時とか。無理にAstroの機能を使わずにNode.jsで呼べばできそうな気がするけど。
まあ、そういうケースが出た時に方法を考えるぐらいで良いのかも。
追加
マークダウンの部分を読んでいたら色々なデータの使い方が書いてあった。
目次とかも作れそうな気がする。ただAstroのテンプレート見ていたら、ドキュメントサイトの中の目次はpreactでuseRefとかuseEffectで作ってあった。まあそうなるよね。自分も作るとなったら最初にそれ考えそうだなと思った。
次の記事
Discussion