jekyll的plugin加载时机
按官网说法,应该会比较靠前执行:
In your site source root, make a _plugins directory. Place your plugins here. Any file ending in *.rb inside this directory will be loaded before Jekyll generates your site
验证一下,先搜搜“_plugins”
➜ jekyll grep '_plugins' -Rn ./
./configuration.rb:12: 'plugins' => '_plugins',
./plugin_manager.rb:38: required_gems = Bundler.require(:jekyll_plugins) # requires the gems in this group only
进configuration.rb看看,它还有个哈希常量叫DEFAULTS
module Jekyll
class Configuration < Hash
# Default options. Overridden by values in _config.yml.
# Strings rather than symbols are used for compatibility with YAML.
DEFAULTS = {
# Where things are
'source' => Dir.pwd,
'destination' => File.join(Dir.pwd, '_site'),
'plugins' => '_plugins',
'layouts' => '_layouts',
'data_source' => '_data',
'collections' => nil,
搜搜DEFAULTS,看样子应该到plugin_manager.rb看看
➜ jekyll grep 'DEFAULTS' -Rn ./
./configuration.rb:8: DEFAULTS = {
./configuration.rb:112: override['source'] || self['source'] || DEFAULTS['source']
./configuration.rb:116: override['quiet'] || self['quiet'] || DEFAULTS['quiet']
./plugin_manager.rb:88: if (site.config['plugins'] == Jekyll::Configuration::DEFAULTS['plugins'])
发现plugin_manager.rb中,site.config['plugins']的site,是new时赋予的
module Jekyll
class PluginManager
attr_reader :site
# Create an instance of this class.
#
# site - the instance of Jekyll::Site we're concerned with
#
# Returns nothing
def initialize(site)
@site = site
end
于是查查PluginManager.new
➜ jekyll grep 'PluginManager.new' -Rn ./
./site.rb:30: self.plugin_manager = Jekyll::PluginManager.new(self)
到site.rb看看,它持有一个plugin_manager,并且在new时,需要传入config
module Jekyll
class Site
attr_reader :source, :dest, :config
attr_accessor :layouts, :posts, :pages, :static_files,
:exclude, :include, :lsi, :highlighter, :permalink_style,
:time, :future, :unpublished, :safe, :plugins, :limit_posts,
:show_drafts, :keep_files, :baseurl, :data, :file_read_opts,
:gems, :plugin_manager
attr_accessor :converters, :generators
# Public: Initialize a new Site.
#
# config - A Hash containing site configuration details.
def initialize(config)
@config = config.clone
%w[safe lsi highlighter baseurl exclude include future unpublished
show_drafts limit_posts keep_files gems].each do |opt|
self.send("#{opt}=", config[opt])
end
# Source and destination may not be changed after the site has been created.
@source = File.expand_path(config['source']).freeze
@dest = File.expand_path(config['destination']).freeze
self.plugin_manager = Jekyll::PluginManager.new(self)
self.plugins = plugin_manager.plugins_path
查查Site.new
➜ jekyll grep 'Site.new' -Rn ./
./commands/doctor.rb:21: site = Jekyll::Site.new(configuration_from_options(options))
./commands/build.rb:29: site = Jekyll::Site.new(options)
到commands/build.rb看看,其中init_with_program是jekyll命令行的一系列钩子中的一环,当命令行执行“jekyll build”时,最终会执行“Jekyll::Commands::Build.process(options) ”
module Jekyll
module Commands
class Build < Command
class << self
# Create the Mercenary command for the Jekyll CLI for this Command
def init_with_program(prog)
prog.command(:build) do |c|
c.syntax 'build [options]'
c.description 'Build your site'
c.alias :b
add_build_options(c)
c.action do |args, options|
options["serving"] = false
Jekyll::Commands::Build.process(options)
end
end
end
# Build your jekyll site
# Continuously watch if `watch` is set to true in the config.
def process(options)
Jekyll.logger.log_level = :error if options['quiet']
options = configuration_from_options(options)
site = Jekyll::Site.new(options)
Site.new时传入的options,先经configuration_from_options转换,此方法来自于父类Command,去看看
# Create a full Jekyll configuration with the options passed in as overrides
#
# options - the configuration overrides
#
# Returns a full Jekyll configuration
def configuration_from_options(options)
Jekyll.configuration(options)
end
至此更明显了,它就是用于覆盖上面看到的DEFAULTS配置的。它引用了Jekyll.configuration来做,去看看
def configuration(override = Hash.new)
config = Configuration[Configuration::DEFAULTS]
override = Configuration[override].stringify_keys
unless override.delete('skip_config_files')
config = config.read_config_files(config.config_files(override))
end
# Merge DEFAULTS < _config.yml < override
config = Utils.deep_merge_hashes(config, override).stringify_keys
set_timezone(config['timezone']) if config['timezone']
config
end