Что такое 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?

Заранее спасибо!


person Steve Gattuso    schedule 13.06.2012    source источник


Ответы (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 Когда вы используете замыкания, захватывается среда, включая локальную переменную, поэтому вы можете затем писать в нее.

person Joshua Cheek    schedule 13.06.2012