Using a variable called 'request' in dictionary with Python Cheetah3

59 Views Asked by At

I've been experimenting with Cheetah3 as a templating engine to transform XML into something else. I have this working, using the below example XML input

<?xml version="1.0" encoding="UTF-8"?>
<example code="HI">
    <codes>
        <code>1</code>
        <code>2</code>
    </codes>
</example>

and the following code

#!/usr/bin/env python

import xmltodict
from Cheetah.Template import Template


with open('example.xml', 'r') as f:
    example_xml = f.read()
example_dict = xmltodict.parse(example_xml)

templateDefinition = "This is a template.\n" \
                     "Example: $example\n" \
                     "Example: $example.codes\n" \
                     "Example: $example.codes.code[0]"
template = Template(templateDefinition, searchList=[example_dict])
print(str(template))

Now if I change the input XML to be contained with a <request> root element (instead of <example>), and the template code from $example to $request it breaks. It would appear that $request is a reserved word in Cheetah3. Is there anyway around that, short of changing the root XML element before using Cheetah3?

2

There are 2 best solutions below

0
Saxtheowl On BEST ANSWER

request is a special variable in Cheetah3, lets just try to rename the variable.

#!/usr/bin/env python

import xmltodict
from Cheetah.Template import Template


with open('example.xml', 'r') as f:
    example_xml = f.read()
example_dict = xmltodict.parse(example_xml)

# Rename 'request' to '_request' or any other name that is not reserved
if 'request' in example_dict:
    example_dict['_request'] = example_dict.pop('request')

templateDefinition = "This is a template.\n" \
                     "Example: $_request\n" \
                     "Example: $_request.codes\n" \
                     "Example: $_request.codes.code[0]"
template = Template(templateDefinition, searchList=[example_dict])
print(str(template))
1
phd On

(Cheetah maintainer is here.)

Class Template has a base class Servlet that declares a few class-level names that become reserved attributes.

For your current code the solution is to remove the offending attribute:

from Cheetah.Servlet import Servlet
del Servlet.request

The real solution would be to allow searchList to override class attributes or to divorce Servlet and Template (or to remove Servlet completely — it was created for Webware which was abandoned long ago). Both would be breaking changes and require a new major release.