Skip to content

Conversation

@haxibami
Copy link
Member

@haxibami haxibami commented Dec 22, 2025

概要

  • サイト内の様々なデータについて、Astro のコンテンツコレクションを使うようにしました
  • データをコンテンツコレクションで管理することで、事前にZodで定義したスキーマに基づき、データのバリデーション・加工を行うことができます
    • これにより、誤った形式・型のデータを入力した際の問題発見が早くなるなどのメリットがあります
    • 例:「お知らせのYAMLを更新した際に、英語・日本語両方のタイトルが入力されていなければ、ビルドがエラーになるようにする」といったことが可能になります
  • また、deprecated な Astro.glob() を使っている箇所の改修も兼ねています

変更対象

  • 対象となるデータは、従来 Astro.glob()import foo from "foo.yml"; などの方法で取得されていたものです(Markdown / MDX、YAML)
  • 変更対象ごとにコミットが分かれているので、それぞれのコミットを見てもらうのがわかりやすいと思います

変更対象の一覧・留意点

  • 説明会等
  • 緊急のお知らせ
    • コンテンツコレクションの仕様上、エントリが0件だと警告メッセージが出るため、ダミーのエントリ(src/emergencies/sample.md)を追加しています 805b228
  • お知らせ(とRSS)
    • お知らせのタイトルは、日本語か英語のいずれかがあればエラーにならないようにしました。ただし、以下のガイドラインを踏まえ、片方の言語しかない場合は警告メッセージを出すようにしています
      • ja:の後に日本語の、en:の後に英語のタイトルを,それぞれ書いてください.仮にリンク先ページが片方の言語でしか書かれていなかったとしても,トップページでお知らせを発見できるよう,タイトルは両方の言語で書いてください.

    • お知らせに id を付与する処理をZodの .transform() 内に移した結果、src/data/utils/notice.ts にはユーティリティ関数のみが残ったため、削除して src/lib/util.ts に移動しました e0cf9de
    • 従来の処理では、英語タイトルのみを持ち、日本語タイトルを持たないお知らせ(例:2022-03-18)が英語版のお知らせページに表示されていませんでしたが、その点も修正されました
  • サイトマップ
  • ナビゲーション
  • グッドプラクティス
    • src/pages/good-practice/_Loader.astro を消して src/pages/good-practice/index.tsx にまとめました
    • バリデーションの結果、不足しているフィルタが見つかったため、追加しました 0f383e5

今後の見通し

  • 説明会等のページ(/events)は、現在は手書きだが、お知らせページと同様にYAMLから生成できそう
  • 過去のお知らせもすべて英訳して、日英双方のタイトルを必須にする(欠けている場合にエラーを出すようにする)ことも可能

@github-actions
Copy link

🚀 Deployed on https://deploy-preview-1777--utelecon.netlify.app

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates the codebase to use Astro's Content Collections feature with Zod schema validation, replacing the deprecated Astro.glob() API. This change provides type safety, runtime validation, and better data management for various content types including notices, events, navigation, good practices, and emergency notifications.

Key changes:

  • Introduction of a centralized src/content.config.ts with Zod schemas for all content collections
  • Migration from Astro.glob() and direct YAML imports to getCollection() and getEntry() APIs
  • Moved utility functions from src/data/utils/notices.ts to src/lib/util.ts for better organization
  • Enhanced validation with warnings for notices missing bilingual titles

Reviewed changes

Copilot reviewed 14 out of 16 changed files in this pull request and generated 16 comments.

Show a summary per file
File Description
src/content.config.ts New centralized configuration defining all content collections with Zod schemas for emergencies, events, notices, navigation, pages, and interviews
src/pages/good-practice/index.mdx Updated to use Content Collections API instead of the deleted _Loader.astro component
src/pages/good-practice/_Loader.astro Deleted file - functionality moved inline to index.mdx
src/lib/util.ts Added date formatting utility functions moved from the deleted notices utility file
src/layouts/Header/Navigation.astro Changed from direct YAML import to getEntry() API for navigation data
src/layouts/Footer/Navigation.astro Changed from direct YAML import to getEntry() API for navigation data
src/layouts/Emergency.astro Updated to use Content Collections with getCollection() and render() APIs
src/emergencies/sample.md Added dummy emergency entry to avoid empty collection warnings
src/data/utils/notices.ts Deleted - utilities moved to src/lib/util.ts and ID generation moved to content.config.ts
src/data/schemas/notice.d.ts Deleted TypeScript type definitions, replaced by Zod schema inference
src/data/schemas/nav.d.ts Deleted TypeScript type definitions, replaced by Zod schema inference
src/components/pages/rss.ts Updated to use getEntry() API for retrieving notices
src/components/pages/Sitemap.astro Updated to use getCollection() and getEntry() APIs for pages and navigation
src/components/pages/Notice.astro Updated to use getEntry() API and import utilities from new location
src/components/pages/GoodPractice.tsx Added missing filter options (TeX, Mathematica, UTAS, etc.) and exported constants for use in content.config.ts
src/components/pages/Events.astro Updated to use getCollection() API instead of Astro.glob()

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

.transform(
(v) => new RegExp(v)
)
})
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space after closing brace in the object literal. This is inconsistent with the formatting used elsewhere in the file.

Copilot uses AI. Check for mistakes.
import { select } from "hast-util-select";
import type { Lang } from "@components/types";

const { data: noticesWithId } = await getEntry("notices", "notice")!
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing semicolon at the end of the statement. This is inconsistent with the coding style used in the rest of the file where other statements have semicolons.

Suggested change
const { data: noticesWithId } = await getEntry("notices", "notice")!
const { data: noticesWithId } = await getEntry("notices", "notice")!;

Copilot uses AI. Check for mistakes.
ja,
en,
}[lang];
const { data } = await getEntry("nav", lang)!
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing semicolon at the end of the statement. This is inconsistent with line 11 in Header/Navigation.astro which has a semicolon, and also inconsistent with other statements in the same file.

Suggested change
const { data } = await getEntry("nav", lang)!
const { data } = await getEntry("nav", lang)!;

Copilot uses AI. Check for mistakes.
(v) => new RegExp(v)
)
})
})
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space after closing brace in the object literal. This is inconsistent with the formatting used elsewhere in the file.

Suggested change
})
} )

Copilot uses AI. Check for mistakes.
)
})
)
})
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space after closing brace in the object literal. This is inconsistent with the formatting used elsewhere in the file.

Copilot uses AI. Check for mistakes.
return { ...notice, id };
}).toReversed();
})
})
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space after closing brace in the object literal. This is inconsistent with the formatting used elsewhere in the file.

Copilot uses AI. Check for mistakes.
tools: z.string()
})
})
})
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space after closing brace in the object literal. This is inconsistent with the formatting used elsewhere in the file.

Suggested change
})
} )

Copilot uses AI. Check for mistakes.
{ label: "実験・実習", value: "experiment" },
{ label: "グループワーク", value: "group-work" },
{ label: "TA", value: "ta" },
{ label: "テキスト", value: "text"}
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space before closing brace in the object literal. This is inconsistent with the formatting used elsewhere in the file.

Suggested change
{ label: "テキスト", value: "text"}
{ label: "テキスト", value: "text" }

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,144 @@
import { styleText } from "node:util";
import { defineCollection } from "astro:content";
import { z } from "astro/zod"
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing semicolon at the end of the import statement. This is inconsistent with the other import statements in the file which all end with semicolons.

Suggested change
import { z } from "astro/zod"
import { z } from "astro/zod";

Copilot uses AI. Check for mistakes.
import { getISODateString } from "src/lib/util";

const emergencies = defineCollection({
loader: glob({pattern: "*.{md,mdx}", base: "./src/emergencies" }),
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space after the opening brace in the object literal. This is inconsistent with formatting used elsewhere in the file and across the codebase.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants