ESI meets ERB, with some odd results

Hi David,

I've got some ESI variables in a template, and am trying to assign
their values to Ruby variables. Strangely, it seems to work and not
work at the same time.

Why mixing them anyway?

<esi:vars>
<% state = "$(GEO{'region_code'})" %>
<% city = "$(GEO{'city'})" %>

State: <%= state %><br/> # CT
City: <%= city %><br/> # NEWHAVEN

<% # becomes: %>
State: $(GEO{'region_code'})
City: $(GEO{'city'})
<% # so the ESI processor replaces them after ERB %>

Massaged city: <%= CITIES[state][city] %> # Uses the literal EIS strings

<% # becomes: %>
Massaged city: <%= CITIES["$(GEO{'region_code'})"]["$(GEO{'city'})"]
# => "KEYING LITERAL ESI STRINGS" %>
<% # so the ESI processor replaces ... nothing. %>

</esi:vars>

So, strange as it sounds, the variables seem to be differently bound
depending on which line is being evaluated. So far I've not been able
to puzzle through the sequence of events in such a way as to come up
with a way to inject the state and city values into a call to the
CITIES hash. I'd be interested in any ideas or solutions people might
have.

You can:
process the template with the ESI proc before it's evaluated by erb
or drop erb and define your mapping as ESI variables by writing a script that
writes the complete mapping into an esi:include'd file
or drop ESI and expose the GEO server variables to erb...

or define
class ESIlabeth < Struct.new(:name, :words)

  def initialize\(name, \*words\)
    super name, words\.flatten
  end

  def \[\]\(word\)
    self\.class\.new name, words \+ \[ word \]
  end

  def to\_s
    ugh = words\.map \{ |word| &quot;\[\#\{ word\.inspect \}\]&quot; \}\.join
    %Q&#39;&lt;% \#\{ name \}\#\{ ugh \} %&gt;&#39;
  end
  \# or implement to\_s in a way it resolves the http vars and then
  \# accesses the real CITIES storage\.

end

CITIES = ESIlabeth\.new &#39;CITIES&#39;
\# puts CITIES\[&quot;$\(GEO\{&#39;region\_code&#39;\}\)&quot;\]\[&quot;$\(GEO\{&#39;city&#39;\}\)&quot;\]
\# =&gt; CITIES\[&quot;$\(GEO\{&#39;region\_code&#39;\}\)&quot;\]\[&quot;$\(GEO\{&#39;city&#39;\}\)&quot;\]

and parse it again after ESI did its stuff... :slight_smile:

or implement your own ESI processor and embed it into ruby, ...

It's a matter of the problems environment. Hope I could help.

best
Florian

Hi –

Hi David,

I’ve got some ESI variables in a template, and am trying to assign

their values to Ruby variables. Strangely, it seems to work and not

work at the same time.

Why mixing them anyway?

We need to correct/normalize the cities that have spaces removed, like NEWYORK.

esi:vars

<% state = “$(GEO{‘region_code’})” %>

<% city = “$(GEO{‘city’})” %>

State: <%= state %>
# CT

City: <%= city %>
# NEWHAVEN

<% # becomes: %>
State: $(GEO{‘region_code’})

City: $(GEO{‘city’})

<% # so the ESI processor replaces them after ERB %>

But they display CT and NEWHAVEN, which suggests that they’ve already been ESI-processed.

Massaged city: <%= CITIES[state][city] %> # Uses the literal EIS strings

<% # becomes: %>

Massaged city: <%= CITIES["$(GEO{‘region_code’})"]["$(GEO{‘city’})"]

               # => "KEYING LITERAL ESI STRINGS" %>

<% # so the ESI processor replaces … nothing. %>

I’m still mystified as to why/how the same variables can behave in both ways (literal strings and interpolated strings).

</esi:vars>

So, strange as it sounds, the variables seem to be differently bound

depending on which line is being evaluated. So far I’ve not been able

to puzzle through the sequence of events in such a way as to come up

with a way to inject the state and city values into a call to the

CITIES hash. I’d be interested in any ideas or solutions people might

have.

You can:
[ideas snipped]

As I mentioned in my last response we’re going to do it in JavaScript, but I’ll have a look at your ideas which will probably increase my ESI understanding.

David

Hi David,

I'd prefer getting the values from request.env[]. I'd reduce complexity across your application. It also reduces the number of times the document is processed.

As Jens said ERB comes before ESI.

     App (erb) => Server (esi) => World

Did you try accessing those HTTP vars (HTTP_GEO) in your Rails app?
Do you use Varnish using a pimped version of the GeoIP plugin?

best
Florian

David Black schrieb: