產生器
當您需要 Jekyll 根據您自己的規則建立其他內容時,您可以建立一個產生器。
產生器是 Jekyll::Generator
的子類別,它定義了一個 generate
方法,該方法接收 Jekyll::Site
的執行個體。 generate
的傳回值會被忽略。
在 Jekyll 清點現有內容後,產生器才會執行,而且會在產生網站之前執行。包含 front matter 的頁面會儲存為 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
。 - 透過 前置資料預設值 設定頁面的能力將會非常棒!因此,將特定
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
現在,已產生的頁面可以設定為使用特定配置或輸出至目標目錄中的特定路徑,所有這些都可以透過設定檔使用前置資料預設值來完成。例如
# _config.yml
defaults:
- scope:
type: categories # select all category pages
values:
layout: category_page
permalink: categories/:category/
技術層面
產生器只需要實作一個方法
方法 | 說明 |
---|---|
|
產生內容作為副作用。 |
如果您的產生器包含在單一檔案中,則可以命名為您想要的任何名稱,但應具有 .rb
副檔名。如果您的產生器分佈在多個檔案中,則應將其打包為 Rubygem,並發佈在 https://rubygems.org/。在此情況下,寶石的名稱取決於該網站上名稱的可用性,因為沒有兩個寶石可以具有相同的名稱。
預設情況下,Jekyll 會在 _plugins
目錄中尋找產生器。但是,您可以透過在設定檔中將所需的目錄名稱指定給金鑰 plugins_dir
來變更預設目錄。