包括串的内部ERB的分隔符在块ERB(Include ERB delimiters inside o

2019-07-03 14:49发布

我的工作风格指南,显示代码,以及输出。 这是目前的结构,这样的代码只需要进行一次说明,并同时显示在其原始和解释的版本,像这样:

<% code = <<PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
<div>
  #{ image_tag 'image.png' }
</div>  
PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
%>

<%= raw code %>
<%= content_tag :pre, code, class: "prettyprint linenums" %>

这是伟大的,很容易维护。 这个问题是在与轨道帮手,就像image_tag在上面的例子。 视图例如在一个div正确地显示图像,以及将码示例显示相关HTML。 在这种情况下,相关的HTML包括一个锚标记-的结果image_tag方法,而不是调用本身。

我宁愿代码示例显示辅助方法,而他们的结果。 我能够通过指定一个文件中的示例代码,使这项工作,并且或者渲染或读取文件。 我宁愿通过指定代码中的变量,如上述,使这项工作,但我似乎无法得到一个ERB分隔为一个字符串的内部工作的ERB块内。 甚至最简单的情况下<% foo = '<%= bar %>' %>不工作的。 我试着用语法(打<%% %%>% %为例),从使用细节官方文档 ,但没有成功。

我能找到的关于此事的信息只有在这里 ,使用<%= "<" + "%=" %> link_to <%= image.css_tag.humanize %> <%= "%" + ">" %> %> ,这并不在这个用例的工作(如果有的话)。

那么,有没有指定包含ERB结束分隔符(字符串的方式%>在ERB字符串),还是我坚持使用略微笨重的文件读取方法? 谢谢!

编辑:

我想直到结束就是一个工作版本:

<%# Idealized code - does not work %>
<% code = <<PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
<div>
  <% image_tag 'image.png' %>
</div>  
PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
%>

使得<%= raw code %>将(继续)输出:

<div>
  <img src="/images/image.png" alt="Image" />
</div>

<%= content_tag :pre, code, class: "prettyprint linenums" %>将输出:

<pre class="prettyprint linenums">
  <div>
    <% image_tag 'image.png' %>
  </div>  
</pre>

而不是使用一个变量,这是当它目前并:

<pre class="prettyprint linenums">
  <div>
    <img src="/images/image.png" alt="Image" />
  </div>
</pre>

我希望用户能够复制的代码示例并将其粘贴到一个新的视图,而不必回到转化成HTML产生它们的帮手。 我想我主要需要的是另一种ERB分隔符,以同样的方式, '" (甚至%q{}会发生变化的字符串。如此看来,即使最终ERB分隔符字符串里出现的,它是而实际处理作为块的结束。最简单的情况下<% foo = '<%= bar %>' %>演示有些我想要完成的任务。在一个发电机,可以使用<% foo = '<%%= bar %>' %> (或类似的东西),告诉它不处理作为ERB,然后有。这一切都从文件读取时能正常工作,甚至在纯RB文件(如助手)但它最有意义把它的观点,在这种情况下,因为它是要由我们的设计师很容易被操纵。

Answer 1:

如果我理解你的权利,你真正的问题是,here文档表现得像双引号,只要插而言。 因此,所有你需要的是一个行为像单引号引用机制。 Ruby有很多的字符串引用机制,特别是我们有%q{...}

<% code = %q{
<div>
  #{ image_tag 'image.png' }
</div>  
} %>

您可以使用其他分隔符,如果你想: %q|...|%q(...)等目前仍然课程的变化,但至少你不用担心插问题。

如果你真的想用一个定界符,你可以指定用引号定界符终止以及相应的引用样式将应用于内容:

<% code = <<'PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR'
<div>
  #{ image_tag 'image.png' }
</div>  
PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
%>

在单引号<<'PLACE...'指定单引号规则(即无插值),适用于定界符的内容。


当然,没有这些东西将与嵌入式ERB这样的工作:

<% code = %q{
<div>
  <% ... %>
</div>  
} %>

因为ERB解析器将看到第一%>作为结束分隔符用于外<% code...的一部分。 不要害怕,我想我有一个计划,将不涉及总值(GDP)黑客或工作太多工作。

一些准备工作

  • Rails使用Erubis再培训局处理。
  • Erubis让您与改变分隔符:pattern选择给它的构造。
  • Rails使用倾斜和链轮处理模板处理流水线,这些让你做出正确的事情发生pancakes.js.coffee.erb正确的顺序。

使用上面你可以添加你自己的模板格式,再培训局有不同的分隔符,你可以有Rails的使用这种新的格式来处理你的“特殊”节之前的正常再培训局处理可以让乱七八糟的东西。

首先,你需要连接倾斜。 如果你看一下lib/tilt/erb.rb在倾斜安装,你会看到在Erubis东西Tilt::ErubisTemplate在底部。 你应该能够继承Tilt::ErubisTemplate ,并提供一个prepare覆盖,增加了,说, :pattern => '<!--% %-->'选项,平底船超类。 然后在Rails初始化像这样的东西倾斜和链轮注册此:

Tilt.register(Your::Template::Subclass, 'klerb') # "kl" for "kludge" :)
Rails.application.assets.register_engine('.klerb', Your::Template::Subclass)

现在,您的应用程序应该能够处理.klerb与文件<!--% ... %-->为模板分隔符。 而且你还可以链使用类似名称ERB你klerb pancakes.html.erb.klerb和文件会经过klerb该局之前; 这意味着,像这样的模板(在一个名为whatever.html.erb.klerb ):

<!--% code = <<PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
<div>
  <% image_tag 'image.png' %>
</div>  
PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
%-->
<!--%= "code = escape_the_erb_as_needed(%q{#{code}})" %-->
<% do_normal_erb_stuff %>

会做正确的事。

你需要一个帮手来实现escape_the_erb_as_needed课程的功能; 一个小实验应该帮助你理清哪些需要逃避,以何种方式。

所有这一切看起来有点复杂,但它确实是非常直截了当。 我添加使用倾斜和链轮的自定义模板的加工步骤,它竟然是在年底相当简单; 搞清楚这简单的事做了一些工作,但我已经为你做的工作:

  1. Tilt::Template的子类,您可以通过捎带上得到这个Tilt::ErubisTemplate
  2. 通过调用倾斜注册Tilt.register
  3. 通过调用链轮注册Rails.application.assets.register_engine
  4. ...
  5. 利润。


文章来源: Include ERB delimiters inside of a string in an ERB block