2

I'm trying to set up an object instance that will provide values to the Cheetah3 text templating engine.

This is my text template script...

#filename: py_text_template.py

from traits.api import String, Range
from traits.api import HasTraits

from loguru import logger

from Cheetah.Template import Template

class Info(HasTraits):
    keyword_integer = Range(value=0, low=1, high=60)
    keyword_string = String(value="snack", regex=r"^\w+")

@logger.catch(onerror=lambda _: sys.exit(1))
def generate_text_template():
    myinfo = Info(keyword_integer=10, keyword_string="snack-attack")
    t = Template("On the first $myinfo.keyword_string, my true love")
    print(t)

generate_text_template()

I expected to use the myinfo instance of the Info() class to populate the Template, but I get the following error...

Cheetah.NameMapper.NotFound: cannot find 'myinfo'
Mike Pennington
  • 41,899
  • 19
  • 136
  • 174

1 Answers1

1

For reasons I don't yet understand, Cheetah does not follow normal conventions to access object instance attributes and methods.

To fix the problem, I had to replace the $myinfo.keyword_string call with $keyword_string. Then I added searchList=[myinfo] to the Template() call...

myinfo = Info(keyword_integer=10, keyword_string="snack-attack")
t = Template("On the first $keyword_string, my true love",
    searchList=[myinfo])

The object instances in searchList are searched for the dictionary key, attribute, or method in question.

The complete working Cheetah script was:

#filename: py_text_template.py

from traits.api import String, Range
from traits.api import HasTraits

from loguru import logger

from Cheetah.Template import Template

class Info(HasTraits):
    keyword_integer = Range(value=0, low=1, high=60)
    keyword_string = String(value="snack", regex=r"^\w+")

@logger.catch(onerror=lambda _: sys.exit(1))
def generate_text_template():
    myinfo = Info(keyword_integer=10, keyword_string="snack-attack")
    t = Template("On the first $keyword_string, my true love",
                              # ^^^^^^^^^^^^^^
        searchList=[myinfo])  # <--- put myinfo instance here
    print(t)

generate_text_template()

Running this under python3.7 yields the expected results...

(py37_test) [mpenning@mudslide fixme]$ python py_text_template.py

On the first snack-attack, my true love
(py37_test) [mpenning@mudslide fixme]$

This script requires installing:

I'm using:

  • Linux mudslide 5.10.0-9-amd64 #1 SMP Debian 5.10.70-1 (2021-09-30) x86_64 GNU/Linux
  • Python 3.7.0
  • Traits 6.3.2
  • loguru 0.5.3
  • Cheetah 3.2.6.post1
Mike Pennington
  • 41,899
  • 19
  • 136
  • 174