Ruby templates: How to pass variables into inlined ERB?

前端 未结 10 1712
陌清茗
陌清茗 2020-11-30 21:18

I have an ERB template inlined into Ruby code:

require \'erb\'

DATA = {
    :a => \"HELLO\",
    :b => \"WORLD\",
}

template = ERB.new <<-EOF
          


        
相关标签:
10条回答
  • 2020-11-30 21:59

    As others said, to evaluate ERB with some set of variables, you need a proper binding. There are some solutions with defining classes and methods but I think simplest and giving most control and safest is to generate a clean binding and use it to parse the ERB. Here's my take on it (ruby 2.2.x):

    module B
      def self.clean_binding
        binding
      end
    
      def self.binding_from_hash(**vars)
        b = self.clean_binding
        vars.each do |k, v|
          b.local_variable_set k.to_sym, v
        end
        return b
      end
    end
    my_nice_binding = B.binding_from_hash(a: 5, **other_opts)
    result = ERB.new(template).result(my_nice_binding)
    

    I think with eval and without ** same can be made working with older ruby than 2.1

    0 讨论(0)
  • 2020-11-30 22:08

    Got it!

    I create a bindings class

    class BindMe
        def initialize(key,val)
            @key=key
            @val=val
        end
        def get_binding
            return binding()
        end
    end
    

    and pass an instance to ERB

    dataHash.keys.each do |current|
        key = current.to_s
        val = dataHash[key]
    
        # here, I pass the bindings instance to ERB
        bindMe = BindMe.new(key,val)
    
        result = template.result(bindMe.get_binding)
    
        # unnecessary code goes here
    end
    

    The .erb template file looks like this:

    Key: <%= @key %>
    
    0 讨论(0)
  • 2020-11-30 22:08

    In the code from original question, just replace

    result = template.result
    

    with

    result = template.result(binding)
    

    That will use the each block's context rather than the top-level context.

    (Just extracted the comment by @sciurus as answer because it's the shortest and most correct one.)

    0 讨论(0)
  • 2020-11-30 22:08

    This article explains this nicely.

    http://www.garethrees.co.uk/2014/01/12/create-a-template-rendering-class-with-erb/

    0 讨论(0)
提交回复
热议问题