如果您查看以下输出的代码erb -x -T - test.erb
:
#coding:ASCII-8BIT
_erbout = ''; _erbout.concat "<div class='row'>\n "
; _erbout.concat(( form.field_container :name do ).to_s); _erbout.concat "\n"
; _erbout.concat " "; _erbout.concat(( form.label :name, raw('Name' + content_tag(:span, ' *', :class => 'required')) ).to_s); _erbout.concat "\n"
; _erbout.concat " "; _erbout.concat(( form.text_field :name, :class => 'fullwidth' ).to_s); _erbout.concat "\n"
; _erbout.concat " "; _erbout.concat(( form.error_message_on :name ).to_s); _erbout.concat "\n"
; _erbout.concat " "; end ; _erbout.concat "\n"
; _erbout.concat "</div>\n"
; _erbout.force_encoding(__ENCODING__)
您可以在第三行看到, ado
后跟 a )
。Ruby 期待do
...<code>end 块,但得到一个右括号。这是语法错误的直接原因。
erb
输出错误代码的原因是您<%=
在应该使用<%
. 将代码更改为此可以修复语法错误:
<div class='row'>
<% form.field_container :name do %>
<%= form.label :name, raw('Name' + content_tag(:span, ' *', :class => 'required')) %>
<%= form.text_field :name, :class => 'fullwidth' %>
<%= form.error_message_on :name %>
<% end %>
</div>
我无法运行此代码来测试它是否在我更改后输出它应该输出的内容,但生成的代码erb
看起来会起作用:
#coding:ASCII-8BIT
_erbout = ''; _erbout.concat "<div class='row'>\n "
; form.field_container :name do ; _erbout.concat "\n"
; _erbout.concat " "; _erbout.concat(( form.label :name, raw('Name' + content_tag(:span, ' *', :class => 'required')) ).to_s); _erbout.concat "\n"
# more...
编辑
由于该解决方案显然会破坏输出,因此我研究了建议的 mu 太短。我检查了Rails 3 默认使用的Erubis的行为是否与 ERB 不同。由(原始,未经编辑)输出的代码:erubis -x -T - test.erb
test.erb
_buf = ''; _buf << '<div class=\'row\'>
'; _buf << ( form.field_container :name do ).to_s; _buf << '
'; _buf << ' '; _buf << ( form.label :name, raw('Name' + content_tag(:span, ' *', :class => 'required')) ).to_s; _buf << '
'; _buf << ' '; _buf << ( form.text_field :name, :class => 'fullwidth' ).to_s; _buf << '
'; _buf << ' '; _buf << ( form.error_message_on :name ).to_s; _buf << '
'; end
_buf << '</div>
';
_buf.to_s
第三行有完全相同的问题,并erubis -x -T - test.erb | ruby -c
输出相同的语法错误。因此,ERB 和 Erubis 之间的差异可能不是问题所在。
我还尝试对 Rails 官方文档中的这段代码进行语法检查:
<%= form_for(zone) do |f| %>
<p>
<b>Zone name</b><br />
<%= f.text_field :name %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
它得到相同的语法错误。因此,并不是您的 ERB 代码写得不好。您的代码与该示例非常相似。
在这一点上,我最好的猜测是erb
's-x
标志,它将 ERB 模板转换为 Ruby 代码而不是直接评估它,是有缺陷的,并且不支持它应该支持的某些功能。虽然现在我想了想,但当你输出一个本身输出文本的块的结果时,我很难想象究竟应该输出什么 Ruby 代码。每个输出应该在什么时候被写入——首先是结果,还是首先写入块内容?