Jekyll 静态站点完全教程 / 第10章:主题系统
第10章:主题系统
10.1 主题概述
Jekyll 主题(Theme)定义了站点的外观,包含布局(Layouts)、包含(Includes)、样式(Sass)和静态文件。
主题包含的内容
| 组件 | 说明 |
|---|
_layouts/ | 布局模板 |
_includes/ | 可复用片段 |
_sass/ | Sass 样式源文件 |
assets/ | CSS、JS、图片等静态资源 |
主题分发方式
| 方式 | 说明 | 适用场景 |
|---|
| Gem 主题 | 通过 RubyGems 安装 | 稳定版本管理 |
| 远程主题 | 从 GitHub 仓库加载 | GitHub Pages 项目 |
| 本地主题 | 直接放在项目中 | 完全自定义 |
10.2 使用默认主题创建站点
# 创建带默认主题 minima 的站点
jekyll new my-site
# 创建空白站点
jekyll new --blank my-site
# 使用指定主题
jekyll new --skip-bundle my-site
cd my-site
# 编辑 Gemfile 使用目标主题
bundle install
10.3 Gem 主题
安装 Gem 主题
# Gemfile
source "https://rubygems.org"
gem "jekyll", "~> 4.3"
gem "minima", "~> 2.5" # 默认主题
# _config.yml
theme: minima
bundle install
bundle exec jekyll serve
常见 Gem 主题
| 主题 | 说明 | 风格 |
|---|
minima | 默认主题,简洁 | 博客 |
jekyll-theme-chirpy | 功能丰富的博客 | 博客 |
jekyll-rtd-theme | Read the Docs 风格 | 文档 |
jekyll-gitbook | GitBook 风格 | 文档 |
jekyll-theme-hamilton | 现代简洁 | 博客 |
jekyll-theme-minimal | 极简主义 | 通用 |
jekyll-theme-slate | 深色主题 | 项目页 |
jekyll-theme-cayman | 单页面 | 项目页 |
查看主题文件位置
# 查看主题 gem 的安装路径
bundle show minima
# 输出: /path/to/gems/minima-2.5.1
# 查看主题的布局文件
ls $(bundle show minima)/_layouts/
# => default.html home.html page.html post.html
10.4 远程主题(Remote Theme)
远程主题从 GitHub 仓库直接加载,特别适合 GitHub Pages。
配置远程主题
# _config.yml
remote_theme: pages-themes/[email protected]
# 或使用 jekyll-remote-theme 插件
plugins:
- jekyll-remote-theme
remote_theme: mmistakes/minimal-mistakes
使用远程主题的限制
远程主题 vs Gem 主题
| 维度 | Gem 主题 | 远程主题 |
|---|
| 安装方式 | bundle install | 自动从 GitHub 拉取 |
| 版本控制 | Gemfile.lock 锁定 | @tag 指定版本 |
| 构建速度 | 快(本地缓存) | 首次较慢 |
| GitHub Pages | 部分支持 | 完全支持 |
| 离线使用 | ✅ | ❌ |
| 自定义覆盖 | ✅ | ✅ |
10.5 主题自定义与覆盖
Jekyll 允许在项目中覆盖主题的任何文件。
覆盖原理
项目目录优先级 > 主题文件
覆盖布局
# 主题布局位置
$(bundle show minima)/_layouts/
├── default.html
├── home.html
├── page.html
└── post.html
# 在项目中创建同名文件即可覆盖
my-site/
└── _layouts/
└── default.html # 覆盖主题的 default.html
覆盖包含文件
# 主题包含文件
$(bundle show minima)/_includes/
├── disqus_comments.html
├── footer.html
├── google-analytics.html
├── head.html
├── header.html
└── icon-github.html
# 覆盖页脚
my-site/
└── _includes/
└── footer.html # 覆盖主题的 footer.html
覆盖样式
// my-site/assets/css/main.scss
// 方式1:覆盖变量后引入主题样式
$brand-color: #ff6600;
$background-color: #fafafa;
@import "minima"; // 引入主题样式
// 方式2:添加自定义样式
.site-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.post-card {
border: 1px solid #eee;
border-radius: 8px;
padding: 1.5rem;
margin-bottom: 1rem;
transition: box-shadow 0.3s;
&:hover {
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
}
覆盖静态文件
# 添加自定义 JavaScript
my-site/
└── assets/
└── js/
└── custom.js # 追加到主题的 assets
# 添加自定义字体
my-site/
└── assets/
└── fonts/
└── custom-font.woff2
10.6 创建自定义主题
创建主题 gem
# 使用 Jekyll CLI 创建主题骨架
jekyll new-theme my-theme
# 目录结构
my-theme/
├── _layouts/
│ ├── default.html
│ ├── page.html
│ └── post.html
├── _includes/
│ ├── head.html
│ ├── header.html
│ └── footer.html
├── _sass/
│ ├── _variables.scss
│ ├── _base.scss
│ └── _layout.scss
├── assets/
│ ├── css/
│ │ └── style.scss
│ ├── js/
│ │ └── main.js
│ └── images/
├── my-theme.gemspec
├── Gemfile
├── LICENSE.txt
└── README.md
gemspec 配置
# my-theme.gemspec
Gem::Specification.new do |spec|
spec.name = "my-theme"
spec.version = "1.0.0"
spec.authors = ["Your Name"]
spec.email = ["[email protected]"]
spec.summary = "A beautiful Jekyll theme"
spec.homepage = "https://github.com/user/my-theme"
spec.license = "MIT"
spec.files = `git ls-files -z`.split("\x0").select do |f|
f.match(%r{^(_layouts|_includes|_sass|assets|LICENSE|README)}i)
end
spec.add_runtime_dependency "jekyll", ">= 3.9", "< 5.0"
spec.add_runtime_dependency "jekyll-seo-tag", "~> 2.8"
spec.add_runtime_dependency "jekyll-feed", "~> 0.17"
spec.add_development_dependency "bundler", "~> 2.0"
end
主题布局示例
<!-- _layouts/default.html -->
<!DOCTYPE html>
<html lang="{{ site.lang | default: 'en' }}">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% if page.title %}{{ page.title }} | {{ site.title }}{% else %}{{ site.title }}{% endif %}</title>
<link rel="stylesheet" href="{{ '/assets/css/style.css' | relative_url }}">
{% seo %}
{% feed_meta %}
</head>
<body class="{{ page.layout }} {% if page.hero %}has-hero{% endif %}">
{% include header.html %}
{% if page.hero %}
<section class="hero" style="background-image: url('{{ page.hero.image }}')">
<h1>{{ page.hero.title | default: page.title }}</h1>
{% if page.hero.subtitle %}
<p>{{ page.hero.subtitle }}</p>
{% endif %}
</section>
{% endif %}
<main class="site-main" role="main">
<div class="container">
{{ content }}
</div>
</main>
{% include footer.html %}
<script src="{{ '/assets/js/main.js' | relative_url }}"></script>
</body>
</html>
发布主题
# 构建 gem
gem build my-theme.gemspec
# 发布到 RubyGems
gem push my-theme-1.0.0.gem
# 或仅推送到 GitHub(用作远程主题)
git push origin main
10.7 主题变量与配置
通过配置控制主题行为
# _config.yml
theme: my-theme
# 主题自定义配置
title: "My Blog"
description: "A tech blog"
author: "Zhang San"
# 主题特性开关
show_sidebar: true
show_breadcrumbs: true
show_reading_time: true
show_toc: true
enable_dark_mode: true
enable_search: true
# 社交链接
social_links:
github: "https://github.com/user"
twitter: "https://twitter.com/user"
rss: "/feed.xml"
在主题中读取配置
<!-- _includes/header.html -->
<header>
<a href="{{ '/' | relative_url }}">{{ site.title }}</a>
{% if site.social_links.github %}
<a href="{{ site.social_links.github }}">GitHub</a>
{% endif %}
{% if site.enable_dark_mode %}
<button id="theme-toggle">🌙</button>
{% endif %}
</header>
10.8 业务场景:企业文档主题
# _config.yml
theme: corporate-docs
# 主题配置
theme_config:
logo: "/assets/images/logo.svg"
primary_color: "#2563eb"
sidebar:
collapse: true
sticky: true
footer:
copyright: "© 2025 Company Name"
links:
- title: "隐私政策"
url: "/privacy/"
- title: "使用条款"
url: "/terms/"
// _sass/_custom.scss
// 覆盖主题变量
$primary-color: {{ site.theme_config.primary_color | default: '#2563eb' }};
$sidebar-width: 280px;
// 自定义组件
.sidebar-logo {
img {
max-width: 180px;
padding: 1rem;
}
}
10.9 从其他主题迁移
备份当前自定义
# 导出自定义文件
mkdir -p _custom_backup
cp -r _layouts _custom_backup/
cp -r _includes _custom_backup/
cp -r _sass _custom_backup/
cp -r assets _custom_backup/
逐步迁移策略
1. 备份现有自定义文件
2. 在 Gemfile 中切换主题
3. bundle install
4. 逐个覆盖主题文件,将自定义内容移植
5. 测试所有页面
6. 清理旧主题残留文件
10.10 扩展阅读
本章小结
| 要点 | 说明 |
|---|
| Gem 主题 | 通过 theme: name 配置,bundle install 安装 |
| 远程主题 | remote_theme: owner/repo 从 GitHub 加载 |
| 覆盖 | 项目中的同名文件优先于主题文件 |
| 自定义主题 | 使用 jekyll new-theme 创建骨架 |
| 变量控制 | 通过 _config.yml 控制主题行为 |
下一章:数据文件与动态内容