From: Wells Oliver on
Can you use dicts with string.Template?

e.g. a structure like:

game = {
'home': {'team': row['home_team_full'], 'score': row['home_score'],
'record': '0-0', 'pitcher': {
'id': home_pitcher.attrib['id'], 'name':
home_pitcher.attrib['last_name'], 'wins': home_pitcher.attrib['wins'],
'losses': home_pitcher.attrib['losses']
}, 'win': home_win}
}

Then, in the template, 'game' is passed, but I want to access like
$home.pitcher.id

This doesn't seem to work, though. Is it possible? Or must everything
in the dict passed to string.Template be one-level deep string
variables?
From: Peter Otten on
Wells Oliver wrote:

> Can you use dicts with string.Template?
>
> e.g. a structure like:
>
> game = {
> 'home': {'team': row['home_team_full'], 'score': row['home_score'],
> 'record': '0-0', 'pitcher': {
> 'id': home_pitcher.attrib['id'], 'name':
> home_pitcher.attrib['last_name'], 'wins': home_pitcher.attrib['wins'],
> 'losses': home_pitcher.attrib['losses']
> }, 'win': home_win}
> }
>
> Then, in the template, 'game' is passed, but I want to access like
> $home.pitcher.id
>
> This doesn't seem to work, though. Is it possible? Or must everything
> in the dict passed to string.Template be one-level deep string
> variables?

If you're unclear about the capabilities of a piece of python it's time to
have a look at the source code ;)

My conclusion: you can make string.Template accept dotted variables and
nested dicts, but not without subclassing and a few lines of custom code.

$ cat extended_template.py
import string

class DotDict(object):
def __init__(self, d):
self._nested = d
def __getitem__(self, key):
result = self._nested
for k in key.split("."):
result = result[k]
return result

class Template(string.Template):
idpattern = r'[_a-z][_a-z0-9.]*'

def substitute(self, *args, **kw):
assert not kw
[d] = args
return string.Template.substitute(self, DotDict(d))

if __name__ == "__main__":
game = {"home": {"pitcher": {"id": 42}}}
print Template("home/pitcher/id is $home.pitcher.id").substitute(game)

$ python extended_template.py
home/pitcher/id is 42

Peter