我有一个Haml模板,周围散布着一堆“自定义标签”,例如{{REPLACE_ME}}
。在渲染此模板之前,我将浏览模板并使用Ruby的String#gsub
替换所有实例。
这不是问题 - 我只是简单地创建了一个自定义模板处理程序,它首先通过修改模板源然后将其传递给Haml模板处理程序充当中间人。
对于视图中每个“自定义标签”的出现,它会添加到存储在后台的分子中。然而,我所面临的问题是分子正在被提升,因为内容永远不会向用户显示,例如<% if false %>{{SECTION_NO}}<% end %>
。
在替换内容之前,应该过滤掉上述内容。然而,我似乎碰到了墙,因为Haml(和ERB)处理程序返回内容缓冲区而不是“结束/完成”内容。
这个问题是否有直接的解决方案?
以下是一个视图示例:
- if true
%h1 {{SECTION_NO}}
- if false
%h1 {{SECTION_NO}}
- if true
%h1 {{SECTION_NO}}
所以基本上,在替换和计算“{{SECTION_NO}}”的出现之前,我需要一种方法来过滤掉视图源的中间(错误语句)。
作为参考,这是我为此目的创建的模板处理程序的要点:
class ActionView::Template::Handlers::Caml
def initialize
@section = 0
@paragraph = 0
@references = {}
end
def call(template)
rendered_haml = ActionView::Template.registered_template_handler(:haml).call(template)
updated_source = render_sections(rendered_haml)
updated_source = render_paragraphs(updated_source)
updated_source = render_references(updated_source)
return ActionView::Template.new(
updated_source,
template.identifier,
template.handler,
{
locals: template.locals,
virtual_path: template.virtual_path,
updated_at: template.updated_at
}
)
end
private
def render_sections(source)
source.gsub(/{{section:([a-zA-Z0-9-_]+)}}/).each do |match|
fail 'Key already exists.' if @references.key?($1)
@section += 1
@references[$1] = "#{@section}"
"#{@section}"
end
end
def render_paragraphs(source)
# ...
end
def render_references(source)
source.gsub(/{{([a-zA-Z0-9-_]+)}}/).each do |match|
@references.fetch($1)
end
end
end
ActionView::Template.register_template_handler(
:caml,
ActionView::Template::Handlers::Caml.new
)