🐙

Astroチュートリアルメモ その5-1【投稿一覧の取得】

2022/11/07に公開

ブログでよくある記事一覧を作る。

https://docs.astro.build/en/tutorial/5-astro-api/1/

投稿一覧のデータを取得する。

Next.jsのチュートリアルではfs.readdirSyncでファイル名を持ってきて、拡張子を除外して…という作業をしたが、AstroではAstro.glob()で指定フォルダのurlを全て持ってくることができる。

Astro.glob()で全URLを取得する

https://docs.astro.build/en/guides/imports/#astroglob

frontmatter部分でAstro.globを使いurlを配列で取得する。

src/pages/blog.astr
---
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で呼べばできそうな気がするけど。

まあ、そういうケースが出た時に方法を考えるぐらいで良いのかも。

追加

マークダウンの部分を読んでいたら色々なデータの使い方が書いてあった。

https://docs.astro.build/ja/guides/markdown-content/#markdown-heading-ids

目次とかも作れそうな気がする。ただAstroのテンプレート見ていたら、ドキュメントサイトの中の目次はpreactでuseRefとかuseEffectで作ってあった。まあそうなるよね。自分も作るとなったら最初にそれ考えそうだなと思った。

次の記事

https://zenn.dev/k_neko3/articles/7519564d5d6f3e

Discussion