4

When writing a helper for printing javascript that can be used from both other helpers and views, I stumbled upon the following problem:

def javascript(print_tag = false, &block)
  content_for(:javascript) do
    if print_tag
      javascript_tag(&block)          # does not work
      javascript_tag { block.call }   # does work 
    else
      capture(&block)
    end
  end
end

This helper should be called with javascript { "alert('hurray'); }.

In the first alternative - which I expected to work - the Rails javascript_tag helper renders an empty <script type="text/javascript"> //<![CDATA[ //]]> </script> tag.

The second alternative, however, works as expected.

What's going on there? How can that be different?

1 Answer 1

4

You say you are doing this on your views, right?

<%= javascript { "alert('hurray');" } %>

But for content_tag(&block) to work, you should call javascript the way content_tag is intended to be used in views, which is:

<% javascript do %>
  alert('hurray');
<% end %>

content_tag's behavior is different depending on where it's called from, see the function block_called_from_erb? in the source code. In the first case this function returns true because the block does come from an erb (and then it's concated, you don't want that!), in the second returns false (you re-created the block from scratch) and content_tag simply returns the string content, which is what you want.

# ./action_view/helpers/javascript_helper.rb
tag = content_tag(:script, javascript_cdata_section(content), html_options.merge(:type => Mime::JS))
if block_called_from_erb?(block)
  concat(tag)
else
  tag
end
Sign up to request clarification or add additional context in comments.

1 Comment

Ough... what a tricky implementation! Actually I am using Haml: - javascript(true) { fire_flash } if flash_message.present? and I don't want to write that in 4 lines if it is fine in 1 line. But, thank you very much!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.