0

在 jinja2 中,我可以在宏中指定常用的模板代码,本质上类似于模板函数:

{% macro input(name, value='', type='text', size=20) -%}
    <input type="{{ type }}" name="{{ name }}" value="{{value|e }}" size="{{ size }}">
{%- endmacro %}

然后像这样使用它:

{% input("hello") %}

有没有办法用 erb 模板完成类似的事情?

提前致谢!

4

1 回答 1

1

如果您使用 lambdas/procs 而不是方法,那么您可以:

require 'erb'

doc = <<ERB
<% input = lambda do |name, value='', type='text', size=20| %>
  <input type="<%= type %>" name="<%= name %>" value="<%= value || 'e' %>" size="<%= size %>">
<% end %>
<% input["hello"] %>
<% input["HELLO", 123, 'select', 50] %>
ERB

puts ERB.new(doc, 0, '>').result
# >>   <input type="text" name="hello" value="" size="20">
# >>   <input type="select" name="HELLO" value="123" size="50">

问题是 erb(和 erubis)通过解析文档并创建另一段代码来创建这些字符串,其中标签内部和外部的值被反转。然后标签之间的模板只是附加到一些局部变量。(实际上有一些方法可以解决这个问题,但你必须深入一些,我必须先扩展 erubis 才能获得我想要的替代行为)。当您创建方法时,会更改范围并且不再可以看到局部变量,因此它会给您一些模糊的错误NameError: undefined local variable or method ‘_erbout’ for main:Object当您使用闭包时,会捕获环境,包括局部变量,因此您可以写入它。

于 2012-06-13T03:50:50.773 回答