2017-09-25 128 views
0

我的特殊用例是構建具有佔位符值的HTML電子郵件模板,這些模板稍後將替換爲實際數據。使用Nokogiri替換HTML佔位符標記

例子:

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

...變成 「你好,約翰的」 佔位符被替換時。

我有這些佔位符的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文檔,但我承認節點解析對我來說是非常新的,並且需要一些時間才能掌握術語。

是否有一個更高性能的方式來實現這一點,還是有更好的解決方案,我的問題,我不知道?

回答

1

基於您的方法的一些輸入。

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']]) 

看來你目前的做法是分別處理每個佔位符:可以通過散列placeholder_mappings不迭代,並基於密鑰,而不是獲取的價值做出一些改進。這可能是更快一氣呵成貫穿整個模板:

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

在這裏,我不是更換整個節點,因爲這使得迭代困難。相反,我只是替換內容,然後在最後刪除.placeholder以刪除CSS。

+0

我不敢相信我沒有想到只參考使用的映射!這應該更具性能,因爲大多數模板只能使用10個左右不同的佔位符。關於不刪除節點,問題是,如果我離開'span'標籤並僅刪除'class',電子郵件客戶端是否會在主題行中輸出原始字符串'hello '。 –