4.2 ``cheetah compile'' and .py template modules

To create a .py template module, do either of these:

cheetah compile [options] [FILES ...]
cheetah c [options] [FILES ...]

The following options are supported:

  --idir DIR, --odir DIR : input/output directories (default: current dir)
  --iext EXT, --oext EXT : input/output filename extensions
    (default input: tmpl,  default output:  py)
  -R : recurse subdirectories looking for input files
  --debug : print lots of diagnostic output to standard error
  --flat : no destination subdirectories
  --nobackup : don't make backups
  --stdout, -p : output to standard output (pipe)

Note: If Cheetah can't find your input files, or if it puts output files in the wrong place, use the --debug option to see what Cheetah thinks of your command line.

The most basic usage is:

cheetah compile a.tmpl           : writes a.py
cheetah compile a.tmpl b.tmpl    : writes a.py and b.py

Cheetah will automatically add the default input extension (.tmpl) if the file is not found. So the following two examples are the same as above (provided files ``a'' and ``b'' don't exist):

cheetah compile a                : writes a.py (from a.tmpl)
cheetah compile a b              : writes a.py and b.py

You can override the default input extension and output extension (py) using --iext and --oext, although there's little reason to do so. Cheetah assumes the extension has a leading dot (.) even if you don't specify it.

Use the -R option to recurse subdirectories:

cheetah compile dir1             : error, file is a directory
cheetah compile -R dir1          : look in `dir1' for files to compile
cheetah compile                  : error, no file specified
cheetah compile -R               : look in current directory for files
                                   to compile
cheetah compile -R a b dir1      : compile files and recurse
When recursing, only regular files that end in the input extension (.tmpl) are considered source files. All other filenames are ignored.

The options --idir and --odir allow you to specify that the source (and/or destination) paths are relative to a certain directory rather than to the current directory. This is useful if you keep your *.tmpl and *.py files in separate directory hierarchies. After editing a source file, just run one of these (or put the command in a script or Makefile):

cheetah compile --odir /var/webware a.tmpl
cheetah compile -R --odir /var/webware
cheetah c --odir /var/webware sub/a.tmpl
                                 : writes /var/webware/sub/a.py

``cheetah compile'' overwrites any existing .py file it finds, after backing it up to FILENAME.py_bak (unless you specify --nobackup). For this reason, you should make changes to the .tmpl version of the template rather than to the .py version.

For the same reason, if your template requires custom Python methods or other Python code, don't put it in the FILENAME.py file. Instead, put it in a separate base class and use the #extends directive to inherit from it.

Because FILENAME will be used as a class and module name, it must be a valid Python identifier. For instance, cheetah compile spam-eggs.tmpl is illegal because of the hyphen ("-"). This is sometimes inconvenient when converting a site of HTML files into Webware servlets. Fortunately, the directory it's in does not have to be an identifier. (Hint: for date-specific files, try converting 2002/04/12.html to 2002/04/12/index.tmpl. This also gives you a directory to store images or supplemental files.)

Occasionally you may want output files put directly into the output directory (or current directory), rather than into a subdirectory parallel to the input file. The --flat option does this. Note that this introduces the possibility that several input files might map to one output file. Cheetah checks for output file collisions before writing any files, and aborts if there are any collisions.

cheetah c sub/a.py            : writes sub/a.py
cheetah c --flat sub/a.py     : writes a.py
cheetah c --odir DEST sub/a.tmpl
                              : writes DEST/sub/a.py
cheetah c --flat --odir DEST sub/a.tmpl
                              : writes DEST/a.py
cheetah c --idir /home/henry sub/rollins.tmpl
                              : writes sub/rollins.py
cheetah c --flat --idir /home/henry sub/rollins.tmpl
                              : writes rollins.py
cheetah c --idir /home/henry --odir /home/henry sub/rollins.tmpl
                              : writes /home/henry/sub/rollins.py
cheetah c --flat --idir /home/henry --odir /home/henry sub/rollins.tmpl
                              : writes /home/henry/rollins.py

Whenever ``cheetah compile'' has to create an output directory or subdirectory, it also creates an __init__.py file in it. This file is necessary in order to make Python treat the directory as a Python package.

One of the advantages of .py template modules is that you don't lose any flexibility. The generated class contains all #attr values and #def/#block values as ordinary attributes and methods, so you can read the values individually from other Python tools for any kind of custom processing you want. For instance, you can extract the titles of all your templates into a database, or find all the servlets with a certain $author value.