mj4eeg
Last Updated: March 07, 2016
·
732
· rafaelcgo

Offline Template Renderer for Rails Rake Tasks or Background Worker

Trying to render a .pdf offline, in a rake task, without success? Host nil? Request nil?

Try using this trick...

offline_template.rb

class OfflineTemplate < AbstractController::Base
  include AbstractController::Logger
  include AbstractController::Rendering
  include AbstractController::Layouts
  include AbstractController::Helpers
  include AbstractController::Translation
  include AbstractController::AssetPaths
  include ActionDispatch::Routing::UrlFor
  include Rails.application.routes.url_helpers
  Rails.application.routes.default_url_options = { :host => 'www.yoursite.com' }

  helper ApplicationHelper

  helper_method :protect_against_forgery?

  # configure the different paths correctly
  def initialize(*args)
    super()
    lookup_context.view_paths = Rails.root.join('app', 'views')
    config.javascripts_dir = Rails.root.join('public', 'javascripts')
    config.stylesheets_dir = Rails.root.join('public', 'stylesheets')
    config.assets_dir = Rails.root.join('public')
  end

  # we are not in a browser, no need for this
  def protect_against_forgery?
    false
  end

  # so that your flash calls still work
  def flash
    {}
  end

  def params
    {}
  end

  # same asset host as the controllers
  self.asset_host = ActionController::Base.asset_host
end

Usage

template = OfflineTemplate.new
pdf_page = template.render_to_string partial: 'partial', layout: "pdf", formats: :html, locals: {:@user => user}

kit = PDFKit.new(pdf_page)
kit.stylesheets << "#{Rails.root}/app/assets/stylesheets/pdf/pdf.css"

pdf = open(kit.to_file(temp_dir + user.id.to_s + '_tmp.pdf'))