jinja2中的等价宏是什么?

时间:2012-06-13 01:11:14

标签: ruby sinatra erb jinja2

在jinja2中,我可以在宏中指定经常使用的模板代码,基本上就像模板函数一样:

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

然后像这样使用它:

{% input("hello") %}

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

提前致谢!

1 个答案:

答案 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当您使用闭包时,会捕获环境,包括局部变量,因此您可以编写它。