I'm trying to write an if statement that compares two variables in a puppet erb template:
<% #array_of_ip_addresses.each_with_index do |ip, idx| -%>
<% if #ip == #ipaddress_eth0 -%>
<%= "doing something with #{idx}" -%>
<% end -%>
<% end -%>
I cannot figure out why, but the condition on my if statement keeps returning false (needless to say I confirmed there should be a match).
What dumb thing am I missing?
ip is a block scope variable and not a variable instantiated from the invoking code (in this case, Puppet's template function), so you should not specify it as a class instance variable with #. When you remove that and specify it as a block scope variable ip, the template will look like:
<% #array_of_ip_addresses.each_with_index do |ip, idx| -%>
<% if ip == #ipaddress_eth0 -%>
<%= "doing something with #{idx}" -%>
<% end -%>
<% end -%>
Using the class instance variable #ip would likely result in a resolution of nil, which would definitely almost always be false as nil != #ipaddress_eth0 unless Facter failed to resolve a value for your eth0 ipaddress, which would be quite uncommon (but still possible).
Related
I have this line in EJS file:
<%= nominations[i].month %>
I want to decrement it in the EJS by 1.
So I tried:
<%= (nominations[i--].month) %>
But this didn't change the output value.
I tried subtraction also but the output still stayed the same.
<%= (nominations[i-1].month) %>
I also tried:
<%= (nominations[i].month -1) %>
Update: I didn't realize the number is in string format, the solution:
Here is solution in case it help someone else in future.
I didn't realize that nominations[i].month is actually string data type.
I manage to subtract the number by 1.
First converted the string to the number
<%= parseInt(nominations[i].month) %>
And then I subtract by 1
<%= parseInt(nominations[i].month-1) %>
I have an alert section pulling items with a repeater. My transformation pulls date and copy and displays them in UL tags.
I've been asked to make a change where a specific alert would only be seen by people is a specific group/role.
My thoughts were change the page type form with a check box. On the transformation side i would then need a conditional statement where the check box is true and the user is part of specific Role.
My transformation is currently an ASCX and is as follows:
<li><%# Eval("Alert") %></li>
I imagine it being something like this
<% if ( checked = true && role = XX ) { <li>Eval("Alert")</li> } %>
I just can't figure out the conditional statement.
For Text/XML transformation
{% if(checked == true && CurrentUser.IsInRole("MyRole")) {return "<li>" + Alert + "</li>"} %}
ASCX
<%# If(CMS.Membership.MembershipContext.AuthenticatedUser.IsInRole("rolename", CMS.SiteProvider.SiteContext.CurrentSiteName) && Eval("checked") == true, "<li>" + Eval("Alert") + "</li>","") %>
I'd recommend to add some CSS class based on your condition:
<li class="<% if(Eval<bool>("FieldsName") &&
CMS.Membership.MembershipContext.AuthenticatedUser.IsInRole("rolename", CMS.SiteProvider.SiteContext.CurrentSiteName);) {"alert"} %>">
....
</li>
Having "alert" class added to your li, you can change visibility, colors or whatever you need for that item.
This approach requires ASPX transformation.
You can use the method CurrentUser.IsInRole(, )
I came up with something like:
<%# (checked && CurrentUser.IsInRole("_everyone_", "corporate") ? Eval("DocumentName") : "empty") %>
David
I'm trying to analyse an XML tree using XmlSlurper and GPath, and the behaviour of the findAll method confuses me.
Say, for example, that you have the following XML tree:
<html>
<body>
<ul>
<li class="odd"><span>Element 1</span></li>
<li class="even"><span>Element 2</span></li>
<li class="odd"><span>Element 3</span></li>
<li class="even"><span>Element 4</span></li>
<li class="odd"><span>Element 5</span></li>
</ul>
</body>
</html>
Assuming that xml has been initialised through one of XmlSlurper's parse methods, the following code executes as one would expect:
// Prints:
// odd
// odd
// odd
xml.body.ul.li.findAll {it.#class == 'odd'}.#class.each {println it.text()}
On the other hand:
// Doesn't print anything.
xml.body.ul.li.findAll {it.#class == 'odd'}.span.each {println it.text()}
I'm struggling to understand why I can use the special # property (as well as others, such as **), but not 'normal' ones.
I've looked at the API code, and what confuses me even more is that the getProperty implementation (found in GPathResult) seems to support what I'm trying to do.
What am I missing?
You need to iterate over every span, so you can use the spread-dot operator:
xml.body.ul.li.findAll {it.#class == 'odd'}*.span.each {println it.text()}
I'm working on a static site using middleman and am trying to use mm's local data functionality.
Currently I have the required data directory within the source directory of my middleman project.
Inside the data directroy is a yaml file (home.yml)
Here's the structure of the file:
slides:
- image: "/img/slider/slide1.jpg"
image_alt: "Slide 1 alt text"
caption: "Slide 1 caption"
- image: "/img/slider/slide2.jpg"
image_alt: "Slide 2 alt text"
caption: "Slide 2 caption"
I'm then trying to loop through those slides in a html.erb file like so:
<%= data.home.slides.each do |s| %>
<figure class="slide">
<%= image_tag(s[:image], alt: s[:image_alt]) %>
<figcaption><%= s[:caption] %></figcaption>
</figure>
<% end %>
But middleman spits a NoMethodError on the compiled html file.
undefined method `home' for #<Middleman::CoreExtensions::Data::DataStore:0x4383918>
I don't know what I'm doing wrong. I tried moving the data directory up a level outside of the source folder but that did nothing.
It seems like middleman doesn't recognise the home.yml folder in side the data directory.
Any help with this is much appreciated as I've found there's not much in the way of documentation or support for middleman's data functionality.
You were pretty close -- you just had a minor typo. Note how I removed the equals "=" sign.
Change this line:
<%= data.home.slides.each do |s| %>
to this:
<% data.home.slides.each do |s| %>
The following markup should be generated once this is done:
<figure class="slide">
<img alt="Slide 1 alt text" src="/img/slider/slide1.jpg">
<figcaption>Slide 1 caption</figcaption>
</figure>
<figure class="slide">
<img alt="Slide 2 alt text" src="/img/slider/slide2.jpg">
<figcaption>Slide 2 caption</figcaption>
</figure>
I need some help with erb templates, I can't seem to get my head around passing an array and then iterating over it.
My problem is this.
I want to pass a few arrays:
`
device => ["eth0", "br0"],
ipaddr => ["192.168.12.166", "192.168.12.199"],
netmask => ["255.255.255.0", "255.255.255.0"],
hwaddr => '',
network => '',
gateway => ["192.168.12.254", "192.168.12.204"],
To a template that iterates over each item in the array and prints it out:
auto <%= device %> inet static
address <%= ipaddr %>
netmask <%= netmask %>
broadcast <%= broadcast %>
gateway <%= gateway %>
As far as I can get so far is figuring out that I need to do something with device.each |device| puts device, but I don't know what the syntax is supposed to look like.
I believe you can tell what I'm trying to do from these snippets, and then you might understand that the entries need to be seperate, and not interpolated.
Any help you can offer would be appreciated. I know I should be trying things out in irb and figuring them out from there, which is what I'm reading up on now.
Thanks!
the basic syntax for using each in ruby is something like this:
array.each do |item_from_array| BLOCK
so if you only had one array then you could just do something like this:
(I would use a different name inside the vertical bars for clarity)
<% device.each do |dev| %>
auto <%= dev %> inet static
<% end %>
However that would iterate over all of your devices first, before moving on to your ipaddr array. I'm guessing you want them each in turn auto, address, netmask, etc. In that case you'd be better off using a more 'traditional' index and looping through N times, like this:
<% for idx in (0..1) %>
auto <%= device[idx] %> inet static
address <%= address[idx] %>
netmask <%= netmask[idx] %>
broadcast <%= broadcast[idx] %>
<% end %>
Of course you need to think about what your maximum size of array is, and what to do if an array contains less entries than the others. You can find the maximum size of all the arrays by doing something like this: [device,address,netmask,broadcast].map{|a| a.length}.max
and you can skip over a particular array like this: <% if idx < address.length %> address <%= address[idx] %><% end %>
ERB Templates for Dummies
Basic code:
require 'erb'
ERB.new(template).result binding_for_template
What are template and binding_for_template?
Template
Just the template content. You can read it from a file just with a File.read(path).
Binding for template
A binding
encapsulate the execution context at some particular place in the code and retain this context for future use.
How do you use it? Easy:
def binding_for_my_template
devices = ["eth0", "br0"]
ipaddrs = ["192.168.12.166", "192.168.12.199"]
netmasks = ["255.255.255.0", "255.255.255.0"]
hwaddrs = ['']
networks = ['']
gateways = ["192.168.12.254", "192.168.12.204"]
binding
end
That will return a binding with all six arrays (I changed hwaddr and network to arrays for consistency.
Iterating over arrays
The usual way is using the each method, just like this:
<%- devices.each do |d| %>
auto <%= d %> inet static
<%- end %>
but there are other methods if you wanna put all in one line, for example devices.join ' ' will join all the strings with a space in between.
You should read the docs. Quoting:
# Managed by Class['ntp']
<% servers_real.each do |server| -%>
server <%= server %>
<% end -%>
# ...
This snippet will iterate over each entry in the array and print it
after a server statement, so, for example, the string generated from
the Debian template will end up with a block like this:
# Managed by Class['ntp']
server 0.debian.pool.ntp.org iburst
server 1.debian.pool.ntp.org iburst
server 2.debian.pool.ntp.org iburst
server 3.debian.pool.ntp.org iburst