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"
  Bundler.require

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

  $docraptor = DocRaptor::DocApi.new

  begin

    # https://docraptor.com/documentation/api#api_general
    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:   "https://theatren.com/programs", # 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: "http://hello.com",                                # pretend URL when using document_content
      # },
    )
    File.open("/Users/ryanhayden/ktch/theatren/_site/programs.pdf", "wb") do |file|
      file.write(create_response)
    end
    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")
    end

end

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
end

or

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

  • 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.

And how could I do it to modify some files to be written to disk? More specifically, I’d like to modify my assets/css/main.css file, which I use with sass, such as:

---
---
@charset "utf-8";

@import
  "variables",
  "themes",
  "layout",
  "base"
;

I would like to add some classes to it based on values from _config.yml. The problem is that these classes are modified later when using JEKYLL_ENV=production and sass style: compressed in _config.yml, and these changes made it behave incorrectly (I have no idea why). So I would like to be able to still use my sass style: compressed, but after it was compressed add these classes. How can I do this?