Astro2.0のCollections

Astro2.0のCollections

Astro 2.0 Collections

tsconfig.json のcompilerOptionsに以下を追記する。
Markdownの要求されているfrontmatterがちゃんと書かれているかのチェックが行われるようになる。

tsconfig.json
    "strictNullChecks": true

src/content フォルダを作成しAstro2.0のCollectionの定義は src/content/config.ts に記述する。

src/content/config.ts
---// `astro:content`から z defineCollection を読み込むimport { z, defineCollection } from "astro:content";// Collection の定義const blogCollection = defineCollection({  schema: z.object({    layout: z.string(),    title: z.string(),    date: z.string().transform((str) => new Date(str)),    description: z.string().optional(),    tags: z.array(z.string()).optional(),    featured: z.string().optional(),    heroImage: z.string().optional(),    author: z.string().optional(),    isDraft: z.boolean().optional(),    updatedDate: z      .string()      .transform((str) => new Date(str))      .optional(),  }),});// 以下で Collection を割り当てる Collection を読み込む場合は// getcollection(以下の文字列) で可能export const collections = {  blog: blogCollection,  note: blogCollection,};

上記のようにCollectionが定義されているとMarkdownファイルが src/content 以下に作成・更新されるたびに /.astro/types.d.ts に自動的に型が生成されていく。
(npm run devしてあれば常に /src/contentを監視して生成してくれる)

types.d.ts
---// 以下は自動生成された types.d.ts の一部 const entryMap: {  "blog": {"2011/2011-01-02.md": {  id: "2011/2011-01-02.md",  slug: "2011/2011-01-02",  body: string,  collection: "blog",  data: InferEntrySchema<"blog">},"2011/2011-01-13.md": {  id: "2011/2011-01-13.md",  slug: "2011/2011-01-13",  body: string,  collection: "blog",  data: InferEntrySchema<"blog">},

Collection を読み込む

以前は glob で行っていたブログのオブジェクト読み出しは以下のようにできる

以前の方法

---const posts = await Astro.glob("../pages/posts/**/*.md");

Astro2.0 の方法

読み込みたいCollectionを文字列で指定できる。

---const posts = await getCollection("blog");

サブディレクトリの処理

[slug].astroは[...slug].astroとすればサブディレクトリも読み込む

逆にそうしないとサブディレクトリのコンテンツを生成しない

src/content の中のフォルダとCollection名は一致させることが必要

"blog" をクラスとして読み込んでいるため 文字列blogを直接書き込んでいるファイルがある

src/content/config.ts
---export const collections = {  blog: blogCollection,};
src/components/BlogCard.astro
---post: CollectionEntry<"blog">;
src/pages/[...page].astro と src/pages/[tag]/[...page].astro
  <CardList>    {page.data.map((post: CollectionEntry<"blog">) => <Card post={post} />)}  </CardList>

それ以外はsrc/config.tsで定義したBLOG_NAMEを使用している

---// Place any global data in this file.// You can import this data from anywhere in your site by using the `import` keyword.export const SITE_TITLE = "へび右曲がり";export const SITE_DESCRIPTION = "へび右曲がりはubanisによるふたなりサイトです";export const SITE_LANG = "ja";export const SITE_DATE_LANG = "ja-JP";export const SITE_DOUJIN_BASE_URL = "/doujin/";export const BLOG_NAME = "blog";export const BLOG_BLOG_PAGE_SIZE = 10;