生成器
当你需要 Jekyll 根据你自己的规则创建附加内容时,你可以创建一个生成器。
生成器是 Jekyll::Generator
的子类,它定义了一个 generate
方法,该方法接收 Jekyll::Site
的一个实例。 generate
的返回值将被忽略。
生成器在 Jekyll 清点现有内容后和生成网站之前运行。带有页眉信息的页面存储为 Jekyll::Page
的实例,并可通过 site.pages
获得。静态文件成为 Jekyll::StaticFile
的实例,并可通过 site.static_files
获得。有关详细信息,请参阅 变量文档页面 和 Jekyll::Site
。
在以下示例中,生成器将在构建时为模板变量注入计算值。名为 reading.html
的模板有两个未定义的变量 ongoing
和 done
,当生成器运行时,这些变量将被定义或分配一个值
module Reading
class Generator < Jekyll::Generator
def generate(site)
book_data = site.data['books']
ongoing = book_data.select { |book| book['status'] == 'ongoing' }
done = book_data.select { |book| book['status'] == 'finished' }
# get template
reading = site.pages.find { |page| page.name == 'reading.html'}
# inject data into template
reading.data['ongoing'] = ongoing
reading.data['done'] = done
end
end
end
以下示例是一个更复杂的生成器,它生成新页面。
在此示例中,生成器的目的是为 site
中注册的每个类别创建一个页面。这些页面是在运行时创建的,因此它们的正文、页眉信息和其他属性需要由插件本身设计。
- 这些页面旨在呈现给定类别下的所有文档的列表。因此,呈现的文件的基本名称最好为
index.html
。 - 能够通过frontmatter 默认值配置页面将非常棒!因此,为这些页面分配特定
type
将是有益的。
module SamplePlugin
class CategoryPageGenerator < Jekyll::Generator
safe true
def generate(site)
site.categories.each do |category, posts|
site.pages << CategoryPage.new(site, category, posts)
end
end
end
# Subclass of `Jekyll::Page` with custom method definitions.
class CategoryPage < Jekyll::Page
def initialize(site, category, posts)
@site = site # the current site instance.
@base = site.source # path to the source directory.
@dir = category # the directory the page will reside in.
# All pages have the same filename, so define attributes straight away.
@basename = 'index' # filename without the extension.
@ext = '.html' # the extension.
@name = 'index.html' # basically @basename + @ext.
# Initialize data hash with a key pointing to all posts under current category.
# This allows accessing the list in a template via `page.linked_docs`.
@data = {
'linked_docs' => posts
}
# Look up front matter defaults scoped to type `categories`, if given key
# doesn't exist in the `data` hash.
data.default_proc = proc do |_, key|
site.frontmatter_defaults.find(relative_path, :categories, key)
end
end
# Placeholders that are used in constructing page URL.
def url_placeholders
{
:path => @dir,
:category => @dir,
:basename => basename,
:output_ext => output_ext,
}
end
end
end
现在,可以通过使用 frontmatter 默认值在配置文件中设置特定布局或在目标目录中的特定路径处输出生成的页面。例如
# _config.yml
defaults:
- scope:
type: categories # select all category pages
values:
layout: category_page
permalink: categories/:category/
技术方面
生成器只需要实现一种方法
方法 | 说明 |
---|---|
|
作为副作用生成内容。 |
如果生成器包含在单个文件中,则可以根据需要对其命名,但它应该具有.rb
扩展名。如果生成器跨多个文件拆分,则应该将其打包为 Rubygem,并在 https://rubygems.org.cn/ 发布。在这种情况下,gem 的名称取决于该网站上名称的可用性,因为没有两个 gem 可以具有相同的名称。
默认情况下,Jekyll 在_plugins
目录中查找生成器。但是,可以通过在配置文件中将所需名称分配给键plugins_dir
来更改默认目录。