主题模板 Themes

Jekyll 提供了高度自定义且强大的主题系统,你可以使用社区维护的主题模板,轻松自定义网站的外观。Jekyll 主题不仅包含插件,还将资源文件、布局、包含文件和样式表打包在一起,同时允许你在站点内容中对其进行覆盖和调整。

选择一个主题

你可以在以下网站中查找一个喜欢的 Jekyll 主题并预览:

更多资源请参考:资源

理解基于 Gem 的主题

当你创建一个新的 Jekyll 站点(运行 jekyll new <PATH> 命令)时,Jekyll 默认会安装一个名为 Minima 的基于 Gem 的主题。

使用基于 Gem 的主题时,站点的一些目录(如 assets_data_layouts_includes_sass)实际上存储在主题的 Gem 文件中,并不会直接出现在你的项目目录里。不过,Jekyll 在构建时仍然会读取并处理这些文件。

以 Minima 主题为例,你在 Jekyll 站点目录中通常只能看到以下文件:

.
├── Gemfile
├── Gemfile.lock
├── _config.yml
├── _posts
│   └── 2016-12-04-welcome-to-jekyll.markdown
├── about.markdown
└── index.markdown

GemfileGemfile.lock 文件由 Bundler 用于跟踪构建 Jekyll 站点所需的 gem 及其版本。

基于 gem 的主题让主题开发者可以更方便地提供更新,任何使用该主题 gem 的用户都能获取最新版本。当主题有更新时,开发者会将更新推送到 RubyGems。

如果你的项目使用了主题 gem,你可以(如果需要的话)运行 bundle update 来更新项目中的所有 gem。或者,你也可以运行 bundle update <THEME>(将 <THEME> 替换为主题名称,比如 minima),仅更新该主题 gem。主题开发者所做的任何新文件或更新(例如样式表或包含的文件)都会自动同步到你的项目中。

基于 gem 的主题的目标是让你能够享受功能完善、持续更新的主题,而不会因为主题的文件过多而干扰你的主要工作——创作内容。

覆盖主题默认设置

Jekyll 主题预设了数据、布局(layouts)、引入文件(includes)和样式表(stylesheets),但你可以用自己的内容覆盖这些默认设置。

如果想修改主题中的布局或引入文件,可以将它们复制到 _layouts_includes 目录中,然后进行修改,或者直接创建一个同名文件来覆盖主题自带的文件。

例如,如果你的主题有一个 page 布局,你可以在 _layouts 目录下创建一个 page.html 文件(即 _layouts/page.html)来自定义该布局。

要在计算机上定位主题的文件:

  1. 运行 bundle info --path,后跟主题 gem 的名称,例如,bundle info --path minima 用于 Jekyll 的默认主题。

    这会返回基于 gem 的主题文件的位置。例如,Minima 主题的文件可能位于 macOS 上的 /usr/local/lib/ruby/gems/2.6.0/gems/minima-2.5.1

  2. 在 Finder 或 Explorer 中打开主题的目录:

    # 在 macOS 上
    open $(bundle info --path minima)
    
    # 在 Windows 上
    # 首先获取 gem 的安装路径:
    #
    #   bundle info --path minima
    #   => C:/Ruby26-x64/lib/ruby/gems/3.1.3/gems/minima-2.5.1
    #
    # 然后用上述路径调用 explorer,替换 `/` 为 `\`
    explorer C:\Ruby26-x64\lib\ruby\gems\3.1.3\gems\minima-2.5.1
    
    # 在 Linux 上
    xdg-open $(bundle info --path minima)
    

    打开 Finder 或 Explorer 窗口,显示主题的文件和目录。Minima 主题 gem 包含以下文件:

    .
    ├── LICENSE.txt
    ├── README.md
    ├── _includes
    │   ├── disqus_comments.html
    │   ├── footer.html
    │   ├── google-analytics.html
    │   ├── head.html
    │   ├── header.html
    │   ├── icon-github.html
    │   ├── icon-github.svg
    │   ├── icon-twitter.html
    │   └── icon-twitter.svg
    ├── _layouts
    │   ├── default.html
    │   ├── home.html
    │   ├── page.html
    │   └── post.html
    ├── _sass
    │   ├── minima
    │   │   ├── _base.scss
    │   │   ├── _layout.scss
    │   │   └── _syntax-highlighting.scss
    │   └── minima.scss
    └── assets
        └── main.scss
    

通过清楚了解主题文件的位置,你现在可以通过在 Jekyll 网站目录中创建同名文件来覆盖任何主题文件。

假设你想覆盖 Minima 的 footer,在你的 Jekyll 网站中创建一个 _includes 文件夹,并在其中添加一个名为 footer.html 的文件。Jekyll 现在会使用你网站中的 footer.html 文件,而不是 Minima 主题 gem 中的 footer.html 文件。

要修改任何样式表,你还需要额外复制 Minima 主题中的主 sass 文件(_sass/minima.scss)到你网站的 _sass 目录中。

Jekyll 在查找请求的文件时,会首先查找你网站的内容,再查找主题的默认文件,搜索以下文件夹:

  • /assets
  • /_data
  • /_layouts
  • /_includes
  • /_sass

请注意,复制主题文件会使你无法接收这些文件的主题更新。为了继续获得所有样式表的主题更新,你可以在自己额外的原始命名 CSS 文件中使用更高特异性的 CSS 选择器。

有关可以覆盖的文件,请参考所选主题的文档和源代码库。

带有 _data 目录的主题4.3.0

从版本 4.3.0 开始,Jekyll 也会考虑主题的 _data 目录。这使得数据可以跨主题进行分发。

一个典型的例子是设计元素中使用的文本。

假设一个主题提供了 testimonials.html 这个包含文件。这个设计元素在页面上创建一个新部分,并在推荐语列表上方放置一个 h3 标题。

主题开发者可能会将标题用英文写好,并直接放入 HTML 源代码中。

使用该主题的人可以将这个包含文件复制到他们的项目中,并在那里替换标题。

考虑到 _data 目录,还有一种解决方案可以完成这一标准任务。

开发者在设计模板中不会直接写入文本,而是引用一个文本目录(例如 site.data.i18n.testimonials.header),并在主题的 _data/i18n/testimonials.yml 文件中创建一个数据文件。

在这个文件中,标题放在 header 键下,Jekyll 会处理其余的工作。

对于主题开发者来说,这看起来比以前的工作量大。

然而,对于主题的使用者来说,定制化变得极为简化。

假设该主题被一个来自德国的客户使用。为了让她获得已翻译的推荐语设计元素标题,她只需要在项目目录中创建一个数据文件,并为 site.data.i18n.testimonials.header 键添加德文翻译或她选择的标题,设计元素就会自动定制。

她不再需要将包含文件复制到她的项目目录中,在那里进行定制,并且最重要的是,放弃所有主题更新,只是因为主题开发者提供了通过文本文件集中修改文本模块的可能性。

数据文件提供了高度的灵活性。主题开发者放置文本模块的位置可能与主题使用者的不同,这可能会导致一些预料之外的问题!

与上述例子相关,覆盖 site.data.i18n.testimonials.header 键时,主题的 _data/i18n/testimonials.yml 文件在使用者站点中可能位于三个不同的位置:

  • _data/i18n.yml 中的 testimonials.header
  • _data/i18n/testimonials.yml 中的 header 键(与给出的例子布局一致)
  • _data/i18n/testimonials/header.yml 中没有键,标题可以直接放入文件中

主题开发者应该注意到这种歧义,当帮助那些在设置主题设计元素的文本模块时感到迷茫的使用者时。

在使用数据功能时,问问自己,所引入的键是否会改变主题的行为(无论键是否存在),或者它只是展示的数据。如果是改变主题行为的,它应该放入 site.config,否则可以通过 site.data 提供。

将修改主题行为的数据捆绑在一起被视为一种 反模式,强烈不建议使用。确保提供的每一项数据都能被主题的使用者轻松覆盖,是主题作者的责任。

将基于 gem 的主题转换为常规主题

假设你想放弃基于 gem 的主题,并将其转换为常规主题,在这种情况下,所有文件都应该存在于你的 Jekyll 网站目录中,且不再存储在主题 gem 中。

为此,你需要将主题 gem 目录中的文件复制到你的 Jekyll 网站目录中(例如,如果你的 Jekyll 网站在 /myblog 目录下,可以将文件复制到 /myblog。更多细节请参考前面的章节)。

接下来,你必须告知 Jekyll 使用该主题时所引用的插件。这些插件可以在主题的 gemspec 文件中找到作为运行时依赖项。例如,如果你正在转换 Minima 主题,可能会看到如下内容:

spec.add_runtime_dependency "jekyll-feed", "~> 0.12"
spec.add_runtime_dependency "jekyll-seo-tag", "~> 2.6"

你应该在 Gemfile 中以两种方式之一包含这些插件的引用。

方法一:在 Gemfile_config.yml 中分别列出插件

# ./Gemfile

gem "jekyll-feed", "~> 0.12"
gem "jekyll-seo-tag", "~> 2.6"
# ./_config.yml

plugins:
  - jekyll-feed
  - jekyll-seo-tag

方法二:在 Gemfile 中显式列出 Jekyll 插件,而不更新 _config.yml

# ./Gemfile

group :jekyll_plugins do
  gem "jekyll-feed", "~> 0.12"
  gem "jekyll-seo-tag", "~> 2.6"
end

无论哪种方式,都不要忘记运行 bundle update

如果你在 GitHub Pages 上发布,则应该只更新 _config.yml,因为 GitHub Pages 不通过 Bundler 加载插件。

最后,移除 Gemfile 和配置中的主题 gem 引用。例如,要移除 minima

  • 打开 Gemfile 并删除 gem "minima", "~> 2.5"
  • 打开 _config.yml 并删除 theme: minima

现在,运行 bundle update 将不再更新主题 gem。

安装基于 gem 的主题

jekyll new <PATH> 命令并不是创建带有基于 gem 的主题的新 Jekyll 网站的唯一方式。你也可以在线找到基于 gem 的主题,并将其集成到你的 Jekyll 项目中。

例如,可以在 RubyGems 上查找 Jekyll 主题 来发现其他基于 gem 的主题。(请注意,并非所有主题的名称都遵循 jekyll-theme 的命名惯例。)

安装基于 gem 的主题:

  1. 将主题 gem 添加到你的站点的 Gemfile 中:

    # ./Gemfile
    
    # 这是一个示例,声明你要使用的主题 gem
    gem "jekyll-theme-minimal"
    

    或者,如果你是通过 jekyll new 命令开始的,可以将 gem "minima", "~> 2.0" 替换为你想要的 gem,例如:

    # ./Gemfile
    
    - gem "minima", "~> 2.5"
    + gem "jekyll-theme-minimal"
    
  2. 安装主题:

    bundle install
    
  3. 在站点的 _config.yml 中添加以下内容以启用主题:

    theme: jekyll-theme-minimal
    
  4. 构建站点:

    bundle exec jekyll serve
    

你可以在站点的 Gemfile 中列出多个主题,但在 _config.yml 中只能选择一个主题。

如果你要将 Jekyll 网站发布到 GitHub Pages,请注意 GitHub Pages 仅支持 某些基于 gem 的主题。GitHub Pages 还支持 使用托管在 GitHub 上的任何主题,就像使用 gem-based 主题一样,通过 remote_theme 配置来实现。

创建基于 gem 的主题

如果你是 Jekyll 主题开发者(而不是主题的使用者),你可以将你的主题打包成 RubyGems,并允许用户通过 Bundler 安装它。

如果你不熟悉创建 Ruby gem,不用担心。Jekyll 会通过 new-theme 命令帮助你创建一个新的主题。运行 jekyll new-theme 命令并指定主题名称作为参数。

例如:

jekyll new-theme jekyll-theme-awesome
    create /path/to/jekyll-theme-awesome/_layouts
    create /path/to/jekyll-theme-awesome/_includes
    create /path/to/jekyll-theme-awesome/_sass
    create /path/to/jekyll-theme-awesome/_layouts/page.html
    create /path/to/jekyll-theme-awesome/_layouts/post.html
    create /path/to/jekyll-theme-awesome/_layouts/default.html
    create /path/to/jekyll-theme-awesome/Gemfile
    create /path/to/jekyll-theme-awesome/jekyll-theme-awesome.gemspec
    create /path/to/jekyll-theme-awesome/README.md
    create /path/to/jekyll-theme-awesome/LICENSE.txt
    initialize /path/to/jekyll-theme-awesome/.git
    create /path/to/jekyll-theme-awesome/.gitignore
Your new Jekyll theme, jekyll-theme-awesome, is ready for you in /path/to/jekyll-theme-awesome!
For help getting started, read /path/to/jekyll-theme-awesome/README.md.

将你的模板文件添加到相应的文件夹中。然后根据需要完成 .gemspec 和 README 文件。

布局和包含文件

主题的布局和包含文件在 Jekyll 中的工作方式与其他 Jekyll 网站相同。将布局文件放在主题的 /_layouts 文件夹中,并将包含文件放在主题的 /_includes 文件夹中。

例如,如果你的主题有一个 /_layouts/page.html 文件,且某页面的 front matter(页面头部参数) 中包含 layout: page,Jekyll 会首先在站点的 _layouts 文件夹中查找 page 布局,如果不存在,则会使用主题中的 page 布局。

资源文件

任何位于 /assets 文件夹中的文件,在构建时会被复制到用户站点,除非站点中已存在相同路径的文件。你可以将任何类型的资源文件放在这里:SCSS 文件、图片、网页字体等。这些文件的处理方式与页面和静态文件相似:

  • 如果文件顶部有 front matter(页面头部参数),它将被渲染。
  • 如果文件没有 front matter(页面头部参数),它将直接被复制到生成的站点中。

这使得主题开发者可以提供一个默认的 /assets/styles.scss 文件,供其布局依赖,最终生成 /assets/styles.css 文件。

所有位于 /assets 文件夹中的文件都会按预期输出到编译后的站点的 /assets 文件夹中。

样式表

你的主题的样式表应该放在主题的 _sass 文件夹中,和你在编写 Jekyll 网站时一样。

_sass
└── jekyll-theme-awesome.scss

用户可以通过 @import 指令将你的主题样式包含到站点的样式表中。

@import "{{ site.theme }}";

主题依赖3.5.0

{#theme-gem-dependencies350}

Jekyll 会自动要求所有在主题 gem 中被列入白名单的 runtime_dependencies,即使它们没有明确地包含在站点的 plugins 配置项中。(注意:只有在使用 --safe 选项时才需要进行白名单设置。)

这样,最终用户无需跟踪需要在配置文件中包含的插件,确保主题 gem 按预期工作。

预配置主题 gems4.0

{#pre-configuring-theme-gems40}

Jekyll 会读取主题 gem 根目录中的 _config.yml 文件,并将其中的数据与站点现有的配置数据合并。

但与其他从主题中加载的实体不同,加载配置文件时有一些限制,概述如下:

  • Jekyll 的默认设置无法被主题配置文件覆盖。这部分仍由用户控制。
  • 主题配置文件不能是符号链接,无论是否启用了 safe mode,以及符号链接指向的文件是否为主题 gem 中的合法文件。
  • 主题配置文件应为键值对的形式。空的配置文件、仅列出项目的配置文件,或只包含简单文本的配置文件将被静默忽略。用户不会收到任何警告或日志输出,提醒这个问题。
  • 任何由主题配置文件定义的设置,都可以由用户覆盖。

虽然这一功能旨在简化主题的使用,但这些限制确保了主题配置文件不会以令人担忧的方式影响构建。任何主题所需的插件必须由用户手动列出,或通过主题的 gemspec 文件提供。

该功能将使主题 gem 能够直接支持 特定于主题的配置变量

在 README.md 文档中说明你的主题

你的主题应包括一个 /README.md 文件,说明站点作者如何安装和使用你的主题。包含哪些布局?有哪些包含项?他们需要在站点的配置文件中添加任何特别的内容吗?

添加截图

主题是视觉性的。通过在主题的仓库中包含一张 /screenshot.png 截图,让用户看到你的主题是什么样子的,这样它可以被程序化地获取。你也可以在主题的文档中包括这张截图。

预览你的主题

在创作主题时,预览你的主题可能会很有帮助。例如,可以在 /index.html/page.html 文件中添加虚拟内容。这样,你就可以使用 jekyll buildjekyll serve 命令来预览你的主题,就像预览 Jekyll 网站一样。

如果你在本地预览你的主题,请务必将 /_site 添加到主题的 .gitignore 文件中,以防止编译后的站点在分发主题时也被包含进去。

发布你的主题

主题通过 RubyGems.org 发布。你需要一个 RubyGems 账户,你可以 免费创建

  1. 首先,你需要将其放入 git 仓库中:

    git init # 仅第一次执行
    git add -A
    git commit -m "Init commit"
    
  2. 接下来,打包你的主题,运行以下命令,将 jekyll-theme-awesome 替换为你的主题名称:

    gem build jekyll-theme-awesome.gemspec
    
  3. 最后,将打包好的主题推送到 RubyGems 服务,运行以下命令,同样将 jekyll-theme-awesome 替换为你的主题名称:

    gem push jekyll-theme-awesome-*.gem
    
  4. 若要发布新版本的主题,请更新 gemspec 文件中的版本号(此示例中的文件为 jekyll-theme-awesome.gemspec),然后重复执行步骤 1 到 3。我们建议你遵循 语义化版本控制 来更新主题版本号。