Best way to write a plugin that executes after jekyll has done its thing


I’m looking to write a simple script that runs docraptor on a file in my _site folder (after Jekyll has processed it) and then saves the returned PDF to the _site folder so that it can be consumed on the internet.

This was my first thought:

Jekyll::Hooks.register :site, :post_render do 

  require "bundler/setup"

  DocRaptor.configure do |dr|
    dr.username  = "--REDACTED--" # this key works for test documents
    # dr.debugging = true

  $docraptor =


    create_response = $docraptor.create_doc(
      test:             true,                                         # test documents are free but watermarked
      # document_content: "<html><body>Hello World</body></html>",      # supply content directly
      document_url:   "", # or use a url
      name:             "docraptor-ruby.pdf",                         # help you find a document later
      document_type:    "pdf",                                        # pdf or xls or xlsx
      # javascript:       true,                                       # enable JavaScript processing
      # prince_options: {
      #   media: "screen",                                            # use screen styles instead of print styles
      #   baseurl: "",                                # pretend URL when using document_content
      # },
    )"/Users/ryanhayden/ktch/theatren/_site/programs.pdf", "wb") do |file|
    puts "Wrote PDF to /Users/ryanhayden/ktch/theatren/_site/programs.pdf"

    rescue DocRaptor::ApiError => error
      puts "#{error.class}: #{error.message}"
      puts error.code          # HTTP response code
      puts error.response_body # HTTP response body
      puts error.backtrace[0..3].join("\n")


When I run this, I get undefined method 'downcase' for nil:NilClass

I’m definitely not a ruby expert, so I may be missing something obvious. Is this how you would even go about this?


By the way, I can confirm that if you just run the script without the first and last lines, it works. I’m just trying to get it to do this as part of the Jekyll build process.


try passing argument(s) to the block

Jekyll::Hooks.register :site, :post_render do |_site, _payload|
  # code to be run


Jekyll::Hooks.register :site, :post_write do |_site|
  # code to be run

  • prepended ‘underscore’ signifies that parameter wont be used in the code body.
  • I feel :post_write to be better as there will be a HTML version in the _site as well.


Thanks, @ashmaroli, I’ll try that.