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

pdf[R]
pdf_options[R]

Public Class Methods

new(options={}) click to toggle source
# 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

available_styles() click to toggle source
# File lib/thousand_island/template.rb, line 159
def available_styles
  @available_styles ||= []
end
draw_body() { || ... } click to toggle source
# 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
draw_header() { || ... } click to toggle source
# 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
settings() click to toggle source

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

body_height() click to toggle source
# File lib/thousand_island/template.rb, line 184
def body_height
  @body_height ||= body_start - footer_space
end
body_klass() click to toggle source
# File lib/thousand_island/template.rb, line 234
def body_klass
  Components::Body
end
body_obj() click to toggle source
# File lib/thousand_island/template.rb, line 238
def body_obj
  @body ||= body_klass.new(pdf, pdf_options[:body])
end
body_start() click to toggle source
# File lib/thousand_island/template.rb, line 180
def body_start
  @body_start ||= pdf.bounds.height - header_space
end
calculate_bounds() click to toggle source
# File lib/thousand_island/template.rb, line 175
def calculate_bounds
  pdf_options[:body][:top] = body_start
  pdf_options[:body][:height] = body_height
end
component_defaults() click to toggle source
# 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
deep_merger() click to toggle source
# File lib/thousand_island/template.rb, line 242
def deep_merger
  @deep_merger ||= Utilities::DeepMerge::TemplateOptions
end
defaults() click to toggle source
# 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
header_klass() click to toggle source
# File lib/thousand_island/template.rb, line 218
def header_klass
  Components::Header
end
header_obj() click to toggle source
# File lib/thousand_island/template.rb, line 222
def header_obj
  @header ||= header_klass.new(pdf, pdf_options[:header])
end
header_space() click to toggle source
# 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
method_missing(method_name, *arguments, &block) click to toggle source

Respond to methods that relate to the style_sheet known styles

Calls superclass method
# 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
render_header?() click to toggle source
# File lib/thousand_island/template.rb, line 165
def render_header?
  pdf_options[:header][:render]
end
render_with_style(style, output) click to toggle source

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
respond_to_missing?(method_name, *) click to toggle source
Calls superclass method
# File lib/thousand_island/template.rb, line 278
def respond_to_missing?(method_name, *)
  available_styles.include?(method_name) || super
end
setup_available_styles() click to toggle source
# 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
setup_document_options(options={}) click to toggle source
# 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
setup_prawn_document() click to toggle source
# File lib/thousand_island/template.rb, line 199
def setup_prawn_document
  @pdf = Prawn::Document.new(pdf_options)
end