Rendering ruby block result in layout file

If you want to render some result of ruby block in your layout file, you may run into some problems. For example, your result may be repeated on page or you can get something worse.

let’s assume we have these methods:

def add_to_head(&block)
  @head_html ||= []
  @head_html << block if block_given?
end

def display_custom_head
  return unless @head_html
  @head_html.map(&:call).join
end

Of cource you can use captire method from rails and sinatra-contrib librares. But what will you do if you can’t use these methods or you need something easier?

I faced a similar problem (for example, in sidekiq) and I used own capture method for layout files.

def capture(&block)
  block.call
  eval('', block.binding)
end

And after that we can update our display_custom_head method:

def display_custom_head
  return unless @head_html
  @head_html.map { |block| capture(&block) }.join
end

I hope it will be useful to you as well as for me at one time.

Happy hacking!