<%= %> 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

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 %>'?

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

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.

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

<tr><td><%= @mold.body.gsub( "\n", "<br />" ) %></td></tr>

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

<%= bar.to_s %>

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

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

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.

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.

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
http://freshmeat.net/articles/templates-in-ruby, 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:

http://www.liquidmarkup.org/

Jarin Udom
Robot Mode LLC

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..."

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

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:

> > 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.)

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