class ThousandIsland::Template
The Template
class is where you can define elements that may be common to all (or some) documents within your application. It is likely that a common style will be required, so defining it in a Template
and then using that Template
subclass in any custom Builders DRYs up your pdf generation, as well as allowing for easy restyling across the whole application.
Typically, the Template
subclass would define the settings for the PrawnDocument, as well as the settings for the header and footer. See the Docs below for the settings
method for the defaults. Add your own or override any existing settings in the settings
method. Any options passed into the constructor as a Hash will be merged with these settings, and the defaults.
Content for the header and footer will be defined in the methods header_content
and footer_content
. These methods are passed as a block when the pdf is rendered. Any standard Prawn methods may be used (including bounding boxes or any other layout tools). In addition, any of the styles from the StyleSheet
can be applied as helper methods. For instance, the default style sheet has a h1_style
method that returns a ThousandIsland::StyleHash
, so in your code you can use:
h1 "My Document Header"
and Prawn will render the text in the style set in the h1_style
ThousandIsland::StyleHash
.
In addition to the supplied style methods, you can create a custom method:
def magic_style ThousandIsland::StyleHash.new({ size: 15 style: bold }) end
As long as the method ends in the word “_style” and returns a Hash, you magically get to do this:
magic "My magic text is bold and size 15!!"
The method may return a standard Hash, but it is safer to return a ThousandIsland::StyleHash
, as this dynamically duplicates a few keys to accommodate using the style in normal Prawn text methods as well as formatted text boxes, which use a slightly different convention. You don't have to worry about that if you use the ThousandIsland::StyleHash
.
Alternatively, your method could do this:
def magic_style h1_style.merge({ size: 15 style: bold }) end
The following is an example of a custom template that subclasses ThousandIsland::Template
-
class MyTemplate < ThousandIsland::Template include MyCustomStyleSheet # optional # settings here are merged with and override the defaults def settings { header: { height: 55, render:true, repeated: true }, footer: { render:true, height: 9, numbering_string: 'Page <page> of <total>', repeated: true } } end def header_content pdf.image "#{pdf_images_path}/company_logo.png", height: 30 # Standard Prawn syntax end def footer_content footer "www.mycompanyurl.com" # Using the magic method we get from the footer_style end def pdf_images_path "#{Rails.root}/app/assets/pdf_images" # This is entirely up to you end end
Nb. The Footer is a three column layout, with the numbering on the right column and the content defined here in the middle. More flexibility will be added in a later version.
Optional:
Add a body_content
method to add content before whatever the Builder
defines in it's method of the same name.
Attributes
Public Class Methods
# File lib/thousand_island/template.rb, line 100 def initialize(options={}) setup_available_styles setup_document_options(options) setup_prawn_document calculate_bounds end
Public Instance Methods
# File lib/thousand_island/template.rb, line 159 def available_styles @available_styles ||= [] end
# File lib/thousand_island/template.rb, line 138 def draw_body(&block) body_obj.draw do body_content if respond_to? :body_content yield if block_given? end end
# File lib/thousand_island/template.rb, line 145 def draw_header header_obj.draw do header_content if respond_to? :header_content yield if block_given? end if render_header? end
Override in inheriting class to override defaults. The default settings are:
page_size: 'A4', page_layout: :portrait, left_margin: 54, right_margin: 54, header: { render: true, height: 33, bottom_padding: 20, repeated: true }, footer: { render: true, height: 33, top_padding: 20, repeated: true, number_pages: true, numbering_string: '<page>', numbering_options: { align: :right, start_count_at: 1, }
The settings in the hash will be merged with the default settings. Any Prawn setting should be valid at the top level of the hash. The styles used in the Header and Footer are determined by the default styles in the StyleSheet
, but can be overridden in your Template
class or by building your own StyleSheet
# File lib/thousand_island/template.rb, line 134 def settings {} end
Private Instance Methods
# File lib/thousand_island/template.rb, line 184 def body_height @body_height ||= body_start - footer_space end
# File lib/thousand_island/template.rb, line 234 def body_klass Components::Body end
# File lib/thousand_island/template.rb, line 238 def body_obj @body ||= body_klass.new(pdf, pdf_options[:body]) end
# File lib/thousand_island/template.rb, line 180 def body_start @body_start ||= pdf.bounds.height - header_space end
# File lib/thousand_island/template.rb, line 175 def calculate_bounds pdf_options[:body][:top] = body_start pdf_options[:body][:height] = body_height end
# File lib/thousand_island/template.rb, line 208 def component_defaults components = { footer: footer_klass.defaults, header: header_klass.defaults, body: body_klass.defaults, } components[:footer][:style] = footer_style components end
# File lib/thousand_island/template.rb, line 242 def deep_merger @deep_merger ||= Utilities::DeepMerge::TemplateOptions end
# File lib/thousand_island/template.rb, line 252 def defaults { page_size: 'A4', page_layout: :portrait, left_margin: 54, right_margin: 54, header: { render: true, }, footer: { render: true, }, body: {}, } end
# File lib/thousand_island/template.rb, line 218 def header_klass Components::Header end
# File lib/thousand_island/template.rb, line 222 def header_obj @header ||= header_klass.new(pdf, pdf_options[:header]) end
# File lib/thousand_island/template.rb, line 188 def header_space return 0 unless pdf_options[:header][:render] pdf_options[:header][:height] + pdf_options[:header][:bottom_padding] end
Respond to methods that relate to the style_sheet known styles
# File lib/thousand_island/template.rb, line 269 def method_missing(method_name, *arguments, &block) style_method = "#{method_name}_style" if respond_to?(style_method) render_with_style(method_name, arguments[0]) else super end end
# File lib/thousand_island/template.rb, line 165 def render_header? pdf_options[:header][:render] end
Called by method missing when a style is supplied with text, ie: h1 'Header'
# File lib/thousand_island/template.rb, line 247 def render_with_style(style, output) style_values = send("#{style}_style") pdf.text output, style_values end
# File lib/thousand_island/template.rb, line 278 def respond_to_missing?(method_name, *) available_styles.include?(method_name) || super end
# File lib/thousand_island/template.rb, line 282 def setup_available_styles self.class.instance_methods.grep(/_style$/).each do |method_name| style = method_name.to_s.sub('_style', '') available_styles << style.to_sym unless style == 'default' end available_styles.flatten! end
# File lib/thousand_island/template.rb, line 203 def setup_document_options(options={}) @pdf_options = deep_merger.merge_options(options, settings, defaults, component_defaults) end
# File lib/thousand_island/template.rb, line 199 def setup_prawn_document @pdf = Prawn::Document.new(pdf_options) end