简体   繁体   中英

How to make the “sanitize” Rails method to leave a space where an HTML used to be?

So, I'm doing the following:

sanitize(self.content, :tags => %w(""))

So I'm taking something like this:

<p>one two three four five six seven eight nine then eleven</p><p>twelve thirteen</p>

And turning it into something like this:

one two three four five six seven eight nine then eleventwelve thirteen

As you can see there is a problem here: eleventwelve

How can I do it so there is a space left between eleven and twelve ?

Custom sanitizer :) [updated]

# models/custom_sanitizer.rb

class CustomSanitizer  
  def do(html, *conditions)
    document = HTML::Document.new(html)    
    export = ActiveSupport::SafeBuffer.new # or just String
    parse(document.root) do |node|
      if node.is_a?(HTML::Text)
        if node.parent.is_a?(HTML::Tag) && match(node.parent, conditions) && export.present?
          export << " "
        end
        export << node.to_s
      end
    end
    export
  end

  private

  def match(node, conditions = [])
    eval(conditions.map {|c| "node.match(#{c})"}.join(" || "))
  end

  def parse(node, &block)
    node.children.each do |node|
      yield node if block_given?
      if node.is_a?(HTML::Tag)
        parse(node, &block)
      end
    end
  end

end

# Helper

def custom_sanitize(*args)
  CustomSanitizer.new.do(*args)
end

Basic usage:

custom_sanitize(html, conditions)
# where conditions is a hash or hashes like {:tag => "p", :attributes => {:class => "new_line"}}

Your example:

html = "<p>one two three four five six seven eight nine then eleven</p><p>twelve thirteen</p>"
custom_sanitize(html, :tag => "p")
#=> "one two three four five six seven eight nine then eleven twelve thirteen"

Example of multiple conditions:

custom_sanitize(html, {:tag => "p"}, {:tag => "div", :attributes => {:class => "title"})

=========

For models [simple version]

Including helper into helper file you just open it for ActionView environment. If you want to use this method within AR models, you should include it into ActiveRecord::Base before Rails has been loaded. But much easily just use CustomSanitizer class directly:

class Post < ActiveRecord::Base

  def no_html_content
    CustomSanitizer.new.do(content, :tag => "p")
  end

end

# Post.find(1).no_html_content

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM