Add a class to the first child in a loop using Middleman - ruby

I am creating a slider for my blog and I want to add a collection of featured items to it, The slider requires that the first child load with the class selected.
How can I do something like if first child do this else do that
Here is what I have so far:
<ul class="cd-hero-slider">
<% blog.articles.select {|a| a.data[:featured] }.each do |article| %>
<li class="selected" style="background-image: url('https://images.unsplash.com/photo-1447014421976-7fec21d26d86?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&s=c82e04e1201234889daab5427f481731')">
<div class="cd-full-width">
<h2><%= link_to article.title, article %></h2>
<p><%= article.summary(250) %></p>
<%= link_to 'Read More', article, :class => 'cd-btn' %>
</div>
</li>
<% end %>
</ul>

Use each_with_index instead of each - this will give you the object but also the position into the array, first being 0:
<% blog.articles.select {|a| a.data[:featured] }.each_with_index do |article, index| %>
<% if index == 0 %>
<li>I'm the first!</li>
<% else %>
<li>Not the first</li>
<% end %>
<% end %>

Related

Elegant way to print HTML Lists with Ruby + ERB

I have the following code
<% if items.any? %>
<ul class="level1">
<% items.each do |item| %>
<li class="item">
<%= item.text %>
</li>
<% end %>
</ul>
<% end %>
While this works, I was wondering if there was a way to make it more elegant. The if and then each is not very pretty...
Anyone knows a more elegant syntax?
Try this, based on:
<% content_tag(:ul, class: 'level1') do %>
<% content_tag_for(:li, items, class: "item") do |item|
<%= link_to item.text, '#' %>
<% end %>
<% end if items.any? %>
5 lines, no extra partials, only rails helpers.
As suggested by sawa, you could use Slim:
- if items.any?
ul.level1
- items.each do |item|
li.item
a href="#"
= item.text
or Haml:
- if items.any?
%ul.level1
- items.each do |item|
%li.item
%a{href: "#"}= item.text
Both produce nicely formatted HTML.
I would go into something like this:
if items.any?
content_tag(:ul, class: 'level1') do
items.each do |item|
concat content_tag(:li, class: 'item', item)
end
end
end
That actually looks sufficiently elegant to me already, but you could do this to make a little cleaner:
<% if items.any? %>
<ul class="level1">
= render items
</ul>
<% end %>
And then have your li code in a partial called _items.html.erb, like so:
<li class="item">
<%= item.text %>
</li>

erb template for nested array

I have nested array:
book= {"Dan Brown"=>["Angels and Demons", "The Da Vinci Code"], "Dale Carnegie"=>["How to Win Friends and Influence People", "How to Stop Worrying and Start Living"]}
I need this html result:
<h3 class="title">Book</h3>
<h4>Dan Brown</h4>
<ul>
<li>Angels and Demons</li>
<li>The Da Vinci Code</li>
</ul>
<h4>Dale Carnegie</h4>
<ul>
<li>How to Win Friends and Influence People</li>
<li>How to Stop Worrying and Start Living</li>
</ul>
Can't understand how to do it via erb template.
May be from this method:
book.each {|key, value| puts "#{key} is #{value}" }
But for me this method don't work, I think I can't understand how to use it.
Thank you for help.
Just like that:
<h3 class="title">Book</h3>
<% book.each do |key, value| %>
<h4><%= key %></h4>
<ul>
<% value.each do |title| %>
<li><%= title %></li>
<% end %>
</ul>
<% end %>
<h3 class="title">Book</h3>
<% book.each do |author,books| %>
<h4><%= author%></h4>
<ul>
<% books.each do |book| %>
<li><%= book%></li>
<% end %>
</ul>
<% end %>

Do I need an Enumerator for this?

I want to do this:
<div class="menu">
<%- render_menu do |title,path,children| %>
<%= link_to title, path %>
<div class="submenu">
<%= render_menu(children) do |title,path,children| %>
<%= link_to title, path %>
<%= children %>
<%- end %>
</div>
<% end %>
</div>
The method render_menu would look something like this:
def render_menu(children=nil)
children = Paths.roots if children.nil?
children.collect do |child|
[ child.title, child.path, child.children ]
end
end
I'm not sure what the render_menu needs to return to get the three params..
The render_menu will grab the default menu items if no argument is given..
You have to use yield and replace each for collect inside render_menu:
def render_menu(children=nil)
children = Paths.roots if children.nil?
children.each do |child|
yield([child.title, child.path, child.children])
end
end
You should also modify your template to not display the value returned by render_menu:
<div class="submenu">
<% render_menu(children) do |title,path,children| %>
<%= link_to title, path %>
<%= children %>
<% end %>
</div>

my final step in the rails app, how to make comments appear in a popup?

This is the last remaining item to complete my first rails app and need some help.
On each user profile (localhost:3000/users/username), there's a listing of posts that the user has made. Associated with each post are comments. So post_id: 3 could have comments.
I have it working already in view form but I need the comments to appear in a popup instead when the "Comments" link under each post is clicked.
I have already applied facebox which is a jQuery-based lightbox that displays popups.
I just need to move what's currently shown in show.html.erb into a popup.
There's the _comment_form.html.erb which renders into _post.html.erb
<%= link_to #, :rel => "facebox-#{post.id}" do %>
+<%= post.comments.count.to_s %>
<% end %>
<div class ="ItemComments"><% if post.comments.exists? %>
<% post.comments.each do |comment| %>
<%= image_tag("http://www.gravatar.com/avatar.php?gravatar_id=#{Digest::MD5::hexdigest(comment.user.email)}" %>
<span class="users"><%= link_to comment.user.name, comment.user %></span>
<span class="timestamp"><%= time_ago_in_words(comment.created_at) %> ago</span>
<span class="content2"><%= comment.comment_content %></span>
<% end %>
<% end %></div>
The above renders into _post.html.erb using:
<%= render 'shared/comment_form', post: post if signed_in?%>
Then it renders into show.html.erb
I'm trying to use this line, but what do I link it to?
<%= link_to #, :rel => "facebox-#{post.id}" do %>
+<%= post.comments.count.to_s %>
<% end %>
This is shared/_comment.html.erb
<% if post.comments.exists? %>
<% post.comments.each do |comment| %>
<%= image_tag("http://www.gravatar.com/avatar.php?gravatar") %>
<%= link_to comment.user.name, comment.user %>
<span class="timestamp"><%= time_ago_in_words(comment.created_at) %> ago</span>
<span class="content2"><%= comment.comment_content %></span>
<% end %>
<% end %>
One way of doing this is to render your comments into a hidden div and give that div an id. Next you point your link to the id of the div using # followed by the id. It would look something like this:
_post.html.erb
<%= link_to "#comments", :rel => "facebox" do %>
<%= post.comments.count.to_s %>
<% end %>
<div id="comments">
<%= render 'shared/comment_form', post: post if signed_in?%>
</div>
CSS
#comments {
display: none;
}
See the 'Divs' heading over at the Facebox docs.

Ruby variable each loop substitution

I need to replace X_VARIABLE in 2 places.
For the first X_VARIABLE I want to keep the text 'remove'
For the second X_VARIABLE I want to keep 'd_cars_path'
<% #cars.each do |x| %>
<% #a = #b.send(x) %>
<% if #a == true %>
<%= button_to "removeX_VARIABLE", X_VARIABLEd_cars_path(:id => #user.id), class: "btn btn-large btn-primary" %>
<% end %>
<% end %>
I am looking for some help with the variable substitution syntax. Thanks.
I'd write:
<% #cars.each do |x| %>
<% if #b.send(x) %>
<%= button_to "remove#{x}",
send(:"#{x}d_cars_path", id: #user.id),
class: "btn btn-large btn-primary" %>
<% end %>
<% end %>

Resources