Zenn
Closed10

Astro製ブログに登壇ページを追加する

ikuma-tikuma-t
  • スキーマ定義
  • コンテンツ配置
  • 一覧作成
  • 詳細作成
  • TalksページのOGP生成処理を追加する
  • scaffdogに登壇用のテンプレを追加する
  • トップページに登壇一覧を追加する
  • ナビゲーション追加
ikuma-tikuma-t

スキーマ定義

https://docs.astro.build/ja/guides/content-collections/#defining-multiple-collections

既にblog用のスキーマが存在するので、複数のスキーマを統合するケースになる。

const talkCollection = defineCollection({
  schema: z.object({
    title: z.string().min(1),
    slideUrl: z.string().url(),
    eventName: z.string().min(1),
    eventDate: z.string().transform((str: string) => new Date(str)),
    tags: z.array(z.string()),
    note: z.string(),
  }),
});

export const collections = {
  blog: blogCollection,
  talk: talkCollection,
};
ikuma-tikuma-t

コンテンツ配置

https://speakerdeck.com/ikumatadokoro/hasuratutenanda

今回は最近社内勉強会で使った資料を例にコンテンツを組み立てる。

---
title: "Hasuraってナンダ!?"
slideUrl: "https://speakerdeck.com/ikumatadokoro/hasuratutenanda"
eventName: "社内勉強会"
eventDate: "2023-02-10"
tags: "Hasura, GraphQL"
note: "Biz系のメンバー/Hasuraを使ったことのないメンバーへ向けた、Hasura社内勉強会の資料です。"
---

<iframe
  class="speakerdeck-iframe"
  frameborder="0"
  src="https://speakerdeck.com/player/9eb91cca1d8841a09fbe91e865a10f5a"
  title="Hasuraってナンダ!?"
  allowfullscreen="true"
  mozallowfullscreen="true"
  webkitallowfullscreen="true"
  style="border: 0px; background: padding-box padding-box rgba(0, 0, 0, 0.1); margin: 0px; padding: 0px; border-radius: 6px; box-shadow: rgba(0, 0, 0, 0.2) 0px 5px 40px; width: 100%; height: auto; aspect-ratio: 560 / 324;"
  data-ratio="1.728395061728395"></iframe>

めんどくさいので、とりあえずSpeakerDeck側が提供しているiframeをベタで貼っておく。

追加している途中で、イベントのURLを出したいケースもあるな、と思ったので、OptionalなイベントURLをスキーマに追加した。

eventUrl: z.optional(z.string().url()),

これと同様にあと2件くらいサンプルを追加した。

ikuma-tikuma-t

一覧作成

とりあえず pages/talks.astro を雑に生成して、データ取得を試みる。

---
import Container from "@components/container.astro";
import Sectionhead from "@components/sectionhead.astro";
import Layout from "@layouts/Layout.astro";
import { getCollection } from "astro:content";

const allTalkEntries = await getCollection("talk");
---

<Layout title="Talks">
  <Container>
    <Sectionhead>
      <Fragment slot="title">Talks</Fragment>
      <Fragment slot="desc">外部イベントや社内勉強会の登壇資料です。</Fragment>
    </Sectionhead>
    <main class="mt-6">
      <div class="flex flex-col gap-2 mt-2">
        {
          allTalkEntries.map((talkEntry) => (
            <div class="border border-gray-200 p-4 rounded-lg bg-white">
              <p>{talkEntry.data.title}</p>
              <p>{talkEntry.data.eventName}</p>
              <p>{talkEntry.data.eventDate}</p>
              <p>{talkEntry.data.note}</p>
            </div>
          ))
        }
      </div>
    </main>
  </Container>
</Layout>

いい感じ。

このスクラップは2023/02/12にクローズされました
ログインするとコメントできます