在jinja2中,我可以在宏中指定经常使用的模板代码,基本上就像模板函数一样:
{% macro input(name, value='', type='text', size=20) -%}
<input type="{{ type }}" name="{{ name }}" value="{{value|e }}" size="{{ size }}">
{%- endmacro %}
然后像这样使用它:
{% input("hello") %}
有没有办法用erb模板完成类似的事情?
提前致谢!
答案 0 :(得分: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
当您使用闭包时,会捕获环境,包括局部变量,因此您可以编写它。