使用 Nokogiri 替换 HTML 占位符标签

Using Nokogiri to replace HTML placeholder tags

我的特定用例是构建 HTML 具有占位符值的电子邮件模板,这些值稍后会被真实数据替换。

示例:

hello <span class='placeholder' data-slug='contact.name'>contact.name</span>

...当占位符被替换时变为 "Hello John"。

我有 50 多个这样的占位符,我正在使用 Nokogiri 用实时数据替换占位符:

placeholder_mappings = {
  "contact.name" => @contact.name,
  "contact.email" => @contact.email,
  ...
}

text = "hello <span class='placeholder' data-slug='contact.name'>contact.name</span>"

page = Nokogiri::HTML(text)

placeholder_mappings.each do |key, value|
  page.css("[data-slug='#{key}']").each do |node|
    node.replace(value)
  end
end

page.to_html

我使用 HTML 标签而不是 {{contact.first_name}} 之类的标签的原因是我可以将 CSS 添加到占位符,这样用户在构建模板。否则,我只会使用 gsub 并使其变得简单 :)

我上面的代码有效,但似乎效率低下。我看过 Nokogiri 文档,但我承认节点解析对我来说是个新事物,我需要一些时间才能熟悉术语。

有没有更高效的方法来实现这个,或者有更好的解决我不知道的问题的方法?

一些基于您的方法的输入。您可以通过不遍历散列 placeholder_mappings 而是根据键获取值来进行一些改进:

  page.css('span.placeholder').each do |node|
    node.replace(@placeholder_mappings[node['data-slug']])
  end

或使用at_css

  node = page.at_css('span.placeholder')
  node.replace(@placeholder_mappings[node['data-slug']])

看来您目前的做法是分别处理每个占位符。一次性 运行 整个模板可能会更快:

  nodes = page.css('span.placeholder')
  nodes.each do |node|
    node.content = @placeholder_mappings[node['data-slug']]
  end
  nodes.remove_class("placeholder")

这里我不会替换整个节点,因为这会使迭代变得困难。相反,我只是替换内容,然后在最后删除 .placeholder 以删除 CSS.