Hi David,
I'll describe two scenarios and I hope I can clarify the problem.
First of all the Mapping:
BAZ = {
'GEO_foo' => { 'GEO_bar' => 'GEO_baz' },
"$(GEO{foo})" => { "$(GEO{bar})" => 'KEYING LITERAL ESI STRINGS' }
}
Second the default order of processing...
1. source: -------------------------------------------------------------------
<% foo = "$(GEO{'foo'})" %>
<% bar = "$(GEO{'bar'})" %>
Foo: <%= foo %>
Bar: <%= bar %>
Baz: <%= BAZ[foo][bar] %>
# ... up to this point nothing was evaluated.
2. erb'd: --------------------------------------------------------------------
Foo: $(GEO{'foo'})
Bar: $(GEO{'bar'})
Baz: KEYING LITERAL ESI STRINGS
# ... the time erb evaluates the five expressions the first two assign their
# values, which still contain the ESI instructions. In the following
# expressions these instructions are written to the document.
# As for the last expression Ruby tries to resolve the key `$(GEO{'foo'})` in
# the BAZ hash.
# At this time the BAZ hash has no member with this name resulting in nil
# unless otherwise defined.
# In the first line you see the assignment I made to produce this - kinda
# unwanted - result.
3. ESI: ----------------------------------------------------------------------
Foo: GEO_foo
Bar: GEO_bar
Baz: KEYING LITERAL ESI STRINGS
# Assuming that GEO['foo'] contains the string GEO_foo and GEO['bar'] contains
# GEO_bar the values are correctly replaced.
# But since 'KEYING LITERAL ESI STRINGS' is not in any way an esi instruction
# nothing happens here.
*snip* ***********************************************************************
So, what happens when we switch 2 and 3? First of all I think this could
either suck performance wise or improve it. I don't know 'cause I'm not so
much into socket communication. That aside:
3. ESI: ----------------------------------------------------------------------
<% foo = "GEO_foo" %>
<% bar = "GEO_bar" %>
Foo: <%= foo %>
Bar: <%= bar %>
Baz: <%= BAZ[foo][bar] %>
# ... the ESI instructions were replaced correctly as intended.
2. erb'd: --------------------------------------------------------------------
Foo: GEO_foo
Bar: GEO_foo
Baz: GEO_baz
# ... well, I think this is the result you expected. Mapping is done
# correctly, and Foo: & Bar: show the correct values.
*snip* ***********************************************************************
Switching step 2 and 3 could be a problem depending on your setup, but not
impossible. But still I'd not mix two templating engines as I still think that
it is possible to expose, if not already exposed, the GEO variables to your
Rack::Request object. They should be members of the #env property. If not you
could, if you use VCL and the GeoIP library, modify the plugin in a way it
exposes them.
best
Florian