diff options
| author | hierro <hierro> | 2002-04-06 22:33:37 +0000 |
|---|---|---|
| committer | hierro <hierro> | 2002-04-06 22:33:37 +0000 |
| commit | 9dac0f63e3b9bdcbd0b84434438d7f3f6e9eaccc (patch) | |
| tree | e3b2aa07753364f7a4b3136cfc33ceb12b08728e /docs | |
| parent | 0307843f83366d3dcf54f0bf9b19a5cd279f00ea (diff) | |
| download | python-cheetah-9dac0f63e3b9bdcbd0b84434438d7f3f6e9eaccc.tar.gz | |
Many doc changes.
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/users_guide_src/Makefile | 4 | ||||
| -rw-r--r-- | docs/users_guide_src/gettingStarted.tex | 97 | ||||
| -rw-r--r-- | docs/users_guide_src/howItWorks.tex | 397 | ||||
| -rw-r--r-- | docs/users_guide_src/inheritanceEtc.tex | 29 | ||||
| -rw-r--r-- | docs/users_guide_src/introduction.tex | 4 | ||||
| -rw-r--r-- | docs/users_guide_src/webware.tex | 2 |
6 files changed, 294 insertions, 239 deletions
diff --git a/docs/users_guide_src/Makefile b/docs/users_guide_src/Makefile index 576bccc..c62b25e 100644 --- a/docs/users_guide_src/Makefile +++ b/docs/users_guide_src/Makefile @@ -1,11 +1,13 @@ # You must change PYTHONSRC to the path of your Python source distributon. -PYTHONSRC=/home/tavis/work/src/Python-2.2 +PYTHONSRC=/home/iron/nobackup/PYTHON/Python-2.2 DOCNAME=users_guide MKHOWTO=$(PYTHONSRC)/Doc/tools/mkhowto MAIN_TEX_FILE= users_guide.tex all: ps pdf html htmlMultiPage text +almost-all: ps html htmlMultiPage text + pdf: $(MKHOWTO) --pdf $(MAIN_TEX_FILE) mv $(DOCNAME).pdf ../ diff --git a/docs/users_guide_src/gettingStarted.tex b/docs/users_guide_src/gettingStarted.tex index e417def..4a5fee0 100644 --- a/docs/users_guide_src/gettingStarted.tex +++ b/docs/users_guide_src/gettingStarted.tex @@ -5,9 +5,14 @@ \subsection{Requirements} \label{gettingStarted.requirements} -Cheetah requires Python release 2.0 or greater and should run on any -operating system that Python 2.0 runs on. It has been tested on -Python 2.0, 2.1 and 2.2b1. +Cheetah requires Python release 2.0 or greater. , and should run anywhere +Python runs. It has been tested with Python 2.0, 2.1 and 2.2. It is known to +run on Linux, Windows NT/98/XP, FreeBSD and Solaris, and should run anywhere +Python runs. + +99\% of Cheetah is written in Python. There is one small C module +(\code{\_namemapper.so}) for speed, but Cheetah automatically falls back to a +Python equivalent if the C module is not available. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Installation} @@ -22,8 +27,9 @@ To install Cheetah to your system-wide Python library: \item Run \code{python setup.py install} at the command prompt. -\item The setup program will install the wrapper script {\bf cheetah} to the - "/usr/bin" or something like that. +\item The setup program will install the wrapper script {\bf cheetah} to + wherever it usually puts Python binaries ("/usr/bin/", "bin/" in the + Python install directory, etc.) \end{enumerate} %% @@MO: What about cheetah-compile on non-POSIX systems? @@ -32,7 +38,9 @@ To install Cheetah to an alternate location use the options to setup.py's \code{install} command: \begin{verbatim} python setup.py install --home /home/tavis +\end{verbatim} and +\begin{verbatim} python setup.py install --install-lib /home/tavis/lib/python both install to /home/tavis/lib/python/Cheetah \end{verbatim} @@ -42,6 +50,43 @@ Cheetah's installation is managed by Python's Distribution Utilities setup.py help''} for more information. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Files} +\label{gettingstarted.files} + +If you do the systemwide install, all Cheetah modules are installed in the +{\bf site-packages/Webware/Cheetah/} subdirectory of your standard library +directory; e.g., /opt/Python2.2/lib/python2.2/site-packages/Webware/Cheetah. + +A file site-packages/Webware.pth causes Python to put +site-packages/Webware in the standard Python path, so that when you or a +script executes \code{from Cheetah.Template import Template}, it works as +expected. + +This site-packages/Webware/ directory is otherwise empty unless you've +installed the WebwareExperimentalRefactoring package (not the standard +Webware--unless perhaps Webware switches to distutils in the future). You +may be surprised to have a site-packages/Webware/ directory when you're not +using Webware, but don't worry: Cheetah's author just chose to package Cheetah +that way, and Cheetah works the same whether Webware is installed or not. + +Two commands are installed in Python's \code{bin/} directory or a system +bin directory: \code{cheetah} (section \ref{gettingStarted.cheetah}) and +\code{cheetah-compile} (section \ref{howWorks.cheetah-compile}). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Uninstalling} +\label{gettingstarted.uninstalling} + +% @@MO: When 'python setup.py uninstall' is implemented, mention it here. + +If you play with Cheetah a while and decide not to use it, it's easy to +uninstall. Merely delete the site-packages/Webware/Cheetah/ directory +(or site-packages/Webware/ if it's otherwise empty) and the +site-packages/Webware.pth file. + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The 'cheetah' command} \label{gettingStarted.cheetah} @@ -58,30 +103,30 @@ cheetah test|-t [test options] - Run Cheetah's test suite ('cheetah test --help' for more) cheetah --version|-v - Print Cheetah's version number +cheetah fill|-f + - Fill template(s) [not implemented yet] \end{verbatim} The test suite is described in the next section. The compiler will be -described in section \ref{howItWorks.cheetah-compile}. - -For backward compatibility, the separate \code{cheetah-compile} program -does the same thing as \code{cheetah compile}. +described in section \ref{howItWorks.cheetah-compile}, along with the +separate \code{cheetah-compile} command which does the same thing. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Testing your installation} \label{gettingStarted.test} -You can run the test suite to insure that your installation is correct by -following these steps: -\begin{enumerate} -\item install Cheetah as explained above -\item type: \code{cheetah test} -\end{enumerate} +After installing Cheetah, you can run its self-test routine to verify it's +working properly on your system. Type the following at the command prompt: +\begin{verbatim} +cheetah test +\end{verbatim} +The tests will run for a minute or so and then print a success/failure message. If the tests pass, start Python in interactive mode and try the example in the -Introduction section of this guide. +next section. -If any of the tests fail please send a message to the email list with a copy of -the test output and the following details about your installation: +If any of the tests fail, please send a message to the e-mail list with a copy +of the test output and the following details about your installation: \begin{enumerate} \item your version of Cheetah @@ -95,12 +140,10 @@ the test output and the following details about your installation: \label{gettingStarted.tutorial} This tutorial briefly introduces the basic usage of Cheetah. See the -following chapters for more detailed explanations. - -{\bf This tutorial will be fleshed out further at later date.} +following chapters for more features and more detailed explanations. The core of Cheetah is the \code{Template} class in the \code{Cheetah.Template} -module. The following example shows how to use the \code{Template} class from an +module. The following example shows how to use the \code{Template} class in an interactive Python session. Lines prefixed with \code{>>>} and \code{...} are user input. The remaining lines are Python output. @@ -128,11 +171,10 @@ Hello World! </BODY> </HTML> >>> print templateObj # print it as many times as you want - [ ... identical output not shown ... ] + [ ... same output as above ... ] >>> nameSpace['title'] = 'Example #2' >>> nameSpace['contents'] = 'Hiya Planet Earth!' >>> print templateObj # Now with different plug-in values. - [ ... the output it the same as the first example above ... ] <HTML> <HEAD><TITLE>Example #2</TITLE></HEAD> <BODY> @@ -150,7 +192,7 @@ way: >>> templateObj2.title = 'Hello World Example!' >>> templateObj2.contents = 'Hello World' >>> print templateObj2 - [ ... the output is the same as the first example above ... ] + [ ... same output as the first example above ... ] >>> templateObj2.title = 'Example #2' >>> templateObj2.contents = 'Hello World!' >>> print templateObj2 @@ -175,7 +217,8 @@ The above is all fine for short templates, but for long templates or for an application that depends on many templates in a hierarchy, it's easier to store the templates in separate *.tmpl files and use the {\bf cheetah compile} program to convert them into Python classes in -their own modules. This will be covered in section ??. +their own modules. This will be covered in section +\ref{howWorks.cheetah-compile}. As an appetizer, we'll just briefly mention that you can store constant values {\em inside} the template definition, and they will be converted to attributes @@ -186,7 +229,7 @@ templates (e.g., a "page" template overriding a sidebar in a "section" template). For the minimalists out there, here's a template definition, -instantiation and filling all in Python statement: +instantiation and filling all in one Python statement: \begin{verbatim} >>> print Template("Templates are pretty useless without placeholders.") diff --git a/docs/users_guide_src/howItWorks.tex b/docs/users_guide_src/howItWorks.tex index de43856..e04da40 100644 --- a/docs/users_guide_src/howItWorks.tex +++ b/docs/users_guide_src/howItWorks.tex @@ -5,103 +5,43 @@ \subsection{The Template Class} \label{howWorks.templateClass} -The heart of Cheetah is the \code{Template} class in the \code{Cheetah.Template} -module. It serves two purposes. First, its constructor accepts a -\code{template definition} in a string or a file (filename or file object). -Cheetah compiles the template definition into a Python class (the 'generated -class'). Second, it is used as the base class for the generated classes. -\code{Template} subclasses Webware's \code{HTTPServlet} class when it is -available. Thus, the generated classes can be used as Webware servlets. - -Generated template classes can either be used immediately or written to a Python -module file for future use. In the former case, the methods and attributes of -the generated class are dynamically bound to the instance of Template that did -the compiling. They are available as soon as compilation is complete. In the -latter case, Cheetah will wrap the generated class definition in some -boilerplate code to make a complete module definition. - -Templates objects exist to be {\bf filled}, that is, to have their -placeholders substituted and directives executed to produce a finished string. -To fill a template, you call its {\bf core method}. The core method is -normally \code{.respond()} because that's the core method of a Webware -servlet. You call this method without arguments and it returns the -finished string. For convenience, Cheetah makes the -\code{.\_\_str\_\_} method an alias to the core method. Thus, \code{``print -myTemplateObj''} or \code{``print Template(sourceString)''} will print the -output of the template. (Under certain circumstances, Cheetah will name the -core method \code{.writeBody}, and you can also explicitly name the core -method yourself. See the \code{\#implements} directive (section -\ref{inheritanceEtc.implements}) for more information.) - -To improve performance, Cheetah does "lazy compilation". The compiling step is -delayed until the first time it is needed; e.g., the first time the template is -filled. You can also precompile your templates to gain a (slight) increase -in speed, using the {\bf cheetah compile} command described below. +The heart of Cheetah is the \code{Template} class in the +\code{Cheetah.Template} module. It serves two purposes. First, its constructor +accepts a {\bf template definition} in a string or a file (filename or file +object). Cheetah compiles the template definition into a Python class (the +{\bf generated class}). Second, \code{Template} itself serves as the base class +for the generated class. \code{Template} subclasses Webware's +\code{HTTPServlet} class when available, so the generated class can be used +as a Webware servlet. + +A template is compiled automatically the first time it's {\bf filled}. +(Filling is what you do when you make a finished string from the template, +with all the placeholder values substituted in.) If you use a \code{Template} +object as in the previous two examples (sections \ref{intro.whatIs} and +\ref{gettingStarted.tutorial}), the generated class is overlaid into the +template object itself. That is, the generated class is a dynamic superclass +that affects only that \code{Template} instance, not any other other +\code{Template} instances. Don't worry if you don't understand this; +it does the ``right thing'' behind the scenes. + +If you instead precompile the template by running the \code{cheetah-compile} +program below, the hidden generated class is exposed. It's written to a +file, with some boilerplate code around it to make a bona fide Python module +(called a {\bf .py template module}). This ``freezes'' the class. Anytime +later you can ``unfreeze'' it by importing and instantiating the class. The +advantage of this is speed: compile once, use many times. Plus, if Python +has made a .pyc or .pyo file, you can skip Python's compilation step too. +The speed difference is negligable if you templates just occasionally, +because every template operation seems to be instantaneous, but it may make a +difference for applications such as Webware that use many templates a second. + +To fill a template, you call its {\bf main method}. This is normally +\code{.respond()}, but under certain circumstances it's \code{.writeBody()} or +a user-defined name. (Section \ref{inheritanceEtc.implements} explains why +the method name is not always the same.) However, \code{.\/\_\_str\_\_()} is +always an alias for the main method, so you can always use +\code{print\ myTemplateInstance} or \code{str(myTempateInstance)} to fill it. -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\subsection{Object-Oriented Documents} -\label{howWorks.objoriented} - -As Cheetah documents are actually class definitions, templates may inherit from -one another in a natural way, using regular Python semantics. For instance, -consider this template: - -\begin{verbatim} -#def title -This document has not defined its title -#end def -#def htTitle -$title -#end def -<HTML><HEAD> -<TITLE>$title</TITLE> -</HEAD><BODY> -<H1>$htTitle</H1> -$body -</BODY></HTML> -\end{verbatim} - -And its subclassed document: -\begin{verbatim} -#from SomeModule import TheTemplateAbove -#extends TheTemplateAbove -#def title -The Frog Page -#end def -#def htTitle -The <IMG SRC="Frog.png"> page -#end def -\end{verbatim} - -This is a classic use of inheritance. What we consider a "template" is simply an -abstract superclass. Each subdocument both defines its own behaviour and -specializes the output. For instance, in this document we redefine -\code{\$htTitle} so that we can distinguish between the plain title that appears -in the HEAD and the potentially more complicated title that can appear in -\code{H1}. This allows flexibility, while allowing most documents to ignore the -distinction (since by default \code{\$htTitle} is defined as \code{\$title}). - -In many other templating systems, the solution to this sort of problem is -implemented with case statements (in whatever form they take) often placed in -many different sections of code. This is the classic problem that arises with -purely procedural programming languages, and Cheetah uses a classical approach -to solve it. - -This is also a good way to mix Cheetah and Python code. Cheetah is not and does -not try to be the right language for everything you want to do (in contrast to -PHP, for instance). Instead it tries to focus on display logic and integrate -easily with Python code. - -Consider the first example template: while we show another Cheetah document -inheriting from it, a Python class could inherit from it just as easily. This -Python class could define its programmatically-driven value for \code{\$body} -and \code{\$title}, simply by defining body() and title() methods. - -Similarly, the Cheetah document can inherit from an arbitrary class. This -technique is used when combining Cheetah with Webware for Python -(chapter \ref{webware}): the base template for your site inherits (indirectly) -from the Webware HTTPServlet class. The classes are sufficiently generic that -similar techniques should be possible for other systems. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Constructing Template Objects} @@ -119,9 +59,7 @@ Here are typical ways to create a template object: \\ Pass the Template Definition as a string. Also pass two Namespaces for the searchList: a dictionary 'dict' and an instance 'obj'. \item{\code{templateObj = Template(file="fink.txt", searchList=[dict, obj])}} - \\ Same, but pass a filename instead of a string. The \code{None} is - required here to represent the missing Template Definition string -- this - due to Python's rules for positional parameters. + \\ Same, but pass a filename instead of a string. \item{\code{templateObj = Template(file=f, searchList=[dict, obj])}} \\ Same with a file object. \end{description} @@ -130,7 +68,10 @@ The constructor accepts the following keyword arguments: \begin{description} \item{{\bf source}} - The template definition as a string. + The template definition as a string. You may omit the \code{source=} + prefix {\em if it is the first argument}, as in all the examples above. + The source can be a string literal in your module, or read from a database + or other data structure. \item{{\bf file}} A filename or file object containing the template definition. A filename must be a string, and a file object must be open for reading. @@ -161,19 +102,12 @@ The constructor accepts the following keyword arguments: behavior. Not yet documented. \end{description} -You must specify either {\bf source} or {\bf file}, but not both. All other -arguments are optional. If you are using {\bf source}, you may omit the -\code{source=} prefix {\em if it is the first argument}, as in all the examples -above. - -If you spell a keyword wrong, it will be ignored rather than causing an error. -So check your spelling! - +You {\em must} specify either {\bf source} or {\bf file}, but not both. EXCEPTION: When using a precompiled template class created by -\code{cheetah compile}, you do {\em not} need to specify a {\bf source} or {\bf -file} argument since that has already been provided. This allows you to -instantiate a precompiled template object without any constructor arguments if -you wish: +\code{cheetah compile}, you do {\em not} specify a {\bf source} or {\bf +file} argument, since the source is built into the class. You may, however, +use the other arguments if you wish. + \begin{verbatim} from MyPrecompiledTemplate import MyPrecompiledTemplate t = MyPrecompiledTemplate() @@ -183,80 +117,73 @@ print t \end{verbatim} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\subsection{cheetah compile: converting .tmpl files into .py modules} -\label{howWorks.tmpl2py} +\subsection{cheetah-compile and .py template modules} \label{howWorks.cheetah-compile} +% @@MO: Talk about cheetah-compile vs 'cheetah compile'. + If your application requires only a few short template definitions, you can -just put them inline in your modules, and create Template objects like the -examples in section \ref{gettingStarted.tutorial}. But if your application -has large templates or many templates, you will find it more convenient to -put each template definition in a separate *.tmpl file, and use the -\code{cheetah compile} program to convert it into a *.py template module; that -is, a Python module named after the template, containing the generated class -which is also named after the template. - -\code{cheetah compile} parses template definition -files and creates equivalent Python modules. On Unix systems, it is installed -into a system directory like \code{/usr/local/bin}, so you can use it without -specifying the absolute path of the script. On Windows systems, you must -specify the full path (\code{<cheetahRoot>/bin/cheetah compile}). Type -``\code{cheetah compile --help}'' from the command line after installing +just put them in your modules as strings. But if your application has large +templates or many templates, it's more convenient to put each in a separate +*.tmpl file and use Cheetah's compiler to convert it into a *.py template +module. A {\bf .py template module} is a Python module with the same name as +the template, containing the generated class which is also named after the +template. + +Run ``\code{cheetah compile --help}'' from the command line after installing Cheetah to get usage information. The most common usage is -``\code{cheetah-compile -R}'', which will convert all the *.tmpl files in the +``\code{cheetah compile -R}'', which will convert all the *.tmpl files in the current directory and its subdirectories. -For backward compatibility, a separate program \code{cheetah-compile} is also -installed. This program does exactly the same thing as \code{cheetah compile}. - -If you run \code{cheetah-compile} on a file FILENAME.tmpl, it will -overwrite FILENAME.py if it exists in the same directory, no matter what -FILENAME.py contains. For this reason, you should make changes to the -\code{.tmpl} version of the template rather than to the \code{.py} version. Any -\code{.py servlet files} that are about to be overwritten will are -automatically backed up with the extension \code{.py\_bak}. -Because FILENAME will be used as a class and module name, it must be a valid -Python identifier. For instance, \code{cheetah compile spam-eggs.tmpl} is -illegal because of the hyphen ("-"). +There are actually three ways to invoke the compiler: +\begin{verbatim} +cheetah compile ... +cheetah -c ... +cheetah-compile ... +\end{verbatim} +All three ways are identical and accept the same command-line arguments. +(The separate program \code{cheetah-compile} exists for backward compatibility. +This Guide also uses the term cheetah-compile extensively because it stands out +without requiring quotes.) -One of the advantages of \code{cheetah compile} is that you don't lose any -flexibility. The generated class contains all \code{\#attr} values and -\code{\#def}/\code{\#block} values as ordinary attributes and methods of the -template class, so you can read the values individually from other Python -tools for any kind of custom processing you want. For instance, if you want to -put the titles of all your servlets into a database. +When cheetah-compile converts {\bf FILENAME.tmpl} in some directory, it +overwrites {\bf FILENAME.py} in the same directory if it exists, after backing +it up to FILENAME.py\_bak. For this reason, you should make changes to the +\code{.tmpl} version of the template rather than to the \code{.py} version. For the same reason, if your template requires custom Python methods or other Python code, don't put it in the \code{FILENAME.py} file. Instead, put it in a separate base class and use the \code{\#extends} directive to -inherit from it. Or put the Python code in the calling routine (the routine -that instantiates and uses the template object). +inherit from it. + +Because FILENAME will be used as a class and module name, it must be a valid +Python identifier. For instance, \code{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. + +One of the advantages of cheetah compile is that you don't lose any +flexibility. The generated class contains all \code{\#attr} values and +\code{\#def}/\code{\#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 certaion +\code{\$author} value. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Some trivia about .py template modules} \label{howWorks.pyTrivia} -Note how .py template modules are {\em different} from a module you write -yourself in the spirit of: +We won't look inside .py template modules in this Guide except to note that +they are very different from template definitions. The following template +definition fragment: \begin{verbatim} -from Cheetah.Template import Template - -TEMPLATE_DEF = """\ -#attr $what = "beautiful" -Here's my $what template. -... lots of other fancy stuff ... -""" - -t = Template(TEMPLATE_DEF) -# ... lots of other fancy stuff ... -print t +The number is $Test.unittest.main. \end{verbatim} -This module contains an ordinary template definition, and the compilation is -all done behind the scenes. A ".py template module", in contrast, contains -lines like: +compiles to this: \begin{verbatim} write("The number is ") @@ -264,68 +191,142 @@ write(filter(VFN(VFS(SL,"Test.unittest",1),"main",0) write(".") \end{verbatim} -which is the compiled equivalent of: +In the upcoming Cheetah Developers' Guide, we'll look at .py template +modules in depth, and see what the various directives compile to. +But you are welcome to take a peek at some .py template modules yourself +if you're curious about what Cheetah does under the hood. It's all +regular Python code: writing strings and function calls to a file-like +object. -\begin{verbatim} -The number is $Test.unittest.main. -\end{verbatim} +Looking at a .py template module may also help you see why something +doesn't work, by seeing what Cheetah thought you meant. It also helps +discourage you from modifying the .py file yourself, because who wants to +keep all those function calls and arguments straight? Let the computer +do the drudgery work. -Clearly you don't want to edit a .py template module directly--who wants -to try to keep all those function calls straight? - -We won't speak further about the internals of .py template module in this -Guide. A closer analysis of them will be in the forthcoming {\em Cheetah -Developers' Guide}. But inspecting at a few .py template modules is a good way -to see how Cheetah works under the hood, because it's ordinary object-oriented -Python code. Looking at its .py template module may also give clues as to -why a particular template doesn't work. You can see what the compiler -thought you meant by a particular construct, and what it converted it to. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\subsection{Running your template as a standalone script} +\subsection{Running your .py template module as a standalone script} \label{howWorks.standalone} -In addition to importing your cheetah-compile'd \code{.py} file into a Python -program or using it as a Webware servlet, you can also run it as a standalone -program, just like any Python script. The program will print the filled -template on standard output. This is useful while debugging the template. -It's also useful as a filter in certain production situations such as shell -scripts. +In addition to importing your .py template module file into a Python +script or using it as a Webware servlet, you can also run it from the +command line as a standalone program. The program will print the filled +template on standard output. This is useful while debugging the template, +and for producing formatted output in shell scripts. When running the template as a program, you cannot provide a searchList or -set \code{self.} attributes in the normal way. So you must take +set \code{self.} attributes in the normal way, so you must take alternative measures to ensure that every placeholder has a value. Otherwise, you will get the usual \code{NameMapper.NotFound} exception at the first missing value. -Fortunately, there are three ways to supply values to cheetah-compile'd -templates running directly from the command line: +Fortunately, there are three ways to supply values to .py template modules +run as standalone programs: \begin{description} \item{{\bf Default values}} You can set default values in the template itself - (via the \code{\#attr} directive) or in a Python superclass. -\item{{\bf Environment variables}} If you use the \code{-e} command-line option, - Cheetah will look in the environment for values. This is the easiest way - to pass values from a shell script. -\item{{\bf A pickle file}} If you use the \code{-p PICKLE\_FILE} option, + (via the \code{\#attr} or \code{\#def} directives) or in a Python + superclass. +\item{{\bf Environment variables}} If you use the \code{--env} command-line +option, Cheetah will look in the environment for values. This is the easiest +way to pass values from a shell script. +\item{{\bf A pickle file}} If you use the \code{--pickle PICKLE\_FILE} option, Cheetah will unpickle the file and place the resulting data structure in the searchList. See the standard Python modules \code{pickle} and \code{cPickle} for more information. (The truly masochistic who love - filters can even use \code{-p -} to read the pickle data from standard - input.) + filters can even use \code{--pickle -} to read the pickle data from + standard input.) \end{description} You can always run \code{python FILENAME.py --help} to see all the command-line options your template program accepts. (That's a double hyphen before the -"help", even if LaTeX misformats it to look like a single hyphen.) +``help'', even if LaTeX misformats it as single hyphen.) Cheetah .py templates that will be used as Webware servlets can also be debugged this way. The only caveat is that if they do any processing that tries to call back into a live web transaction (such as looking for form input data), they will raise an exception since there is no web transaction -in progress. These servlets must be debugged by calling them through the +in progress. Those servlets must be debugged by calling them through the web. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Object-Oriented Documents} +\label{howWorks.objoriented} + +Because Cheetah documents are actually class definitions, templates may inherit +from one another in a natural way, using regular Python semantics. For +instance, consider this template, FrogBase.tmpl: + +\begin{verbatim} +#def title +This document has not defined its title +#end def +#def htTitle +$title +#end def +<HTML><HEAD> +<TITLE>$title</TITLE> +</HEAD><BODY> +<H1>$htTitle</H1> +$body +</BODY></HTML> +\end{verbatim} + +And its subclassed document, Frog1.tmpl: +\begin{verbatim} +#from FrogBase import FrogBase +#extends FrogBase +#def title +The Frog Page +#end def +#def htTitle +The <IMG SRC="Frog.png"> page +#end def +#def body +... lots of info about frogs ... +#end def +\end{verbatim} + +This is a classic use of inheritance. The parent ``template'' is simply an +abstract superclass. Each document specializes the output of its parent. + For instance, here the parent defines +\code{\$htTitle} so that by default it's identical to whatever the +\code{\$title} is, but it can also be customized. This is because HTML's +\code{<TITLE>} tag cannot contain embedded tags, but we may want to use +embedded tags in the \code{H1} title for special effect. Yet for simple +cases where the two are identical, we don't want to bother with +\code{\$htTitle} at all: we just want to set \code{\$title} and forget about +it. + +In many other templating systems, you'd have to use case statements or +if-elseif blocks of some sort, repeated in many different sections of code. + +While we show another Cheetah document inheriting from this parent, a Python +class can inherit from it just as easily. This Python class could define its +programmatically-driven value for \code{\$body} and \code{\$title}, simply by +defining body() and title() methods that return a string. (Actually they +can return anything, but we'll get into that later.) + +\begin{verbatim} +from FrogBase import FrogBase +class Frog2(FrogBase): + def title(self): + return "Frog 2 Page" + # We don't override .htTitle, so it defaults to "Frog 2 Page" too. + def body(self): + return " ... more info about frogs ..." +\end{verbatim} + +Similarly, the Cheetah document can inherit from an arbitrary class. This +technique is used when combining Cheetah with Webware for Python +(chapter \ref{webware}): the base template for your site inherits (indirectly) +from the Webware HTTPServlet class. The classes are sufficiently generic that +similar techniques should be possible for other systems. + +({\em Note:}\ \code{FrogBase.tmpl} could be improved by using the +\code{\#block} directive, section \ref{inheritanceEtc.block}.) + % Local Variables: % TeX-master: "users_guide" % End: diff --git a/docs/users_guide_src/inheritanceEtc.tex b/docs/users_guide_src/inheritanceEtc.tex index 8d024fc..dfa60e9 100644 --- a/docs/users_guide_src/inheritanceEtc.tex +++ b/docs/users_guide_src/inheritanceEtc.tex @@ -45,26 +45,33 @@ subclass of Cheetah.Template.Template: #extends SkeletonPage, MyMixin \end{verbatim} +In the very near future, you won't need those \code{\#from ... import} +directives because \code{\#extends} will implicitly import whatever +classes it needs, but for now the explicit imports are necessary. + (There is a discussion about removing multiple inheritance from Cheetah. If that happens, you'll be able to list only one class in the \code{\#extends} directive. Each template would then inherit from its pure Python class if any (a class that provides attributes and methods needed by the particular template) or from its parent template if none. Each Python class would inherit from its parent template. If the top of -the hierarchy is a Cheetah template, it would not have an \code{\#extends} -directive. If the top of the hierarchy is a Python class, it would have to -subclass \code{Cheetah.Template.Template} explicitly. Python classes in the -inheritance chain would be free to do multiple inheritance if they wish--only -templates would be prohibited from doing multiple inheritance. Currently there -is support both for keeping multiple inheritance and for removing it, so it's -too early to say which way it will go.) +the hierarchy (the most general superclass) is a Cheetah template, it would not +have an \code{\#extends} directive. If the top of the hierarchy is a Python +class, it would have to subclass \code{Cheetah.Template.Template} explicitly. +Python classes in the inheritance chain would be free to do multiple +inheritance if they wish--only templates would be prohibited from doing +multiple inheritance. The Cheetah developers are divided over whether to keep +or remove multiple inheritance, so it's too early to say which way it will +go.) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{\#implements} \label{inheritanceEtc.implements} -A template object has several methods, but there is always one {\bf core +% @@MO: Fully describe the main methods. + +A template object has several methods, but there is always one {\bf main method}, the one you call to fill the template. By default, this method is called \code{.respond()}. However, you can use the \code{\#implements} directive to change the name of that method. You have to do this if you're @@ -72,15 +79,15 @@ integrating Cheetah with an existing system, and the calling routine wants to call another method name rather than \code{.respond()}. EXCEPTION: if your template contains an \code{\#extends} directive but no -\code{\#implements}, the core method is \code{.writeBody()} instead of +\code{\#implements}, the main method is \code{.writeBody()} instead of \code{.respond()}. Why? Because that helps templates that are Webware servlets function correctly. So you must think about what your main method should be called and set \code{\#implements} accordingly if necessary. -In any case, \code{\/\_\_str\_\_()} is always an alias for the core method, no -matter what the core method is called. So you can always call \code{str(t)} to +In any case, \code{.\/\_\_str\_\_()} is always an alias for the main method, no +matter what the main method is called. So you can always call \code{str(t)} to fill your template, or \code{print t} to fill and print it. But of course, in a Webware servlet you never use the \code{print} statement directly except for debugging. diff --git a/docs/users_guide_src/introduction.tex b/docs/users_guide_src/introduction.tex index 672d78c..4328715 100644 --- a/docs/users_guide_src/introduction.tex +++ b/docs/users_guide_src/introduction.tex @@ -154,7 +154,9 @@ Compare this with PSP: </HTML> \end{verbatim} -Section \ref{gettingStarted.tutorial} has a more typical example. +Section \ref{gettingStarted.tutorial} has a more typical example, and section +\ref{howWorks.cheetah-compile} explains how to turn your template definition +into an object-oriented Python module. %% @@TR: I'm going to extend this and briefly introduce: %% - Template objects vs. .tmpl files. diff --git a/docs/users_guide_src/webware.tex b/docs/users_guide_src/webware.tex index 8618976..4e4da80 100644 --- a/docs/users_guide_src/webware.tex +++ b/docs/users_guide_src/webware.tex @@ -526,7 +526,7 @@ file relative to the servlet's directory, prefix the path with whatever \code{self.serverSidePath()} returns (from \code{Servlet.serverSidePath()}. If you don't understand how \code{\#extends} and \code{\#implements} work, and -about a template's core method, read the chapter on inheritance (sections +about a template's main method, read the chapter on inheritance (sections \ref{inheritanceEtc.extends} and \ref{inheritanceEtc.implements}). This may help you avoid buggy servlets. |
