How would I use sanitize, but tell it to disallow some enabled by default tags? The documentation states that I can put this in my application.rb
config.after_initialize do
ActionView::Base.sanitized_allowed_tags.delete 'div'
end
Can I instead pass this as an argument to sanitize?
Yes you can specify which tags and attributes to allow on a per-call basis. From the fine manual:
Custom Use (only the mentioned tags and attributes are allowed, nothing else)
<%= sanitize @article.body, :tags => %w(table tr td), :attributes => %w(id class style) %>
But the problem with that is that :tags
has to include all the tags you want to allow.
The sanitize
documentation says to
See ActionView::Base for full docs on the available options.
but the documentation is a lie, ActionView::Base
says nothing about the available options.
So, as usual, we have to go digging through the source and hope they don't silently change the interface. Tracing through the code a bit yields this:
def tokenize(text, options)
options[:parent] = []
options[:attributes] ||= allowed_attributes
options[:tags] ||= allowed_tags
super
end
def process_node(node, result, options)
result << case node
when HTML::Tag
if node.closing == :close
options[:parent].shift
else
options[:parent].unshift node.name
end
process_attributes_for node, options
options[:tags].include?(node.name) ? node : nil
else
bad_tags.include?(options[:parent].first) ? nil : node.to_s.gsub(/</, "<")
end
end
The default value for options[:tags]
in tokenize
and the way options[:tags]
is used in process_node
are of interest and tell us that if options[:tags]
has anything then it has to include the entire set of allowed tags and there aren't any other options for controlling the tag set.
Also, if we look at sanitize_helper.rb
, we see that sanitized_allowed_tags
is just a wrapper for the allowed_tags
in the whitelist sanitizer:
def sanitized_allowed_tags
white_list_sanitizer.allowed_tags
end
You should be able to add your own helper that does something like this (untested off-the-top-of-my-head code):
def sensible_sanitize(html, options)
if options.include? :not_tags
options[:tags] = ActionView::Base.sanitized_allowed_tags - options[:not_tags]
end
sanitize html, options
end
and then you could
<%= sensible_sanitize @stuff, :not_tags => [ 'div' ] %>
to use the standard default tags except for <div>
.