8.2 #extends

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.