贡献指南
欢迎参与武大漫协站点的建设!本页面整合了投稿与维护所需的全部信息。
本站是使用 Next.js 与 Fumadocs 搭建的静态站,定位为社团历史活动与资料的保存库。它将 MDX 文本转换为静态网页,让你专注于内容撰写而非网页设计。MDX 支持常用的 Markdown 标记,也可以使用 React 组件;普通文章只要会基本的 Markdown 标记即可投稿。
不会 Markdown / Git?
你可以将材料写成一份 word 文档,发给维护者并告知需求,维护者会代为添加。
我们希望收到什么
我们希望各位添加的是有意义的材料。以下类型的投稿不会通过:
关于 AI 协作
我们不希望项目的 Contributors 被各种 AI 协作者污染。如果你使用 AI 编写内容,请在 commit 时删除 AI 的 Co-Authors,否则不予通过(#98)。
本地部署
- fork 该仓库,然后克隆你的 fork 到本地
- 安装
node.js(建议 24+,与 CI 一致)与pnpm - 运行
pnpm install安装依赖 - 运行
pnpm dev启动本地服务器,默认地址http://localhost:3000/ - 保存修改后,开发服务器会自动刷新页面;修改配置后按需重启
pnpm dev
提交前建议运行 pnpm build 确认能构建通过——构建会做死链检查,任何失效的站内链接都会导致构建失败(详见下方链接规范)。
目录与资源约定
- 内容:MDX 文件(
.mdx)放在docs/<区域>/下(如docs/activity/、docs/group/) - 资源:图片等静态资源放在
public/的对应镜像目录下。例如 2024 冬日祭的图片放在public/activity/2024/,页面里用绝对路径/activity/2024/xxx.jpg引用(public即站点根目录) - 学年:涉及年份的文件夹均为学年。如
2024表示 2024 学年(2024.6–2025.6),与社团干部任期一致
新增页面
新建一个 .mdx 文件后,需要把它登记到侧边栏才会出现在导航里。侧边栏在 lib/navigation.json 的 sidebar 中手动配置。找到对应区域(如 /activity/),在 items 里按现有写法追加一项即可。页面顶部的 frontmatter 需填写 title;正文继续保留一级标题。
新增内容时,参考同区域已有的页面是最快的方式,例如:
- 活动页:参考
docs/activity/2024/winter-festival.mdx - 成员卡:参考
docs/activity/2025/welcome-party/credits.mdx - 留声箱:参考
docs/message-box/quq/words.mdx
链接规范
站内链接一律使用以 / 开头的绝对路径(如 /group/ani-key/),不要用相对路径。相对路径在嵌套目录下容易解析错误,且会触发构建期的死链检查导致部署失败。
自定义组件
本站在 MDX 中注册了 React 组件,可直接使用 ChatMessage、MemberCard 和 TeamMembers 等。数据通过 @/lib/people 引入;页面中的顶层变量须写成 export const。JSX 属性使用 className 和 avatar={avatarOf('成员名称')},对象、数组使用花括号。原生 HTML 的空元素需闭合,例如 <br /> 和 <img src="/example.jpg" alt="说明" />。
组件与服务端渲染
ChatMessage 和 MemberCard 支持服务端渲染,可直接使用。旧页面中的 <ClientOnly> 作为兼容容器保留,新页面无需添加。需要使用浏览器 API 的交互逻辑应写在独立的 React 客户端组件中。
人员与头像注册表
所有人员的数据统一登记在 lib/people.js 里,主要有两个作用:
- 统一头像:页面通过
avatarOf('成员名称')取头像,避免在多个页面里重复硬编码 URL。 - 贡献者匹配:作为页面历史与贡献者数据的数据源。由于同一个贡献者在不同机器上的 Git 名字/邮箱可能不同,通过在这里设置别名,可以将错乱的提交记录合并到同一个人名下。
新增或完善成员数据时,在 people.js 里修改:
'-QuQ-': {
avatar: '/avatars/-QuQ-.jpeg',
github: 'shenxianovo',
mapByNameAliases: ['shenxianovo'],
mapByEmailAliases: ['shenxianovo@gmail.com', 'shenxianovo@outlook.com']
},
'九尾晨': { avatar: QQ('1540104836') }, // 如果只是普通成员(没有参与网站代码/文档维护),只需头像即可- 本地头像:图片放在
public/avatars/<成员名>.jpg,写'/avatars/<成员名>.jpg' - QQ 头像:直接
QQ('你的QQ号'),模块顶部已有QQhelper - Github / Git 邮箱设定(仅对代码/文档提交者需要):根据提交历史中的 Author 和 Email 配置
mapByNameAliases/mapByEmailAliases,让页面历史归拢记录。
页面历史和贡献者由 fumadocs-page-history 显示。注册表的键名是站内显示名称,github 只决定 GitHub 个人主页链接;例如上面的配置会显示 -QuQ-,点击后打开 shenxianovo 的主页。修改键名即可修改显示名称,同时应更新页面中 avatarOf / memberOf 的对应引用。姓名与邮箱别名只在构建期参与匹配,不会传给浏览器。
注册表里没有的名字会回落到默认占位头像(PLACEHOLDER_AVATAR)。
ChatMessage 对话气泡
用于呈现聊天记录式的对话(参考 docs/about/introduction.mdx)。
| 属性 | 说明 |
|---|---|
avatar | 头像图片路径(推荐 avatar={avatarOf('xxx')} 从注册表取) |
nickname | 昵称 |
message | 消息内容,支持 <br>、内嵌 <img> 等 HTML |
position | left(默认)或 right,右侧通常表示自己 |
import { avatarOf } from '@/lib/people'
<ChatMessage avatar={avatarOf('')} nickname="萌新一枚" message="为什么漫协要叫WHUDAYS呢?" position="right"/>
<ChatMessage avatar={avatarOf('店长')} nickname="店长" message="这都怪当年某管理的恶趣味……"/>MemberCard 成员卡片
用于展示成员/群友信息卡(参考 docs/group/vocaloid-utau-fans/index.mdx)。
| 属性 | 说明 |
|---|---|
name | 成员名称 |
avatar | 头像图片路径或 URL(推荐 avatar={avatarOf('xxx')}) |
description | 一句话描述 |
link | 个人详情页链接,没有则留空 "" |
badges | 徽章数组,type 可选 tip / warning / info / danger |
socials | 社交链接数组,每项含 platform / url / icon |
import { avatarOf } from '@/lib/people'
<div className="member-grid">
<MemberCard
name="示例成员"
avatar={avatarOf('示例成员')}
description="一句话简介"
link=""
badges={[{ type: 'tip', text: '管理员' }, { type: 'warning', text: '创作者' }]}
socials={[{ platform: 'github', url: 'https://github.com/xxx', icon: '/group/vocaloid-utau-fans/members/sns/github.svg' }]}
/>
</div>