1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
require 'erb' # GOAL: render the template with the following vars vars = { :first => 'Mislav', 'last' => 'Marohnic' } template = 'Name: <%= first %> <%= last %>' # create anonymous module which binding we will use m = Module.new do # I want the singleton class, thank you class << self public :binding def meta class << self; self; end end end class << meta public :define_method end # define singleton method for each var vars.each do |name, value| meta.define_method(name) { value } end end puts ERB.new(template).result(m.binding) #=> "Name: Mislav Marohnic"
Refactorings
No refactoring yet !
lifo
April 12, 2008, April 12, 2008 15:38, permalink
Dont make me do these things again :-(
1 2 3 4 5 6
require 'erb' require 'ostruct' vars = OpenStruct.new :first => 'Mislav', 'last' => 'Marohnic' template = 'Name: <%= first %> <%= last %>' puts ERB.new(template).result(vars.send(:binding))
Nathan Weizenbaum
April 12, 2008, April 12, 2008 17:08, permalink
1 2 3 4 5 6
require 'rubygems' require 'erubis' vars = { :first => 'Mislav', 'last' => 'Marohnic' } template = 'Name: <%= first %> <%= last %>' Erubis::Eruby.new(template).result(vars)
Sam Stephenson
April 12, 2008, April 12, 2008 17:34, permalink
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
require "erb" class Hash def to_binding(object = Object.new) object.instance_eval("def binding_for(#{keys.join(",")}) binding end") object.binding_for(*values) end end class Document def initialize(template) @template = ERB.new(template) end def interpolate(replacements = {}) @template.result(replacements.to_binding) end end puts Document.new("Name: <%= first %> <%= last %>").interpolate(:first => "Mislav", "last" => "Marohnic") # Name: Mislav Marohnic
This works. Now, is there a simpler way than my solution?