3.1 Simple placeholders

Let's add a few $placeholders to our template:

>>> from Cheetah.Template import Template
>>> values = {'what': 'surreal', 'punctuation': '?'}
>>> t = Template("""\
... Hello, $what world$punctuation
... One of Python's least-used functions is $xrange.
... """, [values])
>>> print t
Hello, surreal world?
One of Python's least-used functions is <built-in function xrange>.

>>> print t.generatedModuleCode()
  1	#!/usr/bin/env python
    
  2	"""
  3	Autogenerated by CHEETAH: The Python-Powered Template Engine
  4	 CHEETAH VERSION: 0.9.12
  5	 Generation time: Sun Apr 21 00:53:01 2002
  6	"""
    
  7	__CHEETAH_genTime__ = 'Sun Apr 21 00:53:01 2002'
  8	__CHEETAH_version__ = '0.9.12'
    
  9	##################################################
 10	## DEPENDENCIES
    
 11	import sys
 12	import os
 13	import os.path
 14	from os.path import getmtime, exists
 15	import time
 16	import types
 17	from Cheetah.Template import Template
 18	from Cheetah.DummyTransaction import DummyTransaction
 19	from Cheetah.NameMapper import NotFound, valueForName, 
           valueFromSearchList
 20	import Cheetah.Filters as Filters
 21	import Cheetah.ErrorCatchers as ErrorCatchers
    
 22	##################################################
 23	## MODULE CONSTANTS
    
 24	try:
 25	    True, False
 26	except NameError:
 27	    True, False = (1==1), (1==0)
    
 28	##################################################
 29	## CLASSES
    
 30	class GenTemplate(Template):
 31	    """
 32	    
 33	    Autogenerated by CHEETAH: The Python-Powered Template Engine
 34	    """
    
 35	    ##################################################
 36	    ## GENERATED METHODS
    
 37	    def __init__(self, *args, **KWs):
 38	        """
 39	        
 40	        """
    
 41	        Template.__init__(self, *args, **KWs)
    
 42	    def respond(self,
 43	            trans=None,
 44	            dummyTrans=False,
 45	            VFS=valueFromSearchList,
 46	            VFN=valueForName,
 47	            getmtime=getmtime,
 48	            currentTime=time.time):
    
    
 49	        """
 50	        This is the main method generated by Cheetah
 51	        """
    
 52	        if not trans:
 53	            trans = DummyTransaction()
 54	            dummyTrans = True
 55	        write = trans.response().write
 56	        SL = self._searchList
 57	        filter = self._currentFilter
 58	        globalSetVars = self._globalSetVars
 59	        
 60	        ########################################
 61	        ## START - generated method body
 62	        
 63	        write('Hello, ')
 64	        write(filter(VFS(SL,"what",1))) # generated from '$what' at 
                                                # line 1, col 8.
 65	        write(' world')
 66	        write(filter(VFS(SL,"punctuation",1))) # generated from 
                                     # '$punctuation' at line 1, col 19.
 67	        write("\nOne of Python's least-used methods is ")
 68	        write(filter(xrange)) # generated from '$xrange' at line 2, 
                                      # col 39.
 69	        write('.\n')
 70	        
 71	        ########################################
 72	        ## END - generated method body
 73	        
 74	        if dummyTrans:
 75	            return trans.response().getvalue()
 76	        else:
 77	            return ""
 78	        
 79	    ##################################################
 80	    ## GENERATED ATTRIBUTES

 81	    __str__ = respond
 82	    _mainCheetahMethod_for_GenTemplate= 'respond'

 83	# CHEETAH was developed by Tavis Rudd, Chuck Esterbrook, Ian Bicking 
        # and Mike Orr;
 84	# with code, advice and input from many other volunteers.
 85	# For more information visit http://www.CheetahTemplate.org
    
 86	##################################################
 87	## if run from command line:
 88	if __name__ == '__main__':
 89	    GenTemplate().runAsMainProgram()

(Again, I have added line numbers and split the lines as in the previous chapter.)

This generated template module is different from the previous one in several trivial respects and one important respect. Trivially, ._filePath and ._fileMtime are not updated in .__init__, so they inherit the value None from Template. Also, that if-stanza in .respond that recompiles the template if the source file changes is missing - because there is no source file. So this module is several lines shorter than the other one.

But the important way this module is different is that instead of the one write call outputting a string literal, this module has a series of write calls (lines 63-69) outputting successive chunks of the template. Regular text has been translated into a string literal, and placeholders into function calls. Every placeholder is wrapped inside a filter call to apply the current output filter. (The default output filter converts all objects to strings, and None to "".)

Placeholders referring to a Python builtin like xrange (line 68) generate a bare variable name. Placeholders to be looked up in the searchList have a nested function call; e.g.,

write(filter(VFS(SL,"what",1))) # generated from '$what' at line 1, col 8.
VFS, remember, is a function imported from Cheetah.NameMapper that looks up a value in a searchList. So we pass it the searchList, the name to look up, and a boolean (1) indicating we want autocalling. (It's 1 rather than True because it's generated from an and expression, and that's what Python 2.2 outputs for true and expressions.)