Free, tested & ready to use examples : Ruby on Rails HTML safe escaping entity
AnyExample.com
 
Webanyexample.com
 

How to allow some safe HTML in Rails projects

abstract 
Although Ruby On Rails has support for various markup languages like textile and markdown via RedCloth and BlueCloth gems, often simple HTML is more preferable solution(like "Some HTML is OK" on Flickr). This article contains simple Ruby function ae_some_html which allows usage of basic HTML tags and converts everything else to entity-escaped HTML code.
compatible 
  • Any Ruby / Ruby On Rails version

This function ae_some_html converts all HTML special symbols to HTML entities:

  • & to &
  • < to &lt;
  • > to &gt;

Afterwards it parses escaped string with regular expressions replacing safe constructions with proper HTML code.

Here is the source code of the function:

source code: Ruby
 
def ae_some_html(s)
    # converting newlines
    s.gsub!(/\r\n?/, "\n")
 
    # escaping HTML to entities
    s = s.to_s.gsub('&', '&amp;').gsub('<', '&lt;').gsub('>', '&gt;')
 
    # blockquote tag support
    s.gsub!(/\n?&lt;blockquote&gt;\n*(.+?)\n*&lt;\/blockquote&gt;/im, "<blockquote>\\1</blockquote>")
 
    # other tags: b, i, em, strong, u
    %w(b i em strong u).each { |x|
         s.gsub!(Regexp.new('&lt;(' + x + ')&gt;(.+?)&lt;/('+x+')&gt;',
                 Regexp::MULTILINE|Regexp::IGNORECASE), 
                 "<\\1>\\2</\\1>")
        }
 
    # A tag support
    # href="" attribute auto-adds http://
    s = s.gsub(/&lt;a.+?href\s*=\s*['"](.+?)["'].*?&gt;(.+?)&lt;\/a&gt;/im) { |x|
            '<a href="' + ($1.index('://') ? $1 : 'http://'+$1) + "\">" + $2 + "</a>"
          }
 
    # replacing newlines to <br> ans <p> tags
    # wrapping text into paragraph
    s = "<p>" + s.gsub(/\n\n+/, "</p>\n\n<p>").
            gsub(/([^\n]\n)(?=[^\n])/, '\1<br />') + "</p>"
 
    s      
end
 

The function allows following HTML:

  • <a href="URL"> link </a> (only href attribute)
  • <b>bold</b>
  • <blockquote>
    blockquote
    </blockquote>
  • <em>emphasis</em>
  • <i>italic</i>
  • <strong>strong</strong>
  • <u>underlined</u>

Any of unclosed or broken tags will not be converted to HTML.

As you can see this function also replaces line breaks with <br />(single line break) and <p>(two or more line breaks) tags.

Usage example:

source code: Ruby
 
s = "Test is a <b>test</b> 
<blockquote>
 
    >>><em>It Works!</em><<<
 
</blockquote>
<a href='anyexample.com'>Linking</a> works! 
<b>Broken HTML does not work: </i>
"
 
print ae_some_html(s)
 

HTML result is:

Test is a test

>>>It Works!<<<

Linking works!
<b>Broken HTML does not work: </i>

It is possible to put ae_some_html call in before_save function of your Model class. For example:

source code: Ruby / Ruby On Rails
 
class Comment < ActiveRecord::Base
    belongs_to :user
    validates_length_of :text, :minimum => 3
 
    # copy-paste ae_come_html here
    # or to separate .rb file in lib folder (and 'require' it)
 
    def before_save 
        # text_view field is for View
        # original text field saved for editing
        self.text_view = ae_some_html(self.text)
 
        # if you don't need to save original text
        # just do
        # self.text = ae_some_html(self.text)
    end
 
end
 

You can also add ae_some_html to app/helpers/application_helper.rb and call it directly from application templates. This approach usually requires caching techniques to avoid unnecessary ae_some_html calls.

 

warning 
  • For performance reasons, you should better use ae_some_html to process text once, when storing it in database (in Model).
  • Because ae_some_html does one-way conversion, you should store original text if editing is necessary.
tested by AnyExample.com on 2007-07-16
  • Mac OS X :: Ruby On Rails 1.2.3
  • Windows XP :: Ruby 1.8.6
 


 
© AnyExample 2007
License | Privacy | Contact