ruby हैश से मानों के साथ एक ERB टेम्पलेट रेंडर करें




template-engine (6)

मैं यहाँ बहुत सरल कुछ देख रहा हूँ, लेकिन मुझे यह पता नहीं लग सकता है कि हैश-मैप से मानों के साथ एक साधारण ईआरबी टेम्पलेट कैसे प्रस्तुत किया जाए।

मैं रूबी से अपेक्षाकृत नया हूं, अजगर से आ रहा हूं। मेरे पास एक ERB टेम्प्लेट है (HTML नहीं), जिसे मुझे संदर्भ के साथ प्रस्तुत करना होगा जो कि हैश-मैप से लिया जाना है, जो मुझे एक बाहरी स्रोत से प्राप्त होता है।

हालाँकि, ERB का दस्तावेज़ीकरण बताता है कि ERB.result विधि एक binding लेती है। मैंने सीखा है कि वे कुछ ऐसे हैं जो माणिक में चर संदर्भों को पकड़ते हैं globals() अजगर की तरह कुछ locals() और globals() अजगर, मैं मान लेता हूं?)। लेकिन, मुझे नहीं पता कि मैं अपने हैश-मैप से एक बाध्यकारी वस्तु कैसे बना सकता हूं।

थोड़ा ( बहुत , वास्तव में) googling ने मुझे यह दिया: http://refactormycode.com/codes/281-given-a-hash-of-variables-render-an-erb-template , जो अपने रूबी मेटाप्रोग्रामिंग जादू का उपयोग करता है कि मुझसे बच जाता है।

तो, क्या इस समस्या का सरल समाधान नहीं है? या क्या इसके लिए बेहतर अनुकूल (बेहतर HTML से बंधा हुआ) इंजन नहीं है? (मैंने केवल ईआरबी को चुना क्योंकि stdlib में)।


मुझे नहीं पता कि यह "अधिक सुरुचिपूर्ण" के रूप में योग्य है या नहीं:

require 'erb'
require 'ostruct'

class ErbalT < OpenStruct
  def render(template)
    ERB.new(template).result(binding)
  end
end

et = ErbalT.new({ :first => 'Mislav', 'last' => 'Marohnic' })
puts et.render('Name: <%= first %> <%= last %>')

या एक वर्ग विधि से:

class ErbalT < OpenStruct
  def self.render_from_hash(t, h)
    ErbalT.new(h).render(t)
  end

  def render(template)
    ERB.new(template).result(binding)
  end
end

template = 'Name: <%= first %> <%= last %>'
vars = { :first => 'Mislav', 'last' => 'Marohnic' }
puts ErbalT::render_from_hash(template, vars)

(ErbalT में Erb, T टेम्प्लेट के लिए है, और "हर्बल टी" की तरह लगता है। नामकरण कठिन है।)


यदि आप बहुत सरलता से काम करना चाहते हैं, तो आप हमेशा ERB टेम्पलेट के अंदर स्पष्ट हैश लुकअप का उपयोग कर सकते हैं। मान लें कि आप "हैश" नामक हैश वैरिएबल को टेंपलेट में पास करने के लिए "बाइंडिंग" का उपयोग करते हैं, यह इस तरह दिखेगा:

<%= hash["key"] %>

रूबी 2.5 में ERB#result_with_hash जो यह कार्यक्षमता प्रदान करता है:

$ ruby -rerb -e 'p ERB.new("Hi <%= name %>").result_with_hash(name: "Tom")'
"Hi Tom"

require 'erb'
require 'ostruct'

def erb(template, vars)
  ERB.new(template).result(OpenStruct.new(vars).instance_eval { binding })
end

जैसे

1.9.2p290 :008 > erb("Hey, <%= first_name %> <%= last_name %>", :first_name => "James", :last_name => "Moriarty")
 => "Hey, James Moriarty" 

Binding का उपयोग करते हुए सरल समाधान:

b = binding
b.local_variable_set(:a, 'a')
b.local_variable_set(:b, 'b')
ERB.new(template).result(b)

यहाँ मुश्किल हिस्सा बेमानी स्थानीय चर के साथ बाध्यकारी को प्रदूषित नहीं करना है (जैसे कि टॉप-रेटेड उत्तर में):

require 'erb'

class TemplateRenderer
  def self.empty_binding
    binding
  end

  def self.render(template_content, locals = {})
    b = empty_binding
    locals.each { |k, v| b.local_variable_set(k, v) }

    # puts b.local_variable_defined?(:template_content) #=> false

    ERB.new(template_content).result(b)
  end
end

# use it
TemplateRenderer.render('<%= x %> <%= y %>', x: 1, y: 2) #=> "1 2"

# use it 2: read template from file
TemplateRenderer.render(File.read('my_template.erb'), x: 1, y: 2)




template-engine