Passing binding or arguments to ERB from the command line - ruby

I have been playing around with erb from the command line recently. I wanted to make a dirt simple erb template, for example the following:
<%- name = "Joe"; quality = "fantastic" -%>
Hello. My name is <%= name %>. I hope your day is <%= quality %>.
This works if I run
erb -T - thatfile.erb
what I want to do is to make name and quality be passable from command line arguments, so that I could do something like:
./thatfile.erb "Bill" "super"
from the bash prompt and do the same thing.
I am aware that I could write a ruby script that would just read that template in and then use ERB.new(File.read("thatfile.erb")).result(binding), or writing the template after an END and doing likewise, but I'm looking for a more lightweight approach if it exists, because I don't want to write two files for each erb script that I create for this purpose.

Alternatively, you can use a ruby script and load it in as a library.
# vars.rb
#hello = 'kirk'
# template.html.erb
<div><%= #hello %></div>
$ erb -r './vars' template.html.erb

Please note that Ruby 2.2 and newer provide a much nicer solution that was implemented according to this:
erb var1=val1 var2=val2 my-template.erb

I went with the BASH command-line shortcut for environmental variables.
Outside:
STUFF=foo,bar erb input.html.erb >output.html
Inside:
<%
stuff = ENV['STUFF'].split(',')
%>
After a few minutes e-searching I determined the other solutions are all variations on "write the erb wrapper command yourself." Could be wrong, but I ain't going back.

If you are using unix, try following:
$ cat 1.erb
Hello. My name is <%= name %>. I hope your day is <%= quality %>.
$ (echo '<% name="Joe"; quality="fantastic" %>' && cat 1.erb) | erb
Hello. My name is Joe. I hope your day is fantastic.

Related

loop over hash in defined order in ruby template

I have a ruby template (.erb) that I want to iterate over a hash. It should produce the same output file each time the puppet agent runs.
What I currently have is the following. This is my template (part of rsyslog config if anyone is wondering):
<% log_files.each do |log_file, tag| -%>
# <%= log_file %>
$InputFileName <%= log_file %>
$InputFileTag <%= tag %>:
This template is rendered with a hash that looks like this:
log_files => {
'/root/apache_auth.local' => 'httpd',
'/root/install.log' => 'hugo',
},
(Not real logfiles). This works and produces the config file I want. The problem with this is that each time I call the puppet agent, the order of the log files in the hash is changed, so the config file gets rewritten, and subsequently the daemon gets restarted. The functionality stays the same, but I would rather not have the config file rewritten and rsyslog restarted each time the puppet agent runs.
Now I assume that this is unsolvable with hashes, as their nature is that they do not have a defined order. What other options do I have to achieve what I want?
Since the scriptlets inside an ERB template consist of Ruby code, this is essentially a Ruby question. The possible answers therefore depend on which version of Ruby is running underneath your Puppet catalog compiler. However, although there may be better alternatives in newer Ruby, this variation on your code will work in any Ruby supported by Puppet since Puppet 2.7:
<% #log_files.sort.each do |log_file, tag| -%>
# <%= log_file %>
$InputFileName <%= log_file %>
$InputFileTag <%= tag %>:
<% end -%>
The key here (no pun intended) is the sort.

Using Redcarpet Gem with .erb file

I am trying to pull up a markdown file from a database that I created. My server. rb file has the following:
get "/designers/:id" do
id = params[:id]
#content = conn.exec_params("SELECT * FROM articles_info WHERE id = $1",[id]).first
erb :raf
end
In that table is the following markdown information:
# **RAF SIMONS**
*THIS IS THE RAF SIMONS BIO* :blush:
*[Raf Link](http://rafsimons.com/)*
The .erb file works when I have plain text or the following in it:
<%= "#{#content["content"]}" %>
However it only prints the actual .md text as it is. So I have tried using Redcarpet to render the markdown file. The code is as follows in my .erb:
renderer = Redcarpet::Render::HTML.new
markdown = Redcarpet::Markdown.new(renderer)
<%= markdown.render(#content.content) %>
But I am getting the error:
ArgumentError at /designers/1
wrong number of arguments (0 for 1..3)
Which is stemming from the <%= line. I thought at first that the syntax was wrong, so I tried:
markdown.render <%= "#{#content["content"]} %>
However that did not change anything. I also tried adding in a method in the server.rb file, but that gave me more errors. I read through the entire documentation: https://github.com/vmg/redcarpet file but am not understanding where the error is coming from. Is it possible that I need extensions in order to make it work? I also tried:
markdown = Redcarpet::Markdown::new(renderer, extensions={})
But that didn't change anything. Not sure what else to try here! I know that it is tricky but I thought I had a handle on it and have now tried many different iterations and still am having trouble executing it. Any advice would be much appreciated!

.erb equivalent to the PHP $_GET["name"];

I have a page set up in PHP which pulls data from the URL and echos it in HTML. Is there a .erb Ruby equivalent to this?
<?php echo $_GET["name"];?>
Is this possible? Thanks!
In ERB, it looks like this:
<%= variable_name %>
If you want to perform some action without printing the result, you do this
<% #user.sign_up %>
Notice the difference being the =

undocumented ERB syntax: <%=h ... %>

http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/classes/ERB.html lists a set of Recognized Tags - however, this list seems incomplete; for one thing it's missing the dash variant (<%- ... -%>, which suppresses line breaks IIRC).
Now I've come across another seemingly undocumented variant:
<%=h some_variable %>
<%= link_to h(some_variable) ... %>
Google wouldn't tell me what that was all about; can anyone point me to an explanation?
It's not an ERB syntax. It is <%= ... %> and inside it is calling the ERB::Util.hmethod
h here is just a regular method, in fact it's an alias for html_escape.
http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/classes/ERB/Util.html#M000868

How do I execute ruby template files (ERB) without a web server from command line?

I need ERB (Ruby's templating system) for templating of non-HTML files.
(Instead, I want to use it for source files such as .java, .cs, ...)
How do I "execute" Ruby templates from command line?
You should have everything you need in your ruby/bin directory. On my (WinXP, Ruby 1.8.6) system, I have ruby/bin/erb.bat
erb.bat [switches] [inputfile]
-x print ruby script
-n print ruby script with line number
-v enable verbose mode
-d set $DEBUG to true
-r [library] load a library
-K [kcode] specify KANJI code-set
-S [safe_level] set $SAFE (0..4)
-T [trim_mode] specify trim_mode (0..2, -)
-P ignore lines which start with "%"
so erb your_erb_file.erb should write the result to STDOUT.
(EDIT: windows has erb.bat and just plain "erb". The .bat file is just a wrapper for erb, which I guess should make the same command work pretty much the same on any OS)
See the prag prog book discussion (starts about half-way down the page).
Note also that Jack Herrington wrote a whole book about code generation that uses Ruby/ERB.
Write a ruby script that does it. The API documentation is here:
http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/
For example:
template = ERB.new File.read("path/to/template.erb"), nil, "%"
template.result(binding)
(Where binding is a binding with the #vars that the template needs.)
Another option would be to use ruby -e, since ERB itslef is so simple.
Something like:
ruby -rerb -e "puts ERB.new(File.read(<file name here>)).result"
However, I assume you have a context you want to render the template in. How are you expecting to get that context? As an example, check out:
ruby -rerb -e "hello = 'hello'; puts ERB.new('<%= hello %> world').result(binding)"
which will print out "hello world", using the top-level, where you defined the hello variable, as the binding.
If you can switch ERB to Erubis, your problem solving is as simple as:
require 'erubis'
template = File.read("sample_file.erb")
template = Erubis::Eruby.new(template)
template.result(:your_variable => "sample")
Found this question while trying to test my Puppet templates.
Ended with this solution:
Along your foo.erb create a file foo.vars.erb
Put all your template variables into that new file, e.g.:
<% #my_param="foo bar" %>
<% #another_param=123 %>
or (equivalent):
<%
#my_param="foo bar"
#another_param=123
%>
On command line run this:
cat foo.vars.erb foo.erb | erb
Your fully rendered template should now be printed to std-out. From there you check the output by hand, or you can take diff (or other tools) to compare it to a pre-rendered output.
I tried to comment on this, but comments link not available.
I'm using this:
template = ERB.new File.new("path/to/template.erb").read, nil, "%"
template.result(binding)
From the posting above: and I found what I think it might be a problem:
I'm creating DOS BATCH files like:
%JAVA_HOME%\bin\jar -xvf <%=inputfile%>...
And I found weird thing problem - I get this when I run with the code above:
Processing Template test.txt
erb):2:in `render': compile error (SyntaxError)
erb):2: syntax error, unexpected tSTRING_BEG, expecting $end
erbout.concat "\n"
^
from DBUser.rb:49:in `render'
from DBUser.rb:43:in `each'
from DBUser.rb:43:in `render'
from DBUser.rb:81
I tried the following, and got round my particular problem - not sure if this is the right answer for everybody ...
template = ERB.new File.new("path/to/template.erb").read
template.result(binding)

Resources