ruby-on-rails - 完全转义多行 erb 段

标签 ruby-on-rails ruby ruby-on-rails-3 html

我正在尝试创建一个简单的部分,它允许我显示代码块,而无需在我的代码中经历奇怪的扭曲。

所以我在部分中这样做了:

<% lang ||= "" %>
<% language = "lang='#{lang}'" %>

<div class="codebox">
        <% if title %>
            <h3><%= title %></h3>
        <% end %>
    <pre <%= language %>><%=text.unindent%></pre>
</div>

这在 lib 中用于取消缩进字符串(感谢非常好的 SO 建议):

class String
    def unindent; gsub(/^#{scan(/^\s+/).min}/, "") end
end

然后,我可以这样做,得到一个非常漂亮的小代码框:

<%= render partial: 'pre', locals: { title: "example.html", lang: 'html', text: "
                <div class='cl' style='text-align:center'>
                  <div class='collapse-group'>
                        <!-- Title, always viewable --> 
                        <a class='bundle' href='#'>'Click here to expand'</a> 
                    <div class='collapse'>
                        <!-- The content to be hidden or shown -->
                    </div> 
                  </div>
                </div>
                "} %>

这变成了:

enter image description here

工作起来就像一个魅力,除非我放入一堆 erb,在这种情况下它会发疯并开始到处出错。错误产生者的例子(内容不是 super 相关。我确保其中的所有引号都是双引号,而“字符串”是单引号):

<%= render partial: 'pre', locals: { title: "example.html", lang: 'html', text: '
                <% sub ||= "" %>
                <% term ||= "(expand)" %>
                <% style ||= "" %>

                <div class="cl" style="text-align:center">
                <div class="collapse-group">
                    <<%=tag%> class="squeeze" style=<%="#{style}"%>> 
                        <%=title%> 
                        <% if sub != "" %> 
                            <small><%= sub %></small>
                        <% end %>
                        <a class="bundle" href="#"><%= term %></a> 
                    </<%=tag%>>
                <div class="collapse">
                ' } %>

我可以通过任何方式告诉 html 我在这些引号中放入的内容是 100% 的文字字符?我已经尝试过单独转义“>”s 和“>”s 和“%”s 等等,但这是一条困惑(且无效)的路径,我希望不要走下去。

我希望上面的内容的 EX:

enter image description here

最佳答案

我认为一个不错的方法是使用 #capture ,例如在帮助器中(未经测试,只是暗示该做什么):

def code_block( title = nil, lang = nil, &block )
  output = capture( &block ) # this is the answer to all your problems
  output = output.unindent   # optional, escape it as you want, too
  # rendering a partial is still possible, 
  # but i'd recommend using an absolute path : 
  render partial: 'my_html_bits/code_block', 
         locals:  {title: title, lang: lang, text: output }
end

那么你可以这样做:

<%= code_block( 'example.html', 'html' ) do %>
  <%# whatever code here will be captured %>
  <p>Even plain old html.</p>
<% end %>

作为旁注:

  • 您的#unindent 方法或多或少模仿了String 上现有的ActiveSupport monkey-patch,#strip_heredoc
  • 在这些情况下,使用 #content_tag还可以为您省去很多麻烦,即:

    <<%=tag%> class="squeeze" style=<%="#{style}"%>>
    # more code...
    

    可以变成:

    <%= content_tag tag, class: 'squeeze', style: style do %>
    # more code...
    

关于ruby-on-rails - 完全转义多行 erb 段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14720724/

相关文章:

ruby-on-rails - 何时跳过 verify_authenticity_token

ruby-on-rails-3 - 为什么这个 'validate' 方法会引发 ArgumentError?

ruby-on-rails-3 - Rails 3 邮件不工作,但设计邮件工作

ruby-on-rails - Capybara/Poltergeist 无法到达服务器(连接被拒绝+ GET '/identify')

ruby-on-rails - 在 Ubuntu 12.04 上使用 rvm 安装 Ruby on Rails

ruby-on-rails - 在 Rails 中获取 session 数据

ruby - RubyMotion 要求 'motion-cocoapods' 时出错

ruby-on-rails - Devise 和 Cancancan - 如何让它发挥作用?

ruby-on-rails - 使用 Ruby 一次处理数组的 X 个元素的选项

ruby - 使用 RSpec 测试 ActionMailer 多部分电子邮件(文本和 html 版本)