Free, tested & ready to use examples!
AnyExample.com
 
Web anyexample.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 
  • Mac OS X :: Ruby On Rails 1.2.3
  • Windows XP :: Ruby 1.8.6
  •  


     
    © AnyExample 2010-2013
    License | Privacy | Contact