如何从Ruby调用Jekyll命令

Cal*_*eed 3 ruby ruby-on-rails jekyll

我有一个Rails应用程序,它在同一台服务器上创建/构建一些Jekyll站点.现在,我用这样的反引号调用Jekyll命令:

def build_jekyll
  result = `jekyll build -s /some/source/path -d /some/dest/path`
end
Run Code Online (Sandbox Code Playgroud)

这很好用,但感觉有点像红宝石一样.如果jekyll gem在我的Rails Gemfile中,有没有办法可以使用ruby构建一个jekyll网站?

(来自文档,看起来我会打电话,Jekyll::Commands::Build.build但我不知道如何初始化网站参数).

Pat*_*ity 13

TL; DR

require 'jekyll'

conf = Jekyll.configuration({
  'source'      => 'path/to/source',
  'destination' => 'path/to/destination'
})

Jekyll::Site.new(conf).process
Run Code Online (Sandbox Code Playgroud)

但是你是怎么发现的?

我通过查看源代码来解决这个问题.运行时jekyll build,输入源文件bin/jekyll.这里有趣的部分是

command :build do |c|
  # ommitted

  c.action do |args, options|
    options = normalize_options(options.__hash__)
    options = Jekyll.configuration(options)
    Jekyll::Commands::Build.process(options)
  end
end
Run Code Online (Sandbox Code Playgroud)

嗯,看起来像是完成了实际的工作Jekyll::Commands::Build.process,所以让我们来看看这个方法lib/jekyll/commands/build.rb:

def self.process(options)
  site = Jekyll::Site.new(options)
  self.build(site, options)

  # other stuff
end
Run Code Online (Sandbox Code Playgroud)

再一次,真正的魔法发生在其他地方,即in Jekyll::Commands::Build.build,in inlib/jekyll/commands/build.rb

def self.build(site, options)
  # some logging going on here

  self.process_site(site)
end
Run Code Online (Sandbox Code Playgroud)

这又调用了一个名为的类方法process_site,它来自于中Jekyll::Command定义的超类lib/jekyll/command.rb

def self.process_site(site)
  site.process
rescue Jekyll::FatalException => e
  # some error handling
end
Run Code Online (Sandbox Code Playgroud)

所以我们实际上想要打电话processJekyll::Site.我们还没有找到的一件事是如何为Jekyll::Site实例指定选项.我们来仔细看看lib/jekyll/site.rb

def initialize(config)
  # more options ...

  self.source          = File.expand_path(config['source'])
  self.dest            = File.expand_path(config['destination'])

  # more options ...
end
Run Code Online (Sandbox Code Playgroud)

所以显然我们需要提供一个散列,其中'source''destination'键指向所需的目录.其余的配置将由Jekyll使用Jekyll.configuration我们之前看到的方法生成bin/jekyll.就是这样.现在,唯一要做的就是将各个部分放在一起;-)

  • 我很忙,所以我写下了如何逐步执行代码:) (2认同)