Class: Tap::Templater

Inherits:
OpenStruct
  • Object
show all
Includes:
Utils
Defined in:
lib/tap/templater.rb

Overview

Templater is a convenience class for creating ERB templates. As a subclass of OpenStruct, attributes can be assigned/unassigned directly. When the template is built, all the method of Templater (and hence all the assigned attributes) are available.

t = Templater.new( "key: <%= value %>")
t.value = "default"
t.build                 # => "key: default"

t.value = "another"
t.build                 # => "key: another"

Templater includes the Templater::Utils utility methods.

ERB Redirection

Templater hooks into the ERB templating mechanism by providing itself as the ERB output target (_erbout). ERB concatenates each line of an ERB template to _erbout, as can be seen here:

e = ERB.new("<%= 1 + 2 %>")
e.src                   # => "_erbout = ''; _erbout.concat(( 1 + 2 ).to_s); _erbout"

By setting itself as _erbout, instances of Templater can redirect output to a temporary target and perform string transformations.

For example, redirection allows indentation of nested content:

template = %Q{
# Un-nested content
<% redirect do |target| %>
# Nested content
<% module_nest("Nesting::Module") { target } %>
<% end %>
}

t = Templater.new(template)
t.build
# => %Q{
# # Un-nested content
# module Nesting
#   module Module
#     # Nested content
#     
#   end
# end}

Defined Under Namespace

Modules: Utils

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Utils

#comment, #indent, #module_nest, #nest, #yamlize

Constructor Details

#initialize(template, attributes = {}) ⇒ Templater

Initialized a new Templater. An ERB or String may be provided as the template. If a String is provided, it will be used to initialize an ERB with a trim_mode of “<>”.



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/tap/templater.rb', line 145

def initialize(template, attributes={})
  @template = case template
  when ERB
    # matching w/wo the coding effectively checks @src
    # across ruby versions (encoding appears in 1.9)
    if template.instance_variable_get(:@src) !~ /^(#coding:US-ASCII\n)?_erbout =/
      raise ArgumentError, "Templater does not work with ERB templates where eoutvar != '_erbout'"
    end
    template
  when String then ERB.new(template, nil, "<>")
  else raise ArgumentError, "cannot convert #{template.class} into an ERB template"
  end
  
  src = @template.instance_variable_get(:@src)
  @template.instance_variable_set(:@src, "self." + src) 

  super(attributes)
end

Class Method Details

.build(template, attributes = {}, filename = nil) ⇒ Object

Builds the erb template with the specified attributes.



130
131
132
# File 'lib/tap/templater.rb', line 130

def build(template,  attributes={}, filename=nil)
  new(template).build(attributes, filename)
end

.build_file(path, attributes = {}) ⇒ Object

Builds the erb template file with the specified attributes.



135
136
137
# File 'lib/tap/templater.rb', line 135

def build_file(path, attributes={})
  self.build(File.read(path), attributes, path)
end

Instance Method Details

#_erboutObject

Returns self (not the underlying erbout storage that actually receives the output lines). In the ERB context, this method directs erb outputs to Templater#concat and into the redirect mechanism.



167
168
169
# File 'lib/tap/templater.rb', line 167

def _erbout
  self
end

#_erbout=(input) ⇒ Object

Sets the underlying erbout storage to input.



172
173
174
# File 'lib/tap/templater.rb', line 172

def _erbout=(input)
  @_erbout = input
end

#build(attrs = nil, filename = nil) ⇒ Object

Build the template, setting the attributes and filename if specified. All methods of self will be accessible in the template.



204
205
206
207
208
209
210
211
212
# File 'lib/tap/templater.rb', line 204

def build(attrs=nil, filename=nil)
  attrs.each_pair do |key, value|
    send("#{key}=", value)
  end if attrs
  
  @template.filename = filename
  @template.result(binding)
  @_erbout
end

#concat(input) ⇒ Object

Concatenates the specified input to the underlying erbout storage.



198
199
200
# File 'lib/tap/templater.rb', line 198

def concat(input)
  @_erbout << input
end

#force_encoding(encoding) ⇒ Object

– TODO check if this is still needed…



179
180
181
182
# File 'lib/tap/templater.rb', line 179

def force_encoding(encoding)
  @_erbout.force_encoding(encoding)
  @_erbout
end

#redirectObject

Redirects output of erb to the redirected_erbout string for the duration of the block. When redirect completes, the redirected_erbout is concatenated to the main erbout storage.



189
190
191
192
193
194
195
# File 'lib/tap/templater.rb', line 189

def redirect # :yields: redirected_erbout
  current = @_erbout
  @_erbout = ""
  result = yield(@_erbout)
  @_erbout = current
  concat(result)
end