Ryan Bigg
Ryan Bigg

Reputation: 107728

Blocks in pure ERB / Erubis

I have the following Ruby script:

require 'erubis'

def listing(title, attributes={})
  "output" + yield + "more output"
end

example = %Q{<% listing "db/migrate/[date]_create_purchases.rb", :id => "ch01_292" do %>
<![CDATA[class CreatePurchases < ActiveRecord::Migration
  def change
    create_table :purchases do |t|
      t.string :name
      t.float :cost
      t.timestamps
    end
  end
end]]>
<% end %>}

chapter = Erubis::Eruby.new(example)
p chapter.result(binding)

I am attempting to use a block here and get it to output "output", then the content in the block and then "more output", but I can't seem to get it to work.

I know that ERB used to work this way in Rails 2.3 and now works with <%= in Rails 3... but I'm not using Rails at all. This is just pure ERB.

How can I get it to output all the content?

Upvotes: 5

Views: 1848

Answers (2)

Great. I remember seeing that a while ago. Playing a bit I was getting this:

require 'erubis'

def listing(title, attributes={})
    %Q{<%= "output #{yield} more output" %>}
end

example = listing "some title", :id => 50 do
            def say_something
              "success?"
            end
            say_something
          end


c = Erubis::Eruby.new(example)
p c.evaluate
# => "output success? more output"

Upvotes: 0

Ryan Bigg
Ryan Bigg

Reputation: 107728

Jeremy McAnally linked me to this perfect description of how to do it.

Basically, you need to tell ERB to store the output buffer in a variable.

The script ends up looking like this:

require 'erb'

def listing(title, attributes={})
  concat %Q{
<example id='#{attributes[:id]}'>
  <programlisting>
    <title>#{title}</title>}
  yield
  concat %Q{
  </programlisting>
</example>
  }
end

def concat(string)
  @output.concat(string)
end

example = %Q{<% listing "db/migrate/[date]_create_purchases.rb", :id => "ch01_292" do %>
<![CDATA[class CreatePurchases < ActiveRecord::Migration
  def change
    create_table :purchases do |t|
      t.string :name
      t.float :cost
      t.timestamps
    end
  end
end]]>
<% end %>}

chapter = ERB.new(example, nil, nil, "@output")
p chapter.result(binding)

Upvotes: 3

Related Questions