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

**URL:** <https://talk.jekyllrb.com/t/best-way-to-write-a-plugin-that-executes-after-jekyll-has-done-its-thing/202>\
**Category:** Help\
**Created:** [February 25, 2017, 3:47am UTC](https://talk.jekyllrb.com/t/best-way-to-write-a-plugin-that-executes-after-jekyll-has-done-its-thing/202 "2017-02-25T03:47:10Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![ryanhayden](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/ryanhayden/32/88_2.png) [@ryanhayden](https://talk.jekyllrb.com/u/ryanhayden)\
**Post date:** [February 25, 2017, 3:47am UTC](https://talk.jekyllrb.com/t/best-way-to-write-a-plugin-that-executes-after-jekyll-has-done-its-thing/202/1 "2017-02-25T03:47:10Z")

</div>

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:

```ruby

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?

---

<div class="post-metadata">

**Author:** ![ryanhayden](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/ryanhayden/32/88_2.png) [@ryanhayden](https://talk.jekyllrb.com/u/ryanhayden)\
**Post date:** [February 25, 2017, 3:48am UTC](https://talk.jekyllrb.com/t/best-way-to-write-a-plugin-that-executes-after-jekyll-has-done-its-thing/202/2 "2017-02-25T03:48:00Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![ashmaroli](https://avatars.discourse-cdn.com/v4/letter/a/df705f/32.png) [@ashmaroli](https://talk.jekyllrb.com/u/ashmaroli)\
**Post date:** [February 25, 2017, 3:02pm UTC](https://talk.jekyllrb.com/t/best-way-to-write-a-plugin-that-executes-after-jekyll-has-done-its-thing/202/3 "2017-02-25T15:02:07Z")

</div>

try passing argument(s) to the block

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

```

or

```auto
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.

---

<div class="post-metadata">

**Author:** ![ryanhayden](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/ryanhayden/32/88_2.png) [@ryanhayden](https://talk.jekyllrb.com/u/ryanhayden)\
**Post date:** [February 25, 2017, 3:21pm UTC](https://talk.jekyllrb.com/t/best-way-to-write-a-plugin-that-executes-after-jekyll-has-done-its-thing/202/4 "2017-02-25T15:21:02Z")

</div>

Thanks, @ashmaroli, I’ll try that.

---

<div class="post-metadata">

**Author:** ![george-gca](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/george-gca/32/5301_2.png) [@george-gca](https://talk.jekyllrb.com/u/george-gca)\
**Post date:** [March 6, 2024, 3:39pm UTC](https://talk.jekyllrb.com/t/best-way-to-write-a-plugin-that-executes-after-jekyll-has-done-its-thing/202/5 "2024-03-06T15:39:58Z")

</div>

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:

```css
---
---
@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?
