Fill tilt template using hash - ruby

I got following ruby example:
require 'tilt'
data = { "site_link" => "http://www.example.com", "title" => "example"}
template = Tilt.new('../templates/test.erb', :default_encoding => 'UTF-8')
output = template.render(data)
puts output
and this is test.erb file:
This should be a link - <%= site_link %>
I can't find a proper syntax to get a value from data hash into template.

Ok,
it looks like I need to specify to tilt that data are a hash. Correct code is:
output = template.render(Hash,data)

Related

How do you create pretty json in CHEF (ruby)

How would you make an erb template that has human readable json?
The following code works, but it makes a flat json file
default.rb
default['foo']['bar'] = { :herp => 'true', :derp => 42 }
recipe.rb
template "foo.json" do
source 'foo.json.erb'
variables :settings => node['foo']['bar'].to_json
action :create
end
foo.json.erb
<%= #settings %>
Similar SO questions
Chef and ruby templates - how to loop though key value pairs?
How can I "pretty" format my JSON output in Ruby on Rails?
As pointed out by this SO Answer .erb templates are great for HTML, and XML, but is not good for json.
Luckily, CHEF uses its own json library which has support for this using .to_json_pretty
#coderanger in IRC, pointed out that you can use this library right inside the recipe. This article shows more extensively how to use chef helpers in recipes.
default.rb
# if ['foo']['bar'] is null, to_json_pretty() will error
default['foo']['bar'] = {}
recipe/foo.rb
pretty_settings = Chef::JSONCompat.to_json_pretty(node['foo']['bar'])
template "foo.json" do
source 'foo.json.erb'
variables :settings => pretty_settings
action :create
end
Or more concise as pointed out by YMMV
default.rb
# if ['foo']['bar'] is null, to_json_pretty() will error
default['foo']['bar'] = {}
recipe/foo.rb
template "foo.json" do
source 'foo.json.erb'
variables :settings => node['foo']['bar']
action :create
end
templates/foo.json.erb
<%= Chef::JSONCompat.to_json_pretty(#settings) %>
Something like this would also work:
file "/var/my-file.json" do
content Chef::JSONCompat.to_json_pretty(node['foo']['bar'].to_hash)
end
<%= Chef::JSONCompat.to_json_pretty(#settings) %> Works like Charm !!

How to get list of variable names from an erubis file?

From within a Ruby script, is there a way to pragmatically obtain a list of all expected variable names and function names found in an erubis file?
For instance, how would one determine from the Eruby object that the contains the variable 'name'?
require 'erubis'
source = 'Hello, <%= name %>'
erb = Erubis::Eruby.new(source)
My hackish solution:
# from the original question
require 'erubis'
source = 'Hello, <%= name %>'
erb = Erubis::Eruby.new(source)
# a not so great solution
vars = {}
begin
Erubis::Eruby.new(code).result(vars)
rescue NameError => e
puts "Found: '#{e.name}'"
vars[e.name.to_sym] = nil
retry
end
Which results in:
Found: 'name'

Formatting a cell as Text using the axlsx spreadsheet ruby gem?

I'm using the axlsx ruby gem to create Excel-compatible .xlsx files. I can't figure out how to override the cell type that is generated by it's automatic type detection. For Active Record model attributes of type string the gem is setting the Excel cell format to General, but I want it to use Text explicitly. That way I can avoid stripping leading zeros off of zip codes, etc.
Anybody know how to accomplish this?
You can override the type of data using the types option on add row.
Something like:
worksheet.add_row ['0012342'], :types => [:string]
Grab me on irc (JST) if you need any help getting that to work.
Best
randym
edit --
I've added an example for this to examples/example.rb in the repo.
wb.add_worksheet(:name => "Override Data Type") do |sheet|
sheet.add_row ['dont eat my zeros!', '0088'] , :types => [nil, :string]
end
https://github.com/randym/axlsx/blob/master/examples/example.rb#L349
format_code: '#' will work for you. Please find below code for reference.
def default_data_type_as_string
#xlsx_package = Axlsx::Package.new
#workbook = #xlsx_package.workbook
#worksheet = #workbook.add_worksheet(:name => "Introduction")
default_style = #workbook.styles.add_style({ format_code: '#' })
row_data_array = ['1', '2%', '3$']
#worksheet.add_row row_data_array, :style => [nil, default_style, nil]
#xlsx_package.serialize('default_data_type_as_string.xlsx')
end
For gem versions gem 'axlsx', '2.1.0.pre', gem 'axlsx_rails' in order to have the file columns in text type should specify both style and type
default_style = worksheet.styles.add_style({ format_code: '#' })
worksheet.add_row ['0012687'], :types => [:string], :style => [default_style]

How to get values in XML data using Nokogiri?

I'm using Nokogiri to parse XML data that I'm getting from the roar engine after I create a user. The XML looks like below:
<roar tick="135098427907">
<facebook>
<create_oauth status="ok">
<auth_token>14802206136746256007</auth_token>
<player_id>8957881063899628798</player_id>
</create_oauth>
</facebook>
</roar>
I'm totally new to Nokogiri. How do I get the value of status, the auth_token and player_id?
str = "<roar ......"
doc = Nokogiri.XML(str)
puts doc.xpath('//create_oauth/#status') # => ok
puts doc.xpath('//auth_token').text # => 148....
# player_id is the same as auth_token
And it is a great idea to learn you some good xpath from w3schools.
How about this
h1 = Nokogiri::XML.parse %{
<roar tick="135098427907">
<facebook>
<create_oauth status="ok">
<auth_token>14802206136746256007</auth_token>
<player_id>8957881063899628798</player_id>
</create_oauth>
</facebook>
</roar>
}
h1.xpath("//facebook/create_oauth/auth_token").text()
h1.xpath("//facebook/create_oauth/player_id").text()
You can use Nori gem. Its a xml to hash converter and in ruby its so much convenient to access hashes
require 'nori'
Nori.parser = :nokogiri
xml = "<roar tick='135098427907'>
<facebook>
<create_oauth status='ok'>
<auth_token>14802206136746256007</auth_token>
<player_id>8957881063899628798</player_id>
</create_oauth>
</facebook>
</roar>"
hash = Nori.parse(xml)
create_oauth = hash["roar"]["facebook"]["create_oauth"]
puts create_oauth["auth_token"] # 14802206136746256007
puts create_oauth["#status"] # ok
puts create_oauth["player_id"] # 8957881063899628798

Looping through XML to create an array of hashes in Ruby

I have the following XML
<CallResult>
<Success>true</Success>
<Result>
<ZoneInfo>
<Id>3</Id>
<Name>test-room</Name>
<NId>sdfsdg</NId>
</ZoneInfo>
<ZoneInfo>
<Id>16</Id>
<Name>Dynamic</Name>
<NId>sadadrwed543th</NId>
</ZoneInfo>
<ZoneInfo>
<Id>32</Id>
<Name>lobby</Name>
<NId>ssdfrgfdfg</NId>
</ZoneInfo>
<ZoneInfo>
<Id>33</Id>
<Name>conf</Name>
<NId>sdfsfewr232f</NId>
</ZoneInfo>
</Result>
<Message>Success</Message>
</CallResult>
I am trying to parse the XML so that each different 'ZoneInfo' attributes is a hash in an array.
E.g.
Zones[0] = Hash[Id => 32, Name => lobby, NId => ssdfrgfdfg]
Zones[1] = Hash[Id => 33, Name => conf, NId => sdfsfewr232f]
etc...
My limited XML parsing knowledge has come a croper. All I really know is how to extract a single element. E.g.
doc = REXML::Document.new(xmlData)
doc.elements.each("CallResult/Success") do |ele|
p ele.text;
end
Could someone help with some more info on how to loop through just extracting info from each 'ZoneInfo' element?
Thanks
I use another gem 'nokogiri', maybe the best gem to parse HTML/XML now.
require 'nokogiri'
str = "<CallResult> ......"
doc = Nokogiri.XML(str)
Zones = []
doc.xpath('//ZoneInfo').each do |zone|
Zones << { "Id" => zone.xpath('Id').text, "Name" => zone.xpath('Name').text, "NId" => zone.xpath("NId").text}
end
You just need to use nori gem
require 'nori'
your_hash = Nori.parse(your_xml)
And then it should be straightforward to convert this nested hash to an array of hashes if you need to store your data that way.
If you need more info, api doc is here - http://rubydoc.info/gems/nori/1.1.3/frames

Resources