Reputation: 5877
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?
Upvotes: 4
Views: 386
Reputation: 67850
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 concat
ed, 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
Upvotes: 4