Project

General

Profile

Templates Query

Added by Anonymous about 10 years ago

While the project I'm working on is in the form of a plugin, I feel this forum is more appropriate than the "Plugins" subforum... I'm quite simply overriding certain view partials with a custom plugin in order to build a page layout that works for a corporate LAN access Redmine setup. Problem is, I know hardly anything about Ruby on Rails, so the template tags are confusing me somewhat.

At the moment, I'm looking at the code below (/app/views/projects/show.html.erb:30-33, running Redmine 2.4.1).

<% if @subprojects.any? %>
  <li><%=l(:label_subproject_plural)%>:
    <%= @subprojects.collect{|p| link_to p, project_path(p)}.join(", ").html_safe %></li>
<% end %>

The default template gives me an output of...

  • Subprojects: project 1 link, project 2 link, project 3 link

Whereas I'd prefer to have the output as...

  • Subprojects:
    • project 1 link
    • project 2 link
    • project 3 link

Now, I understand that @subprojects is an array and that .collect{..} loops over the array elements, returning a new array after it's done. I assume the link_to function is what generates the anchor links here, but I can't figure out how to wrap the anchor in a list item tag.

To make things interesting, I'm used to templating engines such as Mustache, and since I don't understand Ruby well enough, I have no idea what features to look at in the docs. Could someone help break down this little code snippet for me and help me understand it better...?


Replies (4)

RE: Templates Query - Added by Anonymous about 10 years ago

I've discovered I need to change the .collect{...} syntax to do what I need here, effectively moving the <li> tags inside the loop that collect uses for each array element. However, this is as far as I got.

The best I could come up with, after reading through docs and tutorials, is the following:

<% if @subprojects.any? %>
    <li class="subproj-head"><%=l(:label_subproject_plural)%>:</li>
    <%= @subprojects.collect{|p| "<li>"+ link_to p +"</li>", project_path(p)} %>
<% end %>

As per my understanding of collect, this should simply wrap the generated link in list item tags, but apparently not.

Nobody here able to help? Perhaps at least point me in the right direction?

RE: Templates Query - Added by Martin Denizet (redmine.org team member) about 10 years ago

Hello Andre,
Replace:

<% if @subprojects.any? %>
  <li><%=l(:label_subproject_plural)%>:
    <%= @subprojects.collect{|p| link_to p, project_path(p)}.join(", ").html_safe %></li>
<% end %>

by:
<% if @subprojects.any? %>
<li><%=l(:label_subproject_plural)%>:
  <ul>
    <% @subprojects.each do |p| %>
      <li><%= link_to p, project_path(p) %></li>
    <% end %>
  </ul>
</li>
<% end %>

If it's helpful, you're welcome to endorse me on CoderWall, it could help me out ;)

Cheers,

RE: Templates Query - Added by Anonymous about 10 years ago

Thank you so much Martin, you're a legend.. I wasn't sure if the .collect{...} function (?) was required for this part of the template or not, my lack of Ruby knowledge really got me stumped by this.

Your example is simple enough for me to make sense of and it achieves precisely what I needed. :D

Martin Denizet wrote:

If it's helpful, you're welcome to endorse me on CoderWall, it could help me out ;)

I don't have a CoderWall account, but I'll most definitely keep that in mind if I do join the site. :)

RE: Templates Query - Added by Martin Denizet (redmine.org team member) about 10 years ago

Glad it helped ;)
Collect is used to run a block on each element of an array.

For example to get(collect) the first names of all users you would do something like:

users = User.all
firstnames = users.collect { |user| user.firstname } #Array of all the users' first names!


Also can be used to retreive a modified copy of an array as stated in the documentation :
a = [ "a", "b", "c", "d" ]
a.collect { |x| x + "!" }        #=> ["a!", "b!", "c!", "d!"]

I suggest you to play (Not in production!) with the Rails console or IRB to experiment on this like that if you get stuck.

Cheers!

    (1-4/4)