Render an Erb Template with Values from a Hash

Render an ERB template with values from a hash

I don't know if this qualifies as "more elegant" or not:

require 'erb'
require 'ostruct'

class ErbalT < OpenStruct
def render(template)
ERB.new(template).result(binding)
end
end

et = ErbalT.new({ :first => 'Mislav', 'last' => 'Marohnic' })
puts et.render('Name: <%= first %> <%= last %>')

Or from a class method:

class ErbalT < OpenStruct
def self.render_from_hash(t, h)
ErbalT.new(h).render(t)
end

def render(template)
ERB.new(template).result(binding)
end
end

template = 'Name: <%= first %> <%= last %>'
vars = { :first => 'Mislav', 'last' => 'Marohnic' }
puts ErbalT::render_from_hash(template, vars)

(ErbalT has Erb, T for template, and sounds like "herbal tea". Naming things is hard.)

Ruby accessing nested hash and erb template

If services_hash had this format:

services_hash = {
"max_logger_services" => [
"max-logger",
"max-analytics", {
"max-analytics" => 83,
"max-logger" => 82
}
]
}

Then you could access max-analytics and to max-logger just with:

hash = services_hash['max_logger_services'][2]
p hash['max-analytics']
# => 83
p hash['max-logger']
# => 82

If you don't know if the data will be always formatted the same way, at least you can "dig" until the deeper hash values:

hash = services_hash['max_logger_services'].inject{|_k,v| v}
# => {"max-analytics"=>83, "max-logger"=>82}

Rendering a hash inside a JSON file with Ruby and ERB ('= ' notation)

Are you looking for something like :

require 'erb'
require 'json'

h = Hash.new
h["first"] = "First"
h["second"] = "Second"

template = ERB.new <<-EOF
{
"key": "value",
"foo": 1,
"Hash": <%= h.to_json %>,
"bar": 2
}
EOF

puts template.result(binding)

output

[arup@Ruby]$ ruby a.rb
{
"key": "value",
"foo": 1,
"Hash": {"first":"First","second":"Second"},
"bar": 2
}
[arup@Ruby]$

How to pass binding with ERB.result_with_hash

In your case, if you need to use both the args and binding, you need to populate keys/values of your args into the binding object.

# To avoid polluting your current binding, copy to a new one
b_clone = binding.clone
args.each { |k, v| b_clone.local_variable_set(k,v) }
ERB.new(template).result(b_clone)

So you can use both methods in your binding and keys/values in args as variables

ERB template nested variable - accessing a hash key based on array element

I realized lately they won't work if they don't match in name (array value, hash key):

{"max-api" => 83, "max-logger" => 82, "max-data" => 84}

They differ in - and/or _ from @services:

%w( max_api max_data max_logger )

Just tweaked a bit @services:

ports = {'max-api' => 83, 'max-logger' => 82, 'max-data' => 84}
services = %w(max-api max-data max-logger)

services.each do |service|
puts "shell: echo #{service}:#{ports[service]}#{'00' if service != 'max-logger'}"
end
# => shell: echo max-api:8300
# => shell: echo max-data:8400
# => shell: echo max-logger:82

ERB render expression as string

Short answer is no. You either:

  1. replace < and > with the equivalent html codes < and >, which looks like <% unsubscribe %>,

or


  1. make your ruby statement print the string: <%= '<% subscribe %>' %>

Ruby templating: is it possible that only pass some values to variables in template?

You can use double opening %%s to prevent it from being evaluated in erb.

This solution might look ugly but it returns exactly what you want (if it is what you want):

require 'erb'

template = ERB.new <<-EOF
The value of x is: <% if defined?(x) %><%= x %><% else %><%%= x %><% end %>
The value of y is: <% if defined?(y) %><%= y %><% else %><%%= y %><% end %>
EOF
=> #<ERB:0x00007feeec80c428 @safe_level=nil, @src="#coding:UTF-8\n_erbout = +''; _erbout.<<(-\" The value of x is: \"); if defined?(x) ; _erbout.<<(( x ).to_s); else ; _erbout.<<(-\"<%= x %>\"); end ; _erbout.<<(-\"\\n The value of y is: \"\n); if defined?(y) ; _erbout.<<(( y ).to_s); else ; _erbout.<<(-\"<%= y %>\"); end ; _erbout.<<(-\"\\n\"\n); _erbout", @encoding=#<Encoding:UTF-8>, @frozen_string=nil, @filename=nil, @lineno=0>

puts template.result(binding)
The value of x is: <%= x %>
The value of y is: <%= y %>
=> nil

x = 20

puts template.result(binding)
The value of x is: 20
The value of y is: <%= y %>
=> nil

y= 50

puts template.result(binding)
The value of x is: 20
The value of y is: 50
=> nil

I assume you can do the formatting.

How to dump different hash objects into a erb template

Just remove that from the dump output of YAML:

<%= YAML.dump(compilation).sub(/.*?\n/, '') %>


Related Topics



Leave a reply



Submit