Question

I have a YAML file of products:

# Product - Granola Bar
-   title       : "Granola Bar"
    excerpt     : "Comes in several amazing varieties including nut, and delicious fruit."
    description : "Comes in several amazing varieties including nut, and delicious fruit."
    image       : "granola-bar.jpg"
    cost        : "3.50"
    discount    : "2.50"
    stock       : "100"
    ingredients :
        - value : key

# Product - Granola Bar
-   title       : "Hazelnut Spread"
    excerpt     : "Chocolate"
    description : "Chocolate"
    image       : "hazelnut-spread.jpg"
    cost        : "2.50"
    discount    : "1.50"
    stock       : "100"
    ingredients :
        - value : key

When I iterate through these the content is being appended to the previous one's content variable:

"Comes in several amazing varieties including nut, and delicious fruit. 3.50"
"Comes in several amazing varieties including nut, and delicious fruit. 3.50 Chocolate 2.50"

But it should be:

"Comes in several amazing varieties including nut, and delicious fruit. 3.50"

then

"Chocolate 2.50"

I'm using:

-# Create new array for the thumbnails
- thumbnails  = []

-# Loop through the array
- data.products.each do | product |

    -# Content
    - content_for :content do

        -# Excerpt
        = product.excerpt

        -# Cost
        = product.cost

    - content = yield_content :content

    - thumbnails << { :"data-src" => "holder.js/300x200/auto",
                      :caption    => content,
                      :title      => product.title }

I'm not sure what to search for, mutable variables in a loop? I tried putting content = nil before the loop and inside also to unset it at each pass.

I want to save the content_for to push into a partial.

This is an image of what is happening. It should obviously not be doubled up in the second thumbnail:

enter image description here

Was it helpful?

Solution

content_for is used to capture content that is used in a different place.

If you have yield_content :title in your application layout and you set it in the currently rendered partial:

# index.haml
- content_for :title, "I'm on the index page"

Your example should NOT use content_for at all. It should just render the strings into the output:

- data.products.each do |product|
  = product.excerpt
  = product.cost

If you want to use that output in a img_tag helper or something like that, than use a helper method to generate the content or put it into its own partial if the logic is more complex.

You can also assign new variables in the view code and use them later on:

- caption = "#{product.excerpt} #{product.cost}"

I don't see a need for anything like that in your example at all. Maybe that's because you actually never use "thumbnails" anywhere.

OTHER TIPS

In the end I changed to using capture_html

    -# Loop through the array
- data.products.each do | product |

    -# Content
    - capture = capture_html do

        -# Excerpt
        %p
            = product.excerpt

        -# Page Name
        - page = product.title.downcase.gsub( /[^a-z0-9\- ]/, ' ').gsub( / /, '-' )

        -# Button
        = partial "bootstrap/css/button",
                   :locals => { :color      => "primary",
                                :content    => "View Product",
                                :extraClass => "pull-right",
                                :href       => "/shop/#{ page }" }

        -# Cost
        %p.text-left.price
            &pound;
            = product.cost

        .clearfix

    - thumbnails << { :"data-src" => "holder.js/300x200/auto",
                      :caption    => capture,
                      :title      => product.title  }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top