Creating Special Pages
Relevant source files
The following files were used as context for generating this wiki page:
Special Pages in the Charlotte project are a distinct content type used for creating standalone pages like "About" or "Projects". They are managed within a dedicated Astro content collection named spec. Unlike chronological blog posts, these pages serve as static, informational sections of the site.
Authored in Markdown, Special Pages can leverage custom components to embed dynamic content, such as GitHub repository cards. This system provides a flexible way to manage non-post content while maintaining a consistent authoring workflow.
The spec Content Collection
The foundation for Special Pages is the spec collection, defined using Astro's content collections feature. This distinguishes them from the posts collection.
Sources: src/content/config.ts
Collection Definition
The spec collection is defined in src/content/config.ts alongside the posts collection. Its schema is intentionally minimal, allowing for free-form Markdown content without requiring any specific frontmatter fields.
// src/content/config.ts:19-21
const specCollection = defineCollection({
schema: z.object({}),
});
Sources: src/content/config.ts:19-21
Both collections are then exported to be registered by Astro.
// src/content/config.ts:22-25
export const collections = {
posts: postsCollection,
spec: specCollection,
};
Sources: src/content/config.ts:22-25
The diagram below illustrates the content collection structure.
This diagram shows how astro:content uses src/content/config.ts to define and manage the posts and spec collections.
Sources: src/content/config.ts:3-25
Comparison of posts and spec Collections
The two main content collections serve different purposes, which is reflected in their configuration.
| Feature | posts Collection | spec Collection |
|---|---|---|
| Purpose | Chronological blog articles | Standalone informational pages |
| Location | src/content/posts/ | src/content/spec/ |
| Schema | Strictly defined with required fields like title, published, tags, etc. | Empty schema (z.object({})), no frontmatter required. |
| Example Files | Unveiling.md, Charlotte-Markdown.md | about.md, projects.md |
Sources: src/content/config.ts:3-21, src/content/spec/about.md, src/content/spec/projects.md, src/content/posts/2018-10-30/Charlotte-Markdown.md
Authoring Special Pages
Special Pages are created as standard Markdown files (.md) inside the src/content/spec/ directory.
File Structure and Examples
The project includes two primary examples of special pages:
src/content/spec/about.md: An "About" page for the blog.src/content/spec/projects.md: A page to showcase GitHub projects.
These files contain standard Markdown and utilize custom components for enhanced functionality.
Example: about.md
# About
## 这里是[ChuwuYo](https://github.com/ChuwuYo)的小窝
### 本站使用[Charlotte](https://github.com/ChuwuYo/Charlotte)主题搭建
#### 欢迎你的到来!
<img src="/favicon/icon_1024.webp" alt="Nao Tomori" width="256" height="256" />
::github{repo="ChuwuYo/Charlotte"}
> 注意:如果卡片无法正常加载,请检查是否为403错误
> 遭遇此错误说明访问IP受限,一分钟之内的访问都会被GitHub拒绝,请稍后重试
Sources: src/content/spec/about.md
Example: projects.md
# Projects
::github{repo="ChuwuYo/MultiLangSwitcher"}
::github{repo="ChuwuYo/ChuwuBookmarks"}
::github{repo="ChuwuYo/BookmarksPortal"}
::github{repo="ChuwuYo/proxy-cleaner"}
::github{repo="ChuwuYo/AudioRename"}
::github{repo="ChuwuYo/NCMCoverSnatcher"}
::github{repo="ChuwuYo/Endfield-Pomodoro"}
Sources: src/content/spec/projects.md
Custom ::github Component
A key feature used in Special Pages is the ::github custom component, which renders a dynamic card with information about a specified GitHub repository.
Usage
This component is invoked using a remark directive syntax within a Markdown file. The repo attribute specifies the target repository in the format <owner>/<repo>.
::github{repo="ChuwuYo/Charlotte"}
Sources: src/content/posts/2018-10-30/Charlotte-Markdown.md:120-124
Implementation and Dependencies
The functionality for these custom directives is enabled by remark plugins. The package.json file lists remark-directive and remark-directive-rehype, which are responsible for parsing the :: syntax and transforming it into HTML.
// package.json:39-40
"remark-directive": "^4.0.0",
"remark-directive-rehype": "^0.4.2",
Sources: package.json:39-40
The processing flow from a Markdown directive to the final rendered component is as follows:
This diagram shows how a custom directive in a Markdown file is processed by remark plugins to render a dynamic component on the final web page.
Sources: package.json:39-40, src/content/spec/about.md:10