More on passing parameters to erb in Cuba

624 Views Asked by At

The answers for Sinatra seem to not apply exactly to Cuba. I want to pass in a parameter from a ruby environment to an erb in Cuba. This is a simplified test for passing in, from the routing environment, what will be an array of objects in the final code.

This simplified sample consists in parametrically defining 'color' to be "red", but if it not set to anything, then internally it is then set to green. The target code would need to bail out if the parameter were not set. As currently set, samp1 successfully renders the erb file, but it is green. The question resolves into: How must I change samp1 (or any of the samp-n's) within app2.rb in order to set 'color' within sample.erb to red? Hopefully, I can abstract the answer to use globally for my purpose. Note the other samp-n's are other failed tries.

Very Many Thanks for any help.

Files:

app2.rb:

require 'cuba' 
require 'erb' 
require 'cuba/render' 
require 'tilt/erubis'

Cuba.plugin Cuba::Render
Cuba.define do

# only GET requests   on get do

  # /samp1    
  on "samp1" do
    res.write render('sample.erb')
  end

  # /samp2
  on "samp2" do
    ns = OpenStruct.new(color: 'red')
    template = File.read('./sample.erb')
    res.write render(template).result(ns.instance_eval {binding})
  end

  # /samp3
  on "samp3" do
    ns = OpenStruct.new(color: 'red')
    template = File.read('./sample.erb')
    res.write erb(template).result(ns.instance_eval {binding})
  end

  # /samp4
  on "samp4" do
    locals = {}
    locals["color"]="red"
    res.write render('sample.erb',locals)
  end

  # /Cuba
  on Cuba do
     res.write "hello, Cuba!"
  end   end end

And the following config.ru:

require './app2'

run Cuba

Lastly, the erb file, sample.erb:

<% 
   color = ARGV[0]
   color = "green" if color.nil?
%>   

<html>
  <head>
    <title>Square</title>
  </head>
  <body>
    <h1>Square</h1>

    <svg width="700" height="500"
       xmlns="http://www.w3.org/2000/svg" version="1.1">
      <desc>Sample Board</desc>

      <style type="text/css"> <![CDATA[
    rect.a {stroke:black; fill:<%=color%>}]]>
      </style>

      <rect class="a" x="100" y="50" width="200" height="200" stroke_width="10"/>
    </svg>
  </body>
</html>

End of files

3

There are 3 best solutions below

0
Daniel B. Davis On

I finally succeeded in making it work. Within file app2.rb, I changed samp2 as follows:

# /samp2
on "samp2" do
  res.write render('sample.erb', color: 'red', wid: '400')
end

This changed both the color and the width. But I also needed to edit 'sample.erb' as follows:

  1. Remove all <% .. %> material above
  2. Leave <:=color%> as is.
  3. Change ...width="200"... to ...width='<%=wid%>'...

I added width to make sure that the solution generalized well, and it did. This suggests that any object or set of objects may be passed in to the erb from Ruby.

1
Daniel B. Davis On

In the answer above there is an error at 1. It should read: "Remove all material above the html tag between the <%= and %>", but when I entered the answer I used the bracketed tag.

0
danizen On

Look at lib/cuba/render.rb and the signature of the render function:

def render(template, locals = {}, options = {}, &block)
    ...
end

So, if you just give a hash in your call, it will be locals:

res.write render("views/hello.erb", :foo => bar, ...)

You can also make it explicit:

res.write render("views/hello.erb", { :foo => bar, ... }, options_hash)

See a working example at http://github.com/danizen/cuba-erb-hello