Kevin Whitaker
Kevin Whitaker

Reputation: 13425

Sinatra & HAML: auto-escape/convert unsafe HTML characters for a whole template?

I've got a little sinatra app I'm using to run a basic website. The content for said site is being provided by a client, and most of it is coming out of PDFs. Since I'd rather not have to manually replace all the < with &lt;, and the & with &amp;, is there a way to configure HAML/Sinatra to do it for me automatically?

Basically, I have some blocks that look like this:

%p
  large block of text here...
  multi-line so I can see it in my IDE...
  more lines here...

I'd like to just find some config option that tells HAML to go through all of the content and replace unsafe characters with their HTML entity counterparts.

I tried using the HTMLEntities gem, but this site has a lot of multi-line paragraphs, and I couldn't seem to get it to work. By that I mean that I would do something like this in my server.rb file:

def "/some_url"
  @encoder = HTMLEntities.new
  haml :some_template
end

And in my template:

%p
  = @encoder.encode("Really long multiline string...
    some more lines here...
    and more lines...")

And it would spit out an error about missing a closing ).

Upvotes: 4

Views: 1623

Answers (2)

matt
matt

Reputation: 79743

You could use the :escaped filter:

%p
  :escaped
    A block of text here that might
    contain & and <.

output:

<p>
  A block of text here that might
  contain &amp; and &lt;.
</p>

It’s not quite automatic, but might reduce the editing required.

Upvotes: 6

Patrick Oscity
Patrick Oscity

Reputation: 54684

Maybe you are looking for this:

require 'cgi'
CGI::escapeHTML('unsafe string <script>kill() && destroy()</script>'
#=> "unsafe string &lt;script&gt;kill() &amp;&amp; destroy()&lt;/script&gt;"

EDIT

Now i actually get what you want. Just use :escape_html => true and you can wrap your text in ='...text here...' because all strings are implicitly escaped.

require 'sinatra'

get '/' do
  haml :index, :escape_html => true
end

__END__

@@layout
!!! 5
%html
  %head
    %title Example
  %body
    = yield

@@index
%p
  ='Here is some <em>unsafe</em> HTML.'
  ='<script type="text/javascript">'
  ='killKittens() && destroyHumanity()'
  ='</script>'

Result:

$ curl localhost:4567
<!DOCTYPE html>
<html>
  <head>
    <title>Example</title>
  </head>
  <body>
    <p>
      Here is some &lt;em&gt;unsafe&lt;/em&gt; HTML.
      &lt;script type=&quot;text/javascript&quot;&gt;
      killKittens() &amp;&amp; destroyHumanity()
      &lt;/script&gt;
    </p>
  </body>
</html>

Upvotes: 2

Related Questions