Reputation:
I have the following Yaml:
role::test::logos::filesanddata:
logo01.jpg:
title01: 'value01'
title02: 'value02'
title03: 'value03'
title04: 'value04'
title05: 'value05'
title06: 'value06'
title07:
- title07_01: value07_01
- title07_02: value07_02
- title07_03: value07_03
- title07_04: value07_03
- title07_05: value07_04
logo02.jpg:
title01: 'value01'
Through my Class (in Puppet code) am getting the following result:
["logo01.jpg", {"title01"=>"value01", "title02"=>"value02", "title03"=>"value03", "title04"=>"value04", "title05"=>"value05", "title06"=>"value06", "title07"=>[{"title07_01"=>"value07_01"}, {"title07_02"=>"value07_02"}, {"title07_03"=>"value07_03"}, {"title07_04"=>"value07_04"}, {"title07_05"=>"value07_05}]}]
["logo02.jpg", {"title01"=>"value01"}]
I am writing a template to split the data in multiple files (so far works). I am stuck on the item "title07", how should I continue the loop from there?
<%= @arraydata[0] %>
<% @arraydata.shift -%>
<% @arraydata.each do |item| -%>
<%= item['title01'] %>
<%= item['title02'] %>
<%= item['title03'] %>
<%= item['title04'] %>
<%= item['title05'] %>
<%= item['title06'] %>
<% item['title07'].each do |inner_item| -%>
<%= inner_item['title07']['title07_01'] %>
<% end -%>
<% end -%>
Upvotes: 0
Views: 3727
Reputation: 799
Its not clear to me what the end goal is however hopefully the below example should help you unblock the issues you have
given the following hiera data:
role::test::logos::filesanddata:
logo01.jpg:
title01: 'value01'
title02: 'value02'
title03: 'value03'
title04: 'value04'
title05: 'value05'
title06: 'value06'
title07:
- title07_01: value07_01
- title07_02: value07_02
- title07_03: value07_03
- title07_04: value07_03
- title07_05: value07_04
logo02.jpg:
title01: 'value01'
The following code assuming filesanddata = lookup('role::test::logos::filesanddata')
<% @filesanddata.each_pair do |file, titles| -%>
<%- titles.each_pair do |title, values| -%>
<%- if values.is_a?(String) -%>
<%= value %>
<%- elsif value.is_a?(Array) -%>
<%# As mentioned by John Bollinger you have an array %>
<%# of hashes so we have to unpack that as well %>
<%- values.each do |value_hash| -%>
<%- value_hash.each_pair do |_, value| -%>
<%= value %>
<%- end -%>
<%- end -%>
<%- end -%>
<%- end -%>
<% end -%>
would create a file with the following content
value01
value02
value03
value04
value05
value06
value07_01
value07_02
value07_03
value07_03
value07_04
value01
Upvotes: 1
Reputation: 180201
There seems to be confusion both in the data and in the ERB about how the data are structured. This YAML ...
title07: - title07_01: value07_01 - title07_02: value07_02 - title07_03: value07_03 - title07_04: value07_03 - title07_05: value07_04
... provides an array of single-key hashes as the value of the host hash's 'title07' key. That's not necessarily wrong, but it's very suspicious. It's unclear what thge array layer is supposed to be doing for you, relative to making the data a single five-element hash.
Consider the ERB presented in light of that data structure. Here ...
<% item['title07'].each do |inner_item| -%>
... item['title07']
is an array of single-key hashes, so each inner_item
is one of those hashes. The one key appearing in that hash varies from hash to hash, which makes these unnecessarily difficult to work with. None of the keys is 'title07'
, however, so this will break:
<%= inner_item['title07']['title07_01'] %>
You would need something along the lines of
<%= inner_item['title07_01'] %>
, but accounting for the fact that the key differs from inner_item
to inner_item
. If you really want to try to work with that, then you might find it useful to use each_with_index
instead of each
, so that you can construct the needed hash key from the array index. Alternatively, you could just iterate the inner hash to get the value.
But that demonstrates some of the infelicities of that data structure. Suppose that you instead structured the data as a single multi-key hash, bypassing the array level:
title07:
title07_01: value07_01
title07_02: value07_02
title07_03: value07_03
title07_04: value07_03
title07_05: value07_04
Then iterating over the entries probably gets you what you want more directly:
<% item['title07'].each do |_, value| -%>
<%= value %>
<% end -%>
Alternatively, since the keys have a computable form you can compute the keys with which to retrieve the leaf data:
<% 1...5.each do |i| -%>
<%= item['title07']["title07_0#{i}"] %>
<% end -%>
Similar could be made to work with your array-based structure, too, but the needed expression would be more complex (and is left as an exercise).
Upvotes: 1