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:
- replace
<
and>
with the equivalent html codes<
and>
, which looks like<% unsubscribe %>
,
or
- 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
Rails: Copying Attributes from an Object to Another Using the "Attributes" Method
Options for Distribution of an Offline Ruby on Rails Application
Coding Style Checker or Code Formatter for Ruby/Rails
Edit Each Line in a File in Ruby
Write CSV in Ruby 1.9 and CSV::Writer
Sprockets::Circulardependencyerror in Store#Index
Attr_Accessor Strongly Typed Ruby on Rails
Rails 3:How to Generate Models for Existing Database Tables
How to Use Watir::Waiter::Wait_Until to Force Chrome to Wait
How to Cache a Calculated Column in Rails
How to Validate Members of an Array Field
Active Admin - Refresh Second Drop Down Based on First Drop Down, Ruby on Rails
Jekyll - Generating JSON Files Alongside the HTML Files