Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unescaping HAML in an Attribute Hash

Tags:

ruby

haml

I have a problem similar to some I've found on stackoverflow, but not quite the same. I'd like to avoid the solution to the following question:

https://stackoverflow.com/a/10407782/996587

Basically, would like the following HTML output:

<div class='myclass' extraattr='UNESCAPED <>& CONTENT'>
    Content...
</div>

The HAML I'm using looks like this:

.myclass{ "extraattr" => "UNESCAPED <>& CONTENT" }
  Content...

I can't quite figure out how to get the content to output the way I want. Tried applying .html_safe to the end of the string, but got the following error:

undefined method `html_safe' for "UNESCAPED <>& CONTENT":String

Later realized that for this particular application I'm not using Rails, just ruby + HAML. (I inherited this project and I'm just starting to learn HAML, ruby, and Rails anyways)

And again, for those of you too lazy to click links and didn't read the solution I referred to, I'd prefer not to configure HAML to not escape attrs for the entire file, just for this one attribute.

Thanks!

UPDATE

I just found the :plain filter, and was able to get what I wanted using that. However, if there's a trick I don't know about so I don't have to write all the HTML, I'd appreciate it. My "fix":

:plain
  <div class='myclass' extraattr='UNESCAPED <>& CONTENT'>
    Content...
  </div>
like image 492
thexfactor Avatar asked May 16 '13 20:05

thexfactor


1 Answers

There isn’t (currently) any way to turn off escaping for an individual attribute in Haml outside of Rails, it’s all or nothing using the :escape_attrs option. Depending on what you want, it might be worth looking at the :once option.

When Haml is used in Rails, it replaces the html escaping methods with some that respect the html_safe value that ActiveSupport adds (see lib/haml/helpers/xss_mods.rb).

It is possible to use these methods outside of Rails if you want. You will need to add html_safe and html_safe? methods to the String class in order for this to work (be careful here, this example is only a “poor man’s” version of the full XSS protection that Rails provides, it won’t really protect you from much but it will allow selective escaping of attributes).

Add the following somewhere after requiring Haml (it might be best in its own file that gets required):

class String
  def html_safe?
    defined?(@html_safe) && @html_safe
  end

  def html_safe
    @html_safe = true
    self
  end
end

require 'haml/helpers/xss_mods'

module Haml::Helpers
  include Haml::Helpers::XssMods
end

Now you can use html_safe on your strings, and Haml won’t escape them:

.myclass{ "extraattr" => "UNESCAPED <>& CONTENT".html_safe,
          "otherextraattr" => "ESCAPED <>& CONTENT"}
  Content...

Output:

<div class='myclass' extraattr='UNESCAPED <>& CONTENT' otherextraattr='ESCAPED &lt;&gt;&amp; CONTENT'>
  Content...
</div>
like image 172
matt Avatar answered Nov 10 '22 00:11

matt