views:

220

answers:

2

Hi!

I ran into a big problem in moving my application to Rails 3. I have a view helper which i call 'WidgetHelper'. It helps to render some partials automatically when i refer to it. For example

<%= widget('loginbox', :global => true) %>

But it not works correctly. It renders HTML code as I want, but escapes the return value, what is not expected. How can I tell to render (or to something) to not escape the return value for me?

Here is my code:

  def widget(widget, options={})
    begin
      unless options[:fullpath]
        render :partial => widget_path(widget, options[:global])
      else
        render "widgets/#{widget}"
      end
    rescue ActionView::MissingTemplate
      "<!-- widget: #{widget.inspect}, #{options.inspect} -->"
    end
  end
+1  A: 

Rails 3 changed the way that content filtering works - it by default assumes you want everything filtered.

You can correct this using html_safe:

"<!-- widget: #{widget.inspect}, #{options.inspect} -->".html_safe

See: http://asciicasts.com/episodes/204-xss-protection-in-rails-3

Jamie Wong
+2  A: 
def widget(widget, options={})
  begin
    unless options[:fullpath]
      raw render(:partial => widget_path(widget, options[:global]))
    else
      raw render("widgets/#{widget}"))
    end
  rescue ActionView::MissingTemplate
    raw "<!-- widget: #{widget.inspect}, #{options.inspect} -->"
  end
end

The raw method of Rails 3 does the reverse of h method in Rails 2. Escaping a string was done with the h method on Rails 2. On Rails 3, strings output from a view are escaped by default, and the escaping can be disabled by the raw method.

edgerunner
Thank you, it works well. I add score for you and for @Jamie Wong too, because i used both solution in my app.
Gabor Garami
This seems kind of backwards in my mind - when would you ever want widget without raw? Specifying you want the raw should be part of the definition in my mind, not the invocation.
Jamie Wong
You're right Jamie. Fix coming up.
edgerunner