Created
October 18, 2011 18:48
-
-
Save henrik/1296300 to your computer and use it in GitHub Desktop.
Draft of view+template+helper PDFs with Prawn, including simple spec and manual verification specs triggered by Guard.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "prawn/measurement_extensions" | |
class BaseDocument | |
delegate :render, :render_file, | |
to: :renderer | |
def initialize(data) | |
@data = data | |
end | |
private | |
def renderer | |
@renderer ||= PrawnTemplateRenderer.new(template, @data, self.class.helper_procs) | |
end | |
def template | |
self.class.name.underscore | |
end | |
# Any time we do "helpers do; stuff; end" in this class or subclasses, | |
# store that proc to be evaluated in the template context. | |
class_attribute :helper_procs | |
self.helper_procs ||= [] | |
def self.helpers(&block) | |
self.helper_procs << block | |
end | |
end | |
class BaseDocument::PrawnTemplateRenderer | |
delegate :render, :render_file, | |
to: :doc | |
module PageSizes | |
A4 = "A4" | |
MY_SPECIAL_PAGE_SIZE = [ 123.mm, 456.mm ] | |
end | |
def initialize(template, data={}, helper_procs=[]) | |
@template = template | |
@data = data | |
@helper_procs = helper_procs | |
# Evaluate the template within this instance, i.e. so that | |
# it calls our `meta` and `content` methods. | |
instance_eval(read_template, template_path) | |
end | |
def meta | |
extend PageSizes | |
@prawn_document_options = yield | |
end | |
def content(&block) | |
# Define any helpers on the Prawn document by evaluating them | |
# in its instance. | |
@helper_procs.each do |proc| | |
doc.instance_eval(&proc) | |
end | |
# Evaluate the contents of the data block in the Prawn document | |
# instance, yielding the data hash to that block. | |
doc.instance_exec(data_object, &block) | |
end | |
private | |
def doc | |
@doc ||= Prawn::Document.new(@prawn_document_options || {}) | |
end | |
def data_object | |
OpenStruct.new(@data) | |
end | |
def read_template | |
File.read(File.join(app_root, template_path)) | |
end | |
def template_path | |
"app/views/documents/#{@template}.pdf.rb" | |
end | |
def app_root | |
Rails.root | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MyDocument < BaseDocument | |
def initialize(user) | |
super( | |
name: user.name, | |
copies: 1 | |
) | |
end | |
helpers do | |
def copies(count) | |
count.times do |i| | |
yield | |
start_new_page unless i == count-1 | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
meta do | |
{ | |
page_size: MY_SPECIAL_PAGE_SIZE, | |
margin: 12.mm | |
} | |
end | |
content do |data| | |
copies(data.copies) do | |
text "Hello #{data.name}!" | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
source 'http://rubygems.org' | |
# … | |
gem 'prawn' | |
group :test do | |
gem 'pdf-inspector', :require => "pdf/inspector" | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# … | |
watch('app/documents/base_document.rb') { |m| "spec/documents" } | |
watch(%r{app/views/documents/(.+)\.pdf\.rb}) { |m| "spec/documents/#{m[1]}_spec.rb" } | |
# … |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# encoding: utf-8 | |
require "spec_helper" | |
describe MyDocument do | |
let(:document) { MyDocument.new(user) } | |
let(:pdf) { document.render } | |
let(:text) { PDF::Inspector::Text.analyze(pdf).strings.join(" ") } | |
context "with name" do | |
let(:user) { User.new(name: "Svelle") } | |
it "generates" do | |
text.should include("Hello Svelle!") | |
end | |
# To trigger these during dev: | |
# VIEW_PDF=true guard | |
it "previews", :manual_verification do | |
preview :name | |
end | |
end | |
context "with long name" do | |
let(:user) { User.new(name: "Svelle Forever") } | |
it "previews", :manual_verification do | |
preview :long_name | |
end | |
end | |
def preview(name) | |
file_name = "/tmp/my_document_#{name}.pdf" | |
document.render_file(file_name) | |
system("open", file_name) # OS X | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
RSpec.configure do |config| | |
config.treat_symbols_as_metadata_keys_with_true_values = true | |
# These are only for manual verification in dev and should never trigger from CI, specjour, rake spec etc. | |
# Do: VIEW_PDF=true guard | |
if ENV['VIEW_PDF'] | |
puts "PDFs may open at any time!!1" | |
else | |
config.filter_run_excluding :manual_verification | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment