ScottE
ScottE

Reputation: 41

Django parsing templates to extract variables

Situation:

I am using Django templates to write custom flat files, but I want to be able to use the same django template to extract any data that was generated by the Django template.

Here is an example of the template file test.conf.

object User "{{ user }}" {

  display_name = "{{first_name}} {{last_name}}"
  groups = [ "{{ group_name }}" ]
  email = "{{ email }}" }

Here is the generated output.

object User "test1" {
  display_name = "test2"
  groups = [ "test3" ]
  email = "test4" }

I want to be able to extract the data "test1, test2, test3, test4" from the flat file using the "test.conf" Django template. Is this possible, or will I need to parse this data using re?

EDIT: This code snippet worked. If you open template file with open("file", 'r') it will add the escape codes into the string. You would just need to add regex escape flags like \\[ for [. Thank you for the help.

Upvotes: 4

Views: 932

Answers (1)

gbs
gbs

Reputation: 1325

There's no reverse parsing API as far as I know, so I think what you have in mind is not possible.

However, you can still use the template to generate a regex to extract the keywords by doing something like this:

from django.template import Template, Context
import re

template_source = """
object User "{{ user }}" {

display_name = "{{first_name}} {{last_name}}"
groups = [ "{{ group_name }}" ]
email = "{{ email }}" }
"""

# re.escape will add backslashes to all non-alphanumeric characters
template_source = re.escape(template_source)
# but we need to fix all escaped {{ and }} characters
template_source = template_source.replace('\{\{', '{{')
template_source = template_source.replace('\}\}', '{{')

# (you will also need to do this for the tag delimiters {% %} and for
# any symbols inside your template tags)

t = Template(template_source)
c = Context({
    "user": "(?P<user>.*?)",
    "first_name" :"(?P<first_name>.*?)",
    # (there's probably an easier way to do this for all the parameters)
    ...
})

regex_string = t.render(c)

# regex_string will look like this:
# (actually way uglier since re.escape will also escape whitespace!)
"""
object User \"(?P<user>.*?)\" \{

display_name \= \"(?P<first_name.*?) (?P<last_name.*?)\"
groups \= ...
"""

regex = re.compile(regex_string, re.MULTILINE)

Upvotes: 5

Related Questions