Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I find the path of a template file using ERB?

Tags:

ruby

erb

I am using embedded ruby (ERB) to generating text files. I need to know the directory of the template file in order to locate another file relative to the template file path. Is there a simple method from within ERB that will give me the file name and directory of the current template file?

I'm looking for something similar to __FILE__, but giving the template file instead of (erb).

like image 722
Neal Kruis Avatar asked Sep 05 '12 23:09

Neal Kruis


People also ask

What is an ERB template?

An ERB template looks like a plain-text document interspersed with tags containing Ruby code. When evaluated, this tagged code can modify text in the template. Puppet passes data to templates via special objects and variables, which you can use in the tagged Ruby code to control the templates' output.

How do ERB files work?

An ERB object works by building a chunk of Ruby code that will output the completed template when run. If safe_level is set to a non-nil value, ERB code will be run in a separate thread with $SAFE set to the provided level. eoutvar can be used to set the name of the variable ERB will build up its output in.

How do I open ERB files?

To open an ERB file in Braille Music Reader, select File → Open, navigate to your file, and click Open.


1 Answers

When you use the ERB api from Ruby, you provide a string to ERB.new, so there isn’t really any way for ERB to know where that file came from. You can however tell the object which file it came from using the filename attribute:

t = ERB.new(File.read('my_template.erb')
t.filename = 'my_template.erb'

Now you can use __FILE__ in my_template.erb and it will refer to the name of the file. (This is what the erb executable does, which is why __FILE__ works in ERB files that you run from the command line).

To make this a bit a bit more useful, you could monkey patch ERB with a new method to read from a file and set the filename:

require 'erb'

class ERB
  # these args are the args for ERB.new, which we pass through
  # after reading the file into a string
  def self.from_file(file, safe_level=nil, trim_mode=nil, eoutvar='_erbout')
    t = new(File.read(file), safe_level, trim_mode, eoutvar)
    t.filename = file
    t
  end
end

You can now use this method to read ERB files, and __FILE__ should work in them, and refer to the actual file and not just (erb):

t = ERB.from_file 'my_template.erb'
puts t.result
like image 68
matt Avatar answered Nov 03 '22 02:11

matt