学术主页搭建指南:从模板复刻到部署上线的完整流程
2026/9/9 21:27:23 网站建设 项目流程

如果你也动过“个人网站搭建”的念头,大概率搜到过 Academic Pages。这个基于 GitHub Pages 的 Jekyll 学术主页模板,是我用了两年之后最终固定下来的方案。这篇配置指南不打算泛泛讲建站原理,而是把从 Fork 模板、本地预览、信息配置、内容填充到部署上线的完整路径走一遍,顺便把我实际踩过、也帮别人排查过的坑都交代清楚。适合刚读研的研究生、青年教师,以及任何想把学术成果以独立方式展示出来的研究者。

先说一句总结性的话:学术主页不是一个“放照片和简历”的地方,而是一个让陌生人在 30 秒内确认你研究方向、近期成果和联系方式的工具。Academic Pages 的价值在于它把这件事做到了“免费、可版本管理、更新一次只需要三分钟”的程度。下面我从选型逻辑开始讲,再一步步带你把它跑起来。

1. 为什么我最终把学术主页放在了 Academic Pages 上

1.1 学术主页要承担的隐形任务

审稿人搜到你的主页,最想确认的是:这篇论文的一作到底是不是你、你的研究方向和稿件是否一致。合作方打开你的主页,想找的是 PDF、代码仓库和联系邮箱。学生翻到你的页面,可能想知道你带什么课、实验室做什么方向。这些需求本质上都是“信息检索”,而不是“视觉展示”。

Academic Pages 的布局正好把这些信息放在了清晰的位置上:论文列表、学术报告、教学页面、博客短文,入口都在导航栏里,点两下就能找到。它基于 Jekyll 静态站点,没有数据库,也没有后台,所有内容都是 Markdown 文件和 YAML 配置,存放在 Git 仓库里。这带来的隐性好处是:每句话、每个论文条目、每次修改都有记录,git log能完整还原站点演变过程。我曾经靠这份历史记录直接整理出一份材料更新清单,那种体验是可视化后台给不了的。

1.2 它和主流方案的差异在哪里

我用过学校提供的个人主页后台,也试过 WordPress、Hexo,最后才定在 Academic Pages 上。几个方案的核心差异可以看这张表:

方案维护成本自定义能力学术场景贴合度适合人群
Academic Pages低,Markdown + Git 即可中高,基于 Jekyll 模板改高,内置论文/报告/教学集合大多数有稳定更新需求的科研人员
WordPress中高,需要服务器、数据库、插件更新高,但主题和插件质量参差不齐一般,需要自己组装论文列表已经买了服务器且有完整博客运营需求
Hexo / Hugo中,需要自己搭内容结构高,适合前端工程化玩法中,论文列表等学术模块要自己写喜欢折腾技术栈、愿意写模板的人
学校个人主页后台低,但受平台功能限制低,通常只能填预设字段中,存在学校域名迁移风险学校强制要求时作为辅助展示

Academic Pages 不是功能最花哨的,但它是“学术内容组织方式”上最贴近科研习惯的。它把论文、报告、教学、博客分成独立的 collection,每一种内容都有对应的目录和 front matter 规范。相比之下,用通用博客框架做学术主页,往往需要自己定义分类、标签和列表模板,前期工作量会大不少。

1.3 先确认你适不适合它

如果你需要展示论文列表和 PDF、想在会议或访问后放一页 Talk 介绍、需要给学生放课程资料,或者只是想要一个能被搜索引擎稳定收录的个人主页,Academic Pages 直接选即可。反过来,如果你想做一个流量驱动的图文博客、想用可视化编辑器拖拽排版、或者需要用户注册和评论区,它就不合适。静态站加表单服务、评论服务只是勉强能用,不如直接选动态站。

这个边界想清楚,后面所有配置都不会纠结。很多人在配置时反复改主题、加插件,最后发现核心需求其实只是“论文列表 + CV + 联系方式”,那 Academic Pages 默认模板就已经全部覆盖了。

2. 搭建前的准备动作:Fork 模板与本地预览

2.1 在 GitHub 上把模板变成自己的仓库

第一步是打开浏览器,进入 GitHub 上的academicpages/academic-pages模板仓库,点击右上角的 Fork。这个操作会把整套模板复制到你的账号下,之后你改的每一处都只影响自己的仓库。

Fork 之后要立刻做一件事:修改仓库名。两种命名方式差别很大:

  • 仓库名改成username.github.io,站点最终会发布在https://username.github.io
  • 仓库名保持academic-pages这类项目名,访问地址会变成https://username.github.io/academic-pages

第一次尝试强烈建议使用username.github.io这种用户名仓库。原因后面详细说,它能让所有资源路径都从根路径开始,少掉一大半 baseurl 相关的配置问题。仓库可见性建议设为 Public,因为 GitHub Pages 免费托管当前只对公开仓库开放。

2.2 本地环境三件套:Git、Ruby 和 Bundler

Jekyll 是 Ruby 生态的工具,本地环境需要三样东西:

  • Git:用来 clone 仓库和提交内容
  • Ruby:Jekyll 的运行环境
  • Bundler:Ruby 的依赖管理工具,用来安装项目锁定的 Gem 包

Windows 用户直接装 RubyInstaller,安装过程中勾选“Add Ruby executables to your PATH”。macOS 用户系统自带的 Ruby 版本往往偏旧,建议用版本管理工具安装新版本。Linux 用户用系统包管理器安装ruby-fullbundler即可。

装完后打开终端,逐个验证:

git --version ruby -v bundle -v

三个命令都能输出版本号,环境就算通了。最容易卡住的地方是 Ruby 版本过老,和项目Gemfile里锁定的 Jekyll 版本不兼容,报错通常长这样:incompatible library version或者bundler failed to load。遇到这类问题先别急着改 Gemfile,把 Ruby 升到 3.0 以上再试,大概率直接解决。

2.3 Clone 到本地并安装依赖

环境准备好之后,把刚才 Fork 的仓库拉到本地:

git clone https://github.com/你的用户名/你的仓库名.git cd 你的仓库名 bundle install

bundle install会读取项目根目录的GemfileGemfile.lock,把 Jekyll 以及配套插件全部装好。第一次执行时间会比较长,因为要下载不少 RubyGems 包。如果终端提示权限错误,不要随手加sudo,优先执行:

bundle config set path 'vendor/bundle'

这条命令会把依赖装到项目内部的vendor/bundle目录,不需要管理员权限,以后换机器迁移也更干净。装完之后不用管这个目录里的东西,它已经通过.gitignore被排除在版本管理之外。

2.4 启动本地服务,先看到基线版本

依赖装完,运行:

bundle exec jekyll serve

Jekyll 会先执行一次完整构建,然后启动本地服务器。默认访问地址是http://localhost:4000,浏览器打开后,你会看到一个完整但还未改动的学术主页模板。

这个“基线版本”非常重要。后续每改一处配置,都先在本地刷新确认没有破坏页面,再推送到线上。我见过太多人改完直接 push,结果线上 404 或样式全丢,最后才发现本地构建早就报错了。serve命令会监听文件变化并自动重新构建,但注意一点:_config.yml这类站点级配置文件修改后,最好手动按Ctrl+C重启一次,因为它的变更不一定被自动监听机制完整捕获。这是 Jekyll 的固有行为,不是你的操作问题。

3. 把模板脸改成自己的主页:配置项逐个拆

3.1 站点级字段:url 和 baseurl 是最优先的四个值

打开根目录的_config.yml,不要急着通读全文,先找到并修改这四个字段:

  • url:站点最终访问地址,例如https://username.github.io
  • baseurl:用户名仓库留空"",项目仓库填"/仓库名"
  • title:显示在浏览器标签页和页面头部的站名
  • description:站点描述,很多搜索引擎会把这段文字作为摘要

这四个字段影响所有生成页面的路径和 SEO,优先级最高。我踩过的典型错误是:在用户名仓库里仍然把baseurl写成/仓库名,结果所有 CSS、图片路径全部变成二级目录,页面打开是纯 HTML 裸排版。判断方法很简单,打开浏览器的 Network 面板,如果样式文件请求返回 404,九成是baseurl不对。

3.2 作者信息、头像与个人简介

继续往下滚动_config.yml,会找到author段。这里面通常有nameavatarbiolocation等字段。头像路径建议直接填/images/avatar.png,然后把images目录里的默认头像替换成你自己的照片。bio字段会显示在侧边栏,控制在两三句话以内,别写成长篇自传,更详细的经历放到_pages/about.md里。

_pages/about.md是多数访客的落地页,支持完整的 Markdown 排版,可以放研究兴趣、教育经历、招生说明、代表性项目。这里有一点容易被忽略:在 Markdown 正文里引用图片时,推荐用 Jekyll 的relative_url过滤器统一处理:

{{ "/images/xxx.png" | relative_url }}

而不是硬编码/images/xxx.png。这样以后切域名、切 baseurl 时,图片路径不会第二次踩坑。头像在 YAML 里的写法保持模板示例即可,生成页面时模板会自动处理。

3.3 导航栏与页面结构

顶部导航栏的内容在_data/navigation.yml文件里维护。默认会有 About、Publications、Talks、Blog 等条目,每一条的结构是:

- title: "Publications" url: /publications/

新增一个栏目时,先在_pages目录下创建 Markdown 文件,用 front matter 声明页面地址:

--- layout: single title: "Projects" permalink: /projects/ ---

然后在navigation.yml里加一条对应记录。这样整个站点的栏目就是你完全可控的了。默认模板已经内置好了 Publications、Talks、Teaching 的集合页面,你不需要从零创建,只需要往对应的内容目录里加文件。

3.4 社交入口与学术身份标识

author段里通常会预留google_scholarorcidgithublinkedintwitter这些字段,填上对应的 ID 或用户名,页面侧边栏就会自动渲染图标链接。

学术 ID 的填写优先级,我的建议是这样:

  • ORCID 最通用,投稿系统和基金申请系统都认这个标识
  • Google Scholar 在国际同行访问时很有用,可以放但不用作为唯一入口
  • GitHub 只要你有代码仓库,就一定要填,这是很多人判断工程能力的直接入口

如果还没有 ORCID,建议先去注册一个。它是终身绑定的学术身份标识,比个人域名更不容易漂移,即使换学校、换域名也不会丢。

3.5 小图标与搜索引擎收录

images目录里的 favicon.ico 是浏览器标签页的小图标,不换不影响功能,但换上自己的图标会让整个站点的完成度高一个档次。搜索引擎收录方面,Jekyll 插件jekyll-sitemap会自动生成sitemap.xml,模板里已经内置了这个插件的话,站点上线后就能自动被抓取。学术主页不需要过度优化 SEO,除非你面临比较严重的重名问题,需要通过搜索排名把正确主页顶到第一位,才需要额外做结构化数据标记。

4. 内容填充:论文、学术报告、博客三种内容各有各的规矩

4.1 论文条目的最小写法

_publications目录下,每篇论文对应一个独立 Markdown 文件。文件名我建议用年份-第一作者-简短标题.md的格式,比如2024-zhangsan-nerf-analysis.md。这样文件排序天然就是时间倒序,在编辑器里也好辨认。

文件开头的 front matter 是这个机制的核心:

--- title: "论文完整标题" date: 2024-03-15 venue: "期刊或会议全称" paperurl: "https://doi.org/..." citation: "作者列表 (2024). 论文标题. 期刊/会议." ---

正文区可以写摘要、PDF 预览说明,或者复现代码的使用注意。paperurlcodeslides这些字段会在列表页自动渲染成下载或查看按钮,不需要自己排版。日期字段date不只是显示用,模板的列表排序也依赖它。格式必须是 ISO 标准的YYYY-MM-DD,写成“2024年3月”这种中文格式,轻则排序混乱,重则条目直接不显示。

批量录入历史论文时,我一般从 DBLP 或 BibTeX 导出条目,再用一个小脚本把titleyearvenue映射成 front matter,半小时能处理完几十篇。手动复制模板一个个建文件效率太低,还容易漏字段。

4.2 论文之外的学术内容:报告与教学

_publications之外,模板还内置了_talks_teaching两个内容集合。_talks下同样是 Markdown 文件,front matter 里写titledatevenue,如果报告有 slides 或视频回放,可以直接加slidesvideo字段。_teaching适合放课程主页,讲义 PDF 可以放在files目录统一引用。

这里有一个从结构设计上就值得理解的点:学术主页的价值不只是论文列表,招生和合作方很看重“这个人有没有在参与学术社区交流”。哪怕只更新一个 seminar 报告,也比主页半年不动要可信得多。所以哪怕内容暂时不多,也建议把这三类集合的骨架都建好,后续有内容直接往里填就行。

4.3 博客短文:_posts 的命名规范

博客目录是_posts,文件名必须遵循YYYY-MM-DD-title.md的格式,这是 Jekyll 的硬性规范。写好后会在 Blog 页面按日期倒序排列。

学术博客不一定要写完整论文。会议见闻、复现笔记、教学答疑、工具评测都合适。我个人很推荐博士生把实验踩坑过程记录下来,形式上像是在写备忘,实际上是在给自己积累可检索的知识库。很多东西半年后回头看,当时的解决方案比自己记忆中的要详细得多。

4.4 PDF 等附件放哪、链接怎么写

论文 PDF、课程讲义、CV 这些文件,统一放在files目录下,和images目录同级。链接推荐用相对路径,最稳妥的写法还是配合relative_url过滤器:

[下载 PDF]({{ "/files/paper1.pdf" | relative_url }})

直接写files/paper1.pdf在用户名仓库下也能用,但如果未来仓库改成子路径部署,链接就断。既然 Jekyll 提供了成熟的过滤器,就一次养成好习惯,避免未来迁移时返工。

文件命名有两条铁律:不要用中文,不要用空格,统一英文小写加连字符。我见过有人上传“论文终稿最终版 final.PDF”,本地打开没问题,push 到线上直接 404。静态站的链接是大小写敏感且不处理空格的,和本地操作系统文件系统不一样,这是最容易栽的隐形坑。

5. 部署上线与自动化:GitHub Pages 的完整链路

5.1 第一次 Push 和 Pages 开关

本地改好后,把内容推送到 GitHub:

git add -A git commit -m "feat: init academic site" git push origin main

注意分支名以你仓库实际为准,模板可能是main也可能是master。推送完成后,进入仓库 Settings -> Pages,Source 选择 Deploy from a branch,分支选main,目录选/root,保存。

稍等一两分钟,GitHub 会自动执行 Jekyll 构建,把生成的静态页面发布出去。这是 GitHub Pages 的默认工作方式:它识别到这是一个 Jekyll 项目后,会在云端跑一次完整构建,不依赖你本机的 Ruby 版本。所以本地 build 失败时,线上也大概率失败;反过来,本地能正常serve,线上基本不会出问题。两者的差异主要来自 GitHub Pages 锁定的依赖版本和本地Gemfile.lock不一致,如果出现同步问题,优先把两边的依赖对齐。

5.2 自定义域名:CNAME 文件和 DNS 解析

学术圈很流行用自己的名字做域名,比如zhangsan.me。部署流程分两步:

第一步,在仓库根目录新建一个纯文本文件CNAME,里面只写一行域名,例如:

www.zhangsan.me

push 后 GitHub 会验证这个域名。第二步,去 DNS 服务商处添加解析:主域名用 A 记录指向 GitHub Pages 的 IP 地址,www子域名用 CNAME 记录指向username.github.io。解析生效后,回到 Pages 设置里勾选 Enforce HTTPS,让浏览器强制走加密链接。

这里要重点提醒:CNAME文件属于仓库的一部分,每次 push 都会带上,不要把它加到.gitignore。以后换域名时直接改这个文件内容并 push,旧域名会自动解绑。

5.3 用 GitHub Actions 固定构建行为

如果你希望多人协作时构建行为完全一致,或者想脱离本地环境依赖,推荐把构建从默认方式切到 GitHub Actions。在仓库里创建.github/workflows/github-pages.yml,一个最小可用的 workflow 可以写成:

name: Deploy Jekyll site to Pages on: push: branches: ["main"] permissions: contents: read pages: write id-token: write jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/configure-pages@v5 - uses: actions/cache@v4 with: path: vendor/bundle key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }} restore-keys: ${{ runner.os }}-gems- - uses: actions/setup-ruby@v1 with: ruby-version: '3.2' - name: Install dependencies run: bundle install - name: Build site run: bundle exec jekyll build - uses: actions/upload-pages-artifact@v3 deploy: needs: build runs-on: ubuntu-latest environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} steps: - id: deployment uses: actions/deploy-pages@v4

这个 workflow 的逻辑并不复杂:每次 push 到 main 分支后,自动 checkout 代码、安装依赖、执行构建,然后把构建产物发布到 Pages。切到 Actions 构建后,本地只需要做内容编辑和预览,具体构建行为由 CI 固化下来,换电脑、多人协作都不会出现“你本地能跑我这不行”的问题。使用 Actions 后,记得在 Settings -> Pages 的 Source 里选择 GitHub Actions,而不是 Deploy from a branch。

5.4 更新内容的最小流程

日常更新一篇论文或博客,最小流程是四步:

  1. 本地新建或修改对应目录下的 Markdown 文件
  2. 运行bundle exec jekyll serve预览确认
  3. git addgit commitgit push
  4. 等 GitHub 构建完成,刷新线上页面确认

熟练之后,一次内容更新的平均耗时大概三分钟,大头反而花在 PDF 扫描和 citation 信息整理上。这也是我坚持用 Academic Pages 的原因:静态站没有后台数据库,没有插件要升级,内容全部是文本文件,随时能备份、能迁移、能版本回滚。

6. 我反复遇到的坑与排查思路

6.1 样式突然变成裸 HTML?先查 baseurl

最典型的症状是:页面能打开,但没有任何样式,图片全部裂开。根因九成出在_config.yml里的urlbaseurl写错。用户名仓库正确的写法是baseurl: "",项目仓库是baseurl: "/仓库名"。改完记得重启本地 serve,因为站点级配置文件不总是被热更新机制捕获。

还有一个连带场景:项目仓库下,页面内部导航链接如果写的绝对路径,会在站点上线后全部跳到根路径,表现就是点击导航回到首页。正确做法是让所有内部链接都经过relative_url处理,或者在写_pages的 permalink 时统一带上前缀。

6.2 本地正常,GitHub Pages 上线却空白

如果本地一切正常,线上却 404 或白屏,优先级依次排查:

  • 分支没选对:Settings -> Pages 里配置的分支,和实际 push 的分支不一致
  • Source 模式和仓库内容不匹配:Source 选了 GitHub Actions,但仓库里没有可用的 workflow,构建从未触发
  • 依赖版本不一致:本地跑过bundle update导致 Gemfile.lock 和线上锁定版本不一致,线上构建失败

排查突破口是仓库的 Actions 标签页,构建日志里会有明确报错行。我一直把线上构建日志当作最可靠的排错入口,遇到线上问题先看日志,而不是反复改配置盲试。

6.3 论文列表不显示,或顺序不对

不显示的情况,先看 front matter 是否被正确识别。最容易犯的错误是直接复制别人论文文件的 YAML,字段名大小写和模板要求不一致,比如把venue写成Venue。Jekyll 的 front matter 字段名是大小写敏感的,这个错误不会报构建失败,但字段值就是渲染不出来。

排序错乱则主要是date格式问题。统一用2024-01-15,不要写2024/01/15,也不要写January 2024。还有一个隐蔽问题:文件名重复。同一个 Markdown 文件如果同时出现在_drafts_publications里,构建结果可能出乎意料。保持一个内容文件只放在一个集合目录,不要图省事复用。

6

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询