Syntax:
#extends CLASS
All templates are subclasses of Cheetah.Template.Template
. However,
it's possible for a template to subclass another template or a pure Python
class. This is where #extends
steps in: it
specifies the parent class. It's equivalent to PSP's ``@page extends=''
directive.
Cheetah imports the class mentioned in an #extends
directive
automatically if you haven't imported it yet. The implicit importing works
like this:
#extends Superclass ## Implicitly does '#from Superclass import Superclass'. #extends Cheetah.Templates.SkeletonPage ## Implicitly does '#from Cheetah.Templates.SkeletonPage import SkeletonPage'.
If your superclass is in an unusual location or in a module named differently than the class, you must import it explicitly. There is no support for extending from a class that is not imported; e.g., from a template dynamically created from a string. Since the most practical way to get a parent template into a module is to precompile it, all parent templates essentially have to be precompiled.
There can be only one #extends
directive in a template and it
may list only one class. In other words, templates don't do multiple
inheritance. This is intentional: it's too hard to initialize multiple
base classes correctly from inside a template. However, you can do
multiple inheritance in your pure Python classes.
If your pure Python class overrides any of the standard Template
methods such as .__init__
or .awake
, be sure to call
the superclass method in your method or things will break. Examples of calling
the superclass method are in section 13.4.
A list of all superclass methods is in section
13.5.
In all cases, the root superclass must be Template
. If your
bottommost class is a template, simply omit the #extends
in it and it
will automatically inherit from Template
. If your bottommost class
is a pure Python class, it must inherit from Template
explicitly:
from Cheetah.Template import Template class MyPurePythonClass(Template):
If you're not keen about having your Python classes inherit from
Template
, create a tiny glue class that inherits both from your
class and from Template
.
Before giving any examples we'll stress that Cheetah does not dictate how you should structure your inheritance tree. As long as you follow the rules above, many structures are possible.
Here's an example for a large web site that has not only a general site template, but also a template for this section of the site, and then a specific template-servlet for each URL. (This is the ``inheritance approach'' discussed in the Webware chapter.) Each template inherits from a pure Python class that contains methods/attributes used by the template. We'll begin with the bottommost superclass and end with the specific template-servlet:
1. SiteLogic.py (pure Python class containing methods for the site) from Cheetah.Template import Template class SiteLogic(Template): 2. Site.tmpl/py (template containing the general site framework; this is the template that controls the output, the one that contains "<HTML><HEAD>...", the one that contains text outside any #def/#block.) #from SiteLogic import SiteLogic #extends SiteLogic #implements respond 3. SectionLogic.py (pure Python class with helper code for the section) from Site import Site class SectionLogic(Site) 4. Section.tmpl/py (template with '#def' overrides etc. for the section) #from SectionLogic import SectionLogic #extends SectionLogic 5. page1Logic.py (pure Python class with helper code for the template-servlet) from Section import Section class indexLogic(Section): 6. page1.tmpl/py (template-servlet for a certain page on the site) #from page1Logic import page1Logic #extends page1Logic
A pure Python classes might also contain methods/attributes that aren't used by their immediate child template, but are available for any descendant template to use if it wishes. For instance, the site template might have attributes for the name and e-mail address of the site administrator, ready to use as $placeholders in any template that wants it.
Whenever you use #extends
, you often need #implements
too, as in step 2 above. Read the next section to understand what
#implements
is and when to use it.