Generator とは
Jekyll で独自のファイルを生成するためのプラグインの一つである。Jekyll::Generator
を継承して作成する。
Jekyll は以下の順序でサイトをビルドする。
- 処理対象のファイル(Page/Post/Static File)を探す
- Generator を実行する
- Page と Post を Converter で変換する
- 出力先ディレクトリをクリアする
- 出力先ディレクトリに Page と Post の変換結果を出力し、Static File をコピーする
全ての Generator は手順 2. で実行される。
Generator という名前から、Generator 自身に何らかのファイルを生成させてしまいそうになるが、生成したファイルは上記の手順 4 で Jekyll によって削除されてしまう(ただし _config.yml
の keep_files
に指定したファイルは削除されない)ので、作成されたはずのファイルが見つからず、頭を捻ることになる。
したがって、Generator は直接ファイルを生成するのではなく、独自の Page や StaticFile を生成し、処理対象に追加する。実際のファイル生成は Jekyll の通常の処理に任せるのがよい。
Generator の使用例
-
処理対象のファイルが存在せず、他の情報から出力ファイルを生成する場合。例えば、他の Post からカテゴリ一覧ページや月別アーカイブページを生成する場合など。
-
処理対象のファイルを変換したいが、YAML front-matter を書くことができない場合。例えば、画像ファイルを圧縮したり、sass ファイルや AltJS ファイルを変換したりする場合など。
Generator の実装例
Sass の変換を Jekyll のビルドに統合する場合を考える。今回は _scss
ディレクトリに Sass のソースファイルを配置し、出力先の css
ディレクトリに出力する。
まず、.scss
ファイルを表す StaticFile
のサブクラス SassStaticFile
を作成する。Jekyll は、Static File を出力する際、StaticFile#write
を呼ぶので、write
をオーバーライドし、出力時に CSS に変換する。
require 'pathname'
require 'sass'
module Jekyll
class SassStaticFile < ::Jekyll::StaticFile
def initialize(site, base, dir, name)
super
end
def destination(dest)
(Pathname.new(dest) + 'css' + @name).sub_ext('.css').to_s
end
def write(dest)
dest_path = destination(dest)
return false if File.exist?(dest_path) && !modified?
@@mtimes[path] = mtime
FileUtils.mkdir_p(File.dirname(dest_path))
template = File.read(path)
sass = ::Sass::Engine.new(template, syntax: :scss)
File.write(dest_path, sass.render)
true
end
end
end
次に、.scss
を探して SassStaticFile
を作成し、Jekyll の処理対象に追加する SassGenerator
を作成する。
module Jekyll
class SassGenerator < ::Jekyll::Generator
def generate(site)
sass_files(site.source).each do |sass|
site.static_files << SassStaticFile.new(site,
site.source,
File.dirname(sass),
File.basename(sass))
end
end
def sass_files(source)
sass_dir = File.join(source, '_scss')
return [] unless File.directory?(sass_dir)
files = Dir.chdir(sass_dir) { Dir['**/*.{sass,scss}'] }
files.map { |file| File.join('_scss', file) }
end
end
end
上記の内容を _plugins/sass.rb
など、_plugins
ディレクトリ以下に配置すれば、Jekyll がビルド時に自動でロードし、_scss/*.scss
を CSS ファイルに変換して css/*.css
に出力してくれる。