++++++++++ ZPTKit 0.4 ++++++++++ .. contents:: ZPTKit is copyright 2005 `Imaginary Landscape, LLC`__. .. __: http://imagescape.com Downloads and Websites ---------------------- * Homepage: http://imagescape.com/software/ZPTKit/ * Download: http://imagescape.com/software/ZPTKit/ZPTKit-0.4.tar.gz * Source repository: http://svn.webwareforpython.org/ZPTKit/trunk * Discussion: `webware-discuss@lists.sourceforge.net`__ .. __: http://lists.sourceforge.net/lists/listinfo/webware-discuss The repository is a Subversion_ repository. To check out a copy:: $ svn co http://svn.webwareforpython.org/ZPTKit/trunk ZPTKit .. _Subversion: http://subversion.tigris.org/ License and Prerequesites ------------------------- ZPTKit is licensed under an `MIT-style license`__. This gives you permission to most anything you want with ZPTKit. .. __: http://www.opensource.org/licenses/mit-license.php ZPTKit is a toolkit for `Webware For Python`_. It builds upon several other pieces of code: * Webware_. This should be compatible at least to 0.8.1 and probably earlier. This is also compatible with `Paste `_ (both ``paste.webkit`` and ``paste.wareweb``). * `Zope Page Templates`_. Right now there's several implementations of ZPT That have been either reimplemented from the spec or split from Zope. ZPTKit uses the package from http://zpt.sourceforge.net/ -- in the future it may move to a package derived from the Zope 3 tree. * Component_. This is a subclass of ``WebKit.Page``, and adds extra features for integrating new features into your servlet (like a template manager). You must subclass your servlets from ``Component.CPage`` to use ZPTKit. .. _Zope Page Templates: http://www.zope.org/DevHome/Wikis/DevSite/Projects/ZPT/FrontPage .. _Webware: .. _Webware For Python: http://webwareforpython.org .. _Component: http://svn.webwareforpython.org/Component Status & News ------------- ZPTKit is used in production environments, but has not had a wide base of users. As such, it should probably be considered beta quality -- while in a certain use case it performs well, it's likely that new users will provide new use cases. Also, ZPTKit builds on Component, and Component is still at a beta quality. By the `Stable Dependencies Principle`__, ZPTKit can not be more stable than Component. .. __: http://c2.com/cgi/wiki?StableDependenciesPrinciple Changes in ZPTKit 0.4 ~~~~~~~~~~~~~~~~~~~~~ * htmlrender handles ```` without exception * Also it handles ``http://foo.com/bar?a=b&var=value`` -- before the ``&var`` would throw it a loop. Changes in ZPTKit 0.3 ~~~~~~~~~~~~~~~~~~~~~ * Improve support for templates in subdirectories of the search path * Removed special handling of RFC-822 headers in emails; now only the markup form of headers is allowed * Improved rendering of tables with htmlrender * Make more compatible with setuptools (setuptools is not required) * Added `Paste Script `_ package template * Added ``.renderTemplate()`` method, that does normal rendering but returning the result instead of writing it to the output stream * Added ``add_template_path()`` method to servlet, which allows per-request addition of items to the path * Added ``egg/PackageName/template_name.pt``, which allows you to load templates out of other packages (based on `Eggs `_) Changes in ZPTKit 0.2 ~~~~~~~~~~~~~~~~~~~~~ (Note: no public APIs were changed.) * Fixed problem where macro templates were not being cached. * Caches all templates more aggressively. These two fixes should have a considerable impact on performance. * Cleanup and simplification. * Distutils-based distribution. * Some small improvements to the HTML->text renderer. Features -------- * Compiles templates as needed. * Caches and pools compiled templates. * Can find templates in several directories (typically used so that you can shadow individual templates to change the look of an application). * Send emails from ZPT templates, including a text form of an email. Conversion to text is done after the template is rendered, and does word wrapping on the rendered form. * Serves static files from several directories (so that static files like CSS can be put alongside templates, and also shadowed). * Shows exceptions with extended ZPT information. * Model-View-Controller style (where the ZPT template is the view). To-Do ----- * Better configuration, for sending ZPT-based emails outside of a servlet or web request (e.g., from TaskKit based on a schedule). * There's always improvements to be made in the HTML->text converter. * ``If-Modified-Since`` support in ResourceComponent (though this file might simply go away at some point). Using ZPTKit ------------ First, make sure you are subclassing from ``Component.CPage``; typically you change your ``SitePage``:: from Component import CPage from ZPTKit import ZPTComponent class SitePage(CPage): components = [ZPTComponent(zpt_paths)] def writeHTML(self): self.writeTemplate() # Needed for Webware 0.8.1 and earlier: def handleAction(self, action): CPage.handleAction(self, action) self.defaultAction() ``CPage`` is compatible with ``WebKit.Page``. You must fill in ``zpt_paths`` on your own, using whatever configuration mechanism you choose. This can be a single path (where all templates are found) or a list of paths; if a list, then the paths will be searched in order for each template. Your template will now have several new methods and attributes: ``writeTemplate()``: Renders and writes the template that you've set with ``setView``, and writes it to the response. ``template(filename)``: Retrieve the named template. You can render it by calling it. ``sendMail(filename, to_address, from_address, **options)``: Send an email with the given to and from address, and ``options``. ``options``: A dictionary of ``options``. You can also set and get values from this custom dictionary with attributes. The values will be made available in your template under ``options/attribute_name``. In Zope you typically pass values into a template as keyword arguments, and they show up as ``options``; this way top-level attributes remain fairly fixed. This is empty until you add values to it. ``context``: Another custom dictionary, which has all the values available to the template, including ``options``. This also includes ``request``, a dictionary-like object that holds values from the request, ``test(cond, if_true, if_false=None)`` for inline conditionals, and ``here``, which represents the current directory (for use when calling macros in a template). ``CPage`` adds the concept of "view", which ZPTKit interprets as the name of a template (by default ``CPage`` interprets it as the name of a servlet method). This way you can have multiple templates for a single servlet, with each template as a view. E.g.:: class Register(SitePage): def actions(self): return ['save'] def save(self): ... process form ... if successful: self.setView('RegisterSuccessful.pt') By default the view matches the servlet's name, so ``Register.pt`` is called. In this case if the form is successfully submitted we instead use ``RegisterSuccessful.pt``. Templates --------- ZPTKit templates are normal Zope Page Templates. In most cases they will look very similar. You can use macros as normal, for instance. One difference is that there is no ``container`` variable. You can use ``here`` to refer to other templates (like ``here/standard_template.pt``), but only to templates (in Zope you can access scripts and functions the same way). Instead the variable ``servlet`` is added, which is a reference to the calling servlet. So if you have a complicated callback, you can refer to ``python: servlet.method(arg1, ...)`` and the value will be substituted in (be sure to use ``structure`` if that value includes markup). Providing Template With Eggs ---------------------------- You must add something like to your ``setup.py`` file:: setup(.... entry_points=""" [zptkit.template_dir] main = mypackage.templates:template_location """, ...) Then in ``mypackage/templates.py`` put something like:: template_location = 'mypackage/templates/' Then when someone tries to load ``egg/MyPackage/foo.pt`` it will look in ``mypackage/templates/foo.pt``. Also ``egg/MyPackage/main/foo.pt`` will work (using the name you used in ``entry_points``) -- ``main`` is the default. ResourceComponent ----------------- ``ResourceComponent`` is also provided to allow static files (like CSS or images) to go alongside templates. You must turn ``ExtraPathInfo`` on in ``Application.config``, and add a component *just* to your ``index.py`` (or ``Main.py``) servlet:: from ZPTKit.resourcecomponent import ResourceComponent class index(SitePage): components = SitePage.components + [ ResourceComponent(zpt_paths)] Then ``zpt_paths`` will be searched for files if no servlet is found by a given name (and it will produce 404s if no file is found either). The normal processing of the ``index`` servlet will be aborted in either case, so long as there is any ``request.extraURLPath()``.