Skip to content

Instantly share code, notes, and snippets.

@jsexauer
Created February 14, 2015 18:31
Show Gist options
  • Save jsexauer/ebf912c208eafd749014 to your computer and use it in GitHub Desktop.
Save jsexauer/ebf912c208eafd749014 to your computer and use it in GitHub Desktop.
Quick and dirty function to template strings
import re
def resolve(template, context):
"""Quick and dirty template resolver, replacing {{ }} with context's values
For example, {{foo.bar}} is replaced with foo.bar's value, provided "foo"
is variable passed in context.
Args:
template (str)
Templated string for which will we substitue in templated values
context (dict)
Dictionary containing context to apply to the template
Returns:
templated_str (str)
String `template` but with context interpolated into it.
Ex:
>>> foo = {'bar': 10, 'baz': 15}
>>> print resolve("Foo's bar + baz is: {{ foo['bar'] + foo['baz'] }}", locals())
Foo's bar + baz is: 25
"""
# Regular expression to find token between "{{" and "}}"
# Group 1 is the full token (ie: "{{ test }}")
# Group 2 is just the part to evaluate (ie: "test")
pattern = re.compile(ur'({{\s*(.+?)\s*}})', flags=re.M+re.S)
def _resolve_var(match):
# Get the token's resolution path (ie, "a.bleh")
(full_token, token_path) = match.groups()
try:
return "%s" % eval(token_path, context)
except Exception as e:
raise Exception("Unable to resolve %s:\n\t %s" %
(full_token, e))
return re.sub(pattern, _resolve_var, template)
if __name__ == '__main__':
test_str = 'templated string'
class A(object):
b = 10
c = 'var c'
d = {'a': "A.d['a']'s value"}
a = A()
great_power = True
print resolve("""
This is a test {{test_str}}.
You can be pretty fancy: {{ a.d['a'] }}
Even do some quick evaluation if needed: {{ "%s = %d" % (a.c, a.b+10) }}
But be careful you are {{ " ".join(['executing','python']) }} in here!
But with great power comes {{
("great responsability" if great_power
else "...actually, don't worry about it :)" )
}}.
Finally, here is how to do a litteral {{ '{{' }} and {{ '}'+'}' }} if needed.
""", locals())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment