I have a list of products and I want to show an ad in the product feed.
I want something like:
<div id="container">
<div id="product">Bla..</div>
<div id="product">Bla..</div>
<div id="product">Bla..</div>
</div>
<div id="add">
Adsense Stuff
</div>
<div id="container">
<div id="product">Bla..</div>
<div id="product">Bla..</div>
<div id="product">Bla..</div>
<div id="product">Bla..</div>
<div id="product">Bla..</div>
</div>
In ERB, I would have:
<div id="container">
<% productes.each_with_index do |product,index| %>
<div id="product"><%= product %></div>
<% if index == 2 %>
</div>
<div id="add">
Adsense Stuff
</div>
<div id="container">
<% end %>
<% end %>
</div>
How you translate this to Haml or Slim?
I don't want to break the loop in two loops for two reasons: I don't know the products count by page and I have some more elaborate code which uses the same HTML tricks with the Rails cycle()
helper. So, it will help me a lot to find a trick to make it possible.
Haml lets you write raw HTML as output when you want it. Although weird, you can use this to achieve your goals here, as you did with Erb:
TEMPLATE = '
.container
- products.each_with_index do |product,index|
- if index == 2
</div>
<div class="ad">AdSense Stuff</div>
<div class="container">
.product<
= product
'
require 'haml'
products = %w[ cat box kitten shoes hounds ]
puts Haml::Engine.new(TEMPLATE).render binding
#=> <div class='container'>
#=> <div class='product'>cat</div>
#=> <div class='product'>box</div>
#=> </div>
#=> <div class="ad">AdSense Stuff</div>
#=> <div class="container">
#=> <div class='product'>kitten</div>
#=> <div class='product'>shoes</div>
#=> <div class='product'>hounds</div>
#=> </div>
The indentation looks weird, but you can see that you have two containers with the AdSense stuff outside either.
In HAML
-products.each_with_index do |product,index|
.product= product
-if index == 2
.ad= Adsense Stuff
I wouldn't bother with the container, just set up the css to deal with the product and ad classes. (Which also brings up the fact that you have multiple ids of the same name, these should be changed to classes).
- products.each_with_index do |product,index|
.product
= product
- if index == 2
.ad= Adsense Stuff
This should do it?
A possible Haml solution, using the surround
helper:
.container
-products.each_with_index do |product,index|
.product=product
-if index == 2
=surround "</div>", "<div class='container'>" do
.add
Adsense stuff
This is a bit of a hack, in that we're "faking" closing and opening the container div; as far as Haml knows we're still in it. For this reason it also introduces a bit of repetition in that you have to specify the "container" class (and any other attributes that div might have) in two places.
This solution is similar to @Phrogz's solution but this is a bit more "Haml-ly" and allows you to use Haml syntax to define the add div.
来源:https://stackoverflow.com/questions/8893538/how-do-i-close-the-container-div-in-a-loop