我的视图中有一个方法调用,如此
<%= Navigation.with(params) do |menu|
if current_user && current_user.can_verify?
menu.item("Listings", manage_listings_path())
menu.item("Listing changes", needing_change_approval_manage_listings_path())
menu.item("Flagged Items", flagged_manage_listings_path())
menu.item("Transfers", manage_listing_transfers_path())
menu.item("Reviews", manage_listing_reviews_path())
end
if current_user && current_user.admin?
menu.item("Log", manage_verifications_path())
menu.item("Indexer Compensations", manage_compensations_path())
menu.item("Users", manage_users_path())
end
end%>
分割出以下字符串
"<li><a href="/manage/listings" class="active">Listings</a></li> <li><a href="/manage/listings/needing_change_approval">Listing changes</a></li> <li><a href="/manage/listings/flagged">Flagged Items</a></li> <li><a href="/manage/listing_transfers">Transfers</a></li> <li><a href="/manage/listing_reviews">Reviews</a></li> <li><a href="/manage/verifications">Log</a></li> <li><a href="/manage/compensations">Indexer Compensations</a></li> <li><a href="/manage/users">Users</a></li>"
我只是在我的页面中获取此字符串。我希望它们是由CSS完美设计的菜单。我只是在我的页面中获取上述原始文本。如何通过浏览器将此字符串转换为HTML格式。
请帮忙
这是导航类
class NavigationMenu < ActionView::Base
def initialize(params)
@params = params
end
def item(title, path, options={})
@items ||= Array.new
unless (route = Rails.application.routes.recognize_path(path,:method => options[:method]|| :get))
raise "Unrecognised path #{path}, are you sure it's in routes.rb?"
end
@items << content_tag(:li, link_to(title,path, :class => (@params[:controller] == route[:controller] && @params[:action] == route[:action])? 'active' : nil))
end
def output
return '' if @items.blank?
content_tag(:ul, @items.join("\n"), :id => 'navigation')
end
end
class Navigation
def self.with(params, &block)
menu = NavigationMenu.new(params)
yield menu
menu.output
end
end
答案 0 :(得分:9)
您必须添加对raw
方法的调用:
<%= raw ... %>
这是必要的,因为在Rails 3中,默认情况下每个字符串都会被转义,除非您使用raw
方法。
它类似于Rails 2中h
方法的反转,默认情况下每个字符串都没有转义,除非你使用h
方法。
示例:强>
Rails 2中的代码......
<%= h "String which must be escaped" %>
<%= "String which must be output raw %>
...必须在Rails 3中使用:
<%= "String which must be escaped" %>
<%= raw "String which must be output raw %>
(虽然对h
的额外调用对Rails 3没有任何伤害)
答案 1 :(得分:4)
您需要将.html_safe
附加到字符串 - 这将阻止rails在输出文本时转义它。可能最好将它放在您重复调用的item
方法中。
答案 2 :(得分:1)
我最近在从Rails 2升级时写了一篇关于Rails 3中XSS保护的文章: http://developer.uservoice.com/entries/upgrading-to-rails-3-printing-escaped-strings
我们的想法是将代码挂钩到打印HTML,以便我们可以确定何时实际打印我们不想要的内容:
module ActionView
module Helpers
module TextHelper
def simple_format_with_double_escape_reporting(*args)
HtmlDoubleEscapeReporter.assert_sane(simple_format_without_double_escape_reporting(*args))
end
alias_method_chain :simple_format, :double_escape_reporting
end
module TagHelper
private
def content_tag_string_with_double_escape_reporting(*args)
HtmlDoubleEscapeReporter.assert_sane(content_tag_string_without_double_escape_reporting(*args))
end
alias_method_chain :content_tag_string, :double_escape_reporting
end
module UrlHelper
def link_to_with_double_escape_reporting(*args, &block)
HtmlDoubleEscapeReporter.assert_sane(link_to_without_double_escape_reporting(*args, &block))
end
alias_method_chain :link_to, :double_escape_reporting
end
end
end
方法HtmlDoubleEscapeReporter.assert_sane可以编写,例如,像这样:
class HtmlDoubleEscapeReporter
def self.assert_sane(str)
if (str.match(/<[a-z]/) || str.match(/&(quot|rarr|larr|amp|#)/)) &&
!str.match(/looks something you do not want to print/
send_problem_report('#{str}' looks something you do not want to print")
end
return str
end
end
在这里,“看起来你不想打印的东西”用于防止无限循环的可能性。 send_problem_report('#{str}'行看起来你不想打印的东西“)可以替换为调用”debugger“(来自ruby-debug gem),这样你就可以检查回溯并查看问题来自。
答案 3 :(得分:0)
这是新课程。最后......我得到了那个错误。
class NavigationMenu < ActionView::Base
def initialize(params)
@params = params
end
def item(title, path, options={})
@items ||= Array.new
unless (route = Rails.application.routes.recognize_path(path,:method => options[:method]|| :get))
raise "Unrecognised path #{path}, are you sure it's in routes.rb?"
end
@items << content_tag(:li, link_to(title,path, :class => (@params[:controller] == route[:controller] && @params[:action] == route[:action])? 'active' : nil))
end
def output
@items = @items.join("\n").html_safe
return '' if @items.blank?
content_tag(:ul, @items, :id => 'navigation')
end
end
class Navigation
def self.with(params, &block)
menu = NavigationMenu.new(params)
yield menu
menu.output
end
end