I am trying to create a chef recipe for my Amazon OpsWorks stack. I'd like to pass custom JSON data into the stack, and have the recipe create an .ini file for use with PHP's parse_ini_file() command.
What I Have Working
Currently, I can create a flat .ini file with the following:
JSON:
{
"settings_ini": {
"quantity": 1,
"width": 10,
"height": 20
}
}
The resulting settings.ini file is:
quantity = 1
width = 10
height = 20
Chef recipe:
template "/my/path/here/settings.ini" do
owner "www_data"
group "www_data"
mode "0644"
source "settings.ini.erb"
variables({
:settings_ini => node[:settings_ini]
})
end
Chef template "settings.ini.erb":
<% #settings_ini.each do |name, value| -%>
<%= name %> = <%= value %>
<% end -%>
What I'm Trying to Make Work
I'd like to change my JSON data to be this:
{
"settings_ini": {
"quantity": 1,
"attributes": {
"width": 10,
"height": 20
}
}
}
And I want my resulting settings.ini file to be this:
quantity = 1
[attributes]
width = 10
height = 20
Or, it could also be this:
quantity = 1
[attributes]width = 10
[attributes]height = 20
I need help modifying my settings.ini.erb template file to use the nested JSON data correctly.
You could use a recursive function.
Stick this into libraries/hash_to_ini.rb:
def hash_to_ini(hash, lines = [])
hash.each do |name, value|
unless value.is_a? Hash
lines << "#{name} = #{value}"
else
lines << "[#{name}]"
lines = hash_to_ini(value, lines)
end
end
return lines
end
Then in your template:
<% hash_to_ini(#settings_ini).each do |line| -%>
<%= line %>
<% end -%>
Why not just a second each loop?
<% #settings_ini.each do |section, data| -%>
[<%= section %>]
<% data.each do |name, value| -%>
<%= name %> = <%= value %>
<% end -%>
<% end -%>
This code is untested.. but I guess it should work.
You could also add some safety like done e.g. here and here
Related
VoilĂ I have a list like this 0, 1000, 2860, 3619, 4789, 5970 in a field of my database. I would like to iterate over it and update the corresponding subtitle with the value of the timecode.
Here is my code. It is all in a view:
<%if params[:envoi]%>
<%#ze_videos.each do |attached| %>
<h1><%= attached.remarque %></h1>
<% #mesattachedtcs = attached.remarque %>
<%end%>
<p>
<% #tchash = "" %>
<% #mesattachedtcs.split(/, ?/).each do |montc| %>
<% #tchash = #tchash + '"' + montc.to_s + '"' + ', ' %>
<%end%>
<%# #tchash = '{' + #tchash + '}' %>
<%= #tchash %>
<% aa = 0 %>
<% #traductions.each do |sync| %>
<% aa += 1 %>
<%= #tchash[aa] %> _
<%
#temps = (#tchash[aa]).to_i
if sync.auteur == current_user.email
sync.update_attributes(:timecode => #temps)
end
%>
<%end%>
</p>
<%end%>
What I do not understand is that <%= #tchash[aa] %> is not a being saved with the corresponding subtitle. But the value goes in the database in a "cryptographic" way.
Like this
I'm not a pro with hashes, it works very fine if I write the hash in the code: myhash = [111, 222, 333, 444] and access the value or the key with myHash1, myHash2..
In this pict you see that I have not a whole variable but each character of the string is dispatched in the column Timecode instead of being in one row.
Could you please help me in this matter? Merci
I'm sorry but I just didn't look at the theory. I had to say Hash.new() before all.
I'm trying to convert erb templates to epp (new company policy) and there isn't a lot of documentation on epp yet.
Here's what i have in erb:
<% filter.select{|x| x != 'filtertype'}.sort.each do |key, element| -%>
<%= key %>: '<%= element %>'
<% end -%>
it works great! however i have to find the equivalent for epp. I can get the "each" part to work, but the select method isn't working for me.
I'm stumped!
I tried something like:
<% $filter.select { |$x| $x != 'filtertype'}.each |$key, $element| { -%>
<%= $key %>: '<%= $element %>'
<% } -%>
this in particular errors on '|' for the $x.
I also tried:
<% $filter.select |$x| {$x != 'filtertype'}.each |$key, $element| { -%>
<%= $key %>: '<%= $element %>'
<% } -%>
but that gives me something like "Error while evaluating a Method call, select(): Wrong number of arguments given 1 for 3"
I've tried moving around the {} and changing them to (), but no luck.
does anyone have any ideas?
Thanks!
As Dominic Cleal mentions in the comment, select() is not a Puppet function, however filter() is and is the equivalent of select in Ruby.
Therefore:
Given a class:
class foo () {
# Some test data.
$filter = {
'filtertype' => 'foo',
'apples' => 1,
'bananas' => 2,
}
# How to declare the ERB template for comparison:
file { '/foo':
ensure => file,
content => template('foo/mytemplate.erb'),
}
# How to declare the EPP template for comparison:
file { '/bar':
ensure => file,
content => epp('foo/mytemplate.epp', {'filter' => $filter}),
}
}
Content of the ERB file exactly as given in the question:
<% #filter.select{|x| x != 'filtertype'}.sort.each do |key, element| -%>
<%= key %>: '<%= element %>'
<% end -%>
Content of an equivalent EPP file:
<% | Hash $filter | -%>
<% include stdlib -%>
<% $filter.keys.sort.filter |$k| {$k != 'filtertype'}.each |$k| { -%>
<%= $k %>: '<%= $filter[$k] %>'
<% } -%>
Things to note:
1) You need include stdlib to access the keys and sort functions.
2) The variable name $filter now clashes with the built-in Puppet function filter(), which is syntactically fine, but confusing, so you would consider renaming the $filter variable to something else for clarity.
Also, if you don't care about sorting the keys, then I could make what you tried work using:
<% | Hash $filter | -%>
<% $filter.filter |$k| {$k[0] != 'filtertype'}.each |$k, $v| { -%>
<%= $k %>: '<%= $v %>'
<% } -%>
See also here where I just answered a similar question.
How do I change the erb file to add first five nodes to director director1 and others to director2
My current erb file.
director director1 round-robin {
<%- if !(node['varnish']['backend_servers']).nil? -%>
<%- node['varnish']['backend_servers'].each do |server| -%>
{ .backend = <%= server[:hostname] %>; }
<%- end %>
<%- end %>
}
I am trying to drill down some searches in my app using time intervals....posts in the last day, last week, last month. I am trying to be DRY and write a search controller method that will handle this for me. I am having probelms passing in the time variable. See the form below. #search_term is the search term and hidden becasue for this form as an example, all the client sees is a link saying "last 24 hours"
<%= form_tag time_searches_path do %>
<%= hidden_field_tag :search_task, #search_term %>
<%= hidden_field_tag :time, "24" %>
<%= hidden_field_tag :Klass, Micropost %>
<%= submit_tag "Last 24 hours", class: 'Criteria'%>
<% end %>
Then I have a helper method that is included in my search controller.....
def get_time_interval time
if time == "24"
#time_variable = 1.day.ago
elsif time == "week"
#time_variable = 1.week.ago
elsif time == "month"
#time_variable = 1.month.ago
end
end
Then I add the time_variable into my controller action
def search
model = params[:Klass]
klass = model.constantize
time = params[:time]
get_time_interval time
#search = Sunspot.search [klass] do
fulltext params[:search_task]
with(:created_at).greater_than(#time_variable)
end
end
Clearly this is wrong. I assuming i need some form of metaprogramming. I am new to rails to don't really know how to proceed.
Error I get is
undefined method `gsub' for nil:nilclass
And it highlights the line with the time variable in the controller
I want to delete a record from a maodel but i got a strange behave:
when i delete a record form a non empty list it works perfectly but when it still just one record in that list and i try to delete it it generates this error:
in paniers_controller.rb:
def enlever
#p = Panier.find(params[:id])
#book = Book.where( id: #p.book_id).first
if #p
#book= Book.update(#p.book_id, nbr_exemplaires: #p.quantity)
#p= Panier.destroy(#p.id)
redirect_to detail_path
end
end
in paniers/detail.html.erb
<tr><td>Reference du livre</td><td>prix du livre</td><td>Quantité</td><td>Services</td></tr>
<% for p in #panier %>
<tr>
<td><%= p.book_id %></td><td><%= p.price%> $</td><td><%= p.quantity %></td><td><%= link_to 'enlever du panier', enlever_path(p), data: { confirm: 'Are you sure?' } %></td></tr>
<% somme +=p.price * p.quantity %>
<%end %>
in routes.rb
get 'panier/enlever/:id' => 'paniers#enlever', as: :enlever
the error that I got is:
Couldn't find Panier with 'id'=23
in this line:
#p = Panier.find(params[:id])
but the record is deleted from the database in spite of the display of this error
Perhaps you want to pluralize #panier in the view (also, check if you are initializing #panier with a list of panier, as opposed to a single panier) - something like:
# in paniers_controller.rb
def detail
#panier = Panier.all
end
# in paniers/detail.html.erb
<% for p in #paniers %>