diff --git a/.astro/astro/content.d.ts b/.astro/astro/content.d.ts new file mode 100644 index 0000000..ef995ed --- /dev/null +++ b/.astro/astro/content.d.ts @@ -0,0 +1,221 @@ +declare module 'astro:content' { + interface Render { + '.mdx': Promise<{ + Content: import('astro').MarkdownInstance<{}>['Content']; + headings: import('astro').MarkdownHeading[]; + remarkPluginFrontmatter: Record; + }>; + } +} + +declare module 'astro:content' { + interface RenderResult { + Content: import('astro/runtime/server/index.js').AstroComponentFactory; + headings: import('astro').MarkdownHeading[]; + remarkPluginFrontmatter: Record; + } + interface Render { + '.md': Promise; + } + + export interface RenderedContent { + html: string; + metadata?: { + imagePaths: Array; + [key: string]: unknown; + }; + } +} + +declare module 'astro:content' { + type Flatten = T extends { [K: string]: infer U } ? U : never; + + export type CollectionKey = keyof AnyEntryMap; + export type CollectionEntry = Flatten; + + export type ContentCollectionKey = keyof ContentEntryMap; + export type DataCollectionKey = keyof DataEntryMap; + + type AllValuesOf = T extends any ? T[keyof T] : never; + type ValidContentEntrySlug = AllValuesOf< + ContentEntryMap[C] + >['slug']; + + /** @deprecated Use `getEntry` instead. */ + export function getEntryBySlug< + C extends keyof ContentEntryMap, + E extends ValidContentEntrySlug | (string & {}), + >( + collection: C, + // Note that this has to accept a regular string too, for SSR + entrySlug: E, + ): E extends ValidContentEntrySlug + ? Promise> + : Promise | undefined>; + + /** @deprecated Use `getEntry` instead. */ + export function getDataEntryById( + collection: C, + entryId: E, + ): Promise>; + + export function getCollection>( + collection: C, + filter?: (entry: CollectionEntry) => entry is E, + ): Promise; + export function getCollection( + collection: C, + filter?: (entry: CollectionEntry) => unknown, + ): Promise[]>; + + export function getEntry< + C extends keyof ContentEntryMap, + E extends ValidContentEntrySlug | (string & {}), + >(entry: { + collection: C; + slug: E; + }): E extends ValidContentEntrySlug + ? Promise> + : Promise | undefined>; + export function getEntry< + C extends keyof DataEntryMap, + E extends keyof DataEntryMap[C] | (string & {}), + >(entry: { + collection: C; + id: E; + }): E extends keyof DataEntryMap[C] + ? Promise + : Promise | undefined>; + export function getEntry< + C extends keyof ContentEntryMap, + E extends ValidContentEntrySlug | (string & {}), + >( + collection: C, + slug: E, + ): E extends ValidContentEntrySlug + ? Promise> + : Promise | undefined>; + export function getEntry< + C extends keyof DataEntryMap, + E extends keyof DataEntryMap[C] | (string & {}), + >( + collection: C, + id: E, + ): E extends keyof DataEntryMap[C] + ? Promise + : Promise | undefined>; + + /** Resolve an array of entry references from the same collection */ + export function getEntries( + entries: { + collection: C; + slug: ValidContentEntrySlug; + }[], + ): Promise[]>; + export function getEntries( + entries: { + collection: C; + id: keyof DataEntryMap[C]; + }[], + ): Promise[]>; + + export function render( + entry: AnyEntryMap[C][string], + ): Promise; + + export function reference( + collection: C, + ): import('astro/zod').ZodEffects< + import('astro/zod').ZodString, + C extends keyof ContentEntryMap + ? { + collection: C; + slug: ValidContentEntrySlug; + } + : { + collection: C; + id: keyof DataEntryMap[C]; + } + >; + // Allow generic `string` to avoid excessive type errors in the config + // if `dev` is not running to update as you edit. + // Invalid collection names will be caught at build time. + export function reference( + collection: C, + ): import('astro/zod').ZodEffects; + + type ReturnTypeOrOriginal = T extends (...args: any[]) => infer R ? R : T; + type InferEntrySchema = import('astro/zod').infer< + ReturnTypeOrOriginal['schema']> + >; + + type ContentEntryMap = { + "post": { +"0h2p5w7rfh.md": { + id: "0h2p5w7rfh.md"; + slug: "0h2p5w7rfh"; + body: string; + collection: "post"; + data: InferEntrySchema<"post"> +} & { render(): Render[".md"] }; +"4d4y1g2up.md": { + id: "4d4y1g2up.md"; + slug: "4d4y1g2up"; + body: string; + collection: "post"; + data: InferEntrySchema<"post"> +} & { render(): Render[".md"] }; +"4sdndar2n.mdx": { + id: "4sdndar2n.mdx"; + slug: "4sdndar2n"; + body: string; + collection: "post"; + data: InferEntrySchema<"post"> +} & { render(): Render[".mdx"] }; +"fw7_gmrn2w.md": { + id: "fw7_gmrn2w.md"; + slug: "fw7_gmrn2w"; + body: string; + collection: "post"; + data: InferEntrySchema<"post"> +} & { render(): Render[".md"] }; +"kvc56ubf4.md": { + id: "kvc56ubf4.md"; + slug: "kvc56ubf4"; + body: string; + collection: "post"; + data: InferEntrySchema<"post"> +} & { render(): Render[".md"] }; +"m2juo4dy7c.mdx": { + id: "m2juo4dy7c.mdx"; + slug: "m2juo4dy7c"; + body: string; + collection: "post"; + data: InferEntrySchema<"post"> +} & { render(): Render[".mdx"] }; +"rkmss30pwd1.mdx": { + id: "rkmss30pwd1.mdx"; + slug: "rkmss30pwd1"; + body: string; + collection: "post"; + data: InferEntrySchema<"post"> +} & { render(): Render[".mdx"] }; +"rwft75ng_3.md": { + id: "rwft75ng_3.md"; + slug: "rwft75ng_3"; + body: string; + collection: "post"; + data: InferEntrySchema<"post"> +} & { render(): Render[".md"] }; +}; + + }; + + type DataEntryMap = { + + }; + + type AnyEntryMap = ContentEntryMap & DataEntryMap; + + export type ContentConfig = typeof import("../../src/content/config.js"); +} diff --git a/.astro/types.d.ts b/.astro/types.d.ts index 748cd96..a82cceb 100644 --- a/.astro/types.d.ts +++ b/.astro/types.d.ts @@ -1,2 +1,3 @@ /// -/// \ No newline at end of file +/// +/// \ No newline at end of file diff --git a/bun.lockb b/bun.lockb index 65ee5a3..379503f 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/plop-templates/blog/index.md.hbs b/plop-templates/blog/index.md.hbs index 775a7c9..2ccbdb6 100644 --- a/plop-templates/blog/index.md.hbs +++ b/plop-templates/blog/index.md.hbs @@ -4,5 +4,4 @@ createdAt: {{createdAt}} description: "キャッチコピー" link: https://yukky-sandbox.dev/post/{{pathname}} pubDate: {{createdAt}} -layout: "../../../layouts/PostLayout.astro" --- \ No newline at end of file diff --git a/plopfile.js b/plopfile.js index 863ce63..76c0e5a 100644 --- a/plopfile.js +++ b/plopfile.js @@ -1,6 +1,9 @@ +import { format } from "@formkit/tempo"; + export default function (plop) { const today = new Date(); - const pathname = `${today.getFullYear()}-${today.getMonth() + 1}-${today.getDate()}-${today.getMilliseconds()}`; + const createdAt = format(today, "YYYY-MM-DD"); + const pathname = `${createdAt}-${today.getMilliseconds()}`; plop.setGenerator("blog", { description: "blog post", @@ -8,10 +11,10 @@ export default function (plop) { actions: [ { type: "add", - path: `src/pages/post/${pathname}/index.md`, + path: `src/content/post/${pathname}.md`, templateFile: "plop-templates/blog/index.md.hbs", data: { - createdAt: `${today.getFullYear()}/${today.getMonth() + 1}/${today.getDate()}`, + createdAt, pathname, }, }, diff --git a/src/components/organisms/PostCards.astro b/src/components/organisms/PostCards.astro index 874857f..beb7dd4 100644 --- a/src/components/organisms/PostCards.astro +++ b/src/components/organisms/PostCards.astro @@ -1,5 +1,6 @@ --- import PostCard from "../molecules/PostCard.astro"; +import { getCollection } from 'astro:content'; interface Frontmatter { title: string; @@ -9,19 +10,19 @@ interface Frontmatter { date: number; } -const posts = await Astro.glob('../../pages/post/**/*.{md,mdx}') +const posts = await getCollection('post'); ---

記事一覧

{ - posts.sort((postA, postB) => { return new Date(postA.frontmatter.createdAt) < new Date(postB.frontmatter.createdAt) ? 1 : -1 }).map((post) => ( + posts.sort((postA, postB) => { return new Date(postA.data.createdAt) < new Date(postB.data.createdAt) ? 1 : -1 }).map((post) => ( )) } diff --git a/src/content/config.ts b/src/content/config.ts new file mode 100644 index 0000000..599fdfe --- /dev/null +++ b/src/content/config.ts @@ -0,0 +1,14 @@ +import { defineCollection, z } from "astro:content"; +const blogCollection = defineCollection({ + type: "content", + schema: z.object({ + title: z.string(), + createdAt: z.string().date(), + description: z.string(), + link: z.string(), + pubDate: z.string().date(), + }), +}); +export const collections = { + post: blogCollection, +}; diff --git a/src/pages/post/0h2p5w7rfh/index.md b/src/content/post/0h2p5w7rfh.md similarity index 98% rename from src/pages/post/0h2p5w7rfh/index.md rename to src/content/post/0h2p5w7rfh.md index 029db3b..b3f2144 100644 --- a/src/pages/post/0h2p5w7rfh/index.md +++ b/src/content/post/0h2p5w7rfh.md @@ -1,10 +1,9 @@ --- title: "転職して1ヶ月が経過した" -createdAt: 2023/6/11 +createdAt: "2023-06-11" description: "転職して1ヶ月が経過したため、転職活動中のことや今感じていること・思っていることをまとめてみます!" link: https://yukky-sandbox.dev/post/0h2p5w7rfh -pubDate: 2023/6/11 -layout: "../../../layouts/PostLayout.astro" +pubDate: "2023-06-11" --- ## はじめに diff --git a/src/pages/post/4d4y1g2up/index.md b/src/content/post/4d4y1g2up.md similarity index 96% rename from src/pages/post/4d4y1g2up/index.md rename to src/content/post/4d4y1g2up.md index d4d7d8d..c1d6437 100644 --- a/src/pages/post/4d4y1g2up/index.md +++ b/src/content/post/4d4y1g2up.md @@ -1,10 +1,9 @@ --- title: "2023年の目標50本" -createdAt: 2023/1/9 +createdAt: "2023-01-09" description: "今年の目標を50本立てました!!達成できるように頑張ろう!!" link: https://yukky-sandbox.dev/post/4d4y1g2up -pubDate: 2023/1/9 -layout: "../../../layouts/PostLayout.astro" +pubDate: "2023-01-09" --- ## MUST diff --git a/src/pages/post/4sdndar2n/index.mdx b/src/content/post/4sdndar2n.mdx similarity index 83% rename from src/pages/post/4sdndar2n/index.mdx rename to src/content/post/4sdndar2n.mdx index 367c17c..8b92e75 100644 --- a/src/pages/post/4sdndar2n/index.mdx +++ b/src/content/post/4sdndar2n.mdx @@ -1,19 +1,19 @@ --- title: "Cloudflareでbun使えないじゃん!!!と思ったらBuild Systemが古いだけでした" -createdAt: 2023/12/3 +createdAt: "2023-12-03" description: "Cloudflareでbunが使えないと思ってnカ月。。原因はBuild System Versionが1のままなことでした。。。 " link: https://yukky-sandbox.dev/post/4sdndar2n -pubDate: 2023/12/3 -layout: "../../../layouts/PostLayout.astro" +pubDate: "2023-12-03" --- -import { Image } from "astro:assets"; -import buildSystemVersionPng from "./_build_system_version.png"; +import { Picture } from "astro:assets"; +import buildSystemVersionPng from "../../images/post/4sdndar2n/_build_system_version.png"; Cloudflareでbunが使えないと思ってnカ月。。原因は`Build System Version`が1のままなことでした。。。 -Build System Versionが1のままだった - - + + - + + {title} | ゆっきーの砂場 @@ -26,17 +28,20 @@ const { title, description, ogType } = Astro.props; + - - - + + + + + - +
diff --git a/src/layouts/PostLayout.astro b/src/layouts/PostLayout.astro index 253c94b..9e8e3b3 100644 --- a/src/layouts/PostLayout.astro +++ b/src/layouts/PostLayout.astro @@ -6,7 +6,7 @@ export interface Props { description: string; createdAt: string; } -const { title, description, createdAt } = Astro.props.frontmatter; +const { title, description, createdAt } = Astro.props; const OG_TYPE = "article"; const dateTypeCreatedAt = new Date(createdAt); --- diff --git a/src/pages/introduction.astro b/src/pages/introduction.astro index f0ec681..b86710e 100644 --- a/src/pages/introduction.astro +++ b/src/pages/introduction.astro @@ -1,6 +1,6 @@ --- export const prerender = true; -import { Image } from "astro:assets"; +import { Picture } from "astro:assets"; import Layout from "../layouts/Layout.astro"; import glaceon from "../images/glaceon.png"; import twitterLikeBird from "../images/twitter_like_bird.png"; @@ -13,7 +13,7 @@ import qiita from "../images/qiita.png";

自己紹介

ゆっきーのアイコン + >

ゆっきー

@@ -26,7 +26,8 @@ import qiita from "../images/qiita.png";
  • Twitter

    - twitterアカウント

    Bluesky

    - Blueskyアカウント @@ -45,7 +47,8 @@ import qiita from "../images/qiita.png";
  • Github

    - githubアカウント @@ -54,7 +57,8 @@ import qiita from "../images/qiita.png";
  • Qiita

    - qiitaアカウント diff --git a/src/pages/post/[...slug].astro b/src/pages/post/[...slug].astro new file mode 100644 index 0000000..9c7e817 --- /dev/null +++ b/src/pages/post/[...slug].astro @@ -0,0 +1,16 @@ +--- +import { getCollection } from 'astro:content'; +import PostLayout from '../../layouts/PostLayout.astro'; +export async function getStaticPaths() { + const blogEntries = await getCollection('post'); + return blogEntries.map(entry => ({ + params: { slug: entry.slug }, props: { entry }, + })); +} +const { entry } = Astro.props; +const { Content } = await entry.render(); +--- + + + + diff --git a/src/pages/rss.xml.js b/src/pages/rss.xml.js index 2b0a0b8..5144c4b 100644 --- a/src/pages/rss.xml.js +++ b/src/pages/rss.xml.js @@ -1,11 +1,24 @@ import rss, { pagesGlobToRssItems } from "@astrojs/rss"; +import { getCollection } from "astro:content"; export async function GET(context) { + const blog = await getCollection("post"); return rss({ title: "ゆっきーの砂場", description: "ポケモンと旅行、美味しい料理が好きなエンジニア「ゆっきー」のブログ兼実験場です。", site: context.site, - items: await pagesGlobToRssItems(import.meta.glob("./post/**/*.{md,mdx}")), + items: blog + .sort((postA, postB) => { + return new Date(postA.data.createdAt) < new Date(postB.data.createdAt) + ? 1 + : -1; + }) + .map((post) => ({ + title: post.data.title, + pubDate: post.data.pubDate, + description: post.data.description, + link: `/post/${post.slug}/`, + })), }); }