Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call Jekyll commands from Ruby

I have a Rails app which creates/builds some Jekyll sites on the same server. Right now, I'm calling Jekyll commands with backticks like this:

def build_jekyll
  result = `jekyll build -s /some/source/path -d /some/dest/path`
end

This works fine but feels a little un-ruby like. If the jekyll gem is in my Rails Gemfile, is there a way I can build a jekyll site using ruby?

(from the docs, it looks like I would call Jekyll::Commands::Build.build but I'm not sure how to initialize the site parameter).

like image 654
Callmeed Avatar asked Dec 11 '22 12:12

Callmeed


1 Answers

TL;DR

require 'jekyll'

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

Jekyll::Site.new(conf).process

But how did you find out?

I figured this out by looking at the source code. When you run jekyll build, you enter into the source file bin/jekyll. The interesting part here is

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

Hm, looks like the actual work is done in Jekyll::Commands::Build.process, so let's take a look into that method in lib/jekyll/commands/build.rb:

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

  # other stuff
end

Again, the actual magic happens somewhere else, namely in Jekyll::Commands::Build.build, also in lib/jekyll/commands/build.rb

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

  self.process_site(site)
end

This in turn calls a class method called process_site, which comes from the superclass Jekyll::Command defined in lib/jekyll/command.rb

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

So we actually want to call process on a Jekyll::Site. One thing we have yet to find out is how to specify options for the Jekyll::Site instance. Let's take a closer look at 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

So apparently we need to supply a hash with the 'source' and 'destination' keys pointing to the desired directories. The rest of the configuration will be generated by Jekyll with the Jekyll.configuration method which we saw earlier in bin/jekyll. That's about it. Now, the only thing left to do is putting the pieces together ;-)

like image 61
Patrick Oscity Avatar answered Dec 22 '22 16:12

Patrick Oscity