<%= %> Interpolation question

Is there a way to get a Rails view to interpolate inside <%= %>?
E.g. if foo = ‘<%= bar %>’ and bar = ‘2’,
to have some variant of <%= foo %> in app/views/whatever/
whatever.html.erb display ‘2’ rather than ‘<%= bar %>’?

Many TIA,
Craig

On Sat, 2010-02-27 at 07:08 -0800, Dudebot wrote:

Is there a way to get a Rails view to interpolate inside <%= %>?
E.g. if foo = ‘<%= bar %>’ and bar = ‘2’,
to have some variant of <%= foo %> in app/views/whatever/
whatever.html.erb display ‘2’ rather than ‘<%= bar %>’?


lots of ways… choose whatever is best for the situation…

<%= @foo == ‘bar’ ? “result 1” : “result 2” %>

or

<% if @foo == ‘bar’ -%>
<%= ‘result 1’ %>
<% else -%>
<%= ‘result 2’ %>
<% end -%>

Craig


This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.

Thanks, Craig–I think my example was too terse. What I’m trying to
do is to pass a block of text to a view which may contain multiple
references to external models, and I’d like to interpolate those
references.

So, for example, if @thing.body = " This is the id of foo: <%= @foo.id
%> and this is its body: <%= @foo.body %> "

If @foo.id = 2 and @foo.body = “Norman”, I’d like in the view
whatever.html.erb to have

<%= @thing.body %>

display

This is the id of foo: 2 and this is its body: Norman

Is there a way to do that? I also tried #{ … } and am still getting
the literal rather than the interpolation.

Many thanks,
Craig

OK, here’s what I have in app/views/molds/show.html.erb:

<%= @mold.body.gsub( "\n", "
" ) %>

The controller finds @patient, and @patient.id = 2

If @mold.body = “The patients id is <%= @patient.id %>”

Then the view displays

The patients id is <%= @patient.id %>

rather than

The patients id is 2

Same goes for replacing <%= with #{ and %> with }

Many TIA,
Craig

On Sat, 2010-02-27 at 07:43 -0800, Dudebot wrote:

<%= @thing.body %>

display

This is the id of foo: 2 and this is its body: Norman

Is there a way to do that? I also tried #{ … } and am still getting
the literal rather than the interpolation.


try actual code examples

Craig


This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.

<%= bar.to_s %>

It still displays the literal and not the interpolation :frowning:

On 27 February 2010 16:30, Dudebot [email protected] wrote:

The patients id is <%= @patient.id %>

rather than

The patients id is 2

I don’t think many of the readers have actually worked out what you
are asking. That is, if I am correct, have a string produced by a
controller where the string includes the literal text <%= … %> and
have this interpolated somehow in the view. Perhaps if you were to
explain why you are trying to achieve this someone may suggest a
better way of solving the problem. Are the strings containing <%= …
%> stored in the db for example?

Colin

Thanks, Colin! I’d like to give the user the flexibility to make a
template that interpolates objects within it. Sort of like a mail
merge. The templates are stored as text entries in a database. The
idea is, say you have something like this as a text entry in the
database

Dear Mr. <%= @person.lastname %>,
We understand that your favorite programming language is <%=
@person.language %>.

Then, if the user was accessing the person show form for @person 2
with lastname Smith and language Ruby, it would display

Dear Mr. Smith,
We understand that your favorite programming language is Ruby.

I am so open to ideas :slight_smile: Right now I’m imagining building an XML
parser, and identifying the fields as tags, then replacing them with
the appropriate objects, but I was wondering if there was a more
direct (or better) way.

Again, thanks,
Craig

I’m no expert at Rails, Craig, but I’ve been writing working Rails
code for about 8 months now on more than a few projects. I’ve read
Agile Development more than once, and have over the course of time
watched scores of Rails webcasts.

If you have a solution to my question, I’d appreciate it. I don’t
think you understand the question. I need the user to generate their
own templates. If I was hard coding all the templates for them, this
would be cake.

On Sat, 2010-02-27 at 10:12 -0800, Dudebot wrote:

Then, if the user was accessing the person show form for @person 2
with lastname Smith and language Ruby, it would display

Dear Mr. Smith,
We understand that your favorite programming language is Ruby.

I am so open to ideas :slight_smile: Right now I’m imagining building an XML
parser, and identifying the fields as tags, then replacing them with
the appropriate objects, but I was wondering if there was a more
direct (or better) way.


I think you need to start with another rails beginner tutorial because
this is very beginner stuff and easily accomplished just as you said and
without any need for xml parsers or sophisticated methods at all.

Craig


This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.

Found it. Use #{}, eval and ‘"’

e.g. foo = ‘#{ bar }’
then eval( ‘"’ + foo + ‘"’ ) will interpolate bar

Freshmeat has a great write-up on templates in Ruby at
Best Open Source Mac Software Development Software 2023, including other
approaches

Needless to say, this code is not safe. A user can run anything in
that eval. In my application, only trusted users have access to
building templates.

We love Ruby :slight_smile:
Craig

You may also want to check out Liquid for a safer way of doing
templates:

Jarin U.
Robot Mode LLC

On Feb 28, 3:04 am, Michael P. [email protected] wrote:

On 27 February 2010 21:15, Dudebot [email protected] wrote:

Needless to say, this code is not safe. A user can run anything in
that eval. In my application, only trusted users have access to
building templates.

I don’t think it’s needless… I think it’s extremely important to
say. For anyone reading this post and thinking it’s a solution to
their problem - if anyone sat back and presented this as a “fix” to
me, I would fire them for their recklessness :-/

That’s exactly why I said it :wink: Believe it or not, in this particular
application we have written contracts with the administrators that
would be creating templates (for other reasons as well.)

However, I am eager to find a better way, and thanks, Jarin, for the
reference to Liquid!

Thanks,
Craig

On 27 February 2010 21:15, Dudebot [email protected] wrote:

Needless to say, this code is not safe. A user can run anything in
that eval. In my application, only trusted users have access to
building templates.

I don’t think it’s needless… I think it’s extremely important to
say. For anyone reading this post and thinking it’s a solution to
their problem - if anyone sat back and presented this as a “fix” to
me, I would fire them for their recklessness :-/

Regardless of how trusted your users are; a) people get spiteful on
occasion, b) they make mistakes and accidents happen, c) They might,
at some point in the future legitimately try to put code examples in
their template (don’t say “they won’t”… you don’t know what people
will use your application for in six months or more…), and those
examples might execute with all sorts of unexpected, unpleasant
results.

never trust user input… rule one.

The simplest example of the general problem; a small typo in their
template will raise an exception to the front end, and they’ll be
blaming you. You can’t test your system, because you don’t know what
code will execute. One second they’re just using “@user.name”, the
next they’ve discovered (probably because some helpful coder friend
[1] has shown them) that they can use the ternary operator, then they
go and start experimenting … “@user.delete… I wonder what that
will do?”… :-/

Still, if you think it’s the best way to solve your problem, Craig,
fair enough - it’s your code, server, and data that’s at risk. But
please, you’re wrong (nothing personal… I just get to see the result
of this type of “solution” time and again, and I don’t want other
people to think it’s a good way :-/

Best regards,
Michael

[1] I’ve found this tends to be the next step to solve another
“problem”, and it’s often at the original developer’s suggestion.
User : “The templates are great, but I need to print ‘Dear Mr’
if I don’t know their firstname”
Developer : “Oh, that’s easy with the way we’ve done the
templates…”

On 28 February 2010 11:30, Dudebot [email protected] wrote:

me, I would fire them for their recklessness :-/

That’s exactly why I said it :wink:

Yeah, I figured; I was just concerned that you hadn’t qualified why it
was not safe, and someone reading the thread and acting upon it as
advice might expose themselves to a very unexpected, unpleasant risk -
then they’d only post here asking someone to clean it up! :slight_smile:

On Feb 28, 11:30 am, Dudebot [email protected] wrote:

their problem - if anyone sat back and presented this as a “fix” to
me, I would fire them for their recklessness :-/

That’s exactly why I said it :wink: Believe it or not, in this particular
application we have written contracts with the administrators that
would be creating templates (for other reasons as well.)

It’s not necessarily malicious - if your administrators are not
trained ruby developers (or even if they are) sooner or later they
will make a mistake. They probably won’t accidentally type <%=
ActiveRecord::Base.connection.execute ‘drop database …’ %> but they
could easily type something which raises an error in some cases (or
all cases) and before you know it you’re getting called at 3 in the
morning because something isn’t working.

Fred

will make a mistake. They probably won’t accidentally type <%=
ActiveRecord::Base.connection.execute ‘drop database …’ %> but they
could easily type something which raises an error in some cases (or
all cases) and before you know it you’re getting called at 3 in the
morning because something isn’t working.

Avoiding 3 in the morning phone calls is the most worthy of
pursuits :slight_smile: Jarin’s pointing to Liquid saved the day–what a great
gem/plugin. Works like a charm.

Many thanks all,
Craig