ジェネレーター
独自のルールに基づいてJekyllに追加コンテンツを作成する必要がある場合は、ジェネレーターを作成できます。
ジェネレーターは、Jekyll::Generator
のサブクラスであり、generate
メソッドを定義します。このメソッドは、Jekyll::Site
のインスタンスを受け取ります。generate
の戻り値は無視されます。
ジェネレーターは、Jekyllが既存のコンテンツのインベントリを作成した後、サイトが生成される前に実行されます。フロントマターを持つページはJekyll::Page
のインスタンスとして保存され、site.pages
を介してアクセスできます。静的ファイルはJekyll::StaticFile
のインスタンスになり、site.static_files
を介してアクセスできます。詳細は、変数に関するドキュメントページとJekyll::Site
を参照してください。
次の例では、ジェネレーターはビルド時に計算された値をテンプレート変数に挿入します。reading.html
という名前のテンプレートには、未定義の変数ongoing
とdone
の2つがあり、ジェネレーターの実行時に定義または値が割り当てられます。
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/
技術的な側面
ジェネレーターは1つのメソッドのみを実装する必要があります
メソッド | 説明 |
---|---|
|
副作用としてコンテンツを生成します。 |
ジェネレーターが単一のファイルに含まれている場合、任意の名前を付けることができますが、.rb
拡張子を持つ必要があります。ジェネレーターが複数のファイルに分割されている場合は、https://rubygems.org/で公開するためにRubygemとしてパッケージ化する必要があります。この場合、2つのgemが同じ名前を持つことはできないため、gemの名前はそのサイトでの名前の可用性に依存します。
デフォルトでは、Jekyllは_plugins
ディレクトリでジェネレーターを探します。ただし、設定ファイルのキーplugins_dir
に必要な名前を割り当てることで、デフォルトのディレクトリを変更できます。