Created
May 7, 2009 20:03
-
-
Save rtyler/108317 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| diff --git a/CHANGES b/CHANGES | |
| index 3007717..ab083a0 100644 | |
| --- a/CHANGES | |
| +++ b/CHANGES | |
| @@ -1,4 +1,7 @@ | |
| +2.1.2 (May 5, 2009) | |
| + - 0000006: [Templates] Support @staticmethod and @classmethod (rtyler) | |
| + | |
| 2.1.1 (April 16, 2009) | |
| - Support __eq__() and __ne__() the way you might expect in src/Tools/RecursiveNull (patch suggested by Peter Warasin <peter@endian.com>) | |
| - Applied patch to avoid hitting the filesystem to get the file modification time everytime a #include directive is processed (Jean-Baptiste Quenot <jbq@caraldi.com>) | |
| diff --git a/SetupConfig.py b/SetupConfig.py | |
| index 1aa8aa7..42dbd43 100644 | |
| --- a/SetupConfig.py | |
| +++ b/SetupConfig.py | |
| @@ -1,5 +1,5 @@ | |
| #-------Main Package Settings-----------# | |
| -name = 'Cheetah' | |
| +name = "Cheetah Community Edition" | |
| from src.Version import Version as version | |
| maintainer = "R. Tyler Ballance" | |
| author = "Tavis Rudd" | |
| @@ -78,6 +78,6 @@ http://www.communitycheetah.org/credits.html | |
| Recent Changes | |
| ================================================================================ | |
| -See http://www.communitycheetah.org/docs/CHANGES for full details | |
| +See http://www.communitycheetah.org/CHANGES.txt for full details | |
| ''' | |
| diff --git a/docs/COPYING b/docs/COPYING | |
| deleted file mode 100644 | |
| index ee79713..0000000 | |
| --- a/docs/COPYING | |
| +++ /dev/null | |
| @@ -1,122 +0,0 @@ | |
| -The Cheetah Users' Guide, Cheetah Developers' Guide and all other | |
| -documentation in this directory is released under the Open | |
| -Publication License (http://www.opencontent.org/openpub/). | |
| - | |
| -Regarding section VI of the Open Publication License, there are no | |
| -"license options" (=additional restrictions) on these works. | |
| - | |
| -A text version of the Open Publication License follows. It was | |
| -downloaded from http://www.opencontent.org/openpub/, converted to | |
| -text with 'links', and (minimally) reformatted by hand. | |
| - | |
| -################################################################### | |
| - Open Publication License | |
| - v1.0, 8 June 1999 | |
| - | |
| - I. REQUIREMENTS ON BOTH UNMODIFIED AND MODIFIED VERSIONS | |
| - | |
| - The Open Publication works may be reproduced and distributed in whole or in | |
| - part, in any medium physical or electronic, provided that the terms of this | |
| - license are adhered to, and that this license or an incorporation of it by | |
| - reference (with any options elected by the author(s) and/or publisher) is | |
| - displayed in the reproduction. | |
| - | |
| - Proper form for an incorporation by reference is as follows: | |
| - | |
| - Copyright (c) <year> by <author's name or designee>. This material may be | |
| - distributed only subject to the terms and conditions set forth in the Open | |
| - Publication License, vX.Y or later (the latest version is presently | |
| - available at http://www.opencontent.org/openpub/). | |
| - | |
| - The reference must be immediately followed with any options elected by the | |
| - author(s) and/or publisher of the document (see section VI). | |
| - | |
| - Commercial redistribution of Open Publication-licensed material is permitted. | |
| - | |
| - Any publication in standard (paper) book form shall require the citation of | |
| - the original publisher and author. The publisher and author's names shall | |
| - appear on all outer surfaces of the book. On all outer surfaces of the book | |
| - the original publisher's name shall be as large as the title of the work and | |
| - cited as possessive with respect to the title. | |
| - | |
| - II. COPYRIGHT | |
| - | |
| - The copyright to each Open Publication is owned by its author(s) or designee. | |
| - | |
| - III. SCOPE OF LICENSE | |
| - | |
| - The following license terms apply to all Open Publication works, unless | |
| - otherwise explicitly stated in the document. | |
| - | |
| - Mere aggregation of Open Publication works or a portion of an Open | |
| - Publication work with other works or programs on the same media shall not | |
| - cause this license to apply to those other works. The aggregate work shall | |
| - contain a notice specifying the inclusion of the Open Publication material | |
| - and appropriate copyright notice. | |
| - | |
| - SEVERABILITY. If any part of this license is found to be unenforceable in any | |
| - jurisdiction, the remaining portions of the license remain in force. | |
| - | |
| - NO WARRANTY. Open Publication works are licensed and provided "as is" without | |
| - warranty of any kind, express or implied, including, but not limited to, the | |
| - implied warranties of merchantability and fitness for a particular purpose or | |
| - a warranty of non-infringement. | |
| - | |
| - IV. REQUIREMENTS ON MODIFIED WORKS | |
| - | |
| - All modified versions of documents covered by this license, including | |
| - translations, anthologies, compilations and partial documents, must meet the | |
| - following requirements: | |
| - | |
| - 1. The modified version must be labeled as such. | |
| - 2. The person making the modifications must be identified and the | |
| - modifications dated. | |
| - 3. Acknowledgement of the original author and publisher if applicable must | |
| - be retained according to normal academic citation practices. | |
| - 4. The location of the original unmodified document must be identified. | |
| - 5. The original author's (or authors') name(s) may not be used to assert or | |
| - imply endorsement of the resulting document without the original author's | |
| - (or authors') permission. | |
| - | |
| - V. GOOD-PRACTICE RECOMMENDATIONS | |
| - | |
| - In addition to the requirements of this license, it is requested from and | |
| - strongly recommended of redistributors that: | |
| - | |
| - 1. If you are distributing Open Publication works on hardcopy or CD-ROM, you | |
| - provide email notification to the authors of your intent to redistribute | |
| - at least thirty days before your manuscript or media freeze, to give the | |
| - authors time to provide updated documents. This notification should | |
| - describe modifications, if any, made to the document. | |
| - 2. All substantive modifications (including deletions) be either clearly | |
| - marked up in the document or else described in an attachment to the | |
| - document. | |
| - 3. Finally, while it is not mandatory under this license, it is considered | |
| - good form to offer a free copy of any hardcopy and CD-ROM expression of | |
| - an Open Publication-licensed work to its author(s). | |
| - | |
| - VI. LICENSE OPTIONS | |
| - | |
| - The author(s) and/or publisher of an Open Publication-licensed document may | |
| - elect certain options by appending language to the reference to or copy of | |
| - the license. These options are considered part of the license instance and | |
| - must be included with the license (or its incorporation by reference) in | |
| - derived works. | |
| - | |
| - A. To prohibit distribution of substantively modified versions without the | |
| - explicit permission of the author(s). "Substantive modification" is defined | |
| - as a change to the semantic content of the document, and excludes mere | |
| - changes in format or typographical corrections. | |
| - | |
| - To accomplish this, add the phrase `Distribution of substantively modified | |
| - versions of this document is prohibited without the explicit permission of | |
| - the copyright holder.' to the license reference or copy. | |
| - | |
| - B. To prohibit any publication of this work or derivative works in whole or | |
| - in part in standard (paper) book form for commercial purposes is prohibited | |
| - unless prior permission is obtained from the copyright holder. | |
| - | |
| - To accomplish this, add the phrase 'Distribution of the work or derivative of | |
| - the work in any standard (paper) book form is prohibited unless prior | |
| - permission is obtained from the copyright holder.' to the license reference | |
| - or copy. | |
| diff --git a/docs/OnePageTutorial.html b/docs/OnePageTutorial.html | |
| deleted file mode 100644 | |
| index eaa9acc..0000000 | |
| --- a/docs/OnePageTutorial.html | |
| +++ /dev/null | |
| @@ -1,546 +0,0 @@ | |
| -<!-- OnePageTutorial.html : | |
| - Originally this was Chuck Esterbrook's tutorial for his template | |
| - maintainers. Eventually this may expand into the future Cheetah | |
| - Quick Reference or Beginners' Guide. | |
| ---> | |
| - | |
| -<html> | |
| - | |
| -<head> | |
| -<title>Cheetah Template One-Page Tutorial</title> | |
| - | |
| -<style type="text/css"> | |
| -<!-- | |
| - | |
| -/* Document-wide styles */ | |
| - | |
| -BODY { | |
| - background-color: white; | |
| -} | |
| - | |
| - | |
| -/* Header styles */ | |
| - | |
| -TD.banner-top { | |
| - background-color: #A43403; | |
| -} | |
| -TD.banner-bottom { | |
| - background-color: #C75509; | |
| - color: #EFA84B; | |
| - font-family: sans-serif; | |
| - font-weight: normal; | |
| - font-size: 14px; | |
| -} | |
| -TD.banner-bottom-active { | |
| - background-color: #C75509; | |
| - color: #EFA84B; | |
| - font-family: sans-serif; | |
| - font-weight: normal; | |
| - font-size: 14px; | |
| -} | |
| -TD.banner-bottom-inactive { | |
| - background-color: #C75509; | |
| - color: #EFA84B; | |
| - font-family: sans-serif; | |
| - font-weight: normal; | |
| - font-size: 14px; | |
| -} | |
| -SPAN.banner-bottom-active { | |
| - background-color: #A43403; | |
| - color: #EFA84B; | |
| - font-family: sans-serif; | |
| - font-weight: bold; | |
| - font-size: 14px; | |
| -} | |
| -SPAN.banner-bottom-inactive { | |
| - background-color: #C75509; | |
| - color: #EFA84B; | |
| - font-family: sans-serif; | |
| - font-weight: bold; | |
| - font-size: 14px; | |
| -} | |
| - | |
| - | |
| - | |
| -TD.banner-menu { | |
| - background-color: #A43403; | |
| - color: #EFA84B; | |
| - font-family: sans-serif; | |
| - font-weight: normal; | |
| - font-size: 14px; | |
| -} | |
| -SPAN.banner-menu { | |
| - background-color: #A43403; | |
| - color: #EFA84B; | |
| - font-family: sans-serif; | |
| - font-weight: bold; | |
| - font-size: 14px; | |
| -} | |
| - | |
| - | |
| - | |
| - | |
| - | |
| -/* Interface body styles */ | |
| - | |
| - | |
| -A:link { | |
| - color: #00638E; | |
| - font-family: sans-serif; | |
| - font-weight: bold; | |
| - text-decoration: none; | |
| -} | |
| - | |
| -/* A:visited */ | |
| -/* A:active */ | |
| - | |
| -TD.action-header { | |
| - color: #7A311C; | |
| - font-family: Verdana, Arial, Helvetica, sans-serif; | |
| - font-weight: bold; | |
| - font-size: 16px; | |
| -} | |
| - | |
| -TD.body { | |
| - color: #C75509; | |
| - font-family: Verdana, Arial, Helvetica, sans-serif; | |
| - font-weight: normal; | |
| - font-size: 14px; | |
| -} | |
| -SPAN.doc_title { | |
| - color: #666666; | |
| - font-family: Verdana, Arial, Helvetica, sans-serif; | |
| - font-weight: normal; | |
| - font-size: 12px; | |
| -} | |
| - | |
| -P.instructions { | |
| - color: #C75509; | |
| - font-family: Verdana, Arial, Helvetica, sans-serif; | |
| - font-weight: normal; | |
| - font-size: 12px; | |
| -} | |
| - | |
| - | |
| - /* | |
| - * Top level page | |
| - */ | |
| - | |
| - body { | |
| - font-family: Verdana, Arial, Helvetica, sans-serif; | |
| - font-size: 80%; | |
| - background-color: #FFFFFF; | |
| - color: black; | |
| - } | |
| - | |
| - p { | |
| - font-family: Verdana, Arial, Helvetica, sans-serif; | |
| - font-size: 12px; | |
| - color: black; | |
| - } | |
| - | |
| - table.banner { | |
| - width: 100%; | |
| - } | |
| - | |
| - td.bannerLogo { | |
| - color: #FFA; | |
| - background-color: orange; | |
| - text-align: center; | |
| - border: 2px solid #FFA; | |
| - padding-left: 3px; | |
| - padding-right: 3px; | |
| - letter-spacing: -2px; | |
| - white-space: nowrap; | |
| - font-family: Arial, Helvetica, sans-serif; | |
| - font-weight: bold; | |
| - font-size: 18px; | |
| - } | |
| - | |
| - td.bannerTitle { | |
| - width: 95%; | |
| - color: darkorange; | |
| - text-align: center; | |
| - font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; | |
| - font-weight: bold; | |
| - font-size: 24px; | |
| - } | |
| - | |
| - td.bannerStuff { | |
| - text-align: right; | |
| - white-space: nowrap; | |
| - font-family: Arial, Helvetica, sans-serif; | |
| - } | |
| - | |
| - a.bannerStuff { | |
| - text-decoration: none; | |
| - } | |
| - | |
| - a.bannerStuff:hover { | |
| - text-decoration: underline; | |
| - } | |
| - | |
| - span.pageFooter { | |
| - } | |
| - | |
| - a.mainMenuLink { | |
| - font-size: 175%; | |
| - } | |
| - | |
| - .error { | |
| - color: red; | |
| - } | |
| - | |
| - /* | |
| - * Tab navigation | |
| - */ | |
| - | |
| - tr.tabTop { | |
| - font-size: 14px; | |
| - } | |
| - | |
| - tr.tabBottom { | |
| - background-color: #149; | |
| - } | |
| - | |
| - td.activeTab { | |
| - font-family: Arial, Helvetica, sans-serif; | |
| - font-weight: bold; | |
| - color: #FFA; | |
| - background-color: #149; | |
| - } | |
| - | |
| - td.inactiveTab { | |
| - font-family: Arial, Helvetica, sans-serif; | |
| - color: #FFA; | |
| - background-color: #DEF; | |
| - } | |
| - | |
| - a.activeTab { | |
| - color: #FFA; | |
| - text-decoration: none; | |
| - } | |
| - | |
| - a.activeTab:hover { | |
| - color: #FFA; | |
| - text-decoration: underline; | |
| - } | |
| - | |
| - a.inactiveTab { | |
| - color: black; | |
| - text-decoration: none; | |
| - } | |
| - | |
| - a.inactiveTab:hover { | |
| - color: black; | |
| - text-decoration: underline; | |
| - } | |
| - | |
| - /* | |
| - * Panels | |
| - */ | |
| - | |
| - table.panel { | |
| - } | |
| - | |
| - tr.panelTitle { | |
| - font-weight: bold; | |
| - background-color: lightblue; | |
| - } | |
| - | |
| - td.panelTitle { | |
| - } | |
| - | |
| - tr.panelBody { | |
| - background-color: #EEEEEE; | |
| - } | |
| - | |
| - | |
| - /* | |
| - * Other | |
| - */ | |
| - | |
| - table.ObjectBrowser { | |
| - } | |
| - | |
| - tr.ObjectBrowser{ | |
| - } | |
| - | |
| - /* This is for a body row of the document list table */ | |
| - td.ObjectBrowserBody { | |
| - background-color: #EEE; | |
| - } | |
| - | |
| - /* This is for the header row of the document list table */ | |
| - td.ObjectBrowserHeader { | |
| - background-color: #C6EFF7; | |
| - font-weight: bold; | |
| - } | |
| - | |
| - td.ObjectBrowserLink { | |
| - background-color: #DEF3BD; | |
| - font-weight: bold; | |
| - } | |
| - | |
| - table.ObjectViewer { | |
| - } | |
| - | |
| - tr.ObjectViewer { | |
| - } | |
| - | |
| - /* This is for the name column of the object view table */ | |
| - td.ObjectViewerName { | |
| - background-color: #C6EFF7; | |
| - font-weight: bold; | |
| - } | |
| - | |
| - /* This is for the value column of the object view table */ | |
| - td.ObjectViewerValue { | |
| - background-color: #EEE; | |
| - } | |
| - | |
| - /* This is for the info column of the object view table */ | |
| - td.ObjectViewerInfo { | |
| - background-color: white; | |
| - } | |
| - | |
| - table.ObjectEditor { | |
| - } | |
| - | |
| - tr.ObjectEditor { | |
| - } | |
| - | |
| - /* This is for the section label of the document edit table */ | |
| - td.ObjectEditorSection { | |
| - background-color: #E6E6E6; | |
| - font-weight: bold; | |
| - font-size: 18px; | |
| - color: #AC003B; | |
| - } | |
| - | |
| - /* This is for the field name column of the document edit table */ | |
| - td.ObjectEditorName { | |
| - background-color: white; | |
| - font-weight: bold; | |
| - } | |
| - | |
| - /* This is for the field value column of the document edit table */ | |
| - td.ObjectEditorValue { | |
| - background-color: white; | |
| - } | |
| - | |
| - /* This is for the info column of the object edit table */ | |
| - td.ObjectEditorInfo { | |
| - background-color: white; | |
| - } | |
| - | |
| - /* This is for the error column of the object edit table */ | |
| - td.ObjectEditorError { | |
| - background-color: white; | |
| - color: red; | |
| - font-weight: bold; | |
| - font-size: 12px; | |
| - } | |
| - | |
| - | |
| - /* | |
| - * Help | |
| - */ | |
| - | |
| - blockquote.example { | |
| - background-color: #EEE; | |
| - } | |
| - | |
| - | |
| - /*********************** from other site *********************/ | |
| - | |
| - td.ColumnHeading { | |
| - font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; | |
| - font-size: 150%; | |
| - font-weight: bold; | |
| - background-color: #FFFF77; | |
| - } | |
| - | |
| - | |
| - /* | |
| - * Sidebar | |
| - */ | |
| - | |
| - span.SidebarHeading { | |
| - font-weight: bold; | |
| - } | |
| - | |
| - a.SidebarLink { | |
| - } | |
| - | |
| - | |
| - /* | |
| - * News | |
| - */ | |
| - | |
| - span.NewsHeading { | |
| - font-family: Tahoma; | |
| - font-size: 14px; | |
| - font-weight: bold; | |
| - } | |
| - | |
| - | |
| - /* | |
| - * Headings | |
| - */ | |
| - | |
| - h1 { | |
| - font-family: Arial, Helvetica; | |
| - font-size: 14px; | |
| - padding-top: 1em; | |
| - padding-bottom: 0; | |
| - } | |
| - | |
| - /* | |
| - * Other | |
| - */ | |
| - | |
| - h2 { font-family: Arial, Helvetica; | |
| - font-size: 14px; | |
| - color: darkblue; | |
| - padding-top: 1em; | |
| - padding-bottom: 0; | |
| - } | |
| - h3 { font-family: Arial, Helvetica; | |
| - font-size: 13px; | |
| - padding-top: 1em; | |
| - padding-bottom: 0; | |
| - } | |
| - h4 { font-family: Arial, Helvetica; | |
| - font-size: 12px; | |
| - padding-top: 1em; | |
| - padding-bottom: 0; | |
| - } | |
| - dl { padding-left: 2em; | |
| - } | |
| - ol { padding-left: 0.5em; | |
| - } | |
| - ul { list-style-type: disc; | |
| - padding-left: 1.0em; | |
| - } | |
| - li { padding-top: 0em; | |
| - } | |
| - table { | |
| - font-family: Verdana, Arial, Helvetica, sans-serif; | |
| - font-size: 100%; | |
| - color: black; | |
| - } | |
| - | |
| ---> | |
| -</style> | |
| - | |
| -</head> | |
| - | |
| -<body> | |
| - | |
| -<h1>Cheetah Template One-Page Tutorial<BR> | |
| -<SMALL>By Chuck Esterbrook, now maintained by Mike Orr<BR> | |
| -Updated May 17, 2002</SMALL></h1> | |
| - | |
| -<h2>Substitution</h2> | |
| - | |
| -<p> The most commonly used templating feature is substitution: | |
| - | |
| -<blockquote class=example><pre> | |
| -My name is $name | |
| -</pre></blockquote> | |
| - | |
| -<p> You can use <i>dotted notation</i> to traverse objects. For example: | |
| - | |
| -<blockquote class=example><pre> | |
| -$author.person.primaryEmail | |
| -</pre></blockquote> | |
| - | |
| -<p> When a variable name is flush against other text you must use curly braces to separate it: | |
| - | |
| -<blockquote class=example><pre> | |
| -Jim is a ${vice}maniac. | |
| -</pre></blockquote> | |
| - | |
| -<p> However, the template language is savvy enough to handle sentence endings and variables: | |
| - | |
| -<blockquote class=example><pre> | |
| -My name is $name. | |
| -$foo$bar | |
| -</pre></blockquote> | |
| - | |
| - | |
| -<h2>#if (conditional)</h2> | |
| - | |
| -<p> The <i>#if</i> statement can be used to detect if a value is blank/undefined/NULL. The most common use for an #if statement is showing a different form of content if something is undefined. | |
| - | |
| -<blockquote class=example><pre> | |
| -#if $keywords | |
| - $keywords | |
| -#else | |
| - There are no keywords! | |
| -#end if | |
| -</pre></blockquote> | |
| - | |
| -<p> The #else part is optional: | |
| - | |
| -<blockquote class=example><pre> | |
| -#if $keywords | |
| - <span class=keywords>$keywords</span> | |
| -#end if | |
| -</blockquote> | |
| - | |
| - | |
| -<h2>#for (looping)</h2> | |
| - | |
| -<p> The <i>#for</i> statement is used to loop through any kind of list. | |
| - | |
| -<blockquote class=example><pre> | |
| -#for $author in $authors | |
| - $author.person.fullName | |
| -#end for | |
| -</pre></blockquote> | |
| - | |
| - | |
| -<h2>Combining statements</h2> | |
| - | |
| -<p> You can combine statements. For example, | |
| - | |
| -<p> Template.html: | |
| -<blockquote class=example><pre> | |
| -$name | |
| - | |
| -<p> $content | |
| - | |
| -#include "authors.html" | |
| -</pre></blockquote> | |
| - | |
| -Authors.html: | |
| -<blockquote class=example><pre> | |
| -#if $authors | |
| - <table class=Author> | |
| - #for $author in $authors | |
| - <tr class=Author> <td class=Author> | |
| - $author | |
| - </td> </tr> | |
| - #end for | |
| - </table> | |
| -#end if | |
| -</pre></blockquote> | |
| - | |
| - | |
| -<h2>Examples</h2> | |
| - | |
| -<p> Here is an example that lists several names and puts commas between them. Note the use of #slurp to slurp up extra whitespace that might interfere. | |
| - | |
| -<blockquote class=example><pre> | |
| -#set sep = '' | |
| -#for $author in $authors | |
| -${sep}${author.person}#slurp | |
| -#set sep = ', ' | |
| -#end for | |
| -</pre></blockquote> | |
| - | |
| -</body> | |
| - | |
| -</html> | |
| diff --git a/docs/README b/docs/README | |
| deleted file mode 100644 | |
| index 3f3fcd7..0000000 | |
| --- a/docs/README | |
| +++ /dev/null | |
| @@ -1,15 +0,0 @@ | |
| -users_guide_src/ : | |
| - Users' Guide for Cheetah 1.0. Will be deleted when users Guide 2 is | |
| - finished. | |
| - | |
| -users_guide_2_src/ : | |
| - Users' Guide and Cookbook for Cheetah 2.0. HTML version has both parts | |
| - in one; PDF version has them as two documents. This section is under | |
| - construction. | |
| - | |
| -devel_guide_src/ : | |
| - Developers' Guide for Cheetah 1.0. Will be deleted when Users' Guide 2 | |
| - is finished. | |
| - | |
| -howto_extras/ : | |
| - Extra content for future HOWTOs and FAQs. May or may not be up to date. | |
| diff --git a/docs/TODO b/docs/TODO | |
| deleted file mode 100644 | |
| index 8c22561..0000000 | |
| --- a/docs/TODO | |
| +++ /dev/null | |
| @@ -1,46 +0,0 @@ | |
| -Cheetah Documentation TODO | |
| --------------------------- | |
| - | |
| -Cheetah FAQ | |
| -=============================================================================== | |
| -A place for specific questions & answers for troubleshooting. Some questions | |
| -may duplicate material in the Users' Guide, but some paragraphs in the UG will | |
| -be moved to the FAQ. | |
| -- Why am I getting a NotFound error? I put my variable in the searchList! | |
| -- Why is my template output empty? | |
| -- Why are my $property, $file, ... placeholders misbehaving? | |
| - | |
| -Users' Guide: | |
| -=============================================================================== | |
| -- 200+ e-mails in MO's mailbox regarding possible doc updates. | |
| -- more examples in the Webware section (EL) | |
| -- more examples/advice all over the Users' Guide about recommended/ | |
| - non-recommended strategies (MO) | |
| - | |
| -Developers' Guide: | |
| -=============================================================================== | |
| -- Finish. (MO) | |
| - | |
| -Quick Reference Guide: | |
| -=============================================================================== | |
| -Cheat sheet on Cheetah syntax and usage. (MO but not soon) | |
| - | |
| -Beginners' Guide: | |
| -=============================================================================== | |
| -Written for somebody who has to maintain templates but | |
| -doesn't know Python. Looking for a writer, somebody who trains such | |
| -maintainers and knows what their needs are. To get the correct LaTeX | |
| -structure, copy users_guide.tex and one of its chapters, and modify as | |
| -necessary. | |
| - | |
| - | |
| -HOWTOs: | |
| -======= | |
| -Somebody offered to write some HOWTOs on specialized topics. Who was it? | |
| - | |
| -BNF: | |
| -==== | |
| -- write a formalized grammar for Cheetah in BNF. MO partly did in | |
| -a Developer's Guide appendix. Essentially, the directives still need | |
| -to be done, and a proofreading of the rest. Move to separate text file and | |
| -find somebody to finish it. | |
| diff --git a/docs/devel_guide_src/Makefile b/docs/devel_guide_src/Makefile | |
| deleted file mode 100755 | |
| index 9e5da96..0000000 | |
| --- a/docs/devel_guide_src/Makefile | |
| +++ /dev/null | |
| @@ -1,38 +0,0 @@ | |
| -# You must change PYTHONSRC to the path of your Python source distributon. | |
| -PYTHONSRC=/home/tavis/tmp/Python-2.2 | |
| -DOCNAME=devel_guide | |
| -MKHOWTO=$(PYTHONSRC)/Doc/tools/mkhowto | |
| -MAIN_TEX_FILE= devel_guide.tex | |
| - | |
| -all: ps pdf html htmlMultiPage text | |
| - | |
| -almost-all: ps html htmlMultiPage text | |
| - | |
| -pdf: | |
| - $(MKHOWTO) --pdf $(MAIN_TEX_FILE) | |
| - mv $(DOCNAME).pdf ../ | |
| - | |
| -ps: | |
| - $(MKHOWTO) --ps $(MAIN_TEX_FILE) | |
| - mv $(DOCNAME).ps ../ | |
| -html: | |
| - -rm -rf $(DOCNAME) | |
| - $(MKHOWTO) --html --split 1 --iconserver . $(MAIN_TEX_FILE) | |
| - -rm -rf ../$(DOCNAME)_html | |
| - mv $(DOCNAME) ../$(DOCNAME)_html | |
| - | |
| -htmlMultiPage: | |
| - -rm -rf $(DOCNAME) | |
| - $(MKHOWTO) --html --iconserver . $(MAIN_TEX_FILE) | |
| - -rm -rf ../$(DOCNAME)_html_multipage | |
| - mv $(DOCNAME) ../$(DOCNAME)_html_multipage | |
| - | |
| -text: | |
| - $(MKHOWTO) --text $(MAIN_TEX_FILE) | |
| - mv $(DOCNAME).txt ../ | |
| - | |
| -clean: | |
| - -rm -rf $(DOCNAME) | |
| - -rm -f *.aux *.l2h *~ *.log *.ind *.bkm *.how *.toc | |
| - -rm -rf ../html | |
| - | |
| diff --git a/docs/devel_guide_src/README b/docs/devel_guide_src/README | |
| deleted file mode 100755 | |
| index 3b45564..0000000 | |
| --- a/docs/devel_guide_src/README | |
| +++ /dev/null | |
| @@ -1,9 +0,0 @@ | |
| -To build the Cheetah documentation, you need the 'mkhowto' program from | |
| -the Python source distribution. So: | |
| - | |
| -1) Get the Python source distribution and unpack it in some directory. | |
| - | |
| -2) Edit the Cheetah documentation's Makefile and change PYTHONSRC to | |
| -point to the top-level directory of your Python source distribution. | |
| - | |
| -3) Run 'make'. | |
| diff --git a/docs/devel_guide_src/bnf.tex b/docs/devel_guide_src/bnf.tex | |
| deleted file mode 100755 | |
| index aa7149c..0000000 | |
| --- a/docs/devel_guide_src/bnf.tex | |
| +++ /dev/null | |
| @@ -1,7 +0,0 @@ | |
| -\section{A BNF Grammar of Cheetah} | |
| -\label{bnf} | |
| - | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "devel_guide" | |
| -% End: | |
| diff --git a/docs/devel_guide_src/cache.tex b/docs/devel_guide_src/cache.tex | |
| deleted file mode 100755 | |
| index 043b8cf..0000000 | |
| --- a/docs/devel_guide_src/cache.tex | |
| +++ /dev/null | |
| @@ -1,365 +0,0 @@ | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\section{Caching placeholders and \#cache} | |
| -\label{cache} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Dynamic placeholder -- no cache} | |
| -\label{cache.dynamic} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -Dynamic variable: $voom | |
| -\end{verbatim} | |
| - | |
| -The command line and the output: | |
| -\begin{verbatim} | |
| -% voom='Voom!' python x.py --env | |
| -Dynamic variable: Voom! | |
| -\end{verbatim} | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| -write('Dynamic variable: ') | |
| -write(filter(VFS(SL,"voom",1))) # generated from '$voom' at line 1, col 20. | |
| -write('\n') | |
| -\end{verbatim} | |
| - | |
| -Just what we expected, like any other dynamic placeholder. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Static placeholder} | |
| -\label{cache.static} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -Cached variable: $*voom | |
| -\end{verbatim} | |
| - | |
| -The command line and output: | |
| -\begin{verbatim} | |
| -% voom='Voom!' python x.py --env | |
| -Cached variable: Voom! | |
| -\end{verbatim} | |
| - | |
| -The generated code, with line numbers: | |
| -\begin{verbatim} | |
| - 1 write('Cached variable: ') | |
| - 2 ## START CACHE REGION: at line, col (1, 19) in the source. | |
| - 3 RECACHE = True | |
| - 4 if not self._cacheData.has_key('19760169'): | |
| - 5 pass | |
| - 6 else: | |
| - 7 RECACHE = False | |
| - 8 if RECACHE: | |
| - 9 orig_trans = trans | |
| -10 trans = cacheCollector = DummyTransaction() | |
| -11 write = cacheCollector.response().write | |
| -12 write(filter(VFS(SL,"voom",1))) # generated from '$*voom' at line 1, | |
| - # col 19. | |
| -13 trans = orig_trans | |
| -14 write = trans.response().write | |
| -15 self._cacheData['19760169'] = cacheCollector.response().getvalue() | |
| -16 del cacheCollector | |
| -17 write(self._cacheData['19760169']) | |
| -18 ## END CACHE REGION | |
| - | |
| -19 write('\n') | |
| -\end{verbatim} | |
| - | |
| -That one little star generated a whole lotta code. First, instead of an | |
| -ordinary \code{VFS} lookup (searchList) lookup, it converted the | |
| -placeholder to a lookup in the \code{.\_cacheData} dictionary. Cheetah also | |
| -generated a unique key (\code{'19760169'}) for our cached item -- this is its | |
| -cache ID. | |
| - | |
| -Second, Cheetah put a pair of if-blocks before the \code{write}. The first | |
| -(lines 3-7) determine whether the cache value is missing or out of date, and | |
| -sets local variable \code{RECACHE} true or false. | |
| -This stanza may look unnecessarily verbose -- lines 3-7 could be eliminated if | |
| -line 8 was changed to | |
| -\begin{verbatim} | |
| -if not self._cacheData.has_key('19760169'): | |
| -\end{verbatim} | |
| --- but this model is expandable for some of the cache features we'll see below. | |
| - | |
| -The second if-block, lines 8-16, do the cache updating if necessary. | |
| -Clearly, the programmer is trying to stick as close to normal (dynamic) | |
| -workflow as possible. Remember that \code{write}, even though it looks like a | |
| -local function, is actually a method of a file-like object. So we create a | |
| -temporary file-like object to divert the \code{write} object into, then read | |
| -the result and stuff it into the cache. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Timed-refresh placeholder} | |
| -\label{cache.timed} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -Timed cache: $*.5m*voom | |
| -\end{verbatim} | |
| - | |
| -The command line and the output: | |
| -\begin{verbatim} | |
| -% voom='Voom!' python x.py --env | |
| -Timed cache: Voom! | |
| -\end{verbatim} | |
| - | |
| -The generated method's docstring: | |
| -\begin{verbatim} | |
| -""" | |
| -This is the main method generated by Cheetah | |
| -This cache will be refreshed every 30.0 seconds. | |
| -""" | |
| -\end{verbatim} | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| - 1 write('Timed cache: ') | |
| - 2 ## START CACHE REGION: at line, col (1, 15) in the source. | |
| - 3 RECACHE = True | |
| - 4 if not self._cacheData.has_key('55048032'): | |
| - 5 self.__cache55048032__refreshTime = currentTime() + 30.0 | |
| - 6 elif currentTime() > self.__cache55048032__refreshTime: | |
| - 7 self.__cache55048032__refreshTime = currentTime() + 30.0 | |
| - 8 else: | |
| - 9 RECACHE = False | |
| -10 if RECACHE: | |
| -11 orig_trans = trans | |
| -12 trans = cacheCollector = DummyTransaction() | |
| -13 write = cacheCollector.response().write | |
| -14 write(filter(VFS(SL,"voom",1))) # generated from '$*.5m*voom' at | |
| - # line 1, col 15. | |
| -15 trans = orig_trans | |
| -16 write = trans.response().write | |
| -17 self._cacheData['55048032'] = cacheCollector.response().getvalue() | |
| -18 del cacheCollector | |
| -19 write(self._cacheData['55048032']) | |
| -20 ## END CACHE REGION | |
| - | |
| -21 write('\n') | |
| -\end{verbatim} | |
| - | |
| -This code is identical to the static cache example except for the docstring | |
| -and the first if-block. (OK, so the cache ID is different and the comment on | |
| -line 14 is different too. Big deal.) | |
| - | |
| -Each timed-refresh cache item has a corrsponding private attribute | |
| -\code{.\_\_cache\#\#\#\#\#\#\#\#\_\_refreshTime} giving the refresh time | |
| -in ticks (=seconds since January 1, 1970). The first if-block (lines 3-9) | |
| -checks whether the cache value is missing or its update time has passed, and if | |
| -so, sets \code{RECACHE} to true and also schedules another refresh at the next | |
| -interval. | |
| - | |
| -The method docstring reminds the user how often the cache will be refreshed. | |
| -This information is unfortunately not as robust as it could be. Each | |
| -timed-cache placeholder blindly generates a line in the docstring. If all | |
| -refreshes are at the same interval, there will be multiple identical lines | |
| -in the docstring. If the refreshes are at different intervals, you get a | |
| -situation like this: | |
| -\begin{verbatim} | |
| -""" | |
| -This is the main method generated by Cheetah | |
| -This cache will be refreshed every 30.0 seconds. | |
| -This cache will be refreshed every 60.0 seconds. | |
| -This cache will be refreshed every 120.0 seconds. | |
| -""" | |
| -\end{verbatim} | |
| -The docstring tells only that ``something'' will be refreshed every 60.0 | |
| -seconds, but doesn't reveal {\em which} placeholder that is. Only if you | |
| -know the relative order of the placeholders in the template can you figure | |
| -that out. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Timed-refresh placeholder with braces} | |
| -\label{cache.timed.braces} | |
| - | |
| -This example is the same but with the long placeholder syntax. It's here | |
| -because it's a Cheetah FAQ whether to put the cache interval inside or outside | |
| -the braces. (It's also here so I can look it up because I frequently forget.) | |
| -The answer is: outside. The braces go around only the placeholder name (and | |
| -perhaps some output-filter arguments.) | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -Timed with {}: $*.5m*{voom} | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -Timed with {}: Voom! | |
| -\end{verbatim} | |
| - | |
| -The generated code differs only in the comment. Inside the cache-refresh | |
| -if-block: | |
| -\begin{verbatim} | |
| -write(filter(VFS(SL,"voom",1))) # generated from '$*.5m*{voom}' at line 1, | |
| - #col 17. | |
| -\end{verbatim} | |
| - | |
| -If you try to do it this way: | |
| -\begin{verbatim} | |
| -Timed with {}: ${*.5m*voom} ## Wrong! | |
| -\end{verbatim} | |
| -you get: | |
| -\begin{verbatim} | |
| -Timed with {}: ${*.5m*voom} | |
| -\end{verbatim} | |
| -\verb+${+ is not a valid placeholder, so it gets treated as ordinary text. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#cache} | |
| -\label{cache.directive} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#cache | |
| -This is a cached region. $voom | |
| -#end cache | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -This is a cached region. Voom! | |
| -\end{verbatim} | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| - 1 ## START CACHE REGION: at line, col (1, 1) in the source. | |
| - 2 RECACHE = True | |
| - 3 if not self._cacheData.has_key('23711421'): | |
| - 4 pass | |
| - 5 else: | |
| - 6 RECACHE = False | |
| - 7 if RECACHE: | |
| - 8 orig_trans = trans | |
| - 9 trans = cacheCollector = DummyTransaction() | |
| -10 write = cacheCollector.response().write | |
| -11 write('This is a cached region. ') | |
| -12 write(filter(VFS(SL,"voom",1))) # generated from '$voom' at line 2, | |
| - # col 27. | |
| -13 write('\n') | |
| -14 trans = orig_trans | |
| -15 write = trans.response().write | |
| -16 self._cacheData['23711421'] = cacheCollector.response().getvalue() | |
| -17 del cacheCollector | |
| -18 write(self._cacheData['23711421']) | |
| -19 ## END CACHE REGION | |
| -\end{verbatim} | |
| - | |
| -This is the same as the \code{\$*voom} example, except that the plain text | |
| -around the placeholder is inside the second if-block. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#cache with timer and id} | |
| -\label{cache.directive.timer} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#cache timer='.5m', id='cache1' | |
| -This is a cached region. $voom | |
| -#end cache | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -This is a cached region. Voom! | |
| -\end{verbatim} | |
| - | |
| -The generated code is the same as the previous example except the first | |
| -if-block: | |
| -\begin{verbatim} | |
| -RECACHE = True | |
| -if not self._cacheData.has_key('13925129'): | |
| - self._cacheIndex['cache1'] = '13925129' | |
| - self.__cache13925129__refreshTime = currentTime() + 30.0 | |
| -elif currentTime() > self.__cache13925129__refreshTime: | |
| - self.__cache13925129__refreshTime = currentTime() + 30.0 | |
| -else: | |
| - RECACHE = False | |
| -\end{verbatim} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#cache with test: expression and method conditions} | |
| -\label{cache.directive.test} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#cache test=$isDBUpdated | |
| -This is a cached region. $voom | |
| -#end cache | |
| -\end{verbatim} | |
| - | |
| -(Analysis postponed: bug in Cheetah produces invalid Python.) | |
| - | |
| -%The output: | |
| -%\begin{verbatim} | |
| -%\end{verbatim} | |
| - | |
| -%The generated code: | |
| -%\begin{verbatim} | |
| -%\end{verbatim} | |
| - | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#cache id='cache1', test=($isDBUpdated or $someOtherCondition) | |
| -This is a cached region. $voom | |
| -#end cache | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -This is a cached region. Voom! | |
| -\end{verbatim} | |
| - | |
| -The first if-block in the generated code: | |
| -\begin{verbatim} | |
| -RECACHE = True | |
| -if not self._cacheData.has_key('36798144'): | |
| - self._cacheIndex['cache1'] = '36798144' | |
| -elif (VFS(SL,"isDBUpdated",1) or VFS(SL,"someOtherCondition",1)): | |
| - RECACHE = True | |
| -else: | |
| - RECACHE = False | |
| -\end{verbatim} | |
| -The second if-block is the same as in the previous example. If you leave | |
| -out the \code{()} around the test expression, the result is the same, although | |
| -it may be harder for the template maintainer to read. | |
| - | |
| -You can even combine arguments, although this is of questionable value. | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#cache id='cache1', timer='30m', test=$isDBUpdated or $someOtherCondition | |
| -This is a cached region. $voom | |
| -#end cache | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -This is a cached region. Voom! | |
| -\end{verbatim} | |
| - | |
| -The first if-block: | |
| -\begin{verbatim} | |
| -RECACHE = True | |
| -if not self._cacheData.has_key('88939345'): | |
| - self._cacheIndex['cache1'] = '88939345' | |
| - self.__cache88939345__refreshTime = currentTime() + 1800.0 | |
| -elif currentTime() > self.__cache88939345__refreshTime: | |
| - self.__cache88939345__refreshTime = currentTime() + 1800.0 | |
| -elif VFS(SL,"isDBUpdated",1) or VFS(SL,"someOtherCondition",1): | |
| - RECACHE = True | |
| -else: | |
| - RECACHE = False | |
| -\end{verbatim} | |
| - | |
| -We are planning to add a \code{'varyBy'} keyword argument in the future that | |
| -will allow separate cache instances to be created for a variety of conditions, | |
| -such as different query string parameters or browser types. This is inspired by | |
| -ASP.net's varyByParam and varyByBrowser output caching keywords. Since this is | |
| -not implemented yet, I cannot provide examples here. | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "devel_guide" | |
| -% End: | |
| diff --git a/docs/devel_guide_src/comments.tex b/docs/devel_guide_src/comments.tex | |
| deleted file mode 100755 | |
| index 4a7bdbd..0000000 | |
| --- a/docs/devel_guide_src/comments.tex | |
| +++ /dev/null | |
| @@ -1,100 +0,0 @@ | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\section{Directives: Comments} | |
| -\label{comments} | |
| - | |
| -The template: | |
| - | |
| -\begin{verbatim} | |
| -Text before the comment. | |
| -## The comment. | |
| -Text after the comment. | |
| -#* A multi-line comment spanning several lines. | |
| - It spans several lines, too. | |
| -*# | |
| -Text after the multi-line comment. | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| - | |
| -\begin{verbatim} | |
| -Text before the comment. | |
| -Text after the comment. | |
| - | |
| -Text after the multi-line comment. | |
| - | |
| -\end{verbatim} | |
| - | |
| -The generated code: | |
| - | |
| -\begin{verbatim} | |
| - write('Text before the comment.\n') | |
| - # The comment. | |
| - write('Text after the comment.\n') | |
| - # A multi-line comment spanning several lines. | |
| - # It spans several lines, too. | |
| - write('\nText after the multi-line comment.\n') | |
| -\end{verbatim} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Docstring and header comments} | |
| -\label{comments.docstring} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -##doc: .respond() method comment. | |
| -##doc-method: Another .respond() method comment. | |
| -##doc-class: A class comment. | |
| -##doc-module: A module comment. | |
| -##header: A header comment. | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| - | |
| -\end{verbatim} | |
| - | |
| -The beginning of the generated \code{.respond} method: | |
| -\begin{verbatim} | |
| -def respond(self, | |
| - trans=None, | |
| - dummyTrans=False, | |
| - VFS=valueFromSearchList, | |
| - VFN=valueForName, | |
| - getmtime=getmtime, | |
| - currentTime=time.time): | |
| - | |
| - """ | |
| - This is the main method generated by Cheetah | |
| - .respond() method comment. | |
| - Another .respond() method comment. | |
| - """ | |
| -\end{verbatim} | |
| - | |
| -The class docstring: | |
| -\begin{verbatim} | |
| -""" | |
| -A class comment. | |
| - | |
| -Autogenerated by CHEETAH: The Python-Powered Template Engine | |
| -""" | |
| -\end{verbatim} | |
| - | |
| -The top of the module: | |
| -\begin{verbatim} | |
| -#!/usr/bin/env python | |
| -# A header comment. | |
| - | |
| -"""A module comment. | |
| - | |
| -Autogenerated by CHEETAH: The Python-Powered Template Engine | |
| - CHEETAH VERSION: 0.9.13a1 | |
| - Generation time: Fri Apr 26 22:39:23 2002 | |
| - Source file: x.tmpl | |
| - Source file last modified: Fri Apr 26 22:36:23 2002 | |
| -""" | |
| -\end{verbatim} | |
| - | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "devel_guide" | |
| -% End: | |
| diff --git a/docs/devel_guide_src/compiler.tex b/docs/devel_guide_src/compiler.tex | |
| deleted file mode 100755 | |
| index e27aa94..0000000 | |
| --- a/docs/devel_guide_src/compiler.tex | |
| +++ /dev/null | |
| @@ -1,8 +0,0 @@ | |
| -\section{The compiler} | |
| -\label{compiler} | |
| - | |
| -How templates are compiled: a walk through Compiler.py. | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "devel_guide" | |
| -% End: | |
| diff --git a/docs/devel_guide_src/design.tex b/docs/devel_guide_src/design.tex | |
| deleted file mode 100755 | |
| index 3008a63..0000000 | |
| --- a/docs/devel_guide_src/design.tex | |
| +++ /dev/null | |
| @@ -1,102 +0,0 @@ | |
| -\section{Design Decisions and Tradeoffs} | |
| -\label{design} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Delimiters} | |
| -\label{design.Delimiters} | |
| - | |
| -One of the first decisions we encountered was which delimiter syntax to use. | |
| -We decided to follow Velocity's \code{\$placeholder} and \code{\#directive} | |
| -syntax because the former is widely used in other languages for the same | |
| -purpose, and the latter stands out in an HTML or text document. We also | |
| -implemented the \verb+${longPlaceholder}+ syntax like the shells for cases | |
| -where Cheetah or you might be confused where a placeholder ends. Tavis went | |
| -ahead and made \verb+${longPlaceholder}+ and \verb+$[longPlaceholder]+ | |
| -interchangeable with it since it was trivial to implement. Finally, | |
| -the \code{\#compiler} directive allows you to change the delimiters if you | |
| -don't like them or if they conflict with the text in your document. | |
| -(Obviously, if your document contains a Perl program listing, you don't | |
| -necessarily want to backslash each and every \code{\$} and \code{\#}, do you?) | |
| - | |
| -The choice of comment delimiters was more arbitrary. \code{\#\#} and | |
| -\code{\#* \ldots *\#} doesn't match any language, but it's reminiscent of | |
| -Python and C while also being consistent with our ``\code{\#} is for | |
| -directives'' convention. | |
| - | |
| -We specifically chose {\em not} to use pseudo HTML tags for placeholders and | |
| -directives, as described more thoroughly in the Cheetah Users' Guide | |
| -introduction. Pseudo HTML tags may be easier to see in a visual editor | |
| -(supposedly), but in text editors they're hard to distinguish from ``real'' | |
| -HTML tags unless you look closely, and they're many more keystrokes to type. | |
| -Also, if you make a mistake, the tag will show up as literal text in the | |
| -rendered HTML page where it will be easy to notice and eradicate, rather than | |
| -disappearing as bogus HTML tags do in browsers. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Late binding} | |
| -\label{design.lateBinding} | |
| - | |
| -One of Cheetah's unique features is the name mapper, which lets you write | |
| -\code{\$a.b} without worrying much about the type of \code{a} or \code{b}. | |
| -Prior to version 0.9.7, Cheetah did the entire NameMapper lookup at runtime. | |
| -This provided maximum flexibility at the expense of speed. Doing a NameMapper | |
| -lookup is intrinsically more expensive than an ordinary Python expression | |
| -because Cheetah has to decide what type of container \code{a} is, whether the | |
| -the value is a function (autocall it), issue the appropriate Python incantation | |
| -to look up \code{b} in it, autocall again if necessary, and then convert the | |
| -result to a string. | |
| - | |
| -To maximize run-time (filling-time) performance, Cheetah 0.9.7 pushed much of | |
| -this work back into the compiler. The compiler looked up \code{a} in the | |
| -searchList at compile time, noted its type, and generated an eval'able Python | |
| -expression based on that. | |
| - | |
| -This approach had two significant drawbacks. What if \code{a} later changes | |
| -type before a template filling? Answer: unpredictable exceptions occur. What | |
| -if \code{a} does not exist in the searchList at compile time? Answer: the | |
| -template can't compile. | |
| - | |
| -To prevent these catastrophes, users were required to prepopulate the | |
| -searchList before instantiating the template instance, and then not to change | |
| -\code{a}'s type. Static typing is repugnant in a dynamic language like Python, | |
| -and having to prepopulate the searchList made certain usages impossible. For | |
| -example, you couldn't instantiate the template object without a searchList and | |
| -then set \code{self} attributes to specify the values. | |
| - | |
| -After significant user complaints about the fragility of this system, Tavis | |
| -rewrote placeholder handling, and in version 0.9.8a3 (August 2001), Tavis | |
| -moved the name mapper lookup back into runtime. Performance wasn't crippled | |
| -because he discovered that writing a C version of the name mapper was easier | |
| -than anticipated, and the C version completed the lookup quickly. Now Cheetah | |
| -had ``late binding'', meaning the compiler does not look up \code{a} or care | |
| -whether it exists. This allows users to create \code{a} or change its type | |
| -anytime before a template filling. | |
| - | |
| -The lesson we learned is that it's better to decide what you want and then | |
| -figure out how to do it, rather than assuming that certain goals are | |
| -unattainable due to performance considerations. | |
| - | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Caching framework} | |
| -\label{design.cache} | |
| - | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Webware compatibility and the transaction framework} | |
| -\label{design.webware} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Single inheritance} | |
| -\label{design.singleInheritance} | |
| - | |
| - | |
| - | |
| - | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "devel_guide" | |
| -% End: | |
| diff --git a/docs/devel_guide_src/devel_guide.tex b/docs/devel_guide_src/devel_guide.tex | |
| deleted file mode 100755 | |
| index 1e795c4..0000000 | |
| --- a/docs/devel_guide_src/devel_guide.tex | |
| +++ /dev/null | |
| @@ -1,55 +0,0 @@ | |
| -\documentclass{howto} | |
| -\usepackage{moreverb} %% Verbatim Code Listings | |
| - | |
| -\title{Cheetah Developers' Guide} | |
| -\release{0.9.15a1} | |
| - | |
| -\author{Mike Orr with assistance from Tavis Rudd} | |
| -\authoraddress{\email{iron@mso.oz.net}} | |
| - | |
| -\begin{document} | |
| -\maketitle | |
| - | |
| - | |
| -\tableofcontents | |
| - | |
| -\copyright{Copyright 2002, Mike Orr. | |
| - This document may be copied and modified under the terms of the | |
| - {\bf Open Publication License} \url{http://www.opencontent.org/openpub/} } | |
| - | |
| - | |
| - %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| - \include{introduction} | |
| - | |
| - %% How the directives affect the .py template module. | |
| - \include{pyModules} | |
| - \include{placeholders} | |
| - \include{cache} | |
| - \include{comments} | |
| - \include{output} | |
| - \include{inheritanceEtc} | |
| - \include{flowControl} | |
| - \include{errorHandling} | |
| - \include{parserInstructions} | |
| - | |
| - %% A walk through the Cheetah source. | |
| - \include{files} | |
| - \include{template} | |
| - \include{parser} | |
| - \include{compiler} | |
| - | |
| - %% Other development issues and howtos. | |
| - \include{history} | |
| - \include{design} | |
| - \include{patching} | |
| - \include{documenting} | |
| - | |
| - %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| - \appendix | |
| - \include{bnf} | |
| - \include{safeDelegation} | |
| -\end{document} | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| diff --git a/docs/devel_guide_src/documenting.tex b/docs/devel_guide_src/documenting.tex | |
| deleted file mode 100755 | |
| index 51d5153..0000000 | |
| --- a/docs/devel_guide_src/documenting.tex | |
| +++ /dev/null | |
| @@ -1,8 +0,0 @@ | |
| -\section{Documenting Cheetah} | |
| -\label{documenting} | |
| - | |
| -How to build the documentation. Why LaTeX, a minimum LaTeX reference, etc. | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "devel_guide" | |
| -% End: | |
| diff --git a/docs/devel_guide_src/errorHandling.tex b/docs/devel_guide_src/errorHandling.tex | |
| deleted file mode 100755 | |
| index 02079d5..0000000 | |
| --- a/docs/devel_guide_src/errorHandling.tex | |
| +++ /dev/null | |
| @@ -1,309 +0,0 @@ | |
| -\section{Directives: Error Handling} | |
| -\label{errorHandling} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#try and \#raise} | |
| -\label{errorHandling.try} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#import traceback | |
| -#try | |
| -#raise RuntimeError | |
| -#except RuntimeError | |
| -A runtime error occurred. | |
| -#end try | |
| - | |
| -#try | |
| -#raise RuntimeError("Hahaha!") | |
| -#except RuntimeError | |
| -#echo $sys.exc_info()[1] | |
| -#end try | |
| - | |
| -#try | |
| -#echo 1/0 | |
| -#except ZeroDivisionError | |
| -You can't divide by zero, idiot! | |
| -#end try | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -A runtime error occurred. | |
| - | |
| -Hahaha! | |
| - | |
| -You can't divide by zero, idiot! | |
| -\end{verbatim} | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| -try: | |
| - raise RuntimeError | |
| -except RuntimeError: | |
| - write('A runtime error occurred.\n') | |
| -write('\n') | |
| -try: | |
| - raise RuntimeError("Hahaha!") | |
| -except RuntimeError: | |
| - write(filter(VFN(sys,"exc_info",0)()[1])) | |
| - write('\n') | |
| -write('\n') | |
| -try: | |
| - write(filter(1/0)) | |
| - write('\n') | |
| -except ZeroDivisionError: | |
| - write("You can't divide by zero, idiot!\n") | |
| -\end{verbatim} | |
| - | |
| -\code{\#finally} works just like in Python. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#assert} | |
| -\label{errorHandling.assert} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#assert False, "You lose, buster!" | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -Traceback (most recent call last): | |
| - File "x.py", line 117, in ? | |
| - x().runAsMainProgram() | |
| - File "/local/opt/Python/lib/python2.2/site-packages/Webware/Cheetah/ | |
| -Template.py", line 331, in runAsMainProgram | |
| - CmdLineIface(templateObj=self).run() | |
| - File "/local/opt/Python/lib/python2.2/site-packages/Webware/Cheetah/ | |
| -TemplateCmdLineIface.py", line 59, in run | |
| - print self._template | |
| - File "x.py", line 91, in respond | |
| - assert False, "You lose, buster!" | |
| -AssertionError: You lose, buster! | |
| -\end{verbatim} | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| -assert False, "You lose, buster!" | |
| -\end{verbatim} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#errorCatcher} | |
| -\label{errorHandling.errorCatcher} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{No error catcher} | |
| -\label{errorHandling.errorCatcher.no} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -$noValue | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| - | |
| -Traceback (most recent call last): | |
| - File "x.py", line 118, in ? | |
| - x().runAsMainProgram() | |
| - File "/local/opt/Python/lib/python2.2/site-packages/Webware/Cheetah/ | |
| -Template.py", line 331, in runAsMainProgram | |
| - CmdLineIface(templateObj=self).run() | |
| - File "/local/opt/Python/lib/python2.2/site-packages/Webware/Cheetah/ | |
| -TemplateCmdLineIface.py", line 59, in run | |
| - print self._template | |
| - File "x.py", line 91, in respond | |
| - write(filter(VFS(SL,"noValue",1))) # generated from '$noValue' at line | |
| -1, col 1. | |
| -NameMapper.NotFound: noValue | |
| -\end{verbatim} | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| -write(filter(VFS(SL,"noValue",1))) # generated from '$noValue' at line 1, | |
| - # col 1. | |
| -write('\n') | |
| -\end{verbatim} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{Echo and BigEcho} | |
| -\label{errorHandling.errorCatcher.echo} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#errorCatcher Echo | |
| -$noValue | |
| -#errorCatcher BigEcho | |
| -$noValue | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -$noValue | |
| -===============<$noValue could not be found>=============== | |
| -\end{verbatim} | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| -if self._errorCatchers.has_key("Echo"): | |
| - self._errorCatcher = self._errorCatchers["Echo"] | |
| -else: | |
| - self._errorCatcher = self._errorCatchers["Echo"] = ErrorCatchers.Echo(self) | |
| -write(filter(self.__errorCatcher1(localsDict=locals()))) | |
| - # generated from '$noValue' at line 2, col 1. | |
| -write('\n') | |
| -if self._errorCatchers.has_key("BigEcho"): | |
| - self._errorCatcher = self._errorCatchers["BigEcho"] | |
| -else: | |
| - self._errorCatcher = self._errorCatchers["BigEcho"] = \ | |
| - ErrorCatchers.BigEcho(self) | |
| -write(filter(self.__errorCatcher1(localsDict=locals()))) | |
| - # generated from '$noValue' at line 4, col 1. | |
| -write('\n') | |
| -\end{verbatim} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{ListErrors} | |
| -\label{errorHandling.errorCatcher.listErrors} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#import pprint | |
| -#errorCatcher ListErrors | |
| -$noValue | |
| -$anotherMissingValue.really | |
| -$pprint.pformat($errorCatcher.listErrors) | |
| -## This is really self.errorCatcher().listErrors() | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -$noValue | |
| -$anotherMissingValue.really | |
| -[{'code': 'VFS(SL,"noValue",1)', | |
| - 'exc_val': <NameMapper.NotFound instance at 0x8170ecc>, | |
| - 'lineCol': (3, 1), | |
| - 'rawCode': '$noValue', | |
| - 'time': 'Wed May 15 00:38:23 2002'}, | |
| - {'code': 'VFS(SL,"anotherMissingValue.really",1)', | |
| - 'exc_val': <NameMapper.NotFound instance at 0x816d0fc>, | |
| - 'lineCol': (4, 1), | |
| - 'rawCode': '$anotherMissingValue.really', | |
| - 'time': 'Wed May 15 00:38:23 2002'}] | |
| -\end{verbatim} | |
| - | |
| -The generated import: | |
| -\begin{verbatim} | |
| -import pprint | |
| -\end{verbatim} | |
| - | |
| -Then in the generated class, we have our familiar \code{.respond} method | |
| -and several new methods: | |
| -\begin{verbatim} | |
| -def __errorCatcher1(self, localsDict={}): | |
| - """ | |
| - Generated from $noValue at line, col (3, 1). | |
| - """ | |
| - | |
| - try: | |
| - return eval('''VFS(SL,"noValue",1)''', globals(), localsDict) | |
| - except self._errorCatcher.exceptions(), e: | |
| - return self._errorCatcher.warn(exc_val=e, code= 'VFS(SL,"noValue",1)' , | |
| - rawCode= '$noValue' , lineCol=(3, 1)) | |
| - | |
| -def __errorCatcher2(self, localsDict={}): | |
| - """ | |
| - Generated from $anotherMissingValue.really at line, col (4, 1). | |
| - """ | |
| - | |
| - try: | |
| - return eval('''VFS(SL,"anotherMissingValue.really",1)''', globals(), | |
| - localsDict) | |
| - except self._errorCatcher.exceptions(), e: | |
| - return self._errorCatcher.warn(exc_val=e, | |
| - code= 'VFS(SL,"anotherMissingValue.really",1)' , | |
| - rawCode= '$anotherMissingValue.really' , lineCol=(4, 1)) | |
| - | |
| -def __errorCatcher3(self, localsDict={}): | |
| - """ | |
| - Generated from $pprint.pformat($errorCatcher.listErrors) at line, col | |
| - (5, 1). | |
| - """ | |
| - | |
| - try: | |
| - return eval('''VFN(pprint,"pformat",0)(VFS(SL, | |
| - "errorCatcher.listErrors",1))''', globals(), localsDict) | |
| - except self._errorCatcher.exceptions(), e: | |
| - return self._errorCatcher.warn(exc_val=e, code= | |
| - 'VFN(pprint,"pformat",0)(VFS(SL,"errorCatcher.listErrors",1))' , | |
| - rawCode= '$pprint.pformat($errorCatcher.listErrors)' , | |
| - lineCol=(5, 1)) | |
| -\end{verbatim} | |
| -\begin{verbatim} | |
| -def respond(self, | |
| - trans=None, | |
| - dummyTrans=False, | |
| - VFS=valueFromSearchList, | |
| - VFN=valueForName, | |
| - getmtime=getmtime, | |
| - currentTime=time.time): | |
| - | |
| - | |
| - """ | |
| - This is the main method generated by Cheetah | |
| - """ | |
| - | |
| - if not trans: | |
| - trans = DummyTransaction() | |
| - dummyTrans = True | |
| - write = trans.response().write | |
| - SL = self._searchList | |
| - filter = self._currentFilter | |
| - globalSetVars = self._globalSetVars | |
| - | |
| - ######################################## | |
| - ## START - generated method body | |
| - | |
| - if exists(self._filePath) and getmtime(self._filePath) > self._fileMtime: | |
| - self.compile(file=self._filePath) | |
| - write(getattr(self, self._mainCheetahMethod_for_x)(trans=trans)) | |
| - if dummyTrans: | |
| - return trans.response().getvalue() | |
| - else: | |
| - return "" | |
| - if self._errorCatchers.has_key("ListErrors"): | |
| - self._errorCatcher = self._errorCatchers["ListErrors"] | |
| - else: | |
| - self._errorCatcher = self._errorCatchers["ListErrors"] = \ | |
| - ErrorCatchers.ListErrors(self) | |
| - write(filter(self.__errorCatcher1(localsDict=locals()))) | |
| - # generated from '$noValue' at line 3, col 1. | |
| - write('\n') | |
| - write(filter(self.__errorCatcher2(localsDict=locals()))) | |
| - # generated from '$anotherMissingValue.really' at line 4, col 1. | |
| - write('\n') | |
| - write(filter(self.__errorCatcher3(localsDict=locals()))) | |
| - # generated from '$pprint.pformat($errorCatcher.listErrors)' at line | |
| - # 5, col 1. | |
| - write('\n') | |
| - # This is really self.errorCatcher().listErrors() | |
| - | |
| - ######################################## | |
| - ## END - generated method body | |
| - | |
| - if dummyTrans: | |
| - return trans.response().getvalue() | |
| - else: | |
| - return "" | |
| -\end{verbatim} | |
| - | |
| -So whenever an error catcher is active, each placeholder gets wrapped in its | |
| -own method. No wonder error catchers slow down the system! | |
| - | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "devel_guide" | |
| -% End: | |
| diff --git a/docs/devel_guide_src/files.tex b/docs/devel_guide_src/files.tex | |
| deleted file mode 100755 | |
| index 0ce45a9..0000000 | |
| --- a/docs/devel_guide_src/files.tex | |
| +++ /dev/null | |
| @@ -1,11 +0,0 @@ | |
| -\section{Files} | |
| -\label{files} | |
| - | |
| -This chapter will be an overview of the files in the Cheetah package, | |
| -and how they interrelate in compiling and filling a template. We'll | |
| -also look at files in the Cheetah tarball that don't get copied into | |
| -the package. | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "devel_guide" | |
| -% End: | |
| diff --git a/docs/devel_guide_src/flowControl.tex b/docs/devel_guide_src/flowControl.tex | |
| deleted file mode 100755 | |
| index 936df67..0000000 | |
| --- a/docs/devel_guide_src/flowControl.tex | |
| +++ /dev/null | |
| @@ -1,360 +0,0 @@ | |
| -\section{Directives: Flow Control} | |
| -\label{flowControl} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#for} | |
| -\label{flowControl.for} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#for $i in $range(10) | |
| -$i #slurp | |
| -#end for | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -0 1 2 3 4 5 6 7 8 9 | |
| -\end{verbatim} | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| -for i in range(10): | |
| - write(filter(i)) # generated from '$i' at line 2, col 1. | |
| - write(' ') | |
| -\end{verbatim} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#repeat} | |
| -\label{flowControl.repeat} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#repeat 3 | |
| -My bonnie lies over the ocean | |
| -#end repeat | |
| -O, bring back my bonnie to me! | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -My bonnie lies over the ocean | |
| -My bonnie lies over the ocean | |
| -My bonnie lies over the ocean | |
| -O, bring back my bonnie to me! | |
| -\end{verbatim} | |
| -(OK, so the second line should be ``sea'' instead of ``ocean''.) | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| -for __i0 in range(3): | |
| - write('My bonnie lies over the ocean\n') | |
| -write('O, bring back my bonnie to me!\n') | |
| -\end{verbatim} | |
| - | |
| -Note that a new local variable of the form \code{\_\_i\$num} will be | |
| -used for each instance of \code{repeat} in order to permit nesting. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#while} | |
| -\label{flowControl.while} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#set $alive = True | |
| -#while $alive | |
| -I am alive! | |
| -#set $alive = False | |
| -#end while | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -I am alive! | |
| -\end{verbatim} | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| -alive = True | |
| -while alive: | |
| - write('I am alive!\n') | |
| - alive = False | |
| -\end{verbatim} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#if} | |
| -\label{} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#set $size = 500 | |
| -#if $size >= 1500 | |
| -It's big | |
| -#else if $size < 1500 and $size > 0 | |
| -It's small | |
| -#else | |
| -It's not there | |
| -#end if | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -It's small | |
| -\end{verbatim} | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| -size = 500 | |
| -if size >= 1500: | |
| - write("It's big\n") | |
| -elif size < 1500 and size > 0: | |
| - write("It's small\n") | |
| -else: | |
| - write("It's not there\n") | |
| -\end{verbatim} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#unless} | |
| -\label{flowControl.unless} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#set $count = 9 | |
| -#unless $count + 5 > 15 | |
| -Count is in range. | |
| -#end unless | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -Count is in range. | |
| -\end{verbatim} | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| - count = 9 | |
| - if not (count + 5 > 15): | |
| - write('Count is in range.\n') | |
| -\end{verbatim} | |
| - | |
| -{\em Note:} There is a bug in Cheetah 0.9.13. It's forgetting the | |
| -parentheses in the \code{if} expression, which could lead to it calculating | |
| -something different than it should. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#break and \#continue} | |
| -\label{flowControl.break} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#for $i in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 'James', 'Joe', 'Snow'] | |
| -#if $i == 10 | |
| - #continue | |
| -#end if | |
| -#if $i == 'Joe' | |
| - #break | |
| -#end if | |
| -$i - #slurp | |
| -#end for | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 11 - 12 - James - | |
| -\end{verbatim} | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| -for i in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 'James', 'Joe', 'Snow']: | |
| - if i == 10: | |
| - write('') | |
| - continue | |
| - if i == 'Joe': | |
| - write('') | |
| - break | |
| - write(filter(i)) # generated from '$i' at line 8, col 1. | |
| - write(' - ') | |
| -\end{verbatim} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#pass} | |
| -\label{flowControl.pass} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -Let's check the number. | |
| -#set $size = 500 | |
| -#if $size >= 1500 | |
| -It's big | |
| -#elif $size > 0 | |
| -#pass | |
| -#else | |
| -Invalid entry | |
| -#end if | |
| -Done checking the number. | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -Let's check the number. | |
| -Done checking the number. | |
| -\end{verbatim} | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| -write("Let's check the number.\n") | |
| -size = 500 | |
| -if size >= 1500: | |
| - write("It's big\n") | |
| -elif size > 0: | |
| - pass | |
| -else: | |
| - write('Invalid entry\n') | |
| -write('Done checking the number.\n') | |
| -\end{verbatim} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#stop} | |
| -\label{flowControl.stop} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -A cat | |
| -#if 1 | |
| - sat on a mat | |
| - #stop | |
| - watching a rat | |
| -#end if | |
| -in a flat. | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -A cat | |
| - sat on a mat | |
| -\end{verbatim} | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| -write('A cat\n') | |
| -if 1: | |
| - write(' sat on a mat\n') | |
| - if dummyTrans: | |
| - return trans.response().getvalue() | |
| - else: | |
| - return "" | |
| - write(' watching a rat\n') | |
| -write('in a flat.\n') | |
| -\end{verbatim} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#return} | |
| -\label{flowControl.return} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -1 | |
| -$test[1] | |
| -3 | |
| -#def test | |
| -1.5 | |
| -#if 1 | |
| -#return '123' | |
| -#else | |
| -99999 | |
| -#end if | |
| -#end def | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -1 | |
| -2 | |
| -3 | |
| -\end{verbatim} | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| - def test(self, | |
| - trans=None, | |
| - dummyTrans=False, | |
| - VFS=valueFromSearchList, | |
| - VFN=valueForName, | |
| - getmtime=getmtime, | |
| - currentTime=time.time): | |
| - | |
| - | |
| - """ | |
| - Generated from #def test at line 5, col 1. | |
| - """ | |
| - | |
| - if not trans: | |
| - trans = DummyTransaction() | |
| - dummyTrans = True | |
| - write = trans.response().write | |
| - SL = self._searchList | |
| - filter = self._currentFilter | |
| - globalSetVars = self._globalSetVars | |
| - | |
| - ######################################## | |
| - ## START - generated method body | |
| - | |
| - write('1.5\n') | |
| - if 1: | |
| - return '123' | |
| - else: | |
| - write('99999\n') | |
| - | |
| - ######################################## | |
| - ## END - generated method body | |
| - | |
| - if dummyTrans: | |
| - return trans.response().getvalue() | |
| - else: | |
| - return "" | |
| -\end{verbatim} | |
| -\begin{verbatim} | |
| - def respond(self, | |
| - trans=None, | |
| - dummyTrans=False, | |
| - VFS=valueFromSearchList, | |
| - VFN=valueForName, | |
| - getmtime=getmtime, | |
| - currentTime=time.time): | |
| - | |
| - | |
| - """ | |
| - This is the main method generated by Cheetah | |
| - """ | |
| - | |
| - if not trans: | |
| - trans = DummyTransaction() | |
| - dummyTrans = True | |
| - write = trans.response().write | |
| - SL = self._searchList | |
| - filter = self._currentFilter | |
| - globalSetVars = self._globalSetVars | |
| - | |
| - ######################################## | |
| - ## START - generated method body | |
| - | |
| - write('\n1\n') | |
| - write(filter(VFS(SL,"test",1)[1])) # generated from '$test[1]' at line 3, col 1. | |
| - write('\n3\n') | |
| - | |
| - ######################################## | |
| - ## END - generated method body | |
| - | |
| - if dummyTrans: | |
| - return trans.response().getvalue() | |
| - else: | |
| - return "" | |
| -\end{verbatim} | |
| - | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "devel_guide" | |
| -% End: | |
| diff --git a/docs/devel_guide_src/history.tex b/docs/devel_guide_src/history.tex | |
| deleted file mode 100755 | |
| index d5444d5..0000000 | |
| --- a/docs/devel_guide_src/history.tex | |
| +++ /dev/null | |
| @@ -1,92 +0,0 @@ | |
| -\section{History of Cheetah} | |
| -\label{history} | |
| - | |
| -In Spring 2001, several members of the webware-discuss mailing list expressed | |
| -the need for a template engine. Webware like Python is great for organizing | |
| -logic, but they both suffer when you need to do extensive variable | |
| -interpolation into large pieces of text, or to build up a text string from its | |
| -nested parts. Python's \code{\%} operator gets you only so far, the syntax is | |
| -cumbersome, and you have to use a separate format string for each nested part. | |
| -Most of us had used template systems from other platforms--chiefly Zope's DTML, | |
| -PHPLib's Template object and Java's Velocity--and wanted to port something like | |
| -those so it could be used both in Webware servlets and in standalone Python | |
| -programs. | |
| - | |
| -% @@MO: What influence did PSP have on Cheetah? | |
| - | |
| -Since I (Mike Orr) am writing this history, I'll describe how I encountered | |
| -Cheetah. I had written a template module called PlowPlate based on PHPLib's | |
| -Template library. Like PHPLib, it used regular expressions to search | |
| -and destroy--er, replace--placeholders, behaved like a dictionary to | |
| -specify placeholder values, contained no directives, but did have BEGIN and | |
| -END markers which could be used to extract a named block (subtemplate). | |
| -Meanwhile, Tavis Rudd was also on webware-discuss and interested in templates, | |
| -and he lived just a few hours away. So on 12 May 2001 we met in Vancouver at | |
| -a gelato shop on Denman Street and discussed Webware, and he drew on a napkin | |
| -the outline of a template system he was working on. | |
| - | |
| -[Note from Tavis: Mikes got the dates and sequence of things a little out of order, | |
| -but what the hell ...] | |
| - | |
| -Instead of filling the template by search-and-replace, he wanted to break it up | |
| -into parts. This was a primitive form of template compiling: do the | |
| -time-consuming work once and put it to a state where you can fill the template | |
| -quickly multiple times. A template without directives happens to break down | |
| -naturally into a list of alternating text/placeholder pairs. The odd | |
| -subscript values are literal strings; the even subscripts are string keys into | |
| -a dictionary of placeholder values. The project was called TemplateServer. | |
| - | |
| -In a couple months, Tavis decided that instead of compiling to a list, he | |
| -wanted to compile to Python source code: a series of \code{write} calls that | |
| -would output into a file-like object. This was the nucleus that became | |
| -Cheetah. I thought that idea was stupid, but it turned out that this | |
| -not-so-stupid idea blew all the others out of the water in terms of | |
| -performance. | |
| - | |
| -Another thing Tavis pushed hard for from near the beginning was ``display | |
| -logic'', or simple directives like \code{\#for}, \code{\#if} and | |
| -\code{\#echo}. (OK, \code{\#echo} came later, but conceptually it belongs | |
| -here. I thought display logic was even stupider than compiling to Python | |
| -source code because it would just lead to ``DTML hell''--complicated templates | |
| -that are hard to read and maintain, and for which you have to learn (and debug) | |
| -a whole new language when Python does it just fine. But others (hi Chuck!) had | |
| -templates that were maintained by secretaries who didn't know Python, and the | |
| -secretaries needed display logic, so that was that. Finally, after working | |
| -with Cheetah templates (with display logic) and PlowPlate templates (with just | |
| -blocks rather than display logic), I realized Tavis was smarter than I was and | |
| -display logic really did belong in the template. | |
| - | |
| -The next step was making directives for all the Python flow-control | |
| -statements: \code{\#while}, \code{\#try}, \code{\#assert}, etc. Some of | |
| -them we couldn't think of a use for. Nevertheless, they were easy to code, | |
| -and ``somebody'' would probably need them ``someday'', so we may as well | |
| -implement them now. | |
| - | |
| -During all this, Chuck Esterbrook, Ian Bicking and others offered (and still | |
| -offer) their support and suggestions, and Chuck gave us feedback about his use | |
| -of Cheetah--its first deployment in a commercial production environment. | |
| -Later, Edmund Lian became our \#1 bug reporter and suggester as he used Cheetah | |
| -in his web applications. | |
| - | |
| -% @@MO: Write more about the contributions of Chuck, Ian and others. My | |
| -% memory is faulty so I'll have to ask them. | |
| - | |
| -We were going to release 1.0 in January 2002, but we decided to delay it | |
| -until more people used it in real-world situations and gave us feedback | |
| -about what is still needed. This has led to many refinements, and we have | |
| -added (and removed) features according to this feedback. Nevertheless, | |
| -Cheetah has been changing but stable since the late-binding rewrite in | |
| -fall 2001, and anybody who keeps up with the cheetah-discuss mailing list | |
| -will know when changes occur that require modifying one's template, and | |
| -since most people use point releases rather than CVS, they generally have | |
| -a few week's warning about any significant changes. | |
| - | |
| -More detail on Cheetah's history and evolution, and why it is the way it is, | |
| -can be found in our paper for the Python10 conference, | |
| -\url{http://www.cheetahtemplate.org/Py10.html}. | |
| - | |
| -% @@MO: Look through the changelog for important milestones to mention. | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "devel_guide" | |
| -% End: | |
| diff --git a/docs/devel_guide_src/inheritanceEtc.tex b/docs/devel_guide_src/inheritanceEtc.tex | |
| deleted file mode 100755 | |
| index 0179555..0000000 | |
| --- a/docs/devel_guide_src/inheritanceEtc.tex | |
| +++ /dev/null | |
| @@ -1,232 +0,0 @@ | |
| -\section{Directives: Import, Inheritance, Declaration and Assignment} | |
| -\label{inheritanceEtc} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#import and \#from} | |
| -\label{inheritanceEtc.import} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#import math | |
| -\end{verbatim} | |
| - | |
| -This construct does not produce any output. | |
| - | |
| -The generated module, at the bottom of the import section: | |
| -\begin{verbatim} | |
| -import math | |
| -\end{verbatim} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#extends} | |
| -\label{inheritanceEtc.extends} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#extends SomeClass | |
| -\end{verbatim} | |
| - | |
| -The generated import (skipped if \code{SomeClass} has already been | |
| -imported): | |
| -\begin{verbatim} | |
| -from SomeClass import SomeClass | |
| -\end{verbatim} | |
| - | |
| -The generated class: | |
| -\begin{verbatim} | |
| -class x(SomeClass): | |
| -\end{verbatim} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#implements} | |
| -\label{inheritanceEtc.implements} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#implements doOutput | |
| -\end{verbatim} | |
| - | |
| -In the generated class, the main method is \code{.doOutput} instead of | |
| -\code{.respond}, and the attribute naming this method is: | |
| -\begin{verbatim} | |
| -_mainCheetahMethod_for_x2= 'doOutput' | |
| -\end{verbatim} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#set and \#set global} | |
| -\label{inheritanceEtc.set} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#set $namesList = ['Moe','Larry','Curly'] | |
| -$namesList | |
| -#set global $toes = ['eeny', 'meeny', 'miney', 'moe'] | |
| -$toes | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -['Moe', 'Larry', 'Curly'] | |
| -['eeny', 'meeny', 'miney', 'moe'] | |
| -\end{verbatim} | |
| - | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| -1 namesList = ['Moe','Larry','Curly'] | |
| -2 write(filter(namesList)) # generated from '$namesList' at line 2, col 1. | |
| -3 write('\n') | |
| -4 globalSetVars["toes"] = ['eeny', 'meeny', 'miney', 'moe'] | |
| -5 write(filter(VFS(SL,"toes",1))) # generated from '$toes' at line 4, col 1. | |
| -6 write('\n') | |
| -\end{verbatim} | |
| - | |
| -\code{globalSetVars} is a local variable referencing \code{.\_globalSetVars}. | |
| -Writes go into it directly, but reads take advantage of the fact that | |
| -\code{.\_globalSetVars} is on the searchList. (In fact, it's the very first | |
| -namespace.) | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#del} | |
| -\label{inheritanceEtc.del} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#set $a = 1 | |
| -#del $a | |
| -#set $a = 2 | |
| -#set $arr = [0, 1, 2] | |
| -#del $a, $arr[1] | |
| -\end{verbatim} | |
| - | |
| -In the generated class: | |
| -\begin{verbatim} | |
| -1 a = 1 | |
| -2 del a | |
| -3 a = 2 | |
| -4 arr = [0, 1, 2] | |
| -5 del a, arr[1] | |
| -\end{verbatim} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#attr} | |
| -\label{inheritanceEtc.attr} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#attr $namesList = ['Moe', 'Larry', 'Curly'] | |
| -\end{verbatim} | |
| - | |
| -In the generated class: | |
| -\begin{verbatim} | |
| -## GENERATED ATTRIBUTES | |
| - | |
| -namesList = ['Moe', 'Larry', 'Curly'] | |
| -\end{verbatim} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#def} | |
| -\label{inheritanceEtc.def} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#def printArg($arg) | |
| -The argument is $arg. | |
| -#end def | |
| -My method returned $printArg(5). | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -My method returned The argument is 5. | |
| -. | |
| -\end{verbatim} | |
| - | |
| -Hmm, not exactly what we expected. The method returns a trailing newline | |
| -because we didn't end the last line with \code{\#slurp}. So the second | |
| -period (outside the method) appears on a separate line. | |
| - | |
| -The \code{\#def} generates a method \code{.printArg} whose structure is similar | |
| -to the main method: | |
| -\begin{verbatim} | |
| -def printArg(self, | |
| - arg, | |
| - trans=None, | |
| - dummyTrans=False, | |
| - VFS=valueFromSearchList, | |
| - VFN=valueForName, | |
| - getmtime=getmtime, | |
| - currentTime=time.time): | |
| - | |
| - | |
| - """ | |
| - Generated from #def printArg($arg) at line 1, col 1. | |
| - """ | |
| - | |
| - if not trans: | |
| - trans = DummyTransaction() | |
| - dummyTrans = True | |
| - write = trans.response().write | |
| - SL = self._searchList | |
| - filter = self._currentFilter | |
| - globalSetVars = self._globalSetVars | |
| - | |
| - ######################################## | |
| - ## START - generated method body | |
| - | |
| - write('The argument is ') | |
| - write(filter(arg)) # generated from '$arg' at line 2, col 17. | |
| - write('.\n') | |
| - | |
| - ######################################## | |
| - ## END - generated method body | |
| - | |
| - if dummyTrans: | |
| - return trans.response().getvalue() | |
| - else: | |
| - return "" | |
| -\end{verbatim} | |
| - | |
| -When \code{.printArg} is called from a placeholder, only the arguments the user | |
| -supplied are passed. The other arguments retain their default values. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#block} | |
| -\label{inheritanceEtc.block} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#block content | |
| -This page is under construction. | |
| -#end block | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -This page is under construction. | |
| -\end{verbatim} | |
| - | |
| -This construct generates a method \code{.content} in the same structure | |
| -as \code{.printArg} above, containing the write code: | |
| -\begin{verbatim} | |
| -write('This page is under construction.\n') | |
| -\end{verbatim} | |
| - | |
| -In the main method, the write code is: | |
| -\begin{verbatim} | |
| -self.content(trans=trans) # generated from ('content', '#block content') | |
| - # at line 1, col 1. | |
| -\end{verbatim} | |
| - | |
| -So a block placeholder implicitly passes the current transaction to the method. | |
| - | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "devel_guide" | |
| -% End: | |
| diff --git a/docs/devel_guide_src/introduction.tex b/docs/devel_guide_src/introduction.tex | |
| deleted file mode 100755 | |
| index 3403d7e..0000000 | |
| --- a/docs/devel_guide_src/introduction.tex | |
| +++ /dev/null | |
| @@ -1,29 +0,0 @@ | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\section{Introduction} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Who should read this Guide?} | |
| - | |
| -The Cheetah Developers' Guide is for those who want to learn how Cheetah works | |
| -internally, or wish to modify or extend Cheetah. It is assumed that | |
| -you've read the Cheetah Users' Guide and have an intermediate knowledge of | |
| -Python. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Contents} | |
| - | |
| -This Guide takes a behaviorist approach. First we'll look at what the | |
| -Cheetah compiler generates when it compiles a template definition, and | |
| -how it compiles the various \$placeholder features and \#directives. | |
| -Then we'll stroll through the files in the Cheetah source distribution | |
| -and show how each file contributes to the compilation and/or filling of | |
| -templates. Then we'll list every method/attribute inherited by a template | |
| -object. Finally, we'll describe how to submit bugfixes/enhancements to | |
| -Cheetah, and how to add to the documentation. | |
| - | |
| -Appendix A will contain a BNF syntax of the Cheetah template language. | |
| - | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| diff --git a/docs/devel_guide_src/output.tex b/docs/devel_guide_src/output.tex | |
| deleted file mode 100755 | |
| index 1b714c2..0000000 | |
| --- a/docs/devel_guide_src/output.tex | |
| +++ /dev/null | |
| @@ -1,282 +0,0 @@ | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\section{Directives: Output} | |
| -\label{output} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#echo} | |
| -\label{output.echo} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -Here is my #echo ', '.join(['silly']*5) # example | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -Here is my silly, silly, silly, silly, silly example | |
| -\end{verbatim} | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| -write('Here is my ') | |
| -write(filter(', '.join(['silly']*5) )) | |
| -write(' example\n') | |
| -\end{verbatim} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#silent} | |
| -\label{output.silent} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -Here is my #silent ', '.join(['silly']*5) # example | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -Here is my example | |
| -\end{verbatim} | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| - write('Here is my ') | |
| - ', '.join(['silly']*5) | |
| - write(' example\n') | |
| -\end{verbatim} | |
| - | |
| -OK, it's not quite covert because that extra space gives it away, but it | |
| -almost succeeds. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#raw} | |
| -\label{output.raw} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -Text before raw. | |
| -#raw | |
| -Text in raw. $alligator. $croc.o['dile']. #set $a = $b + $c. | |
| -#end raw | |
| -Text after raw. | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -Text before raw. | |
| -Text in raw. $alligator. $croc.o['dile']. #set $a = $b + $c. | |
| -Text after raw. | |
| -\end{verbatim} | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| - write('''Text before raw. | |
| -Text in raw. $alligator. $croc.o['dile']. #set $a = $b + $c. | |
| -Text after raw. | |
| -''') | |
| -\end{verbatim} | |
| - | |
| -So we see that \code{\#raw} is really like a quoting mechanism. It says that | |
| -anything inside it is ordinary text, and Cheetah joins a \code{\#raw} section | |
| -with adjacent string literals rather than generating a separate \code{write} | |
| -call. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#include} | |
| -\label{output.include} | |
| - | |
| -The main template: | |
| -\begin{verbatim} | |
| -#include "y.tmpl" | |
| -\end{verbatim} | |
| - | |
| -The included template y.tmpl: | |
| -\begin{verbatim} | |
| -Let's go $voom! | |
| -\end{verbatim} | |
| - | |
| -The shell command and output: | |
| -\begin{verbatim} | |
| -% voom="VOOM" x.py --env | |
| -Let's go VOOM! | |
| -\end{verbatim} | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| -write(self._includeCheetahSource("y.tmpl", trans=trans, includeFrom="file", | |
| - raw=0)) | |
| -\end{verbatim} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{\#include raw} | |
| -\label{output.include.raw} | |
| - | |
| -The main template: | |
| -\begin{verbatim} | |
| -#include raw "y.tmpl" | |
| -\end{verbatim} | |
| - | |
| -The shell command and output: | |
| -\begin{verbatim} | |
| -% voom="VOOM" x.py --env | |
| -Let's go $voom! | |
| -\end{verbatim} | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| -write(self._includeCheetahSource("y.tmpl", trans=trans, includeFrom="fil | |
| -e", raw=1)) | |
| -\end{verbatim} | |
| - | |
| -That last argument, \code{raw}, makes the difference. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{\#include from a string or expression (eval)} | |
| -\label{output.include.expression} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#attr $y = "Let's go $voom!" | |
| -#include source=$y | |
| -#include raw source=$y | |
| -#include source="Bam! Bam!" | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -% voom="VOOM" x.py --env | |
| -Let's go VOOM!Let's go $voom!Bam! Bam! | |
| -\end{verbatim} | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| -write(self._includeCheetahSource(VFS(SL,"y",1), trans=trans, | |
| - includeFrom="str", raw=0, includeID="481020889808.74")) | |
| -write(self._includeCheetahSource(VFS(SL,"y",1), trans=trans, | |
| - includeFrom="str", raw=1, includeID="711020889808.75")) | |
| -write(self._includeCheetahSource("Bam! Bam!", trans=trans, | |
| - includeFrom="str", raw=0, includeID="1001020889808.75")) | |
| -\end{verbatim} | |
| - | |
| -Later in the generated class: | |
| -\begin{verbatim} | |
| -y = "Let's go $voom!" | |
| -\end{verbatim} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#slurp} | |
| -\label{output.slurp} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#for $i in range(5) | |
| -$i | |
| -#end for | |
| -#for $i in range(5) | |
| -$i #slurp | |
| -#end for | |
| -Line after slurp. | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -0 | |
| -1 | |
| -2 | |
| -3 | |
| -4 | |
| -0 1 2 3 4 Line after slurp. | |
| -\end{verbatim} | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| -for i in range(5): | |
| - write(filter(i)) # generated from '$i' at line 2, col 1. | |
| - write('\n') | |
| -for i in range(5): | |
| - write(filter(i)) # generated from '$i' at line 5, col 1. | |
| - write(' ') | |
| -write('Line after slurp.\n') | |
| -\end{verbatim} | |
| - | |
| -The space after each number is because of the space before \code{\#slurp} in | |
| -the template definition. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#filter} | |
| -\label{output.filter} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -#attr $ode = ">> Rubber Ducky, you're the one! You make bathtime so much fun! <<" | |
| -$ode | |
| -#filter WebSafe | |
| -$ode | |
| -#filter MaxLen | |
| -${ode, maxlen=13} | |
| -#filter None | |
| -${ode, maxlen=13} | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| ->> Rubber Ducky, you're the one! You make bathtime so much fun! << | |
| ->> Rubber Ducky, you're the one! You make bathtime so much fun! << | |
| ->> Rubber Duc | |
| ->> Rubber Ducky, you're the one! You make bathtime so much fun! << | |
| -\end{verbatim} | |
| - | |
| -The \code{WebSafe} filter escapes characters that have a special meaning in | |
| -HTML. The \code{MaxLen} filter chops off values at the specified length. | |
| -\code{\#filter None} returns to the default filter, which ignores the \code{maxlen} | |
| -argument. | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| - 1 write(filter(VFS(SL,"ode",1))) # generated from '$ode' at line 2, col 1. | |
| - 2 write('\n') | |
| - 3 filterName = 'WebSafe' | |
| - 4 if self._filters.has_key("WebSafe"): | |
| - 5 filter = self._currentFilter = self._filters[filterName] | |
| - 6 else: | |
| - 7 filter = self._currentFilter = \ | |
| - 8 self._filters[filterName] = getattr(self._filtersLib, | |
| - filterName)(self).filter | |
| - 9 write(filter(VFS(SL,"ode",1))) # generated from '$ode' at line 4, col 1. | |
| -10 write('\n') | |
| -11 filterName = 'MaxLen' | |
| -12 if self._filters.has_key("MaxLen"): | |
| -13 filter = self._currentFilter = self._filters[filterName] | |
| -14 else: | |
| -15 filter = self._currentFilter = \ | |
| -16 self._filters[filterName] = getattr(self._filtersLib, | |
| - filterName)(self).filter | |
| -17 write(filter(VFS(SL,"ode",1), maxlen=13)) # generated from | |
| - #'${ode, maxlen=13}' at line 6, col 1. | |
| -18 write('\n') | |
| -19 filter = self._initialFilter | |
| -20 write(filter(VFS(SL,"ode",1), maxlen=13)) # generated from | |
| - #'${ode, maxlen=13}' at line 8, col 1. | |
| -21 write('\n') | |
| -\end{verbatim} | |
| - | |
| -As we've seen many times, Cheetah wraps all placeholder lookups in a | |
| -\code{filter} call. (This also applies to non-searchList lookups: local, | |
| -global and builtin variables.) The \code{filter} ``function'' | |
| -is actually an alias to the current filter object: | |
| -\begin{verbatim} | |
| -filter = self._currentFilter | |
| -\end{verbatim} | |
| -as set at the top of the main method. Here in lines 3-8 and 11-16 we see | |
| -the filter being changed. Whoops, I lied. \code{filter} is not an alias to | |
| -the filter object itself but to that object's \code{.filter} method. Line 19 | |
| -switches back to the default filter. | |
| - | |
| -In line 17 we see the \code{maxlen} argument being passed as a keyword | |
| -argument to \code{filter} (not to \code{VFS}). In line 20 the same thing | |
| -happens although the default filter ignores the argument. | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "devel_guide" | |
| -% End: | |
| diff --git a/docs/devel_guide_src/parser.tex b/docs/devel_guide_src/parser.tex | |
| deleted file mode 100755 | |
| index 0198b5d..0000000 | |
| --- a/docs/devel_guide_src/parser.tex | |
| +++ /dev/null | |
| @@ -1,9 +0,0 @@ | |
| -\section{The parser} | |
| -\label{parser} | |
| - | |
| -How templates are compiled: a walk through Parser.py's source. | |
| -(Also need to look at Lexer.py, but not too closely.) | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "devel_guide" | |
| -% End: | |
| diff --git a/docs/devel_guide_src/parserInstructions.tex b/docs/devel_guide_src/parserInstructions.tex | |
| deleted file mode 100644 | |
| index 0af065f..0000000 | |
| --- a/docs/devel_guide_src/parserInstructions.tex | |
| +++ /dev/null | |
| @@ -1,61 +0,0 @@ | |
| -\section{Directives: Parser Instructions} | |
| -\label{parserInstructions} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#breakpoint} | |
| -\label{parserInstructions.breakpoint} | |
| - | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -Text before breakpoint. | |
| -#breakpoint | |
| -Text after breakpoint. | |
| -#raise RuntimeError | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -Text before breakpoint. | |
| -\end{verbatim} | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| -write('Text before breakpoint.\n') | |
| -\end{verbatim} | |
| - | |
| -Nothing after the breakpoint was compiled. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#compiler} | |
| -\label{parserInstructions.compiler} | |
| - | |
| -The template: | |
| -\begin{verbatim} | |
| -// Not a comment | |
| -#compiler commentStartToken = '//' | |
| -// A comment | |
| -#compiler reset | |
| -// Not a comment | |
| -\end{verbatim} | |
| - | |
| -The output: | |
| -\begin{verbatim} | |
| -// Not a comment | |
| -// Not a comment | |
| -\end{verbatim} | |
| - | |
| -The generated code: | |
| -\begin{verbatim} | |
| -write('// Not a comment\n') | |
| -# A comment | |
| -write('// Not a comment\n') | |
| -\end{verbatim} | |
| - | |
| -So this didn't affect the generated program, it just affected how the | |
| -template definition was read. | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "devel_guide" | |
| -% End: | |
| diff --git a/docs/devel_guide_src/patching.tex b/docs/devel_guide_src/patching.tex | |
| deleted file mode 100755 | |
| index 6049068..0000000 | |
| --- a/docs/devel_guide_src/patching.tex | |
| +++ /dev/null | |
| @@ -1,134 +0,0 @@ | |
| -\section{Patching Cheetah} | |
| -\label{patching} | |
| - | |
| -How to commit changes to CVS or submit patches, how to run the test suite. | |
| -Describe distutils and how the regression tests work. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{File Requirements} | |
| -\label{patching.fileRequirements} | |
| - | |
| -The code{Template} class contains not only the Cheetah infrastructure, but also | |
| -some convenience methods useful in all templates. More methods may be added if | |
| -it's generally agreed among Cheetah developers that the method is sufficiently | |
| -useful to all types of templates, or at least to all types of HTML-output | |
| -templates. If a method is too long to fit into \code{Template} -- especially | |
| -if it has helper methods -- put it in a mixin class under \code{Cheetah.Utils} | |
| -and inherit it. | |
| - | |
| -Routines for a specific problem domain should be put under | |
| -\code{Cheetah.Tools}, so that it doesn't clutter the namespace unless the user | |
| -asks for it. | |
| - | |
| -Remember: \code{Cheetah.Utils} is for objects required by any part of Cheetah's | |
| -core. \code{Cheetah.Tools} is for completely optional objects. It should | |
| -always be possible to delete \code{Cheetah.Tools} without breaking Cheetah's | |
| -core services. | |
| - | |
| -If a core method needs to look up an attribute defined under | |
| -\code{Cheetah.Tools}, it should use \code{hasattr()} and gracefully provide a | |
| -default if the attribute does not exist (meaning the user has not imported that | |
| -subsystem). | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Testing Changes and Building Regression Tests} | |
| -\label{patching.testing} | |
| - | |
| -Cheetah ships with a regression test suite. To run the built-in tests, | |
| -execute at the shell prompt: | |
| -\begin{verbatim} | |
| - cheetah test | |
| -\end{verbatim} | |
| - | |
| -Before checking any changes in, run the tests and verify they all pass. That | |
| -way, users can check out the CVS version of Cheetah at any time with a fairly | |
| -high confidence that it will work. If you fix a bug or add a feature, please | |
| -take the time to add a test that exploits the bug/feature. This will help in | |
| -the future, to prevent somebody else from breaking it again without realizing | |
| -it. Users can also run the test suite to verify all the features work on their | |
| -particular platform and computer. | |
| - | |
| -The general procedure for modifying Cheetah is as follows: | |
| -\begin{enumerate} | |
| -\item Write a simple Python program that exploits the bug/feature you're | |
| - working on. You can either write a regression test (see below), or a | |
| - separate program that writes the template output to one file and put the | |
| - expected output in another file; then you can run \code{diff} on the two | |
| - outputs. (\code{diff} is a utility included on all Unix-like systems. It | |
| - shows the differences between two files line by line. A precompiled | |
| - Windows version is at | |
| - \url{http://gnuwin32.sourceforge.net/packages/diffutils.htm}, and MacOS | |
| - sources at \url{http://perso.wanadoo.fr/gilles.depeyrot/DevTools\_en.html}.) | |
| -\item Make the change in your Cheetah CVS sandbox or in your installed | |
| - version of Cheetah. If you make it in the sandbox, you'll have to run | |
| - \code{python setup.py install} before testing it. If you make it in the | |
| - installed version, do {\em not} run the installer or it will overwrite your | |
| - changes! | |
| -\item Run \code{cheetah test} to verify you didn't break anything. Then run | |
| - your little test program. | |
| -\item Repeat steps 2-3 until everything is correct. | |
| -\item Turn your little program into a regression test as described below. | |
| -\item When \code{cheetah test} runs cleanly with your regression test | |
| - included, update the \code{CHANGES} file and check in your changes. If you | |
| - made the changes in your installed copy of Cheetah, you'll have to copy | |
| - them back into the CVS sandbox first. If you added any files that must be | |
| - distributed, {\em be sure to} \code{cvs add} them before committing. | |
| - Otherwise Cheetah will run fine on your computer but fail on anybody | |
| - else's, and the test suite can't check for this. | |
| -\item Announce the change on the cheetahtemplate-discuss list and provide a | |
| - tutorial if necessary. The documentation maintainer will update the | |
| - Users' Guide and Developers' Guide based on this message and on the | |
| - changelog. | |
| -\end{enumerate} | |
| - | |
| -If you add a directory to Cheetah, you have to mention it in \code{setup.py} or | |
| -it won't be installed. | |
| - | |
| -The tests are in the \code{Cheetah.Tests} package, aka the \code{src/Tests/} | |
| -directory of your CVS sandbox. Most of the tests are in | |
| -\code{SyntaxAndOutput.py}. You can either run all the tests or choose which | |
| -to run: | |
| -\begin{description} | |
| -\item{\code{python Test.py}} | |
| - Run all the tests. (Equivalent to \code{cheetah test}.) | |
| -\item{\code{python SyntaxAndOutput.py}} | |
| - Run only the tests in that module. | |
| -\item{\code{python SyntaxAndOutput.py CGI}} | |
| - Run only the tests in the class \code{CGI} inside the module. The class | |
| - must be a direct or indirect subclass of | |
| - \code{unittest\_local\_copy.TestCase}. | |
| -\item{\code{python SyntaxAndOutput.py CGI Indenter}} | |
| - Run the tests in classes \code{CGI} and \code{Indenter}. | |
| -\item{\code{python SyntaxAndOutput.py CGI.test1}} | |
| - Run only test \code{test1}, which is a method in the \code{CGI} class. | |
| -\item{etc...} | |
| -\end{description} | |
| - | |
| -To make a SyntaxAndOutput test, first see if your test logically fits into one | |
| -of the existing classes. If so, simply add a method; e.g., \code{test16}. | |
| -The method should not require any arguments except \code{self}, and should | |
| -call \code{.verify(source, expectedOutput)}, where the two arguments are | |
| -a template definition string and a control string. The tester will complain | |
| -if the template output does not match the control string. You have a wide | |
| -variety of placeholder variables to choose from, anything that's included in | |
| -the \code{defaultTestNameSpace} global dictionary. If that's not enough, add | |
| -items to the dictionary, but please keep it from being cluttered with wordy | |
| -esoteric items for a single test). | |
| - | |
| -If your test logically belongs in a separate class, create a subclass of | |
| -\code{OutputTest}. You do not need to do anything else; the test suite will | |
| -automatically find your class in the module. Having a separate class allows | |
| -you to define state variables needed by your tests (see the \code{CGI} class) | |
| -or override \code{.searchList()} (see the \code{Indenter} class) to provide | |
| -your own searchList. | |
| - | |
| -To modify another test module or create your own test module, you'll have to | |
| -study the existing modules, the \code{unittest\_local\_copy} source, and the | |
| -\code{unittest} documentation in the Python Library Reference. Note that we | |
| -are using a hacked version of \code{unittest} to make a more convenient test | |
| -structure for Cheetah. The differences between \code{unittest\_local\_copy} | |
| -and Python's standard \code{unittest} are documented at the top of the module. | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "devel_guide" | |
| -% End: | |
| diff --git a/docs/devel_guide_src/placeholders.tex b/docs/devel_guide_src/placeholders.tex | |
| deleted file mode 100755 | |
| index e487d09..0000000 | |
| --- a/docs/devel_guide_src/placeholders.tex | |
| +++ /dev/null | |
| @@ -1,478 +0,0 @@ | |
| -\section{Placeholders} | |
| -\label{placeholders} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Simple placeholders} | |
| -\label{placeholders.simple} | |
| - | |
| -Let's add a few \$placeholders to our template: | |
| - | |
| -\begin{verbatim} | |
| ->>> from Cheetah.Template import Template | |
| ->>> values = {'what': 'surreal', 'punctuation': '?'} | |
| ->>> t = Template("""\ | |
| -... Hello, $what world$punctuation | |
| -... One of Python's least-used functions is $xrange. | |
| -... """, [values]) | |
| ->>> print t | |
| -Hello, surreal world? | |
| -One of Python's least-used functions is <built-in function xrange>. | |
| - | |
| ->>> print t.generatedModuleCode() | |
| - 1 #!/usr/bin/env python | |
| - | |
| - 2 """ | |
| - 3 Autogenerated by CHEETAH: The Python-Powered Template Engine | |
| - 4 CHEETAH VERSION: 0.9.12 | |
| - 5 Generation time: Sun Apr 21 00:53:01 2002 | |
| - 6 """ | |
| - | |
| - 7 __CHEETAH_genTime__ = 'Sun Apr 21 00:53:01 2002' | |
| - 8 __CHEETAH_version__ = '0.9.12' | |
| - | |
| - 9 ################################################## | |
| - 10 ## DEPENDENCIES | |
| - | |
| - 11 import sys | |
| - 12 import os | |
| - 13 import os.path | |
| - 14 from os.path import getmtime, exists | |
| - 15 import time | |
| - 16 import types | |
| - 17 from Cheetah.Template import Template | |
| - 18 from Cheetah.DummyTransaction import DummyTransaction | |
| - 19 from Cheetah.NameMapper import NotFound, valueForName, | |
| - valueFromSearchList | |
| - 20 import Cheetah.Filters as Filters | |
| - 21 import Cheetah.ErrorCatchers as ErrorCatchers | |
| - | |
| - 22 ################################################## | |
| - 23 ## MODULE CONSTANTS | |
| - | |
| - 24 try: | |
| - 25 True, False | |
| - 26 except NameError: | |
| - 27 True, False = (1==1), (1==0) | |
| - | |
| - 28 ################################################## | |
| - 29 ## CLASSES | |
| - | |
| - 30 class GenTemplate(Template): | |
| - 31 """ | |
| - 32 | |
| - 33 Autogenerated by CHEETAH: The Python-Powered Template Engine | |
| - 34 """ | |
| - | |
| - 35 ################################################## | |
| - 36 ## GENERATED METHODS | |
| - | |
| -\end{verbatim} | |
| -\begin{verbatim} | |
| - | |
| - 37 def __init__(self, *args, **KWs): | |
| - 38 """ | |
| - 39 | |
| - 40 """ | |
| - | |
| - 41 Template.__init__(self, *args, **KWs) | |
| - | |
| - 42 def respond(self, | |
| - 43 trans=None, | |
| - 44 dummyTrans=False, | |
| - 45 VFS=valueFromSearchList, | |
| - 46 VFN=valueForName, | |
| - 47 getmtime=getmtime, | |
| - 48 currentTime=time.time): | |
| - | |
| - | |
| - 49 """ | |
| - 50 This is the main method generated by Cheetah | |
| - 51 """ | |
| - | |
| - 52 if not trans: | |
| - 53 trans = DummyTransaction() | |
| - 54 dummyTrans = True | |
| - 55 write = trans.response().write | |
| - 56 SL = self._searchList | |
| - 57 filter = self._currentFilter | |
| - 58 globalSetVars = self._globalSetVars | |
| - 59 | |
| - 60 ######################################## | |
| - 61 ## START - generated method body | |
| - 62 | |
| - 63 write('Hello, ') | |
| - 64 write(filter(VFS(SL,"what",1))) # generated from '$what' at | |
| - # line 1, col 8. | |
| - 65 write(' world') | |
| - 66 write(filter(VFS(SL,"punctuation",1))) # generated from | |
| - # '$punctuation' at line 1, col 19. | |
| - 67 write("\nOne of Python's least-used methods is ") | |
| - 68 write(filter(xrange)) # generated from '$xrange' at line 2, | |
| - # col 39. | |
| - 69 write('.\n') | |
| - 70 | |
| - 71 ######################################## | |
| - 72 ## END - generated method body | |
| - 73 | |
| - 74 if dummyTrans: | |
| - 75 return trans.response().getvalue() | |
| - 76 else: | |
| - 77 return "" | |
| -\end{verbatim} | |
| -\begin{verbatim} | |
| - 78 | |
| - 79 ################################################## | |
| - 80 ## GENERATED ATTRIBUTES | |
| - | |
| - 81 __str__ = respond | |
| - 82 _mainCheetahMethod_for_GenTemplate= 'respond' | |
| - | |
| - 83 # CHEETAH was developed by Tavis Rudd, Chuck Esterbrook, Ian Bicking | |
| - # and Mike Orr; | |
| - 84 # with code, advice and input from many other volunteers. | |
| - 85 # For more information visit http://www.CheetahTemplate.org | |
| - | |
| - 86 ################################################## | |
| - 87 ## if run from command line: | |
| - 88 if __name__ == '__main__': | |
| - 89 GenTemplate().runAsMainProgram() | |
| - | |
| -\end{verbatim} | |
| - | |
| -(Again, I have added line numbers and split the lines as in the previous | |
| -chapter.) | |
| - | |
| -This generated template module is different from the previous one in several | |
| -trivial respects and one important respect. Trivially, | |
| -\code{.\_filePath} and \code{.\_fileMtime} are not updated in | |
| -\code{.\_\_init\_\_}, so they inherit the value \code{None} from | |
| -\code{Template}. Also, that if-stanza in \code{.respond} that recompiles the | |
| -template if the source file changes is missing -- because there is no source | |
| -file. So this module is several lines shorter than the other one. | |
| - | |
| -But the important way this module is different is that instead of the one | |
| -\code{write} call outputting a string literal, this module has a series of | |
| -\code{write} calls (lines 63-69) outputting successive chunks of the | |
| -template. Regular text has been translated into a string literal, and | |
| -placeholders into function calls. Every placeholder is wrapped inside a | |
| -\code{filter} call to apply the current output filter. (The default | |
| -output filter converts all objects to strings, and \code{None} to \code{""}.) | |
| - | |
| -Placeholders referring to a Python builtin like \code{xrange} (line 68) | |
| -generate a bare variable name. Placeholders to be looked up in the searchList | |
| -have a nested function call; e.g., | |
| -\begin{verbatim} | |
| -write(filter(VFS(SL,"what",1))) # generated from '$what' at line 1, col 8. | |
| -\end{verbatim} | |
| -\code{VFS}, remember, is a function imported from \code{Cheetah.NameMapper} | |
| -that looks up a value in a searchList. So we pass it the searchList, the | |
| -name to look up, and a boolean (1) indicating we want autocalling. (It's | |
| -\code{1} rather than \code{True} because it's generated from an | |
| -\code{and} expression, and that's what Python 2.2 outputs for true \code{and} | |
| -expressions.) | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Complex placeholders} | |
| -\label{placeholders.complex} | |
| - | |
| -Placeholders can get far more complicated than that. This example shows what | |
| -kind of code the various NameMapper features produce. The formulas are | |
| -taken from Cheetah's test suite, in the | |
| -\code{Cheetah.Tests.SyntaxAndOutput.Placeholders} class. | |
| - | |
| -\begin{verbatim} | |
| -1 placeholder: $aStr | |
| -2 placeholders: $aStr $anInt | |
| -2 placeholders, back-to-back: $aStr$anInt | |
| -1 placeholder enclosed in {}: ${aStr} | |
| -1 escaped placeholder: \$var | |
| -func placeholder - with (): $aFunc() | |
| -func placeholder - with (int): $aFunc(1234) | |
| -func placeholder - with (string): $aFunc('aoeu') | |
| -func placeholder - with ('''\nstring'\n'''): $aFunc('''\naoeu'\n''') | |
| -func placeholder - with (string*int): $aFunc('aoeu'*2) | |
| -func placeholder - with (int*float): $aFunc(2*2.0) | |
| -Python builtin values: $None $True $False | |
| -func placeholder - with ($arg=float): $aFunc($arg=4.0) | |
| -deeply nested argstring: $aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) ): | |
| -function with None: $aFunc(None) | |
| -autocalling: $aFunc! $aFunc(). | |
| -nested autocalling: $aFunc($aFunc). | |
| -list subscription: $aList[0] | |
| -list slicing: $aList[:2] | |
| -list slicing and subcription combined: $aList[:2][0] | |
| -dict - NameMapper style: $aDict.one | |
| -dict - Python style: $aDict['one'] | |
| -dict combined with autocalled string method: $aDict.one.upper | |
| -dict combined with string method: $aDict.one.upper() | |
| -nested dict - NameMapper style: $aDict.nestedDict.two | |
| -nested dict - Python style: $aDict['nestedDict']['two'] | |
| -nested dict - alternating style: $aDict['nestedDict'].two | |
| -nested dict - NameMapper style + method: $aDict.nestedDict.two.upper | |
| -nested dict - alternating style + method: $aDict['nestedDict'].two.upper | |
| -nested dict - NameMapper style + method + slice: $aDict.nestedDict.two.upper[:4] | |
| -nested dict - Python style, variable key: $aDict[$anObj.meth('nestedDict')].two | |
| -object method: $anObj.meth1 | |
| -object method + complex slice: $anObj.meth1[0: ((4/4*2)*2)/$anObj.meth1(2) ] | |
| -very complex slice: $( anObj.meth1[0: ((4/4*2)*2)/$anObj.meth1(2) ] ) | |
| -$_('a call to gettext') | |
| -\end{verbatim} | |
| - | |
| -We'll need a big program to set up the placeholder values. Here it is: | |
| - | |
| -\begin{verbatim} | |
| -#!/usr/bin/env python | |
| -from ComplexExample import ComplexExample | |
| - | |
| -try: # Python >= 2.2.1 | |
| - True, False | |
| -except NameError: # Older Python | |
| - True, False = (1==1), (1==0) | |
| - | |
| -class DummyClass: | |
| - _called = False | |
| - def __str__(self): | |
| - return 'object' | |
| - | |
| - def meth(self, arg="arff"): | |
| - return str(arg) | |
| - | |
| - def meth1(self, arg="doo"): | |
| - return arg | |
| - | |
| - def meth2(self, arg1="a1", arg2="a2"): | |
| - return str(arg1) + str(arg2) | |
| - | |
| - def callIt(self, arg=1234): | |
| - self._called = True | |
| - self._callArg = arg | |
| - | |
| -def dummyFunc(arg="Scooby"): | |
| - return arg | |
| - | |
| -defaultTestNameSpace = { | |
| - 'aStr':'blarg', | |
| - 'anInt':1, | |
| - 'aFloat':1.5, | |
| - 'aList': ['item0','item1','item2'], | |
| - 'aDict': {'one':'item1', | |
| - 'two':'item2', | |
| - 'nestedDict':{1:'nestedItem1', | |
| - 'two':'nestedItem2' | |
| - }, | |
| - 'nestedFunc':dummyFunc, | |
| - }, | |
| - 'aFunc': dummyFunc, | |
| - 'anObj': DummyClass(), | |
| - 'aMeth': DummyClass().meth1, | |
| - '_': lambda x: 'translated ' + x | |
| -} | |
| - | |
| -print ComplexExample( searchList=[defaultTestNameSpace] ) | |
| -\end{verbatim} | |
| - | |
| -Here's the output: | |
| - | |
| -\begin{verbatim} | |
| -1 placeholder: blarg | |
| -2 placeholders: blarg 1 | |
| -2 placeholders, back-to-back: blarg1 | |
| -1 placeholder enclosed in {}: blarg | |
| -1 escaped placeholder: $var | |
| -func placeholder - with (): Scooby | |
| -func placeholder - with (int): 1234 | |
| -func placeholder - with (string): aoeu | |
| -func placeholder - with ('''\nstring'\n'''): | |
| -aoeu' | |
| - | |
| -func placeholder - with (string*int): aoeuaoeu | |
| -func placeholder - with (int*float): 4.0 | |
| -Python builtin values: 1 0 | |
| -func placeholder - with ($arg=float): 4.0 | |
| -deeply nested argstring: 1: | |
| -function with None: | |
| -autocalling: Scooby! Scooby. | |
| -nested autocalling: Scooby. | |
| -list subscription: item0 | |
| -list slicing: ['item0', 'item1'] | |
| -list slicing and subcription combined: item0 | |
| -dict - NameMapper style: item1 | |
| -dict - Python style: item1 | |
| -dict combined with autocalled string method: ITEM1 | |
| -dict combined with string method: ITEM1 | |
| -nested dict - NameMapper style: nestedItem2 | |
| -nested dict - Python style: nestedItem2 | |
| -nested dict - alternating style: nestedItem2 | |
| -nested dict - NameMapper style + method: NESTEDITEM2 | |
| -nested dict - alternating style + method: NESTEDITEM2 | |
| -nested dict - NameMapper style + method + slice: NEST | |
| -nested dict - Python style, variable key: nestedItem2 | |
| -object method: doo | |
| -object method + complex slice: do | |
| -very complex slice: do | |
| -translated a call to gettext | |
| - | |
| -\end{verbatim} | |
| - | |
| -And here -- tada! -- is the generated module. | |
| -To save space, I've included only the lines containing the \code{write} calls. | |
| -The rest of the module is the same as in the first example, chapter | |
| -\ref{pyModules.example}. I've split some of the lines to make them fit on | |
| -the page. | |
| - | |
| -\begin{verbatim} | |
| - 1 write('1 placeholder: ') | |
| - 2 write(filter(VFS(SL,"aStr",1))) # generated from '$aStr' at line 1, col 16. | |
| - 3 write('\n2 placeholders: ') | |
| - 4 write(filter(VFS(SL,"aStr",1))) # generated from '$aStr' at line 2, col 17. | |
| - 5 write(' ') | |
| - 6 write(filter(VFS(SL,"anInt",1))) | |
| - # generated from '$anInt' at line 2, col 23. | |
| - 7 write('\n2 placeholders, back-to-back: ') | |
| - 8 write(filter(VFS(SL,"aStr",1))) # generated from '$aStr' at line 3, col 31. | |
| - 9 write(filter(VFS(SL,"anInt",1))) | |
| - # generated from '$anInt' at line 3, col 36. | |
| -10 write('\n1 placeholder enclosed in {}: ') | |
| -11 write(filter(VFS(SL,"aStr",1))) # generated from '${aStr}' at line 4, | |
| - # col 31. | |
| -12 write('\n1 escaped placeholder: $var\nfunc placeholder - with (): ') | |
| -13 write(filter(VFS(SL,"aFunc",0)())) # generated from '$aFunc()' at line 6, | |
| - # col 29. | |
| -14 write('\nfunc placeholder - with (int): ') | |
| -15 write(filter(VFS(SL,"aFunc",0)(1234))) # generated from '$aFunc(1234)' at | |
| - # line 7, col 32. | |
| -16 write('\nfunc placeholder - with (string): ') | |
| -17 write(filter(VFS(SL,"aFunc",0)('aoeu'))) # generated from "$aFunc('aoeu')" | |
| - # at line 8, col 35. | |
| -18 write("\nfunc placeholder - with ('''\\nstring'\\n'''): ") | |
| -19 write(filter(VFS(SL,"aFunc",0)('''\naoeu'\n'''))) # generated from | |
| - # "$aFunc('''\\naoeu'\\n''')" at line 9, col 46. | |
| -20 write('\nfunc placeholder - with (string*int): ') | |
| -21 write(filter(VFS(SL,"aFunc",0)('aoeu'*2))) # generated from | |
| - # "$aFunc('aoeu'*2)" at line 10, col 39. | |
| -22 write('\nfunc placeholder - with (int*float): ') | |
| -23 write(filter(VFS(SL,"aFunc",0)(2*2.0))) # generated from '$aFunc(2*2.0)' | |
| - # at line 11, col 38. | |
| -24 write('\nPython builtin values: ') | |
| -25 write(filter(None)) # generated from '$None' at line 12, col 24. | |
| -26 write(' ') | |
| -27 write(filter(True)) # generated from '$True' at line 12, col 30. | |
| -28 write(' ') | |
| -29 write(filter(False)) # generated from '$False' at line 12, col 36. | |
| -30 write('\nfunc placeholder - with ($arg=float): ') | |
| -31 write(filter(VFS(SL,"aFunc",0)(arg=4.0))) # generated from | |
| - # '$aFunc($arg=4.0)' at line 13, col 40. | |
| -32 write('\ndeeply nested argstring: ') | |
| -33 write(filter(VFS(SL,"aFunc",0)( | |
| - arg = VFS(SL,"aMeth",0)( arg = VFS(SL,"aFunc",0)( 1 ) ) ))) | |
| - # generated from '$aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) )' | |
| - # at line 14, col 26. | |
| -34 write(':\nfunction with None: ') | |
| -35 write(filter(VFS(SL,"aFunc",0)(None))) # generated from '$aFunc(None)' at | |
| - # line 15, col 21. | |
| -36 write('\nautocalling: ') | |
| -37 write(filter(VFS(SL,"aFunc",1))) # generated from '$aFunc' at line 16, | |
| - # col 14. | |
| -38 write('! ') | |
| -39 write(filter(VFS(SL,"aFunc",0)())) # generated from '$aFunc()' at line 16, | |
| - # col 22. | |
| -\end{verbatim} | |
| -\begin{verbatim} | |
| -40 write('.\nnested autocalling: ') | |
| -41 write(filter(VFS(SL,"aFunc",0)(VFS(SL,"aFunc",1)))) # generated from | |
| - # '$aFunc($aFunc)' at line 17, col 21. | |
| -42 write('.\nlist subscription: ') | |
| -43 write(filter(VFS(SL,"aList",1)[0])) # generated from '$aList[0]' at line | |
| - # 18, col 20. | |
| -44 write('\nlist slicing: ') | |
| -45 write(filter(VFS(SL,"aList",1)[:2])) # generated from '$aList[:2]' at | |
| - # line 19, col 15. | |
| -46 write('\nlist slicing and subcription combined: ') | |
| -47 write(filter(VFS(SL,"aList",1)[:2][0])) # generated from '$aList[:2][0]' | |
| - # at line 20, col 40. | |
| -48 write('\ndict - NameMapper style: ') | |
| -49 write(filter(VFS(SL,"aDict.one",1))) # generated from '$aDict.one' at line | |
| - # 21, col 26. | |
| -50 write('\ndict - Python style: ') | |
| -51 write(filter(VFS(SL,"aDict",1)['one'])) # generated from "$aDict['one']" | |
| - # at line 22, col 22. | |
| -52 write('\ndict combined with autocalled string method: ') | |
| -53 write(filter(VFS(SL,"aDict.one.upper",1))) # generated from | |
| - # '$aDict.one.upper' at line 23, col 46. | |
| -54 write('\ndict combined with string method: ') | |
| -55 write(filter(VFN(VFS(SL,"aDict.one",1),"upper",0)())) # generated from | |
| - # '$aDict.one.upper()' at line 24, col 35. | |
| -56 write('\nnested dict - NameMapper style: ') | |
| -57 write(filter(VFS(SL,"aDict.nestedDict.two",1))) # generated from | |
| - # '$aDict.nestedDict.two' at line 25, col 33. | |
| -58 write('\nnested dict - Python style: ') | |
| -59 write(filter(VFS(SL,"aDict",1)['nestedDict']['two'])) # generated from | |
| - # "$aDict['nestedDict']['two']" at line 26, col 29. | |
| -60 write('\nnested dict - alternating style: ') | |
| -61 write(filter(VFN(VFS(SL,"aDict",1)['nestedDict'],"two",1))) # generated | |
| - # from "$aDict['nestedDict'].two" at line 27, col 34. | |
| -62 write('\nnested dict - NameMapper style + method: ') | |
| -63 write(filter(VFS(SL,"aDict.nestedDict.two.upper",1))) # generated from | |
| - # '$aDict.nestedDict.two.upper' at line 28, col 42. | |
| -64 write('\nnested dict - alternating style + method: ') | |
| -65 write(filter(VFN(VFS(SL,"aDict",1)['nestedDict'],"two.upper",1))) | |
| - # generated from "$aDict['nestedDict'].two.upper" at line 29, col 43. | |
| -66 write('\nnested dict - NameMapper style + method + slice: ') | |
| -\end{verbatim} | |
| -\begin{verbatim} | |
| -67 write(filter(VFN(VFS(SL,"aDict.nestedDict.two",1),"upper",1)[:4])) | |
| - # generated from '$aDict.nestedDict.two.upper[:4]' at line 30, col 50. | |
| -68 write('\nnested dict - Python style, variable key: ') | |
| -69 write(filter(VFN(VFS(SL,"aDict",1) | |
| - [VFN(VFS(SL,"anObj",1),"meth",0)('nestedDict')],"two",1))) | |
| - # generated from "$aDict[$anObj.meth('nestedDict')].two" at line 31, | |
| - # col 43. | |
| -70 write('\nobject method: ') | |
| -71 write(filter(VFS(SL,"anObj.meth1",1))) # generated from '$anObj.meth1' at | |
| - # line 32, col 16. | |
| -72 write('\nobject method + complex slice: ') | |
| -73 write(filter(VFN(VFS(SL,"anObj",1),"meth1",1) | |
| - [0: ((4/4*2)*2)/VFN(VFS(SL,"anObj",1),"meth1",0)(2) ])) | |
| - # generated from '$anObj.meth1[0: ((4/4*2)*2)/$anObj.meth1(2) ]' | |
| - # at line 33, col 32. | |
| -74 write('\nvery complex slice: ') | |
| -75 write(filter(VFN(VFS(SL,"anObj",1),"meth1",1) | |
| - [0: ((4/4*2)*2)/VFN(VFS(SL,"anObj",1),"meth1",0)(2) ] )) | |
| - # generated from '$( anObj.meth1[0: ((4/4*2)*2)/$anObj.meth1(2) ] )' | |
| - # at line 34, col 21. | |
| -76 if False: | |
| -77 _('foo') | |
| -78 write(filter(VFS(SL,"_",0)("a call to gettext"))) | |
| - # generated from "$_('a call to gettext')" | |
| - # at line 35, col 1. | |
| -79 write('\n') | |
| -\end{verbatim} | |
| - | |
| -For each placeholder lookup, the the innermost level of nesting is a \code{VFS} | |
| -call, which looks up the first (leftmost) placeholder component in the | |
| -searchList. This is wrapped by zero or more \code{VFN} calls, which perform | |
| -Universal Dotted Notation lookup on the next dotted component of the | |
| -placeholder, looking for an attribute or key by that name within the previous | |
| -object (not in the searchList). Autocalling is performed by \code{VFS} and | |
| -\code{VFN}: that's the reason for their third argument. | |
| - | |
| -Explicit function/method arguments, subscripts and keys (which | |
| -are all expressions) are left unchanged, besides expanding any embedded | |
| -\$placeholders in them. This means they must result in valid Python | |
| -expressions, following the standard Python quoting rules. | |
| - | |
| -Built-in Python values (\code{None}, \code{True} and \code{False}) are | |
| -converted to \code{filter(None)}, etc. They use normal Python variable | |
| -lookup rather than \code{VFS}. (Cheetah emulates \code{True} and \code{False} | |
| -using global variables for Python < 2.2.1, when they weren't builtins yet.) | |
| - | |
| -Notice the last line is a call to \code{_} (i.e. \code{gettext}) which is used | |
| -for internationalization (see | |
| -\url{http://docs.python.org/lib/module-gettext.html}). The code is converted | |
| -normally, but an \code{if False} block is used so that gettext can | |
| -successfully mark the string for translation when parsing the generated Python. | |
| -Otherwise, the NameMapper syntax would get in the way of this. | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "devel_guide" | |
| -% End: | |
| diff --git a/docs/devel_guide_src/pyModules.tex b/docs/devel_guide_src/pyModules.tex | |
| deleted file mode 100755 | |
| index 2aa3236..0000000 | |
| --- a/docs/devel_guide_src/pyModules.tex | |
| +++ /dev/null | |
| @@ -1,246 +0,0 @@ | |
| -\section{.py Template Modules} | |
| -\label{pyModules} | |
| - | |
| -This chapter examines the structure of a .py template module. The following | |
| -few chapters will then show how each placeholder and directive affects the | |
| -generated Python code. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{An example} | |
| -\label{pyModules.example} | |
| - | |
| -Our first template follows a long noble tradition in computer tutorials. | |
| -It produces a familiar, friendly greeting. Here's the template: | |
| - | |
| -\begin{verbatim} | |
| -Hello, world! | |
| -\end{verbatim} | |
| - | |
| -... the output: | |
| - | |
| -\begin{verbatim} | |
| -Hello, world! | |
| -\end{verbatim} | |
| - | |
| -... and the .py template module cheetah-compile produced, with line | |
| -numbers added: | |
| - | |
| -% @@MO: Is it possible to print the line numbers gray instead of black? | |
| - | |
| -\begin{verbatim} | |
| - 1 #!/usr/bin/env python | |
| - | |
| - 2 """ | |
| - 3 Autogenerated by CHEETAH: The Python-Powered Template Engine | |
| - 4 CHEETAH VERSION: 0.9.12 | |
| - 5 Generation time: Sat Apr 20 14:27:47 2002 | |
| - 6 Source file: x.tmpl | |
| - 7 Source file last modified: Wed Apr 17 22:10:59 2002 | |
| - 8 """ | |
| - | |
| - 9 __CHEETAH_genTime__ = 'Sat Apr 20 14:27:47 2002' | |
| - 10 __CHEETAH_src__ = 'x.tmpl' | |
| - 11 __CHEETAH_version__ = '0.9.12' | |
| - | |
| - 12 ################################################## | |
| - 13 ## DEPENDENCIES | |
| - | |
| - 14 import sys | |
| - 15 import os | |
| - 16 import os.path | |
| - 17 from os.path import getmtime, exists | |
| - 18 import time | |
| - 19 import types | |
| - 20 from Cheetah.Template import Template | |
| - 21 from Cheetah.DummyTransaction import DummyTransaction | |
| - 22 from Cheetah.NameMapper import NotFound, valueForName, | |
| - valueFromSearchList | |
| - 23 import Cheetah.Filters as Filters | |
| - 24 import Cheetah.ErrorCatchers as ErrorCatchers | |
| - | |
| - 25 ################################################## | |
| - 26 ## MODULE CONSTANTS | |
| - | |
| - 27 try: | |
| - 28 True, False | |
| - 29 except NameError: | |
| - 30 True, False = (1==1), (1==0) | |
| - | |
| - 31 ################################################## | |
| - 32 ## CLASSES | |
| - | |
| - 33 class x(Template): | |
| - 34 """ | |
| - 35 | |
| - 36 Autogenerated by CHEETAH: The Python-Powered Template Engine | |
| - 37 """ | |
| -\end{verbatim} | |
| -\begin{verbatim} | |
| - 38 ################################################## | |
| - 39 ## GENERATED METHODS | |
| - | |
| - | |
| - 40 def __init__(self, *args, **KWs): | |
| - 41 """ | |
| - 42 | |
| - 43 """ | |
| - | |
| - 44 Template.__init__(self, *args, **KWs) | |
| - 45 self._filePath = 'x.tmpl' | |
| - 46 self._fileMtime = 1019106659 | |
| - | |
| - 47 def respond(self, | |
| - 48 trans=None, | |
| - 49 dummyTrans=False, | |
| - 50 VFS=valueFromSearchList, | |
| - 51 VFN=valueForName, | |
| - 52 getmtime=getmtime, | |
| - 53 currentTime=time.time): | |
| - | |
| - | |
| - 54 """ | |
| - 55 This is the main method generated by Cheetah | |
| - 56 """ | |
| - | |
| - 57 if not trans: | |
| - 58 trans = DummyTransaction() | |
| - 59 dummyTrans = True | |
| - 60 write = trans.response().write | |
| - 61 SL = self._searchList | |
| - 62 filter = self._currentFilter | |
| - 63 globalSetVars = self._globalSetVars | |
| - 64 | |
| - 65 ######################################## | |
| - 66 ## START - generated method body | |
| - 67 | |
| - 68 if exists(self._filePath) and getmtime(self._filePath) > \ | |
| - self._fileMtime: | |
| - 69 self.compile(file=self._filePath) | |
| - 70 write(getattr(self, self._mainCheetahMethod_for_x) | |
| - (trans=trans)) | |
| - 71 if dummyTrans: | |
| - 72 return trans.response().getvalue() | |
| - 73 else: | |
| - 74 return "" | |
| - 75 write('Hello, world!\n') | |
| - 76 | |
| - 77 ######################################## | |
| - 78 ## END - generated method body | |
| - 79 | |
| - 80 if dummyTrans: | |
| - 81 return trans.response().getvalue() | |
| - 82 else: | |
| - 83 return "" | |
| -\end{verbatim} | |
| -\begin{verbatim} | |
| - 84 | |
| - 85 ################################################## | |
| - 86 ## GENERATED ATTRIBUTES | |
| - | |
| - | |
| - 87 __str__ = respond | |
| - | |
| - 88 _mainCheetahMethod_for_x= 'respond' | |
| - | |
| - | |
| - 89 # CHEETAH was developed by Tavis Rudd, Chuck Esterbrook, Ian Bicking | |
| - # and Mike Orr; | |
| - 90 # with code, advice and input from many other volunteers. | |
| - 91 # For more information visit http://www.CheetahTemplate.org | |
| - | |
| - 92 ################################################## | |
| - 93 ## if run from command line: | |
| - 94 if __name__ == '__main__': | |
| - 95 x().runAsMainProgram() | |
| - | |
| -\end{verbatim} | |
| - | |
| -(I added the line numbers for this Guide, and split a few lines to fit the | |
| -page width. The continuation lines don't have line numbers, and I added | |
| -indentation, backslashes and '\#' as necessary to make the result a valid | |
| -Python program.) | |
| - | |
| -The examples were generated from CVS versions of Cheetah between 0.9.12 and | |
| -0.9.14. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{A walk through the example} | |
| -\label{pyModules.walk} | |
| - | |
| -Lines 20-24 are the Cheetah-specific imports. Line 33 introduces our generated | |
| -class, \code{x}, a subclass of \code{Template}. It's called x because the | |
| -source file was x.tmpl. | |
| - | |
| -Lines 40-46 are the \code{.\_\_init\_\_} method called when the template is | |
| -instantiated or used as a Webware servlet, or when the module is run as a | |
| -standalone program. We can see it calling its superclass constructor and | |
| -setting \code{.\_filePath} and \code{.\_fileMtime} to the filename and | |
| -modification time (in Unix ticks) of the source .tmpl file. | |
| - | |
| -Lines 47-84 are the main method \code{.respond}, the one that fills the | |
| -template. Normally you call it without arguments, but Webware calls it with a | |
| -Webware \code{Transaction} object representing the current request. Lines | |
| -57-59 set up the \code{trans} variable. If a real or dummy transaction is | |
| -passed in, the method uses it. Otherwise (if the \code{trans} argument is | |
| -\code{None}), the method creates a \code{DummyTransaction} instance. | |
| -\code{dummyTrans} is a flag that just tells whether a dummy transaction is in | |
| -effect; it'll be used at the end of the method. | |
| - | |
| -The other four \code{.respond} arguments aren't anything you'd ever want to | |
| -pass in; they exist solely to speed up access to these frequently-used | |
| -global functions. This is a standard Python trick described in question 4.7 | |
| -of the Python FAQ (\url{http://www.python.org/cgi-bin/faqw.py}). | |
| -\code{VFS} and \code{VFN} are the functions that give your template the | |
| -benefits of NameMapper lookup, such as the ability to use the searchList. | |
| - | |
| -Line 60 initializes the \code{write} variable. This important variable is | |
| -discussed below. | |
| - | |
| -Lines 60-63 initialize a few more local variables. \code{SL} is the | |
| -searchList. \code{filter} is the current output filter. \code{globalSetVars} | |
| -are the variables that have been defined with \code{\#set global}. | |
| - | |
| -The comments at lines 65 and 78 delimit the start and end of the code that | |
| -varies with each template. The code outside this region is identical in all | |
| -template modules. That's not quite true -- \code{\#import} for instance | |
| -generates additional \code{import} statements at the top of the module -- | |
| -but it's true enough for the most part. | |
| - | |
| -Lines 68-74 exist only if the template source was a named file rather than | |
| -a string or file object. The stanza recompiles the template if the source | |
| -file has changed. Lines 70-74 seem to be redundant with 75-83: both | |
| -fill the template and send the output. The reason the first set of lines | |
| -exists is because the second set may become invalid when the template is | |
| -recompiled. (This is for {\em re}\ compilation only. The initial compilation | |
| -happened in the \code{.\_\_init\_\_} method if the template wasn't | |
| -precompiled.) | |
| - | |
| -Line 75 is the most interesting line in this module. It's a direct | |
| -translation of what we put in the template definition, ``Hello, world!'' Here | |
| -the content is a single string literal. \code{write} looks like an ordinary | |
| -function call, but remember that line 60 made it an alias to | |
| -\code{trans.response().write}, a method in the transaction. The next few | |
| -chapters describe how the different placeholders and directives influence this | |
| -portion of the generated class. | |
| - | |
| -Lines 80-83 finish the template filling. If \code{trans} is a real Webware | |
| -transaction, \code{write} has already sent the output to Webware for handling, | |
| -so we return \code{""}. If \code{trans} is a dummy transaction, | |
| -\code{write} has been accumulating the output in a Python \code{StringIO} | |
| -object rather than sending it anywhere, so we have to return it. | |
| - | |
| -Line 83 is the end of the \code{.respond} method. | |
| - | |
| -Line 87 makes code{.\_\_str\_\_} an alias for the main method, so that you | |
| -can \code{print} it or apply \code{str} to it and it will fill the template. | |
| -Line 88 gives the name of the main method, because sometimes it's not | |
| -\code{.respond}. | |
| - | |
| -Lines 94-95 allow the module to be run directly as a script. Essentially, | |
| -they process the command-line arguments and them make the template fill | |
| -itself. | |
| - | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "devel_guide" | |
| -% End: | |
| diff --git a/docs/devel_guide_src/safeDelegation.tex b/docs/devel_guide_src/safeDelegation.tex | |
| deleted file mode 100755 | |
| index dd1a8aa..0000000 | |
| --- a/docs/devel_guide_src/safeDelegation.tex | |
| +++ /dev/null | |
| @@ -1,44 +0,0 @@ | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\section{Safe Delegation} | |
| -\label{safeDelegation} | |
| - | |
| -% @@MO: Does this really belong in the Developers' Guide or any guide? | |
| -% It's more of a wiki Wishlist item, no? Especially since nobody has | |
| -% expressed a need for it. | |
| - | |
| -Safe delegation, as provided by Zope and Allaire's Spectra, is not implemented | |
| -in Cheetah. The core aim has been to help developers and template maintainers | |
| -get things done, without throwing unnecessary complications in their | |
| -way. So you should give write access to your templates only to those whom you | |
| -trust. However, several hooks have been built into Cheetah so that safe | |
| -delegation can be implemented at a later date. | |
| - | |
| -It should be possible to implement safe delegation via a future configuration | |
| -Setting \code{safeDelegationLevel} (0=none, 1=semi-secure, 2-alcatraz). This | |
| -is not implemented but the steps are listed here in case somebody wants to try | |
| -them out and test them. | |
| - | |
| -Of course, you would also need to benchmark your code | |
| -and verify it does not impact performance when safe delegation is off, and | |
| -impacts it only modestly when it is on." All necessary changes can be made | |
| -at compile time, so there should be no performance impact when filling the | |
| -same TO multiple times. | |
| - | |
| -\begin{enumerate} | |
| - | |
| -\item Only give untrusted developers access to the .tmpl files. | |
| -(Verifying what this means. Why can't trusted developers access them?) | |
| - | |
| -\item Disable the \code{\#attr} directive and maybe the \code{\#set} directive. | |
| - | |
| -\item Use Cheetah's directive validation hooks to disallow | |
| -references to \code{self}, etc | |
| -(e.g. \code{\#if \$steal(self.thePrivateVar)} ) | |
| - | |
| -\item Implement a validator for the \$placeholders and use it | |
| -to disallow '\_\_' in \$placeholders so that tricks like | |
| -\code{\$obj.\_\_class\_\_.\_\_dict\_\_} are not possible. | |
| - | |
| -\end{enumerate} | |
| - | |
| - | |
| diff --git a/docs/devel_guide_src/template.tex b/docs/devel_guide_src/template.tex | |
| deleted file mode 100755 | |
| index 1ad21c4..0000000 | |
| --- a/docs/devel_guide_src/template.tex | |
| +++ /dev/null | |
| @@ -1,11 +0,0 @@ | |
| -\section{Template} | |
| -\label{template} | |
| - | |
| -This chapter will mainly walk through the \code{Cheetah.Template} constructor | |
| -and not at what point the template is compiled. | |
| - | |
| -(Also need to look at Transaction,py and Servlet.py.) | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "devel_guide" | |
| -% End: | |
| diff --git a/docs/howto_extras/comparisions.txt b/docs/howto_extras/comparisions.txt | |
| deleted file mode 100755 | |
| index 56a0fb3..0000000 | |
| --- a/docs/howto_extras/comparisions.txt | |
| +++ /dev/null | |
| @@ -1,451 +0,0 @@ | |
| -\section{Cheetah vs. Other Template Engines} | |
| -\label{comparisons} | |
| - | |
| -This appendix compares Cheetah with various other template/emdedded scripting | |
| -languages and Internet development frameworks. As Cheetah is similar to | |
| -Velocity at a superficial level, you may also wish to read comparisons between | |
| -Velocity and other languages at | |
| -\url{http://jakarta.apache.org/velocity/ymtd/ymtd.html}. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Which features are unique to Cheetah} | |
| -\label{comparisons.unique} | |
| - | |
| -\begin{itemize} | |
| -\item The {\bf block framework} (section \ref{inheritanceEtc.block}) | |
| -\item Cheetah's powerful yet simple {\bf caching framework} (section | |
| - \ref{output.caching}) | |
| -\item Cheetah's {\bf Unified Dotted Notation} and {\bf autocalling} | |
| - (sections \ref{language.namemapper.dict} and | |
| - \ref{language.namemapper.autocalling}) | |
| -\item Cheetah's searchList (section \ref{language.searchList}) | |
| - information. | |
| -\item Cheetah's \code{\#raw} directive (section \ref{output.raw}) | |
| -\item Cheetah's \code{\#slurp} directive (section \ref{output.slurp}) | |
| -\item Cheetah's tight integration with Webware for Python (section | |
| - \ref{webware}) | |
| -\item Cheetah's {\bf SkeletonPage framework} (section | |
| - \ref{libraries.templates.skeletonPage}) | |
| -\item Cheetah's ability to mix PSP-style code with Cheetah | |
| - Language syntax (section \ref{tips.PSP}) | |
| - Because of Cheetah's design and Python's flexibility it is | |
| - relatively easy to extend Cheetah's syntax with syntax elements from almost | |
| - any other template or embedded scripting language. | |
| -\end{itemize} | |
| - | |
| -%% @@MO: What about the new features we've been adding? | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Cheetah vs. Velocity} | |
| -\label{comparisons.velocity} | |
| - | |
| -For a basic introduction to Velocity, visit | |
| -\url{http://jakarta.apache.org/velocity}. | |
| - | |
| -Velocity is a Java template engine. It's older than Cheetah, has a larger user | |
| -base, and has better examples and docs at the moment. Cheetah, however, has a | |
| -number of advantages over Velocity: | |
| -\begin{itemize} | |
| -\item Cheetah is written in Python. Thus, it's easier to use and extend. | |
| -\item Cheetah's syntax is closer to Python's syntax than Velocity's is to | |
| -Java's. | |
| -\item Cheetah has a powerful caching mechanism. Velocity has no equivalent. | |
| -\item It's far easier to add data/objects into the namespace where \$placeholder | |
| - values are extracted from in Cheetah. Velocity calls this namespace a 'context'. | |
| - Contexts are dictionaries/hashtables. You can put anything you want into a | |
| - context, BUT you have to use the .put() method to populate the context; | |
| - e.g., | |
| - | |
| -\begin{verbatim} | |
| -VelocityContext context1 = new VelocityContext(); | |
| -context1.put("name","Velocity"); | |
| -context1.put("project", "Jakarta"); | |
| -context1.put("duplicate", "I am in context1"); | |
| -\end{verbatim} | |
| - | |
| - Cheetah takes a different approach. Rather than require you to manually | |
| - populate the 'namespace' like Velocity, Cheetah will accept any existing | |
| - Python object or dictionary AS the 'namespace'. Furthermore, Cheetah | |
| - allows you to specify a list namespaces that will be searched in sequence | |
| - to find a varname-to-value mapping. This searchList can be extended at | |
| - run-time. | |
| - | |
| - If you add a `foo' object to the searchList and the `foo' has an attribute | |
| - called 'bar', you can simply type \code{\$bar} in the template. If the | |
| - second item in the searchList is dictionary 'foofoo' containing | |
| - \code{\{'spam':1234, 'parrot':666\}}, Cheetah will first look in the `foo' | |
| - object for a `spam' attribute. Not finding it, Cheetah will then go to | |
| - `foofoo' (the second element in the searchList) and look among its | |
| - dictionary keys for `spam'. Finding it, Cheetah will select | |
| - \code{foofoo['spam']} as \code{\$spam}'s value. | |
| - | |
| -\item In Cheetah, the tokens that are used to signal the start of | |
| - \$placeholders and \#directives are configurable. You can set them to any | |
| - character sequences, not just \$ and \#. | |
| -\end{itemize} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Cheetah vs. WebMacro} | |
| -\label{comparisons.webmacro} | |
| - | |
| -For a basic introduction to WebMacro, visit | |
| -\url{http://webmacro.org}. | |
| - | |
| -The points discussed in section \ref{comparisons.velocity} also apply to the | |
| -comparison between Cheetah and WebMacro. For further differences please refer | |
| -to \url{http://jakarta.apache.org/velocity/differences.html}. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Cheetah vs. Zope's DTML} | |
| -\label{comparisons.dtml} | |
| - | |
| -For a basic introduction to DTML, visit | |
| -\url{http://www.zope.org/Members/michel/ZB/DTML.dtml}. | |
| - | |
| -\begin{itemize} | |
| -\item Cheetah is faster than DTML. | |
| -\item Cheetah does not use HTML-style tags; DTML does. Thus, Cheetah tags are | |
| - visible in rendered HTML output if something goes wrong. | |
| -\item DTML can only be used with ZOPE for web development; Cheetah can be | |
| - used as a standalone tool for any purpose. | |
| -\item Cheetah's documentation is more complete than DTML's. | |
| -\item Cheetah's learning curve is shorter than DTML's. | |
| -\item DTML has no equivalent of Cheetah's blocks, caching framework, | |
| - unified dotted notation, and \code{\#raw} directive. | |
| -\end{itemize} | |
| - | |
| -Here are some examples of syntax differences between DTML and Cheetah: | |
| -\begin{verbatim} | |
| -<ul> | |
| -<dtml-in frogQuery> | |
| - <li><dtml-var animal_name></li> | |
| -</dtml-in> | |
| -</ul> | |
| -\end{verbatim} | |
| - | |
| -\begin{verbatim} | |
| -<ul> | |
| -#for $animal_name in $frogQuery | |
| - <li>$animal_name</li> | |
| -#end for | |
| -</ul> | |
| -\end{verbatim} | |
| - | |
| -\begin{verbatim} | |
| -<dtml-if expr="monkeys > monkey_limit"> | |
| - <p>There are too many monkeys!</p> | |
| -<dtml-elif expr="monkeys < minimum_monkeys"> | |
| - <p>There aren't enough monkeys!</p> | |
| -<dtml-else> | |
| - <p>There are just enough monkeys.</p> | |
| -</dtml-if> | |
| -\end{verbatim} | |
| - | |
| -\begin{verbatim} | |
| -#if $monkeys > $monkey_limit | |
| - <p>There are too many monkeys!</p> | |
| -#else if $monkeys < $minimum_monkeys | |
| - <p>There aren't enough monkeys!</p> | |
| -#else | |
| - <p>There are just enough monkeys.</p> | |
| -#end if | |
| -\end{verbatim} | |
| - | |
| -\begin{verbatim} | |
| -<table> | |
| -<dtml-in expr="objectValues('File')"> | |
| - <dtml-if sequence-even> | |
| - <tr bgcolor="grey"> | |
| - <dtml-else> | |
| - <tr> | |
| - </dtml-if> | |
| - <td> | |
| - <a href="&dtml-absolute_url;"><dtml-var title_or_id></a> | |
| - </td></tr> | |
| -</dtml-in> | |
| -</table> | |
| -\end{verbatim} | |
| - | |
| -\begin{verbatim} | |
| -<table> | |
| -#set $evenRow = 0 | |
| -#for $file in $files('File') | |
| - #if $evenRow | |
| - <tr bgcolor="grey"> | |
| - #set $evenRow = 0 | |
| - #else | |
| - <tr> | |
| - #set $evenRow = 1 | |
| - #end if | |
| - <td> | |
| - <a href="$file.absolute_url">$file.title_or_id</a> | |
| - </td></tr> | |
| -#end for | |
| -</table> | |
| -\end{verbatim} | |
| - | |
| -The last example changed the name of \code{\$objectValues} to | |
| -\code{\$files} because that's what a Cheetah developer would write. | |
| -The developer would be responsible for ensuring \code{\$files} returned a | |
| -list (or tuple) of objects (or dictionaries) containing the attributes (or | |
| -methods or dictionary keys) `absolute\_url' and `title\_or\_id'. All these | |
| -names (`objectValues', `absolute\_url' and `title\_or\_id') are standard parts | |
| -of Zope, but in Cheetah the developer is in charge of writing them and giving | |
| -them a reasonable behaviour. | |
| - | |
| -Some of DTML's features are being ported to Cheetah, such as | |
| -\code{Cheetah.Tools.MondoReport}, which is based on the | |
| -\code{<dtml-in>} tag. We are also planning an output filter as flexible as | |
| -the \code{<dtml-var>} formatting options. However, neither of these are | |
| -complete yet. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Cheetah vs. Zope Page Templates} | |
| -\label{comparisons.zpt} | |
| - | |
| -For a basic introduction to Zope Page Templates, please visit | |
| -\url{http://www.zope.org/Documentation/Articles/ZPT2}. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Cheetah vs. PHP's Smarty templates} | |
| -\label{comparisons.smarty} | |
| - | |
| -PHP (\url{http://www.php.net/}) is one of the few scripting languages | |
| -expressly designed for web servlets. However, it's also a full-fledged | |
| -programming language with libraries similar to Python's and Perl's. The | |
| -syntax and functions are like a cross between Perl and C plus some original | |
| -ideas (e.g.; a single array type serves as both a list and a dictionary, | |
| -\verb+$arr[]="value";+ appends to an array). | |
| - | |
| -Smarty (\url{http://smarty.php.net/}) is an advanced template engine for | |
| -PHP. ({\em Note:} this comparision is based on Smarty's on-line documentation. | |
| -The author has not used Smarty. Please send corrections or ommissions to the | |
| -Cheetah mailing list.) Like Cheetah, Smarty: | |
| - | |
| -\begin{itemize} | |
| -\item compiles to the target programming language (PHP). | |
| -\item has configurable delimeters. | |
| -\item passes if-blocks directly to PHP, so you can use any PHP expression in | |
| -them. | |
| -\item allows you to embed PHP code in a template. | |
| -\item has a caching framework (although it works quite differently). | |
| -\item can read the template definition from any arbitrary source. | |
| -\end{itemize} | |
| - | |
| -Features Smarty has that Cheetah lacks: | |
| -\begin{itemize} | |
| -\item Preprocessors, postprocessors and output filters. You can emulate a | |
| -preprocessor in Cheetah by running your template definition through a filter | |
| -program or function before Cheetah sees it. To emulate a postprocessor, run a | |
| -.py template module through a filter program/function. To emulate a Smarty | |
| -output filter, run the template output through a filter program/function. If | |
| -you want to use ``cheetah compile'' or ``cheetah fill'' in a pipeline, use | |
| -\code{-} as the input file name and \code{--stdout} to send the result to | |
| -standard output. Note that Cheetah uses the term ``output filter'' differently | |
| -than Smarty: Cheetah output filters (\code{\#filter}) operate on placeholders, | |
| -while Smarty output filters operate on the entire template output. There has | |
| -been a proposed \code{\#sed} directive that would operate on the entire output | |
| -line by line, but it has not been implemented. | |
| -\item Variable modifiers. In some cases, Python has equivalent string | |
| -methods (\code{.strip}, \code{.capitalize}, \code{.replace(SEARCH, REPL)}), | |
| -but in other cases you must wrap the result in a function call or write | |
| -a custom output filter (\code{\#filter}). | |
| -\item Certain web-specific functions, which can be emulated with | |
| -third-party functions. | |
| -\item The ability to ``plug in'' new directives in a modular way. Cheetah | |
| -directives are tightly bound to the compiler. However, third-party | |
| -{\em functions} can be freely imported and called from placeholders, and | |
| -{\em methods} can be mixed in via \code{\#extends}. Part of this is | |
| -because Cheetah distinguishes between functions and directives, while | |
| -Smarty treats them all as ``functions''. Cheetah's design does not | |
| -allow functions to have flow control effect outside the function | |
| -(e.g., \code{\#if} and \code{\#for}, which operate on template body lines), | |
| -so directives like these cannot be encoded as functions. | |
| -\item Configuration variables read from an .ini-style file. The | |
| -\code{Cheetah.SettingsManager} module can parse such a file, but you'd | |
| -have to invoke it manually. (See the docstrings in the module for | |
| -details.) In Smarty, this feature is used for | |
| -multilingual applications. In Cheetah, the developers maintain that everybody | |
| -has their own preferred way to do this (such as using Python's \code{gettext} | |
| -module), and it's not worth blessing one particular strategy in Cheetah since | |
| -it's easy enough to integrate third-party code around the template, or to add | |
| -the resulting values to the searchList. | |
| -\end{itemize} | |
| - | |
| -Features Cheetah has that Smarty lacks: | |
| -\begin{itemize} | |
| -\item Saving the compilation result in a Python (PHP) module for quick | |
| -reading later. | |
| -\item Caching individual placeholders or portions of a template. Smarty | |
| -caches only the entire template output as a unit. | |
| -\end{itemize} | |
| - | |
| -Comparisions of various Smarty constructs: | |
| -\begin{verbatim} | |
| -{assign var="name" value="Bob"} (#set has better syntax in the author's opinion) | |
| -counter (looks like equivalent to #for) | |
| -eval (same as #include with variable) | |
| -fetch: insert file content into output (#include raw) | |
| -fetch: insert URL content into output (no euqivalent, user can write | |
| - function calling urllib, call as $fetchURL('URL') ) | |
| -fetch: read file into variable (no equivalent, user can write function | |
| - based on the 'open/file' builtin, or on .getFileContents() in | |
| - Template.) | |
| -fetch: read URL content into variable (no equivalent, use above | |
| - function and call as: #set $var = $fetchURL('URL') | |
| -html_options: output an HTML option list (no equivalent, user can | |
| - write custom function. Maybe FunFormKit can help.) | |
| -html_select_date: output three dropdown controls to specify a date | |
| - (no equivalent, user can write custom function) | |
| -html_select_time: output four dropdown controls to specify a time | |
| - (no equvalent, user can write custom function) | |
| -math: eval calculation and output result (same as #echo) | |
| -math: eval calculation and assign to variable (same as #set) | |
| -popup_init: library for popup windows (no equivalent, user can write | |
| - custom method outputting Javascript) | |
| - | |
| - | |
| -Other commands: | |
| -capture (no equivalent, collects output into variable. A Python | |
| - program would create a StringIO instance, set sys.stdout to | |
| - it temporarily, print the output, set sys.stdout back, then use | |
| - .getvalue() to get the result.) | |
| -config_load (roughly analagous to #settings, which was removed | |
| - from Cheetah. Use Cheetah.SettingsManager manually or write | |
| - a custom function.) | |
| -include (same as #include, but can include into variable. | |
| - Variables are apparently shared between parent and child.) | |
| -include_php: include a PHP script (e.g., functions) | |
| - (use #extends or #import instead) | |
| -insert (same as #include not in a #cache region) | |
| -{ldelim}{rdelim} (escape literal $ and # with a backslash, | |
| - use #compiler-settings to change the delimeters) | |
| -literal (#raw) | |
| -php (``<% %>'' tags) | |
| -section (#for $i in $range(...) ) | |
| -foreach (#for) | |
| -strip (like the #sed tag which was never implemented. Strips | |
| - leading/trailing whitespace from lines, joins several lines | |
| - together.) | |
| - | |
| - | |
| -Variable modifiers: | |
| -capitalize ( $STRING.capitalize() ) | |
| -count_characters ( $len(STRING) ) | |
| -count_paragraphs/sentances/words (no equivalent, user can write function) | |
| -date_format (use 'time' module or download Egenix's mx.DateTime) | |
| -default ($getVar('varName', 'default value') ) | |
| -escape: html encode ($cgi.escape(VALUE) ) | |
| -escape: url encode ($urllib.quote_plus(VALUE) ) | |
| -escape: hex encode (no equivalent? user can write function) | |
| -escape: hex entity encode (no equivalent? user can write function) | |
| -indent: indent all lines of a var's output (may be part of future | |
| - #indent directive) | |
| -lower ($STRING.lower() ) | |
| -regex_replace ('re' module) | |
| -replace ($STRING.replace(OLD, NEW, MAXSPLIT) ) | |
| -spacify (#echo "SEPARATOR".join(SEQUENCE) ) | |
| -string_format (#echo "%.2f" % FLOAT , etc.) | |
| -strip_tags (no equivalent, user can write function to strip HTML tags, | |
| - or customize the WebSafe filter) | |
| -truncate (no equivalent, user can write function) | |
| -upper ($STRING.upper() ) | |
| -wordwrap ('writer' module, or a new module coming in Python 2.3) | |
| -\end{verbatim} | |
| - | |
| -Some of these modifiers could be added to the super output filter we | |
| -want to write someday. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Cheetah vs. PHPLib's Template class} | |
| -\label{comparisons.php} | |
| - | |
| -PHPLib (\url(http://phplib.netuse.de/) is a collection of classes for various | |
| -web objects (authentication, shopping cart, sessions, etc), but what we're | |
| -interested in is the \code{Template} object. It's much more primitive than | |
| -Smarty, and was based on an old Perl template class. In fact, one of the | |
| -precursors to Cheetah was based on it too. Differences from Cheetah: | |
| - | |
| -\begin{itemize} | |
| -\item Templates consist of text with \code{\{placeholders\}} in braces. | |
| -\item Instead of a searchList, there is one flat namespace. Every variable | |
| - must be assigned via the \code{set\_var} method. However, you can pass | |
| - this method an array (dictionary) of several variables at once. | |
| -\item You cannot embed lookups or calculations into the template. Every | |
| - placeholder must be an exact variable name. | |
| -\item There are no directives. You must do all display logic (if, for, etc) | |
| - in the calling routine. | |
| -\item There is, however, a ``block'' construct. A block is a portion of text | |
| - between the comment markers \code{<!-- BEGIN blockName --> \ldots | |
| - <!-- END blockName>}. The \code{set\_block} method extracts this text | |
| - into a namespace variable and puts a placeholder referring to it in the | |
| - template. This has a few parallels with Cheetah's \code{\#block} | |
| - directive but is overall quite different. | |
| -\item To do the equivalent of \code{\#if}, extract the block. Then if true, do | |
| - nothing. If false, assign the empty string to the namespace variable. | |
| -\item To do the equivalent of \code{\#for}, extract the block. Set any | |
| - namespace variables needed inside the loop. To parse one iteration, use | |
| - the \code{parse} method to fill the block variable (a mini-template) into | |
| - another namespace variable, appending to it. Refresh the namespace | |
| - variables needed inside the loop and parse again; repeat for each | |
| - iteration. You'll end up with a mini-result that will be plugged into the | |
| - main template's placeholder. | |
| -\item To read a template definition from a file, use the \code{set\_file} | |
| - method. This places the file's content in a namespace variable. | |
| - To read a template definition from a string, assign it to a namespace | |
| - variable. | |
| -\item Thus, for complicated templates, you are doing a lot of recursive block | |
| - filling and file reading and parsing mini-templates all into one flat | |
| - namespace as you finally build up values for the main template. In | |
| - Cheetah, all this display logic can be embedded into the template using | |
| - directives, calling out to Python methods for the more complicated tasks. | |
| -\item Although you can nest blocks in the template, it becomes tedious and | |
| - arguably hard to read, because all blocks have identical syntax. Unless | |
| - you choose your block names carefully and put comments around them, it's | |
| - hard to tell which blocks are if-blocks and which are for-blocks, or what | |
| - their nesting order is. | |
| -\item PHPLib templates do not have caching, output filters, etc. | |
| -\end{itemize} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Cheetah vs. PSP, PHP, ASP, JSP, Embperl, etc.} | |
| -\label{comparisons.pspEtc} | |
| - | |
| -\begin{description} | |
| -\item[Webware's PSP Component] -- \url{http://webware.sourceforge.net/Webware/PSP/Docs/} | |
| -\item[Tomcat JSP Information] -- \url{http://jakarta.apache.org/tomcat/index.html} | |
| -\item[ASP Information at ASP101] -- \url{http://www.asp101.com/} | |
| -\item[Embperl] -- \url{http://perl.apache.org/embperl/} | |
| -\end{description} | |
| - | |
| - | |
| -Here's a basic Cheetah example: | |
| -\begin{verbatim} | |
| -<TABLE> | |
| -#for $client in $service.clients | |
| -<TR> | |
| -<TD>$client.surname, $client.firstname</TD> | |
| -<TD><A HREF="mailto:$client.email" >$client.email</A></TD> | |
| -</TR> | |
| -#end for | |
| -</TABLE> | |
| -\end{verbatim} | |
| - | |
| -Compare this with PSP: | |
| - | |
| -\begin{verbatim} | |
| -<TABLE> | |
| -<% for client in service.clients(): %> | |
| -<TR> | |
| -<TD><%=client.surname()%>, <%=client.firstname()%></TD> | |
| -<TD><A HREF="mailto:<%=client.email()%>"><%=client.email()%></A></TD> | |
| -</TR> | |
| -<%end%> | |
| -</TABLE> | |
| -\end{verbatim} | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| diff --git a/docs/users_guide_2_src/01_introduction.txt b/docs/users_guide_2_src/01_introduction.txt | |
| deleted file mode 100755 | |
| index 34beeb6..0000000 | |
| --- a/docs/users_guide_2_src/01_introduction.txt | |
| +++ /dev/null | |
| @@ -1,291 +0,0 @@ | |
| -Introduction | |
| -============ | |
| - | |
| -.. | |
| - :label: intro | |
| - | |
| -Who should read this Guide? | |
| ---------------------------- | |
| - | |
| -.. | |
| - :label: intro.whoShouldRead | |
| - | |
| -This Users' Guide is for Python programmers. Part I is a tutorial/reference | |
| -and should be read by everybody. Part II is a cookbook of of techniques for | |
| -using Cheetah with various web frameworks and various non-HTML output formats, | |
| -plus some technical appendices. The PDF version of this Guide is distributed | |
| -as two files so you can print Part I to read offline without having to print a | |
| -lot of pages from Part II that don't apply to you. | |
| - | |
| -What is Cheetah? | |
| ----------------- | |
| - | |
| -.. | |
| - :label: intro.whatIs | |
| - | |
| -Cheetah is a template engine for Python. A template engine is like Python's | |
| -``%`` operator for strings: it has fixed parts which are output verbatim, and | |
| -*placeholders* which are replaced by their values:: | |
| - | |
| - # Python's "%" operator (not Cheetah) | |
| - >>> "The king is a %(noun)s!" % {"noun": "fink"} | |
| - 'The king is a fink!" | |
| - | |
| -Templates are useful for form letters, dynamic web pages, customized source | |
| -code or SQL, and innumerable other tasks. Cheetah is like a super-powered | |
| -``%`` operator, but it also has many other features needed in real-world | |
| -templating situations. | |
| - | |
| -Viewed another way, Cheetah is an alternate source format for Python modules, | |
| -one that's friendlier for large chunks of text. Compiled templates are | |
| -ordinary Python modules which can be imported. Cheetah is one of Python's | |
| -oldest template engines and perhaps the most widely used. This is mainly due | |
| -to its speed (hence the name Cheetah), stability, and suitability for many | |
| -output formats. Cheetah has been used in production environments since 2001 | |
| -(0.9.9a1), and changes are committed conservatively, so even the CVS version is | |
| -usually more bug-free than the previous release. | |
| - | |
| -Cheetah's syntax uses ``$`` before placeholders and a ``#`` | |
| -before control structures (directives), although these characters can be | |
| -changed. This differs from Python's other template systems which generally use | |
| -XML tags (Kid and Tal) or a function syntax (PTL and QPY). The difference | |
| -allows Cheetah to be more suitable for a variety of output formats, and even | |
| -users of the other systems often use Cheetah for non-HTML output such as | |
| -text, Python source code, or SQL. Cheetah's syntax and behavior was | |
| -inspired most directly by Velocity, a Java template engine. In PHP, Smarty is | |
| -Cheetah's closest equivalent. Cheetah templates tend to be function-driven: | |
| -define a method with ``#def``, and call it via a placeholder with arguments. | |
| -Cheetah also has PSP-style tags (``<% %>``) and ``#include``, which will be | |
| -familiar to people coming from ASP/JSP/PHP. However, we'll argue that these | |
| -should be used sparingly, since there are other constructs which are more | |
| -readable. | |
| - | |
| - | |
| -Cheetah: | |
| - | |
| -* generates HTML, SGML, XML, SQL, Postscript, form email, LaTeX, or any | |
| - other text-based format. It has also been used to produce Python, Java | |
| - and PHP source code. | |
| - | |
| -* cleanly separates content, graphic design, and program code. This leads | |
| - to highly modular, flexible, and reusable site architectures; faster | |
| - development time; and HTML and program code that is easier to understand | |
| - and maintain. It is particularly well suited for team efforts. | |
| - | |
| -* blends the power and flexibility of Python with a simple template language | |
| - that non*programmers can understand. | |
| - | |
| -* gives template writers full access in their templates to any Python data | |
| - structure, module, function, object, or method. | |
| - | |
| -* makes code reuse easy by providing an object-oriented interface to | |
| - templates that is accessible from Python code or other Cheetah templates. | |
| - One template can subclass another and selectively reimplement sections of | |
| - it. A compiled template {\em is} a Python class, so it can subclass a | |
| - pure Python class and vice*versa. | |
| - | |
| -* provides a simple yet powerful caching mechanism | |
| - | |
| -Here's a simple example of a Cheetah template:: | |
| - | |
| - <HTML> | |
| - <HEAD><TITLE>$title</TITLE></HEAD> | |
| - <BODY> | |
| - | |
| - <TABLE> | |
| - #for client in clients | |
| - <TR> | |
| - <TD>$client.surname, $client.firstname</TD> | |
| - <TD><A HREF="mailto:$client.email">$client.email</A></TD> | |
| - </TR> | |
| - #end for | |
| - </TABLE> | |
| - | |
| - </BODY> | |
| - </HTML> | |
| - | |
| -* has a lot of features but most of them are optional. Cheetah is easy to use | |
| - in simple cases, and scales well to complex cases. Most of Cheetah's | |
| - features were added due to demonstrated needs in production environments | |
| - where Cheetah was already runing. | |
| - | |
| -Cheetah is distributed under a BSD-style open-source license. See appendix E | |
| -(E_license.txt) for details. Cheetah exists thanks to the help of many | |
| -open-source volunteers (http://cheetahtemplate.sourceforge.net/credits.html). | |
| - | |
| - | |
| - | |
| -What is the philosophy behind Cheetah? | |
| --------------------------------------- | |
| - | |
| -.. | |
| - :label: intro.philosophy | |
| - | |
| -Cheetah's design was guided by these principles: | |
| - | |
| -* Python for the back end (business logic), Cheetah for the front end | |
| - (presentation format). Cheetah was designed to complement Python, not | |
| - replace it. | |
| - | |
| -* Cheetah's core syntax should be easy for non-programmers to learn. | |
| - | |
| -* Cheetah should make code reuse easy by providing an object-oriented | |
| - interface to templates that is accessible from Python code or other | |
| - Cheetah templates. | |
| - | |
| -* Python objects, functions, and other data structures should be fully | |
| - accessible in Cheetah. | |
| - | |
| -* Cheetah should provide flow control and error handling. Logic | |
| - that belongs in the front end shouldn't be relegated to the | |
| - back end simply because it's complex. | |
| - | |
| -* It should be easy to {\bf separate} content, graphic design, and program | |
| - code, but also easy to {\bf integrate} them. | |
| - | |
| - A clean separation makes it easier for a team of content writers, | |
| - HTML/graphic designers, and programmers to work together without stepping | |
| - on each other's toes and polluting each other's work. The HTML framework | |
| - and the content it contains are two separate things, and analytical | |
| - calculations (program code) is a third thing. Each team member should be | |
| - able to concentrate on their specialty and to implement their changes | |
| - without having to go through one of the others (i.e., the dreaded | |
| - "webmaster bottleneck"). | |
| - | |
| - While it should be easy to develop content, graphics and program | |
| - code separately, it should be easy to integrate them together into a | |
| - website. In particular, it should be easy: | |
| - | |
| - - for {\bf programmers} to create reusable components and functions | |
| - that are accessible and understandable to designers. | |
| - - for {\bf designers} to mark out placeholders for content and | |
| - dynamic components in their templates. | |
| - - for {\bf designers} to soft-code aspects of their design that are | |
| - either repeated in several places or are subject to change. | |
| - - for {\bf designers} to reuse and extend existing templates and thus | |
| - minimize duplication of effort and code. | |
| - - and, of course, for {\bf content writers} to use the templates that | |
| - designers have created. | |
| - | |
| -* Features are added only to support a demonstrated need in production | |
| - applications, and generally only if the feature is useful for a wide variety | |
| - of situations and output formats. This prevents Cheetah from accumulating | |
| - lots of esoteric features which are used only rarely. | |
| - | |
| - | |
| -Why Cheetah doesn't use HTML-style tags | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| - | |
| -.. | |
| - :label: intro.htmlStyleTags | |
| - | |
| -Cheetah does not use HTML/XML-style tags for flow control, unlike some other | |
| -Python template engines, for the following reasons: | |
| - | |
| -* Cheetah is not limited to HTML, | |
| -* HTML-style tags are hard to distinguish from real HTML tags, | |
| -* HTML-style tags are not visible in rendered HTML when something goes wrong, | |
| -* HTML-style tags often lead to invalid HTML (e.g., | |
| - \code{<img src="<template*directive>">}), | |
| - | |
| -Cheetah tags are less verbose and easier to understand than HTML-style tags, | |
| -and HTML-style tags aren't compatible with most WYSIWYG editors. In a WSYWIG | |
| -editor, Cheetah tags appear to be literal text. | |
| - | |
| -Besides being much more compact, Cheetah also has some advantages over | |
| -languages that put information inside the HTML tags, such as Zope Page | |
| -Templates or PHP: | |
| - | |
| -* HTML or XML-bound languages do not work well with other languages, | |
| -* While ZPT-like syntaxes work well in many ways with WYSIWYG HTML editors, | |
| - they also give up a significant advantage of those editors -- concrete | |
| - editing of the document. When logic is hidden away in (largely | |
| - inaccessible) tags it is hard to understand a page simply by viewing it, | |
| - and it is hard to confirm or modify that logic. | |
| - | |
| - | |
| -How stable is Cheetah? How do I upgrade? | |
| ------------------------------------------ | |
| - | |
| -.. | |
| - :label: intro.stable | |
| - | |
| -Cheetah 2.0 was released [MONTH] [YEAR] with internal restructuring, | |
| -easier-to-understand usage, updated documentation, and many other improvements. | |
| -Cheetah 1.0 was released December 2005 after a three-year stable beta. | |
| -Production sites have been using Cheetah since 2001. Most changes since then | |
| -have been based on requests from production sites: things they need that we | |
| -hadn't considered. | |
| - | |
| -Templates and calling code from Cheetah 1.0 remain 100% compatible. Those from | |
| -pre-1.0 versions since December 2001 (0.9.9) remain compatible except in rare | |
| -cases. | |
| - | |
| -.. important:: | |
| - You must recompile all precompiled templates when upgrading | |
| - to Cheetah 2.0. | |
| - | |
| -Upgrades from 2.0 to a future version may or may not require | |
| -recompilation. Try filling a single precompiled template and see if you get a | |
| -version exception. If you do, recompile them all. Or to be safe on a | |
| -production site, just recompile them all anyway. | |
| - | |
| -Cheetah's development version is normally as stable as the last release if not | |
| -better. All CVS checkins are installed and run through the test suite before | |
| -being checked in. | |
| - | |
| -Additional information is in these files in the Cheetah source distribution: | |
| - | |
| -CHANGES: | |
| - All changes in each version. | |
| -BUGS: | |
| - Known bugs we haven't fixed yet. | |
| -TODO: | |
| - Enhancements we're planning, thing's like to do someday, and user requests | |
| - we haven't committed to. | |
| - | |
| - | |
| -Web site and mailing list | |
| -------------------------- | |
| - | |
| -.. | |
| - :label: intro.news | |
| - | |
| -Cheetah releases and other stuff can be obtained from the the Cheetah | |
| -{\bf Web site}: | |
| -\url{http://CheetahTemplate.sourceforge.net} | |
| - | |
| -Cheetah discussions take place on the {\bf mailing list} | |
| -\email{cheetahtemplate-discuss@lists.sourceforge.net}. This is where to hear | |
| -the latest news first. | |
| - | |
| -If you encounter difficulties, or are unsure about how to do something, | |
| -please post a detailed message to the list. Also please share your | |
| -experiences, tricks, customizations, and frustrations. And if you have a | |
| -success story for the "Who Is Using Cheetah" | |
| -(http://cheetahtemplate.sourceforge.net/whouses.html) or | |
| -"Testimonials" (http://cheetahtemplate.sourceforge.net/praise.html) | |
| -page on the website, send it to the mailing list. | |
| - | |
| - | |
| -Bug reports, patches, and the test suite | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| - | |
| -If you think there is a bug in Cheetah, send a message to the mailing list | |
| -with the following information: | |
| - | |
| -* a description of what you were trying to do and what happened | |
| -* all tracebacks and error output | |
| -* your version of Cheetah | |
| -* your version of Python | |
| -* your operating system | |
| -* whether you have changed anything in the Cheetah installation | |
| - | |
| -Cheetah is packaged with a regression testing suite that is run with each | |
| -new release to ensure that everything is working as expected and that recent | |
| -changes haven't broken anything. The test cases are in the Cheetah.Tests | |
| -module. If you find a reproduceable bug please consider writing a test case | |
| -that will pass only when the bug is fixed. Send any new test cases to the email | |
| -list with the subject-line "new test case for Cheetah". (@@MO Shorten | |
| -paragraph, link to testing section.) | |
| - | |
| diff --git a/docs/users_guide_2_src/02_glossary.txt b/docs/users_guide_2_src/02_glossary.txt | |
| deleted file mode 100644 | |
| index 49988fd..0000000 | |
| --- a/docs/users_guide_2_src/02_glossary.txt | |
| +++ /dev/null | |
| @@ -1,66 +0,0 @@ | |
| -Glossary | |
| -======== | |
| - | |
| -.. | |
| - :label: glossary | |
| - | |
| -**Template** is an informal term meaning a template definition, a template | |
| -class or a template instance. A **template definition** is what the human | |
| -maintainer writes: a file or string consisting of text, placeholders and | |
| -directives. **Placeholders** are variables that will be looked up when the | |
| -template is filled. **Directives** are commands to be executed when the | |
| -template is filled, or instructions to the Cheetah compiler. Placeholders | |
| -normally start with "$"; directives with "#". The conventional suffix for a | |
| -file containing a template definition is **.tmpl**. | |
| - | |
| -To use a template, you first **compile** the template definition into | |
| -**template class**. Then you instantiate the class and **fill** it by calling | |
| -one of its instance methods. Filling does all the placeholder lookups and | |
| -returns the finished result. Templates can be compiled in memory or written to | |
| -a Python module, called a **precompiled template**. | |
| - | |
| -Every template has a **main** method that fills the entire template. The main | |
| -method is usually ``.respond()``. Calling ``str()`` or ``unicode()`` on a | |
| -template instance is the same as calling the main method. Templates can also | |
| -contain **#def methods** (via ``#def`` or ``#block``), which can be called | |
| -directly. | |
| - | |
| -A **placeholder** consists of one or more **identifiers** separated by periods. | |
| -Identifiers must follow the same rules as Python variable names, and may be | |
| -followed by the usual ``[]`` and ``()`` as in Python. Example with three | |
| -identifiers: ``a.b[2].c("arg")``. The value discovered at fill time is the | |
| -**placeholder value**. | |
| - | |
| -The first (or only) identifier of a placeholder name represents a **variable** | |
| -to be looked up. If Cheetah's **NameMapper** is turned on (the default), it | |
| -looks in various **namespaces** including the template instance's ``self``, | |
| -Python variables local/global to the template method, and an arbitrary list of | |
| -**user-defined namespaces** you may have passed to the template constructor. | |
| -A user-defined namespace is any Python object; Cheetah searches its attributes | |
| -and keys for a matching name. ``#set`` and ``#for`` create local | |
| -variables. ``#import`` and ``#set module global`` create global variables. | |
| -``#attr``, ``#def``, and ``#block`` create ``self`` variables. When the | |
| -NameMapper is turned off, only local/global variables are accessible. | |
| - | |
| -The NameMapper also handles universal dotted notation and autocalling. | |
| -**Universal dotted notation** means that keys may be written as if they were | |
| -attributes: ``a.b`` instead of ``a['b']``. **Autocalling** means that | |
| -if any identifier's value is found to be a function or method, Cheetah will | |
| -call it without arguments if there is no ``()`` following. More about the | |
| -NameMapper is in section \ref{language.namemapper}. | |
| - | |
| -Cheetah 1 used the term "searchList" for user-defined namespaces. However, | |
| -Cheetah has another **search list** internally: the actual list of namespaces | |
| -it consults. This is almost the same thing but not quite. To avoid confusion, | |
| -this Guide uses the term "search list" only for the internal list. | |
| - | |
| -Some directives are multi-line, meaning they have a matching **\#end** tag. | |
| -The lines of text between the start and end tags is the **body** of the | |
| -directive. Arguments on the same line as the start tag, in contrast, are | |
| -considered part of the directive tag. | |
| - | |
| -A **template-servlet** is a Webware_-specific construct. Any .py template | |
| -module in a Webware servlet directory can be filled directly through the web by | |
| -requesting the URL. | |
| - | |
| -.. _Webware: http://www.webwareforpython.org/ | |
| diff --git a/docs/users_guide_2_src/03_gettingStarted.txt b/docs/users_guide_2_src/03_gettingStarted.txt | |
| deleted file mode 100755 | |
| index 6e447c2..0000000 | |
| --- a/docs/users_guide_2_src/03_gettingStarted.txt | |
| +++ /dev/null | |
| @@ -1,262 +0,0 @@ | |
| -Getting Started | |
| -======================================== | |
| - | |
| -.. | |
| - :label: gettingStarted | |
| - | |
| - | |
| -Requirements | |
| ----------------------------------------- | |
| - | |
| -.. | |
| - :label: gettingStarted.requirements | |
| - | |
| -Cheetah requires Python release 2.2 or newer, and has been tested with all | |
| -versions through 2.4.2. It should run everywhere Python runs, and has been | |
| -tested on Linux, Windows NT/98/XP, FreeBSD, Solaris, and Mac OS X. | |
| - | |
| -99% of Cheetah is written in Python. There is one small C module | |
| -(``_namemapper.so``) for speed, but Cheetah automatically falls back to a | |
| -Python equivalent (``NameMapper.py``) if the C module is not available. | |
| - | |
| - | |
| -Installation | |
| ----------------------------------------- | |
| - | |
| -.. | |
| - :label: gettingStarted.install | |
| - | |
| -If you have ``easy_install`` | |
| -(http://peak.telecommunity.com/DevCenter/EasyInstall) set up, this command will | |
| -download and install the latest version of Cheetah as a Python Egg | |
| -(http://peak.telecommunity.com/DevCenter/PythonEggs):: | |
| - | |
| - # easy_install Cheetah | |
| - | |
| -Or from an already-downloaded tarball:: | |
| - | |
| - # easy_install Cheetah-2.0.tar.gz | |
| - | |
| -Or from an unpacked source directory or CVS sandbox:: | |
| - | |
| - # easy_install . | |
| - | |
| -If you don't have ``easy_install``, you'll have to install Cheetah manually:: | |
| - | |
| - # tar xzvf Cheetah-2.0.tar.gz | |
| - # cd Cheetah-2.0 | |
| - # python setup.py install | |
| - | |
| -You can also specify non-default locations:: | |
| - | |
| - # python setup.py install --install-lib=/home/tavis/python | |
| - # python setup.py install --home=/home/tavis | |
| - # python setup.py install --help | |
| - | |
| -.. tip:: | |
| - | |
| - If you install Cheetah manually and then install an egg that depends on | |
| - Cheetah (like TurboCheetah_), ``easy_install`` may *reinstall* | |
| - Cheetah as an egg. This leaves two copies of Cheetah on your system, | |
| - possibly different versions. Python will use whichever version comes | |
| - first in the Python path. To avoid this, use ``easy_install``'s | |
| - **--no-deps** option or delete the copy you don't wish to use. | |
| - | |
| - | |
| -Uninstalling | |
| ----------------------------------------- | |
| - | |
| -.. | |
| - :label: gettingstarted.uninstalling | |
| - | |
| -To uninstall Cheetah: | |
| - | |
| -1. Delete the "cheetah" program | |
| -from whichever bin/ directory it was put in (perhaps /usr/local/bin/). | |
| - | |
| -2. If Cheetah was installed as an egg, delete the egg directory | |
| -(e.g., /usr/local/lib/python2.4/site-packages/Cheetah-2.0-py2.4.egg/), and | |
| -remove the "Cheetah" line in **easy-install.pth** in the same directory. | |
| - | |
| -3. If Cheetah was not installed as an egg, delete the package directory | |
| -(e.g., /usr/local/lib/python2.4/site-packages/Cheetah/). | |
| - | |
| - | |
| -The 'cheetah' command | |
| ----------------------------------------- | |
| - | |
| -.. | |
| - :label: gettingStarted.cheetah | |
| - | |
| -Cheetah comes with a utility "cheetah" that provides a command-line | |
| -interface to various housekeeping tasks. The command's first argument is | |
| -the name of the task. The following commands are currently supported:: | |
| - | |
| - cheetah compile [options] [FILES ...] : Compile template definitions | |
| - cheetah fill [options] [FILES ...] : Fill template definitions | |
| - cheetah help : Print this help message | |
| - cheetah options : Print options help message | |
| - cheetah test : Run Cheetah's regression tests | |
| - cheetah version : Print Cheetah version number | |
| - | |
| -You only have to type the first letter of the command: | |
| -``cheetah c`` is the same as ``cheetah compile``. | |
| - | |
| -The test suite is described in the next section. The ``compile`` | |
| -command in section \ref{howWorks.cheetah-compile}, | |
| -and the ``fill`` command in section \ref{howWorks.cheetah-fill}. | |
| - | |
| - | |
| -Testing your installation | |
| ----------------------------------------- | |
| - | |
| -.. | |
| - :label: gettingStarted.test | |
| - | |
| -After installing Cheetah, you can run its self-test routine to verify it's | |
| -working properly on your system. First cd to to any directory you have write | |
| -permission in (the tests write temporary files) *except* the unpacked Cheetah | |
| -source directory (it might produce spurious errors). Type the following at the | |
| -command prompt:: | |
| - | |
| - $ cheetah test | |
| - | |
| -The tests will run for about three minutes and print a success/failure | |
| -message. If the tests pass, start Python in interactive mode and try the | |
| -example in the next section. | |
| - | |
| -Sometimes the CheetahWrapper tests fail on Windows because they can't execute | |
| -"cheetah" via ``os.system()``. Ignore these; you won't be doing this when | |
| -you use Cheetah. | |
| - | |
| -If any other 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: | |
| - | |
| -* your version of Cheetah | |
| -* your version of Python | |
| -* your operating system | |
| -* whether you have changed anything in the Cheetah installation | |
| - | |
| - | |
| - | |
| -Quickstart tutorial | |
| ----------------------------------------- | |
| - | |
| -.. | |
| - :label: gettingStarted.tutorial | |
| - | |
| -This tutorial briefly introduces how to use Cheetah from the Python prompt. | |
| -The following chapters will discuss other ways to use templates and more of | |
| -Cheetah's features. | |
| - | |
| -The core of Cheetah is the ``Template`` class in the ``Cheetah.Template`` | |
| -module. The following example shows how to use the ``Template`` class in an | |
| -interactive Python session. ``t`` is the Template instance. Lines prefixed | |
| -with ``>>>`` and ``...`` are user input. The remaining lines are Python | |
| -output. :: | |
| - | |
| - >>> from Cheetah.Template import Template | |
| - >>> templateDef = """ | |
| - ... <HTML> | |
| - ... <HEAD><TITLE>$title</TITLE></HEAD> | |
| - ... <BODY> | |
| - ... $contents | |
| - ... ## this is a single-line Cheetah comment and won't appear in the output | |
| - ... #* This is a multi-line comment and won't appear in the output | |
| - ... blah, blah, blah | |
| - ... *# | |
| - ... </BODY> | |
| - ... </HTML>""" | |
| - >>> namespace = {'title': 'Hello World Example', 'contents': 'Hello World!'} | |
| - >>> t = Template(templateDef, namespaces=[namespace]) | |
| - >>> print t | |
| - | |
| - <HTML> | |
| - <HEAD><TITLE>Hello World Example</TITLE></HEAD> | |
| - <BODY> | |
| - Hello World! | |
| - </BODY> | |
| - </HTML> | |
| - >>> print t # print it as many times as you want | |
| - [ ... same output as above ... ] | |
| - >>> namespace['title'] = 'Example #2' | |
| - >>> namespace['contents'] = 'Hiya Planet Earth!' | |
| - >>> print t # Now with different plug-in values. | |
| - <HTML> | |
| - <HEAD><TITLE>Example #2</TITLE></HEAD> | |
| - <BODY> | |
| - Hiya Planet Earth! | |
| - </BODY> | |
| - </HTML> | |
| - | |
| -Because Cheetah is extremely flexible, you can achieve the same result this | |
| -way:: | |
| - | |
| - >>> t2 = Template(templateDef) | |
| - >>> t2.title = 'Hello World Example!' | |
| - >>> t2.contents = 'Hello World' | |
| - >>> print t2 | |
| - [ ... same output as the first example above ... ] | |
| - >>> t2.title = 'Example #2' | |
| - >>> t2.contents = 'Hello World!' | |
| - >>> print t2 | |
| - [ ... same as Example #2 above ... ] | |
| - | |
| -Or the values can be extracted from an object's attributes. | |
| - | |
| - >>> myInstance.title | |
| - 'Hello World Example!' | |
| - >>> myInstance.contents = 'Hello World!' | |
| - >>> t2 = Template(templateDef, namespaces=[myInstance]) | |
| - | |
| -The template will search your namespaces in order, then its own ``self`` | |
| -attributes, until it finds a match. The template definition can also | |
| -come from a file rather than a string. | |
| - | |
| -Let's look at the ``Template`` constructor again:: | |
| - | |
| - t = Template(templateDef, namespaces=[namespace]) | |
| - | |
| -This does more than it appears. It compiles the template definition into a | |
| -template class, a subclass of ``Template``, and instantiates it. Sometimes | |
| -it's desirable to separate these operations, and the ``.compile`` class method | |
| -does this:: | |
| - | |
| - tclass = Template.compile(templateDef) | |
| - t = tclass(namespaces=[namespace]) | |
| - | |
| -The first line compiles the template class; the second line instantiates it. | |
| -You can also do this on one line:: | |
| - | |
| - t = Template.compile(templateDef)(namespaces=[namespace]) | |
| - | |
| -You can use either ``Template()`` or ``Template.compile()`` in your programs, | |
| -but you should learn both styles so you'll recognize them in other people's | |
| -code. | |
| - | |
| -This is all fine for short templates, but for long templates or for an | |
| -application that depends on many templates, it's easier to store the templates | |
| -in separate \*.tmpl files and use the **cheetah** program to compile | |
| -them into Python modules. This will be covered in section | |
| -\ref{howWorks.cheetah-compile}. Here's how you use a precompiled template:: | |
| - | |
| - >>> from MyPrecompiledTemplate import MyPrecompiledTemplate | |
| - >>> t = MyPrecompiledTemplate() | |
| - >>> t.name = "Fred Flintstone" | |
| - >>> t.city = "Bedrock City" | |
| - >>> print t | |
| - | |
| -Or:: | |
| - | |
| - >>> from MyPrecompiledTemplate import MyPrecompiledTemplate | |
| - >>> namespace = {"name": "Fred Flintstone", "city": "Bedrock City"} | |
| - >>> t = MyPrecompiledTemplate(namespaces=[namespace]) | |
| - >>> print t | |
| - | |
| -For the minimalists out there, here's a template compilation, | |
| -instantiation and filling all in one Python statement:: | |
| - | |
| - >>> print Template("Templates are pretty useless without placeholders.") | |
| - Templates are useless without placeholders. | |
| - | |
| -.. _TurboCheetah: http://python.org/pypi/TurboCheetah/ | |
| diff --git a/docs/users_guide_2_src/04_howItWorks.txt b/docs/users_guide_2_src/04_howItWorks.txt | |
| deleted file mode 100755 | |
| index 17ee3d5..0000000 | |
| --- a/docs/users_guide_2_src/04_howItWorks.txt | |
| +++ /dev/null | |
| @@ -1,369 +0,0 @@ | |
| -How Cheetah Works | |
| -================= | |
| - | |
| -.. | |
| - :label: howWorks | |
| - | |
| - | |
| - | |
| -Constructing Template Objects | |
| ------------------------------ | |
| - | |
| -.. | |
| - :label: howWorks.templateClass | |
| - | |
| -.. | |
| - :label: howWorks.constructing | |
| - | |
| -The heart of Cheetah is the ``Template`` class in the | |
| -``Cheetah.Template`` module. There are several ways to construct templates, | |
| -each with slightly different arguments. Where *source* is shown, it's always | |
| -the first argument and may be specified positionally. The order of the | |
| -other arguments may change, so always specify them as keyword arguments. | |
| - | |
| -``Template()`` accepts the following arguments: | |
| - | |
| - source | |
| - The template definition as a string. The source can be a string | |
| - literal in your module, or perhaps a string you read from a database | |
| - or other data structure. | |
| - | |
| - 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. | |
| - By convention, template definition files have the extension **.tmpl**. | |
| - | |
| - namespaces, searchList | |
| - A list of objects which Cheetah will search for placeholder values. | |
| - (Cheetah also searches certain other objects automatically; see the | |
| - "Placeholders" chapter for details.) Use either argument; they both | |
| - mean the same thing. | |
| - | |
| - filter | |
| - Equivalent to putting ``#filter`` at the top of the template. The | |
| - argument may be a subclass of ``Cheetah.Filters.Filter``, or a string | |
| - naming a class in filtersLib (the next argument below). See | |
| - ``#filter`` for details. | |
| - | |
| - filtersLib | |
| - A module containing the filters Cheetah should look up by name. The | |
| - default is ``Cheetah.Filters``. All classes in this module that are | |
| - subclasses of ``Cheetah.Filters.Filter`` are considered filters. | |
| - | |
| - errorCatcher | |
| - Equivalent to putting ``#errorCatcher`` at the top of the template. | |
| - The object may be a subclass of ``Cheetah.ErrorCatchers.ErrorCatcher``, | |
| - or a string naming a class in ``Cheetah.ErrorCatchers``. See | |
| - ``#errorCatcher`` for details. | |
| - | |
| - compilerSettings | |
| - Equivalent to putting ``#compiler-settings`` at the top of the | |
| - template. The argument is a dictionary or nesting of dictionaries. | |
| - See ``#compiler-settings`` for details. | |
| - | |
| -A template class returned by ``Cheetah.compile`` or precompiled via "cheetah | |
| -compile" takes the same constructor arguments as above, except "source" and | |
| -"file" which are not allowed. Use keyword arguments for all arguments | |
| -because their order may change. | |
| - | |
| -The class method ``Template.compile()`` takes the following | |
| -arguments: | |
| - | |
| - source, file, compilerSettings | |
| - Same as above. *These are the only arguments most users will ever | |
| - use.* The other args below are for specialized advanced uses. | |
| - | |
| - returnAClass | |
| - If true (default), return a subclass of ``Template`` specific to this | |
| - template definition. If false, return the Python source of a module | |
| - containing this class; i.e., what "cheetah compile" would write to a | |
| - file. | |
| - | |
| - moduleName, className, mainMethodName | |
| - Override the default names. For instance, TurboCheetah (a third-party | |
| - library) requires its templates to have a fixed class name, so it uses | |
| - *className*. | |
| - | |
| - compilerClass | |
| - Use an You'll probably never need this. | |
| - | |
| - baseclass | |
| - Equivalent to putting ``#extends`` at the top of the template. | |
| - ``#extends`` overrides this, unlike other arguments. | |
| - | |
| - moduleGlobals | |
| - In case you want to sneak in some extra variables that don't require | |
| - the NameMapper. | |
| - | |
| - preprocessors | |
| - A list of filter functions which will modify the template definition | |
| - before Cheetah's compiler sees it. See chapter @@MO for details. | |
| - | |
| - compilerClass, cacheCompilationResults, useCache, cacheModuleFilesForTracebacks, cacheDirForModuleFiles, keepRefToGeneratedCode | |
| - You'll probably never need these. They are used to provide an | |
| - alternate compiler, disable Cheetah's template caching (*not* related | |
| - to ``#cache``), or modify Cheetah's enhanced traceback reporting. See | |
| - the ``Template.compile()`` docstring for details. | |
| - | |
| -Here are typical ways to create a template instance: | |
| - | |
| -``t = Template("The king is a \$placeholder1.")`` | |
| - Pass the template definition as a string. | |
| -``t = Template(file="fink.tmpl")`` | |
| - Read the template definition from a file named "fink.tmpl". | |
| -``t = Template(file=f)`` | |
| - Read the template definition from file-like object 'f'. | |
| -``t = Template("The king is a \$placeholder1.", namespaces=[dict, obj])`` | |
| - Pass the template definition as a string. Also pass two namespaces for | |
| - the namespaces: a dictionary 'dict' and an instance 'obj'. | |
| -``t = Template(file="fink.txt", namespaces=[dict, obj])`` | |
| - Same, but pass a filename instead of a string. | |
| -``t = Template(file=f, namespaces=[dict, obj])`` | |
| - Same with a file object. | |
| - | |
| -Filling templates and extracting data | |
| -------------------------------------- | |
| - | |
| -There are several ways to fill a template. Assume ``t`` is a template | |
| -instance:: | |
| - | |
| - 1 output = t.respond() | |
| - 2 output = str(t) # Shortcut for "str(t.respond())". | |
| - 3 output = unicode(t) # Shortcut for "unicode(t.respond())". | |
| - 4 print t # Shortcut for "print str(t.respond())". | |
| - 4 sys.stderr.write( unicode(t).encode('latin1') ) | |
| - 5 result = t.my_def_method(arg1, arg2) | |
| - | |
| -These all assume the template's main method is ``.respond``, which is true | |
| -in the normal case. [#]_ ``str()`` and | |
| -``unicode()`` will always call the main method whatever it's named. | |
| - | |
| -If the output contains non-ASCII characters, examples 2 and 4 will raise | |
| -an exception. Use one of the other examples instead. | |
| - | |
| -Example 5 calls a ``#def`` method with arguments. Only that method's output | |
| -is returned. | |
| - | |
| -If the template contains ``#attr`` attributes, you can access those directly:: | |
| - | |
| - title = t.title | |
| - author = t.author | |
| - | |
| - | |
| -.. [#] See the Inheritance chapter... (#implements, mainMethodName, | |
| - inheritance). | |
| - | |
| -"cheetah compile" and precompiled templates | |
| -------------------------------------------- | |
| - | |
| -.. | |
| - :label: howWorks.cheetah-compile | |
| - | |
| -To create a precompiled template module, do either of these:: | |
| - | |
| - cheetah compile [options] [FILES ...] | |
| - cheetah c [options] [FILES ...] | |
| - | |
| -There are several advantages of precompiled templates: | |
| - | |
| -- Precompiled templates are easier to debug because you can see the generated | |
| - Python code, and the line numbers in error messages will correspond to the | |
| - actual line in the template definition file. (If the template definition is | |
| - embedded in a string literal inside a module, you'll have to count down from | |
| - the first line in the string to find the error line.) | |
| - | |
| -- Data analysis programs can import the template classes and query their | |
| - attributes, which can be set via ``#attr``. Example: a directory of | |
| - templates can each contain ``.title`` and ``.author`` attributes, and | |
| - another program can read them all and make an index page. | |
| - | |
| -- Slightly faster performance since the compilation is done before | |
| - the user runs your application, and Python will optimize this further | |
| - with .pyc or .pyo files. The actual speed difference is minimal -- | |
| - Cheetah appears to compile templates instantaneously anyway, and it caches | |
| - templates in memory if possible, but precompiling templates will make | |
| - some developers feel better for conserving electrons. | |
| - | |
| -- ``#extends`` requires that the base template be precompiled, or the | |
| - child template cannot be instantiated. (@@MO: The *baseclass* constructor | |
| - arg can be used to set the parent class for a dynamically-compiled | |
| - template.) | |
| - | |
| -- Only precompiled templates may be used as Webware servlets. | |
| - | |
| -Some of Cheetah's developers use only precompiled templates and recommend the | |
| -same. However, it's your choice whether to do this. | |
| - | |
| -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) | |
| - --settings : a string representing the compiler settings to use | |
| - e.g. --settings='useNameMapper=False,useFilters=False' | |
| - This string is eval'd in Python so it should contain | |
| - valid Python syntax. | |
| - --templateAPIClass : a string representing a subclass of | |
| - Cheetah.Template:Template to use for compilation | |
| - | |
| -.. tip:: | |
| - If Cheetah can't find your input files, or if it puts output files | |
| - in the wrong place, use the ``--debug`` option to see how Cheetah | |
| - interpreted 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 exact | |
| -file is not found. So the following two examples are the same as above if | |
| -"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 | |
| - | |
| - | |
| -Use the ``-R`` option to recurse subdirectories:: | |
| - | |
| - cheetah compile dir1 : error, file is a directory | |
| - cheetah compile -R dir1 : look under `dir1' for files to compile | |
| - cheetah compile : error, no file specified | |
| - cheetah compile -R : compile all templates under current | |
| - directory and subdirectories | |
| - 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 or it will be | |
| -overwritten! Instead, put it in a separate base class and use | |
| -``#extends`` 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 subdirectories parallel to the input | |
| -file. The ``--flat`` option does this. This may cause several input files | |
| -might map to the same 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. | |
| - | |
| -Chapter @@MO has a look inside a precompiled template module. | |
| - | |
| -"cheetah fill" | |
| --------------- | |
| - | |
| -.. | |
| - :label: howWorks.cheetah-fill | |
| - | |
| -You can fill templates from the command line with "cheetah fill". The most | |
| -common example is static HTML files which are generated from templates. The | |
| -output extension is .html by default. The compiled template modules are not | |
| -written to disk. All the options to "cheetah compile" are allowed. | |
| - | |
| -Examples:: | |
| - | |
| - cheetah fill a.tmpl : writes a.html | |
| - cheetah fill a.tmpl b.tmpl : writes a.html and b.html | |
| - cheetah f --oext txt a : writes a.txt (from a.tmpl) | |
| - | |
| -You can't specify user-defined namespaces the normal way, so the templates must | |
| -be written to have default values for all variables. However, there is limited | |
| -support for gathering placeholder values from operating-system resources:: | |
| - | |
| - --env : make the environment variables a user-defined namespace | |
| - --pickle FILE : unpickle FILE and make that object a user-defined namespace | |
| - | |
| -Using ``--env`` may have security or reliability implications because the | |
| -environment normally contains lots of variables you inherited rather than | |
| -defining yourself. If any of these variables override any of yours (say a | |
| -``#def``), you will get incorrect output, may reveal private information, | |
| -and may get an exception due to the variable being an unexpected type | |
| -(environment variables are always strings). Your calling program may wish | |
| -to clear out the environment before setting environment variables for the | |
| -template. | |
| - | |
| -There are two other differences between "cheetah compile" and "cheetah fill". | |
| -Cheetah doesn't create __init__.py files when creating directories in | |
| -fill mode. Also, the source filenames don't have to be identifiers. This | |
| -allows you to create any .html filename even if it contains characters like "-" | |
| -that are illegal in identifiers. | |
| - | |
| - | |
| -Running a .py template module as a standalone program | |
| ------------------------------------------------------ | |
| - | |
| -.. | |
| - :label: howWorks.standalone | |
| - | |
| -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 ``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 ``NameMapper.NotFound`` exception at | |
| -the first missing value. You can either set default values in the template | |
| -itself (via the ``\#attr`` or ``\#def`` directives) or in a Python | |
| -superclass, or use the ``--env`` or ``--pickle`` command-line options, | |
| -which work just like their "cheetah fill" counterparts. | |
| - | |
| -Run ``python FILENAME.py --help`` to see all the command-line | |
| -options your .py template module accepts. | |
| - | |
| - | |
| - | |
| diff --git a/docs/users_guide_2_src/05_language.txt b/docs/users_guide_2_src/05_language.txt | |
| deleted file mode 100755 | |
| index 673abca..0000000 | |
| --- a/docs/users_guide_2_src/05_language.txt | |
| +++ /dev/null | |
| @@ -1,651 +0,0 @@ | |
| -\section{Language Overview} | |
| -\label{language} | |
| - | |
| -Cheetah's basic syntax was inspired by the Java-based template engines Velocity | |
| -and WebMacro. It has two types of tags: {\bf \$placeholders} and {\bf | |
| -\#directives}. Both types are case-sensitive. | |
| - | |
| -Placeholder tags begin with a dollar sign (\code{\$varName}) and are similar to | |
| -data fields in a form letter or to the \code{\%(key)s} fields on the left side | |
| -of Python's \code{\%} operator. When the template is filled, the placeholders | |
| -are replaced with the values they refer to. | |
| - | |
| -Directive tags begin with a hash character (\#) and are used for comments, | |
| -loops, conditional blocks, includes, and all other advanced features. | |
| -({\em Note:} you can customize the start and end delimeters for placeholder | |
| -and directive tags, but in this Guide we'll assume you're using the default.) | |
| - | |
| -Placeholders and directives can be escaped by putting a backslash before them. | |
| -\verb+\$var+ and \verb+\#if+ will be output as literal text. | |
| - | |
| -A placeholder or directive can span multiple physical lines, following the same | |
| -rules as Python source code: put a backslash (\verb+\+) at the end of all | |
| -lines except the last line. However, if there's an unclosed parenthesis, | |
| -bracket or brace pending, you don't need the backslash. | |
| - | |
| -\begin{verbatim} | |
| -#if $this_is_a_very_long_line and $has_lots_of_conditions \ | |
| - and $more_conditions: | |
| -<H1>bla</H1> | |
| -#end if | |
| - | |
| -#if $country in ('Argentina', 'Uruguay', 'Peru', 'Colombia', | |
| - 'Costa Rica', 'Venezuela', 'Mexico') | |
| -<H1>Hola, senorita!</H1> | |
| -#else | |
| -<H1>Hey, baby!</H1> | |
| -#end if | |
| -\end{verbatim} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Language Constructs -- Summary} | |
| -\label{language.constructs} | |
| - | |
| -\begin{enumerate} | |
| -\item Comments and documentation strings | |
| - \begin{enumerate} | |
| - \item \code{\#\# single line} | |
| - \item \code{\#* multi line *\#} | |
| - \end{enumerate} | |
| - | |
| -\item Generation, caching and filtering of output | |
| - \begin{enumerate} | |
| - \item plain text | |
| - \item look up a value: \code{\$placeholder} | |
| - \item evaluate an expression: \code{\#echo} \ldots | |
| - \item same but discard the output: \code{\#silent} \ldots | |
| - \item one-line if: \code{\#if EXPR then EXPR else EXPR} | |
| - \item gobble the EOL: \code{\#slurp} | |
| - \item parsed file includes: \code{\#include} \ldots | |
| - \item raw file includes: \code{\#include raw} \ldots | |
| - \item verbatim output of Cheetah code: \code{\#raw} \ldots \code{\#end raw} | |
| - \item cached placeholders: \code{\$*var}, \code{\$*<interval>*var} | |
| - \item cached regions: \code{\#cache} \ldots \code{\#end cache} | |
| - \item set the output filter: \code{\#filter} \ldots | |
| - \item control output indentation: \code{\#indent} \ldots ({\em not | |
| -implemented yet}) | |
| - \end{enumerate} | |
| - | |
| -\item Importing Python modules and objects: \code{\#import} \ldots, | |
| - \code{\#from} \ldots | |
| - | |
| -\item Inheritance | |
| - \begin{enumerate} | |
| - \item set the base class to inherit from: \code{\#extends} | |
| - \item set the name of the main method to implement: \code{\#implements} | |
| -\ldots | |
| - \end{enumerate} | |
| - | |
| -\item Compile-time declaration | |
| - \begin{enumerate} | |
| - \item define class attributes: \code{\#attr} \ldots | |
| - \item define class methods: \code{\#def} \ldots \code{\#end def} | |
| - \item \code{\#block} \ldots \code{\#end block} provides a simplified | |
| - interface to \code{\#def} \ldots \code{\#end def} | |
| - \end{enumerate} | |
| - | |
| -\item Run-time assignment | |
| - \begin{enumerate} | |
| - \item local vars: \code{\#set} \ldots | |
| - \item global vars: \code{\#set global} \ldots | |
| - \item deleting local vars: \code{\#del} \ldots | |
| - \end{enumerate} | |
| - | |
| -\item Flow control | |
| - \begin{enumerate} | |
| - \item \code{\#if} \ldots \code{\#else} \ldots \code{\#else if} (aka | |
| - \code{\#elif}) \ldots \code{\#end if} | |
| - \item \code{\#unless} \ldots \code{\#end unless} | |
| - \item \code{\#for} \ldots \code{\#end for} | |
| - \item \code{\#repeat} \ldots \code{\#end repeat} | |
| - \item \code{\#while} \ldots \code{\#end while} | |
| - \item \code{\#break} | |
| - \item \code{\#continue} | |
| - \item \code{\#pass} | |
| - \item \code{\#stop} | |
| - \end{enumerate} | |
| - | |
| -\item error/exception handling | |
| - \begin{enumerate} | |
| - \item \code{\#assert} | |
| - \item \code{\#raise} | |
| - \item \code{\#try} \ldots \code{\#except} \ldots \code{\#else} \ldots | |
| - \code{\#end try} | |
| - \item \code{\#try} \ldots \code{\#finally} \ldots \code{\#end try} | |
| - \item \code{\#errorCatcher} \ldots set a handler for exceptions raised by | |
| -\$placeholder calls. | |
| - \end{enumerate} | |
| - | |
| -\item Instructions to the parser/compiler | |
| - \begin{enumerate} | |
| - \item \code{\#breakpoint} | |
| - \item \code{\#compiler-settings} \ldots \code{\#end compiler-settings} | |
| - \end{enumerate} | |
| - | |
| -\item Escape to pure Python code | |
| - \begin{enumerate} | |
| - \item evalute expression and print the output: \code{<\%=} \ldots | |
| - \code{\%>} | |
| - \item execute code and discard output: \code{<\%} \ldots \code{\%>} | |
| - \end{enumerate} | |
| - | |
| -\item Fine control over Cheetah-generated Python modules | |
| - \begin{enumerate} | |
| - \item set the source code encoding of compiled template modules: \code{\#encoding} | |
| - \item set the sh-bang line of compiled template modules: \code{\#shBang} | |
| - \end{enumerate} | |
| - | |
| -\end{enumerate} | |
| - | |
| -The use of all these constructs will be covered in the next several chapters. | |
| - | |
| -%% @@MO: TODO: reconcile the order of this summary with the order in the | |
| -%% detail sections. | |
| - | |
| -% @@MO: PSP chapter with examples. What does write() do? Print? | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Placeholder Syntax Rules} | |
| -\label{language.placeholders.syntax} | |
| - | |
| -\begin{itemize} | |
| - | |
| -\item Placeholders follow the same syntax rules as Python variables except | |
| - that they are preceded by \code{\$} (the short form) or enclosed in | |
| - \code{\$\{\}} (the long form). | |
| - Examples: | |
| -\begin{verbatim} | |
| -$var | |
| -${var} | |
| -$var2.abc['def']('gh', $subplaceholder, 2) | |
| -${var2.abc['def']('gh', $subplaceholder, 2)} | |
| -\end{verbatim} | |
| - We recommend \code{\$} in simple cases, and \code{\$\{\}} when followed | |
| - directly by a letter or when Cheetah or a human template maintainer might | |
| - get confused about where the placeholder ends. You may alternately use | |
| - \verb+$()+ or \verb+$[]+, although this may confuse the (human) template | |
| - maintainer: | |
| -\begin{verbatim} | |
| -$(var) | |
| -$[var] | |
| -$(var2.abc['def']('gh', $subplaceholder, 2)) | |
| -$[var2.abc['def']('gh', $subplaceholder, 2)] | |
| -\end{verbatim} | |
| - {\em Note:} Advanced users can change the delimiters to anything they | |
| - want via the \code{\#compiler} directive. | |
| - | |
| - {\em Note 2:} The long form can be used only with top-level placeholders, | |
| - not in expressions. See section \ref{language.placeholders.positions} | |
| - for an elaboration on this. | |
| - | |
| -\item To reiterate Python's rules, placeholders consist of one or more | |
| - identifiers separated by periods. Each identifier must start with a letter | |
| - or an underscore, and the subsequent characters must be letters, digits or | |
| - underscores. Any identifier may be followed by arguments enclosed in | |
| - \verb+()+ and/or keys/subscripts in \verb+[]+. | |
| - | |
| -\item Identifiers are case sensitive. \code{\$var} does not equal \code{\$Var} | |
| - or \code{\$vAr} or \code{\$VAR}. | |
| - | |
| -\item Arguments inside \verb+()+ or \verb+[]+ are just like in Python. | |
| - Strings may be quoted using any Python quoting style. Each argument is an | |
| - expression and may use any of Python's expression operators. Variables | |
| - used in argument expressions are placeholders and should be prefixed with | |
| - \code{\$}. This also applies to the *arg and **kw forms. However, you do | |
| - {\em not} need the \code{\$} with the special Python constants \code{None}, | |
| - \code{True} and \code{False}. | |
| - Examples: | |
| -\begin{verbatim} | |
| -$hex($myVar) | |
| -$func($arg=1234) | |
| -$func2($*args, $**kw) | |
| -$func3(3.14159, $arg2, None, True) | |
| -$myList[$mySubscript] | |
| -\end{verbatim} | |
| - | |
| -\item Trailing periods are ignored. Cheetah will recognize that the placeholder | |
| - name in \code{\$varName.} is \code{varName}, and the period will be left | |
| - alone in the template output. | |
| - | |
| -\item The syntax \code{\$\{placeholderName, arg1="val1"\}} passes arguments to | |
| - the output filter (see \code{\#filter}, section \ref{output.filter}. | |
| - The braces and comma are required in this case. It's conventional to | |
| - omit the \code{\$} before the keyword arguments (i.e. \code{arg1}) in this | |
| - case. | |
| - | |
| -\item Cheetah ignores all dollar signs (\code{\$}) that are not followed by a | |
| - letter or an underscore. | |
| - | |
| -\end{itemize} | |
| - | |
| -The following are valid \$placeholders: | |
| -\begin{verbatim} | |
| -$a $_ $var $_var $var1 $_1var $var2_ $dict.key $list[3] | |
| -$object.method $object.method() $object.method | |
| -$nest($nest($var)) | |
| -\end{verbatim} | |
| - | |
| -These are not \$placeholders but are treated as literal text: | |
| -\begin{verbatim} | |
| -$@var $^var $15.50 $$ | |
| -\end{verbatim} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Where can you use placeholders?} | |
| -\label{language.placeholders.positions} | |
| - | |
| -There are three places you can use placeholders: top-level position, | |
| -expression position and LVALUE position. Each has slightly different | |
| -syntax rules. | |
| - | |
| -Top-level position means interspersed in text. This is the only place | |
| -you can use the placeholder long form: \code{\$\{var\}}. | |
| - | |
| -{\em Expression position} means inside a Cheetah expression, which is the same | |
| -as a Python expression. The placeholder names a searchList or other variable | |
| -to be read. Expression position occurs inside () and $[]$ arguments within | |
| -placeholder tags (i.e., a placeholder inside a placeholder), and in several | |
| -directive tags. | |
| - | |
| -{\em LVALUE position} means naming a variable that will be written to. LVALUE | |
| -is a computer science term meaning ``the left side of an assignment | |
| -statement''. The first argument of directives \code{\#set}, \code{\#for}, | |
| -\code{\#def}, \code{\#block} and \code{\#attr} is an LVALUE. | |
| - | |
| -This stupid example shows the three positions. Top-level position is shown | |
| -in \code{courier}, expression position is {\em italic}, and LVALUE position is | |
| -{\bf bold}. | |
| - | |
| -\begin{quote} | |
| -\#for {\bf \$count} in {\em \$range}({\em \$ninetyNine}, 0, -1)\\ | |
| -\#set {\bf \$after} = {\em \$count} - 1\\ | |
| -\code{\$count} bottles of beer on the wall. \code{\$count} bottles of beer!\\ | |
| -~~~~Take one down, pass it around. \code{\$after} bottles of beer on the wall.\\ | |
| -\#end for\\ | |
| -\code{\$hex}({\em \$myVar}, {\bf \$default}={\em None}) | |
| -\end{quote} | |
| - | |
| -The output of course is: | |
| -\begin{verbatim} | |
| -99 bottles of beer on the wall. 99 bottles of beer! | |
| - Take one down, pass it around. 98 bottles of beer on the wall. | |
| -98 bottles of beer on the wall. 98 bottles of beer! | |
| - Take one down, pass it around. 97 bottles of beer on the wall. | |
| -... | |
| -\end{verbatim} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Are all those dollar signs really necessary?} | |
| -\label{language.placeholders.dollar-signs} | |
| - | |
| -\code{\$} is a ``smart variable prefix''. When Cheetah sees \code{\$}, it | |
| -determines both the variable's position and whether it's a searchList value or | |
| -a non-searchList value, and generates the appropriate Python code. | |
| - | |
| -In top-level position, the \code{\$} is {\em required}. Otherwise there's | |
| -nothing to distinguish the variable from ordinary text, and the variable name | |
| -is output verbatim. | |
| - | |
| -In expression position, the \code{\$} is {\em required} if the value comes from | |
| -the searchList or a ``\#set global'' variable, {\em recommended} for | |
| -local/global/builtin variables, and {\em not necessary} for the special | |
| -constants \code{None}, \code{True} and \code{False}. This works because | |
| -Cheetah generates a function call for a searchList placeholder, but a bare | |
| -variable name for a local/global/builtin variable. | |
| - | |
| -In LVALUE position, the \code{\$} is {\em recommended}. Cheetah knows where | |
| -an LVALUE is expected, so it can handle your variable name whether it has | |
| -\code{\$} or not. | |
| - | |
| -EXCEPTION: Do {\em not} use the \code{\$} prefix for intermediate variables in | |
| -a Python list comprehensions. This is a limitation of Cheetah's parser; it | |
| -can't tell which variables in a list comprehension are the intermediate | |
| -variables, so you have to help it. For example: | |
| -\begin{verbatim} | |
| -#set $theRange = [x ** 2 for x in $range(10)] | |
| -\end{verbatim} | |
| -\code{\$theRange} is a regular \code{\#set} variable. \code{\$range} is a | |
| -Python built-in function. But \code{x} is a scratch variable internal to | |
| -the list comprehension: if you type \code{\$x}, Cheetah will miscompile | |
| -it. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{NameMapper Syntax} | |
| -\label{language.namemapper} | |
| - | |
| -One of our core aims for Cheetah was to make it easy for non-programmers to | |
| -use. Therefore, Cheetah uses a simplified syntax for mapping placeholders | |
| -in Cheetah to values in Python. It's known as the {\bf NameMapper syntax} | |
| -and allows for non-programmers to use Cheetah without knowing (a) the | |
| -difference between an instance and a dictionary, (b) what functions and methods | |
| -are, and (c) what 'self' is. A side benefit is that you can change the | |
| -underlying data structure (e.g., instance to dictionary or vice-versa) without | |
| -having to modify the templates. | |
| - | |
| -NameMapper syntax is used for all variables in Cheetah placeholders and | |
| -directives. If desired, it can be turned off via the \code{Template} class' | |
| -\code{'useNameMapper'} compiler setting. But it's doubtful you'd ever want to | |
| -turn it off. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{Example} | |
| -\label{language.namemapper.example} | |
| - | |
| -Consider this scenario: | |
| - | |
| -You are building a customer information system. The designers with you want to | |
| -use information from your system on the client's website --AND-- they want to | |
| -understand the display code and so they can maintian it themselves. | |
| - | |
| -You write a UI class with a 'customers' method that returns a dictionary of all | |
| -the customer objects. Each customer object has an 'address' method that returns | |
| -the a dictionary with information about the customer's address. The designers | |
| -want to be able to access that information. | |
| - | |
| -Using PSP, the display code for the website would look something like the | |
| -following, assuming your servlet subclasses the class you created for managing | |
| -customer information: | |
| - | |
| -\begin{verbatim} | |
| - <%= self.customer()[ID].address()['city'] %> (42 chars) | |
| -\end{verbatim} | |
| - | |
| -With Cheetah's NameMapper syntax, you can use any of the following: | |
| - | |
| -\begin{verbatim} | |
| - $self.customers()[$ID].address()['city'] (39 chars) | |
| - --OR-- | |
| - $customers()[$ID].address()['city'] | |
| - --OR-- | |
| - $customers()[$ID].address().city | |
| - --OR-- | |
| - $customers()[$ID].address.city | |
| - --OR-- | |
| - $customers[$ID].address.city (27 chars) | |
| -\end{verbatim} | |
| - | |
| -Which of these would you prefer to explain to the designers, who have no | |
| -programming experience? The last form is 15 characters shorter than the PSP | |
| -version and -- conceptually -- far more accessible. With PHP or ASP, the | |
| -code would be even messier than with PSP. | |
| - | |
| -This is a rather extreme example and, of course, you could also just implement | |
| -\code{\$getCustomer(\$ID).city} and obey the Law of Demeter (search Google for more | |
| -on that). But good object orientated design isn't the point of this example. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{Dictionary Access} | |
| -\label{language.namemapper.dict} | |
| - | |
| -NameMapper syntax allows access to dictionary items with the same dotted | |
| -notation used to access object attributes in Python. This aspect of NameMapper | |
| -syntax is known as 'Unified Dotted Notation'. | |
| -For example, with Cheetah it is possible to write: | |
| -\begin{verbatim} | |
| - $customers()['kerr'].address() --OR-- $customers().kerr.address() | |
| -\end{verbatim} | |
| -where the second form is in NameMapper syntax. | |
| - | |
| -This works only with dictionary keys that also happen to be valid Python | |
| -identifiers. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{Autocalling} | |
| -\label{language.namemapper.autocalling} | |
| - | |
| -Cheetah automatically detects functions and methods in Cheetah \$variables and | |
| -calls them if the parentheses have been left off. Our previous example can be | |
| -further simplified to: | |
| -\begin{verbatim} | |
| - $customers.kerr.address | |
| -\end{verbatim} | |
| - | |
| -As another example, if 'a' is an object, 'b' is a method | |
| -\begin{verbatim} | |
| - $a.b | |
| -\end{verbatim} | |
| - | |
| -is equivalent to | |
| - | |
| -\begin{verbatim} | |
| - $a.b() | |
| -\end{verbatim} | |
| - | |
| -If b returns a dictionary, then following variations are possible | |
| -\begin{verbatim} | |
| - $a.b.c --OR-- $a.b().c --OR-- $a.b()['c'] | |
| -\end{verbatim} | |
| -where 'c' is a key in the dictionary that a.b() returns. | |
| - | |
| -Further notes: | |
| -\begin{itemize} | |
| -\item When Cheetah autocalls a function/method, it calls it without any | |
| -arguments. Thus, the function/method must have been declared without arguments | |
| -(except \code{self} for methods) or to provide default values for all arguments. | |
| -If the function requires arguments, you must use the \code{()}. | |
| - | |
| -\item Cheetah autocalls only functions and methods. Classes and other callable | |
| -objects are not autocalled. The reason is that the primary purpose of a | |
| -function/method is to call it, whereas the primary purpose of an instance is to | |
| -look up its attributes or call its methods, not to call the instance itself. | |
| -And calling a class may allocate large sums of memory uselessly or have other | |
| -side effects, depending on the class. For instance, consider | |
| -\code{\$myInstance.fname}. Do we want to look up \code{fname} in the namespace | |
| -of \code{myInstance} or in the namespace of whatever \code{myinstance} returns? | |
| -It could go either way, so Cheetah follows the principle of least surprise. If | |
| -you {\em do} want to call the instance, put the \code{()} on, or rename the | |
| -\code{.\_\_call\_\_()} method to \code{.\_\_str\_\_}. | |
| - | |
| -\item Autocalling can be disabled via Cheetah's 'useAutocalling' compiler | |
| -setting. You can also disable it for one placeholder by using the syntax | |
| -\code{\$getVar('varName', 'default value', False)}. (\code{.getVar()} works | |
| -only with searchList values.) | |
| -\end{itemize} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Namespace cascading and the searchList} | |
| -\label{language.searchList} | |
| - | |
| -When Cheetah maps a variable name in a template to a Python value, it searches | |
| -several namespaces in order: | |
| - | |
| -\begin{enumerate} | |
| -\item {\bf Local variables:} created by \code{\#set}, | |
| - \code{\#for}, or predefined by Cheetah. | |
| -\item The {\bf searchList}, consisting of: | |
| - \begin{enumerate} | |
| - \item \code{\#set\ global} variables. | |
| - \item The {\bf searchList} containers you passed to the \code{Template} | |
| - constructor, if any. | |
| - \item The {\bf Template instance} (``self''). This contains any attributes | |
| - you assigned, \code{\#def} methods and \code{\#block methods}, | |
| - attributes/methods inherited via \code{\#extends}, and other | |
| - attributes/methods built into \code{Template} or inherited by it | |
| - (there's a list of all these methods in section | |
| - \ref{tips.allMethods}). | |
| - \end{enumerate} | |
| -\item {\bf Python globals:} created by \code{\#import}, | |
| - \code{\#from\ ...\ import}, or otherwise predefined by Cheetah. | |
| -\item {\bf Python builtins:} \code{None}, \code{max}, etc. | |
| -\end{enumerate} | |
| - | |
| -The first matching name found is used. | |
| - | |
| -Remember, these namespaces apply only to the {\em first} identifier after the | |
| -\code{\$}. In a placeholder like \code{\$a.b}, only `a' is looked up in the | |
| -searchList and other namespaces. `b' is looked up only inside `a'. | |
| - | |
| -A searchList container can be any Python object with attributes or keys: | |
| -dictionaries, instances, classes or modules. If an instance contains both | |
| -attributes and keys, its attributes are searched first, then its keys. | |
| - | |
| -Because the \code{Template} instance is part of the searchList, you can | |
| -access its attributes/methods without `self': \code{\$myAttr}. However, use | |
| -the `self' if you want to make sure you're getting the \code{Template} | |
| -attribute and not a same-name variable defined in a higher namespace: | |
| -\code{\$self.myAttr}. This works because ``self'' itself is a local variable. | |
| - | |
| -The final resulting value, after all lookups and function calls (but before the | |
| -filter is applied) is called the {\em placeholder value}, no matter which | |
| -namespace it was found in. | |
| - | |
| -{\em {\bf Note carefully:}} if you put an object `myObject' in the searchList, | |
| -you {\em cannot} look up \code{\$myObject}! You can look up only the | |
| -attributes/keys {\em inside} `myObject'. | |
| - | |
| -Earlier versions of Cheetah did not allow you to override Python builtin | |
| -names, but this was fixed in Cheetah 0.9.15. | |
| - | |
| -If your template will be used as a Webware servlet, do not override methods | |
| -'name' and 'log' in the \code{Template} instance or it will interfere with | |
| -Webware's logging. However, it {\em is} OK to use those variables in a higher | |
| -namespace, since Webware doesn't know about Cheetah namespaces. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Missing Values} | |
| -\label{language.namemapper.missing} | |
| - | |
| -If NameMapper can not find a Python value for a Cheetah variable name, it will | |
| -raise the NameMapper.NotFound exception. You can use the \code{\#errorCatcher} | |
| -directive (section \ref{errorHandling.errorCatcher}) or {\bf errorCatcher} | |
| -Template constructor argument (section \ref{howWorks.constructing}) to specify | |
| -an alternate behaviour. BUT BE AWARE THAT errorCatcher IS ONLY INTENDED FOR | |
| -DEBUGGING! | |
| - | |
| -To provide a default value for a placeholder, write it like this: | |
| -\code{\$getVar('varName', 'default value')}. If you don't specify a default | |
| -and the variable is missing, \code{NameMapper.NotFound} will be raised. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Directive Syntax Rules} | |
| -\label{language.directives.syntax} | |
| - | |
| - | |
| -Directive tags begin with a hash character (\#) and are used for comments, | |
| -loops, conditional blocks, includes, and all other advanced features. Cheetah | |
| -uses a Python-like syntax inside directive tags and understands any valid | |
| -Python expression. {\bf However, unlike Python, Cheetah does not use colons | |
| -(:) and indentation to mark off multi-line directives.} That doesn't work in | |
| -an environment where whitespace is significant as part of the text. Instead, | |
| -multi-line directives like \code{\#for} have corresponding closing tags | |
| -(\code{\#end for}). Most directives are direct mirrors of Python statements. | |
| - | |
| -Many directives have arguments after the opening tag, which must be in the | |
| -specified syntax for the tag. All end tags have the following syntax: | |
| -\begin{verbatim} | |
| -#end TAG_NAME [EXPR] | |
| -\end{verbatim} | |
| -The expression is ignored, so it's essentially a comment. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{Directive closures and whitespace handling} | |
| -\label{language.directives.closures} | |
| -Directive tags can be closed explicitly with \code{\#}, or implicitly with the | |
| -end of the line if you're feeling lazy. | |
| - | |
| -\begin{verbatim} | |
| -#block testBlock # | |
| -Text in the body of the | |
| -block directive | |
| -#end block testBlock # | |
| -\end{verbatim} | |
| -is identical to: | |
| -\begin{verbatim} | |
| -#block testBlock | |
| -Text in the body of the | |
| -block directive | |
| -#end block testBlock | |
| -\end{verbatim} | |
| - | |
| -When a directive tag is closed explicitly, it can be followed with other text on | |
| -the same line: | |
| - | |
| -\begin{verbatim} | |
| -bah, bah, #if $sheep.color == 'black'# black#end if # sheep. | |
| -\end{verbatim} | |
| - | |
| -When a directive tag is closed implicitly with the end of the line, all trailing | |
| -whitespace is gobbled, including the newline character: | |
| -\begin{verbatim} | |
| -""" | |
| -foo #set $x = 2 | |
| -bar | |
| -""" | |
| -outputs | |
| -""" | |
| -foo bar | |
| -""" | |
| - | |
| -while | |
| -""" | |
| -foo #set $x = 2 # | |
| -bar | |
| -""" | |
| -outputs | |
| -""" | |
| -foo | |
| -bar | |
| -""" | |
| -\end{verbatim} | |
| - | |
| -When a directive tag is closed implicitly AND there is no other text on the | |
| -line, the ENTIRE line is gobbled up including any preceeding whitespace: | |
| -\begin{verbatim} | |
| -""" | |
| -foo | |
| - #set $x = 2 | |
| -bar | |
| -""" | |
| -outputs | |
| -""" | |
| -foo | |
| -bar | |
| -""" | |
| - | |
| -while | |
| -""" | |
| -foo | |
| - - #set $x = 2 | |
| -bar | |
| -""" | |
| -outputs | |
| -""" | |
| -foo | |
| - - bar | |
| -""" | |
| -\end{verbatim} | |
| - | |
| -The \code{\#slurp} directive (section \ref{output.slurp}) also gobbles up | |
| -whitespace. | |
| - | |
| -Spaces outside directives are output {\em exactly} as written. In the | |
| -black sheep example, there's a space before ``black'' and another before | |
| -``sheep''. So although it's legal to put multiple directives on one line, | |
| -it can be hard to read. | |
| - | |
| -\begin{verbatim} | |
| -#if $a# #echo $a + 1# #end if | |
| - - There's a space between each directive, | |
| - or two extra spaces total. | |
| -#if $a##echo $a + 1##end if | |
| - - No spaces, but you have to look closely | |
| - to verify none of the ``##'' are comment markers. | |
| -#if $a##echo $a + 1##end if ### A comment. | |
| - - In ``###'', the first ``#'' ends the directive, | |
| - the other two begin the comment. (This also shows | |
| - how you can add extra whitespace in the directive | |
| - tag without affecting the output.) | |
| -#if $a##echo $a + 1##end if # ## A comment. | |
| - - More readable, but now there's a space before the | |
| - comment. | |
| -\end{verbatim} | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| - | |
| -% # vim: sw=4 ts=4 expandtab | |
| diff --git a/docs/users_guide_2_src/05_placeholders_and_the_namemapper.txt b/docs/users_guide_2_src/05_placeholders_and_the_namemapper.txt | |
| deleted file mode 100644 | |
| index e69de29..0000000 | |
| diff --git a/docs/users_guide_2_src/06_comments.txt b/docs/users_guide_2_src/06_comments.txt | |
| deleted file mode 100755 | |
| index 36323cf..0000000 | |
| --- a/docs/users_guide_2_src/06_comments.txt | |
| +++ /dev/null | |
| @@ -1,99 +0,0 @@ | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\section{Comments} | |
| -\label{comments} | |
| - | |
| -Comments are used to mark notes, explanations, and decorative text that should | |
| -not appear in the output. Cheetah maintains the comments in the Python module | |
| -it generates from the Cheetah source code. There are two forms of the comment | |
| -directive: single-line and multi-line. | |
| - | |
| -All text in a template definition that lies between two hash characters | |
| -(\code{\#\#}) and the end of the line is treated as a single-line comment and | |
| -will not show up in the output, unless the two hash characters are escaped with | |
| -a backslash. | |
| -\begin{verbatim} | |
| -##============================= this is a decorative comment-bar | |
| -$var ## this is an end-of-line comment | |
| -##============================= | |
| -\end{verbatim} | |
| - | |
| -Any text between \code{\#*} and \code{*\#} will be treated as a multi-line | |
| -comment. | |
| -\begin{verbatim} | |
| -#* | |
| - Here is some multiline | |
| - comment text | |
| -*# | |
| -\end{verbatim} | |
| - | |
| -If you put blank lines around method definitions or loops to separate them, | |
| -be aware that the blank lines will be output as is. To avoid this, make sure | |
| -the blank lines are enclosed in a comment. Since you normally have a | |
| -comment before the next method definition (right?), you can just extend that | |
| -comment to include the blank lines after the previous method definition, like | |
| -so: | |
| -\begin{verbatim} | |
| -#def method1 | |
| -... lines ... | |
| -#end def | |
| -#* | |
| - | |
| - | |
| - Description of method2. | |
| - $arg1, string, a phrase. | |
| -*# | |
| -#def method2($arg1) | |
| -... lines ... | |
| -#end def | |
| -\end{verbatim} | |
| - | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Docstring Comments} | |
| -\label{comments.docstring} | |
| - | |
| -Python modules, classes, and methods can be documented with inline | |
| -'documentation strings' (aka 'docstrings'). Docstrings, unlike comments, are | |
| -accesible at run-time. Thus, they provide a useful hook for interactive help | |
| -utilities. | |
| - | |
| -Cheetah comments can be transformed into doctrings by adding one of the | |
| -following prefixes: | |
| - | |
| -\begin{verbatim} | |
| -##doc: This text will be added to the method docstring | |
| -#*doc: If your template file is MyTemplate.tmpl, running "cheetah compile" | |
| - on it will produce MyTemplate.py, with a class MyTemplate in it, | |
| - containing a method .respond(). This text will be in the .respond() | |
| - method's docstring. *# | |
| - | |
| -##doc-method: This text will also be added to .respond()'s docstring | |
| -#*doc-method: This text will also be added to .respond()'s docstring *# | |
| - | |
| -##doc-class: This text will be added to the MyTemplate class docstring | |
| -#*doc-class: This text will be added to the MyTemplate class docstring *# | |
| - | |
| -##doc-module: This text will be added to the module docstring MyTemplate.py | |
| -#*doc-module: This text will be added to the module docstring MyTemplate.py*# | |
| -\end{verbatim} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Header Comments} | |
| -\label{comments.headers} | |
| -Cheetah comments can also be transformed into module header comments using the | |
| -following syntax: | |
| - | |
| -\begin{verbatim} | |
| -##header: This text will be added to the module header comment | |
| -#*header: This text will be added to the module header comment *# | |
| -\end{verbatim} | |
| - | |
| -Note the difference between \code{\#\#doc-module: } and \code{header: }: | |
| -``cheetah-compile'' puts \code{\#\#doc-module: } text inside the module | |
| -docstring. \code{header: } makes the text go {\em above} the docstring, as a | |
| -set of \#-prefixed comment lines. | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| diff --git a/docs/users_guide_2_src/07_output.txt b/docs/users_guide_2_src/07_output.txt | |
| deleted file mode 100755 | |
| index 742291e..0000000 | |
| --- a/docs/users_guide_2_src/07_output.txt | |
| +++ /dev/null | |
| @@ -1,548 +0,0 @@ | |
| -\section{Generating, Caching and Filtering Output} | |
| -\label{output} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Output from complex expressions: \#echo} | |
| -\label{output.echo} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#echo EXPR | |
| -\end{verbatim} | |
| - | |
| -The \code{\#echo} directive is used to echo the output from expressions that | |
| -can't be written as simple \$placeholders. | |
| - | |
| -\begin{verbatim} | |
| -Here is my #echo ', '.join(['silly']*5) # example | |
| -\end{verbatim} | |
| - | |
| -This produces: | |
| - | |
| -\begin{verbatim} | |
| -Here is my silly, silly, silly, silly, silly example. | |
| -\end{verbatim} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Executing expressions without output: \#silent} | |
| -\label{output.silent} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#silent EXPR | |
| -\end{verbatim} | |
| - | |
| -\code{\#silent} is the opposite of \code{\#echo}. It executes an expression | |
| -but discards the output. | |
| - | |
| -\begin{verbatim} | |
| -#silent $myList.reverse() | |
| -#silent $myList.sort() | |
| -Here is #silent $covertOperation() # nothing | |
| -\end{verbatim} | |
| - | |
| -If your template requires some Python code to be executed at the beginning; | |
| -(e.g., to calculate placeholder values, access a database, etc), you can put | |
| -it in a "doEverything" method you inherit, and call this method using | |
| -\code{\#silent} at the top of the template. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{One-line \#if} | |
| -\label{output.oneLineIf} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#if EXPR1 then EXPR2 else EXPR3# | |
| -\end{verbatim} | |
| - | |
| -The \code{\#if} flow-control directive (section \ref{flowControl.if}) has a | |
| -one-line counterpart akin to Perl's and C's \code{?:} operator. | |
| -If \code{EXPR1} is true, it evaluates \code{EXPR2} and outputs the result (just | |
| -like \code{\#echo\ EXPR2\#}). Otherwise it evaluates \code{EXPR3} and outputs | |
| -that result. This directive is short-circuiting, meaning the expression that | |
| -isn't needed isn't evaluated. | |
| - | |
| -You MUST include both 'then' and 'else'. If this doesn't work for you or you | |
| -don't like the style use multi-line \code{\#if} directives (section | |
| -\ref{flowControl.if}). | |
| - | |
| -The trailing \code{\#} is the normal end-of-directive character. As usual | |
| -it may be omitted if there's nothing after the directive on the same line. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Caching Output} | |
| -\label{output.caching} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{Caching individual placeholders} | |
| -\label{output.caching.placeholders} | |
| - | |
| -By default, the values of each \$placeholder is retrieved and | |
| -interpolated for every request. However, it's possible to cache the values | |
| -of individual placeholders if they don't change very often, in order to | |
| -speed up the template filling. | |
| - | |
| -To cache the value of a single \code{\$placeholder}, add an asterisk after the | |
| -\$; e.g., \code{\$*var}. The first time the template is | |
| -filled, \code{\$var} is looked up. Then whenever the template is filled again, | |
| -the cached value is used instead of doing another lookup. | |
| - | |
| -The \code{\$*} format caches ``forever''; that is, as long as the template | |
| -instance remains in memory. It's also possible to cache for a certain time | |
| -period using the form \code{\$*<interval>*variable}, where \code{<interval>} is | |
| -the interval. The time interval can be specified in seconds (5s), minutes | |
| -(15m), hours (3h), days (2d) or weeks (1.5w). The default is minutes. | |
| - | |
| -\begin{verbatim} | |
| -<HTML> | |
| -<HEAD><TITLE>$title</TITLE></HEAD> | |
| -<BODY> | |
| - | |
| -$var ${var} ## dynamic - will be reinterpolated for each request | |
| -$*var2 $*{var2} ## static - will be interpolated only once at start-up | |
| -$*5*var3 $*5*{var3} ## timed refresh - will be updated every five minutes. | |
| - | |
| -</BODY> | |
| -</HTML> | |
| -\end{verbatim} | |
| - | |
| -Note that ``every five minutes'' in the example really means every five | |
| -minutes: the variable is looked up again when the time limit is reached, | |
| -whether the template is being filled that frequently or not. Keep this in | |
| -mind when setting refresh times for CPU-intensive or I/O intensive | |
| -operations. | |
| - | |
| -If you're using the long placeholder syntax, \verb+${}+, the braces go only | |
| -around the placeholder name: \verb+$*.5h*{var.func('arg')}+. | |
| - | |
| -Sometimes it's preferable to explicitly invalidate a cached item whenever | |
| -you say so rather than at certain time intervals. You can't do this with | |
| -individual placeholders, but you can do it with cached regions, which will | |
| -be described next. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{Caching entire regions} | |
| -\label{output.caching.regions} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#cache [id=EXPR] [timer=EXPR] [test=EXPR] | |
| -#end cache | |
| -\end{verbatim} | |
| - | |
| -The \code{\#cache} directive is used to cache a region of | |
| -content in a template. The region is cached as a single unit, after | |
| -placeholders and directives inside the region have been evaluated. If there | |
| -are any \code{\$*<interval>*var} placholders inside the cache | |
| -region, they are refreshed only when {\em both} the cache region {\em and} the | |
| -placeholder are simultaneously due for a refresh. | |
| - | |
| -Caching regions offers more flexibility than caching individual placeholders. | |
| -You can specify the refresh interval using a placeholder or | |
| -expression, or refresh according to other criteria rather than a certain | |
| -time interval. | |
| - | |
| -\code{\#cache} without arguments caches the region statically, the same | |
| -way as \code{\$*var}. The region will not be automatically refreshed. | |
| - | |
| -To refresh the region at an interval, use the \code{timer=EXPRESSION} argument, | |
| -equivalent to \code{\$*<interval>*}. The expression should evaluate to a | |
| -number or string that is a valid interval (e.g., 0.5, '3m', etc). | |
| - | |
| -To refresh whenever an expression is true, use \code{test=EXPRESSION}. | |
| -The expression can be a method/function returning true or false, a boolean | |
| -placeholder, several of these joined by \code{and} and/or \code{or}, or any | |
| -other expression. If the expression contains spaces, it's easier to | |
| -read if you enclose it in \code{()}, but this is not required. | |
| - | |
| -To refresh whenever you say so, use \code{id=EXPRESSION}. Your program can | |
| -then call \code{.refreshCache(ID)} whenever it wishes. This is useful if the | |
| -cache depends on some external condition that changes infrequently but has just | |
| -changed now. | |
| - | |
| -You can combine arguments by separating them with commas. For instance, you can | |
| -specify both \code{id=} and \code{interval=}, or \code{id=} and \code{test=}. | |
| -(You can also combine interval and test although it's not very useful.) | |
| -However, repeating an argument is undefined. | |
| - | |
| -\begin{verbatim} | |
| -#cache | |
| -This is a static cache. It will not be refreshed. | |
| -$a $b $c | |
| -#end cache | |
| - | |
| -#cache timer='30m', id='cache1' | |
| -#for $cust in $customers | |
| -$cust.name: | |
| -$cust.street - $cust.city | |
| -#end for | |
| -#end cache | |
| - | |
| -#cache id='sidebar', test=$isDBUpdated | |
| -... left sidebar HTML ... | |
| -#end cache | |
| - | |
| -#cache id='sidebar2', test=($isDBUpdated or $someOtherCondition) | |
| -... right sidebar HTML ... | |
| -#end cache | |
| -\end{verbatim} | |
| - | |
| - | |
| -The \code{\#cache} directive cannot be nested. | |
| - | |
| -We are planning to add a \code{'varyBy'} keyword argument in the future that | |
| -will allow a separate cache instances to be created for a variety of conditions, | |
| -such as different query string parameters or browser types. This is inspired by | |
| -ASP.net's varyByParam and varyByBrowser output caching keywords. | |
| - | |
| -% @@MO: Can we cache by Webware sessions? What about sessions where the | |
| -% session ID is encoded as a path prefix in the URI? Need examples. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#raw} | |
| -\label{output.raw} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#raw | |
| -#end raw | |
| -\end{verbatim} | |
| - | |
| -Any section of a template definition that is inside a \code{\#raw \ldots | |
| -\#end raw} tag pair will be printed verbatim without any parsing of | |
| -\$placeholders or other directives. This can be very useful for debugging, or | |
| -for Cheetah examples and tutorials. | |
| - | |
| -\code{\#raw} is conceptually similar to HTML's \code{<PRE>} tag and LaTeX's | |
| -\code{\\verbatim\{\}} tag, but unlike those tags, \code{\#raw} does not cause | |
| -the body to appear in a special font or typeface. It can't, because Cheetah | |
| -doesn't know what a font is. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#include} | |
| -\label{output.include} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#include [raw] FILENAME_EXPR | |
| -#include [raw] source=STRING_EXPR | |
| -\end{verbatim} | |
| - | |
| -The \code{\#include} directive is used to include text from outside the | |
| -template definition. The text can come from an external file or from a | |
| -\code{\$placeholder} variable. When working with external files, Cheetah will | |
| -monitor for changes to the included file and update as necessary. | |
| - | |
| -This example demonstrates its use with external files: | |
| -\begin{verbatim} | |
| -#include "includeFileName.txt" | |
| -\end{verbatim} | |
| -The content of "includeFileName.txt" will be parsed for Cheetah syntax. | |
| - | |
| -And this example demonstrates use with \code{\$placeholder} variables: | |
| -\begin{verbatim} | |
| -#include source=$myParseText | |
| -\end{verbatim} | |
| -The value of \code{\$myParseText} will be parsed for Cheetah syntax. This is not | |
| -the same as simply placing the \$placeholder tag ``\code{\$myParseText}'' in | |
| -the template definition. In the latter case, the value of \$myParseText would | |
| -not be parsed. | |
| - | |
| -By default, included text will be parsed for Cheetah tags. The argument | |
| -``\code{raw}'' can be used to suppress the parsing. | |
| - | |
| -\begin{verbatim} | |
| -#include raw "includeFileName.txt" | |
| -#include raw source=$myParseText | |
| -\end{verbatim} | |
| - | |
| -Cheetah wraps each chunk of \code{\#include} text inside a nested | |
| -\code{Template} object. Each nested template has a copy of the main | |
| -template's searchList. However, \code{\#set} variables are visible | |
| -across includes only if the defined using the \code{\#set global} keyword. | |
| - | |
| -All directives must be balanced in the include file. That is, if you start | |
| -a \code{\#for} or \code{\#if} block inside the include, you must end it in | |
| -the same include. (This is unlike PHP, which allows unbalanced constructs | |
| -in include files.) | |
| - | |
| -% @@MO: What did we decide about #include and the searchList? Does it really | |
| -% use a copy of the searchList, or does it share the searchList with the | |
| -% parent? | |
| - | |
| -% @@MO: deleted | |
| -%These nested templates share the same \code{searchList} | |
| -%as the top-level template. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#slurp} | |
| -\label{output.slurp} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#slurp | |
| -\end{verbatim} | |
| - | |
| -The \code{\#slurp} directive eats up the trailing newline on the line it | |
| -appears in, joining the following line onto the current line. | |
| - | |
| - | |
| -It is particularly useful in \code{\#for} loops: | |
| -\begin{verbatim} | |
| -#for $i in range(5) | |
| -$i #slurp | |
| -#end for | |
| -\end{verbatim} | |
| -outputs: | |
| -\begin{verbatim} | |
| -0 1 2 3 4 | |
| -\end{verbatim} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#indent} | |
| -\label{output.indent} | |
| - | |
| -This directive is not implemented yet. When/if it's completed, it will allow | |
| -you to | |
| -\begin{enumerate} | |
| -\item indent your template definition in a natural way (e.g., the bodies | |
| - of \code{\#if} blocks) without affecting the output | |
| -\item add indentation to output lines without encoding it literally in the | |
| - template definition. This will make it easier to use Cheetah to produce | |
| - indented source code programmatically (e.g., Java or Python source code). | |
| -\end{enumerate} | |
| - | |
| -There is some experimental code that recognizes the \code{\#indent} | |
| -directive with options, but the options are purposely undocumented at this | |
| -time. So pretend it doesn't exist. If you have a use for this feature | |
| -and would like to see it implemented sooner rather than later, let us know | |
| -on the mailing list. | |
| - | |
| -The latest specification for the future \code{\#indent} directive is in the | |
| -TODO file in the Cheetah source distribution. | |
| - | |
| -% @@MO: disabled because it's not implemented and the spec is changing | |
| -% \code{\#indent} decouples the indentation in the template definition from the | |
| -% indentation in the output. Normally, Cheetah outputs indentation exactly as | |
| -% it sees it, no matter whether the indentation is on the first line of a | |
| -% paragraph, in front of a directive, or wherever. \code{\#indent} has two main | |
| -% uses: | |
| -% \begin{enumerate} | |
| -% \item To strip all indentation from source lines. This lets you indent | |
| -% multiline directives (e.g., \code{\#if}, \code{\#for}) in a natural way | |
| -% without having that indentation appear in the output. | |
| -% \item To indent every text line in the output according to a user-specified | |
| -% ``indentation level'', independent of whatever indentation the source lines | |
| -% may have. This is useful for producing Python output, or any language that | |
| -% requires strict indentation levels at certain places. To accomplish this, | |
| -% Cheetah adds a call to an indentation method at the beginning of every | |
| -% affected source line. | |
| -% \end{enumerate} | |
| -% | |
| -% To accomplish the first part, Cheetah removes leading whitespace from the | |
| -% affected source lines before the compiler see them. To accomplish the second | |
| -% part, Cheetah keeps track of the current indentation level, a value you have | |
| -% full control over. At the beginning of every affected text line, Cheetah calls | |
| -% a method that outputs the appropriate indentation string. This affects only | |
| -% lines in the template definition itself, not multiline placeholder values. | |
| -% See the \code{Indent} filter below to indent multiline placeholder values. | |
| -% | |
| -% All \code{\#indent} commands operate on the lines physically below them in | |
| -% the template definition until the next \code{\#indent}, regardless of scope. | |
| -% This means they work thorugh all other directives (\code{\#def}, \code{\#for}, | |
| -% \code{\#if}, etc) -- so that if you turn on indentation inside a \code{\#def}, | |
| -% it remains in effect past the \code{\#end def}. | |
| -% | |
| -% The following commands turn indentation on and off: | |
| -% \begin{description} | |
| -% \item{\code{\#indent on}} Strip leading whitespace and add indentation to the | |
| -% following lines. This fulfills use \#2 above. | |
| -% \item{\code{\#indent off}} Do not strip leading whitespace or add indentation. | |
| -% This is Cheetah's default behavior. | |
| -% \item{\code{\#indent strip}} Strip leading whitespace but do {\em not} add | |
| -% indentation. This fulfills use \#1 above. | |
| -% \end{description} | |
| -% | |
| -% Indentation by default uses real tabs. But you can change the indentation | |
| -% string thus: | |
| -% \begin{verbatim} | |
| -% ## Output four spaces for each indentation level. | |
| -% #indent chars ' ' | |
| -% ## Output the mail reply prefix for each indentation level. | |
| -% #indent chars '> ' | |
| -% ## Use a placeholder. | |
| -% #indent chars $indentChars | |
| -% ## Return to the default behavior. | |
| -% #indent chars '\t' | |
| -% \end{verbatim} | |
| -% | |
| -% | |
| -% The following commands change the indentation level, which is a non-negative | |
| -% integer initially at zero. All of these commands implicitly do an | |
| -% \code{\#indent on}: | |
| -% \begin{description} | |
| -% \item{\code{\#indent ++}} Increment the current indentation level. | |
| -% \item{\code{\#indent --}} Decrement the current indentation level. | |
| -% \item{\code{\#indent +3}} Add three indentation levels (or any number). | |
| -% \item{\code{\#indent -3}} Subtract three indentation levels (or any number). | |
| -% \item{\code{\#indent =3}} Set the indentation level to 3. | |
| -% \item{\code{\#indent push +2}} Save the current indentation level on a stack | |
| -% and add two. | |
| -% \item{\code{\#indent pop}} Return to the most recently pushed level. Raise | |
| -% \code{IndentationStackEmptyError} if there is no previous level. | |
| -% \end{description} | |
| -% | |
| -% The expressions after \code{+}/\code{-}/\code{=} may be numeric literals or | |
| -% Cheetah expressions. The effect is undefined if the value is negative. There | |
| -% may be whitespace after the \code{+}/\code{-}/\code{=} symbol. | |
| -% The initial implementation uses a simple preprocessor that doesn't understand | |
| -% newline characters in expressions. \code{\\n} is fine, but not a real newline. | |
| -% | |
| -% To indent multiline placeholder values using the current indentation level, | |
| -% use the \code{Indent} filter: | |
| -% \begin{verbatim} | |
| -% #filter Indent | |
| -% \end{verbatim} | |
| -% It works like the default filter but adds indentation after every newline. It | |
| -% does not strip any leading whitespace. It hooks into \code{\$self.\_indenter}, | |
| -% defined in \code{Cheetah.Utils.Indenter}. This object keeps track of the | |
| -% current indentation level. Specifically, the filter calls | |
| -% \code{\$self.\_indent()}, which is a shortcut to the indenter's | |
| -% \code{.indent()} method. This is the same thing \code{\#indent} does. | |
| -% However, the filter is usable even when indentation is in | |
| -% \code{off} or \code{strip} mode. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Ouput Filtering and \#filter} | |
| -\label{output.filter} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#filter FILTER_CLASS_NAME | |
| -#filter $PLACEHOLDER_TO_A_FILTER_INSTANCE | |
| -#filter None | |
| -\end{verbatim} | |
| - | |
| - | |
| -Output from \$placeholders is passed through an ouput filter. The default | |
| -filter merely returns a string representation of the placeholder value, | |
| -unless the value is \code{None}, in which case the filter returns an empty | |
| -string. Only top-level placeholders invoke the filter; placeholders inside | |
| -expressions do not. | |
| - | |
| -Certain filters take optional arguments to modify their behaviour. To pass | |
| -arguments, use the long placeholder syntax and precede each filter argument by | |
| -a comma. By convention, filter arguments don't take a \code{\$} prefix, to | |
| -avoid clutter in the placeholder tag which already has plenty of dollar signs. | |
| -For instance, the MaxLen filter takes an argument 'maxlen': | |
| - | |
| -\begin{verbatim} | |
| -${placeholderName, maxlen=20} | |
| -${functionCall($functionArg), maxlen=$myMaxLen} | |
| -\end{verbatim} | |
| - | |
| -To change the output filter, use the \code{'filter'} keyword to the | |
| -\code{Template} class constructor, or the \code{\#filter} | |
| -directive at runtime (details below). You may use \code{\#filter} as often as | |
| -you wish to switch between several filters, if certain \code{\$placeholders} | |
| -need one filter and other \code{\$placeholders} need another. | |
| - | |
| -The standard filters are in the module \code{Cheetah.Filters}. Cheetah | |
| -currently provides: | |
| - | |
| -\begin{description} | |
| -\item{\code{Filter}} | |
| - \\ The default filter, which converts None to '' and everything else to | |
| - \code{str(whateverItIs)}. This is the base class for all other filters, | |
| - and the minimum behaviour for all filters distributed with Cheetah. | |
| -\item{\code{ReplaceNone}} | |
| - \\ Same. | |
| -\item{\code{MaxLen}} | |
| - \\ Same, but truncate the value if it's longer than a certain length. | |
| - Use the 'maxlen' filter argument to specify the length, as in the | |
| - examples above. If you don't specify 'maxlen', the value will not be | |
| - truncated. | |
| -\item{\code{Pager}} | |
| - \\ Output a "pageful" of a long string. After the page, output HTML | |
| - hyperlinks to the previous and next pages. This filter uses several | |
| - filter arguments and environmental variables, which have not been | |
| - documented yet. | |
| -\item{\code{WebSafe}} | |
| - \\ Same as default, but convert HTML-sensitive characters ('$<$', '\&', | |
| - '$>$') | |
| - to HTML entities so that the browser will display them literally rather | |
| - than interpreting them as HTML tags. This is useful with database values | |
| - or user input that may contain sensitive characters. But if your values | |
| - contain embedded HTML tags you want to preserve, you do not want this | |
| - filter. | |
| - | |
| - The filter argument 'also' may be used to specify additional characters to | |
| - escape. For instance, say you want to ensure a value displays all on one | |
| - line. Escape all spaces in the value with '\ ', the non-breaking | |
| - space: | |
| -\begin{verbatim} | |
| -${$country, also=' '}} | |
| -\end{verbatim} | |
| -\end{description} | |
| - | |
| -To switch filters using a class object, pass the class using the | |
| -{\bf filter} argument to the Template constructor, or via a placeholder to the | |
| -\code{\#filter} directive: \code{\#filter \$myFilterClass}. The class must be | |
| -a subclass of \code{Cheetah.Filters.Filter}. When passing a class object, the | |
| -value of {\bf filtersLib} does not matter, and it does not matter where the | |
| -class was defined. | |
| - | |
| -To switch filters by name, pass the name of the class as a string using the | |
| -{\bf filter} argument to the Template constructor, or as a bare word (without | |
| -quotes) to the \code{\#filter} directive: \code{\#filter TheFilter}. The | |
| -class will be looked up in the {\bf filtersLib}. | |
| - | |
| -The filtersLib is a module containing filter classes, by default | |
| -\code{Cheetah.Filters}. All classes in the module that are subclasses of | |
| -\code{Cheetah.Filters.Filter} are considered filters. If your filters are in | |
| -another module, pass the module object as the {\bf filtersLib} argument to the | |
| -Template constructor. | |
| - | |
| -Writing a custom filter is easy: just override the \code{.filter} method. | |
| -\begin{verbatim} | |
| - def filter(self, val, **kw): # Returns a string. | |
| -\end{verbatim} | |
| -Return the {\em string} that should be output for `val'. `val' may be any | |
| -type. Most filters return `' for \code{None}. Cheetah passes one keyword | |
| -argument: \verb+kw['rawExpr']+ is the placeholder name as it appears in | |
| -the template definition, including all subscripts and arguments. If you use | |
| -the long placeholder syntax, any options you pass appear as keyword | |
| -arguments. Again, the return value must be a string. | |
| - | |
| -You can always switch back to the default filter this way: | |
| -\code{\#filter None}. This is easy to remember because "no filter" means the | |
| -default filter, and because None happens to be the only object the default | |
| -filter treats specially. | |
| - | |
| -We are considering additional filters; see | |
| -\url{http://webware.colorstudy.net/twiki/bin/view/Cheetah/MoreFilters} | |
| -for the latest ideas. | |
| - | |
| -%% @@MO: Is '#end filter' implemented? Will it be? Can filters nest? | |
| -%% Will '#end filter' and '#filter None' be equivalent? | |
| - | |
| -%% @@MO: Tavis TODO: fix the description of the Pager filter. It needs a howto. | |
| - | |
| -%% @@MO: How about using settings to provide default arguments for filters? | |
| -%% Each filter could look up FilterName (or FilterNameDefaults) setting, | |
| -%% whose value would be a dictionary containing keyword/value pairs. These | |
| -%% would be overridden by same-name keys passed by the placeholder. | |
| - | |
| -%% @@MO: If sed-filters (#sed) get added to Cheetah, give them a section here. | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| - | |
| -% vim: shiftwidth=4 tabstop=4 expandtab | |
| diff --git a/docs/users_guide_2_src/08_inheritanceEtc.txt b/docs/users_guide_2_src/08_inheritanceEtc.txt | |
| deleted file mode 100755 | |
| index 3e76ce2..0000000 | |
| --- a/docs/users_guide_2_src/08_inheritanceEtc.txt | |
| +++ /dev/null | |
| @@ -1,564 +0,0 @@ | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\section{Import, Inheritance, Declaration and Assignment} | |
| -\label{inheritanceEtc} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#import and \#from directives} | |
| -\label{inheritanceEtc.import} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#import MODULE_OR_OBJECT [as NAME] [, ...] | |
| -#from MODULE import MODULE_OR_OBJECT [as NAME] [, ...] | |
| -\end{verbatim} | |
| - | |
| - | |
| -The \code{\#import} and \code{\#from} directives are used to make external | |
| -Python modules or objects available to placeholders. The syntax is identical | |
| -to the import syntax in Python. Imported modules are visible globally to all | |
| -methods in the generated Python class. | |
| - | |
| -\begin{verbatim} | |
| -#import math | |
| -#import math as mathModule | |
| -#from math import sin, cos | |
| -#from math import sin as _sin | |
| -#import random, re | |
| -#from mx import DateTime # ## Part of Egenix's mx package. | |
| -\end{verbatim} | |
| - | |
| -After the above imports, \code{\$math}, \code{\$mathModule}, | |
| -\code{\$sin}, \code{\$cos} and \code{\$\_sin}, \code{\$random}, \code{\$re} | |
| -and \code{\$DateTime} may be used in \code{\$placeholders} and expressions. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#extends} | |
| -\label{inheritanceEtc.extends} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#extends CLASS | |
| -\end{verbatim} | |
| - | |
| - | |
| -All templates are subclasses of \code{Cheetah.Template.Template}. However, | |
| -it's possible for a template to subclass another template or a pure Python | |
| -class. This is where \code{\#extends} steps in: it | |
| -specifies the parent class. It's equivalent to PSP's \code{``@page extends=''} | |
| -directive. | |
| - | |
| -Cheetah imports the class mentioned in an \code{\#extends} directive | |
| -automatically if you haven't imported it yet. The implicit importing works | |
| -like this: | |
| - | |
| -\begin{verbatim} | |
| -#extends Superclass | |
| -## Implicitly does '#from Superclass import Superclass'. | |
| - | |
| -#extends Cheetah.Templates.SkeletonPage | |
| -## Implicitly does '#from Cheetah.Templates.SkeletonPage import SkeletonPage'. | |
| -\end{verbatim} | |
| - | |
| -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 \code{\#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 \code{Template} | |
| -methods such as \code{.\_\_init\_\_} or \code{.awake}, be sure to call | |
| -the superclass method in your method or things will break. Examples of calling | |
| -the superclass method are in section \ref{tips.callingSuperclassMethods}. | |
| -A list of all superclass methods is in section | |
| -\ref{tips.allMethods}. | |
| - | |
| -In all cases, the root superclass must be \code{Template}. If your | |
| -bottommost class is a template, simply omit the \code{\#extends} in it and it | |
| -will automatically inherit from \code{Template}. {\em If your bottommost class | |
| -is a pure Python class, it must inherit from \code{Template} explicitly: } | |
| -\begin{verbatim} | |
| -from Cheetah.Template import Template | |
| -class MyPurePythonClass(Template): | |
| -\end{verbatim} | |
| - | |
| -If you're not keen about having your Python classes inherit from | |
| -\code{Template}, create a tiny glue class that inherits both from your | |
| -class and from \code{Template}. | |
| - | |
| -Before giving any examples we'll stress that Cheetah does {\em 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: | |
| - | |
| -\begin{verbatim} | |
| -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 | |
| -\end{verbatim} | |
| - | |
| -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. | |
| - | |
| -{\em Whenever you use \code{\#extends}, you often need \code{\#implements} | |
| -too,} as in step 2 above. Read the next section to understand what | |
| -\code{\#implements} is and when to use it. | |
| - | |
| -% @@MO: Edmund suggests making some diagrams of inheritance chains. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#implements} | |
| -\label{inheritanceEtc.implements} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#implements METHOD | |
| -\end{verbatim} | |
| - | |
| -You can call any \code{\#def} or \code{\#block} method directly and get its | |
| -outpt. The top-level content -- all the text/placeholders/directives outside any | |
| -\code{\#def}/\code{\#block} -- gets concatenated and wrapped in a ``main | |
| -method'', by default \code{.respond()}. So if you call \code{.respond()}, you | |
| -get the ``whole template output''. When Webware calls \code{.respond()}, | |
| -that's what it's doing. And when you do 'print t' or 'str(t)' on a template | |
| -instance, you're taking advantage of the fact that Cheetah makes | |
| -\code{.\_\_str\_\_()} an alias for the main method. | |
| - | |
| -That's all fine and dandy, but what if your application prefers to call another | |
| -method name rather than \code{.respond()}? What if it wants to call, say, | |
| -\code{.send\_output()} instead? That's where \code{\#implements} steps in. It | |
| -lets you choose the name for the main method. Just put this in your template | |
| -definition: | |
| -\begin{verbatim} | |
| -#implements send_output | |
| -\end{verbatim} | |
| - | |
| -When one template extends another, every template in the inheritance chain | |
| -has its own main method. To fill the template, you invoke exactly one of | |
| -these methods and the others are ignored. The method you call may be in any of | |
| -the templates in the inheritance chain: the base template, the leaf template, | |
| -or any in between, depending on how you structure your application. So you | |
| -have two problems: (1) calling the right method name, and (2) preventing an | |
| -undesired same-name subclass method from overriding the one you want to call. | |
| - | |
| -Cheetah assumes the method you will call is \code{.respond()} because | |
| -that's what Webware calls. It further assumes the desired main method is the | |
| -one in the lowest-level base template, because that works well with | |
| -\code{\#block} as described in the Inheritance Approach for building Webware | |
| -servlets (section \ref{webware.inheritance}), which was originally the | |
| -principal use for Cheetah. So when you use \code{\#extends}, Cheetah changes | |
| -that template's main method to \code{.writeBody()} to get it out of the way and | |
| -prevent it from overriding the base template's \code{.respond()}. | |
| - | |
| -Unfortunately this assumption breaks down if the template is used in other | |
| -ways. For instance, you may want to use the main method in the highest-level | |
| -leaf template, and treat the base template(s) as merely a library of | |
| -methods/attributes. In that case, the leaf template needs \code{\#implements | |
| -respond} to change its main method name back to \code{.respond()} (or whatever | |
| -your application desires to call). Likewise, if your main method is in one of the | |
| -intermediate templates in an inheritance chain, that template needs | |
| -\code{\#implements respond}. | |
| - | |
| -The other way the assumption breaks down is if the main method {\em is} in | |
| -the base template but that template extends a pure Python class. Cheetah sees | |
| -the \code{\#extends} and dutifully but incorrectly renames the method to | |
| -\code{.writeBody()}, so you have to use \code{\#implements respond} to change | |
| -it back. Otherwise the dummy \code{.respond()} in \code{Cheetah.Template} | |
| -is found, which outputs... nothing. {\bf So if you're using \code{\#extends} | |
| -and get no output, the {\em first} thing you should think is, ``Do I need to | |
| -add \code{\#implements respond} somewhere?'' } | |
| - | |
| - | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#set} | |
| -\label{inheritanceEtc.set} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#set [global] $var = EXPR | |
| -\end{verbatim} | |
| - | |
| -\code{\#set} is used to create and update local variables at run time. | |
| -The expression may be any Python expression. | |
| -Remember to preface variable names with \$ unless they're part of an | |
| -intermediate result in a list comprehension. | |
| - | |
| -Here are some examples: | |
| -\begin{verbatim} | |
| -#set $size = $length * 1096 | |
| -#set $buffer = $size + 1096 | |
| -#set $area = $length * $width | |
| -#set $namesList = ['Moe','Larry','Curly'] | |
| -#set $prettyCountry = $country.replace(' ', ' ') | |
| -\end{verbatim} | |
| - | |
| -\code{\#set} variables are useful to assign a short name to a | |
| -\code{\$deeply.nested.value}, to a calculation, or to a printable version of | |
| -a value. The last example above converts any spaces in the 'country' value | |
| -into HTML non-breakable-space entities, to ensure the entire value appears on | |
| -one line in the browser. | |
| - | |
| -\code{\#set} variables are also useful in \code{\#if} expressions, but | |
| -remember that complex logical routines should be coded in Python, not in | |
| -Cheetah! | |
| -\begin{verbatim} | |
| -#if $size > 1500 | |
| - #set $adj = 'large' | |
| -#else | |
| - #set $adj = 'small' | |
| -#end if | |
| -\end{verbatim} | |
| -Or Python's one-line equivalent, "A and B or C". Remember that in this case, | |
| -B must be a true value (not None, '', 0, [] or {}). | |
| -\begin{verbatim} | |
| -#set $adj = $size > 1500 and 'large' or 'small' | |
| -\end{verbatim} | |
| -(Note: Cheetah's one-line \code{\#if} will not work for this, since it | |
| -produces output rather than setting a variable. | |
| - | |
| -You can also use the augmented assignment operators: | |
| -\begin{verbatim} | |
| -## Increment $a by 5. | |
| -#set $a += 5 | |
| -\end{verbatim} | |
| - | |
| -By default, \code{\#set} variables are not visible in method calls or include | |
| -files unless you use the \code{global} attribute: \code{\#set global \$var = | |
| -EXPRESSION}. Global variables are visible in all methods, nested templates and | |
| -included files. Use this feature with care to prevent surprises. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#del} | |
| -\label{inheritanceEtc.del} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#del $var | |
| -\end{verbatim} | |
| - | |
| -\code{\#del} is the opposite of \code{\#set}. It deletes a {\em local} | |
| -variable. Its usage is just like Python's \code{del} statement: | |
| -\begin{verbatim} | |
| -#del $myVar | |
| -#del $myVar, $myArray[5] | |
| -\end{verbatim} | |
| - | |
| -Only local variables can be deleted. There is no directive to delete a | |
| -\code{\#set global} variable, a searchList variable, or any other type of | |
| -variable. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#attr} | |
| -\label{inheritanceEtc.attr} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#attr $var = EXPR | |
| -\end{verbatim} | |
| - | |
| -The \code{\#attr} directive creates class attributes in the generated Python | |
| -class. It should be used to assign simple Python literals such as numbers or | |
| -strings. In particular, the expression must {\em not} depend on searchList | |
| -values or \code{\#set} variables since those are not known at compile time. | |
| - | |
| -\begin{verbatim} | |
| -#attr $title = "Rob Roy" | |
| -#attr $author = "Sir Walter Scott" | |
| -#attr $version = 123.4 | |
| -\end{verbatim} | |
| - | |
| -This template or any child template can output the value thus: | |
| -\begin{verbatim} | |
| -$title, by $author, version $version | |
| -\end{verbatim} | |
| - | |
| -If you have a library of templates derived from etexts | |
| -(\url{http://www.gutenberg.org/}), you can extract the titles and authors | |
| -and put them in a database (assuming the templates have been compiled into | |
| -.py template modules): | |
| - | |
| -%\begin{verbatim} | |
| -%import glob | |
| -% | |
| -%\end{verbatim} | |
| -% | |
| -% @@MO: Finish this example. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#def} | |
| -\label{inheritanceEtc.def} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#def METHOD[(ARGUMENTS)] | |
| -#end def | |
| -\end{verbatim} | |
| - | |
| -Or the one-line variation: | |
| -\begin{verbatim} | |
| -#def METHOD[(ARGUMENTS)] : TEXT_AND_PLACEHOLDERS | |
| -\end{verbatim} | |
| - | |
| - | |
| -The \code{\#def} directive is used to define new methods in the generated | |
| -Python class, or to override superclass methods. It is analogous to Python's | |
| -\code{def} statement. The directive is silent, meaning it does not itself | |
| -produce any output. However, the content of the method will be inserted into | |
| -the output (and the directives executed) whenever the method is later called by | |
| -a \$placeholder. | |
| - | |
| -\begin{verbatim} | |
| -#def myMeth() | |
| -This is the text in my method | |
| -$a $b $c(123) ## these placeholder names have been defined elsewhere | |
| -#end def | |
| - | |
| -## and now use it... | |
| -$myMeth() | |
| -\end{verbatim} | |
| - | |
| -The arglist and parentheses can be omitted: | |
| -\begin{verbatim} | |
| -#def myMeth | |
| -This is the text in my method | |
| -$a $b $c(123) | |
| -#end def | |
| - | |
| -## and now use it... | |
| -$myMeth | |
| -\end{verbatim} | |
| - | |
| -Methods can have arguments and have defaults for those arguments, just like | |
| -in Python. Remember the \code{\$} before variable names: | |
| -\begin{verbatim} | |
| -#def myMeth($a, $b=1234) | |
| -This is the text in my method | |
| -$a - $b | |
| -#end def | |
| - | |
| -## and now use it... | |
| -$myMeth(1) | |
| -\end{verbatim} | |
| - | |
| -The output from this last example will be: | |
| - | |
| -\begin{verbatim} | |
| -This is the text in my method | |
| -1 - 1234 | |
| -\end{verbatim} | |
| - | |
| -There is also a single line version of the \code{\#def} directive. | |
| -{\bf Unlike the multi-line directives, it uses a colon (:) to delimit the method | |
| -signature and body}: | |
| -\begin{verbatim} | |
| -#attr $adj = 'trivial' | |
| -#def myMeth: This is the $adj method | |
| -$myMeth | |
| -\end{verbatim} | |
| -Leading and trailing whitespace is stripped from the method. This is in | |
| -contrast to: | |
| -\begin{verbatim} | |
| -#def myMeth2 | |
| -This is the $adj method | |
| -#end def | |
| -\end{verbatim} | |
| -where the method includes a newline after "method". If you don't want the | |
| -newline, add \code{\#slurp}: | |
| -\begin{verbatim} | |
| -#def myMeth3 | |
| -This is the $adj method#slurp | |
| -#end def | |
| -\end{verbatim} | |
| - | |
| -Because \code{\#def} is handled at compile time, it can appear above or | |
| -below the placeholders that call it. And if a superclass placeholder | |
| -calls a method that's overridden in a subclass, it's the subclass method | |
| -that will be called. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#block ... \#end block} | |
| -\label{inheritanceEtc.block} | |
| - | |
| - | |
| -The \code{\#block} directive allows you to mark a section of your template that | |
| -can be selectively reimplemented in a subclass. It is very useful for | |
| -changing part of a template without having to copy-paste-and-edit | |
| -the entire thing. The output from a template definition that uses blocks will | |
| -be identical to the output from the same template with the \code{\#block \ldots | |
| -\#end block} tags removed. | |
| - | |
| -({\em Note:} don't be confused by the generic word `block'' in this Guide, | |
| -which means a section of code inside {\em any} \code{\#TAG \ldots \#end TAG} | |
| -pair. Thus, an if-block, for-block, def-block, block-block etc. In this | |
| -section we are talking only of block-blocks.) | |
| - | |
| -To reimplement the block, use the \code{\#def} directive. The magical effect | |
| -is that it appears to go back and change the output text {\em at the point the | |
| -original block was defined} rather than at the location of the | |
| -reimplementation. | |
| - | |
| -\begin{verbatim} | |
| -#block testBlock | |
| -Text in the contents | |
| -area of the block directive | |
| -#if $testIt | |
| -$getFoo() | |
| -#end if | |
| -#end block testBlock | |
| -\end{verbatim} | |
| - | |
| -You can repeat the block name in the \code{\#end block} directive or not, as | |
| -you wish. | |
| - | |
| -\code{\#block} directives can be nested to any depth. | |
| - | |
| -\begin{verbatim} | |
| -#block outerBlock | |
| -Outer block contents | |
| - | |
| -#block innerBlock1 | |
| -inner block1 contents | |
| -#end block innerBlock1 | |
| - | |
| -#block innerBlock2 | |
| -inner block2 contents | |
| -#end block innerBlock2 | |
| - | |
| -#end block outerBlock | |
| -\end{verbatim} | |
| - | |
| -Note that the name of the block is optional for the \code{\#end block} tag. | |
| - | |
| -Technically, \code{\#block} directive is equivalent to a \code{\#def} directive | |
| -followed immediately by a \code{\#placeholder} for the same name. In fact, | |
| -that's what Cheetah does. Which means you can use \code{\$theBlockName} | |
| -elsewhere in the template to output the block content again. | |
| - | |
| -There is a one-line \code{\#block} syntax analagous to the one-line | |
| -\code{\#def}. | |
| - | |
| -The block must not require arguments because the implicit placeholder that's | |
| -generated will call the block without arguments. | |
| - | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| - | |
| - | |
| -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:: | |
| - | |
| - #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> | |
| - | |
| -And its subclassed document, Frog1.tmpl:: | |
| - | |
| - #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 | |
| - | |
| - | |
| -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 | |
| -``\$htTitle`` so that by default it's identical to whatever the | |
| -``\$title`` is, but it can also be customized. | |
| - | |
| -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 ``\$body`` and ``\$title``, simply by | |
| -defining body() and title() methods that return a string. (Actually they | |
| -can return anything, but we'll get into that later.) :: | |
| - | |
| - 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 ..." | |
| - | |
| -Similarly, the Cheetah document can inherit from an arbitrary class. That's | |
| -how Cheetah makes templates usable as Webware servlets, by subclassing | |
| -``Servlet``. This technique should be possible for non-Webware systems | |
| -too. | |
| - | |
| -(*Note:*\ ``FrogBase.tmpl`` could be improved by using the | |
| -``\#block`` directive, section \ref{inheritanceEtc.block}.) | |
| - | |
| - | |
| diff --git a/docs/users_guide_2_src/09_flowControl.txt b/docs/users_guide_2_src/09_flowControl.txt | |
| deleted file mode 100755 | |
| index 75a5845..0000000 | |
| --- a/docs/users_guide_2_src/09_flowControl.txt | |
| +++ /dev/null | |
| @@ -1,414 +0,0 @@ | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\section{Flow Control} | |
| -\label{flowControl} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#for ... \#end for} | |
| -\label{flowControl.for} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#for $var in EXPR | |
| -#end for | |
| -\end{verbatim} | |
| - | |
| - | |
| -The \code{\#for} directive iterates through a sequence. The syntax is the same | |
| -as Python, but remember the \code{\$} before variables. | |
| - | |
| -Here's a simple client listing: | |
| -\begin{verbatim} | |
| -<TABLE> | |
| -#for $client in $service.clients | |
| -<TR> | |
| -<TD>$client.surname, $client.firstname</TD> | |
| -<TD><A HREF="mailto:$client.email" >$client.email</A></TD> | |
| -</TR> | |
| -#end for | |
| -</TABLE> | |
| -\end{verbatim} | |
| - | |
| -Here's how to loop through the keys and values of a dictionary: | |
| -\begin{verbatim} | |
| -<PRE> | |
| -#for $key, $value in $dict.items() | |
| -$key: $value | |
| -#end for | |
| -</PRE> | |
| -\end{verbatim} | |
| - | |
| -Here's how to create list of numbers separated by hyphens. This ``\#end for'' | |
| -tag shares the last line to avoid introducing a newline character after each | |
| -hyphen. | |
| -\begin{verbatim} | |
| -#for $i in range(15) | |
| -$i - #end for | |
| -\end{verbatim} | |
| - | |
| -If the location of the \code{\#end for} offends your sense of indentational | |
| -propriety, you can do this instead: | |
| -\begin{verbatim} | |
| -#for $i in $range(15) | |
| -$i - #slurp | |
| -#end for | |
| -\end{verbatim} | |
| - | |
| -The previous two examples will put an extra hyphen after last number. Here's | |
| -how to get around that problem, using the \code{\#set} directive, which will be | |
| -dealt with in more detail below. | |
| -\begin{verbatim} | |
| -#set $sep = '' | |
| -#for $name in $names | |
| -$sep$name | |
| -#set $sep = ', ' | |
| -#end for | |
| -\end{verbatim} | |
| - | |
| -Although to just put a separator between strings, you don't need a for loop: | |
| -\begin{verbatim} | |
| -#echo ', '.join($names) | |
| -\end{verbatim} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#repeat ... \#end repeat} | |
| -\label{flowControl.repeat} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#repeat EXPR | |
| -#end repeat | |
| -\end{verbatim} | |
| - | |
| - | |
| -Do something a certain number of times. | |
| -The argument may be any numeric expression. | |
| -If it's zero or negative, the loop will execute zero times. | |
| -\begin{verbatim} | |
| -#repeat $times + 3 | |
| -She loves me, she loves me not. | |
| -#repeat | |
| -She loves me. | |
| -\end{verbatim} | |
| - | |
| - | |
| -Inside the loop, there's no way to tell which iteration you're on. If you | |
| -need a counter variable, use \code{\#for} instead with Python's \code{range} | |
| -function. Since Python's ranges are base 0 by default, there are two ways | |
| -to start counting at 1. Say we want to count from 1 to 5, and that | |
| -\code{\$count} is 5. | |
| -\begin{verbatim} | |
| -#for $i in $range($count) | |
| -#set $step = $i + 1 | |
| -$step. Counting from 1 to $count. | |
| -#end for | |
| - | |
| - | |
| -#for $i in $range(1, $count + 1) | |
| -$i. Counting from 1 to $count. | |
| -#end for | |
| -\end{verbatim} | |
| - | |
| - | |
| -A previous implementation used a local variable \code{\$i} as the repeat | |
| -counter. However, this prevented instances of \code{\#repeat} from | |
| -being nested. The current implementation does not have this problem as it | |
| -uses a new local variable for every instance of \code{\#repeat}. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#while ... \#end while} | |
| -\label{flowControl.while} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#while EXPR | |
| -#end while | |
| -\end{verbatim} | |
| - | |
| - | |
| -\code{\#while} is the same as Python's \code{while} statement. It may be | |
| -followed by any boolean expression: | |
| -\begin{verbatim} | |
| -#while $someCondition('arg1', $arg2) | |
| -The condition is true. | |
| -#end while | |
| -\end{verbatim} | |
| - | |
| -Be careful not to create an infinite loop. \code{\#while 1} will loop until | |
| -the computer runs out of memory. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#if ... \#else if ... \#else ... \#end if} | |
| -\label{flowControl.if} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#if EXPR | |
| -#else if EXPR | |
| -#elif EXPR | |
| -#else | |
| -#end if | |
| -\end{verbatim} | |
| - | |
| - | |
| -The \code{\#if} directive and its kin are used to display a portion of text | |
| -conditionally. \code{\#if} and \code{\#else if} should be followed by a | |
| -true/false expression, while \code{\#else} should not. Any valid Python | |
| -expression is allowed. As in Python, the expression is true unless it evaluates | |
| -to 0, '', None, an empty list, or an empty dictionary. In deference to Python, | |
| -\code{\#elif} is accepted as a synonym for \code{\#else if}. | |
| - | |
| -Here are some examples: | |
| -\begin{verbatim} | |
| -#if $size >= 1500 | |
| -It's big | |
| -#else if $size < 1500 and $size > 0 | |
| -It's small | |
| -#else | |
| -It's not there | |
| -#end if | |
| -\end{verbatim} | |
| - | |
| -\begin{verbatim} | |
| -#if $testItem($item) | |
| -The item $item.name is OK. | |
| -#end if | |
| -\end{verbatim} | |
| - | |
| -Here's an example that combines an \code{\#if} tag with a \code{\#for} tag. | |
| -\begin{verbatim} | |
| -#if $people | |
| -<table> | |
| -<tr> | |
| -<th>Name</th> | |
| -<th>Address</th> | |
| -<th>Phone</th> | |
| -</tr> | |
| -#for $p in $people | |
| -<tr> | |
| -<td>$p.name</td> | |
| -<td>$p.address</td> | |
| -<td>$p.phone</td> | |
| -</tr> | |
| -#end for | |
| -</table> | |
| -#else | |
| -<p> Sorry, the search did not find any people. </p> | |
| -#end if | |
| -\end{verbatim} | |
| - | |
| -See section \ref{output.oneLineIf} for the one-line \code{\#if} directive, | |
| -which is equivalent to Perl's and C's \code{?:} operator. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#unless ... \#end unless} | |
| -\label{flowControl.unless} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#unless EXPR | |
| -#end unless | |
| -\end{verbatim} | |
| - | |
| - | |
| -\code{\#unless} is the opposite of \code{\#if}: the text is executed if the | |
| -condition is {\bf false}. Sometimes this is more convenient. | |
| -\code{\#unless EXPR} is equivalent to \code{\#if not (EXPR)}. | |
| - | |
| -\begin{verbatim} | |
| -#unless $alive | |
| -This parrot is no more! He has ceased to be! | |
| -'E's expired and gone to meet 'is maker! ... | |
| -THIS IS AN EX-PARROT!! | |
| -#end unless | |
| -\end{verbatim} | |
| - | |
| -You cannot use \code{\#else if} or \code{\#else} inside an \code{\#unless} | |
| -construct. If you need those, use \code{\#if} instead. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#break and \#continue} | |
| -\label{flowControl.break} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#break | |
| -#continue | |
| -\end{verbatim} | |
| - | |
| - | |
| -These directives are used as in Python. \code{\#break} will | |
| -exit a \code{\#for} loop prematurely, while \code{\#continue} will immediately | |
| -jump to the next iteration in the \code{\#for} loop. | |
| - | |
| -In this example the output list will not contain ``10 - ''. | |
| -\begin{verbatim} | |
| -#for $i in range(15) | |
| -#if $i == 10 | |
| - #continue | |
| -#end if | |
| -$i - #slurp | |
| -#end for | |
| -\end{verbatim} | |
| - | |
| -In this example the loop will exit if it finds a name that equals 'Joe': | |
| -\begin{verbatim} | |
| -#for $name in $names | |
| -#if $name == 'Joe' | |
| - #break | |
| -#end if | |
| -$name - #slurp | |
| -#end for | |
| -\end{verbatim} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#pass} | |
| -\label{flowControl.pass} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#pass | |
| -\end{verbatim} | |
| - | |
| - | |
| -The \code{\#pass} directive is identical to Python \code{pass} statement: it | |
| -does nothing. It can be used when a statement is required syntactically but the | |
| -program requires no action. | |
| - | |
| -The following example does nothing if only \$A is true | |
| -\begin{verbatim} | |
| -#if $A and $B | |
| - do something | |
| -#elif $A | |
| - #pass | |
| -#elif $B | |
| - do something | |
| -#else | |
| - do something | |
| -#end if | |
| -\end{verbatim} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#stop} | |
| -\label{flowControl.stop} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#stop | |
| -\end{verbatim} | |
| - | |
| - | |
| -The \code{\#stop} directive is used to stop processing of a template at a | |
| -certain point. The output will show {\em only} what has been processed up to | |
| -that point. | |
| - | |
| -When \code{\#stop} is called inside an \code{\#include} it skips the rest of | |
| -the included code and continues on from after the \code{\#include} directive. | |
| -stop the processing of the included code. Likewise, when \code{\#stop} is | |
| -called inside a \code{\#def} or \code{\#block}, it stops only the \code{\#def} | |
| -or \code{\#block}. | |
| - | |
| -\begin{verbatim} | |
| -A cat | |
| -#if 1 | |
| - sat on a mat | |
| - #stop | |
| - watching a rat | |
| -#end if | |
| -in a flat. | |
| -\end{verbatim} | |
| - | |
| -will print | |
| -\begin{verbatim} | |
| -A cat | |
| - sat on a mat | |
| -\end{verbatim} | |
| - | |
| -And | |
| -\begin{verbatim} | |
| -A cat | |
| -#block action | |
| - sat on a mat | |
| - #stop | |
| - watching a rat | |
| -#end block | |
| -in a flat. | |
| -\end{verbatim} | |
| - | |
| -will print | |
| - | |
| -\begin{verbatim} | |
| -A cat | |
| - sat on a mat | |
| -in a flat. | |
| -\end{verbatim} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#return} | |
| -\label{flowControl.return} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#return | |
| -\end{verbatim} | |
| - | |
| - | |
| -This is used as in Python. \code{\#return} will exit the current method with a | |
| -default return value of \code{None} or the value specified. It may be used | |
| -only inside a \code{\#def} or a \code{\#block}. | |
| - | |
| -Note that \code{\#return} is different from the \code{\#stop} directive, | |
| -which returns the sum of all text output from the method in which it is called. | |
| -The following examples illustrate this point: | |
| - | |
| -\begin{verbatim} | |
| -1 | |
| -$test[1] | |
| -3 | |
| -#def test | |
| -1.5 | |
| -#if 1 | |
| -#return '123' | |
| -#else | |
| -99999 | |
| -#end if | |
| -#end def | |
| -\end{verbatim} | |
| - | |
| -will produce | |
| -\begin{verbatim} | |
| -1 | |
| -2 | |
| -3 | |
| -\end{verbatim} | |
| - | |
| -while | |
| -\begin{verbatim} | |
| -1 | |
| -$test | |
| -3 | |
| -#def test | |
| -1.5 | |
| -#if 1 | |
| -#stop | |
| -#else | |
| -99999 | |
| -#end if | |
| -#end def | |
| -\end{verbatim} | |
| - | |
| -will produce | |
| -\begin{verbatim} | |
| -1 | |
| -1.5 | |
| -3 | |
| -\end{verbatim} | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| diff --git a/docs/users_guide_2_src/10_errorHandling.txt b/docs/users_guide_2_src/10_errorHandling.txt | |
| deleted file mode 100755 | |
| index 28eee3a..0000000 | |
| --- a/docs/users_guide_2_src/10_errorHandling.txt | |
| +++ /dev/null | |
| @@ -1,145 +0,0 @@ | |
| -\section{Error Handling} | |
| -\label{errorHandling} | |
| - | |
| -There are two ways to handle runtime errors (exceptions) in Cheetah. The first | |
| -is with the Cheetah directives that mirror Python's structured exception | |
| -handling statements. The second is with Cheetah's \code{ErrorCatcher} | |
| -framework. These are described below. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#try ... \#except ... \#end try, \#finally, and \#assert} | |
| -\label{errorHandling.directives} | |
| - | |
| -Cheetah's exception-handling directives are exact mirrors Python's | |
| -exception-handling statements. See Python's documentation for details. The | |
| -following Cheetah code demonstrates their use: | |
| - | |
| - | |
| -\begin{verbatim} | |
| -#try | |
| - $mightFail() | |
| -#except | |
| - It failed | |
| -#end try | |
| - | |
| -#try | |
| - #assert $x == $y | |
| -#except AssertionError | |
| - They're not the same! | |
| -#end try | |
| - | |
| -#try | |
| - #raise ValueError | |
| -#except ValueError | |
| - #pass | |
| -#end try | |
| - | |
| - | |
| -#try | |
| - $mightFail() | |
| -#except ValueError | |
| - Hey, it raised a ValueError! | |
| -#except NameMapper.NotFound | |
| - Hey, it raised a NameMapper.NotFound! | |
| -#else | |
| - It didn't raise anything! | |
| -#end try | |
| - | |
| -#try | |
| - $mightFail() | |
| -#finally | |
| - $cleanup() | |
| -#end try | |
| -\end{verbatim} | |
| - | |
| -Like Python, \code{\#except} and \code{\#finally} cannot appear in the same | |
| -try-block, but can appear in nested try-blocks. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#errorCatcher and ErrorCatcher objects} | |
| -\label{errorHandling.errorCatcher} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#errorCatcher CLASS | |
| -#errorCatcher $PLACEHOLDER_TO_AN_ERROR_CATCHER_INSTANCE | |
| -\end{verbatim} | |
| - | |
| - | |
| -\code{ErrorCatcher} is a debugging tool that catches exceptions that occur | |
| -inside \code{\$placeholder} tags and provides a customizable warning to the | |
| -developer. Normally, the first missing namespace value raises a | |
| -\code{NameMapper.NotFound} error and halts the filling of the template. This | |
| -requires the developer to resolve the exceptions in order without seeing the | |
| -subsequent output. When an \code{ErrorCatcher} is enabled, the developer can | |
| -see all the exceptions at once as well as the template output around them. | |
| - | |
| -The \code{Cheetah.ErrorCatchers} module defines the base class for | |
| -ErrorCatchers: | |
| - | |
| -\begin{verbatim} | |
| -class ErrorCatcher: | |
| - _exceptionsToCatch = (NameMapper.NotFound,) | |
| - | |
| - def __init__(self, templateObj): | |
| - pass | |
| - | |
| - def exceptions(self): | |
| - return self._exceptionsToCatch | |
| - | |
| - def warn(self, exc_val, code, rawCode, lineCol): | |
| - return rawCode | |
| -\end{verbatim} | |
| - | |
| -This ErrorCatcher catches \code{NameMapper.NotFound} exceptions and leaves the | |
| -offending placeholder visible in its raw form in the template output. If the | |
| -following template is executed: | |
| -\begin{verbatim} | |
| -#errorCatcher Echo | |
| -#set $iExist = 'Here I am!' | |
| -Here's a good placeholder: $iExist | |
| -Here's bad placeholder: $iDontExist | |
| -\end{verbatim} | |
| - | |
| -the output will be: | |
| -\begin{verbatim} | |
| -Here's a good placeholder: Here I am! | |
| -Here's bad placeholder: $iDontExist | |
| -\end{verbatim} | |
| - | |
| -The base class shown above is also accessible under the alias | |
| -\code{Cheetah.ErrorCatchers.Echo}. \code{Cheetah.ErrorCatchers} also provides a | |
| -number of specialized subclasses that warn about exceptions in different ways. | |
| -\code{Cheetah.ErrorCatchers.BigEcho} will output | |
| - | |
| -\begin{verbatim} | |
| -Here's a good placeholder: Here I am! | |
| -Here's bad placeholder: ===============<$iDontExist could not be found>=============== | |
| -\end{verbatim} | |
| - | |
| -ErrorCatcher has a significant performance impact and is turned off by default. | |
| -It can also be turned on with the \code{Template} class' \code{'errorCatcher'} | |
| -keyword argument. The value of this argument should either be a string | |
| -specifying which of the classes in \code{Cheetah.ErrorCatchers} to use, or a | |
| -class that subclasses \code{Cheetah.ErrorCatchers.ErrorCatcher}. The | |
| -\code{\#errorCatcher} directive can also be used to change the errorCatcher part | |
| -way through a template. | |
| - | |
| -\code{Cheetah.ErrorCatchers.ListErrors} will produce the same ouput as | |
| -\code{Echo} while maintaining a list of the errors that can be retrieved later. | |
| -To retrieve the list, use the \code{Template} class' \code{'errorCatcher'} | |
| -method to retrieve the errorCatcher and then call its \code{listErrors} method. | |
| - | |
| -ErrorCatcher doesn't catch exceptions raised inside directives. | |
| - | |
| -% @@MO: How do you turn ErrorCatcher off after turn it on. | |
| -% '#ErrorCatcher None'? | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| - | |
| - | |
| - | |
| - | |
| diff --git a/docs/users_guide_2_src/11_parserInstructions.txt b/docs/users_guide_2_src/11_parserInstructions.txt | |
| deleted file mode 100755 | |
| index bfd6bc2..0000000 | |
| --- a/docs/users_guide_2_src/11_parserInstructions.txt | |
| +++ /dev/null | |
| @@ -1,116 +0,0 @@ | |
| -\section{Instructions to the Parser/Compiler} | |
| -\label{parserInstructions} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#breakpoint} | |
| -\label{parserInstructions.breakpoint} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#breakpoint | |
| -\end{verbatim} | |
| - | |
| - | |
| -\code{\#breakpoint} is a debugging tool that tells the parser to stop | |
| -parsing at a specific point. All source code from that point on will be ignored. | |
| - | |
| -The difference between \code{\#breakpoint} and \code{\#stop} is that | |
| -\code{\#stop} occurs in normal templates (e.g., inside an \code{\#if}) but | |
| -\code{\#breakpoint} is used only when debugging Cheetah. Another difference is | |
| -that \code{\#breakpoint} operates at compile time, while \code{\#stop} is | |
| -executed at run time while filling the template. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#compiler-settings} | |
| -\label{parserInstructions.compiler-settings} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#compiler-settings | |
| -key = value (no quotes) | |
| -#end compiler-settings | |
| - | |
| -#compiler-settings reset | |
| -\end{verbatim} | |
| - | |
| - | |
| -The \code{\#compiler-settings} directive overrides Cheetah's standard settings, | |
| -changing how it parses source code and generates Python code. This | |
| -makes it possible to change the behaviour of Cheetah's parser/compiler for a | |
| -certain template, or within a portion of the template. | |
| - | |
| -The \code{reset} argument reverts to the default settings. With \code{reset}, | |
| -there's no end tag. | |
| - | |
| -Here are some examples of what you can do: | |
| -\begin{verbatim} | |
| -$myVar | |
| -#compiler-settings | |
| -cheetahVarStartToken = @ | |
| -#end compiler-settings | |
| -@myVar | |
| -#compiler-settings reset | |
| -$myVar | |
| -\end{verbatim} | |
| - | |
| - | |
| -\begin{verbatim} | |
| -## normal comment | |
| -#compiler-settings | |
| -commentStartToken = // | |
| -#end compiler-settings | |
| - | |
| -// new style of comment | |
| - | |
| -#compiler-settings reset | |
| - | |
| -## back to normal comments | |
| -\end{verbatim} | |
| - | |
| -\begin{verbatim} | |
| -#slurp | |
| -#compiler-settings | |
| -directiveStartToken = % | |
| -#end compiler-settings | |
| - | |
| -%slurp | |
| -%compiler-settings reset | |
| - | |
| -#slurp | |
| -\end{verbatim} | |
| - | |
| -Here's a partial list of the settings you can change: | |
| -\begin{enumerate} | |
| -\item syntax settings | |
| - \begin{enumerate} | |
| - \item cheetahVarStartToken | |
| - \item commentStartToken | |
| - \item multilineCommentStartToken | |
| - \item multilineCommentEndToken | |
| - \item directiveStartToken | |
| - \item directiveEndToken | |
| - \end{enumerate} | |
| -\item code generation settings | |
| - \begin{enumerate} | |
| - \item commentOffset | |
| - \item outputRowColComments | |
| - \item defDocStrMsg | |
| - \item useNameMapper | |
| - \item useAutocalling | |
| - \item reprShortStrConstants | |
| - \item reprNewlineThreshold | |
| - \end{enumerate} | |
| -\end{enumerate} | |
| -The meaning of these settings and their default values will be documented in | |
| -the future. | |
| - | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| - | |
| - | |
| - | |
| - | |
| diff --git a/docs/users_guide_2_src/12_moduleFormatting.txt b/docs/users_guide_2_src/12_moduleFormatting.txt | |
| deleted file mode 100644 | |
| index 9c558e3..0000000 | |
| --- a/docs/users_guide_2_src/12_moduleFormatting.txt | |
| +++ /dev/null | |
| @@ -1 +0,0 @@ | |
| -. | |
| diff --git a/docs/users_guide_2_src/13_tipsAndTroubleshooting.txt b/docs/users_guide_2_src/13_tipsAndTroubleshooting.txt | |
| deleted file mode 100755 | |
| index a7b58e5..0000000 | |
| --- a/docs/users_guide_2_src/13_tipsAndTroubleshooting.txt | |
| +++ /dev/null | |
| @@ -1,549 +0,0 @@ | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\section{Tips, Tricks and Troubleshooting} | |
| -\label{tips} | |
| - | |
| -Troubleshooting: make a precomiled template with "cheetah compile" and inspect | |
| -the Python code. Put $_CHEETAH__searchList in the template. (Caveat about | |
| -"<value>" results.) Make a tiny template containing only the suspicious code | |
| -and precompile it. | |
| - | |
| -This chapter contains short stuff that doesn't fit anywhere else. | |
| - | |
| -See the Cheetah FAQ for more specialized issues and for troubleshooting tips. | |
| -Check the wiki periodically for recent tips contributed by users. If you | |
| -get stuck and none of these resources help, ask on the mailing list. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Placeholder Tips} | |
| -\label{tips.placeholder} | |
| - | |
| -Here's how to do certain important lookups that may not be obvious. | |
| -For each, we show first the Cheetah expression and then the Python equivalent, | |
| -because you can use these either in templates or in pure Python subclasses. | |
| -The Cheetah examples use NameMapper shortcuts (uniform dotted notation, | |
| -autocalling) as much as possible. | |
| - | |
| -To verify whether a variable exists in the searchList: | |
| -\begin{verbatim} | |
| -$varExists('theVariable') | |
| -self.varExists('theVariable') | |
| -\end{verbatim} | |
| -This is useful in \code{\#if} or \code{\#unless} constructs to avoid a | |
| -\code{\#NameMapper.NotFound} error if the variable doesn't exist. For instance, | |
| -a CGI GET parameter that is normally supplied but in this case the user typed | |
| -the URL by hand and forgot the parameter (or didn't know about it). | |
| -(\code{.hasVar} is a synonym for \code{.varExists}.) | |
| - | |
| -To look up a variable in the searchList from a Python method: | |
| -\begin{verbatim} | |
| -self.getVar('theVariable') | |
| -self.getVar('theVariable', myDefault) | |
| -\end{verbatim} | |
| -This is the equivalent to \code{\$theVariable} in the template. If the | |
| -variable is missing, it returns the second argument, \code{myDefault}, if | |
| -present, or raises \code{NameMapper.NotFound} if there is no second argument. | |
| -However, it usually easier to write your method so that all needed searchList | |
| -values come in as method arguments. That way the caller can just use a | |
| -\code{\$placeholder} to specify the argument, which is less verbose than you | |
| -writing a getVar call. | |
| - | |
| -To do a ``safe'' placeholder lookup that returns a default value if the | |
| -variable is missing: | |
| -\begin{verbatim} | |
| -$getVar('theVariable', None) | |
| -$getVar('theVariable', $myDefault) | |
| -\end{verbatim} | |
| - | |
| -To get an environmental variable, put \code{os.environ} on the searchList as a | |
| -container. Or read the envvar in Python code and set a placeholder variable | |
| -for it. | |
| - | |
| -Remember that variables found earlier in the searchList override same-name | |
| -variables located in a later searchList object. Be careful when adding objects | |
| -containing other variables besides the ones you want (e.g., \code{os.environ}, | |
| -CGI parameters). The "other" variables may override variables your application | |
| -depends on, leading to hard-to-find bugs. Also, users can inadvertently or | |
| -maliciously set an environmental variable or CGI parameter you didn't expect, | |
| -screwing up your program. To avoid all this, know what your namespaces | |
| -contain, and place the namespaces you have the most control over first. For | |
| -namespaces that could contain user-supplied "other" variables, don't put the | |
| -namespace itself in the searchList; instead, copy the needed variables into | |
| -your own "safe" namespace. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Diagnostic Output} | |
| -\label{tips.diagnostic} | |
| - | |
| -If you need send yourself some debugging output, you can use \code{\#silent} to | |
| -output it to standard error: | |
| -\begin{verbatim} | |
| -#silent $sys.stderr.write("Incorrigible var is '$incorrigible'.\n") | |
| -#silent $sys.stderr.write("Is 'unknown' in the searchList? " + | |
| - $getVar("unknown", "No.") + "\n" ) | |
| -\end{verbatim} | |
| -(Tip contributed by Greg Czajkowski.) | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{When to use Python methods} | |
| -\label{tips.pythonMethods} | |
| - | |
| -You always have a choice whether to code your methods as Cheetah \code{\#def} | |
| -methods or Python methods (the Python methods being located in a class your | |
| -template inherits). So how do you choose? | |
| - | |
| -Generally, if the method consists mostly of text and placeholders, use a | |
| -Cheetah method (a \code{\#def} method). That's why \code{\#def} exists, to | |
| -take the tedium out of writing those kinds of methods. And if you have a | |
| -couple \code{\#if} stanzas to \code{\#set} some variables, followed by a | |
| -\code{\#for} loop, no big deal. But if your method consists mostly of | |
| -directives and only a little text, you're better off writing it in Python. | |
| -Especially be on the watch for extensive use of \code{\#set}, \code{\#echo} and | |
| -\code{\#silent} in a Cheetah method--it's a sure sign you're probably using the | |
| -wrong language. Of course, though, you are free to do so if you wish. | |
| - | |
| -Another thing that's harder to do in Cheetah is adjacent or nested | |
| -multiline stanzas (all those directives with an accompanying \code{\#end} | |
| -directive). Python uses indentation to show the beginning and end of nested | |
| -stanzas, but Cheetah can't do that because any indentation shows up in the | |
| -output, which may not be desired. So unless all those extra spaces and tabs | |
| -in the output are acceptable, you have to keep directives flush with the left | |
| -margin or the preceding text. | |
| - | |
| -The most difficult decisions come when you have conflicting goals. What if | |
| -a method generates its output in parts (i.e., output concatenation), contains | |
| -many searchList placeholders and lots of text, {\em and} requires lots of | |
| -\code{\#if \ldots \#set \ldots \#else \#set \ldots \#end if} stanzas. A Cheetah | |
| -method would be more advantageous in some ways, but a Python method in others. | |
| -You'll just have to choose, perhaps coding groups of methods all the same | |
| -way. Or maybe you can split your method into two, one Cheetah and one Python, | |
| -and have one method call the other. Usually this means the Cheetah method | |
| -calling the Python method to calculate the needed values, then the Cheetah | |
| -method produces the output. One snag you might run into though is that | |
| -\code{\#set} currently can set only one variable per statement, so if your | |
| -Python method needs to return multiple values to your Cheetah method, you'll | |
| -have to do it another way. | |
| - | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Calling superclass methods, and why you have to} | |
| -\label{tips.callingSuperclassMethods} | |
| - | |
| -If your template or pure Python class overrides a standard method or attribute | |
| -of \code{Template} or one of its base classes, you should call the superclass | |
| -method in your method to prevent various things from breaking. The most common | |
| -methods to override are \code{.awake} and \code{.\_\_init\_\_}. \code{.awake} | |
| -is called automatically by Webware early during the web transaction, so it makes | |
| -a convenient place to put Python initialization code your template needs. | |
| -You'll definitely want to call the superclass \code{.awake} because it sets up | |
| -many wonderful attributes and methods, such as those to access the CGI input | |
| -fields. | |
| - | |
| -There's nothing Cheetah-specific to calling superclass methods, but | |
| -because it's vital, we'll recap the standard Python techniques | |
| -here. We mention only the solution for old-style classes because | |
| -Cheetah classes are old-style (in other Python documentation, you will | |
| -find the technique for new-style classes, but they are not listed here | |
| -because they cannot be used with Cheetah if you use | |
| -dynamically-compiled templates). | |
| - | |
| -\begin{verbatim} | |
| -from Cheetah.Template import Template | |
| -class MyClass(Template): | |
| - def awake(self, trans): | |
| - Template.awake(self, trans) | |
| - ... great and exciting features written by me ... | |
| -\end{verbatim} | |
| - | |
| -[ @@MO: Need to test this. .awake is in Servlet, which is a superclass | |
| -of Template. Do we really need both imports? Can we call | |
| -Template.awake? ] | |
| - | |
| -To avoid hardcoding the superclass name, you can use this | |
| -function \code{callbase()}, which emulates \code{super()} for older versions of | |
| -Python. It also works even \code{super()} does exist, so you don't have to | |
| -change your servlets immediately when upgrading. Note that the argument | |
| -sequence is different than \code{super} uses. | |
| - | |
| -\begin{verbatim} | |
| -=========================================================================== | |
| -# Place this in a module SOMEWHERE.py . Contributed by Edmund Lian. | |
| -class CallbaseError(AttributeError): | |
| - pass | |
| - | |
| -def callbase(obj, base, methodname='__init__', args=(), kw={}, | |
| - raiseIfMissing=None): | |
| - try: method = getattr(base, methodname) | |
| - except AttributeError: | |
| - if raiseIfMissing: | |
| - raise CallbaseError, methodname | |
| - return None | |
| - if args is None: args = () | |
| - return method(obj, *args, **kw) | |
| -=========================================================================== | |
| -# Place this in your class that's overriding .awake (or any method). | |
| -from SOMEWHERE import callbase | |
| -class MyMixin: | |
| - def awake(self, trans): | |
| - args = (trans,) | |
| - callbase(self, MyMixin, 'awake', args) | |
| - ... everything else you want to do ... | |
| -=========================================================================== | |
| -\end{verbatim} | |
| - | |
| -% @@MO: Edmund wants us to mention delegation too, as an alternative to | |
| -% inheritance. Contact elian@inbrief.net for details. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{All methods} | |
| -\label{tips.allMethods} | |
| - | |
| -Here is a list of all the standard methods and attributes that can be accessed | |
| -from a placeholder. Some of them exist for you to call, others are mainly used | |
| -by Cheetah internally but you can call them if you wish, and others are only | |
| -for internal use by Cheetah or Webware. Do not use these method names in mixin | |
| -classes (\code{\#extends}, section \ref{inheritanceEtc.extends}) unless you | |
| -intend to override the standard method. | |
| - | |
| -Variables with a star prefix ({\bf *}) are frequently used in templates or in | |
| -pure Python classes. | |
| - | |
| -\paragraph*{Inherited from Cheetah.Template} | |
| - | |
| -\begin{description} | |
| -\item{{\bf compile(source=None, file=None, moduleName=None, | |
| - mainMethodName='respond')}} Compile the template. Automatically called | |
| - by \code{.\_\_init\_\_}. | |
| -\item{{\bf generatedModuleCode()}} Return the module code the compiler | |
| - generated, or \code{None} if no compilation took place. | |
| -\item{{\bf generatedClassCode()}} Return the class code the compiler | |
| - generated, or \code{None} if no compilation took place. | |
| -\item{{\bf * searchList()}} Return a reference to the underlying search list. | |
| - (a list of objects). Use this to print out your searchList for debugging. | |
| - Modifying the returned list will affect your placeholder searches! | |
| -\item{{\bf * errorCatcher()}} Return a reference to the current error | |
| - catcher. | |
| -\item{{\bf * refreshCache(cacheKey=None)}} If 'cacheKey' is not \code{None}, | |
| - refresh that item in the cache. If \code{None}, delete all items in the | |
| - cache so they will be recalculated the next time they are encountered. | |
| -\item{{\bf * shutdown()}} Break reference cycles before discarding a servlet. | |
| -\item{{\bf * getVar(varName, default=NoDefault, autoCall=True)}} Look up a | |
| - variable in the searchList. Same as \code{\$varName} but allows you to | |
| - specify a default value and control whether autocalling occurs. | |
| -\item{{\bf * varExists(varName, autoCall=True)}} | |
| -\item{{\bf * getFileContents(path)}} Read the named file. If used as a | |
| - placeholder, inserts the file's contents in the output without | |
| - interpretation, like \code{\#include\ raw}. If used in an expression, | |
| - returns the file's content (e.g., to assign it to a variable). | |
| -\item{{\bf runAsMainProgram()}} This is what happens if you run a | |
| - .py template module as a standalone program. | |
| -\end{description} | |
| - | |
| -%Private methods: {\bf \_bindCompiledMethod}, {\bf \_bindFunctionAsMethod}, | |
| -%{\bf \_includeCheetahSource}, {\bf \_genTmpFilename}, | |
| -%{\bf \_importAsDummyModule}, {\bf \_makeDummyPackageForDir}, | |
| -%{\bf \_importFromDummyPackage}, {\bf \_importModuleFromDirectory}. | |
| -% | |
| -%Other private attributes: | |
| -%\begin{description} | |
| -%\item{{\bf * \_fileMtime}} Time the template definition was modified, in | |
| -% Unix ticks. \code{None} if the template definition came from a string or | |
| -% file handle rather than a named file, same for the next three variables. | |
| -%\item{{\bf * \_fileDirName}} The directory containing the template definition. | |
| -%\item{{\bf * \_fileBaseName}} The basename of the template definition file. | |
| -%\item{{\bf * \_filePath}} The directory+filename of the template definition. | |
| -%\end{description} | |
| - | |
| -\paragraph*{Inherited from Cheetah.Utils.WebInputMixin} | |
| - | |
| -\begin{description} | |
| -\item{{\bf nonNumericInputError}} Exception raised by \code{.webInput}. | |
| -\item{{\bf * webInput(...)}} Convenience method to access GET/POST variables | |
| - from a Webware servlet or CGI script, or Webware cookie or session | |
| - variables. See section \ref{webware.webInput} for usage information. | |
| -\end{description} | |
| - | |
| -\paragraph*{Inherited from Cheetah.SettingsManager} | |
| - | |
| -\begin{description} | |
| -\item{{\bf setting(name, default=NoDefault)}} Get a compiler setting. | |
| -\item{{\bf hasSetting(name)}} Does this compiler setting exist? | |
| -\item{{\bf setSetting(name, value)}} Set setting 'name' to 'value'. | |
| - See \code{\#compiler-settings}, section | |
| - \ref{parserInstructions.compiler-settings}. | |
| -\item{{\bf settings()}} Return the underlying settings dictionary. (Warning: | |
| - modifying this dictionary will change Cheetah's behavior.) | |
| -\item{{\bf copySettings()}} Return a copy of the underlying settings | |
| - dictionary. | |
| -\item{{\bf deepcopySettings()}} Return a deep copy of the underlying settings | |
| - dictionary. See Python's \code{copy} module. | |
| -\item{{\bf updateSettings(newSettings, merge=True)}} Update Cheetah's | |
| - compiler settings from the 'newSettings' dictionary. If 'merge' is true, | |
| - update only the names in newSettings and leave the other names alone. | |
| - (The SettingsManager is smart enough to update nested dictionaries one | |
| - key at a time rather than overwriting the entire old dictionary.) | |
| - If 'merge' is false, delete all existing settings so that the new ones are | |
| - the only settings. | |
| -\item{{\bf updateSettingsFromPySrcStr(theString, merge=True)}} Same, | |
| - but pass a string of \code{name=value} pairs rather | |
| - than a dictionary, the same as you would provide in a | |
| - \code{\#compiler-settings} directive, section | |
| - \ref{parserInstructions.compiler-settings}. | |
| -\item{{\bf updateSettingsFromPySrcFile(path, merge=True)}} Same, but | |
| - exec a Python source file and use the variables it contains as the new | |
| - settings. (e.g., \code{cheetahVarStartToken\ =\ "@"}). | |
| -\item{{\bf updateSettingsFromConfigFile(path, **kw)}} Same, but get the new | |
| - settings from a text file in ConfigParser format (similar to Windows' | |
| - *.ini file format). See Python's \code{ConfigParser} module. | |
| -\item{{\bf updateSettingsFromConfigFileObj}} Same, but read the open file | |
| - object 'inFile' for the new settings. | |
| -\item{{\bf updateSettingsFromConfigStr(configStr, convert=True, merge=True}} | |
| - Same, but read the new settings from a string in ConfigParser format. | |
| -\item{{\bf writeConfigFile(path)}} Write the current compiler settings to | |
| - a file named 'path' in *.ini format. | |
| -\item{{\bf getConfigString()}} Return a string containing the current | |
| - compiler settings in *.ini format. | |
| -\end{description} | |
| - | |
| -\paragraph*{Inherited from Cheetah.Servlet} | |
| - | |
| -{\em Do not override these in a subclass or assign to them as attributes | |
| -if your template will be used as a servlet,} otherwise Webware will behave | |
| -unpredictably. However, it {\em is} OK to put same-name variables in the | |
| -searchList, because Webware does not use the searchList. | |
| - | |
| -EXCEPTION: It's OK to override {\bf awake} and {\bf sleep} as long as you | |
| -call the superclass methods. (See section | |
| -\ref{tips.callingSuperclassMethods}.) | |
| - | |
| -\begin{description} | |
| -\item{{\bf * isControlledByWebKit}} True if this template instance is | |
| - part of a live transaction in a running WebKit servlet. | |
| -\item{{\bf * isWebwareInstalled}} True if Webware is installed and the | |
| - template instance inherits from WebKit.Servlet. If not, it inherits | |
| - from Cheetah.Servlet.DummyServlet. | |
| -\item{{\bf * awake(transaction)}} Called by WebKit at the beginning of | |
| - the web transaction. | |
| -\item{{\bf * sleep(transaction)}} Called by WebKit at the end of the | |
| - web transaction. | |
| -\item{{\bf * respond(transaction)}} Called by WebKit to produce the | |
| - web transaction content. For a template-servlet, this means | |
| - filling the template. | |
| -\item{{\bf shutdown()}} Break reference cycles before deleting instance. | |
| -\item{{\bf * serverSidePath()}} The filesystem pathname of the | |
| - template-servlet (as opposed to the URL path). | |
| -\item{{\bf transaction}} The current Webware transaction. | |
| -\item{{\bf application}} The current Webware application. | |
| -\item{{\bf response}} The current Webware response. | |
| -\item{{\bf request}} The current Webware request. | |
| -\item{{\bf session}} The current Webware session. | |
| -\item{{\bf write}} Call this method to insert text in the filled template | |
| - output. | |
| -\end{description} | |
| - | |
| -Several other goodies are available to template-servlets under the | |
| -\code{request} attribute, see section \ref{webware.input}. | |
| - | |
| -\code{transaction}, \code{response}, \code{request} and \code{session} are | |
| -created from the current transaction when WebKit calls \code{awake}, and don't | |
| -exist otherwise. Calling \code{awake} yourself (rather than letting WebKit | |
| -call it) will raise an exception because the \code{transaction} argument won't | |
| -have the right attributes. | |
| - | |
| -\paragraph*{Inherited from WebKit.Servlet} | |
| -These are accessible only if Cheetah knows Webware is installed. This | |
| -listing is based on a CVS snapshot of Webware dated 22 September 2002, and | |
| -may not include more recent changes. | |
| - | |
| -The same caveats about overriding these methods apply. | |
| - | |
| -\begin{description} | |
| -\item{name()} The simple name of the class. Used by Webware's logging and | |
| - debugging routines. | |
| -\item{log()} Used by Webware's logging and debugging routines. | |
| -\item{canBeThreaded()} True if the servlet can be multithreaded. | |
| -\item{canBeReused()} True if the servlet can be used for another transaction | |
| - after the current transaction is finished. | |
| -\item{serverSideDir()} Depreciated by \code{.serverSidePath()}. | |
| -\end{description} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Optimizing templates} | |
| -\label{tips.optimizing} | |
| - | |
| -Here are some things you can do to make your templates fill faster and user | |
| -fewer CPU cycles. Before you put a lot of energy into this, however, make | |
| -sure you really need to. In many situations, templates appear to initialize | |
| -and fill instantaneously, so no optimization is necessary. If you do find a | |
| -situation where your templates are filling slowly or taking too much memory or | |
| -too many CPU cycles, we'd like to hear about it on the mailing list. | |
| - | |
| -Cache \$placeholders whose values don't change frequently. (Section | |
| -\ref{output.caching}). | |
| - | |
| -Use \code{\#set} for values that are very frequently used, especially if they | |
| -come out of an expensive operation like a deeply.nested.structure or a database | |
| -lookup. \code{\#set} variables are set to Python local variables, which have a | |
| -faster lookup time than Python globals or values from Cheetah's searchList. | |
| - | |
| -Moving variable lookups into Python code may provide a speedup in certain | |
| -circumstances. If you're just reading \code{self} attributes, there's no | |
| -reason to use NameMapper lookup (\$placeholders) for them. NameMapper does | |
| -a lot more work than simply looking up a \code{self} attribute. | |
| - | |
| -On the other hand, if you don't know exactly where the value will come from | |
| -(maybe from \code{self}, maybe from the searchList, maybe from a CGI input | |
| -variable, etc), it's easier to just make that an argument to your method, and | |
| -then the template can handle all the NameMapper lookups for you: | |
| -\begin{verbatim} | |
| -#silent $myMethod($arg1, $arg2, $arg3) | |
| -\end{verbatim} | |
| -Otherwise you'd have to call \code{self.getVar('arg1')} etc in your | |
| -method, which is more wordy, and tedious. | |
| - | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{PSP-style tags} | |
| -\label{tips.PSP} | |
| - | |
| -\code{<\%= \ldots \%>} and \code{<\% \ldots \%>} allow an escape | |
| -to Python syntax inside the template. You do not need it to use Cheetah | |
| -effectively, and we're hard pressed to think of a case to recommend it. | |
| -Nevertheless, it's there in case you encounter a situation you can't | |
| -express adequately in Cheetah syntax. For instance, to set a local | |
| -variable to an elaborate initializer. | |
| - | |
| -\code{<\%= \ldots \%>} encloses a Python expression whose result will | |
| -be printed in the output. | |
| - | |
| -\code{<\% \ldots \%>} encloses a Python statement or expression (or set of | |
| -statements or expressions) that will be included as-is into the generated | |
| -method. The statements themselves won't produce any output, but you can use | |
| -the local function \code{write(EXPRESSION)} to produce your own output. | |
| -(Actually, it's a method of a file-like object, but it looks like a local | |
| -function.) This syntax also may be used to set a local variable with a | |
| -complicated initializer. | |
| - | |
| -To access Cheetah services, you must use Python code like you would in an | |
| -inherited Python class. For instance, use \code{self.getVar()} to look up | |
| -something in the searchList. | |
| - | |
| -{\em Warning:} {\bf No error checking is done!} If you write: | |
| -\begin{verbatim} | |
| -<% break %> ## Wrong! | |
| -\end{verbatim} | |
| -you'll get a \code{SyntaxError} when you fill the template, but that's what you | |
| -deserve. | |
| - | |
| -Note that these are PSP-{\em style} tags, not PSP tags. A Cheetah template | |
| -is not a PSP document, and you can't use PSP commands in it. | |
| - | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Makefiles} | |
| -\label{tips.Makefile} | |
| - | |
| -If your project has several templates and you get sick of typing | |
| -``cheetah compile FILENAME.tmpl'' all the time--much less remembering which | |
| -commands to type when--and your system has the \code{make} | |
| -command available, consider building a Makefile to make your life easier. | |
| - | |
| -Here's a simple Makefile that controls two templates, ErrorsTemplate and | |
| -InquiryTemplate. Two external commands, \code{inquiry} and \code{receive}, | |
| -depend on ErrorsTemplate.py. Aditionally, InquiryTemplate | |
| -itself depends on ErrorsTemplate. | |
| - | |
| -\begin{verbatim} | |
| -all: inquiry receive | |
| - | |
| -.PHONY: all receive inquiry printsource | |
| - | |
| -printsource: | |
| - a2ps InquiryTemplate.tmpl ErrorsTemplate.tmpl | |
| - | |
| -ErrorsTemplate.py: ErrorsTemplate.tmpl | |
| - cheetah compile ErrorsTemplate.tmpl | |
| - | |
| -InquiryTemplate.py: InquiryTemplate.tmpl ErrorsTemplate.py | |
| - cheetah compile InquiryTemplate.tmpl | |
| - | |
| -inquiry: InquiryTemplate.py ErrorsTemplate.py | |
| - | |
| -receive: ErrorsTemplate.py | |
| -\end{verbatim} | |
| - | |
| -Now you can type \code{make} anytime and it will recompile all the templates | |
| -that have changed, while ignoring the ones that haven't. Or you can | |
| -recompile all the templates \code{receive} needs by typing \code{make receive}. | |
| -Or you can recompile only ErrorsTemplate by typing | |
| -\code{make ErrorsTemplate}. There's also another target, ``printsource'': | |
| -this sends a Postscript version of the project's source files to the printer. | |
| -The .PHONY target is explained in the \code{make} documentation; essentially, | |
| -you have it depend on every target that doesn't produce an output file with | |
| -the same name as the target. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Using Cheetah in a Multi-Threaded Application} | |
| -\label{tips.threads} | |
| - | |
| -Template classes may be shared freely between threads. However, template | |
| -instances should not be shared unless you either: | |
| -\begin{itemize} | |
| -\item Use a lock (mutex) to serialize template fills, to prevent two threads | |
| -from filling the template at the same time. | |
| -\item Avoid thread-unsafe features: | |
| - \begin{itemize} | |
| - \item Modifying searchList values or instance variables. | |
| - \item Caching (\code{\$*var}, \code{\#cache}, etc). | |
| - \item \code{\#set global}, \code{\#filter}, \code{\#errorCatcher}. | |
| - \end{itemize} | |
| - Any changes to these in one thread will be visible in other threads, | |
| - causing them to give inconsistent output. | |
| -\end{itemize} | |
| - | |
| -About the only advantage in sharing a template instance is building up the | |
| -placeholder cache. But template instances are so low overhead that it | |
| -probably wouldn't take perceptibly longer to let each thread instantiate its | |
| -own template instance. Only if you're filling templates several times a | |
| -second would the time difference be significant, or if some of the placeholders | |
| -trigger extremely slow calculations (e.g., parsing a long text file each time). | |
| -The biggest overhead in Cheetah is importing the \code{Template} module in | |
| -the first place, but that has to be done only once in a long-running | |
| -application. | |
| - | |
| -You can use Python's \code{mutex} module for the lock, or any similar | |
| -mutex. If you have to change searchList values or instance variables | |
| -before each fill (which is usually the case), lock the mutex before | |
| -doing this, and unlock it only after the fill is complete. | |
| - | |
| -For Webware servlets, you're probably better off using Webware's servlet | |
| -caching rather than Cheetah's caching. Don't override the servlet's | |
| -\code{.canBeThreaded()} method unless you avoid the unsafe operations | |
| -listed above. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Using Cheetah with gettext} | |
| -\label{tips.gettext} | |
| - | |
| -{\bf gettext} is a project for creating internationalized applications. For | |
| -more details, visit \url{http://docs.python.org/lib/module-gettext.html}. | |
| -gettext can be used with Cheetah to create internationalized applications, even | |
| -for CJK character sets, but you must keep a couple things in mind: | |
| -\begin{itemize} | |
| -\item xgettext is used on compiled templates, not on the templates themselves. | |
| -\item The way the NameMapper syntax gets compiled to Python gets in the way of | |
| -the syntax that xgettext recognizes. Hence, a special case exists for the | |
| -functions \code{_}, \code{N_}, and \code{ngettext}. If you need to use a | |
| -different set of functions for marking strings for translation, you must set | |
| -the Cheetah setting \code{gettextTokens} to a list of strings representing the | |
| -names of the functions you are using to mark strings for translation. | |
| -\end{itemize} | |
| - | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| diff --git a/docs/users_guide_2_src/13a_precompiledTemplateModules.txt b/docs/users_guide_2_src/13a_precompiledTemplateModules.txt | |
| deleted file mode 100644 | |
| index 5b0f978..0000000 | |
| --- a/docs/users_guide_2_src/13a_precompiledTemplateModules.txt | |
| +++ /dev/null | |
| @@ -1,109 +0,0 @@ | |
| -A look inside precompiled template modules | |
| -========================================== | |
| - | |
| -.. | |
| - :label: howWorks.pyTrivia | |
| - | |
| -When debugging a template, it's useful to compile it with "cheetah compile" | |
| -and then inspect the resulting Python module. This will often clear up whether | |
| -Cheetah misinterpreted your intent. You can do this even if you don't intend to | |
| -use the precompiled templates in production. It's also a good way to learn how | |
| -Cheetah works. Simply make a throwaway template definition containing only one | |
| -placeholder or directive, compile it with "cheetah compile", and see what | |
| -Python code Cheetah generated. | |
| - | |
| -However, precompiled template modules can be a bit cryptic to read unless you | |
| -have a bit of background information. Let's look at an example. Put the | |
| -following into /tmp/x.tmpl (or any other file) and run "cheetah compile" on | |
| -it:: | |
| - | |
| - The number is $Test.unittest.main. | |
| - #set mood = "lucky" | |
| - I'm feeling $lucky. | |
| - | |
| -Open the resulting /tmp/x.py in your favorite text editor. You'll see a class | |
| -with the same name as the module:: | |
| - | |
| - class x(Template): | |
| - | |
| -This template class contains a method ``.respond()``:: | |
| - | |
| - def respond(self, trans=None): | |
| - ## CHEETAH: main method generated for this template | |
| - if (not trans and not self._CHEETAH__isBuffering and | |
| - not callable(self.transaction)): | |
| - trans = self.transaction # is None unless self.awake() was called | |
| - if not trans: | |
| - trans = DummyTransaction() | |
| - _dummyTrans = True | |
| - else: _dummyTrans = False | |
| - write = trans.response().write | |
| - SL = self._CHEETAH__searchList | |
| - _filter = self._CHEETAH__currentFilter | |
| - | |
| - ######################################## | |
| - ## START - generated method body | |
| - | |
| - | |
| - write('The number is ') | |
| - _v = VFFSL(SL,"Test.unittest.main",True) | |
| - # '$Test.unittest.main' on line 1, col 15 | |
| - if _v is not None: write(_filter(_v, rawExpr='$Test.unittest.main')) | |
| - # from line 1, col 15. | |
| - write('.\n') | |
| - mood = "lucky" | |
| - write("I'm feeling ") | |
| - _v = VFFSL(SL,"lucky",True) # '$lucky' on line 3, col 13 | |
| - if _v is not None: write(_filter(_v, rawExpr='$lucky')) | |
| - # from line 3, col 13. | |
| - write('.\n') | |
| - | |
| - ######################################## | |
| - ## END - generated method body | |
| - | |
| - return _dummyTrans and trans.response().getvalue() or "" | |
| - | |
| -This becomes clearer when we scroll up to see some important imports and | |
| -global variables:: | |
| - | |
| - from Cheetah.Template import Template | |
| - from Cheetah.DummyTransaction import DummyTransaction | |
| - from Cheetah.NameMapper import NotFound, valueFromFrameOrSearchList | |
| - VFFSL=valueFromFrameOrSearchList | |
| - __CHEETAH_version__ = '2.0rc6' | |
| - __CHEETAH_src__ = 'x.tmpl' | |
| - | |
| -The actual code will differ slightly depending on your Cheetah version. Also, | |
| -we've split some long lines to make this page printer-friendly. | |
| - | |
| -Placeholder lookup is handled by ``VFFSL``, which is really the | |
| -``Cheetah.NameMapper.valueFromFrameOrSearchList`` function or its equivalent | |
| -in Cheetah/_namemapper.c. | |
| - | |
| -``trans`` and ``write()`` are Webware compatibility features. Normally | |
| -``trans`` is not specified and Cheetah creates a ``DummyTransaction`` | |
| -instance. ``write()`` is a shortcut for ``trans.response().write()``, | |
| -which concatenates the output to an internal buffer. The method returns | |
| -the result: ``trans.response().getvalue()``. You might assume from | |
| -``.getvalue()`` that Cheetah uses ``StringIO`` internally, but you'd be wrong. | |
| -Cheetah *used* to use ``StringIO`` but now it uses a list and ``str.join()``. | |
| -The ``.getvalue()`` name is retained for backward compatibility. | |
| - | |
| -If this template is part of a Webware site and the user enters its URL, Webware | |
| -calls ``.respond()`` with a live Webware transaction. In this case, | |
| -``write()`` writes the output directly to Webware's output stream. (Or to | |
| -a Webware buffer, but that's not our concern.) There's nothing to return | |
| -because the output has already been written, so the method returns the empty | |
| -string. That way if it accidentally gets concatenated to the output, no harm | |
| -will be done. | |
| - | |
| -You can write your own transaction class to support non-Webware output | |
| -streaming, but Cheetah currently comes with no examples of this. Ask on | |
| -the mailing list if you need help with it. | |
| - | |
| -Global variables and class attributes defined by Cheetah have a | |
| -``_CHEETAH_`` prefix. Instance attributes defined by Cheetah have a | |
| -``__CHEETAH__`` prefix (two trailing underscores). You should normally | |
| -never write to these but you can read them if desired; many are | |
| -self-explanatory. One such attribute is ``._CHEETAH__searchList``. This | |
| -is the actual search List ``VFFSL()`` will consult for placeholder lookups. | |
| diff --git a/docs/users_guide_2_src/14_webware.txt b/docs/users_guide_2_src/14_webware.txt | |
| deleted file mode 100755 | |
| index 8c47e90..0000000 | |
| --- a/docs/users_guide_2_src/14_webware.txt | |
| +++ /dev/null | |
| @@ -1,582 +0,0 @@ | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\section{Using Cheetah with Webware} | |
| -\label{webware} | |
| - | |
| -{\bf Webware for Python} is a 'Python-Powered Internet Platform' that runs | |
| -servlets in a manner similar to Java servlets. {\bf WebKit} is the name of | |
| -Webware's application server. For more details, please visit | |
| -\url{http://webware.sourceforge.net/}. | |
| - | |
| -All comments below refer to the official version of Webware, the DamnSimple! | |
| -offshoot at ?, and the now-abandoned WebwareExperimental implementation at | |
| -\url{http://sourceforge.net/projects/expwebware/}, except where noted. All the | |
| -implementations are 95\% identical to the servlet writer: their differences lie | |
| -in their internal structure and configuration files. One difference is that | |
| -the executable you run to launch standard Webware is called \code{AppServer}, | |
| -whereas in WebwareExperimental it's called \code{webkit}. But to servlets | |
| -they're both "WebKit, Webware's application server", so it's one half dozen to | |
| -the other. In this document, we generally use the term {\bf WebKit} to refer | |
| -to the currently-running application server. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Installing Cheetah on a Webware system} | |
| -\label{webware.installing} | |
| - | |
| -Install Cheetah after you have installed Webware, following the instructions in | |
| -chapter \ref{gettingStarted}. | |
| - | |
| -The standard Cheetah test suite ('cheetah test') does not test Webware features. | |
| -We plan to build a test suite that can run as a Webware servlet, containing | |
| -Webware-specific tests, but that has not been built yet. In the meantime, you | |
| -can make a simple template containing something like "This is a very small | |
| -template.", compile it, put the *.py template module in a servlet | |
| -directory, and see if Webware serves it up OK. | |
| - | |
| -{\em You must not have a Webware context called "Cheetah".} If you do, Webware | |
| -will mistake that directory for the Cheetah module directory, and all | |
| -template-servlets will bomb out with a "ImportError: no module named Template". | |
| -(This applies only to the standard Webware; WebwareExperimental does not have | |
| -contexts.) | |
| - | |
| -If Webware complains that it cannot find your servlet, make sure | |
| -'.tmpl' is listed in 'ExtensionsToIgnore' in your 'Application.config' file. | |
| - | |
| -% @@MO: Should explain extension cascading and how without it, standard | |
| -% Webware pretends a file doesn't exist if it finds two or more servable files | |
| -% that match the URL. | |
| - | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Containment vs Inheritance} | |
| -\label{webware.background} | |
| - | |
| -Because Cheetah's core is flexible, there are many ways to integrate it with | |
| -Webware servlets. There are two broad strategies: the {\bf Inheritance | |
| -approach} and the {\bf Containment approach}. The difference is | |
| -that in the Inheritance approach, your template object \code{\em is} the | |
| -servlet, whereas in the Containment approach, the servlet is not a template but | |
| -merely {\em uses} template(s) for portion(s) of its work. | |
| - | |
| -The Inheritance approach is recommended for new sites because it's simpler, and | |
| -because it scales well for large sites with a | |
| -site->section->subsection->servlet hierarchy. The Containment approach is | |
| -better for existing servlets that you don't want to restructure. For instance, | |
| -you can use the Containment approach to embed a discussion-forum table at the | |
| -bottom of a web page. | |
| - | |
| -However, most people who use Cheetah extensively seem | |
| -to prefer the Inheritance approach because even the most analytical servlet | |
| -needs to produce {\em some} output, and it has to fit the site's look and feel | |
| -{\em anyway}, so you may as well use a template-servlet as the place to put the | |
| -output. Especially since it's so easy to add a template-servlet to a site once | |
| -the framework is established. So we recommend you at least evaluate the | |
| -effort that would be required to convert your site framework to template | |
| -superclasses as described below, vs the greater flexibility and manageability | |
| -it might give the site over the long term. You don't necessarily have to | |
| -convert all your existing servlets right away: just build common site templates | |
| -that are visually and behaviorally compatible with your specification, and use | |
| -them for new servlets. Existing servlets can be converted later, if at all. | |
| - | |
| -Edmund Liam is preparing a section on a hybrid approach, in which the | |
| -servlet is not a template, but still calls template(s) in an inheritance | |
| -chain to produce the output. The advantage of this approach is that you | |
| -aren't dealing with \code{Template} methods and Webware methods in the | |
| -same object. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{The Containment Approach} | |
| -\label{webware.containment} | |
| - | |
| -In the Containment approach, your servlet is not a template. Instead, it | |
| -it makes its own arrangements to create and use template object(s) for whatever | |
| -it needs. The servlet must explicitly call the template objects' | |
| -\code{.respond()} (or \code{.\_\_str\_\_()}) method each time it needs to fill | |
| -the template. This does not present the output to the user; it merely gives | |
| -the output to the servlet. The servlet then calls its | |
| -\code{\#self.response().write()} method to send the output to the user. | |
| - | |
| -The developer has several choices for managing her templates. She can store the | |
| -template definition in a string, file or database and call | |
| -\code{Cheetah.Template.Template} manually on it. Or she can put the | |
| -template definition in a *.tmpl file and use {\bf cheetah compile} (section | |
| -\ref{howWorks.cheetah-compile}) to convert it to a Python class in a *.py | |
| -module, and then import it into her servlet. | |
| - | |
| -Because template objects are not thread safe, you should not store one | |
| -in a module variable and allow multiple servlets to fill it simultaneously. | |
| -Instead, each servlet should instantiate its own template object. Template | |
| -{\em classes}, however, are thread safe, since they don't change once created. | |
| -So it's safe to store a template class in a module global variable. | |
| - | |
| -% @@MO: Example of containment. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{The Inheritance Approach} | |
| -\label{webware.inheritance} | |
| - | |
| -In the Inheritance approach, your template object doubles as as Webware | |
| -servlet, thus these are sometimes called {\bf template-servlets}. {\bf cheetah | |
| -compile} (section \ref{howWorks.cheetah-compile}) automatically creates modules | |
| -containing valid Webware servlets. A servlet is a subclass of Webware's | |
| -\code{WebKit.HTTPServlet} class, contained in a module with the same name as | |
| -the servlet. WebKit uses the request URL to find the module, and then | |
| -instantiates the servlet/template. The servlet must have a \code{.respond()} | |
| -method (or \code{.respondToGet()}, \code{.respondToPut()}, etc., but the | |
| -Cheetah default is \code{.respond()}). Servlets created by \code{cheetah | |
| -compile} meet all these requirements. | |
| - | |
| -(Cheetah has a Webware plugin that automatically converts a \code{.tmpl servlet | |
| -file} into a \code{.py servlet file} when the \code{.tmpl servlet file} is | |
| -requested by a browser. However, that plugin is currently unavailable because | |
| -it's being redesigned. For now, use \code{cheetah compile} instead.) | |
| - | |
| -What about logic code? Cheetah promises to keep content (the placeholder | |
| -values), graphic design (the template definition and is display logic), and | |
| -algorithmic logic (complex calculations and side effects) separate. How? | |
| -Where do you do form processing? | |
| - | |
| -The answer is that your template class can inherit from a pure Python class | |
| -containing the analytical logic. You can either use the \code{\#extends} | |
| -directive in Cheetah to indicate the superclass(es), or write a Python | |
| -\code{class} statement to do the same thing. See the template | |
| -\code{Cheetah.Templates.SkeletonPage.tmpl} and its pure Python class | |
| -\code{Cheetah.Templates.\_SkeletonPage.py} for an example of a template | |
| -inheriting logic code. (See sections \ref{inheritanceEtc.extends} and | |
| -\ref{inheritanceEtc.implements} for more information about \code{\#extends} and | |
| -\code{\#implements}. They have to be used a certain right way.) | |
| - | |
| -If \code{\#WebKit.HTTPServlet} is not available, Cheetah fakes it with a | |
| -dummy class to satisfy the dependency. This allows servlets to be tested on | |
| -the command line even on systems where Webware is not installed. This works | |
| -only with servlets that don't call back into WebKit for information about the | |
| -current web transaction, since there is no web transaction. Trying to access | |
| -form input, for instance, will raise an exception because it depends on a | |
| -live web request object, and in the dummy class the request object is | |
| -\code{None}. | |
| - | |
| -Because Webware servlets must be valid Python modules, and ``cheetah compile'' | |
| -can produce only valid module names, if you're converting an existing site that | |
| -has .html filenames with hyphens (-), extra dots (.), etc, you'll have to | |
| -rename them (and possibly use redirects). | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Site frameworks} | |
| -\label{webware.siteFrameworks} | |
| - | |
| -Web sites are normally arranged hierarchically, with certain features common | |
| -to every page on the site, other features common to certain sections or | |
| -subsections, and others unique to each page. You can model this easily with | |
| -a hierarchy of classes, with specific servlets inheriting from their more | |
| -general superclasses. Again, you can do this two ways, using Cheetah's | |
| -{\bf Containment} approach or {\bf Inheritance} approach. | |
| - | |
| -In the Inheritance approach, parents provide \code{\#block}s and children | |
| -override them using \code{\#def}. Each child \code{\#extend}s its immediate | |
| -parent. Only the leaf servlets need to be under WebKit's document root | |
| -directory. The superclass servlets can live anywhere in the filesystem | |
| -that's in the Python path. (You may want to modify your WebKit startup | |
| -script to add that library directory to your \code{PYTHONPATH} before starting | |
| -WebKit.) | |
| - | |
| -% @@MO Examples: simple, IronSite, SkeletonPage. | |
| - | |
| -Section \ref{libraries.templates.skeletonPage} contains information on a stock | |
| -template that simplifies defining the basic HTML structure of your web | |
| -page templates. | |
| - | |
| -In the Containment approach, your hierarchy of servlets are not templates, but | |
| -each uses one or more templates as it wishes. Children provide callback | |
| -methods to to produce the various portions of the page that are their | |
| -responsibility, and parents call those methods. Webware's \code{WebKit.Page} | |
| -and \code{WebKit.SidebarPage} classes operate like this. | |
| - | |
| -% @@MO Show examples of WebKit.Page and WebKit.SidebarPage. | |
| - | |
| -Note that the two approaches are not compatible! \code{WebKit.Page} was not | |
| -designed to intermix with \code{Cheetah.Templates.SkeletonPage}. Choose either | |
| -one or the other, or expect to do some integration work. | |
| - | |
| -If you come up with a different strategy you think is worth noting in this | |
| -chapter, let us know. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Directory structure} | |
| -\label{webware.directoryStructure} | |
| - | |
| -Here's one way to organize your files for Webware+Cheetah. | |
| - | |
| -\begin{verbatim} | |
| -www/ # Web root directory. | |
| - site1.example.com/ # Site subdirectory. | |
| - apache/ # Web server document root (for non-servlets). | |
| - www/ # WebKit document root. | |
| - index.py # http://site1.example.com/ | |
| - index.tmpl # Source for above. | |
| - servlet2.py # http://site1.example.com/servlet2 | |
| - servlet2.tmpl # Source for above. | |
| - lib/ # Directory for helper classes. | |
| - Site.py # Site superclass ("#extends Site"). | |
| - Site.tmpl # Source for above. | |
| - Logic.py # Logic class inherited by some template. | |
| - webkit.config # Configuration file (for WebwareExperimental). | |
| - Webware/ # Standard Webware's MakeAppWorkDir directory. | |
| - AppServer # Startup program (for standard Webware). | |
| - Configs/ # Configuration directory (for standard Webware). | |
| - Application.config | |
| - # Configuration file (for standard Webware). | |
| - site2.example.org/ # Another virtual host on this computer.... | |
| -\end{verbatim} | |
| - | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Initializing your template-servlet with Python code} | |
| -\label{webware.calculations} | |
| - | |
| -If you need a place to initialize variables or do calculations for your | |
| -template-servlet, you can put it in an \code{.awake()} method because WebKit | |
| -automatically calls that early when processing the web transaction. If you | |
| -do override \code{.awake()}, be sure to call the superclass \code{.awake} | |
| -method. You probably want to do that first so that you have access to the | |
| -web transaction data \code{Servlet.awake} provides. You don't have to worry | |
| -about whether your parent class has its own \code{.awake} method, just call | |
| -it anyway, and somebody up the inheritance chain will respond, or at minimum | |
| -\code{Servlet.awake} will respond. Section | |
| -\ref{tips.callingSuperclassMethods} gives examples of how to call a | |
| -superclass method. | |
| - | |
| -As an alternative, you can put all your calculations in your own method and | |
| -call it near the top of your template. (\code{\#silent}, section | |
| -\ref{output.silent}). | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Form processing} | |
| -\label{webware.form} | |
| - | |
| -There are many ways to display and process HTML forms with Cheetah. | |
| -But basically, all form processing involves two steps. | |
| -\begin{enumerate} | |
| -\item{} Display the form. | |
| -\item{} In the next web request, read the parameters the user submitted, | |
| -check for user errors, perform any side effects (e.g., reading/writing a | |
| -database or session data) and present the user an HTML response or another | |
| -form. | |
| -\end{enumerate} | |
| - | |
| -The second step may involve choosing between several templates to fill (or | |
| -several servlets to redirect to), or a big if-elif-elif-else construct to | |
| -display a different portion of the template depending on the situation. | |
| - | |
| -In the oldest web applications, step 1 and step 2 were handled by separate | |
| -objects. Step 1 was a static HTML file, and step 2 was a CGI script. | |
| -Frequently, a better strategy is to have a single servlet handle both steps. | |
| -That way, the servlet has better control over the entire situation, and if | |
| -the user submits unacceptable data, the servlet can redisplay the form with a | |
| -"try again" error message at the top and and all the previous input filled in. | |
| -The servlet can use the presence or absence of certain CGI parameters (e.g., | |
| -the submit button, or a hidden mode field) to determine which step to take. | |
| - | |
| -One neat way to build a servlet that can handle both the form displaying and | |
| -form processing is like this: | |
| - | |
| -\begin{enumerate} | |
| -\item Put your form HTML into an ordinary template-servlet. In each input | |
| - field, use a placeholder for the value of the \code{VALUE=} attribue. | |
| - Place another placeholder next to each field, for that field's error | |
| - message. | |
| -\item Above the form, put a \code{\$processFormData} method call. | |
| -\item Define that method in a Python class your template \code{\#extend}s. (Or | |
| - if it's a simple method, you can define it in a \code{\#def}.) The method | |
| - should: | |
| - \begin{enumerate} | |
| - \item Get the form input if any. | |
| - \item If the input variable corresponding to the submit field is empty, | |
| - there is no form input, so we're showing the form for the first time. | |
| - Initialize all VALUE= variables to their default value (usually ""), | |
| - and all error variables to "". Return "", which will be the value for | |
| - \code{\$processFormData}. | |
| - \item If the submit variable is not empty, fill the VALUE= variables with | |
| - the input data the user just submitted. | |
| - \item Now check the input for errors and put error messages in the error | |
| - placeholders. | |
| - \item If there were any user errors, return a general error message | |
| - string; this will be the value for \code{\$processFormData}. | |
| - \item If there were no errors, do whatever the form's job is (e.g., update | |
| - a database) and return a success message; this will be the value for | |
| - \code{\$processFormData}. | |
| - \end{enumerate} | |
| -\item The top of the page will show your success/failure message (or nothing | |
| -the first time around), with the form below. If there are errors, the user | |
| -will have a chance to correct them. After a successful submit, the form will | |
| -appear again, so the user can either review their entry, or change it and | |
| -submit it again. Depending on the application, this may make the servlet | |
| -update the same database record again, or it may generate a new record. | |
| -\end{enumerate} | |
| - | |
| -% @@MO: Example of a template that shows a form and then processes the input. | |
| - | |
| -\code{FunFormKit} is a third-party Webware package that makes it easier to | |
| -produce forms and handle their logic. It has been successfully been used with | |
| -Cheetah. You can download FunFormKit from | |
| -\url{http://colorstudy.net/software/funformkit/} and try it out for yourself. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Form input, cookies, session variables and web server variables} | |
| -\label{webware.input} | |
| - | |
| -General variable tips that also apply to servlets are in section | |
| -\ref{tips.placeholder}. | |
| - | |
| -To look up a CGI GET or POST parameter (with POST overriding): | |
| -\begin{verbatim} | |
| -$request.field('myField') | |
| -self.request().field('myField') | |
| -\end{verbatim} | |
| -These will fail if Webware is not available, because \code{\$request} | |
| -(aka \code{self.request()} will be \code{None} rather than a Webware | |
| -\code{WebKit.Request} object. If you plan to read a lot of CGI parameters, | |
| -you may want to put the \code{.fields} method into a local variable for | |
| -convenience: | |
| -\begin{verbatim} | |
| -#set $fields = $request.fields | |
| -$fields.myField | |
| -\end{verbatim} | |
| -But remember to do complicated calculations in Python, and assign the results | |
| -to simple variables in the searchList for display. These \code{\$request} | |
| -forms are useful only for occasions where you just need one or two simple | |
| -request items that going to Python for would be overkill. | |
| - | |
| -To get a cookie or session parameter, subsitute ``cookie'' or ``session'' for | |
| -``field'' above. To get a dictionary of all CGI parameters, substitute | |
| -``fields'' (ditto for ``cookies''). To verify a field exists, | |
| -substitute ``hasField'' (ditto for ``hasCookie''). | |
| - | |
| -Other useful request goodies: | |
| -\begin{verbatim} | |
| -## Defined in WebKit.Request | |
| -$request.field('myField', 'default value') | |
| -$request.time ## Time this request began in Unix ticks. | |
| -$request.timeStamp ## Time in human-readable format ('asctime' format). | |
| -## Defined in WebKit.HTTPRequest | |
| -$request.hasField.myField ## Is a CGI parameter defined? | |
| -$request.fields ## Dictionary of all CGI parameters. | |
| -$request.cookie.myCookie ## A cookie parameter (also .hasCookie, .cookies). | |
| -$request.value.myValue ## A field or cookie variable (field overrides) | |
| - ## (also .hasValue). | |
| -$request.session.mySessionVar # A session variable. | |
| -$request.extraURLPath ## URL path components to right of servlet, if any. | |
| -$request.serverDictionary ## Dict of environmental vars from web server. | |
| -$request.remoteUser ## Authenticated username. HTTPRequest.py source | |
| - ## suggests this is broken and always returns None. | |
| -$request.remoteAddress ## User's IP address (string). | |
| -$request.remoteName ## User's domain name, or IP address if none. | |
| -$request.urlPath ## URI of this servlet. | |
| -$request.urlPathDir ## URI of the directory containing this servlet. | |
| -$request.serverSidePath ## Absolute path of this servlet on local filesystem. | |
| -$request.serverURL ## URL of this servlet, without "http://" prefix, | |
| - ## extra path info or query string. | |
| -$request.serverURLDir ## URL of this servlet's directory, without "http://". | |
| -$log("message") ## Put a message in the Webware server log. (If you | |
| - ## define your own 'log' variable, it will override | |
| - ## this; use $self.log("message") in that case. | |
| -\end{verbatim} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{.webInput()} | |
| -\label{webware.webInput} | |
| - | |
| -From the method docstring: | |
| - | |
| -\begin{verbatim} | |
| - def webInput(self, names, namesMulti=(), default='', src='f', | |
| - defaultInt=0, defaultFloat=0.00, badInt=0, badFloat=0.00, debug=False): | |
| - | |
| -This method places the specified GET/POST fields, cookies or session variables | |
| -into a dictionary, which is both returned and put at the beginning of the | |
| -searchList. It handles: | |
| - * single vs multiple values | |
| - * conversion to integer or float for specified names | |
| - * default values/exceptions for missing or bad values | |
| - * printing a snapshot of all values retrieved for debugging | |
| -All the 'default*' and 'bad*' arguments have "use or raise" behavior, meaning | |
| -that if they're a subclass of Exception, they're raised. If they're anything | |
| -else, that value is substituted for the missing/bad value. | |
| - | |
| -The simplest usage is: | |
| - | |
| - #silent $webInput(['choice']) | |
| - $choice | |
| - | |
| - dic = self.webInput(['choice']) | |
| - write(dic['choice']) | |
| - | |
| -Both these examples retrieves the GET/POST field 'choice' and print it. If you | |
| -leave off the "#silent", all the values would be printed too. But a better way | |
| -to preview the values is | |
| - | |
| - #silent $webInput(['name'], $debug=1) | |
| - | |
| -because this pretty-prints all the values inside HTML <PRE> tags. | |
| - | |
| -Since we didn't specify any coversions, the value is a string. It's a "single" | |
| -value because we specified it in 'names' rather than 'namesMulti'. Single | |
| -values work like this: | |
| - * If one value is found, take it. | |
| - * If several values are found, choose one arbitrarily and ignore the rest. | |
| - * If no values are found, use or raise the appropriate 'default*' value. | |
| - | |
| -Multi values work like this: | |
| - * If one value is found, put it in a list. | |
| - * If several values are found, leave them in a list. | |
| - * If no values are found, use the empty list ([]). The 'default*' | |
| - arguments are *not* consulted in this case. | |
| - | |
| -Example: assume 'days' came from a set of checkboxes or a multiple combo box | |
| -on a form, and the user chose "Monday", "Tuesday" and "Thursday". | |
| - | |
| - #silent $webInput([], ['days']) | |
| - The days you chose are: #slurp | |
| - #for $day in $days | |
| - $day #slurp | |
| - #end for | |
| - | |
| - dic = self.webInput([], ['days']) | |
| - write("The days you chose are: ") | |
| - for day in dic['days']: | |
| - write(day + " ") | |
| - | |
| -Both these examples print: "The days you chose are: Monday Tuesday Thursday". | |
| - | |
| -By default, missing strings are replaced by "" and missing/bad numbers by zero. | |
| -(A "bad number" means the converter raised an exception for it, usually because | |
| -of non-numeric characters in the value.) This mimics Perl/PHP behavior, and | |
| -simplifies coding for many applications where missing/bad values *should* be | |
| -blank/zero. In those relatively few cases where you must distinguish between | |
| -""/zero on the one hand and missing/bad on the other, change the appropriate | |
| -'default*' and 'bad*' arguments to something like: | |
| - * None | |
| - * another constant value | |
| - * $NonNumericInputError/self.NonNumericInputError | |
| - * $ValueError/ValueError | |
| -(NonNumericInputError is defined in this class and is useful for | |
| -distinguishing between bad input vs a TypeError/ValueError | |
| -thrown for some other reason.) | |
| - | |
| -Here's an example using multiple values to schedule newspaper deliveries. | |
| -'checkboxes' comes from a form with checkboxes for all the days of the week. | |
| -The days the user previously chose are preselected. The user checks/unchecks | |
| -boxes as desired and presses Submit. The value of 'checkboxes' is a list of | |
| -checkboxes that were checked when Submit was pressed. Our task now is to | |
| -turn on the days the user checked, turn off the days he unchecked, and leave | |
| -on or off the days he didn't change. | |
| - | |
| - dic = self.webInput([], ['dayCheckboxes']) | |
| - wantedDays = dic['dayCheckboxes'] # The days the user checked. | |
| - for day, on in self.getAllValues(): | |
| - if not on and wantedDays.has_key(day): | |
| - self.TurnOn(day) | |
| - # ... Set a flag or insert a database record ... | |
| - elif on and not wantedDays.has_key(day): | |
| - self.TurnOff(day) | |
| - # ... Unset a flag or delete a database record ... | |
| - | |
| -'source' allows you to look up the variables from a number of different | |
| -sources: | |
| - 'f' fields (CGI GET/POST parameters) | |
| - 'c' cookies | |
| - 's' session variables | |
| - 'v' "values", meaning fields or cookies | |
| - | |
| -In many forms, you're dealing only with strings, which is why the | |
| -'default' argument is third and the numeric arguments are banished to | |
| -the end. But sometimes you want automatic number conversion, so that | |
| -you can do numeric comparisons in your templates without having to | |
| -write a bunch of conversion/exception handling code. Example: | |
| - | |
| - #silent $webInput(['name', 'height:int']) | |
| - $name is $height cm tall. | |
| - #if $height >= 300 | |
| - Wow, you're tall! | |
| - #else | |
| - Pshaw, you're short. | |
| - #end if | |
| - | |
| - dic = self.webInput(['name', 'height:int']) | |
| - name = dic[name] | |
| - height = dic[height] | |
| - write("%s is %s cm tall." % (name, height)) | |
| - if height > 300: | |
| - write("Wow, you're tall!") | |
| - else: | |
| - write("Pshaw, you're short.") | |
| - | |
| -To convert a value to a number, suffix ":int" or ":float" to the name. The | |
| -method will search first for a "height:int" variable and then for a "height" | |
| -variable. (It will be called "height" in the final dictionary.) If a numeric | |
| -conversion fails, use or raise 'badInt' or 'badFloat'. Missing values work | |
| -the same way as for strings, except the default is 'defaultInt' or | |
| -'defaultFloat' instead of 'default'. | |
| - | |
| -If a name represents an uploaded file, the entire file will be read into | |
| -memory. For more sophisticated file-upload handling, leave that name out of | |
| -the list and do your own handling, or wait for Cheetah.Utils.UploadFileMixin. | |
| - | |
| -This mixin class works only in a subclass that also inherits from | |
| -Webware's Servlet or HTTPServlet. Otherwise you'll get an AttributeError | |
| -on 'self.request'. | |
| - | |
| -EXCEPTIONS: ValueError if 'source' is not one of the stated characters. | |
| -TypeError if a conversion suffix is not ":int" or ":float". | |
| -\end{verbatim} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{More examples} | |
| -\label{webware.examples} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection*{Example A -- a standalone servlet} | |
| -%\label{} | |
| - | |
| -% @@MO: | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection*{Example B -- a servlet under a site framework} | |
| -%\label{} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection*{Example C -- several servlets with a common template} | |
| -%\label{} | |
| - | |
| - | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Other Tips} | |
| -\label{webware.otherTips} | |
| - | |
| -If your servlet accesses external files (e.g., via an \code{\#include} | |
| -directive), remember that the current directory is not necessarily directory | |
| -the servlet is in. It's probably some other directory WebKit chose. To find a | |
| -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 main method, read the chapter on inheritance (sections | |
| -\ref{inheritanceEtc.extends} and \ref{inheritanceEtc.implements}). This may | |
| -help you avoid buggy servlets. | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| -%# vim: sw=4 ts=4 expandtab | |
| - | |
| - | |
| - | |
| -``Template`` subclasses Webware's ``Servlet`` class when available, | |
| -so the generated class can be used as a Webware servlet. This is practical | |
| -only with precompiled templates. | |
| - | |
| diff --git a/docs/users_guide_2_src/15_otherHtml.txt b/docs/users_guide_2_src/15_otherHtml.txt | |
| deleted file mode 100755 | |
| index 89fd58a..0000000 | |
| --- a/docs/users_guide_2_src/15_otherHtml.txt | |
| +++ /dev/null | |
| @@ -1,95 +0,0 @@ | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\section{non-Webware HTML output} | |
| -\label{otherHTML} | |
| - | |
| -Cheetah can be used with all types of HTML output, not just with Webware. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Static HTML Pages} | |
| -\label{otherHTML.static} | |
| - | |
| -Some sites like Linux Gazette (\url{http://www.linuxgazette.com/}) require | |
| -completely static pages because they are mirrored on servers running completely | |
| -different software from the main site. Even dynamic sites may have one or | |
| -two pages that are static for whatever reason, and the site administrator may | |
| -wish to generate those pages from Cheetah templates. | |
| - | |
| -There's nothing special here. Just create your templates as usual. Then | |
| -compile and fill them whenever the template definition changes, and fill them | |
| -again whenever the placeholder values change. You may need an extra step to | |
| -copy the .html files to their final location. A Makefile (chapter | |
| -\ref{tips.Makefile}) can help encapsulate these steps. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{CGI scripts} | |
| -\label{otherHTML} | |
| - | |
| -Unlike Webware servlets, which don't have to worry about the HTTP headers, | |
| -CGI scripts must emit their own headers. To make a template CGI aware, add | |
| -this at the top: | |
| -\begin{verbatim} | |
| -#extends Cheetah.Tools.CGITemplate | |
| -#implements respond | |
| -$cgiHeaders#slurp | |
| -\end{verbatim} | |
| - | |
| -Or if your template is inheriting from a Python class: | |
| -\begin{verbatim} | |
| -#extends MyPythonClass | |
| -#implements respond | |
| -$cgiHeaders#slurp | |
| -\end{verbatim} | |
| - | |
| -A sample Python class: | |
| -\begin{verbatim} | |
| -from Cheetah.Tools import CGITemplate | |
| -class MyPythonClass(CGITemplate): | |
| - def cgiHeadersHook(self): | |
| - return "Content-Type: text/html; charset=koi8-r\n\n" | |
| -\end{verbatim} | |
| - | |
| - | |
| -Compile the template as usual, put the .py template module in your | |
| -cgi-bin directory and give it execute permission. \code{.cgiHeaders()} is | |
| -a ``smart'' method that outputs the headers if the module is called as a | |
| -CGI script, or outputs nothing if not. Being ``called as a CGI script'' | |
| -means the environmental variable \code{REQUEST\_METHOD} exists and | |
| -\code{self.isControlledByWebKit} is false. If you don't agree with that | |
| -definition, override \code{.isCgi()} and provide your own. | |
| - | |
| -The default header is a simple \verb+Content-type: text/html\n\n+, which works | |
| -with all CGI scripts. If you want to customize the headers (e.g., to | |
| -specify the character set), override \code{.cgiHeadersHook()} and return | |
| -a string containing all the headers. Don't forget to include the extra | |
| -newline at the end of the string: the HTTP protocol requires this empty | |
| -line to mark the end of the headers. | |
| - | |
| -To read GET/POST variables from form input, use the \code{.webInput()} method | |
| -(section \ref{webware.webInput}), or extract them yourself using Python's | |
| -\code{cgi} module or your own function. Although \code{.webInput()} was | |
| -originally written for Webware servlets, it now handles CGI scripts too. There | |
| -are a couple behavioral differences between CGI scripts and Webware servlets | |
| -regarding input variables: | |
| - | |
| -\begin{enumerate} | |
| -\item CGI scripts, using Python's \code{cgi} module, believe | |
| - \code{REQUEST\_METHOD} and recognize {\em either} GET variables {\em or} | |
| - POST variables, not both. Webware servlets, doing additional processing, | |
| - ignore \code{REQUEST\_METHOD} and recognize both, like PHP does. | |
| -\item Webware servlets can ask for cookies or session variables instead of | |
| - GET/POST variables, by passing the argument \code{src='c'} or | |
| - \code{src='s'}. CGI scripts get a \code{RuntimeError} if they try to do | |
| - this. | |
| -\end{enumerate} | |
| - | |
| -If you keep your .tmpl files in the same directory as your CGI scripts, make | |
| -sure they don't have execute permission. Apache at least refuses to serve | |
| -files in a \code{ScriptAlias} directory that don't have execute permission. | |
| - | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| -%# vim: sw=4 ts=4 expandtab | |
| diff --git a/docs/users_guide_2_src/16_nonHtml.txt b/docs/users_guide_2_src/16_nonHtml.txt | |
| deleted file mode 100755 | |
| index b618ab0..0000000 | |
| --- a/docs/users_guide_2_src/16_nonHtml.txt | |
| +++ /dev/null | |
| @@ -1,17 +0,0 @@ | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\section{Non-HTML Output} | |
| -\label{nonHTML} | |
| - | |
| -Cheetah can also output any other text format besides HTML. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Python source code} | |
| -\label{nonHTML.python} | |
| - | |
| -To be written. We're in the middle of working on an autoindenter to | |
| -make it easier to encode Python indentation in a Cheetah template. | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| -%# vim: sw=4 ts=4 expandtab | |
| diff --git a/docs/users_guide_2_src/17_libraries.txt b/docs/users_guide_2_src/17_libraries.txt | |
| deleted file mode 100755 | |
| index dc9231a..0000000 | |
| --- a/docs/users_guide_2_src/17_libraries.txt | |
| +++ /dev/null | |
| @@ -1,306 +0,0 @@ | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\section{Batteries included: templates and other libraries} | |
| -\label{libraries} | |
| - | |
| -Cheetah comes ``batteries included'' with libraries of templates, functions, | |
| -classes and other objects you can use in your own programs. The different | |
| -types are listed alphabetically below, followed by a longer description of | |
| -the SkeletonPage framework. Some of the objects are classes for specific | |
| -purposes (e.g., filters or error catchers), while others are standalone and | |
| -can be used without Cheetah. | |
| - | |
| -If you develop any objects which are generally useful for Cheetah sites, | |
| -please consider posting them on the wiki with an announcement on the mailing | |
| -list so we can incorporate them into the standard library. That way, all | |
| -Cheetah users will benefit, and it will encourage others to contribute their | |
| -objects, which might include something you want. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{ErrorCatchers} | |
| -\label{libraries.ErrorCatchers} | |
| - | |
| -Module \code{Cheetah.ErrorCatchers} contains error-handling classes suitable for | |
| -the \code{\#errorCatcher} directive. These are debugging tools that are not | |
| -intended for use in production systems. See section | |
| -\ref{errorHandling.errorCatcher} for a description of the error catchers bundled | |
| -with Cheetah. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{FileUtils} | |
| -\label{libraries.FileUtils} | |
| - | |
| -Module \code{Cheetah.FileUtils} contains generic functions and classes for | |
| -doing bulk search-and-replace on several files, and for finding all the files | |
| -in a directory hierarchy whose names match a glob pattern. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Filters} | |
| -\label{libraries.Filters} | |
| - | |
| -Module \code{Filters} contains filters suitable for the \code{\#Filter} | |
| -directive. See section \ref{output.filter} for a description of the | |
| -filters bundled with Cheetah. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{SettingsManager} | |
| -\label{libraries.SettingsManager} | |
| - | |
| -The \code{SettingsManager} class in the \code{Cheetah.SettingsManager} module is | |
| -a baseclass that provides facilities for managing application settings. It | |
| -facilitates the use of user-supplied configuration files to fine tune an | |
| -application. A setting is a key/value pair that an application or component | |
| -(e.g., a filter, or your own servlets) looks up and treats as a configuration | |
| -value to modify its (the component's) behaviour. | |
| - | |
| -SettingsManager is designed to: | |
| -\begin{itemize} | |
| -\item work well with nested settings dictionaries of any depth | |
| -\item read/write \code{.ini style config files} (or strings) | |
| -\item read settings from Python source files (or strings) so that | |
| - complex Python objects can be stored in the application's settings | |
| - dictionary. For example, you might want to store references to various | |
| - classes that are used by the application, and plugins to the application | |
| - might want to substitute one class for another. | |
| -\item allow sections in \code{.ini config files} to be extended by settings in | |
| - Python src files. If a section contains a setting like | |
| - ``\code{importSettings=mySettings.py}'', \code{SettingsManager} will merge | |
| - all the settings defined in ``\code{mySettings.py}'' with the settings for | |
| - that section that are defined in the \code{.ini config file}. | |
| -\item maintain the case of setting names, unlike the ConfigParser module | |
| -\end{itemize} | |
| - | |
| -Cheetah uses \code{SettingsManager} to manage its configuration settings. | |
| -\code{SettingsManager} might also be useful in your own applications. See the | |
| -source code and docstrings in the file \code{src/SettingsManager.py} for more | |
| -information. | |
| - | |
| - | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Templates} | |
| -\label{libraries.templates} | |
| - | |
| -Package \code{Cheetah.Templates} contains stock templates that you can | |
| -either use as is, or extend by using the \code{\#def} directive to redefine | |
| -specific {\bf blocks}. Currently, the only template in here is SkeletonPage, | |
| -which is described in detail below in section | |
| -\ref{libraries.templates.skeletonPage}. (Contributed by Tavis Rudd.) | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Tools} | |
| -\label{libraries.Tools} | |
| - | |
| -Package \code{Cheetah.Tools} contains functions and classes contributed by third | |
| -parties. Some are Cheetah-specific but others are generic and can be used | |
| -standalone. None of them are imported by any other Cheetah component; you can | |
| -delete the Tools/ directory and Cheetah will function fine. | |
| - | |
| -Some of the items in Tools/ are experimental and have been placed there just to | |
| -see how useful they will be, and whether they attract enough users to make | |
| -refining them worthwhile (the tools, not the users :). | |
| - | |
| -Nothing in Tools/ is guaranteed to be: (A) tested, (B) reliable, (C) immune | |
| -from being deleted in a future Cheetah version, or (D) immune from | |
| -backwards-incompatable changes. If you depend on something in Tools/ on a | |
| -production system, consider making a copy of it outside the Cheetah/ directory | |
| -so that this version won't be lost when you upgrade Cheetah. Also, learn | |
| -enough about Python and about the Tool so that you can maintain it and bugfix | |
| -it if necessary. | |
| - | |
| -If anything in Tools/ is found to be necessary to Cheetah's operation (i.e., if | |
| -another Cheetah component starts importing it), it will be moved to the | |
| -\code{Cheetah.Utils} package. | |
| - | |
| -Current Tools include: | |
| -\begin{description} | |
| -\item{Cheetah.Tools.MondoReport} an ambitious class useful when | |
| - iterating over records of data (\code{\#for} loops), displaying one | |
| - pageful of records at a time (with previous/next links), and printing | |
| - summary statistics about the records or the current page. See | |
| - \code{MondoReportDoc.txt} in the same directory as the module. Some | |
| - features are not implemented yet. \code{MondoReportTest.py} is a test | |
| - suite (and it shows there are currently some errors in MondoReport, hmm). | |
| - Contributed by Mike Orr. | |
| - | |
| -\item{Cheetah.Tools.RecursiveNull} Nothing, but in a friendly way. Good | |
| - for filling in for objects you want to hide. If \code{\$form.f1} is a | |
| - RecursiveNull object, then \code{\$form.f1.anything["you"].might("use")} | |
| - will resolve to the empty string. You can also put a \code{RecursiveNull} | |
| - instance at the end of the searchList to convert missing values to '' | |
| - rather than raising a \code{NotFound} error or having a (less efficient) | |
| - errorCatcher handle it. Of course, maybe you prefer to get a | |
| - \code{NotFound} error... Contributed by Ian Bicking. | |
| - | |
| -\item{Cheetah.Tools.SiteHierarchy} Provides navigational links to this | |
| - page's parents and children. The constructor takes a recursive list of | |
| - (url,description) pairs representing a tree of hyperlinks to every page in | |
| - the site (or section, or application...), and also a string containing the | |
| - current URL. Two methods 'menuList' and 'crumbs' return output-ready HTML | |
| - showing an indented menu (hierarchy tree) or crumbs list (Yahoo-style bar: | |
| - home > grandparent > parent > currentURL). Contributed by Ian Bicking. | |
| - | |
| -\item | |
| -\end{description} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Utils} | |
| -\label{libraries.Utils} | |
| - | |
| -Package \code{Cheetah.Utils} contains non-Cheetah-specific functions and | |
| -classes that are imported by other Cheetah components. Many of these utils can | |
| -be used standalone in other applications too. | |
| - | |
| -Current Utils include: | |
| -\begin{description} | |
| -\item{Cheetah.Utils.CGIImportMixin} This is inherited by \code{Template} | |
| - objects, and provides the method, \code{.cgiImport} method | |
| - (section \ref{webware.cgiImport}). | |
| - | |
| -\item{Cheetah.Utils.Misc} A catch-all module for small functions. | |
| - \begin{description} | |
| - \item{\code{UseOrRaise(thing, errmsg='')}} Raise 'thing' if it's a | |
| - subclass of Exception, otherwise return it. Useful when one | |
| - argument does double duty as a default value or an exception to | |
| - throw. Contribyted by Mike Orr. | |
| - | |
| - \item{\code{checkKeywords(dic, legalKeywords, what='argument'}} | |
| - Verifies the dictionary does not contain any keys not listed in | |
| - 'legalKeywords'. If it does, raise TypeError. Useful for | |
| - checking the keyword arguments to a function. Contributed by | |
| - Mike Orr. | |
| - \end{description} | |
| - | |
| -\item{Cheetah.Utils.UploadFileMixin} Not implemented yet, but will contain | |
| - the \code{.uploadFile} method (or three methods) to ``safely'' copy a | |
| - form-uploaded file to a local file, to a searchList variable, or return | |
| - it. When finished, this will be inherited by \code{Template}, allowing | |
| - all templates to do this. If you want this feature, read the docstring | |
| - in the source and let us know on the mailing list what you'd like this | |
| - method to do. Contributed by Mike Orr. | |
| - | |
| -\item{Cheetah.Utils.VerifyType} Functions to verify the type of a | |
| - user-supplied function argument. Contributed by Mike Orr. | |
| -\end{description} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{Cheetah.Templates.SkeletonPage} | |
| -\label{libraries.templates.skeletonPage} | |
| - | |
| -A stock template class that may be useful for web developers is defined in | |
| -the \code{Cheetah.Templates.SkeletonPage} module. The \code{SkeletonPage} | |
| -template class is generated from the following Cheetah source code: | |
| - | |
| -\begin{verbatim} | |
| -##doc-module: A Skeleton HTML page template, that provides basic structure and utility methods. | |
| -################################################################################ | |
| -#extends Cheetah.Templates._SkeletonPage | |
| -#implements respond | |
| -################################################################################ | |
| -#cache id='header' | |
| -$docType | |
| -$htmlTag | |
| -<!-- This document was autogenerated by Cheetah(http://CheetahTemplate.org). | |
| -Do not edit it directly! | |
| - | |
| -Copyright $currentYr - $siteCopyrightName - All Rights Reserved. | |
| -Feel free to copy any javascript or html you like on this site, | |
| -provided you remove all links and/or references to $siteDomainName | |
| -However, please do not copy any content or images without permission. | |
| - | |
| -$siteCredits | |
| - | |
| ---> | |
| - | |
| - | |
| -#block writeHeadTag | |
| -<head> | |
| -<title>$title</title> | |
| -$metaTags | |
| -$stylesheetTags | |
| -$javascriptTags | |
| -</head> | |
| -#end block writeHeadTag | |
| - | |
| -#end cache header | |
| -################# | |
| - | |
| -$bodyTag | |
| - | |
| -#block writeBody | |
| -This skeleton page has no flesh. Its body needs to be implemented. | |
| -#end block writeBody | |
| - | |
| -</body> | |
| -</html> | |
| -\end{verbatim} | |
| - | |
| -You can redefine any of the blocks defined in this template by writing a new | |
| -template that \code{\#extends} SkeletonPage. (As you remember, using | |
| -\code{\#extends} makes your template implement the \code{.writeBody()} | |
| -method instead of \code{.respond()} -- which happens to be the same method | |
| -SkeletonPage expects the page content to be (note the writeBody block in | |
| -SkeletonPage).) | |
| - | |
| -\begin{verbatim} | |
| -#def bodyContents | |
| -Here's my new body. I've got some flesh on my bones now. | |
| -#end def bodyContents | |
| -\end{verbatim} | |
| - | |
| -%% @@MO: Is this still accurate? Does the child template really need to put a | |
| -%% #def around its whole content? Or by implementing .writeBody() does it | |
| -%% automatically insert itself as the writeBody portion of | |
| -%% SkeletonPage? @@TR 2005-01-06: it happens automatically at the moment. | |
| - | |
| -All of the \$placeholders used in the \code{SkeletonPage} template definition | |
| -are attributes or methods of the \code{SkeletonPage} class. You can reimplement | |
| -them as you wish in your subclass. Please read the source code of the file | |
| -\code{src/Templates/\_SkeletonPage.py} before doing so. | |
| - | |
| -You'll need to understand how to use the following methods of the | |
| -\code{SkeletonPage} class: \code{\$metaTags()}, \code{\$stylesheetTags()}, | |
| -\code{\$javascriptTags()}, and \code{\$bodyTag()}. They take the data you | |
| -define in various attributes and renders them into HTML tags. | |
| - | |
| -\begin{itemize} | |
| -\item {\bf metaTags()} -- Returns a formatted vesion of the self.\_metaTags | |
| - dictionary, using the formatMetaTags function from | |
| - \code{\_SkeletonPage.py}. | |
| -\item {\bf stylesheetTags()} -- Returns a formatted version of the | |
| - \code{self.\_stylesheetLibs} and \code{self.\_stylesheets} dictionaries. | |
| - The keys in \code{self.\_stylesheets} must be listed in the order that | |
| - they should appear in the list \code{self.\_stylesheetsOrder}, to ensure | |
| - that the style rules are defined in the correct order. | |
| -\item {\bf javascriptTags()} -- Returns a formatted version of the | |
| - \code{self.\_javascriptTags} and \code{self.\_javascriptLibs} dictionaries. | |
| - Each value in \code{self.\_javascriptTags} should be a either a code string | |
| - to include, or a list containing the JavaScript version number and the code | |
| - string. The keys can be anything. The same applies for | |
| - \code{self.\_javascriptLibs}, but the string should be the SRC filename | |
| - rather than a code string. | |
| -\item {\bf bodyTag()} -- Returns an HTML body tag from the entries in the dict | |
| - \code{self.\_bodyTagAttribs}. | |
| -\end{itemize} | |
| - | |
| -The class also provides some convenience methods that can be used as | |
| -\$placeholders in your template definitions: | |
| - | |
| -\begin{itemize} | |
| -\item {\bf imgTag(self, src, alt='', width=None, height=None, border=0)} -- | |
| - Dynamically generate an image tag. Cheetah will try to convert the | |
| - ``\code{src}'' argument to a WebKit serverSidePath relative to the | |
| - servlet's location. If width and height aren't specified they are | |
| - calculated using PIL or ImageMagick if either of these tools are available. | |
| - If all your images are stored in a certain directory you can reimplement | |
| - this method to append that directory's path to the ``\code{src}'' argument. | |
| - Doing so would also insulate your template definitions from changes in your | |
| - directory structure. | |
| -\end{itemize} | |
| - | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| diff --git a/docs/users_guide_2_src/18_editors.txt b/docs/users_guide_2_src/18_editors.txt | |
| deleted file mode 100755 | |
| index 84c8f03..0000000 | |
| --- a/docs/users_guide_2_src/18_editors.txt | |
| +++ /dev/null | |
| @@ -1,39 +0,0 @@ | |
| -\section{Visual Editors} | |
| -\label{visualEditors} | |
| - | |
| -This chapter is about maintaining Cheetah templates with visual editors, | |
| -and the tradeoffs between making it friendly to both text editors and visual | |
| -editors. | |
| - | |
| -Cheetah's main developers do not use visual editors. Tavis uses \code{emacs}; | |
| -Mike uses \code{vim}. So our first priority is to make templates easy to | |
| -maintain in text editors. In particular, we don't want to add features | |
| -like Zope Page Template's | |
| -placeholder-value-with-mock-text-for-visual-editors-all-in-an-XML-tag. | |
| -The syntax is so verbose it makes for a whole lotta typing just to insert a | |
| -simple placeholder, for the benefit of editors we never use. However, as users | |
| -identify features which would help their visual editing without making it | |
| -harder to maintain templates in a text editor, we're all for it. | |
| - | |
| -As it said in the introduction, Cheetah purposely does not use HTML/XML | |
| -tags for \$placeholders or \#directives. That way, when you preview the | |
| -template in an editor that interprets HTML tags, you'll still see the | |
| -placeholder and directive source definitions, which provides some ``mock text'' | |
| -even if it's not the size the final values will be, and allows you to use | |
| -your imagination to translate how the directive output will look visually in | |
| -the final. | |
| - | |
| -If your editor has syntax highlighting, turn it on. That makes a big | |
| -difference in terms of making the template easier to edit. Since no | |
| -``Cheetah mode'' has been invented yet, set your highlighting to Perl | |
| -mode, and at least the directives/placeholders will show up in different | |
| -colors, although the editor won't reliably guess where the | |
| -directive/placeholder ends and normal text begins. | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| - | |
| - | |
| - | |
| - | |
| diff --git a/docs/users_guide_2_src/A_links.txt b/docs/users_guide_2_src/A_links.txt | |
| deleted file mode 100755 | |
| index 1ec2f6c..0000000 | |
| --- a/docs/users_guide_2_src/A_links.txt | |
| +++ /dev/null | |
| @@ -1,112 +0,0 @@ | |
| -\section{Useful Web Links} | |
| -\label{links} | |
| - | |
| -See the wiki for more links. (The wiki is also updated more often than this | |
| -chapter is.) | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Cheetah Links} | |
| -\label{links.cheetah} | |
| - | |
| -\begin{description} | |
| -\item[Home Page] -- \url{http:www.CheetahTemplate.org/} | |
| - | |
| -\item[On-line Documentation] -- \url{http:www.CheetahTemplate.org/learn.html} | |
| - | |
| -\item[SourceForge Project Page] -- \url{http:sf.net/projects/cheetahtemplate/} | |
| - | |
| -\item[Mailing List Subscription Page] -- | |
| - \url{http://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss} | |
| - | |
| -\item[Mailing List Archive @ Geocrawler] -- | |
| - \url{http://www.geocrawler.com/lists/3/SourceForge/12986/0/} | |
| - | |
| -\item[Mailing List Archive @ Yahoo] -- | |
| - \url{http://groups.yahoo.com/group/cheetah-archive/} | |
| - | |
| -\item[CVS Repository] -- \url{http://sourceforge.net/cvs/?group\_id=28961} | |
| - | |
| -\item[CVS-commits archive] -- | |
| - \url{http://www.geocrawler.com/lists/3/SourceForge/13091/0/} | |
| - | |
| -\end{description} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Third-party Cheetah Stuff} | |
| -\label{links.thirdParty} | |
| - | |
| -\begin{itemize} | |
| -\item Steve Howell has written a photo viewer using Python. | |
| - \url{http://mountainwebtools.com/PicViewer/install.htm} | |
| -\end{itemize} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Webware Links} | |
| -\label{links.webware} | |
| - | |
| -\begin{description} | |
| -\item[Home Page] -- \url{http://webware.sf.net/} | |
| - | |
| -\item[On-line Documentation] -- \url{http://webware.sf.net/Webware/Docs/} | |
| - | |
| -\item[SourceForge Project Page] -- \url{http://sf.net/projects/webware/} | |
| - | |
| -\item[Mailing List Subscription Page] -- | |
| - \url{http://lists.sourceforge.net/lists/listinfo/webware-discuss} | |
| - | |
| -\end{description} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Python Links} | |
| -\label{links.python} | |
| - | |
| -\begin{description} | |
| -\item[Home Page] -- \url{http://www.python.org/} | |
| -\item[On-line Documentation] -- \url{http://www.python.org/doc/} | |
| -\item[SourceForge Project Page] -- \url{http://sf.net/projects/python/} | |
| -\item[The Vaults of Parnassus: Python Resources] -- | |
| - \url{http://www.vex.net/parnassus/} | |
| -\item[Python Cookbook] -- \url{http://aspn.activestate.com/ASPN/Cookbook/Python} | |
| -\end{description} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Other Useful Links} | |
| -\label{links.other} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{Python Database Modules and Open Source Databases} | |
| -\label{links.database} | |
| - | |
| -\begin{description} | |
| -\item[Python Database Topic Guide] -- \url{http://python.org/topics/database/} | |
| -\item[PostgreSQL Database] -- \url{http://www.postgresql.org/index.html} | |
| -\item[MySQL Database] -- \url{http://www.mysql.com/} | |
| -\item[A comparison of PostgreSQL and MySQL] -- | |
| - \url{http://phpbuilder.com/columns/tim20001112.php3} | |
| -\end{description} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{Other Template Systems} | |
| -\label{links.other.templateSystems} | |
| - | |
| -\begin{description} | |
| -\item[Chuck's ``Templates'' Summary Page] -- \url{http://webware.sf.net/Papers/Templates/} | |
| -\end{description} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{Other Internet development frameworks} | |
| -\label{links.internet} | |
| - | |
| -\begin{description} | |
| -\item[ZOPE (Z Object Publishing Environment)] -- \url{http://zope.org/} | |
| -\item[Server Side Java] -- \url{http://jakarta.apache.org/} | |
| -\item[PHP] -- \url{http://php.net/} | |
| -\item[IBM Websphere] -- \url{http://www.ibm.com/websphere/} | |
| -\item[Coldfusion and Spectra] -- \url{http://www.macromedia.com/} | |
| -\end{description} | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| diff --git a/docs/users_guide_2_src/B_examples.txt b/docs/users_guide_2_src/B_examples.txt | |
| deleted file mode 100755 | |
| index 6c394fb..0000000 | |
| --- a/docs/users_guide_2_src/B_examples.txt | |
| +++ /dev/null | |
| @@ -1,24 +0,0 @@ | |
| -\section{Examples} | |
| -\label{examples} | |
| - | |
| -The Cheetah distribution comes with an 'examples' directory. Browse the | |
| -files in this directory and its subdirectories for examples of how | |
| -Cheetah can be used. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Syntax examples} | |
| -The \code{Cheetah.Tests} module contains a large number of test cases that can | |
| -double as examples of how the Cheetah Language works. To view these cases go | |
| -to the base directory of your Cheetah distribution and open the file | |
| -\code{Cheetah/Tests/SyntaxAndOutput.py} in a text editor. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Webware Examples} | |
| -For examples of Cheetah in use with Webware visit the Cheetah and Webware wikis | |
| -or use google. We used to have more examples in the cheetah source tarball, but | |
| -they were out of date and confused people. | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| diff --git a/docs/users_guide_2_src/C_comparisions.txt b/docs/users_guide_2_src/C_comparisions.txt | |
| deleted file mode 100755 | |
| index 56a0fb3..0000000 | |
| --- a/docs/users_guide_2_src/C_comparisions.txt | |
| +++ /dev/null | |
| @@ -1,451 +0,0 @@ | |
| -\section{Cheetah vs. Other Template Engines} | |
| -\label{comparisons} | |
| - | |
| -This appendix compares Cheetah with various other template/emdedded scripting | |
| -languages and Internet development frameworks. As Cheetah is similar to | |
| -Velocity at a superficial level, you may also wish to read comparisons between | |
| -Velocity and other languages at | |
| -\url{http://jakarta.apache.org/velocity/ymtd/ymtd.html}. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Which features are unique to Cheetah} | |
| -\label{comparisons.unique} | |
| - | |
| -\begin{itemize} | |
| -\item The {\bf block framework} (section \ref{inheritanceEtc.block}) | |
| -\item Cheetah's powerful yet simple {\bf caching framework} (section | |
| - \ref{output.caching}) | |
| -\item Cheetah's {\bf Unified Dotted Notation} and {\bf autocalling} | |
| - (sections \ref{language.namemapper.dict} and | |
| - \ref{language.namemapper.autocalling}) | |
| -\item Cheetah's searchList (section \ref{language.searchList}) | |
| - information. | |
| -\item Cheetah's \code{\#raw} directive (section \ref{output.raw}) | |
| -\item Cheetah's \code{\#slurp} directive (section \ref{output.slurp}) | |
| -\item Cheetah's tight integration with Webware for Python (section | |
| - \ref{webware}) | |
| -\item Cheetah's {\bf SkeletonPage framework} (section | |
| - \ref{libraries.templates.skeletonPage}) | |
| -\item Cheetah's ability to mix PSP-style code with Cheetah | |
| - Language syntax (section \ref{tips.PSP}) | |
| - Because of Cheetah's design and Python's flexibility it is | |
| - relatively easy to extend Cheetah's syntax with syntax elements from almost | |
| - any other template or embedded scripting language. | |
| -\end{itemize} | |
| - | |
| -%% @@MO: What about the new features we've been adding? | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Cheetah vs. Velocity} | |
| -\label{comparisons.velocity} | |
| - | |
| -For a basic introduction to Velocity, visit | |
| -\url{http://jakarta.apache.org/velocity}. | |
| - | |
| -Velocity is a Java template engine. It's older than Cheetah, has a larger user | |
| -base, and has better examples and docs at the moment. Cheetah, however, has a | |
| -number of advantages over Velocity: | |
| -\begin{itemize} | |
| -\item Cheetah is written in Python. Thus, it's easier to use and extend. | |
| -\item Cheetah's syntax is closer to Python's syntax than Velocity's is to | |
| -Java's. | |
| -\item Cheetah has a powerful caching mechanism. Velocity has no equivalent. | |
| -\item It's far easier to add data/objects into the namespace where \$placeholder | |
| - values are extracted from in Cheetah. Velocity calls this namespace a 'context'. | |
| - Contexts are dictionaries/hashtables. You can put anything you want into a | |
| - context, BUT you have to use the .put() method to populate the context; | |
| - e.g., | |
| - | |
| -\begin{verbatim} | |
| -VelocityContext context1 = new VelocityContext(); | |
| -context1.put("name","Velocity"); | |
| -context1.put("project", "Jakarta"); | |
| -context1.put("duplicate", "I am in context1"); | |
| -\end{verbatim} | |
| - | |
| - Cheetah takes a different approach. Rather than require you to manually | |
| - populate the 'namespace' like Velocity, Cheetah will accept any existing | |
| - Python object or dictionary AS the 'namespace'. Furthermore, Cheetah | |
| - allows you to specify a list namespaces that will be searched in sequence | |
| - to find a varname-to-value mapping. This searchList can be extended at | |
| - run-time. | |
| - | |
| - If you add a `foo' object to the searchList and the `foo' has an attribute | |
| - called 'bar', you can simply type \code{\$bar} in the template. If the | |
| - second item in the searchList is dictionary 'foofoo' containing | |
| - \code{\{'spam':1234, 'parrot':666\}}, Cheetah will first look in the `foo' | |
| - object for a `spam' attribute. Not finding it, Cheetah will then go to | |
| - `foofoo' (the second element in the searchList) and look among its | |
| - dictionary keys for `spam'. Finding it, Cheetah will select | |
| - \code{foofoo['spam']} as \code{\$spam}'s value. | |
| - | |
| -\item In Cheetah, the tokens that are used to signal the start of | |
| - \$placeholders and \#directives are configurable. You can set them to any | |
| - character sequences, not just \$ and \#. | |
| -\end{itemize} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Cheetah vs. WebMacro} | |
| -\label{comparisons.webmacro} | |
| - | |
| -For a basic introduction to WebMacro, visit | |
| -\url{http://webmacro.org}. | |
| - | |
| -The points discussed in section \ref{comparisons.velocity} also apply to the | |
| -comparison between Cheetah and WebMacro. For further differences please refer | |
| -to \url{http://jakarta.apache.org/velocity/differences.html}. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Cheetah vs. Zope's DTML} | |
| -\label{comparisons.dtml} | |
| - | |
| -For a basic introduction to DTML, visit | |
| -\url{http://www.zope.org/Members/michel/ZB/DTML.dtml}. | |
| - | |
| -\begin{itemize} | |
| -\item Cheetah is faster than DTML. | |
| -\item Cheetah does not use HTML-style tags; DTML does. Thus, Cheetah tags are | |
| - visible in rendered HTML output if something goes wrong. | |
| -\item DTML can only be used with ZOPE for web development; Cheetah can be | |
| - used as a standalone tool for any purpose. | |
| -\item Cheetah's documentation is more complete than DTML's. | |
| -\item Cheetah's learning curve is shorter than DTML's. | |
| -\item DTML has no equivalent of Cheetah's blocks, caching framework, | |
| - unified dotted notation, and \code{\#raw} directive. | |
| -\end{itemize} | |
| - | |
| -Here are some examples of syntax differences between DTML and Cheetah: | |
| -\begin{verbatim} | |
| -<ul> | |
| -<dtml-in frogQuery> | |
| - <li><dtml-var animal_name></li> | |
| -</dtml-in> | |
| -</ul> | |
| -\end{verbatim} | |
| - | |
| -\begin{verbatim} | |
| -<ul> | |
| -#for $animal_name in $frogQuery | |
| - <li>$animal_name</li> | |
| -#end for | |
| -</ul> | |
| -\end{verbatim} | |
| - | |
| -\begin{verbatim} | |
| -<dtml-if expr="monkeys > monkey_limit"> | |
| - <p>There are too many monkeys!</p> | |
| -<dtml-elif expr="monkeys < minimum_monkeys"> | |
| - <p>There aren't enough monkeys!</p> | |
| -<dtml-else> | |
| - <p>There are just enough monkeys.</p> | |
| -</dtml-if> | |
| -\end{verbatim} | |
| - | |
| -\begin{verbatim} | |
| -#if $monkeys > $monkey_limit | |
| - <p>There are too many monkeys!</p> | |
| -#else if $monkeys < $minimum_monkeys | |
| - <p>There aren't enough monkeys!</p> | |
| -#else | |
| - <p>There are just enough monkeys.</p> | |
| -#end if | |
| -\end{verbatim} | |
| - | |
| -\begin{verbatim} | |
| -<table> | |
| -<dtml-in expr="objectValues('File')"> | |
| - <dtml-if sequence-even> | |
| - <tr bgcolor="grey"> | |
| - <dtml-else> | |
| - <tr> | |
| - </dtml-if> | |
| - <td> | |
| - <a href="&dtml-absolute_url;"><dtml-var title_or_id></a> | |
| - </td></tr> | |
| -</dtml-in> | |
| -</table> | |
| -\end{verbatim} | |
| - | |
| -\begin{verbatim} | |
| -<table> | |
| -#set $evenRow = 0 | |
| -#for $file in $files('File') | |
| - #if $evenRow | |
| - <tr bgcolor="grey"> | |
| - #set $evenRow = 0 | |
| - #else | |
| - <tr> | |
| - #set $evenRow = 1 | |
| - #end if | |
| - <td> | |
| - <a href="$file.absolute_url">$file.title_or_id</a> | |
| - </td></tr> | |
| -#end for | |
| -</table> | |
| -\end{verbatim} | |
| - | |
| -The last example changed the name of \code{\$objectValues} to | |
| -\code{\$files} because that's what a Cheetah developer would write. | |
| -The developer would be responsible for ensuring \code{\$files} returned a | |
| -list (or tuple) of objects (or dictionaries) containing the attributes (or | |
| -methods or dictionary keys) `absolute\_url' and `title\_or\_id'. All these | |
| -names (`objectValues', `absolute\_url' and `title\_or\_id') are standard parts | |
| -of Zope, but in Cheetah the developer is in charge of writing them and giving | |
| -them a reasonable behaviour. | |
| - | |
| -Some of DTML's features are being ported to Cheetah, such as | |
| -\code{Cheetah.Tools.MondoReport}, which is based on the | |
| -\code{<dtml-in>} tag. We are also planning an output filter as flexible as | |
| -the \code{<dtml-var>} formatting options. However, neither of these are | |
| -complete yet. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Cheetah vs. Zope Page Templates} | |
| -\label{comparisons.zpt} | |
| - | |
| -For a basic introduction to Zope Page Templates, please visit | |
| -\url{http://www.zope.org/Documentation/Articles/ZPT2}. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Cheetah vs. PHP's Smarty templates} | |
| -\label{comparisons.smarty} | |
| - | |
| -PHP (\url{http://www.php.net/}) is one of the few scripting languages | |
| -expressly designed for web servlets. However, it's also a full-fledged | |
| -programming language with libraries similar to Python's and Perl's. The | |
| -syntax and functions are like a cross between Perl and C plus some original | |
| -ideas (e.g.; a single array type serves as both a list and a dictionary, | |
| -\verb+$arr[]="value";+ appends to an array). | |
| - | |
| -Smarty (\url{http://smarty.php.net/}) is an advanced template engine for | |
| -PHP. ({\em Note:} this comparision is based on Smarty's on-line documentation. | |
| -The author has not used Smarty. Please send corrections or ommissions to the | |
| -Cheetah mailing list.) Like Cheetah, Smarty: | |
| - | |
| -\begin{itemize} | |
| -\item compiles to the target programming language (PHP). | |
| -\item has configurable delimeters. | |
| -\item passes if-blocks directly to PHP, so you can use any PHP expression in | |
| -them. | |
| -\item allows you to embed PHP code in a template. | |
| -\item has a caching framework (although it works quite differently). | |
| -\item can read the template definition from any arbitrary source. | |
| -\end{itemize} | |
| - | |
| -Features Smarty has that Cheetah lacks: | |
| -\begin{itemize} | |
| -\item Preprocessors, postprocessors and output filters. You can emulate a | |
| -preprocessor in Cheetah by running your template definition through a filter | |
| -program or function before Cheetah sees it. To emulate a postprocessor, run a | |
| -.py template module through a filter program/function. To emulate a Smarty | |
| -output filter, run the template output through a filter program/function. If | |
| -you want to use ``cheetah compile'' or ``cheetah fill'' in a pipeline, use | |
| -\code{-} as the input file name and \code{--stdout} to send the result to | |
| -standard output. Note that Cheetah uses the term ``output filter'' differently | |
| -than Smarty: Cheetah output filters (\code{\#filter}) operate on placeholders, | |
| -while Smarty output filters operate on the entire template output. There has | |
| -been a proposed \code{\#sed} directive that would operate on the entire output | |
| -line by line, but it has not been implemented. | |
| -\item Variable modifiers. In some cases, Python has equivalent string | |
| -methods (\code{.strip}, \code{.capitalize}, \code{.replace(SEARCH, REPL)}), | |
| -but in other cases you must wrap the result in a function call or write | |
| -a custom output filter (\code{\#filter}). | |
| -\item Certain web-specific functions, which can be emulated with | |
| -third-party functions. | |
| -\item The ability to ``plug in'' new directives in a modular way. Cheetah | |
| -directives are tightly bound to the compiler. However, third-party | |
| -{\em functions} can be freely imported and called from placeholders, and | |
| -{\em methods} can be mixed in via \code{\#extends}. Part of this is | |
| -because Cheetah distinguishes between functions and directives, while | |
| -Smarty treats them all as ``functions''. Cheetah's design does not | |
| -allow functions to have flow control effect outside the function | |
| -(e.g., \code{\#if} and \code{\#for}, which operate on template body lines), | |
| -so directives like these cannot be encoded as functions. | |
| -\item Configuration variables read from an .ini-style file. The | |
| -\code{Cheetah.SettingsManager} module can parse such a file, but you'd | |
| -have to invoke it manually. (See the docstrings in the module for | |
| -details.) In Smarty, this feature is used for | |
| -multilingual applications. In Cheetah, the developers maintain that everybody | |
| -has their own preferred way to do this (such as using Python's \code{gettext} | |
| -module), and it's not worth blessing one particular strategy in Cheetah since | |
| -it's easy enough to integrate third-party code around the template, or to add | |
| -the resulting values to the searchList. | |
| -\end{itemize} | |
| - | |
| -Features Cheetah has that Smarty lacks: | |
| -\begin{itemize} | |
| -\item Saving the compilation result in a Python (PHP) module for quick | |
| -reading later. | |
| -\item Caching individual placeholders or portions of a template. Smarty | |
| -caches only the entire template output as a unit. | |
| -\end{itemize} | |
| - | |
| -Comparisions of various Smarty constructs: | |
| -\begin{verbatim} | |
| -{assign var="name" value="Bob"} (#set has better syntax in the author's opinion) | |
| -counter (looks like equivalent to #for) | |
| -eval (same as #include with variable) | |
| -fetch: insert file content into output (#include raw) | |
| -fetch: insert URL content into output (no euqivalent, user can write | |
| - function calling urllib, call as $fetchURL('URL') ) | |
| -fetch: read file into variable (no equivalent, user can write function | |
| - based on the 'open/file' builtin, or on .getFileContents() in | |
| - Template.) | |
| -fetch: read URL content into variable (no equivalent, use above | |
| - function and call as: #set $var = $fetchURL('URL') | |
| -html_options: output an HTML option list (no equivalent, user can | |
| - write custom function. Maybe FunFormKit can help.) | |
| -html_select_date: output three dropdown controls to specify a date | |
| - (no equivalent, user can write custom function) | |
| -html_select_time: output four dropdown controls to specify a time | |
| - (no equvalent, user can write custom function) | |
| -math: eval calculation and output result (same as #echo) | |
| -math: eval calculation and assign to variable (same as #set) | |
| -popup_init: library for popup windows (no equivalent, user can write | |
| - custom method outputting Javascript) | |
| - | |
| - | |
| -Other commands: | |
| -capture (no equivalent, collects output into variable. A Python | |
| - program would create a StringIO instance, set sys.stdout to | |
| - it temporarily, print the output, set sys.stdout back, then use | |
| - .getvalue() to get the result.) | |
| -config_load (roughly analagous to #settings, which was removed | |
| - from Cheetah. Use Cheetah.SettingsManager manually or write | |
| - a custom function.) | |
| -include (same as #include, but can include into variable. | |
| - Variables are apparently shared between parent and child.) | |
| -include_php: include a PHP script (e.g., functions) | |
| - (use #extends or #import instead) | |
| -insert (same as #include not in a #cache region) | |
| -{ldelim}{rdelim} (escape literal $ and # with a backslash, | |
| - use #compiler-settings to change the delimeters) | |
| -literal (#raw) | |
| -php (``<% %>'' tags) | |
| -section (#for $i in $range(...) ) | |
| -foreach (#for) | |
| -strip (like the #sed tag which was never implemented. Strips | |
| - leading/trailing whitespace from lines, joins several lines | |
| - together.) | |
| - | |
| - | |
| -Variable modifiers: | |
| -capitalize ( $STRING.capitalize() ) | |
| -count_characters ( $len(STRING) ) | |
| -count_paragraphs/sentances/words (no equivalent, user can write function) | |
| -date_format (use 'time' module or download Egenix's mx.DateTime) | |
| -default ($getVar('varName', 'default value') ) | |
| -escape: html encode ($cgi.escape(VALUE) ) | |
| -escape: url encode ($urllib.quote_plus(VALUE) ) | |
| -escape: hex encode (no equivalent? user can write function) | |
| -escape: hex entity encode (no equivalent? user can write function) | |
| -indent: indent all lines of a var's output (may be part of future | |
| - #indent directive) | |
| -lower ($STRING.lower() ) | |
| -regex_replace ('re' module) | |
| -replace ($STRING.replace(OLD, NEW, MAXSPLIT) ) | |
| -spacify (#echo "SEPARATOR".join(SEQUENCE) ) | |
| -string_format (#echo "%.2f" % FLOAT , etc.) | |
| -strip_tags (no equivalent, user can write function to strip HTML tags, | |
| - or customize the WebSafe filter) | |
| -truncate (no equivalent, user can write function) | |
| -upper ($STRING.upper() ) | |
| -wordwrap ('writer' module, or a new module coming in Python 2.3) | |
| -\end{verbatim} | |
| - | |
| -Some of these modifiers could be added to the super output filter we | |
| -want to write someday. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Cheetah vs. PHPLib's Template class} | |
| -\label{comparisons.php} | |
| - | |
| -PHPLib (\url(http://phplib.netuse.de/) is a collection of classes for various | |
| -web objects (authentication, shopping cart, sessions, etc), but what we're | |
| -interested in is the \code{Template} object. It's much more primitive than | |
| -Smarty, and was based on an old Perl template class. In fact, one of the | |
| -precursors to Cheetah was based on it too. Differences from Cheetah: | |
| - | |
| -\begin{itemize} | |
| -\item Templates consist of text with \code{\{placeholders\}} in braces. | |
| -\item Instead of a searchList, there is one flat namespace. Every variable | |
| - must be assigned via the \code{set\_var} method. However, you can pass | |
| - this method an array (dictionary) of several variables at once. | |
| -\item You cannot embed lookups or calculations into the template. Every | |
| - placeholder must be an exact variable name. | |
| -\item There are no directives. You must do all display logic (if, for, etc) | |
| - in the calling routine. | |
| -\item There is, however, a ``block'' construct. A block is a portion of text | |
| - between the comment markers \code{<!-- BEGIN blockName --> \ldots | |
| - <!-- END blockName>}. The \code{set\_block} method extracts this text | |
| - into a namespace variable and puts a placeholder referring to it in the | |
| - template. This has a few parallels with Cheetah's \code{\#block} | |
| - directive but is overall quite different. | |
| -\item To do the equivalent of \code{\#if}, extract the block. Then if true, do | |
| - nothing. If false, assign the empty string to the namespace variable. | |
| -\item To do the equivalent of \code{\#for}, extract the block. Set any | |
| - namespace variables needed inside the loop. To parse one iteration, use | |
| - the \code{parse} method to fill the block variable (a mini-template) into | |
| - another namespace variable, appending to it. Refresh the namespace | |
| - variables needed inside the loop and parse again; repeat for each | |
| - iteration. You'll end up with a mini-result that will be plugged into the | |
| - main template's placeholder. | |
| -\item To read a template definition from a file, use the \code{set\_file} | |
| - method. This places the file's content in a namespace variable. | |
| - To read a template definition from a string, assign it to a namespace | |
| - variable. | |
| -\item Thus, for complicated templates, you are doing a lot of recursive block | |
| - filling and file reading and parsing mini-templates all into one flat | |
| - namespace as you finally build up values for the main template. In | |
| - Cheetah, all this display logic can be embedded into the template using | |
| - directives, calling out to Python methods for the more complicated tasks. | |
| -\item Although you can nest blocks in the template, it becomes tedious and | |
| - arguably hard to read, because all blocks have identical syntax. Unless | |
| - you choose your block names carefully and put comments around them, it's | |
| - hard to tell which blocks are if-blocks and which are for-blocks, or what | |
| - their nesting order is. | |
| -\item PHPLib templates do not have caching, output filters, etc. | |
| -\end{itemize} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Cheetah vs. PSP, PHP, ASP, JSP, Embperl, etc.} | |
| -\label{comparisons.pspEtc} | |
| - | |
| -\begin{description} | |
| -\item[Webware's PSP Component] -- \url{http://webware.sourceforge.net/Webware/PSP/Docs/} | |
| -\item[Tomcat JSP Information] -- \url{http://jakarta.apache.org/tomcat/index.html} | |
| -\item[ASP Information at ASP101] -- \url{http://www.asp101.com/} | |
| -\item[Embperl] -- \url{http://perl.apache.org/embperl/} | |
| -\end{description} | |
| - | |
| - | |
| -Here's a basic Cheetah example: | |
| -\begin{verbatim} | |
| -<TABLE> | |
| -#for $client in $service.clients | |
| -<TR> | |
| -<TD>$client.surname, $client.firstname</TD> | |
| -<TD><A HREF="mailto:$client.email" >$client.email</A></TD> | |
| -</TR> | |
| -#end for | |
| -</TABLE> | |
| -\end{verbatim} | |
| - | |
| -Compare this with PSP: | |
| - | |
| -\begin{verbatim} | |
| -<TABLE> | |
| -<% for client in service.clients(): %> | |
| -<TR> | |
| -<TD><%=client.surname()%>, <%=client.firstname()%></TD> | |
| -<TD><A HREF="mailto:<%=client.email()%>"><%=client.email()%></A></TD> | |
| -</TR> | |
| -<%end%> | |
| -</TABLE> | |
| -\end{verbatim} | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| diff --git a/docs/users_guide_2_src/E_license.txt b/docs/users_guide_2_src/E_license.txt | |
| deleted file mode 100644 | |
| index 8a5a73f..0000000 | |
| --- a/docs/users_guide_2_src/E_license.txt | |
| +++ /dev/null | |
| @@ -1,32 +0,0 @@ | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{License} | |
| -\label{intro.license} | |
| - | |
| -\paragraph*{The gist} | |
| -Cheetah is open source, but products developed with Cheetah or derived | |
| -from Cheetah may be open source or closed source. | |
| - | |
| -(@@MO If this licence is identical to the MIT license, let's say so. That will | |
| -make it easier for distributors/aggregators to classify the product.) | |
| - | |
| -\paragraph*{Legal terms} | |
| -Copyright \copyright 2001-2006, The Cheetah Development Team: Tavis Rudd, Mike | |
| -Orr, Ian Bicking, Chuck Esterbrook, JJ Behrens. | |
| - | |
| -(@@MO Who is the current development team? Chuck and Ian have not been major | |
| -contributors for years. However, some of their code may remain in Cheetah.) | |
| - | |
| -Permission to use, copy, modify, and distribute this software for any purpose | |
| -and without fee is hereby granted, provided that the above copyright notice | |
| -appear in all copies and that both that copyright notice and this permission | |
| -notice appear in supporting documentation, and that the names of the authors not | |
| -be used in advertising or publicity pertaining to distribution of the software | |
| -without specific, written prior permission. | |
| - | |
| -THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL | |
| -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS | |
| -BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF | |
| -CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION | |
| -WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
| - | |
| diff --git a/docs/users_guide_2_src/Makefile b/docs/users_guide_2_src/Makefile | |
| deleted file mode 100644 | |
| index ad0b786..0000000 | |
| --- a/docs/users_guide_2_src/Makefile | |
| +++ /dev/null | |
| @@ -1,16 +0,0 @@ | |
| -RST = rst2html.py --stylesheet=default.css --link-stylesheet --initial-header-level=2 | |
| - | |
| -#%.html: %.txt | |
| -# ${RST} $< $@ | |
| - | |
| -all: | |
| - #${RST} --warnings=/dev/null index.txt index.html | |
| - ${RST} 01_introduction.txt 01_introduction.html | |
| - ${RST} 02_glossary.txt 02_glossary.html | |
| - ${RST} 03_gettingStarted.txt 03_gettingStarted.html | |
| - ${RST} 04_howItWorks.txt 04_howItWorks.html | |
| - ${RST} 04_howItWorks.txt 04_howItWorks.html | |
| - ${RST} 13a_precompiledTemplateModules.txt 13a_precompiledTemplateModules.html | |
| - | |
| - | |
| -# vim: sw=8 ts=8 noexpandtab ai | |
| diff --git a/docs/users_guide_2_src/default.css b/docs/users_guide_2_src/default.css | |
| deleted file mode 100644 | |
| index fa715d6..0000000 | |
| --- a/docs/users_guide_2_src/default.css | |
| +++ /dev/null | |
| @@ -1,293 +0,0 @@ | |
| -/* BEGIN Cheetah additions. *********************************** */ | |
| - | |
| -body { | |
| - /* font-size: 10pt; */ | |
| -} | |
| - | |
| -blockquote { | |
| - font-family: sans-serif; | |
| -} | |
| - | |
| -li { | |
| - margin-bottom: 1em; | |
| -} | |
| - | |
| -/* END Cheetah additions. ************************************ */ | |
| - | |
| -/* | |
| -:Author: David Goodger | |
| -:Contact: goodger@users.sourceforge.net | |
| -:Date: $Date: 2006/02/20 07:38:08 $ | |
| -:Revision: $Revision: 1.1 $ | |
| -:Copyright: This stylesheet has been placed in the public domain. | |
| - | |
| -Default cascading style sheet for the HTML output of Docutils. | |
| - | |
| -See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to | |
| -customize this style sheet. | |
| -*/ | |
| - | |
| -/* "! important" is used here to override other ``margin-top`` and | |
| - ``margin-bottom`` styles that are later in the stylesheet or | |
| - more specific. See http://www.w3.org/TR/CSS1#the-cascade */ | |
| -.first { | |
| - margin-top: 0 ! important } | |
| - | |
| -.last, .with-subtitle { | |
| - margin-bottom: 0 ! important } | |
| - | |
| -.hidden { | |
| - display: none } | |
| - | |
| -a.toc-backref { | |
| - text-decoration: none ; | |
| - color: black } | |
| - | |
| -blockquote.epigraph { | |
| - margin: 2em 5em ; } | |
| - | |
| -dl.docutils dd { | |
| - margin-bottom: 0.5em } | |
| - | |
| -dl.docutils dt { | |
| - font-weight: bold } | |
| - | |
| -div.abstract { | |
| - margin: 2em 5em } | |
| - | |
| -div.abstract p.topic-title { | |
| - font-weight: bold ; | |
| - text-align: center } | |
| - | |
| -div.admonition, div.attention, div.caution, div.danger, div.error, | |
| -div.hint, div.important, div.note, div.tip, div.warning { | |
| - margin: 2em ; | |
| - border: medium outset ; | |
| - padding: 1em } | |
| - | |
| -div.admonition p.admonition-title, div.hint p.admonition-title, | |
| -div.important p.admonition-title, div.note p.admonition-title, | |
| -div.tip p.admonition-title { | |
| - font-weight: bold ; | |
| - font-family: sans-serif } | |
| - | |
| -div.attention p.admonition-title, div.caution p.admonition-title, | |
| -div.danger p.admonition-title, div.error p.admonition-title, | |
| -div.warning p.admonition-title { | |
| - color: red ; | |
| - font-weight: bold ; | |
| - font-family: sans-serif } | |
| - | |
| -/* Uncomment (and remove this text!) to get reduced vertical space in | |
| - compound paragraphs. | |
| -div.compound .compound-first, div.compound .compound-middle { | |
| - margin-bottom: 0.5em } | |
| - | |
| -div.compound .compound-last, div.compound .compound-middle { | |
| - margin-top: 0.5em } | |
| -*/ | |
| - | |
| -div.dedication { | |
| - margin: 2em 5em ; | |
| - text-align: center ; | |
| - font-style: italic } | |
| - | |
| -div.dedication p.topic-title { | |
| - font-weight: bold ; | |
| - font-style: normal } | |
| - | |
| -div.figure { | |
| - margin-left: 2em } | |
| - | |
| -div.footer, div.header { | |
| - clear: both; | |
| - font-size: smaller } | |
| - | |
| -div.line-block { | |
| - display: block ; | |
| - margin-top: 1em ; | |
| - margin-bottom: 1em } | |
| - | |
| -div.line-block div.line-block { | |
| - margin-top: 0 ; | |
| - margin-bottom: 0 ; | |
| - margin-left: 1.5em } | |
| - | |
| -div.sidebar { | |
| - margin-left: 1em ; | |
| - border: medium outset ; | |
| - padding: 1em ; | |
| - background-color: #ffffee ; | |
| - width: 40% ; | |
| - float: right ; | |
| - clear: right } | |
| - | |
| -div.sidebar p.rubric { | |
| - font-family: sans-serif ; | |
| - font-size: medium } | |
| - | |
| -div.system-messages { | |
| - margin: 5em } | |
| - | |
| -div.system-messages h1 { | |
| - color: red } | |
| - | |
| -div.system-message { | |
| - border: medium outset ; | |
| - padding: 1em } | |
| - | |
| -div.system-message p.system-message-title { | |
| - color: red ; | |
| - font-weight: bold } | |
| - | |
| -div.topic { | |
| - margin: 2em } | |
| - | |
| -h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, | |
| -h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { | |
| - margin-top: 0.4em } | |
| - | |
| -h1.title { | |
| - text-align: center } | |
| - | |
| -h2.subtitle { | |
| - text-align: center } | |
| - | |
| -hr.docutils { | |
| - width: 75% } | |
| - | |
| -img.align-left { | |
| - clear: left } | |
| - | |
| -img.align-right { | |
| - clear: right } | |
| - | |
| -img.borderless { | |
| - border: 0 } | |
| - | |
| -ol.simple, ul.simple { | |
| - margin-bottom: 1em } | |
| - | |
| -ol.arabic { | |
| - list-style: decimal } | |
| - | |
| -ol.loweralpha { | |
| - list-style: lower-alpha } | |
| - | |
| -ol.upperalpha { | |
| - list-style: upper-alpha } | |
| - | |
| -ol.lowerroman { | |
| - list-style: lower-roman } | |
| - | |
| -ol.upperroman { | |
| - list-style: upper-roman } | |
| - | |
| -p.attribution { | |
| - text-align: right ; | |
| - margin-left: 50% } | |
| - | |
| -p.caption { | |
| - font-style: italic } | |
| - | |
| -p.credits { | |
| - font-style: italic ; | |
| - font-size: smaller } | |
| - | |
| -p.label { | |
| - white-space: nowrap } | |
| - | |
| -p.rubric { | |
| - font-weight: bold ; | |
| - font-size: larger ; | |
| - color: maroon ; | |
| - text-align: center } | |
| - | |
| -p.sidebar-title { | |
| - font-family: sans-serif ; | |
| - font-weight: bold ; | |
| - font-size: larger } | |
| - | |
| -p.sidebar-subtitle { | |
| - font-family: sans-serif ; | |
| - font-weight: bold } | |
| - | |
| -p.topic-title { | |
| - font-weight: bold } | |
| - | |
| -pre.address { | |
| - margin-bottom: 0 ; | |
| - margin-top: 0 ; | |
| - font-family: serif ; | |
| - font-size: 100% } | |
| - | |
| -pre.line-block { | |
| - font-family: serif ; | |
| - font-size: 100% } | |
| - | |
| -pre.literal-block, pre.doctest-block { | |
| - margin-left: 2em ; | |
| - margin-right: 2em ; | |
| - background-color: #eeeeee } | |
| - | |
| -span.classifier { | |
| - font-family: sans-serif ; | |
| - font-style: oblique } | |
| - | |
| -span.classifier-delimiter { | |
| - font-family: sans-serif ; | |
| - font-weight: bold } | |
| - | |
| -span.interpreted { | |
| - font-family: sans-serif } | |
| - | |
| -span.option { | |
| - white-space: nowrap } | |
| - | |
| -span.pre { | |
| - white-space: pre } | |
| - | |
| -span.problematic { | |
| - color: red } | |
| - | |
| -span.section-subtitle { | |
| - /* font-size relative to parent (h1..h6 element) */ | |
| - font-size: 80% } | |
| - | |
| -table.citation { | |
| - border-left: solid thin gray } | |
| - | |
| -table.docinfo { | |
| - margin: 2em 4em } | |
| - | |
| -table.docutils { | |
| - margin-top: 0.5em ; | |
| - margin-bottom: 0.5em } | |
| - | |
| -table.footnote { | |
| - border-left: solid thin black } | |
| - | |
| -table.docutils td, table.docutils th, | |
| -table.docinfo td, table.docinfo th { | |
| - padding-left: 0.5em ; | |
| - padding-right: 0.5em ; | |
| - vertical-align: top } | |
| - | |
| -table.docutils th.field-name, table.docinfo th.docinfo-name { | |
| - font-weight: bold ; | |
| - text-align: left ; | |
| - white-space: nowrap ; | |
| - padding-left: 0 } | |
| - | |
| -h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, | |
| -h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { | |
| - font-size: 100% } | |
| - | |
| -tt.docutils { | |
| - background-color: #eeeeee } | |
| - | |
| -ul.auto-toc { | |
| - list-style-type: none } | |
| - | |
| - | |
| -/* vim: sw=4 ts=4 expandtab ai */ | |
| diff --git a/docs/users_guide_2_src/eg_1.py b/docs/users_guide_2_src/eg_1.py | |
| deleted file mode 100644 | |
| index 8098e6b..0000000 | |
| --- a/docs/users_guide_2_src/eg_1.py | |
| +++ /dev/null | |
| @@ -1,11 +0,0 @@ | |
| -#eg_1 | |
| -# | |
| -#Looking up values held in dictionaries. | |
| -#No need to use all values in searchlist. | |
| - | |
| -from Cheetah.Template import Template | |
| -tmpl = "$value1 $value2 $value3" | |
| -NS = [{'value1':1, 'value2':2}, {'value3':3},{'value4':4}] | |
| -T = Template.compile(source=tmpl) | |
| -t = T(namespaces=NS) | |
| -print t.respond() #1,2,3 | |
| diff --git a/docs/users_guide_2_src/eg_2.py b/docs/users_guide_2_src/eg_2.py | |
| deleted file mode 100644 | |
| index ee0f7a7..0000000 | |
| --- a/docs/users_guide_2_src/eg_2.py | |
| +++ /dev/null | |
| @@ -1,10 +0,0 @@ | |
| -from Cheetah.Template import Template | |
| - | |
| -#A retrieved value can be any Python object and can be used _exactly_ | |
| -#as it would be in Python code | |
| - | |
| -tmpl = "$value1, $value2, $value3[0], $value3[1], $value4[0]['this'][0]" | |
| -NS = [{'value1':1, 'value2':2, 'value3':[3,4], 'value4': [ {'this':[5]}]} ] | |
| -#Compile and fill template in one step | |
| -t = Template.compile(source=tmpl)(namespaces=NS) | |
| -print t.respond() #1, 2, 3, 4, 5 | |
| diff --git a/docs/users_guide_2_src/eg_3.py b/docs/users_guide_2_src/eg_3.py | |
| deleted file mode 100644 | |
| index 5c89a65..0000000 | |
| --- a/docs/users_guide_2_src/eg_3.py | |
| +++ /dev/null | |
| @@ -1,18 +0,0 @@ | |
| -from Cheetah.Template import Template | |
| - | |
| -#The namespaces list is a list of dictionaries and/or | |
| -#class instances. Search is for dictionary key or object | |
| -#attributes in this list | |
| -class X: | |
| - pass | |
| - | |
| - | |
| -x = X() | |
| -x.value3 = 3 | |
| -x.value4 = 4 | |
| - | |
| -tmpl = "$value1, $value2, $value3, $value4" | |
| -NS = [{'value1':1},{'value2':2}, x] | |
| - | |
| -t = Template.compile(source=tmpl)(namespaces=NS) | |
| -print t.respond() #1,2,3,4 | |
| diff --git a/docs/users_guide_2_src/eg_4.py b/docs/users_guide_2_src/eg_4.py | |
| deleted file mode 100644 | |
| index 8fab657..0000000 | |
| --- a/docs/users_guide_2_src/eg_4.py | |
| +++ /dev/null | |
| @@ -1,22 +0,0 @@ | |
| -from Cheetah.Template import Template | |
| -from Cheetah import NameMapper | |
| - | |
| -#Error. Cheetah cannot find 'x' because | |
| -#it is not dictionary key or instance member: | |
| - | |
| - | |
| -class X: | |
| - pass | |
| - | |
| -x = X() | |
| -x.value3 = 3 | |
| - | |
| -tmpl = "$x.value3" | |
| -NS = [x] | |
| -t = Template.compile(source=tmpl)(namespaces=NS) | |
| -try: | |
| - t.respond() #Here substitution is attempted | |
| -except NameMapper.NotFound, e: | |
| - print 'NameMapper.NotFound: %s' % e | |
| - #NameMapper.NotFound: cannot find 'x' | |
| - | |
| diff --git a/docs/users_guide_2_src/eg_5.py b/docs/users_guide_2_src/eg_5.py | |
| deleted file mode 100644 | |
| index 551f9c0..0000000 | |
| --- a/docs/users_guide_2_src/eg_5.py | |
| +++ /dev/null | |
| @@ -1,25 +0,0 @@ | |
| -from Cheetah.Template import Template | |
| - | |
| -# ways of using Python to process values after | |
| -#retrieval. 1. Sets a new variable then uses it, | |
| -#2. Uses pure Python function to set new variable | |
| -#3. Cheetah calls function directly | |
| -#4. Extended ${} syntax without function call | |
| - | |
| -tmpl = """ | |
| - | |
| -#set $value1 = $value.replace(' ','-') | |
| -1. $value1 | |
| -<% def change(x): | |
| - return x.replace(' ','-') | |
| -%> | |
| -#set $value1 = change($value) | |
| -2. $value1 | |
| -3. $change($value) | |
| -4. ${value.replace(' ','-')} | |
| -""" | |
| -NS = [ {'value':'this and that'}] | |
| - | |
| -#compile and fill the template | |
| -t = Template(source=tmpl, namespaces=NS) | |
| -print t.respond() | |
| diff --git a/docs/users_guide_2_src/latex2rst.py b/docs/users_guide_2_src/latex2rst.py | |
| deleted file mode 100755 | |
| index 80f9a1d..0000000 | |
| --- a/docs/users_guide_2_src/latex2rst.py | |
| +++ /dev/null | |
| @@ -1,45 +0,0 @@ | |
| -#!/usr/bin/env python | |
| -"""Convert files from LaTeX format to ReStructured Text. | |
| - | |
| - This converter is meant only for saving keystrokes. It won't catch | |
| - everything and it may misformat stuff, so proofread the file after | |
| - processing. | |
| - | |
| - "Verbatim" blocks are not converted due to the difficulty in placing the | |
| - preceding colon(s) and indenting every line. | |
| -""" | |
| -import os, re, shutil, sys | |
| - | |
| -def convert(filename): | |
| - print "Processing file", filename | |
| - backup = filename + ".bak" | |
| - shutil.copy2(filename, backup) | |
| - f = open(filename, 'r+') | |
| - text = f.read() | |
| - text = re.sub( R"%%%+", R"", text) | |
| - text = re.sub( R"\\section\{(.*?)\}", R"\1\n" + ("=" * 40), text) | |
| - text = re.sub( R"\\subsection\{(.*?)\}", R"\1\n" + ("-" * 40), text) | |
| - text = re.sub( R"\\label\{(.*?)\}", R"\n..\n :label: \1", text) | |
| - text = re.sub( R"``|''", R'"', text) | |
| - text = re.sub( R"(?s)\{\\em (.*?)\}", R"*\1*", text) | |
| - text = re.sub( R"(?s)\{\\bf (.*?)\}", R"**\1**", text) | |
| - text = re.sub( R"(?s)\\code\{(.*?)\}", R"``\1``", text) | |
| - text = re.sub( R"\\(begin|end)\{(itemize|enumerate)\}\n", R"", text) | |
| - text = re.sub( R"\\item ", R"* ", text) | |
| - #text = re.sub( | |
| - # R"(?sm)(\w):\n\s*^\\begin\{verbatim\}\s*(.*?)\\end\{verbatim\}", | |
| - # R"\1::\n\n\2", text) | |
| - f.seek(0) | |
| - f.write(text) | |
| - f.truncate() | |
| - f.close() | |
| - | |
| - | |
| -def main(): | |
| - if len(sys.argv) < 2: | |
| - prog = os.path.basename(sys.argv[0]) | |
| - raise SystemExit("usage: %s FILENAMES ..." % prog) | |
| - for filename in sys.argv[1:]: | |
| - convert(filename) | |
| - | |
| -if __name__ == "__main__": main() | |
| diff --git a/docs/users_guide_2_src/unused.txt b/docs/users_guide_2_src/unused.txt | |
| deleted file mode 100644 | |
| index 3b78fc9..0000000 | |
| --- a/docs/users_guide_2_src/unused.txt | |
| +++ /dev/null | |
| @@ -1,67 +0,0 @@ | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Give me an example of a Webware servlet!} | |
| -\label{intro.example.servlet} | |
| - | |
| -This example uses an HTML form to ask the user's name, then invokes itself | |
| -again to display a {\em personalized} friendly greeting. | |
| - | |
| -\begin{verbatim} | |
| -<HTML><HEAD><TITLE>My Template-Servlet</TITLE></HEAD><BODY> | |
| -#set $name = $request.field('name', None) | |
| -#if $name | |
| -Hello $name | |
| -#else | |
| -<FORM ACTION="" METHOD="GET"> | |
| -Name: <INPUT TYPE="text" NAME="name"><BR> | |
| -<INPUT TYPE="submit"> | |
| -</FORM> | |
| -#end if | |
| -</BODY></HTML> | |
| -\end{verbatim} | |
| - | |
| -To try it out for yourself on a Webware system: | |
| -\begin{enumerate} | |
| -\item copy the template definition to a file {\bf test.tmpl} in your | |
| - Webware servlet directory. | |
| -\item Run ``\code{cheetah compile test.tmpl}''. This produces | |
| - {\bf test.py} (a .py template module) in the same directory. | |
| -\item In your web browser, go to {\bf test.py}, using whatever site and | |
| - directory is appropriate. Depending on your Webware configuration, you may | |
| - also be able to go to {\bf test}. | |
| -\end{enumerate} | |
| - | |
| -At the first request, field `name' will be blank (false) so the ``\#else'' | |
| -portion will execute and present a form. You type your name and press submit. | |
| -The form invokes the same page. Now `name' is true so the ``\#if'' portion | |
| -executes, which displays the greeting. The ``\#set'' directive creates a | |
| -local variable that lasts while the template is being filled. | |
| - | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -To install Cheetah in your system-wide Python library: | |
| -* Login as a user with privileges to install system-wide Python packages. | |
| - On POSIX systems (AIX, Solaris, Linux, IRIX, etc.), the command is | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -Certain test failures are insignificant: | |
| -\begin{description} | |
| -\item{**AssertionError: Template output mismatch: Expected Output = 0(end) | |
| -Actual Output = False(end)**} Python 2.3 changed the string representation of | |
| -booleans, and the tests haven't yet been updated to reflect this. | |
| -\item{**AssertionError: subcommand exit status 127**} Certain tests run | |
| -"cheetah" as a subcommand. The failure may mean the command wasn't found | |
| -in your system path. (What happens if you run "cheetah" on the command line?) | |
| -The failure also happens on some Windows systems for unknown reasons. This | |
| -failure has never been observed outside the test suite. Long term, we plan to | |
| -rewrite the tests to do a function call rather than a subcommand, which will | |
| -also make the tests run significantly faster. | |
| -\item{**ImportError: No module named SampleBaseClass**} The test tried to | |
| -write a temporary module in the current directory and ``import`` it. Reread | |
| -the first paragraph in this section about the current directory. | |
| -\item{**ImportError: No module named tmp**} May be the same problem as | |
| -SampleBaseClass; let us know if changing the current directory doesn't work. | |
| -\end{description} | |
| - | |
| - normally 'su root'. On non-POSIX systems such as Windows NT, login as an | |
| - administrator. | |
| diff --git a/docs/users_guide_src/Makefile b/docs/users_guide_src/Makefile | |
| deleted file mode 100755 | |
| index 8b8e977..0000000 | |
| --- a/docs/users_guide_src/Makefile | |
| +++ /dev/null | |
| @@ -1,39 +0,0 @@ | |
| -# You must change PYTHONSRC to the path of your Python source distributon. | |
| -# OR just create a symlink that matches this path. | |
| -PYTHONSRC=/usr/local/src/Python-source | |
| -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 ../ | |
| - | |
| -ps: | |
| - $(MKHOWTO) --ps $(MAIN_TEX_FILE) | |
| - mv $(DOCNAME).ps ../ | |
| -html: | |
| - -rm -rf $(DOCNAME) | |
| - $(MKHOWTO) --html --split 1 --iconserver . $(MAIN_TEX_FILE) | |
| - -rm -rf ../$(DOCNAME)_html | |
| - mv $(DOCNAME) ../$(DOCNAME)_html | |
| - | |
| -htmlMultiPage: | |
| - -rm -rf $(DOCNAME) | |
| - $(MKHOWTO) --html --iconserver . $(MAIN_TEX_FILE) | |
| - -rm -rf ../$(DOCNAME)_html_multipage | |
| - mv $(DOCNAME) ../$(DOCNAME)_html_multipage | |
| - | |
| -text: | |
| - $(MKHOWTO) --text $(MAIN_TEX_FILE) | |
| - mv $(DOCNAME).txt ../ | |
| - | |
| -clean: | |
| - -rm -rf $(DOCNAME) | |
| - -rm -f *.aux *.l2h *~ *.log *.ind *.bkm *.how *.toc | |
| - -rm -rf ../html | |
| - | |
| diff --git a/docs/users_guide_src/README b/docs/users_guide_src/README | |
| deleted file mode 100755 | |
| index 3b45564..0000000 | |
| --- a/docs/users_guide_src/README | |
| +++ /dev/null | |
| @@ -1,9 +0,0 @@ | |
| -To build the Cheetah documentation, you need the 'mkhowto' program from | |
| -the Python source distribution. So: | |
| - | |
| -1) Get the Python source distribution and unpack it in some directory. | |
| - | |
| -2) Edit the Cheetah documentation's Makefile and change PYTHONSRC to | |
| -point to the top-level directory of your Python source distribution. | |
| - | |
| -3) Run 'make'. | |
| diff --git a/docs/users_guide_src/comments.tex b/docs/users_guide_src/comments.tex | |
| deleted file mode 100755 | |
| index 36323cf..0000000 | |
| --- a/docs/users_guide_src/comments.tex | |
| +++ /dev/null | |
| @@ -1,99 +0,0 @@ | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\section{Comments} | |
| -\label{comments} | |
| - | |
| -Comments are used to mark notes, explanations, and decorative text that should | |
| -not appear in the output. Cheetah maintains the comments in the Python module | |
| -it generates from the Cheetah source code. There are two forms of the comment | |
| -directive: single-line and multi-line. | |
| - | |
| -All text in a template definition that lies between two hash characters | |
| -(\code{\#\#}) and the end of the line is treated as a single-line comment and | |
| -will not show up in the output, unless the two hash characters are escaped with | |
| -a backslash. | |
| -\begin{verbatim} | |
| -##============================= this is a decorative comment-bar | |
| -$var ## this is an end-of-line comment | |
| -##============================= | |
| -\end{verbatim} | |
| - | |
| -Any text between \code{\#*} and \code{*\#} will be treated as a multi-line | |
| -comment. | |
| -\begin{verbatim} | |
| -#* | |
| - Here is some multiline | |
| - comment text | |
| -*# | |
| -\end{verbatim} | |
| - | |
| -If you put blank lines around method definitions or loops to separate them, | |
| -be aware that the blank lines will be output as is. To avoid this, make sure | |
| -the blank lines are enclosed in a comment. Since you normally have a | |
| -comment before the next method definition (right?), you can just extend that | |
| -comment to include the blank lines after the previous method definition, like | |
| -so: | |
| -\begin{verbatim} | |
| -#def method1 | |
| -... lines ... | |
| -#end def | |
| -#* | |
| - | |
| - | |
| - Description of method2. | |
| - $arg1, string, a phrase. | |
| -*# | |
| -#def method2($arg1) | |
| -... lines ... | |
| -#end def | |
| -\end{verbatim} | |
| - | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Docstring Comments} | |
| -\label{comments.docstring} | |
| - | |
| -Python modules, classes, and methods can be documented with inline | |
| -'documentation strings' (aka 'docstrings'). Docstrings, unlike comments, are | |
| -accesible at run-time. Thus, they provide a useful hook for interactive help | |
| -utilities. | |
| - | |
| -Cheetah comments can be transformed into doctrings by adding one of the | |
| -following prefixes: | |
| - | |
| -\begin{verbatim} | |
| -##doc: This text will be added to the method docstring | |
| -#*doc: If your template file is MyTemplate.tmpl, running "cheetah compile" | |
| - on it will produce MyTemplate.py, with a class MyTemplate in it, | |
| - containing a method .respond(). This text will be in the .respond() | |
| - method's docstring. *# | |
| - | |
| -##doc-method: This text will also be added to .respond()'s docstring | |
| -#*doc-method: This text will also be added to .respond()'s docstring *# | |
| - | |
| -##doc-class: This text will be added to the MyTemplate class docstring | |
| -#*doc-class: This text will be added to the MyTemplate class docstring *# | |
| - | |
| -##doc-module: This text will be added to the module docstring MyTemplate.py | |
| -#*doc-module: This text will be added to the module docstring MyTemplate.py*# | |
| -\end{verbatim} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Header Comments} | |
| -\label{comments.headers} | |
| -Cheetah comments can also be transformed into module header comments using the | |
| -following syntax: | |
| - | |
| -\begin{verbatim} | |
| -##header: This text will be added to the module header comment | |
| -#*header: This text will be added to the module header comment *# | |
| -\end{verbatim} | |
| - | |
| -Note the difference between \code{\#\#doc-module: } and \code{header: }: | |
| -``cheetah-compile'' puts \code{\#\#doc-module: } text inside the module | |
| -docstring. \code{header: } makes the text go {\em above} the docstring, as a | |
| -set of \#-prefixed comment lines. | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| diff --git a/docs/users_guide_src/comparisons.tex b/docs/users_guide_src/comparisons.tex | |
| deleted file mode 100755 | |
| index 56a0fb3..0000000 | |
| --- a/docs/users_guide_src/comparisons.tex | |
| +++ /dev/null | |
| @@ -1,451 +0,0 @@ | |
| -\section{Cheetah vs. Other Template Engines} | |
| -\label{comparisons} | |
| - | |
| -This appendix compares Cheetah with various other template/emdedded scripting | |
| -languages and Internet development frameworks. As Cheetah is similar to | |
| -Velocity at a superficial level, you may also wish to read comparisons between | |
| -Velocity and other languages at | |
| -\url{http://jakarta.apache.org/velocity/ymtd/ymtd.html}. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Which features are unique to Cheetah} | |
| -\label{comparisons.unique} | |
| - | |
| -\begin{itemize} | |
| -\item The {\bf block framework} (section \ref{inheritanceEtc.block}) | |
| -\item Cheetah's powerful yet simple {\bf caching framework} (section | |
| - \ref{output.caching}) | |
| -\item Cheetah's {\bf Unified Dotted Notation} and {\bf autocalling} | |
| - (sections \ref{language.namemapper.dict} and | |
| - \ref{language.namemapper.autocalling}) | |
| -\item Cheetah's searchList (section \ref{language.searchList}) | |
| - information. | |
| -\item Cheetah's \code{\#raw} directive (section \ref{output.raw}) | |
| -\item Cheetah's \code{\#slurp} directive (section \ref{output.slurp}) | |
| -\item Cheetah's tight integration with Webware for Python (section | |
| - \ref{webware}) | |
| -\item Cheetah's {\bf SkeletonPage framework} (section | |
| - \ref{libraries.templates.skeletonPage}) | |
| -\item Cheetah's ability to mix PSP-style code with Cheetah | |
| - Language syntax (section \ref{tips.PSP}) | |
| - Because of Cheetah's design and Python's flexibility it is | |
| - relatively easy to extend Cheetah's syntax with syntax elements from almost | |
| - any other template or embedded scripting language. | |
| -\end{itemize} | |
| - | |
| -%% @@MO: What about the new features we've been adding? | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Cheetah vs. Velocity} | |
| -\label{comparisons.velocity} | |
| - | |
| -For a basic introduction to Velocity, visit | |
| -\url{http://jakarta.apache.org/velocity}. | |
| - | |
| -Velocity is a Java template engine. It's older than Cheetah, has a larger user | |
| -base, and has better examples and docs at the moment. Cheetah, however, has a | |
| -number of advantages over Velocity: | |
| -\begin{itemize} | |
| -\item Cheetah is written in Python. Thus, it's easier to use and extend. | |
| -\item Cheetah's syntax is closer to Python's syntax than Velocity's is to | |
| -Java's. | |
| -\item Cheetah has a powerful caching mechanism. Velocity has no equivalent. | |
| -\item It's far easier to add data/objects into the namespace where \$placeholder | |
| - values are extracted from in Cheetah. Velocity calls this namespace a 'context'. | |
| - Contexts are dictionaries/hashtables. You can put anything you want into a | |
| - context, BUT you have to use the .put() method to populate the context; | |
| - e.g., | |
| - | |
| -\begin{verbatim} | |
| -VelocityContext context1 = new VelocityContext(); | |
| -context1.put("name","Velocity"); | |
| -context1.put("project", "Jakarta"); | |
| -context1.put("duplicate", "I am in context1"); | |
| -\end{verbatim} | |
| - | |
| - Cheetah takes a different approach. Rather than require you to manually | |
| - populate the 'namespace' like Velocity, Cheetah will accept any existing | |
| - Python object or dictionary AS the 'namespace'. Furthermore, Cheetah | |
| - allows you to specify a list namespaces that will be searched in sequence | |
| - to find a varname-to-value mapping. This searchList can be extended at | |
| - run-time. | |
| - | |
| - If you add a `foo' object to the searchList and the `foo' has an attribute | |
| - called 'bar', you can simply type \code{\$bar} in the template. If the | |
| - second item in the searchList is dictionary 'foofoo' containing | |
| - \code{\{'spam':1234, 'parrot':666\}}, Cheetah will first look in the `foo' | |
| - object for a `spam' attribute. Not finding it, Cheetah will then go to | |
| - `foofoo' (the second element in the searchList) and look among its | |
| - dictionary keys for `spam'. Finding it, Cheetah will select | |
| - \code{foofoo['spam']} as \code{\$spam}'s value. | |
| - | |
| -\item In Cheetah, the tokens that are used to signal the start of | |
| - \$placeholders and \#directives are configurable. You can set them to any | |
| - character sequences, not just \$ and \#. | |
| -\end{itemize} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Cheetah vs. WebMacro} | |
| -\label{comparisons.webmacro} | |
| - | |
| -For a basic introduction to WebMacro, visit | |
| -\url{http://webmacro.org}. | |
| - | |
| -The points discussed in section \ref{comparisons.velocity} also apply to the | |
| -comparison between Cheetah and WebMacro. For further differences please refer | |
| -to \url{http://jakarta.apache.org/velocity/differences.html}. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Cheetah vs. Zope's DTML} | |
| -\label{comparisons.dtml} | |
| - | |
| -For a basic introduction to DTML, visit | |
| -\url{http://www.zope.org/Members/michel/ZB/DTML.dtml}. | |
| - | |
| -\begin{itemize} | |
| -\item Cheetah is faster than DTML. | |
| -\item Cheetah does not use HTML-style tags; DTML does. Thus, Cheetah tags are | |
| - visible in rendered HTML output if something goes wrong. | |
| -\item DTML can only be used with ZOPE for web development; Cheetah can be | |
| - used as a standalone tool for any purpose. | |
| -\item Cheetah's documentation is more complete than DTML's. | |
| -\item Cheetah's learning curve is shorter than DTML's. | |
| -\item DTML has no equivalent of Cheetah's blocks, caching framework, | |
| - unified dotted notation, and \code{\#raw} directive. | |
| -\end{itemize} | |
| - | |
| -Here are some examples of syntax differences between DTML and Cheetah: | |
| -\begin{verbatim} | |
| -<ul> | |
| -<dtml-in frogQuery> | |
| - <li><dtml-var animal_name></li> | |
| -</dtml-in> | |
| -</ul> | |
| -\end{verbatim} | |
| - | |
| -\begin{verbatim} | |
| -<ul> | |
| -#for $animal_name in $frogQuery | |
| - <li>$animal_name</li> | |
| -#end for | |
| -</ul> | |
| -\end{verbatim} | |
| - | |
| -\begin{verbatim} | |
| -<dtml-if expr="monkeys > monkey_limit"> | |
| - <p>There are too many monkeys!</p> | |
| -<dtml-elif expr="monkeys < minimum_monkeys"> | |
| - <p>There aren't enough monkeys!</p> | |
| -<dtml-else> | |
| - <p>There are just enough monkeys.</p> | |
| -</dtml-if> | |
| -\end{verbatim} | |
| - | |
| -\begin{verbatim} | |
| -#if $monkeys > $monkey_limit | |
| - <p>There are too many monkeys!</p> | |
| -#else if $monkeys < $minimum_monkeys | |
| - <p>There aren't enough monkeys!</p> | |
| -#else | |
| - <p>There are just enough monkeys.</p> | |
| -#end if | |
| -\end{verbatim} | |
| - | |
| -\begin{verbatim} | |
| -<table> | |
| -<dtml-in expr="objectValues('File')"> | |
| - <dtml-if sequence-even> | |
| - <tr bgcolor="grey"> | |
| - <dtml-else> | |
| - <tr> | |
| - </dtml-if> | |
| - <td> | |
| - <a href="&dtml-absolute_url;"><dtml-var title_or_id></a> | |
| - </td></tr> | |
| -</dtml-in> | |
| -</table> | |
| -\end{verbatim} | |
| - | |
| -\begin{verbatim} | |
| -<table> | |
| -#set $evenRow = 0 | |
| -#for $file in $files('File') | |
| - #if $evenRow | |
| - <tr bgcolor="grey"> | |
| - #set $evenRow = 0 | |
| - #else | |
| - <tr> | |
| - #set $evenRow = 1 | |
| - #end if | |
| - <td> | |
| - <a href="$file.absolute_url">$file.title_or_id</a> | |
| - </td></tr> | |
| -#end for | |
| -</table> | |
| -\end{verbatim} | |
| - | |
| -The last example changed the name of \code{\$objectValues} to | |
| -\code{\$files} because that's what a Cheetah developer would write. | |
| -The developer would be responsible for ensuring \code{\$files} returned a | |
| -list (or tuple) of objects (or dictionaries) containing the attributes (or | |
| -methods or dictionary keys) `absolute\_url' and `title\_or\_id'. All these | |
| -names (`objectValues', `absolute\_url' and `title\_or\_id') are standard parts | |
| -of Zope, but in Cheetah the developer is in charge of writing them and giving | |
| -them a reasonable behaviour. | |
| - | |
| -Some of DTML's features are being ported to Cheetah, such as | |
| -\code{Cheetah.Tools.MondoReport}, which is based on the | |
| -\code{<dtml-in>} tag. We are also planning an output filter as flexible as | |
| -the \code{<dtml-var>} formatting options. However, neither of these are | |
| -complete yet. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Cheetah vs. Zope Page Templates} | |
| -\label{comparisons.zpt} | |
| - | |
| -For a basic introduction to Zope Page Templates, please visit | |
| -\url{http://www.zope.org/Documentation/Articles/ZPT2}. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Cheetah vs. PHP's Smarty templates} | |
| -\label{comparisons.smarty} | |
| - | |
| -PHP (\url{http://www.php.net/}) is one of the few scripting languages | |
| -expressly designed for web servlets. However, it's also a full-fledged | |
| -programming language with libraries similar to Python's and Perl's. The | |
| -syntax and functions are like a cross between Perl and C plus some original | |
| -ideas (e.g.; a single array type serves as both a list and a dictionary, | |
| -\verb+$arr[]="value";+ appends to an array). | |
| - | |
| -Smarty (\url{http://smarty.php.net/}) is an advanced template engine for | |
| -PHP. ({\em Note:} this comparision is based on Smarty's on-line documentation. | |
| -The author has not used Smarty. Please send corrections or ommissions to the | |
| -Cheetah mailing list.) Like Cheetah, Smarty: | |
| - | |
| -\begin{itemize} | |
| -\item compiles to the target programming language (PHP). | |
| -\item has configurable delimeters. | |
| -\item passes if-blocks directly to PHP, so you can use any PHP expression in | |
| -them. | |
| -\item allows you to embed PHP code in a template. | |
| -\item has a caching framework (although it works quite differently). | |
| -\item can read the template definition from any arbitrary source. | |
| -\end{itemize} | |
| - | |
| -Features Smarty has that Cheetah lacks: | |
| -\begin{itemize} | |
| -\item Preprocessors, postprocessors and output filters. You can emulate a | |
| -preprocessor in Cheetah by running your template definition through a filter | |
| -program or function before Cheetah sees it. To emulate a postprocessor, run a | |
| -.py template module through a filter program/function. To emulate a Smarty | |
| -output filter, run the template output through a filter program/function. If | |
| -you want to use ``cheetah compile'' or ``cheetah fill'' in a pipeline, use | |
| -\code{-} as the input file name and \code{--stdout} to send the result to | |
| -standard output. Note that Cheetah uses the term ``output filter'' differently | |
| -than Smarty: Cheetah output filters (\code{\#filter}) operate on placeholders, | |
| -while Smarty output filters operate on the entire template output. There has | |
| -been a proposed \code{\#sed} directive that would operate on the entire output | |
| -line by line, but it has not been implemented. | |
| -\item Variable modifiers. In some cases, Python has equivalent string | |
| -methods (\code{.strip}, \code{.capitalize}, \code{.replace(SEARCH, REPL)}), | |
| -but in other cases you must wrap the result in a function call or write | |
| -a custom output filter (\code{\#filter}). | |
| -\item Certain web-specific functions, which can be emulated with | |
| -third-party functions. | |
| -\item The ability to ``plug in'' new directives in a modular way. Cheetah | |
| -directives are tightly bound to the compiler. However, third-party | |
| -{\em functions} can be freely imported and called from placeholders, and | |
| -{\em methods} can be mixed in via \code{\#extends}. Part of this is | |
| -because Cheetah distinguishes between functions and directives, while | |
| -Smarty treats them all as ``functions''. Cheetah's design does not | |
| -allow functions to have flow control effect outside the function | |
| -(e.g., \code{\#if} and \code{\#for}, which operate on template body lines), | |
| -so directives like these cannot be encoded as functions. | |
| -\item Configuration variables read from an .ini-style file. The | |
| -\code{Cheetah.SettingsManager} module can parse such a file, but you'd | |
| -have to invoke it manually. (See the docstrings in the module for | |
| -details.) In Smarty, this feature is used for | |
| -multilingual applications. In Cheetah, the developers maintain that everybody | |
| -has their own preferred way to do this (such as using Python's \code{gettext} | |
| -module), and it's not worth blessing one particular strategy in Cheetah since | |
| -it's easy enough to integrate third-party code around the template, or to add | |
| -the resulting values to the searchList. | |
| -\end{itemize} | |
| - | |
| -Features Cheetah has that Smarty lacks: | |
| -\begin{itemize} | |
| -\item Saving the compilation result in a Python (PHP) module for quick | |
| -reading later. | |
| -\item Caching individual placeholders or portions of a template. Smarty | |
| -caches only the entire template output as a unit. | |
| -\end{itemize} | |
| - | |
| -Comparisions of various Smarty constructs: | |
| -\begin{verbatim} | |
| -{assign var="name" value="Bob"} (#set has better syntax in the author's opinion) | |
| -counter (looks like equivalent to #for) | |
| -eval (same as #include with variable) | |
| -fetch: insert file content into output (#include raw) | |
| -fetch: insert URL content into output (no euqivalent, user can write | |
| - function calling urllib, call as $fetchURL('URL') ) | |
| -fetch: read file into variable (no equivalent, user can write function | |
| - based on the 'open/file' builtin, or on .getFileContents() in | |
| - Template.) | |
| -fetch: read URL content into variable (no equivalent, use above | |
| - function and call as: #set $var = $fetchURL('URL') | |
| -html_options: output an HTML option list (no equivalent, user can | |
| - write custom function. Maybe FunFormKit can help.) | |
| -html_select_date: output three dropdown controls to specify a date | |
| - (no equivalent, user can write custom function) | |
| -html_select_time: output four dropdown controls to specify a time | |
| - (no equvalent, user can write custom function) | |
| -math: eval calculation and output result (same as #echo) | |
| -math: eval calculation and assign to variable (same as #set) | |
| -popup_init: library for popup windows (no equivalent, user can write | |
| - custom method outputting Javascript) | |
| - | |
| - | |
| -Other commands: | |
| -capture (no equivalent, collects output into variable. A Python | |
| - program would create a StringIO instance, set sys.stdout to | |
| - it temporarily, print the output, set sys.stdout back, then use | |
| - .getvalue() to get the result.) | |
| -config_load (roughly analagous to #settings, which was removed | |
| - from Cheetah. Use Cheetah.SettingsManager manually or write | |
| - a custom function.) | |
| -include (same as #include, but can include into variable. | |
| - Variables are apparently shared between parent and child.) | |
| -include_php: include a PHP script (e.g., functions) | |
| - (use #extends or #import instead) | |
| -insert (same as #include not in a #cache region) | |
| -{ldelim}{rdelim} (escape literal $ and # with a backslash, | |
| - use #compiler-settings to change the delimeters) | |
| -literal (#raw) | |
| -php (``<% %>'' tags) | |
| -section (#for $i in $range(...) ) | |
| -foreach (#for) | |
| -strip (like the #sed tag which was never implemented. Strips | |
| - leading/trailing whitespace from lines, joins several lines | |
| - together.) | |
| - | |
| - | |
| -Variable modifiers: | |
| -capitalize ( $STRING.capitalize() ) | |
| -count_characters ( $len(STRING) ) | |
| -count_paragraphs/sentances/words (no equivalent, user can write function) | |
| -date_format (use 'time' module or download Egenix's mx.DateTime) | |
| -default ($getVar('varName', 'default value') ) | |
| -escape: html encode ($cgi.escape(VALUE) ) | |
| -escape: url encode ($urllib.quote_plus(VALUE) ) | |
| -escape: hex encode (no equivalent? user can write function) | |
| -escape: hex entity encode (no equivalent? user can write function) | |
| -indent: indent all lines of a var's output (may be part of future | |
| - #indent directive) | |
| -lower ($STRING.lower() ) | |
| -regex_replace ('re' module) | |
| -replace ($STRING.replace(OLD, NEW, MAXSPLIT) ) | |
| -spacify (#echo "SEPARATOR".join(SEQUENCE) ) | |
| -string_format (#echo "%.2f" % FLOAT , etc.) | |
| -strip_tags (no equivalent, user can write function to strip HTML tags, | |
| - or customize the WebSafe filter) | |
| -truncate (no equivalent, user can write function) | |
| -upper ($STRING.upper() ) | |
| -wordwrap ('writer' module, or a new module coming in Python 2.3) | |
| -\end{verbatim} | |
| - | |
| -Some of these modifiers could be added to the super output filter we | |
| -want to write someday. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Cheetah vs. PHPLib's Template class} | |
| -\label{comparisons.php} | |
| - | |
| -PHPLib (\url(http://phplib.netuse.de/) is a collection of classes for various | |
| -web objects (authentication, shopping cart, sessions, etc), but what we're | |
| -interested in is the \code{Template} object. It's much more primitive than | |
| -Smarty, and was based on an old Perl template class. In fact, one of the | |
| -precursors to Cheetah was based on it too. Differences from Cheetah: | |
| - | |
| -\begin{itemize} | |
| -\item Templates consist of text with \code{\{placeholders\}} in braces. | |
| -\item Instead of a searchList, there is one flat namespace. Every variable | |
| - must be assigned via the \code{set\_var} method. However, you can pass | |
| - this method an array (dictionary) of several variables at once. | |
| -\item You cannot embed lookups or calculations into the template. Every | |
| - placeholder must be an exact variable name. | |
| -\item There are no directives. You must do all display logic (if, for, etc) | |
| - in the calling routine. | |
| -\item There is, however, a ``block'' construct. A block is a portion of text | |
| - between the comment markers \code{<!-- BEGIN blockName --> \ldots | |
| - <!-- END blockName>}. The \code{set\_block} method extracts this text | |
| - into a namespace variable and puts a placeholder referring to it in the | |
| - template. This has a few parallels with Cheetah's \code{\#block} | |
| - directive but is overall quite different. | |
| -\item To do the equivalent of \code{\#if}, extract the block. Then if true, do | |
| - nothing. If false, assign the empty string to the namespace variable. | |
| -\item To do the equivalent of \code{\#for}, extract the block. Set any | |
| - namespace variables needed inside the loop. To parse one iteration, use | |
| - the \code{parse} method to fill the block variable (a mini-template) into | |
| - another namespace variable, appending to it. Refresh the namespace | |
| - variables needed inside the loop and parse again; repeat for each | |
| - iteration. You'll end up with a mini-result that will be plugged into the | |
| - main template's placeholder. | |
| -\item To read a template definition from a file, use the \code{set\_file} | |
| - method. This places the file's content in a namespace variable. | |
| - To read a template definition from a string, assign it to a namespace | |
| - variable. | |
| -\item Thus, for complicated templates, you are doing a lot of recursive block | |
| - filling and file reading and parsing mini-templates all into one flat | |
| - namespace as you finally build up values for the main template. In | |
| - Cheetah, all this display logic can be embedded into the template using | |
| - directives, calling out to Python methods for the more complicated tasks. | |
| -\item Although you can nest blocks in the template, it becomes tedious and | |
| - arguably hard to read, because all blocks have identical syntax. Unless | |
| - you choose your block names carefully and put comments around them, it's | |
| - hard to tell which blocks are if-blocks and which are for-blocks, or what | |
| - their nesting order is. | |
| -\item PHPLib templates do not have caching, output filters, etc. | |
| -\end{itemize} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Cheetah vs. PSP, PHP, ASP, JSP, Embperl, etc.} | |
| -\label{comparisons.pspEtc} | |
| - | |
| -\begin{description} | |
| -\item[Webware's PSP Component] -- \url{http://webware.sourceforge.net/Webware/PSP/Docs/} | |
| -\item[Tomcat JSP Information] -- \url{http://jakarta.apache.org/tomcat/index.html} | |
| -\item[ASP Information at ASP101] -- \url{http://www.asp101.com/} | |
| -\item[Embperl] -- \url{http://perl.apache.org/embperl/} | |
| -\end{description} | |
| - | |
| - | |
| -Here's a basic Cheetah example: | |
| -\begin{verbatim} | |
| -<TABLE> | |
| -#for $client in $service.clients | |
| -<TR> | |
| -<TD>$client.surname, $client.firstname</TD> | |
| -<TD><A HREF="mailto:$client.email" >$client.email</A></TD> | |
| -</TR> | |
| -#end for | |
| -</TABLE> | |
| -\end{verbatim} | |
| - | |
| -Compare this with PSP: | |
| - | |
| -\begin{verbatim} | |
| -<TABLE> | |
| -<% for client in service.clients(): %> | |
| -<TR> | |
| -<TD><%=client.surname()%>, <%=client.firstname()%></TD> | |
| -<TD><A HREF="mailto:<%=client.email()%>"><%=client.email()%></A></TD> | |
| -</TR> | |
| -<%end%> | |
| -</TABLE> | |
| -\end{verbatim} | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| diff --git a/docs/users_guide_src/editors.tex b/docs/users_guide_src/editors.tex | |
| deleted file mode 100755 | |
| index 84c8f03..0000000 | |
| --- a/docs/users_guide_src/editors.tex | |
| +++ /dev/null | |
| @@ -1,39 +0,0 @@ | |
| -\section{Visual Editors} | |
| -\label{visualEditors} | |
| - | |
| -This chapter is about maintaining Cheetah templates with visual editors, | |
| -and the tradeoffs between making it friendly to both text editors and visual | |
| -editors. | |
| - | |
| -Cheetah's main developers do not use visual editors. Tavis uses \code{emacs}; | |
| -Mike uses \code{vim}. So our first priority is to make templates easy to | |
| -maintain in text editors. In particular, we don't want to add features | |
| -like Zope Page Template's | |
| -placeholder-value-with-mock-text-for-visual-editors-all-in-an-XML-tag. | |
| -The syntax is so verbose it makes for a whole lotta typing just to insert a | |
| -simple placeholder, for the benefit of editors we never use. However, as users | |
| -identify features which would help their visual editing without making it | |
| -harder to maintain templates in a text editor, we're all for it. | |
| - | |
| -As it said in the introduction, Cheetah purposely does not use HTML/XML | |
| -tags for \$placeholders or \#directives. That way, when you preview the | |
| -template in an editor that interprets HTML tags, you'll still see the | |
| -placeholder and directive source definitions, which provides some ``mock text'' | |
| -even if it's not the size the final values will be, and allows you to use | |
| -your imagination to translate how the directive output will look visually in | |
| -the final. | |
| - | |
| -If your editor has syntax highlighting, turn it on. That makes a big | |
| -difference in terms of making the template easier to edit. Since no | |
| -``Cheetah mode'' has been invented yet, set your highlighting to Perl | |
| -mode, and at least the directives/placeholders will show up in different | |
| -colors, although the editor won't reliably guess where the | |
| -directive/placeholder ends and normal text begins. | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| - | |
| - | |
| - | |
| - | |
| diff --git a/docs/users_guide_src/errorHandling.tex b/docs/users_guide_src/errorHandling.tex | |
| deleted file mode 100755 | |
| index 28eee3a..0000000 | |
| --- a/docs/users_guide_src/errorHandling.tex | |
| +++ /dev/null | |
| @@ -1,145 +0,0 @@ | |
| -\section{Error Handling} | |
| -\label{errorHandling} | |
| - | |
| -There are two ways to handle runtime errors (exceptions) in Cheetah. The first | |
| -is with the Cheetah directives that mirror Python's structured exception | |
| -handling statements. The second is with Cheetah's \code{ErrorCatcher} | |
| -framework. These are described below. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#try ... \#except ... \#end try, \#finally, and \#assert} | |
| -\label{errorHandling.directives} | |
| - | |
| -Cheetah's exception-handling directives are exact mirrors Python's | |
| -exception-handling statements. See Python's documentation for details. The | |
| -following Cheetah code demonstrates their use: | |
| - | |
| - | |
| -\begin{verbatim} | |
| -#try | |
| - $mightFail() | |
| -#except | |
| - It failed | |
| -#end try | |
| - | |
| -#try | |
| - #assert $x == $y | |
| -#except AssertionError | |
| - They're not the same! | |
| -#end try | |
| - | |
| -#try | |
| - #raise ValueError | |
| -#except ValueError | |
| - #pass | |
| -#end try | |
| - | |
| - | |
| -#try | |
| - $mightFail() | |
| -#except ValueError | |
| - Hey, it raised a ValueError! | |
| -#except NameMapper.NotFound | |
| - Hey, it raised a NameMapper.NotFound! | |
| -#else | |
| - It didn't raise anything! | |
| -#end try | |
| - | |
| -#try | |
| - $mightFail() | |
| -#finally | |
| - $cleanup() | |
| -#end try | |
| -\end{verbatim} | |
| - | |
| -Like Python, \code{\#except} and \code{\#finally} cannot appear in the same | |
| -try-block, but can appear in nested try-blocks. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#errorCatcher and ErrorCatcher objects} | |
| -\label{errorHandling.errorCatcher} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#errorCatcher CLASS | |
| -#errorCatcher $PLACEHOLDER_TO_AN_ERROR_CATCHER_INSTANCE | |
| -\end{verbatim} | |
| - | |
| - | |
| -\code{ErrorCatcher} is a debugging tool that catches exceptions that occur | |
| -inside \code{\$placeholder} tags and provides a customizable warning to the | |
| -developer. Normally, the first missing namespace value raises a | |
| -\code{NameMapper.NotFound} error and halts the filling of the template. This | |
| -requires the developer to resolve the exceptions in order without seeing the | |
| -subsequent output. When an \code{ErrorCatcher} is enabled, the developer can | |
| -see all the exceptions at once as well as the template output around them. | |
| - | |
| -The \code{Cheetah.ErrorCatchers} module defines the base class for | |
| -ErrorCatchers: | |
| - | |
| -\begin{verbatim} | |
| -class ErrorCatcher: | |
| - _exceptionsToCatch = (NameMapper.NotFound,) | |
| - | |
| - def __init__(self, templateObj): | |
| - pass | |
| - | |
| - def exceptions(self): | |
| - return self._exceptionsToCatch | |
| - | |
| - def warn(self, exc_val, code, rawCode, lineCol): | |
| - return rawCode | |
| -\end{verbatim} | |
| - | |
| -This ErrorCatcher catches \code{NameMapper.NotFound} exceptions and leaves the | |
| -offending placeholder visible in its raw form in the template output. If the | |
| -following template is executed: | |
| -\begin{verbatim} | |
| -#errorCatcher Echo | |
| -#set $iExist = 'Here I am!' | |
| -Here's a good placeholder: $iExist | |
| -Here's bad placeholder: $iDontExist | |
| -\end{verbatim} | |
| - | |
| -the output will be: | |
| -\begin{verbatim} | |
| -Here's a good placeholder: Here I am! | |
| -Here's bad placeholder: $iDontExist | |
| -\end{verbatim} | |
| - | |
| -The base class shown above is also accessible under the alias | |
| -\code{Cheetah.ErrorCatchers.Echo}. \code{Cheetah.ErrorCatchers} also provides a | |
| -number of specialized subclasses that warn about exceptions in different ways. | |
| -\code{Cheetah.ErrorCatchers.BigEcho} will output | |
| - | |
| -\begin{verbatim} | |
| -Here's a good placeholder: Here I am! | |
| -Here's bad placeholder: ===============<$iDontExist could not be found>=============== | |
| -\end{verbatim} | |
| - | |
| -ErrorCatcher has a significant performance impact and is turned off by default. | |
| -It can also be turned on with the \code{Template} class' \code{'errorCatcher'} | |
| -keyword argument. The value of this argument should either be a string | |
| -specifying which of the classes in \code{Cheetah.ErrorCatchers} to use, or a | |
| -class that subclasses \code{Cheetah.ErrorCatchers.ErrorCatcher}. The | |
| -\code{\#errorCatcher} directive can also be used to change the errorCatcher part | |
| -way through a template. | |
| - | |
| -\code{Cheetah.ErrorCatchers.ListErrors} will produce the same ouput as | |
| -\code{Echo} while maintaining a list of the errors that can be retrieved later. | |
| -To retrieve the list, use the \code{Template} class' \code{'errorCatcher'} | |
| -method to retrieve the errorCatcher and then call its \code{listErrors} method. | |
| - | |
| -ErrorCatcher doesn't catch exceptions raised inside directives. | |
| - | |
| -% @@MO: How do you turn ErrorCatcher off after turn it on. | |
| -% '#ErrorCatcher None'? | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| - | |
| - | |
| - | |
| - | |
| diff --git a/docs/users_guide_src/examples.tex b/docs/users_guide_src/examples.tex | |
| deleted file mode 100755 | |
| index 6c394fb..0000000 | |
| --- a/docs/users_guide_src/examples.tex | |
| +++ /dev/null | |
| @@ -1,24 +0,0 @@ | |
| -\section{Examples} | |
| -\label{examples} | |
| - | |
| -The Cheetah distribution comes with an 'examples' directory. Browse the | |
| -files in this directory and its subdirectories for examples of how | |
| -Cheetah can be used. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Syntax examples} | |
| -The \code{Cheetah.Tests} module contains a large number of test cases that can | |
| -double as examples of how the Cheetah Language works. To view these cases go | |
| -to the base directory of your Cheetah distribution and open the file | |
| -\code{Cheetah/Tests/SyntaxAndOutput.py} in a text editor. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Webware Examples} | |
| -For examples of Cheetah in use with Webware visit the Cheetah and Webware wikis | |
| -or use google. We used to have more examples in the cheetah source tarball, but | |
| -they were out of date and confused people. | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| diff --git a/docs/users_guide_src/flowControl.tex b/docs/users_guide_src/flowControl.tex | |
| deleted file mode 100755 | |
| index 75a5845..0000000 | |
| --- a/docs/users_guide_src/flowControl.tex | |
| +++ /dev/null | |
| @@ -1,414 +0,0 @@ | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\section{Flow Control} | |
| -\label{flowControl} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#for ... \#end for} | |
| -\label{flowControl.for} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#for $var in EXPR | |
| -#end for | |
| -\end{verbatim} | |
| - | |
| - | |
| -The \code{\#for} directive iterates through a sequence. The syntax is the same | |
| -as Python, but remember the \code{\$} before variables. | |
| - | |
| -Here's a simple client listing: | |
| -\begin{verbatim} | |
| -<TABLE> | |
| -#for $client in $service.clients | |
| -<TR> | |
| -<TD>$client.surname, $client.firstname</TD> | |
| -<TD><A HREF="mailto:$client.email" >$client.email</A></TD> | |
| -</TR> | |
| -#end for | |
| -</TABLE> | |
| -\end{verbatim} | |
| - | |
| -Here's how to loop through the keys and values of a dictionary: | |
| -\begin{verbatim} | |
| -<PRE> | |
| -#for $key, $value in $dict.items() | |
| -$key: $value | |
| -#end for | |
| -</PRE> | |
| -\end{verbatim} | |
| - | |
| -Here's how to create list of numbers separated by hyphens. This ``\#end for'' | |
| -tag shares the last line to avoid introducing a newline character after each | |
| -hyphen. | |
| -\begin{verbatim} | |
| -#for $i in range(15) | |
| -$i - #end for | |
| -\end{verbatim} | |
| - | |
| -If the location of the \code{\#end for} offends your sense of indentational | |
| -propriety, you can do this instead: | |
| -\begin{verbatim} | |
| -#for $i in $range(15) | |
| -$i - #slurp | |
| -#end for | |
| -\end{verbatim} | |
| - | |
| -The previous two examples will put an extra hyphen after last number. Here's | |
| -how to get around that problem, using the \code{\#set} directive, which will be | |
| -dealt with in more detail below. | |
| -\begin{verbatim} | |
| -#set $sep = '' | |
| -#for $name in $names | |
| -$sep$name | |
| -#set $sep = ', ' | |
| -#end for | |
| -\end{verbatim} | |
| - | |
| -Although to just put a separator between strings, you don't need a for loop: | |
| -\begin{verbatim} | |
| -#echo ', '.join($names) | |
| -\end{verbatim} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#repeat ... \#end repeat} | |
| -\label{flowControl.repeat} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#repeat EXPR | |
| -#end repeat | |
| -\end{verbatim} | |
| - | |
| - | |
| -Do something a certain number of times. | |
| -The argument may be any numeric expression. | |
| -If it's zero or negative, the loop will execute zero times. | |
| -\begin{verbatim} | |
| -#repeat $times + 3 | |
| -She loves me, she loves me not. | |
| -#repeat | |
| -She loves me. | |
| -\end{verbatim} | |
| - | |
| - | |
| -Inside the loop, there's no way to tell which iteration you're on. If you | |
| -need a counter variable, use \code{\#for} instead with Python's \code{range} | |
| -function. Since Python's ranges are base 0 by default, there are two ways | |
| -to start counting at 1. Say we want to count from 1 to 5, and that | |
| -\code{\$count} is 5. | |
| -\begin{verbatim} | |
| -#for $i in $range($count) | |
| -#set $step = $i + 1 | |
| -$step. Counting from 1 to $count. | |
| -#end for | |
| - | |
| - | |
| -#for $i in $range(1, $count + 1) | |
| -$i. Counting from 1 to $count. | |
| -#end for | |
| -\end{verbatim} | |
| - | |
| - | |
| -A previous implementation used a local variable \code{\$i} as the repeat | |
| -counter. However, this prevented instances of \code{\#repeat} from | |
| -being nested. The current implementation does not have this problem as it | |
| -uses a new local variable for every instance of \code{\#repeat}. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#while ... \#end while} | |
| -\label{flowControl.while} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#while EXPR | |
| -#end while | |
| -\end{verbatim} | |
| - | |
| - | |
| -\code{\#while} is the same as Python's \code{while} statement. It may be | |
| -followed by any boolean expression: | |
| -\begin{verbatim} | |
| -#while $someCondition('arg1', $arg2) | |
| -The condition is true. | |
| -#end while | |
| -\end{verbatim} | |
| - | |
| -Be careful not to create an infinite loop. \code{\#while 1} will loop until | |
| -the computer runs out of memory. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#if ... \#else if ... \#else ... \#end if} | |
| -\label{flowControl.if} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#if EXPR | |
| -#else if EXPR | |
| -#elif EXPR | |
| -#else | |
| -#end if | |
| -\end{verbatim} | |
| - | |
| - | |
| -The \code{\#if} directive and its kin are used to display a portion of text | |
| -conditionally. \code{\#if} and \code{\#else if} should be followed by a | |
| -true/false expression, while \code{\#else} should not. Any valid Python | |
| -expression is allowed. As in Python, the expression is true unless it evaluates | |
| -to 0, '', None, an empty list, or an empty dictionary. In deference to Python, | |
| -\code{\#elif} is accepted as a synonym for \code{\#else if}. | |
| - | |
| -Here are some examples: | |
| -\begin{verbatim} | |
| -#if $size >= 1500 | |
| -It's big | |
| -#else if $size < 1500 and $size > 0 | |
| -It's small | |
| -#else | |
| -It's not there | |
| -#end if | |
| -\end{verbatim} | |
| - | |
| -\begin{verbatim} | |
| -#if $testItem($item) | |
| -The item $item.name is OK. | |
| -#end if | |
| -\end{verbatim} | |
| - | |
| -Here's an example that combines an \code{\#if} tag with a \code{\#for} tag. | |
| -\begin{verbatim} | |
| -#if $people | |
| -<table> | |
| -<tr> | |
| -<th>Name</th> | |
| -<th>Address</th> | |
| -<th>Phone</th> | |
| -</tr> | |
| -#for $p in $people | |
| -<tr> | |
| -<td>$p.name</td> | |
| -<td>$p.address</td> | |
| -<td>$p.phone</td> | |
| -</tr> | |
| -#end for | |
| -</table> | |
| -#else | |
| -<p> Sorry, the search did not find any people. </p> | |
| -#end if | |
| -\end{verbatim} | |
| - | |
| -See section \ref{output.oneLineIf} for the one-line \code{\#if} directive, | |
| -which is equivalent to Perl's and C's \code{?:} operator. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#unless ... \#end unless} | |
| -\label{flowControl.unless} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#unless EXPR | |
| -#end unless | |
| -\end{verbatim} | |
| - | |
| - | |
| -\code{\#unless} is the opposite of \code{\#if}: the text is executed if the | |
| -condition is {\bf false}. Sometimes this is more convenient. | |
| -\code{\#unless EXPR} is equivalent to \code{\#if not (EXPR)}. | |
| - | |
| -\begin{verbatim} | |
| -#unless $alive | |
| -This parrot is no more! He has ceased to be! | |
| -'E's expired and gone to meet 'is maker! ... | |
| -THIS IS AN EX-PARROT!! | |
| -#end unless | |
| -\end{verbatim} | |
| - | |
| -You cannot use \code{\#else if} or \code{\#else} inside an \code{\#unless} | |
| -construct. If you need those, use \code{\#if} instead. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#break and \#continue} | |
| -\label{flowControl.break} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#break | |
| -#continue | |
| -\end{verbatim} | |
| - | |
| - | |
| -These directives are used as in Python. \code{\#break} will | |
| -exit a \code{\#for} loop prematurely, while \code{\#continue} will immediately | |
| -jump to the next iteration in the \code{\#for} loop. | |
| - | |
| -In this example the output list will not contain ``10 - ''. | |
| -\begin{verbatim} | |
| -#for $i in range(15) | |
| -#if $i == 10 | |
| - #continue | |
| -#end if | |
| -$i - #slurp | |
| -#end for | |
| -\end{verbatim} | |
| - | |
| -In this example the loop will exit if it finds a name that equals 'Joe': | |
| -\begin{verbatim} | |
| -#for $name in $names | |
| -#if $name == 'Joe' | |
| - #break | |
| -#end if | |
| -$name - #slurp | |
| -#end for | |
| -\end{verbatim} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#pass} | |
| -\label{flowControl.pass} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#pass | |
| -\end{verbatim} | |
| - | |
| - | |
| -The \code{\#pass} directive is identical to Python \code{pass} statement: it | |
| -does nothing. It can be used when a statement is required syntactically but the | |
| -program requires no action. | |
| - | |
| -The following example does nothing if only \$A is true | |
| -\begin{verbatim} | |
| -#if $A and $B | |
| - do something | |
| -#elif $A | |
| - #pass | |
| -#elif $B | |
| - do something | |
| -#else | |
| - do something | |
| -#end if | |
| -\end{verbatim} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#stop} | |
| -\label{flowControl.stop} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#stop | |
| -\end{verbatim} | |
| - | |
| - | |
| -The \code{\#stop} directive is used to stop processing of a template at a | |
| -certain point. The output will show {\em only} what has been processed up to | |
| -that point. | |
| - | |
| -When \code{\#stop} is called inside an \code{\#include} it skips the rest of | |
| -the included code and continues on from after the \code{\#include} directive. | |
| -stop the processing of the included code. Likewise, when \code{\#stop} is | |
| -called inside a \code{\#def} or \code{\#block}, it stops only the \code{\#def} | |
| -or \code{\#block}. | |
| - | |
| -\begin{verbatim} | |
| -A cat | |
| -#if 1 | |
| - sat on a mat | |
| - #stop | |
| - watching a rat | |
| -#end if | |
| -in a flat. | |
| -\end{verbatim} | |
| - | |
| -will print | |
| -\begin{verbatim} | |
| -A cat | |
| - sat on a mat | |
| -\end{verbatim} | |
| - | |
| -And | |
| -\begin{verbatim} | |
| -A cat | |
| -#block action | |
| - sat on a mat | |
| - #stop | |
| - watching a rat | |
| -#end block | |
| -in a flat. | |
| -\end{verbatim} | |
| - | |
| -will print | |
| - | |
| -\begin{verbatim} | |
| -A cat | |
| - sat on a mat | |
| -in a flat. | |
| -\end{verbatim} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#return} | |
| -\label{flowControl.return} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#return | |
| -\end{verbatim} | |
| - | |
| - | |
| -This is used as in Python. \code{\#return} will exit the current method with a | |
| -default return value of \code{None} or the value specified. It may be used | |
| -only inside a \code{\#def} or a \code{\#block}. | |
| - | |
| -Note that \code{\#return} is different from the \code{\#stop} directive, | |
| -which returns the sum of all text output from the method in which it is called. | |
| -The following examples illustrate this point: | |
| - | |
| -\begin{verbatim} | |
| -1 | |
| -$test[1] | |
| -3 | |
| -#def test | |
| -1.5 | |
| -#if 1 | |
| -#return '123' | |
| -#else | |
| -99999 | |
| -#end if | |
| -#end def | |
| -\end{verbatim} | |
| - | |
| -will produce | |
| -\begin{verbatim} | |
| -1 | |
| -2 | |
| -3 | |
| -\end{verbatim} | |
| - | |
| -while | |
| -\begin{verbatim} | |
| -1 | |
| -$test | |
| -3 | |
| -#def test | |
| -1.5 | |
| -#if 1 | |
| -#stop | |
| -#else | |
| -99999 | |
| -#end if | |
| -#end def | |
| -\end{verbatim} | |
| - | |
| -will produce | |
| -\begin{verbatim} | |
| -1 | |
| -1.5 | |
| -3 | |
| -\end{verbatim} | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| diff --git a/docs/users_guide_src/gettingStarted.tex b/docs/users_guide_src/gettingStarted.tex | |
| deleted file mode 100755 | |
| index 69a3136..0000000 | |
| --- a/docs/users_guide_src/gettingStarted.tex | |
| +++ /dev/null | |
| @@ -1,266 +0,0 @@ | |
| -\section{Getting Started} | |
| -\label{gettingStarted} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Requirements} | |
| -\label{gettingStarted.requirements} | |
| - | |
| -Cheetah requires Python release 2.0 or greater, and 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 (\code{NameMapper.py}) if the C module is not available. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Installation} | |
| -\label{gettingStarted.install} | |
| - | |
| -To install Cheetah in your system-wide Python library: | |
| -\begin{enumerate} | |
| -\item Login as a user with privileges to install system-wide Python packages. | |
| - On POSIX systems (AIX, Solaris, Linux, IRIX, etc.), the command is normally | |
| - 'su root'. On non-POSIX systems such as Windows NT, login as an | |
| - administrator. | |
| - | |
| -\item Run \code{python setup.py install} at the command prompt. | |
| - | |
| -\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} | |
| - | |
| -Cheetah's installation is managed by Python's Distribution Utilities | |
| -('distutils'). There are many options for customization. Type \code{``python | |
| - setup.py help''} for more information. | |
| - | |
| -To install Cheetah in an alternate location -- someplace outside Python's | |
| -\code{site-packages/} directory, use one of these options: | |
| -\begin{verbatim} | |
| - python setup.py install --home /home/tavis | |
| - python setup.py install --install-lib /home/tavis/lib/python | |
| -\end{verbatim} | |
| -Either way installs to /home/tavis/lib/python/Cheetah/ . Of course, | |
| -/home/tavis/lib/python must be in your Python path in order for Python to | |
| -find Cheetah. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Files} | |
| -\label{gettingstarted.files} | |
| - | |
| -If you do the systemwide install, all Cheetah modules are installed in the | |
| -{\bf site-packages/Cheetah/} subdirectory of your standard library | |
| -directory; e.g., /opt/Python2.2/lib/python2.2/site-packages/Cheetah. | |
| - | |
| -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. | |
| - | |
| -To uninstall Cheetah, merely delete the site-packages/Cheetah/ directory. | |
| -Then delete the ``cheetah'' and ``cheetah-compile'' commands from whichever | |
| -bin/ directory they were put in. | |
| - | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{The 'cheetah' command} | |
| -\label{gettingStarted.cheetah} | |
| - | |
| -Cheetah comes with a utility \code{cheetah} that provides a command-line | |
| -interface to various housekeeping tasks. The command's first argument is | |
| -the name of the task. The following commands are currently supported: | |
| - | |
| -\begin{verbatim} | |
| -cheetah compile [options] [FILES ...] : Compile template definitions | |
| -cheetah fill [options] [FILES ...] : Fill template definitions | |
| -cheetah help : Print this help message | |
| -cheetah options : Print options help message | |
| -cheetah test : Run Cheetah's regression tests | |
| -cheetah version : Print Cheetah version number | |
| -\end{verbatim} | |
| - | |
| -You only have to type the first letter of the command: | |
| -\code{cheetah c} is the same as \code{cheetah compile}. | |
| - | |
| -The test suite is described in the next section. The \code{compile} | |
| -command will be described in section \ref{howWorks.cheetah-compile}, | |
| -and the \code{fill} command in section \ref{howWorks.cheetah-fill}. | |
| - | |
| -The depreciated \code{cheetah-compile} program does the same thing as | |
| -\code{cheetah compile}. | |
| - | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Testing your installation} | |
| -\label{gettingStarted.test} | |
| - | |
| -After installing Cheetah, you can run its self-test routine to verify it's | |
| -working properly on your system. Change directory to any directory you have | |
| -write permission in (the tests write temporary files). Do not run the tests | |
| -in the directory you installed Cheetah from, or you'll get unnecessary errors. | |
| -Type the following at the command prompt: | |
| -\begin{verbatim} | |
| -cheetah test | |
| -\end{verbatim} | |
| - | |
| -The tests will run for about three minutes and print a success/failure | |
| -message. If the tests pass, start Python in interactive mode and try the | |
| -example in the next section. | |
| - | |
| -Certain test failures are insignificant: | |
| -\begin{description} | |
| -\item{{\bf AssertionError: Template output mismatch: Expected Output = 0(end) | |
| -Actual Output = False(end)}} Python 2.3 changed the string representation of | |
| -booleans, and the tests haven't yet been updated to reflect this. | |
| -\item{{\bf AssertionError: subcommand exit status 127}} Certain tests run | |
| -``cheetah'' as a subcommand. The failure may mean the command wasn't found | |
| -in your system path. (What happens if you run ``cheetah'' on the command line?) | |
| -The failure also happens on some Windows systems for unknown reasons. This | |
| -failure has never been observed outside the test suite. Long term, we plan to | |
| -rewrite the tests to do a function call rather than a subcommand, which will | |
| -also make the tests run significantly faster. | |
| -\item{{\bf ImportError: No module named SampleBaseClass}} The test tried to | |
| -write a temporary module in the current directory and \code{import} it. Reread | |
| -the first paragraph in this section about the current directory. | |
| -\item{{\bf ImportError: No module named tmp}} May be the same problem as | |
| -SampleBaseClass; let us know if changing the current directory doesn't work. | |
| -\end{description} | |
| - | |
| -If any other 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 | |
| -\item your version of Python | |
| -\item your operating system | |
| -\item whether you have changed anything in the Cheetah installation | |
| -\end{enumerate} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Quickstart tutorial} | |
| -\label{gettingStarted.tutorial} | |
| - | |
| -This tutorial briefly introduces how to use Cheetah from the Python prompt. | |
| -The following chapters will discuss other ways to use templates and more of | |
| -Cheetah's features. | |
| - | |
| -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 in an | |
| -interactive Python session. \code{t} is the Template instance. Lines prefixed | |
| -with \code{>>>} and \code{...} are user input. The remaining lines are Python | |
| -output. | |
| - | |
| -\begin{verbatim} | |
| ->>> from Cheetah.Template import Template | |
| ->>> templateDef = """ | |
| -... <HTML> | |
| -... <HEAD><TITLE>$title</TITLE></HEAD> | |
| -... <BODY> | |
| -... $contents | |
| -... ## this is a single-line Cheetah comment and won't appear in the output | |
| -... #* This is a multi-line comment and won't appear in the output | |
| -... blah, blah, blah | |
| -... *# | |
| -... </BODY> | |
| -... </HTML>""" | |
| ->>> nameSpace = {'title': 'Hello World Example', 'contents': 'Hello World!'} | |
| ->>> t = Template(templateDef, searchList=[nameSpace]) | |
| ->>> print t | |
| - | |
| -<HTML> | |
| -<HEAD><TITLE>Hello World Example</TITLE></HEAD> | |
| -<BODY> | |
| -Hello World! | |
| -</BODY> | |
| -</HTML> | |
| ->>> print t # print it as many times as you want | |
| - [ ... same output as above ... ] | |
| ->>> nameSpace['title'] = 'Example #2' | |
| ->>> nameSpace['contents'] = 'Hiya Planet Earth!' | |
| ->>> print t # Now with different plug-in values. | |
| -<HTML> | |
| -<HEAD><TITLE>Example #2</TITLE></HEAD> | |
| -<BODY> | |
| -Hiya Planet Earth! | |
| -</BODY> | |
| -</HTML> | |
| - | |
| -\end{verbatim} | |
| - | |
| -Since Cheetah is extremely flexible, you can achieve the same result this | |
| -way: | |
| - | |
| -\begin{verbatim} | |
| ->>> t2 = Template(templateDef) | |
| ->>> t2.title = 'Hello World Example!' | |
| ->>> t2.contents = 'Hello World' | |
| ->>> print t2 | |
| - [ ... same output as the first example above ... ] | |
| ->>> t2.title = 'Example #2' | |
| ->>> t2.contents = 'Hello World!' | |
| ->>> print t2 | |
| - [ ... same as Example #2 above ... ] | |
| -\end{verbatim} | |
| - | |
| -Or this way: | |
| - | |
| -\begin{verbatim} | |
| ->>> class Template3(Template): | |
| ->>> title = 'Hello World Example!' | |
| ->>> contents = 'Hello World!' | |
| ->>> t3 = Template3(templateDef) | |
| ->>> print t3 | |
| - [ ... you get the picture ... ] | |
| -\end{verbatim} | |
| - | |
| -The template definition can also come from a file instead of a string, | |
| -as we will see in section \ref{howWorks.constructing}. | |
| - | |
| -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 | |
| -\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 | |
| -in the generated class. You can also create methods the same way. | |
| -You can even use inheritance to arrange your templates in a hierarchy, | |
| -with more specific templates overriding certain parts of more general | |
| -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 one Python statement: | |
| - | |
| -\begin{verbatim} | |
| ->>> print Template("Templates are pretty useless without placeholders.") | |
| -Templates are pretty useless without placeholders. | |
| -\end{verbatim} | |
| - | |
| -You use a precompiled template the same way, except you don't provide | |
| -a template definition since it was already established: | |
| - | |
| -\begin{verbatim} | |
| -from MyPrecompiledTemplate import MyPrecompiledTemplate | |
| -t = MyPrecompiledTemplate() | |
| -t.name = "Fred Flintstone" | |
| -t.city = "Bedrock City" | |
| -print t | |
| -\end{verbatim} | |
| - | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| - | |
| diff --git a/docs/users_guide_src/glossary.tex b/docs/users_guide_src/glossary.tex | |
| deleted file mode 100644 | |
| index 4ee2d9b..0000000 | |
| --- a/docs/users_guide_src/glossary.tex | |
| +++ /dev/null | |
| @@ -1,96 +0,0 @@ | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\section{Vocabulary} | |
| -\label{glossary} | |
| -\label{vocabulary} | |
| - | |
| -{\bf Template} is an informal term meaning a template definition, a | |
| -template instance or a template class. A {\bf template definition} is what | |
| -the human {\bf template maintainer} writes: a string consisting of text, | |
| -placeholders and directives. {\bf Placeholders} are variables that will be | |
| -looked up when the template is filled. {\bf Directives} are commands to be | |
| -executed when the template is filled, or instructions to the Cheetah compiler. | |
| -The conventional suffix for a file containing a template definition is | |
| -{\bf .tmpl}. | |
| - | |
| -There are two things you can do with a template: compile it or fill it. | |
| -{\bf Filling} is the reason you have a template in the first place: | |
| -to get a finished string out of it. Compiling is a necessary prerequisite: the | |
| -{\bf Cheetah compiler} takes a template definition and produces Python code | |
| -to create the finished string. Cheetah provides several ways to compile | |
| -and fill templates, either as one step or two. | |
| - | |
| -Cheetah's compiler produces a subclass of \code{Cheetah.Template} | |
| -specific to that template definition; this is called the {\bf generated | |
| -class}. A {\bf template instance} is an instance of a generated class. | |
| - | |
| -If the user calls the \code{Template} constructor directly (rather than a | |
| -subclass constructor), s/he will get what appears to be an instance of | |
| -\code{Template} but is actually a subclass created on-the-fly. | |
| - | |
| -The user can make the subclass explicit by using the ``cheetah compile'' | |
| -command to write the template class to a Python module. Such a module is | |
| -called a {\bf .py template module}. | |
| - | |
| -The {\bf Template Definition Language} -- or the ``Cheetah language'' for short | |
| --- is the syntax rules governing placeholders and directives. These are | |
| -discussed in sections \ref{language} and following in this Guide. | |
| - | |
| -To fill a template, you call its {\bf main method}. This is normally | |
| -\code{.respond()}, but it may be something else, and you can use the | |
| -\code{\#implements} directive to choose the method name. (Section | |
| -\ref{inheritanceEtc.implements}. | |
| - | |
| -A {\bf template-servlet} is a .py template module in a Webware servlet | |
| -directory. Such templates can be filled directly through the web by requesting | |
| -the URL. ``Template-servlet'' can also refer to the instance being filled by | |
| -a particular web request. If a Webware servlet that is not a | |
| -template-servlet invokes a template, that template is not a template-servlet | |
| -either. | |
| - | |
| -A {\bf placeholder tag} is the substring in the template | |
| -definition that is the placeholder, including the start and end delimeters (if | |
| -there is an end delimeter). The {\bf placeholder name} is the same but without | |
| -the delimeters. | |
| - | |
| -Placeholders consist of one or more {\bf identifiers} separated by periods | |
| -(e.g., \code{a.b}). Each identifier must follow the same rules as Python | |
| -identifiers; that is, a letter or underscore followed by one or more letters, | |
| -digits or underscores. (This is the regular expression | |
| -\verb+[A-Za-z_][A-Za-z0-9_]*+.) | |
| - | |
| -The first (or only) identifier of a placeholder name represents a {\bf | |
| -variable} to be looked up. Cheetah looks up variables in various {\bf | |
| -namespaces}: the searchList, local variables, and certain other places. The | |
| -searchList is a list of objects ({\bf containers}) with attributes | |
| -and/or keys: each container is a namespace. Every template instance has | |
| -exactly one searchList. Identifiers after the first are looked up only in | |
| -the parent object. The final value after all lookups have been performed is | |
| -the {\bf placeholder value}. | |
| - | |
| -Placeholders may occur in three positions: top-level, expression and LVALUE. | |
| -{\bf Top-level} placeholders are those in ordinary text (``top-level text''). | |
| -{\bf Expression} placeholders are those in Python expressions. | |
| -{\bf LVALUE} placeholders are those naming a variable to receive a value. | |
| -(LVALUE is computerese for ``the left side of the equal sign''.) Section | |
| -\ref{language.placeholders.positions} explains the differences between these | |
| -three positions. | |
| - | |
| -The routine that does the placeholder lookups is called the {\bf NameMapper}. | |
| -Cheetah's NameMapper supports universal dotted notation and autocalling. | |
| -{\bf Universal dotted notation} means that keys may be written as if they were | |
| -attributes: \code{a.b} instead of \code{a['b']}. {\bf Autocalling} means that | |
| -if any identifier's value is found to be a function or method, Cheetah will | |
| -call it without arguments if there is no \verb+()+ following. More about the | |
| -NameMapper is in section \ref{language.namemapper}. | |
| - | |
| -Some directives are multi-line, meaning they have a matching {\bf \#end} tag. | |
| -The lines of text between the start and end tags is the {\bf body} of the | |
| -directive. Arguments on the same line as the start tag, in contrast, are | |
| -considered part of the directive tag. More details are in section | |
| -\ref{language.directives.syntax} (Directive Syntax Rules). | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| - | |
| -% # vim: sw=4 ts=4 expandtab | |
| diff --git a/docs/users_guide_src/howItWorks.tex b/docs/users_guide_src/howItWorks.tex | |
| deleted file mode 100755 | |
| index 4efa22f..0000000 | |
| --- a/docs/users_guide_src/howItWorks.tex | |
| +++ /dev/null | |
| @@ -1,420 +0,0 @@ | |
| -\section{How Cheetah Works} | |
| -\label{howWorks} | |
| - | |
| -As mentioned before, you can do two things with templates: compile them and | |
| -fill them. (Actually you can query them too, to see their attributes and | |
| -method values.) Using templates in a Python program was shown in section | |
| -\ref{gettingStarted.tutorial} (Quickstart tutorial). Here we'll focus on | |
| -compiling and filling templates from the shell command line, and how to make | |
| -.py template modules. The compiling information here is also important for | |
| -template-servlets, which will be otherwise covered in chapter \ref{webware} | |
| -(Webware). | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Constructing Template Objects} | |
| -\label{howWorks.templateClass} | |
| -\label{howWorks.constructing} | |
| - | |
| -The heart of Cheetah is the \code{Template} class in the | |
| -\code{Cheetah.Template} module. You can use it directly if you have a | |
| -template definition in hand, or indirectly through a precompiled template, | |
| -which is a subclass. The constructor accepts the following keyword | |
| -arguments. (If you're a beginner, learn the first three arguments now; | |
| -the others are much less frequent.) | |
| - | |
| -\begin{description} | |
| -\item{{\bf source}} | |
| - The template definition as a string. You may omit the \code{source=} | |
| - prefix {\em if it's the first argument}, as in all the examples below. | |
| - The source can be a string literal in your module, or perhaps a string | |
| - you 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. | |
| - By convention, template definition files have the extension | |
| - {\bf .tmpl}. | |
| -\item{{\bf searchList}} | |
| - A list of objects to add to the searchList. The attributes/keys of these | |
| - objects will be consulted for \code{\$placeholder} lookup. | |
| -\item{{\bf filter}} | |
| - A class that will format every \code{\$placeholder} value. You may | |
| - specify a class object or string. If a class object, | |
| - it must be a subclass of \code{Cheetah.Filters.Filter}. If a string, it | |
| - must be the name of one of the filters in filtersLib module (see next | |
| - item). | |
| - (You may also use the \code{\#filter} directive (section | |
| - \ref{output.filter}) to switch filters at runtime.) | |
| -\item{{\bf filtersLib}} | |
| - A module containing the filters Cheetah should look up by name. The | |
| - default is \code{Cheetah.Filters}. All classes in this module that are | |
| - subclasses of \code{Cheetah.Filters.Filter} are considered filters. | |
| -\item{{\bf errorCatcher}} | |
| - A class to handle \code{\$placeholder} errors. You may | |
| - specify a class object or string. If a class object, | |
| - it must be a subclass of \code{Cheetah.ErrorCatchers.ErrorCatcher}. | |
| - If a string, it must be the name of one of the error catchers in | |
| - \code{Cheetah.ErrorCatchers}. This is similar to the | |
| - \code{\#errorCatcher} directive | |
| - (section \ref{errorHandling.errorCatcher}). | |
| -\item{{\bf compilerSettings}} | |
| - A dictionary (or dictionary hierarchy) of settings that change Cheetah's | |
| - behavior. Not yet documented. | |
| -\end{description} | |
| - | |
| -To use \code{Template} directly, you {\em must} specify either \code{source} | |
| -or \code{file}, but not both. To use a precompiled template, you | |
| -{\em must not} specify either one, because the template definition is already | |
| -built into the class. The other arguments, however, may be used in either case. | |
| -Here are typical ways to create a template instance: | |
| -\begin{description} | |
| -\item{\code{t = Template("The king is a \$placeholder1.")}} | |
| - \\ Pass the template definition as a string. | |
| -\item{\code{t = Template(file="fink.tmpl")}} | |
| - \\ Read the template definition from a file named "fink.tmpl". | |
| -\item{\code{t = Template(file=f)}} | |
| - \\ Read the template definition from file-like object 'f'. | |
| -\item{\code{t = Template("The king is a \$placeholder1.", searchList=[dict, obj])}} | |
| - \\ Pass the template definition as a string. Also pass two namespaces for | |
| - the searchList: a dictionary 'dict' and an instance 'obj'. | |
| -\item{\code{t = Template(file="fink.txt", searchList=[dict, obj])}} | |
| - \\ Same, but pass a filename instead of a string. | |
| -\item{\code{t = Template(file=f, searchList=[dict, obj])}} | |
| - \\ Same with a file object. | |
| -\end{description} | |
| - | |
| -If you use \code{Template} directly, the template definition will be compiled | |
| -the first time it's filled. Compilation creates a template-specific class | |
| -called the {\bf generated class}, which is a subclass of \code{Template}. It | |
| -then dynamically switches the instance so it's now an instance of this class. | |
| -Don't worry if you don't understand this; it works. | |
| - | |
| -% By convention, you give a file containing a template definition the extension | |
| -% {\bf .tmpl}. | |
| - | |
| -When you precompile a template using the ``cheetah compile'' command, it | |
| -writes the generated class to a file. Actually, what it writes is the source | |
| -code for a Python module that contains the generated class. Again, the | |
| -generated class is a subclass of \code{Template}. We call the generated | |
| -module a {\bf .py template module}. Thus, if you always use | |
| -precompiled templates (as many people do), you can view Cheetah as a | |
| -convenient front-end for writing certain kinds of Python modules, the way | |
| -you might use a graphical dialog builder to make a dialog module. | |
| - | |
| -Precompiled templates provide a slight performance boost because the | |
| -compilation happens only once rather than every time it's instantiated. | |
| -Also, once you import the .py template module and allow Python to create a | |
| -.pyc or .pyo file, you skip the Python compiler too. The speed advantage | |
| -of all this is negligable, but it may make a difference in programs that | |
| -use templates many times a second. | |
| - | |
| -\code{Template} subclasses Webware's \code{Servlet} class when available, | |
| -so the generated class can be used as a Webware servlet. This is practical | |
| -only with precompiled templates. | |
| - | |
| -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. | |
| -You can also call any \code{\#def} or \code{\#block} method and it will fill | |
| -just that portion of the template, although this feature is not often used. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{``cheetah compile'' and .py template modules} | |
| -\label{howWorks.cheetah-compile} | |
| - | |
| -To create a .py template module, do either of these: | |
| - | |
| -\begin{verbatim} | |
| -cheetah compile [options] [FILES ...] | |
| -cheetah c [options] [FILES ...] | |
| -\end{verbatim} | |
| - | |
| -The following options are supported: | |
| -\begin{verbatim} | |
| - --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) | |
| -\end{verbatim} | |
| - | |
| -{\em Note:} If Cheetah can't find your input files, or if it puts output files | |
| -in the wrong place, use the \code{--debug} option to see what Cheetah thinks | |
| -of your command line. | |
| - | |
| -The most basic usage is: | |
| -\begin{verbatim} | |
| -cheetah compile a.tmpl : writes a.py | |
| -cheetah compile a.tmpl b.tmpl : writes a.py and b.py | |
| -\end{verbatim} | |
| - | |
| -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): | |
| -\begin{verbatim} | |
| -cheetah compile a : writes a.py (from a.tmpl) | |
| -cheetah compile a b : writes a.py and b.py | |
| -\end{verbatim} | |
| - | |
| -You can override the default input extension and output extension | |
| -(\code{py}) using \code{--iext} and \code{--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 \code{-R} option to recurse subdirectories: | |
| -\begin{verbatim} | |
| -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 | |
| -\end{verbatim} | |
| -When recursing, only regular files that end in the input extension (.tmpl) are | |
| -considered source files. All other filenames are ignored. | |
| - | |
| -The options \code{--idir} and \code{--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): | |
| -\begin{verbatim} | |
| -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 | |
| -\end{verbatim} | |
| - | |
| -``cheetah compile'' overwrites any existing \code{.py} file it finds, after | |
| -backing it up to FILENAME.py\_bak (unless you specify \code{--nobackup}). 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. | |
| - | |
| -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 | |
| -{\em directory} it's in does not have to be an identifier. ({\em 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 \code{--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. | |
| -\begin{verbatim} | |
| -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 | |
| -\end{verbatim} | |
| - | |
| -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 \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 certain | |
| -\code{\$author} value. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{``cheetah fill''} | |
| -\label{howWorks.cheetah-fill} | |
| - | |
| -You can compile and fill a large number of template definitions from the | |
| -command line in one step using \code{cheetah fill}. This compiles the template | |
| -in memory; it does {\em not} save the .py template module to disk. Instead it | |
| -writes a finished output file, which has the extension \code{.html} by default. | |
| -All the options to \code{cheetah compile} work the same way here, and there are | |
| -also a couple additional options: | |
| -\begin{verbatim} | |
| - --env : put the environment in the searchList | |
| - --pickle FILE : unpickle FILE and put that object in the searchList | |
| -\end{verbatim} | |
| - | |
| -Because you can't provide a searchList on the command line, the | |
| -templates must either contain or inherit all the variables it needs, | |
| -or use the \code{--env} and \code{--pickle} options to | |
| -provide additional variables. | |
| - | |
| -Examples: | |
| -\begin{verbatim} | |
| -cheetah fill a.tmpl : writes a.html | |
| -cheetah fill a.tmpl b.tmpl : writes a.html and b.html | |
| -cheetah f --oext txt a : writes a.txt (from a.tmpl) | |
| -\end{verbatim} | |
| - | |
| -Using \code{--env} may have security or reliability implications because the | |
| -environment normally contains lots of variables you inherited rather than | |
| -defining yourself. If any of these variables override any of yours (say a | |
| -\code{\#def}), you will get incorrect output, may reveal private information, | |
| -and may get an exception due to the variable being an unexpected type | |
| -(environmental variables are always strings). Your calling program may wish | |
| -to clear out the environment before setting environmental variables for the | |
| -template. | |
| - | |
| -There are two other differences between ``cheetah compile'' and ``cheetah fill''. | |
| -Cheetah doesn't create \_\_init\_\_.py files when creating directories in | |
| -fill mode. Also, the source filenames don't have to be identifiers. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Some trivia about .py template modules} | |
| -\label{howWorks.pyTrivia} | |
| - | |
| -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} | |
| -The number is $Test.unittest.main. | |
| -\end{verbatim} | |
| - | |
| -compiles to this: | |
| - | |
| -\begin{verbatim} | |
| -write("The number is ") | |
| -write(filter(VFN(VFS(SL,"Test.unittest",1),"main",0) | |
| -write(".") | |
| -\end{verbatim} | |
| - | |
| -The Cheetah Developers' Guide looks at .py template | |
| -modules in depth, and shows 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. | |
| - | |
| -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. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Running a .py template module as a standalone program} | |
| -\label{howWorks.standalone} | |
| - | |
| -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 | |
| -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. You can either set default values in the template | |
| -itself (via the \code{\#attr} or \code{\#def} directives) or in a Python | |
| -superclass, or use the \code{--env} or \code{--pickle} command-line options, | |
| -which work just like their ``cheetah fill'' counterparts. | |
| - | |
| -Run \code{python FILENAME.py --help} to see all the command-line | |
| -options your .py template module accepts. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\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. | |
| - | |
| -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. That's | |
| -how Cheetah makes templates usable as Webware servlets, by subclassing | |
| -\code{Servlet}. This technique should be possible for non-Webware systems | |
| -too. | |
| - | |
| -({\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 | |
| deleted file mode 100755 | |
| index 019b042..0000000 | |
| --- a/docs/users_guide_src/inheritanceEtc.tex | |
| +++ /dev/null | |
| @@ -1,492 +0,0 @@ | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\section{Import, Inheritance, Declaration and Assignment} | |
| -\label{inheritanceEtc} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#import and \#from directives} | |
| -\label{inheritanceEtc.import} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#import MODULE_OR_OBJECT [as NAME] [, ...] | |
| -#from MODULE import MODULE_OR_OBJECT [as NAME] [, ...] | |
| -\end{verbatim} | |
| - | |
| - | |
| -The \code{\#import} and \code{\#from} directives are used to make external | |
| -Python modules or objects available to placeholders. The syntax is identical | |
| -to the import syntax in Python. Imported modules are visible globally to all | |
| -methods in the generated Python class. | |
| - | |
| -\begin{verbatim} | |
| -#import math | |
| -#import math as mathModule | |
| -#from math import sin, cos | |
| -#from math import sin as _sin | |
| -#import random, re | |
| -#from mx import DateTime # ## Part of Egenix's mx package. | |
| -\end{verbatim} | |
| - | |
| -After the above imports, \code{\$math}, \code{\$mathModule}, | |
| -\code{\$sin}, \code{\$cos} and \code{\$\_sin}, \code{\$random}, \code{\$re} | |
| -and \code{\$DateTime} may be used in \code{\$placeholders} and expressions. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#extends} | |
| -\label{inheritanceEtc.extends} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#extends CLASS | |
| -\end{verbatim} | |
| - | |
| - | |
| -All templates are subclasses of \code{Cheetah.Template.Template}. However, | |
| -it's possible for a template to subclass another template or a pure Python | |
| -class. This is where \code{\#extends} steps in: it | |
| -specifies the parent class. It's equivalent to PSP's \code{``@page extends=''} | |
| -directive. | |
| - | |
| -Cheetah imports the class mentioned in an \code{\#extends} directive | |
| -automatically if you haven't imported it yet. The implicit importing works | |
| -like this: | |
| - | |
| -\begin{verbatim} | |
| -#extends Superclass | |
| -## Implicitly does '#from Superclass import Superclass'. | |
| - | |
| -#extends Cheetah.Templates.SkeletonPage | |
| -## Implicitly does '#from Cheetah.Templates.SkeletonPage import SkeletonPage'. | |
| -\end{verbatim} | |
| - | |
| -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 \code{\#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 \code{Template} | |
| -methods such as \code{.\_\_init\_\_} or \code{.awake}, be sure to call | |
| -the superclass method in your method or things will break. Examples of calling | |
| -the superclass method are in section \ref{tips.callingSuperclassMethods}. | |
| -A list of all superclass methods is in section | |
| -\ref{tips.allMethods}. | |
| - | |
| -In all cases, the root superclass must be \code{Template}. If your | |
| -bottommost class is a template, simply omit the \code{\#extends} in it and it | |
| -will automatically inherit from \code{Template}. {\em If your bottommost class | |
| -is a pure Python class, it must inherit from \code{Template} explicitly: } | |
| -\begin{verbatim} | |
| -from Cheetah.Template import Template | |
| -class MyPurePythonClass(Template): | |
| -\end{verbatim} | |
| - | |
| -If you're not keen about having your Python classes inherit from | |
| -\code{Template}, create a tiny glue class that inherits both from your | |
| -class and from \code{Template}. | |
| - | |
| -Before giving any examples we'll stress that Cheetah does {\em 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: | |
| - | |
| -\begin{verbatim} | |
| -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 | |
| -\end{verbatim} | |
| - | |
| -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. | |
| - | |
| -{\em Whenever you use \code{\#extends}, you often need \code{\#implements} | |
| -too,} as in step 2 above. Read the next section to understand what | |
| -\code{\#implements} is and when to use it. | |
| - | |
| -% @@MO: Edmund suggests making some diagrams of inheritance chains. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#implements} | |
| -\label{inheritanceEtc.implements} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#implements METHOD | |
| -\end{verbatim} | |
| - | |
| -You can call any \code{\#def} or \code{\#block} method directly and get its | |
| -outpt. The top-level content -- all the text/placeholders/directives outside any | |
| -\code{\#def}/\code{\#block} -- gets concatenated and wrapped in a ``main | |
| -method'', by default \code{.respond()}. So if you call \code{.respond()}, you | |
| -get the ``whole template output''. When Webware calls \code{.respond()}, | |
| -that's what it's doing. And when you do 'print t' or 'str(t)' on a template | |
| -instance, you're taking advantage of the fact that Cheetah makes | |
| -\code{.\_\_str\_\_()} an alias for the main method. | |
| - | |
| -That's all fine and dandy, but what if your application prefers to call another | |
| -method name rather than \code{.respond()}? What if it wants to call, say, | |
| -\code{.send\_output()} instead? That's where \code{\#implements} steps in. It | |
| -lets you choose the name for the main method. Just put this in your template | |
| -definition: | |
| -\begin{verbatim} | |
| -#implements send_output | |
| -\end{verbatim} | |
| - | |
| -When one template extends another, every template in the inheritance chain | |
| -has its own main method. To fill the template, you invoke exactly one of | |
| -these methods and the others are ignored. The method you call may be in any of | |
| -the templates in the inheritance chain: the base template, the leaf template, | |
| -or any in between, depending on how you structure your application. So you | |
| -have two problems: (1) calling the right method name, and (2) preventing an | |
| -undesired same-name subclass method from overriding the one you want to call. | |
| - | |
| -Cheetah assumes the method you will call is \code{.respond()} because | |
| -that's what Webware calls. It further assumes the desired main method is the | |
| -one in the lowest-level base template, because that works well with | |
| -\code{\#block} as described in the Inheritance Approach for building Webware | |
| -servlets (section \ref{webware.inheritance}), which was originally the | |
| -principal use for Cheetah. So when you use \code{\#extends}, Cheetah changes | |
| -that template's main method to \code{.writeBody()} to get it out of the way and | |
| -prevent it from overriding the base template's \code{.respond()}. | |
| - | |
| -Unfortunately this assumption breaks down if the template is used in other | |
| -ways. For instance, you may want to use the main method in the highest-level | |
| -leaf template, and treat the base template(s) as merely a library of | |
| -methods/attributes. In that case, the leaf template needs \code{\#implements | |
| -respond} to change its main method name back to \code{.respond()} (or whatever | |
| -your application desires to call). Likewise, if your main method is in one of the | |
| -intermediate templates in an inheritance chain, that template needs | |
| -\code{\#implements respond}. | |
| - | |
| -The other way the assumption breaks down is if the main method {\em is} in | |
| -the base template but that template extends a pure Python class. Cheetah sees | |
| -the \code{\#extends} and dutifully but incorrectly renames the method to | |
| -\code{.writeBody()}, so you have to use \code{\#implements respond} to change | |
| -it back. Otherwise the dummy \code{.respond()} in \code{Cheetah.Template} | |
| -is found, which outputs... nothing. {\bf So if you're using \code{\#extends} | |
| -and get no output, the {\em first} thing you should think is, ``Do I need to | |
| -add \code{\#implements respond} somewhere?'' } | |
| - | |
| - | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#set} | |
| -\label{inheritanceEtc.set} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#set [global] $var = EXPR | |
| -\end{verbatim} | |
| - | |
| -\code{\#set} is used to create and update local variables at run time. | |
| -The expression may be any Python expression. | |
| -Remember to preface variable names with \$ unless they're part of an | |
| -intermediate result in a list comprehension. | |
| - | |
| -Here are some examples: | |
| -\begin{verbatim} | |
| -#set $size = $length * 1096 | |
| -#set $buffer = $size + 1096 | |
| -#set $area = $length * $width | |
| -#set $namesList = ['Moe','Larry','Curly'] | |
| -#set $prettyCountry = $country.replace(' ', ' ') | |
| -\end{verbatim} | |
| - | |
| -\code{\#set} variables are useful to assign a short name to a | |
| -\code{\$deeply.nested.value}, to a calculation, or to a printable version of | |
| -a value. The last example above converts any spaces in the 'country' value | |
| -into HTML non-breakable-space entities, to ensure the entire value appears on | |
| -one line in the browser. | |
| - | |
| -\code{\#set} variables are also useful in \code{\#if} expressions, but | |
| -remember that complex logical routines should be coded in Python, not in | |
| -Cheetah! | |
| -\begin{verbatim} | |
| -#if $size > 1500 | |
| - #set $adj = 'large' | |
| -#else | |
| - #set $adj = 'small' | |
| -#end if | |
| -\end{verbatim} | |
| -Or Python's one-line equivalent, "A and B or C". Remember that in this case, | |
| -B must be a true value (not None, '', 0, [] or {}). | |
| -\begin{verbatim} | |
| -#set $adj = $size > 1500 and 'large' or 'small' | |
| -\end{verbatim} | |
| -(Note: Cheetah's one-line \code{\#if} will not work for this, since it | |
| -produces output rather than setting a variable. | |
| - | |
| -You can also use the augmented assignment operators: | |
| -\begin{verbatim} | |
| -## Increment $a by 5. | |
| -#set $a += 5 | |
| -\end{verbatim} | |
| - | |
| -By default, \code{\#set} variables are not visible in method calls or include | |
| -files unless you use the \code{global} attribute: \code{\#set global \$var = | |
| -EXPRESSION}. Global variables are visible in all methods, nested templates and | |
| -included files. Use this feature with care to prevent surprises. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#del} | |
| -\label{inheritanceEtc.del} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#del $var | |
| -\end{verbatim} | |
| - | |
| -\code{\#del} is the opposite of \code{\#set}. It deletes a {\em local} | |
| -variable. Its usage is just like Python's \code{del} statement: | |
| -\begin{verbatim} | |
| -#del $myVar | |
| -#del $myVar, $myArray[5] | |
| -\end{verbatim} | |
| - | |
| -Only local variables can be deleted. There is no directive to delete a | |
| -\code{\#set global} variable, a searchList variable, or any other type of | |
| -variable. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#attr} | |
| -\label{inheritanceEtc.attr} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#attr $var = EXPR | |
| -\end{verbatim} | |
| - | |
| -The \code{\#attr} directive creates class attributes in the generated Python | |
| -class. It should be used to assign simple Python literals such as numbers or | |
| -strings. In particular, the expression must {\em not} depend on searchList | |
| -values or \code{\#set} variables since those are not known at compile time. | |
| - | |
| -\begin{verbatim} | |
| -#attr $title = "Rob Roy" | |
| -#attr $author = "Sir Walter Scott" | |
| -#attr $version = 123.4 | |
| -\end{verbatim} | |
| - | |
| -This template or any child template can output the value thus: | |
| -\begin{verbatim} | |
| -$title, by $author, version $version | |
| -\end{verbatim} | |
| - | |
| -If you have a library of templates derived from etexts | |
| -(\url{http://www.gutenberg.org/}), you can extract the titles and authors | |
| -and put them in a database (assuming the templates have been compiled into | |
| -.py template modules): | |
| - | |
| -%\begin{verbatim} | |
| -%import glob | |
| -% | |
| -%\end{verbatim} | |
| -% | |
| -% @@MO: Finish this example. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#def} | |
| -\label{inheritanceEtc.def} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#def METHOD[(ARGUMENTS)] | |
| -#end def | |
| -\end{verbatim} | |
| - | |
| -Or the one-line variation: | |
| -\begin{verbatim} | |
| -#def METHOD[(ARGUMENTS)] : TEXT_AND_PLACEHOLDERS | |
| -\end{verbatim} | |
| - | |
| - | |
| -The \code{\#def} directive is used to define new methods in the generated | |
| -Python class, or to override superclass methods. It is analogous to Python's | |
| -\code{def} statement. The directive is silent, meaning it does not itself | |
| -produce any output. However, the content of the method will be inserted into | |
| -the output (and the directives executed) whenever the method is later called by | |
| -a \$placeholder. | |
| - | |
| -\begin{verbatim} | |
| -#def myMeth() | |
| -This is the text in my method | |
| -$a $b $c(123) ## these placeholder names have been defined elsewhere | |
| -#end def | |
| - | |
| -## and now use it... | |
| -$myMeth() | |
| -\end{verbatim} | |
| - | |
| -The arglist and parentheses can be omitted: | |
| -\begin{verbatim} | |
| -#def myMeth | |
| -This is the text in my method | |
| -$a $b $c(123) | |
| -#end def | |
| - | |
| -## and now use it... | |
| -$myMeth | |
| -\end{verbatim} | |
| - | |
| -Methods can have arguments and have defaults for those arguments, just like | |
| -in Python. Remember the \code{\$} before variable names: | |
| -\begin{verbatim} | |
| -#def myMeth($a, $b=1234) | |
| -This is the text in my method | |
| -$a - $b | |
| -#end def | |
| - | |
| -## and now use it... | |
| -$myMeth(1) | |
| -\end{verbatim} | |
| - | |
| -The output from this last example will be: | |
| - | |
| -\begin{verbatim} | |
| -This is the text in my method | |
| -1 - 1234 | |
| -\end{verbatim} | |
| - | |
| -There is also a single line version of the \code{\#def} directive. | |
| -{\bf Unlike the multi-line directives, it uses a colon (:) to delimit the method | |
| -signature and body}: | |
| -\begin{verbatim} | |
| -#attr $adj = 'trivial' | |
| -#def myMeth: This is the $adj method | |
| -$myMeth | |
| -\end{verbatim} | |
| -Leading and trailing whitespace is stripped from the method. This is in | |
| -contrast to: | |
| -\begin{verbatim} | |
| -#def myMeth2 | |
| -This is the $adj method | |
| -#end def | |
| -\end{verbatim} | |
| -where the method includes a newline after "method". If you don't want the | |
| -newline, add \code{\#slurp}: | |
| -\begin{verbatim} | |
| -#def myMeth3 | |
| -This is the $adj method#slurp | |
| -#end def | |
| -\end{verbatim} | |
| - | |
| -Because \code{\#def} is handled at compile time, it can appear above or | |
| -below the placeholders that call it. And if a superclass placeholder | |
| -calls a method that's overridden in a subclass, it's the subclass method | |
| -that will be called. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#block ... \#end block} | |
| -\label{inheritanceEtc.block} | |
| - | |
| - | |
| -The \code{\#block} directive allows you to mark a section of your template that | |
| -can be selectively reimplemented in a subclass. It is very useful for | |
| -changing part of a template without having to copy-paste-and-edit | |
| -the entire thing. The output from a template definition that uses blocks will | |
| -be identical to the output from the same template with the \code{\#block \ldots | |
| -\#end block} tags removed. | |
| - | |
| -({\em Note:} don't be confused by the generic word `block'' in this Guide, | |
| -which means a section of code inside {\em any} \code{\#TAG \ldots \#end TAG} | |
| -pair. Thus, an if-block, for-block, def-block, block-block etc. In this | |
| -section we are talking only of block-blocks.) | |
| - | |
| -To reimplement the block, use the \code{\#def} directive. The magical effect | |
| -is that it appears to go back and change the output text {\em at the point the | |
| -original block was defined} rather than at the location of the | |
| -reimplementation. | |
| - | |
| -\begin{verbatim} | |
| -#block testBlock | |
| -Text in the contents | |
| -area of the block directive | |
| -#if $testIt | |
| -$getFoo() | |
| -#end if | |
| -#end block testBlock | |
| -\end{verbatim} | |
| - | |
| -You can repeat the block name in the \code{\#end block} directive or not, as | |
| -you wish. | |
| - | |
| -\code{\#block} directives can be nested to any depth. | |
| - | |
| -\begin{verbatim} | |
| -#block outerBlock | |
| -Outer block contents | |
| - | |
| -#block innerBlock1 | |
| -inner block1 contents | |
| -#end block innerBlock1 | |
| - | |
| -#block innerBlock2 | |
| -inner block2 contents | |
| -#end block innerBlock2 | |
| - | |
| -#end block outerBlock | |
| -\end{verbatim} | |
| - | |
| -Note that the name of the block is optional for the \code{\#end block} tag. | |
| - | |
| -Technically, \code{\#block} directive is equivalent to a \code{\#def} directive | |
| -followed immediately by a \code{\#placeholder} for the same name. In fact, | |
| -that's what Cheetah does. Which means you can use \code{\$theBlockName} | |
| -elsewhere in the template to output the block content again. | |
| - | |
| -There is a one-line \code{\#block} syntax analagous to the one-line | |
| -\code{\#def}. | |
| - | |
| -The block must not require arguments because the implicit placeholder that's | |
| -generated will call the block without arguments. | |
| - | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| diff --git a/docs/users_guide_src/introduction.tex b/docs/users_guide_src/introduction.tex | |
| deleted file mode 100755 | |
| index be34fc6..0000000 | |
| --- a/docs/users_guide_src/introduction.tex | |
| +++ /dev/null | |
| @@ -1,392 +0,0 @@ | |
| -\section{Introduction} | |
| -\label{intro} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Who should read this Guide?} | |
| -\label{intro.whoShouldRead} | |
| - | |
| -This Users' Guide provides a technical overview and reference for the | |
| -Cheetah template system. Knowledge of Python and object-oriented programming | |
| -is assumed. The emphasis in this Guide is on features useful in a wide variety | |
| -of situations. Information on less common situations and troubleshooting tips | |
| -are gradually being moved to the Cheetah FAQ. There is also a Cheetah | |
| -Developer's Guide for those who want to know what goes on under the hood. | |
| - | |
| -%% A gentler introduction for template maintainers who don't know | |
| -%% Python will be written later. | |
| - | |
| -This Guide also contains examples of integrating Cheetah with Webware for | |
| -Python. You will have to learn Webware from its own documentation in order to | |
| -build a Webware + Cheetah site. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{What is Cheetah?} | |
| -\label{intro.whatIs} | |
| - | |
| -Cheetah is a Python-powered template engine and code generator. It may be used | |
| -as a standalone utility or combined with other tools. Cheetah has | |
| -many potential uses, but web developers looking for a viable alternative to ASP, | |
| -JSP, PHP and PSP are expected to be its principle user group. | |
| - | |
| -Cheetah: | |
| -\begin{itemize} | |
| -\item generates HTML, SGML, XML, SQL, Postscript, form email, LaTeX, or any | |
| - other text-based format. It has also been used to produce Python, Java | |
| - and PHP source code. | |
| - | |
| -\item cleanly separates content, graphic design, and program code. This leads | |
| - to highly modular, flexible, and reusable site architectures; faster | |
| - development time; and HTML and program code that is easier to understand | |
| - and maintain. It is particularly well suited for team efforts. | |
| - | |
| -\item blends the power and flexibility of Python with a simple template language | |
| - that non-programmers can understand. | |
| - | |
| -\item gives template writers full access in their templates to any Python data | |
| - structure, module, function, object, or method. | |
| - | |
| -\item makes code reuse easy by providing an object-oriented interface to | |
| - templates that is accessible from Python code or other Cheetah templates. | |
| - One template can subclass another and selectively reimplement sections of | |
| - it. A compiled template {\em is} a Python class, so it can subclass a | |
| - pure Python class and vice-versa. | |
| - | |
| -\item provides a simple yet powerful caching mechanism | |
| - | |
| -%% that can dramatically improve the performance of a dynamic website. | |
| -\end{itemize} | |
| - | |
| -Cheetah integrates tightly with {\bf Webware for Python} | |
| -(\url{http://webware.sourceforge.net/}): a Python-powered application server and | |
| -persistent servlet framework. Webware provides automatic session, cookie, and | |
| -user management and can be used with almost any operating-system, web server, or | |
| -database. Through Python, it works with XML, SOAP, XML-RPC, CORBA, COM, DCOM, | |
| -LDAP, IMAP, POP3, FTP, SSL, etc.. Python supports structured exception handling, | |
| -threading, object serialization, unicode, string internationalization, advanced | |
| -cryptography and more. It can also be extended with code and libraries written | |
| -in C, C++, Java and other languages. | |
| - | |
| -Like Python, Cheetah and Webware are Open Source software and are supported by | |
| -active user communities. Together, they are a powerful and elegant framework | |
| -for building dynamic web sites. | |
| - | |
| -Like its namesake, Cheetah is fast, flexible and powerful. | |
| - | |
| -% @@MO: Repeat picture of cheetah. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{What is the philosophy behind Cheetah?} | |
| -\label{intro.philosophy} | |
| - | |
| -Cheetah's design was guided by these principles: | |
| -\begin{itemize} | |
| -\item Python for the back end, Cheetah for the front end. Cheetah was | |
| - designed to complement Python, not replace it. | |
| - | |
| -\item Cheetah's core syntax should be easy for non-programmers to learn. | |
| - | |
| -\item Cheetah should make code reuse easy by providing an object-oriented | |
| - interface to templates that is accessible from Python code or other | |
| - Cheetah templates. | |
| - | |
| -\item Python objects, functions, and other data structures should be fully | |
| - accessible in Cheetah. | |
| - | |
| -\item Cheetah should provide flow control and error handling. Logic | |
| - that belongs in the front end shouldn't be relegated to the | |
| - back end simply because it's complex. | |
| - | |
| -\item It should be easy to {\bf separate} content, graphic design, and program | |
| - code, but also easy to {\bf integrate} them. | |
| - | |
| - A clean separation makes it easier for a team of content writers, | |
| - HTML/graphic designers, and programmers to work together without stepping | |
| - on each other's toes and polluting each other's work. The HTML framework | |
| - and the content it contains are two separate things, and analytical | |
| - calculations (program code) is a third thing. Each team member should be | |
| - able to concentrate on their specialty and to implement their changes | |
| - without having to go through one of the others (i.e., the dreaded | |
| - ``webmaster bottleneck''). | |
| - | |
| - While it should be easy to develop content, graphics and program | |
| - code separately, it should be easy to integrate them together into a | |
| - website. In particular, it should be easy: | |
| - | |
| - \begin{itemize} | |
| - \item for {\bf programmers} to create reusable components and functions | |
| - that are accessible and understandable to designers. | |
| - \item for {\bf designers} to mark out placeholders for content and | |
| - dynamic components in their templates. | |
| - \item for {\bf designers} to soft-code aspects of their design that are | |
| - either repeated in several places or are subject to change. | |
| - \item for {\bf designers} to reuse and extend existing templates and thus | |
| - minimize duplication of effort and code. | |
| - \item and, of course, for {\bf content writers} to use the templates that | |
| - designers have created. | |
| - \end{itemize} | |
| - | |
| -\end{itemize} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{Why Cheetah doesn't use HTML-style tags} | |
| -\label{intro.htmlStyleTags} | |
| - | |
| -Cheetah does not use HTML/XML-style tags like some other template languages for | |
| -the following reasons: | |
| - Cheetah is not limited to HTML, | |
| - HTML-style tags are hard to distinguish from real HTML tags, | |
| - HTML-style tags are not visible in rendered HTML when something goes wrong, | |
| - HTML-style tags often lead to invalid HTML (e.g., | |
| -\code{<img src="<template-directive>">}), | |
| -Cheetah tags are less verbose and easier to understand than HTML-style tags, | |
| -and HTML-style tags aren't compatible with most WYSIWYG editors | |
| - | |
| -Besides being much more compact, Cheetah also has some advantages over | |
| -languages that put information inside the HTML tags, such as Zope Page | |
| -Templates or PHP: | |
| - HTML or XML-bound languages do not work well with other languages, | |
| - While ZPT-like syntaxes work well in many ways with WYSIWYG HTML editors, | |
| - they also give up a significant advantage of those editors -- concrete | |
| - editing of the document. When logic is hidden away in (largely | |
| - inaccessible) tags it is hard to understand a page simply by viewing it, | |
| - and it is hard to confirm or modify that logic. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Give me an example!} | |
| -\label{intro.example} | |
| - | |
| -Here's a very simple example that illustrates some of Cheetah's basic syntax: | |
| - | |
| -\begin{verbatim} | |
| - | |
| -<HTML> | |
| -<HEAD><TITLE>$title</TITLE></HEAD> | |
| -<BODY> | |
| - | |
| -<TABLE> | |
| -#for $client in $clients | |
| -<TR> | |
| -<TD>$client.surname, $client.firstname</TD> | |
| -<TD><A HREF="mailto:$client.email">$client.email</A></TD> | |
| -</TR> | |
| -#end for | |
| -</TABLE> | |
| - | |
| -</BODY> | |
| -</HTML> | |
| -\end{verbatim} | |
| - | |
| -Compare this with PSP: | |
| - | |
| -\begin{verbatim} | |
| -<HTML> | |
| -<HEAD><TITLE><%=title%></TITLE></HEAD> | |
| -<BODY> | |
| - | |
| -<TABLE> | |
| -<% for client in clients: %> | |
| -<TR> | |
| -<TD><%=client['surname']%>, <%=client['firstname']%></TD> | |
| -<TD><A HREF="mailto:<%=client['email']%>"><%=client['email']%></A></TD> | |
| -</TR> | |
| -<%end%> | |
| -</TABLE> | |
| - | |
| -</BODY> | |
| -</HTML> | |
| -\end{verbatim} | |
| - | |
| -Section \ref{gettingStarted.tutorial} has a more typical example that shows | |
| -how to get the plug-in values {\em into} Cheetah, 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. | |
| -%% - how to get data into it | |
| -%% @@MO: If you do this, reconcile this example and the one in gettingStarted. | |
| -%% Keep two examples or collapse into one? | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Give me an example of a Webware servlet!} | |
| -\label{intro.example.servlet} | |
| - | |
| -This example uses an HTML form to ask the user's name, then invokes itself | |
| -again to display a {\em personalized} friendly greeting. | |
| - | |
| -\begin{verbatim} | |
| -<HTML><HEAD><TITLE>My Template-Servlet</TITLE></HEAD><BODY> | |
| -#set $name = $request.field('name', None) | |
| -#if $name | |
| -Hello $name | |
| -#else | |
| -<FORM ACTION="" METHOD="GET"> | |
| -Name: <INPUT TYPE="text" NAME="name"><BR> | |
| -<INPUT TYPE="submit"> | |
| -</FORM> | |
| -#end if | |
| -</BODY></HTML> | |
| -\end{verbatim} | |
| - | |
| -To try it out for yourself on a Webware system: | |
| -\begin{enumerate} | |
| -\item copy the template definition to a file {\bf test.tmpl} in your | |
| - Webware servlet directory. | |
| -\item Run ``\code{cheetah compile test.tmpl}''. This produces | |
| - {\bf test.py} (a .py template module) in the same directory. | |
| -\item In your web browser, go to {\bf test.py}, using whatever site and | |
| - directory is appropriate. Depending on your Webware configuration, you may | |
| - also be able to go to {\bf test}. | |
| -\end{enumerate} | |
| - | |
| -At the first request, field `name' will be blank (false) so the ``\#else'' | |
| -portion will execute and present a form. You type your name and press submit. | |
| -The form invokes the same page. Now `name' is true so the ``\#if'' portion | |
| -executes, which displays the greeting. The ``\#set'' directive creates a | |
| -local variable that lasts while the template is being filled. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{How mature is Cheetah?} | |
| -\label{intro.mature} | |
| - | |
| -Cheetah is stable, production quality, post-beta code. Cheetah's syntax, | |
| -semantics and performance have been generally stable since a performance | |
| -overhaul in mid 2001. Most of the changes since October 2001 have | |
| -been in response to specific requests by production sites, things they need that | |
| -we hadn't considered. | |
| - | |
| -As of summer 2003, we are putting in the final touches before the 1.0 release. | |
| - | |
| -The {\bf TODO} and {\bf BUGS} files in the Cheetah distribution show what we're | |
| -working on now or planning to work on. There's also a {\bf ToDo} page on the | |
| -wiki (see below), which is updated less often. The {\bf WishList} page on the | |
| -wiki shows requested features we're considering but haven't commited to. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Where can I get news?} | |
| -\label{intro.news} | |
| - | |
| -Cheetah releases and other stuff can be obtained from the the Cheetah | |
| -{\bf Web site}: | |
| -\url{http://CheetahTemplate.sourceforge.net} | |
| - | |
| -Cheetah discussions take place on the {\bf mailing list} | |
| -\email{cheetahtemplate-discuss@lists.sourceforge.net}. This is where to hear | |
| -the latest news first. | |
| - | |
| -The Cheetah {\bf wiki} is becoming an increasingly popular place to list | |
| -examples of Cheetah in use, provide cookbook tips for solving various problems, | |
| -and brainstorm ideas for future versions of Cheetah. | |
| -\url{http://www.cheetahtemplate.org/wiki} | |
| -(The wiki is actually hosted at | |
| -\url{http://cheetah.colorstudy.net/twiki/bin/view/Cheetah/WebHome}, but the | |
| -other URL is easier to remember.) | |
| -For those unfamiliar with a wiki, it's a type of Web site that readers can edit | |
| -themselves to make additions or corrections to. Try it. Examples and tips | |
| -from the wiki will also be considered for inclusion in future versions of this | |
| -Users' Guide. | |
| - | |
| -If you encounter difficulties, or are unsure about how to do something, | |
| -please post a detailed message to the list. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{How can I contribute?} | |
| -\label{intro.contribute} | |
| - | |
| -Cheetah is the work of many volunteers. If you use Cheetah please share your | |
| -experiences, tricks, customizations, and frustrations. | |
| - | |
| -\subsubsection{Bug reports and patches} | |
| - | |
| -If you think there is a bug in Cheetah, send a message to the e-mail list | |
| -with the following information: | |
| - | |
| -\begin{enumerate} | |
| -\item a description of what you were trying to do and what happened | |
| -\item all tracebacks and error output | |
| -\item your version of Cheetah | |
| -\item your version of Python | |
| -\item your operating system | |
| -\item whether you have changed anything in the Cheetah installation | |
| -\end{enumerate} | |
| - | |
| -\subsubsection{Example sites and tutorials} | |
| -If you're developing a website with Cheetah, please put a link on the wiki on | |
| -the {\bf WhoIsUsingCheetah} page, and mention it on the list. Also, if you | |
| -discover new and interesting ways to use Cheetah, please put a quick tutorial | |
| -(HOWTO) about your technique on the {\bf CheetahRecipies} page on the wiki. | |
| - | |
| -\subsubsection{Template libraries and function libraries} | |
| -We hope to build up a framework of Template libraries (see section | |
| -\ref{libraries.templates}) to distribute with Cheetah and would appreciate any | |
| -contributions. | |
| - | |
| -\subsubsection{Test cases} | |
| -Cheetah is packaged with a regression testing suite that is run with each | |
| -new release to ensure that everything is working as expected and that recent | |
| -changes haven't broken anything. The test cases are in the Cheetah.Tests | |
| -module. If you find a reproduceable bug please consider writing a test case | |
| -that will pass only when the bug is fixed. Send any new test cases to the email | |
| -list with the subject-line ``new test case for Cheetah.'' | |
| - | |
| -\subsubsection{Publicity} | |
| -Help spread the word ... recommend it to others, write articles about it, etc. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Acknowledgements} | |
| -\label{intro.acknowledgments} | |
| - | |
| -Cheetah is one of several templating frameworks that grew out of a `templates' | |
| -thread on the Webware For Python email list. Tavis Rudd, Mike Orr, Chuck | |
| -Esterbrook and Ian Bicking are the core developers. | |
| - | |
| -We'd like to thank the following people for contributing valuable advice, code | |
| -and encouragement: Geoff Talvola, Jeff Johnson, Graham Dumpleton, Clark C. | |
| -Evans, Craig Kattner, Franz Geiger, Geir Magnusson, Tom Schwaller, Rober Kuzelj, | |
| -Jay Love, Terrel Shumway, Sasa Zivkov, Arkaitz Bitorika, Jeremiah Bellomy, | |
| -Baruch Even, Paul Boddie, Stephan Diehl, Chui Tey, Michael Halle, Edmund Lian | |
| -and Aaron Held. | |
| - | |
| -The Velocity, WebMacro and Smarty projects provided inspiration and design | |
| -ideas. Cheetah has benefitted from the creativity and energy of their | |
| -developers. Thank you. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{License} | |
| -\label{intro.license} | |
| - | |
| -\paragraph*{The gist} | |
| -Cheetah is open source, but products developed with Cheetah or derived | |
| -from Cheetah may be open source or closed source. | |
| - | |
| -{\bf Cheetah.Utils.optik} is based on a third-party package Optik by Gregory | |
| -P Ward. Optik's license is in appendix \ref{optikLicense}. | |
| - | |
| - | |
| -\paragraph*{Legal terms} | |
| -Copyright \copyright 2001, The Cheetah Development Team: Tavis Rudd, Mike Orr, | |
| -Ian Bicking, Chuck Esterbrook. | |
| - | |
| -Permission to use, copy, modify, and distribute this software for any purpose | |
| -and without fee is hereby granted, provided that the above copyright notice | |
| -appear in all copies and that both that copyright notice and this permission | |
| -notice appear in supporting documentation, and that the names of the authors not | |
| -be used in advertising or publicity pertaining to distribution of the software | |
| -without specific, written prior permission. | |
| - | |
| -THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL | |
| -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS | |
| -BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF | |
| -CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION | |
| -WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
| - | |
| -These terms do not apply to the {\bf Cheetah.Utils.optik} package. Optik's | |
| -license is in appendix \ref{optikLicense}. | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| diff --git a/docs/users_guide_src/language.tex b/docs/users_guide_src/language.tex | |
| deleted file mode 100755 | |
| index 673abca..0000000 | |
| --- a/docs/users_guide_src/language.tex | |
| +++ /dev/null | |
| @@ -1,651 +0,0 @@ | |
| -\section{Language Overview} | |
| -\label{language} | |
| - | |
| -Cheetah's basic syntax was inspired by the Java-based template engines Velocity | |
| -and WebMacro. It has two types of tags: {\bf \$placeholders} and {\bf | |
| -\#directives}. Both types are case-sensitive. | |
| - | |
| -Placeholder tags begin with a dollar sign (\code{\$varName}) and are similar to | |
| -data fields in a form letter or to the \code{\%(key)s} fields on the left side | |
| -of Python's \code{\%} operator. When the template is filled, the placeholders | |
| -are replaced with the values they refer to. | |
| - | |
| -Directive tags begin with a hash character (\#) and are used for comments, | |
| -loops, conditional blocks, includes, and all other advanced features. | |
| -({\em Note:} you can customize the start and end delimeters for placeholder | |
| -and directive tags, but in this Guide we'll assume you're using the default.) | |
| - | |
| -Placeholders and directives can be escaped by putting a backslash before them. | |
| -\verb+\$var+ and \verb+\#if+ will be output as literal text. | |
| - | |
| -A placeholder or directive can span multiple physical lines, following the same | |
| -rules as Python source code: put a backslash (\verb+\+) at the end of all | |
| -lines except the last line. However, if there's an unclosed parenthesis, | |
| -bracket or brace pending, you don't need the backslash. | |
| - | |
| -\begin{verbatim} | |
| -#if $this_is_a_very_long_line and $has_lots_of_conditions \ | |
| - and $more_conditions: | |
| -<H1>bla</H1> | |
| -#end if | |
| - | |
| -#if $country in ('Argentina', 'Uruguay', 'Peru', 'Colombia', | |
| - 'Costa Rica', 'Venezuela', 'Mexico') | |
| -<H1>Hola, senorita!</H1> | |
| -#else | |
| -<H1>Hey, baby!</H1> | |
| -#end if | |
| -\end{verbatim} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Language Constructs -- Summary} | |
| -\label{language.constructs} | |
| - | |
| -\begin{enumerate} | |
| -\item Comments and documentation strings | |
| - \begin{enumerate} | |
| - \item \code{\#\# single line} | |
| - \item \code{\#* multi line *\#} | |
| - \end{enumerate} | |
| - | |
| -\item Generation, caching and filtering of output | |
| - \begin{enumerate} | |
| - \item plain text | |
| - \item look up a value: \code{\$placeholder} | |
| - \item evaluate an expression: \code{\#echo} \ldots | |
| - \item same but discard the output: \code{\#silent} \ldots | |
| - \item one-line if: \code{\#if EXPR then EXPR else EXPR} | |
| - \item gobble the EOL: \code{\#slurp} | |
| - \item parsed file includes: \code{\#include} \ldots | |
| - \item raw file includes: \code{\#include raw} \ldots | |
| - \item verbatim output of Cheetah code: \code{\#raw} \ldots \code{\#end raw} | |
| - \item cached placeholders: \code{\$*var}, \code{\$*<interval>*var} | |
| - \item cached regions: \code{\#cache} \ldots \code{\#end cache} | |
| - \item set the output filter: \code{\#filter} \ldots | |
| - \item control output indentation: \code{\#indent} \ldots ({\em not | |
| -implemented yet}) | |
| - \end{enumerate} | |
| - | |
| -\item Importing Python modules and objects: \code{\#import} \ldots, | |
| - \code{\#from} \ldots | |
| - | |
| -\item Inheritance | |
| - \begin{enumerate} | |
| - \item set the base class to inherit from: \code{\#extends} | |
| - \item set the name of the main method to implement: \code{\#implements} | |
| -\ldots | |
| - \end{enumerate} | |
| - | |
| -\item Compile-time declaration | |
| - \begin{enumerate} | |
| - \item define class attributes: \code{\#attr} \ldots | |
| - \item define class methods: \code{\#def} \ldots \code{\#end def} | |
| - \item \code{\#block} \ldots \code{\#end block} provides a simplified | |
| - interface to \code{\#def} \ldots \code{\#end def} | |
| - \end{enumerate} | |
| - | |
| -\item Run-time assignment | |
| - \begin{enumerate} | |
| - \item local vars: \code{\#set} \ldots | |
| - \item global vars: \code{\#set global} \ldots | |
| - \item deleting local vars: \code{\#del} \ldots | |
| - \end{enumerate} | |
| - | |
| -\item Flow control | |
| - \begin{enumerate} | |
| - \item \code{\#if} \ldots \code{\#else} \ldots \code{\#else if} (aka | |
| - \code{\#elif}) \ldots \code{\#end if} | |
| - \item \code{\#unless} \ldots \code{\#end unless} | |
| - \item \code{\#for} \ldots \code{\#end for} | |
| - \item \code{\#repeat} \ldots \code{\#end repeat} | |
| - \item \code{\#while} \ldots \code{\#end while} | |
| - \item \code{\#break} | |
| - \item \code{\#continue} | |
| - \item \code{\#pass} | |
| - \item \code{\#stop} | |
| - \end{enumerate} | |
| - | |
| -\item error/exception handling | |
| - \begin{enumerate} | |
| - \item \code{\#assert} | |
| - \item \code{\#raise} | |
| - \item \code{\#try} \ldots \code{\#except} \ldots \code{\#else} \ldots | |
| - \code{\#end try} | |
| - \item \code{\#try} \ldots \code{\#finally} \ldots \code{\#end try} | |
| - \item \code{\#errorCatcher} \ldots set a handler for exceptions raised by | |
| -\$placeholder calls. | |
| - \end{enumerate} | |
| - | |
| -\item Instructions to the parser/compiler | |
| - \begin{enumerate} | |
| - \item \code{\#breakpoint} | |
| - \item \code{\#compiler-settings} \ldots \code{\#end compiler-settings} | |
| - \end{enumerate} | |
| - | |
| -\item Escape to pure Python code | |
| - \begin{enumerate} | |
| - \item evalute expression and print the output: \code{<\%=} \ldots | |
| - \code{\%>} | |
| - \item execute code and discard output: \code{<\%} \ldots \code{\%>} | |
| - \end{enumerate} | |
| - | |
| -\item Fine control over Cheetah-generated Python modules | |
| - \begin{enumerate} | |
| - \item set the source code encoding of compiled template modules: \code{\#encoding} | |
| - \item set the sh-bang line of compiled template modules: \code{\#shBang} | |
| - \end{enumerate} | |
| - | |
| -\end{enumerate} | |
| - | |
| -The use of all these constructs will be covered in the next several chapters. | |
| - | |
| -%% @@MO: TODO: reconcile the order of this summary with the order in the | |
| -%% detail sections. | |
| - | |
| -% @@MO: PSP chapter with examples. What does write() do? Print? | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Placeholder Syntax Rules} | |
| -\label{language.placeholders.syntax} | |
| - | |
| -\begin{itemize} | |
| - | |
| -\item Placeholders follow the same syntax rules as Python variables except | |
| - that they are preceded by \code{\$} (the short form) or enclosed in | |
| - \code{\$\{\}} (the long form). | |
| - Examples: | |
| -\begin{verbatim} | |
| -$var | |
| -${var} | |
| -$var2.abc['def']('gh', $subplaceholder, 2) | |
| -${var2.abc['def']('gh', $subplaceholder, 2)} | |
| -\end{verbatim} | |
| - We recommend \code{\$} in simple cases, and \code{\$\{\}} when followed | |
| - directly by a letter or when Cheetah or a human template maintainer might | |
| - get confused about where the placeholder ends. You may alternately use | |
| - \verb+$()+ or \verb+$[]+, although this may confuse the (human) template | |
| - maintainer: | |
| -\begin{verbatim} | |
| -$(var) | |
| -$[var] | |
| -$(var2.abc['def']('gh', $subplaceholder, 2)) | |
| -$[var2.abc['def']('gh', $subplaceholder, 2)] | |
| -\end{verbatim} | |
| - {\em Note:} Advanced users can change the delimiters to anything they | |
| - want via the \code{\#compiler} directive. | |
| - | |
| - {\em Note 2:} The long form can be used only with top-level placeholders, | |
| - not in expressions. See section \ref{language.placeholders.positions} | |
| - for an elaboration on this. | |
| - | |
| -\item To reiterate Python's rules, placeholders consist of one or more | |
| - identifiers separated by periods. Each identifier must start with a letter | |
| - or an underscore, and the subsequent characters must be letters, digits or | |
| - underscores. Any identifier may be followed by arguments enclosed in | |
| - \verb+()+ and/or keys/subscripts in \verb+[]+. | |
| - | |
| -\item Identifiers are case sensitive. \code{\$var} does not equal \code{\$Var} | |
| - or \code{\$vAr} or \code{\$VAR}. | |
| - | |
| -\item Arguments inside \verb+()+ or \verb+[]+ are just like in Python. | |
| - Strings may be quoted using any Python quoting style. Each argument is an | |
| - expression and may use any of Python's expression operators. Variables | |
| - used in argument expressions are placeholders and should be prefixed with | |
| - \code{\$}. This also applies to the *arg and **kw forms. However, you do | |
| - {\em not} need the \code{\$} with the special Python constants \code{None}, | |
| - \code{True} and \code{False}. | |
| - Examples: | |
| -\begin{verbatim} | |
| -$hex($myVar) | |
| -$func($arg=1234) | |
| -$func2($*args, $**kw) | |
| -$func3(3.14159, $arg2, None, True) | |
| -$myList[$mySubscript] | |
| -\end{verbatim} | |
| - | |
| -\item Trailing periods are ignored. Cheetah will recognize that the placeholder | |
| - name in \code{\$varName.} is \code{varName}, and the period will be left | |
| - alone in the template output. | |
| - | |
| -\item The syntax \code{\$\{placeholderName, arg1="val1"\}} passes arguments to | |
| - the output filter (see \code{\#filter}, section \ref{output.filter}. | |
| - The braces and comma are required in this case. It's conventional to | |
| - omit the \code{\$} before the keyword arguments (i.e. \code{arg1}) in this | |
| - case. | |
| - | |
| -\item Cheetah ignores all dollar signs (\code{\$}) that are not followed by a | |
| - letter or an underscore. | |
| - | |
| -\end{itemize} | |
| - | |
| -The following are valid \$placeholders: | |
| -\begin{verbatim} | |
| -$a $_ $var $_var $var1 $_1var $var2_ $dict.key $list[3] | |
| -$object.method $object.method() $object.method | |
| -$nest($nest($var)) | |
| -\end{verbatim} | |
| - | |
| -These are not \$placeholders but are treated as literal text: | |
| -\begin{verbatim} | |
| -$@var $^var $15.50 $$ | |
| -\end{verbatim} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Where can you use placeholders?} | |
| -\label{language.placeholders.positions} | |
| - | |
| -There are three places you can use placeholders: top-level position, | |
| -expression position and LVALUE position. Each has slightly different | |
| -syntax rules. | |
| - | |
| -Top-level position means interspersed in text. This is the only place | |
| -you can use the placeholder long form: \code{\$\{var\}}. | |
| - | |
| -{\em Expression position} means inside a Cheetah expression, which is the same | |
| -as a Python expression. The placeholder names a searchList or other variable | |
| -to be read. Expression position occurs inside () and $[]$ arguments within | |
| -placeholder tags (i.e., a placeholder inside a placeholder), and in several | |
| -directive tags. | |
| - | |
| -{\em LVALUE position} means naming a variable that will be written to. LVALUE | |
| -is a computer science term meaning ``the left side of an assignment | |
| -statement''. The first argument of directives \code{\#set}, \code{\#for}, | |
| -\code{\#def}, \code{\#block} and \code{\#attr} is an LVALUE. | |
| - | |
| -This stupid example shows the three positions. Top-level position is shown | |
| -in \code{courier}, expression position is {\em italic}, and LVALUE position is | |
| -{\bf bold}. | |
| - | |
| -\begin{quote} | |
| -\#for {\bf \$count} in {\em \$range}({\em \$ninetyNine}, 0, -1)\\ | |
| -\#set {\bf \$after} = {\em \$count} - 1\\ | |
| -\code{\$count} bottles of beer on the wall. \code{\$count} bottles of beer!\\ | |
| -~~~~Take one down, pass it around. \code{\$after} bottles of beer on the wall.\\ | |
| -\#end for\\ | |
| -\code{\$hex}({\em \$myVar}, {\bf \$default}={\em None}) | |
| -\end{quote} | |
| - | |
| -The output of course is: | |
| -\begin{verbatim} | |
| -99 bottles of beer on the wall. 99 bottles of beer! | |
| - Take one down, pass it around. 98 bottles of beer on the wall. | |
| -98 bottles of beer on the wall. 98 bottles of beer! | |
| - Take one down, pass it around. 97 bottles of beer on the wall. | |
| -... | |
| -\end{verbatim} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Are all those dollar signs really necessary?} | |
| -\label{language.placeholders.dollar-signs} | |
| - | |
| -\code{\$} is a ``smart variable prefix''. When Cheetah sees \code{\$}, it | |
| -determines both the variable's position and whether it's a searchList value or | |
| -a non-searchList value, and generates the appropriate Python code. | |
| - | |
| -In top-level position, the \code{\$} is {\em required}. Otherwise there's | |
| -nothing to distinguish the variable from ordinary text, and the variable name | |
| -is output verbatim. | |
| - | |
| -In expression position, the \code{\$} is {\em required} if the value comes from | |
| -the searchList or a ``\#set global'' variable, {\em recommended} for | |
| -local/global/builtin variables, and {\em not necessary} for the special | |
| -constants \code{None}, \code{True} and \code{False}. This works because | |
| -Cheetah generates a function call for a searchList placeholder, but a bare | |
| -variable name for a local/global/builtin variable. | |
| - | |
| -In LVALUE position, the \code{\$} is {\em recommended}. Cheetah knows where | |
| -an LVALUE is expected, so it can handle your variable name whether it has | |
| -\code{\$} or not. | |
| - | |
| -EXCEPTION: Do {\em not} use the \code{\$} prefix for intermediate variables in | |
| -a Python list comprehensions. This is a limitation of Cheetah's parser; it | |
| -can't tell which variables in a list comprehension are the intermediate | |
| -variables, so you have to help it. For example: | |
| -\begin{verbatim} | |
| -#set $theRange = [x ** 2 for x in $range(10)] | |
| -\end{verbatim} | |
| -\code{\$theRange} is a regular \code{\#set} variable. \code{\$range} is a | |
| -Python built-in function. But \code{x} is a scratch variable internal to | |
| -the list comprehension: if you type \code{\$x}, Cheetah will miscompile | |
| -it. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{NameMapper Syntax} | |
| -\label{language.namemapper} | |
| - | |
| -One of our core aims for Cheetah was to make it easy for non-programmers to | |
| -use. Therefore, Cheetah uses a simplified syntax for mapping placeholders | |
| -in Cheetah to values in Python. It's known as the {\bf NameMapper syntax} | |
| -and allows for non-programmers to use Cheetah without knowing (a) the | |
| -difference between an instance and a dictionary, (b) what functions and methods | |
| -are, and (c) what 'self' is. A side benefit is that you can change the | |
| -underlying data structure (e.g., instance to dictionary or vice-versa) without | |
| -having to modify the templates. | |
| - | |
| -NameMapper syntax is used for all variables in Cheetah placeholders and | |
| -directives. If desired, it can be turned off via the \code{Template} class' | |
| -\code{'useNameMapper'} compiler setting. But it's doubtful you'd ever want to | |
| -turn it off. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{Example} | |
| -\label{language.namemapper.example} | |
| - | |
| -Consider this scenario: | |
| - | |
| -You are building a customer information system. The designers with you want to | |
| -use information from your system on the client's website --AND-- they want to | |
| -understand the display code and so they can maintian it themselves. | |
| - | |
| -You write a UI class with a 'customers' method that returns a dictionary of all | |
| -the customer objects. Each customer object has an 'address' method that returns | |
| -the a dictionary with information about the customer's address. The designers | |
| -want to be able to access that information. | |
| - | |
| -Using PSP, the display code for the website would look something like the | |
| -following, assuming your servlet subclasses the class you created for managing | |
| -customer information: | |
| - | |
| -\begin{verbatim} | |
| - <%= self.customer()[ID].address()['city'] %> (42 chars) | |
| -\end{verbatim} | |
| - | |
| -With Cheetah's NameMapper syntax, you can use any of the following: | |
| - | |
| -\begin{verbatim} | |
| - $self.customers()[$ID].address()['city'] (39 chars) | |
| - --OR-- | |
| - $customers()[$ID].address()['city'] | |
| - --OR-- | |
| - $customers()[$ID].address().city | |
| - --OR-- | |
| - $customers()[$ID].address.city | |
| - --OR-- | |
| - $customers[$ID].address.city (27 chars) | |
| -\end{verbatim} | |
| - | |
| -Which of these would you prefer to explain to the designers, who have no | |
| -programming experience? The last form is 15 characters shorter than the PSP | |
| -version and -- conceptually -- far more accessible. With PHP or ASP, the | |
| -code would be even messier than with PSP. | |
| - | |
| -This is a rather extreme example and, of course, you could also just implement | |
| -\code{\$getCustomer(\$ID).city} and obey the Law of Demeter (search Google for more | |
| -on that). But good object orientated design isn't the point of this example. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{Dictionary Access} | |
| -\label{language.namemapper.dict} | |
| - | |
| -NameMapper syntax allows access to dictionary items with the same dotted | |
| -notation used to access object attributes in Python. This aspect of NameMapper | |
| -syntax is known as 'Unified Dotted Notation'. | |
| -For example, with Cheetah it is possible to write: | |
| -\begin{verbatim} | |
| - $customers()['kerr'].address() --OR-- $customers().kerr.address() | |
| -\end{verbatim} | |
| -where the second form is in NameMapper syntax. | |
| - | |
| -This works only with dictionary keys that also happen to be valid Python | |
| -identifiers. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{Autocalling} | |
| -\label{language.namemapper.autocalling} | |
| - | |
| -Cheetah automatically detects functions and methods in Cheetah \$variables and | |
| -calls them if the parentheses have been left off. Our previous example can be | |
| -further simplified to: | |
| -\begin{verbatim} | |
| - $customers.kerr.address | |
| -\end{verbatim} | |
| - | |
| -As another example, if 'a' is an object, 'b' is a method | |
| -\begin{verbatim} | |
| - $a.b | |
| -\end{verbatim} | |
| - | |
| -is equivalent to | |
| - | |
| -\begin{verbatim} | |
| - $a.b() | |
| -\end{verbatim} | |
| - | |
| -If b returns a dictionary, then following variations are possible | |
| -\begin{verbatim} | |
| - $a.b.c --OR-- $a.b().c --OR-- $a.b()['c'] | |
| -\end{verbatim} | |
| -where 'c' is a key in the dictionary that a.b() returns. | |
| - | |
| -Further notes: | |
| -\begin{itemize} | |
| -\item When Cheetah autocalls a function/method, it calls it without any | |
| -arguments. Thus, the function/method must have been declared without arguments | |
| -(except \code{self} for methods) or to provide default values for all arguments. | |
| -If the function requires arguments, you must use the \code{()}. | |
| - | |
| -\item Cheetah autocalls only functions and methods. Classes and other callable | |
| -objects are not autocalled. The reason is that the primary purpose of a | |
| -function/method is to call it, whereas the primary purpose of an instance is to | |
| -look up its attributes or call its methods, not to call the instance itself. | |
| -And calling a class may allocate large sums of memory uselessly or have other | |
| -side effects, depending on the class. For instance, consider | |
| -\code{\$myInstance.fname}. Do we want to look up \code{fname} in the namespace | |
| -of \code{myInstance} or in the namespace of whatever \code{myinstance} returns? | |
| -It could go either way, so Cheetah follows the principle of least surprise. If | |
| -you {\em do} want to call the instance, put the \code{()} on, or rename the | |
| -\code{.\_\_call\_\_()} method to \code{.\_\_str\_\_}. | |
| - | |
| -\item Autocalling can be disabled via Cheetah's 'useAutocalling' compiler | |
| -setting. You can also disable it for one placeholder by using the syntax | |
| -\code{\$getVar('varName', 'default value', False)}. (\code{.getVar()} works | |
| -only with searchList values.) | |
| -\end{itemize} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Namespace cascading and the searchList} | |
| -\label{language.searchList} | |
| - | |
| -When Cheetah maps a variable name in a template to a Python value, it searches | |
| -several namespaces in order: | |
| - | |
| -\begin{enumerate} | |
| -\item {\bf Local variables:} created by \code{\#set}, | |
| - \code{\#for}, or predefined by Cheetah. | |
| -\item The {\bf searchList}, consisting of: | |
| - \begin{enumerate} | |
| - \item \code{\#set\ global} variables. | |
| - \item The {\bf searchList} containers you passed to the \code{Template} | |
| - constructor, if any. | |
| - \item The {\bf Template instance} (``self''). This contains any attributes | |
| - you assigned, \code{\#def} methods and \code{\#block methods}, | |
| - attributes/methods inherited via \code{\#extends}, and other | |
| - attributes/methods built into \code{Template} or inherited by it | |
| - (there's a list of all these methods in section | |
| - \ref{tips.allMethods}). | |
| - \end{enumerate} | |
| -\item {\bf Python globals:} created by \code{\#import}, | |
| - \code{\#from\ ...\ import}, or otherwise predefined by Cheetah. | |
| -\item {\bf Python builtins:} \code{None}, \code{max}, etc. | |
| -\end{enumerate} | |
| - | |
| -The first matching name found is used. | |
| - | |
| -Remember, these namespaces apply only to the {\em first} identifier after the | |
| -\code{\$}. In a placeholder like \code{\$a.b}, only `a' is looked up in the | |
| -searchList and other namespaces. `b' is looked up only inside `a'. | |
| - | |
| -A searchList container can be any Python object with attributes or keys: | |
| -dictionaries, instances, classes or modules. If an instance contains both | |
| -attributes and keys, its attributes are searched first, then its keys. | |
| - | |
| -Because the \code{Template} instance is part of the searchList, you can | |
| -access its attributes/methods without `self': \code{\$myAttr}. However, use | |
| -the `self' if you want to make sure you're getting the \code{Template} | |
| -attribute and not a same-name variable defined in a higher namespace: | |
| -\code{\$self.myAttr}. This works because ``self'' itself is a local variable. | |
| - | |
| -The final resulting value, after all lookups and function calls (but before the | |
| -filter is applied) is called the {\em placeholder value}, no matter which | |
| -namespace it was found in. | |
| - | |
| -{\em {\bf Note carefully:}} if you put an object `myObject' in the searchList, | |
| -you {\em cannot} look up \code{\$myObject}! You can look up only the | |
| -attributes/keys {\em inside} `myObject'. | |
| - | |
| -Earlier versions of Cheetah did not allow you to override Python builtin | |
| -names, but this was fixed in Cheetah 0.9.15. | |
| - | |
| -If your template will be used as a Webware servlet, do not override methods | |
| -'name' and 'log' in the \code{Template} instance or it will interfere with | |
| -Webware's logging. However, it {\em is} OK to use those variables in a higher | |
| -namespace, since Webware doesn't know about Cheetah namespaces. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Missing Values} | |
| -\label{language.namemapper.missing} | |
| - | |
| -If NameMapper can not find a Python value for a Cheetah variable name, it will | |
| -raise the NameMapper.NotFound exception. You can use the \code{\#errorCatcher} | |
| -directive (section \ref{errorHandling.errorCatcher}) or {\bf errorCatcher} | |
| -Template constructor argument (section \ref{howWorks.constructing}) to specify | |
| -an alternate behaviour. BUT BE AWARE THAT errorCatcher IS ONLY INTENDED FOR | |
| -DEBUGGING! | |
| - | |
| -To provide a default value for a placeholder, write it like this: | |
| -\code{\$getVar('varName', 'default value')}. If you don't specify a default | |
| -and the variable is missing, \code{NameMapper.NotFound} will be raised. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Directive Syntax Rules} | |
| -\label{language.directives.syntax} | |
| - | |
| - | |
| -Directive tags begin with a hash character (\#) and are used for comments, | |
| -loops, conditional blocks, includes, and all other advanced features. Cheetah | |
| -uses a Python-like syntax inside directive tags and understands any valid | |
| -Python expression. {\bf However, unlike Python, Cheetah does not use colons | |
| -(:) and indentation to mark off multi-line directives.} That doesn't work in | |
| -an environment where whitespace is significant as part of the text. Instead, | |
| -multi-line directives like \code{\#for} have corresponding closing tags | |
| -(\code{\#end for}). Most directives are direct mirrors of Python statements. | |
| - | |
| -Many directives have arguments after the opening tag, which must be in the | |
| -specified syntax for the tag. All end tags have the following syntax: | |
| -\begin{verbatim} | |
| -#end TAG_NAME [EXPR] | |
| -\end{verbatim} | |
| -The expression is ignored, so it's essentially a comment. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{Directive closures and whitespace handling} | |
| -\label{language.directives.closures} | |
| -Directive tags can be closed explicitly with \code{\#}, or implicitly with the | |
| -end of the line if you're feeling lazy. | |
| - | |
| -\begin{verbatim} | |
| -#block testBlock # | |
| -Text in the body of the | |
| -block directive | |
| -#end block testBlock # | |
| -\end{verbatim} | |
| -is identical to: | |
| -\begin{verbatim} | |
| -#block testBlock | |
| -Text in the body of the | |
| -block directive | |
| -#end block testBlock | |
| -\end{verbatim} | |
| - | |
| -When a directive tag is closed explicitly, it can be followed with other text on | |
| -the same line: | |
| - | |
| -\begin{verbatim} | |
| -bah, bah, #if $sheep.color == 'black'# black#end if # sheep. | |
| -\end{verbatim} | |
| - | |
| -When a directive tag is closed implicitly with the end of the line, all trailing | |
| -whitespace is gobbled, including the newline character: | |
| -\begin{verbatim} | |
| -""" | |
| -foo #set $x = 2 | |
| -bar | |
| -""" | |
| -outputs | |
| -""" | |
| -foo bar | |
| -""" | |
| - | |
| -while | |
| -""" | |
| -foo #set $x = 2 # | |
| -bar | |
| -""" | |
| -outputs | |
| -""" | |
| -foo | |
| -bar | |
| -""" | |
| -\end{verbatim} | |
| - | |
| -When a directive tag is closed implicitly AND there is no other text on the | |
| -line, the ENTIRE line is gobbled up including any preceeding whitespace: | |
| -\begin{verbatim} | |
| -""" | |
| -foo | |
| - #set $x = 2 | |
| -bar | |
| -""" | |
| -outputs | |
| -""" | |
| -foo | |
| -bar | |
| -""" | |
| - | |
| -while | |
| -""" | |
| -foo | |
| - - #set $x = 2 | |
| -bar | |
| -""" | |
| -outputs | |
| -""" | |
| -foo | |
| - - bar | |
| -""" | |
| -\end{verbatim} | |
| - | |
| -The \code{\#slurp} directive (section \ref{output.slurp}) also gobbles up | |
| -whitespace. | |
| - | |
| -Spaces outside directives are output {\em exactly} as written. In the | |
| -black sheep example, there's a space before ``black'' and another before | |
| -``sheep''. So although it's legal to put multiple directives on one line, | |
| -it can be hard to read. | |
| - | |
| -\begin{verbatim} | |
| -#if $a# #echo $a + 1# #end if | |
| - - There's a space between each directive, | |
| - or two extra spaces total. | |
| -#if $a##echo $a + 1##end if | |
| - - No spaces, but you have to look closely | |
| - to verify none of the ``##'' are comment markers. | |
| -#if $a##echo $a + 1##end if ### A comment. | |
| - - In ``###'', the first ``#'' ends the directive, | |
| - the other two begin the comment. (This also shows | |
| - how you can add extra whitespace in the directive | |
| - tag without affecting the output.) | |
| -#if $a##echo $a + 1##end if # ## A comment. | |
| - - More readable, but now there's a space before the | |
| - comment. | |
| -\end{verbatim} | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| - | |
| -% # vim: sw=4 ts=4 expandtab | |
| diff --git a/docs/users_guide_src/libraries.tex b/docs/users_guide_src/libraries.tex | |
| deleted file mode 100755 | |
| index dc9231a..0000000 | |
| --- a/docs/users_guide_src/libraries.tex | |
| +++ /dev/null | |
| @@ -1,306 +0,0 @@ | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\section{Batteries included: templates and other libraries} | |
| -\label{libraries} | |
| - | |
| -Cheetah comes ``batteries included'' with libraries of templates, functions, | |
| -classes and other objects you can use in your own programs. The different | |
| -types are listed alphabetically below, followed by a longer description of | |
| -the SkeletonPage framework. Some of the objects are classes for specific | |
| -purposes (e.g., filters or error catchers), while others are standalone and | |
| -can be used without Cheetah. | |
| - | |
| -If you develop any objects which are generally useful for Cheetah sites, | |
| -please consider posting them on the wiki with an announcement on the mailing | |
| -list so we can incorporate them into the standard library. That way, all | |
| -Cheetah users will benefit, and it will encourage others to contribute their | |
| -objects, which might include something you want. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{ErrorCatchers} | |
| -\label{libraries.ErrorCatchers} | |
| - | |
| -Module \code{Cheetah.ErrorCatchers} contains error-handling classes suitable for | |
| -the \code{\#errorCatcher} directive. These are debugging tools that are not | |
| -intended for use in production systems. See section | |
| -\ref{errorHandling.errorCatcher} for a description of the error catchers bundled | |
| -with Cheetah. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{FileUtils} | |
| -\label{libraries.FileUtils} | |
| - | |
| -Module \code{Cheetah.FileUtils} contains generic functions and classes for | |
| -doing bulk search-and-replace on several files, and for finding all the files | |
| -in a directory hierarchy whose names match a glob pattern. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Filters} | |
| -\label{libraries.Filters} | |
| - | |
| -Module \code{Filters} contains filters suitable for the \code{\#Filter} | |
| -directive. See section \ref{output.filter} for a description of the | |
| -filters bundled with Cheetah. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{SettingsManager} | |
| -\label{libraries.SettingsManager} | |
| - | |
| -The \code{SettingsManager} class in the \code{Cheetah.SettingsManager} module is | |
| -a baseclass that provides facilities for managing application settings. It | |
| -facilitates the use of user-supplied configuration files to fine tune an | |
| -application. A setting is a key/value pair that an application or component | |
| -(e.g., a filter, or your own servlets) looks up and treats as a configuration | |
| -value to modify its (the component's) behaviour. | |
| - | |
| -SettingsManager is designed to: | |
| -\begin{itemize} | |
| -\item work well with nested settings dictionaries of any depth | |
| -\item read/write \code{.ini style config files} (or strings) | |
| -\item read settings from Python source files (or strings) so that | |
| - complex Python objects can be stored in the application's settings | |
| - dictionary. For example, you might want to store references to various | |
| - classes that are used by the application, and plugins to the application | |
| - might want to substitute one class for another. | |
| -\item allow sections in \code{.ini config files} to be extended by settings in | |
| - Python src files. If a section contains a setting like | |
| - ``\code{importSettings=mySettings.py}'', \code{SettingsManager} will merge | |
| - all the settings defined in ``\code{mySettings.py}'' with the settings for | |
| - that section that are defined in the \code{.ini config file}. | |
| -\item maintain the case of setting names, unlike the ConfigParser module | |
| -\end{itemize} | |
| - | |
| -Cheetah uses \code{SettingsManager} to manage its configuration settings. | |
| -\code{SettingsManager} might also be useful in your own applications. See the | |
| -source code and docstrings in the file \code{src/SettingsManager.py} for more | |
| -information. | |
| - | |
| - | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Templates} | |
| -\label{libraries.templates} | |
| - | |
| -Package \code{Cheetah.Templates} contains stock templates that you can | |
| -either use as is, or extend by using the \code{\#def} directive to redefine | |
| -specific {\bf blocks}. Currently, the only template in here is SkeletonPage, | |
| -which is described in detail below in section | |
| -\ref{libraries.templates.skeletonPage}. (Contributed by Tavis Rudd.) | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Tools} | |
| -\label{libraries.Tools} | |
| - | |
| -Package \code{Cheetah.Tools} contains functions and classes contributed by third | |
| -parties. Some are Cheetah-specific but others are generic and can be used | |
| -standalone. None of them are imported by any other Cheetah component; you can | |
| -delete the Tools/ directory and Cheetah will function fine. | |
| - | |
| -Some of the items in Tools/ are experimental and have been placed there just to | |
| -see how useful they will be, and whether they attract enough users to make | |
| -refining them worthwhile (the tools, not the users :). | |
| - | |
| -Nothing in Tools/ is guaranteed to be: (A) tested, (B) reliable, (C) immune | |
| -from being deleted in a future Cheetah version, or (D) immune from | |
| -backwards-incompatable changes. If you depend on something in Tools/ on a | |
| -production system, consider making a copy of it outside the Cheetah/ directory | |
| -so that this version won't be lost when you upgrade Cheetah. Also, learn | |
| -enough about Python and about the Tool so that you can maintain it and bugfix | |
| -it if necessary. | |
| - | |
| -If anything in Tools/ is found to be necessary to Cheetah's operation (i.e., if | |
| -another Cheetah component starts importing it), it will be moved to the | |
| -\code{Cheetah.Utils} package. | |
| - | |
| -Current Tools include: | |
| -\begin{description} | |
| -\item{Cheetah.Tools.MondoReport} an ambitious class useful when | |
| - iterating over records of data (\code{\#for} loops), displaying one | |
| - pageful of records at a time (with previous/next links), and printing | |
| - summary statistics about the records or the current page. See | |
| - \code{MondoReportDoc.txt} in the same directory as the module. Some | |
| - features are not implemented yet. \code{MondoReportTest.py} is a test | |
| - suite (and it shows there are currently some errors in MondoReport, hmm). | |
| - Contributed by Mike Orr. | |
| - | |
| -\item{Cheetah.Tools.RecursiveNull} Nothing, but in a friendly way. Good | |
| - for filling in for objects you want to hide. If \code{\$form.f1} is a | |
| - RecursiveNull object, then \code{\$form.f1.anything["you"].might("use")} | |
| - will resolve to the empty string. You can also put a \code{RecursiveNull} | |
| - instance at the end of the searchList to convert missing values to '' | |
| - rather than raising a \code{NotFound} error or having a (less efficient) | |
| - errorCatcher handle it. Of course, maybe you prefer to get a | |
| - \code{NotFound} error... Contributed by Ian Bicking. | |
| - | |
| -\item{Cheetah.Tools.SiteHierarchy} Provides navigational links to this | |
| - page's parents and children. The constructor takes a recursive list of | |
| - (url,description) pairs representing a tree of hyperlinks to every page in | |
| - the site (or section, or application...), and also a string containing the | |
| - current URL. Two methods 'menuList' and 'crumbs' return output-ready HTML | |
| - showing an indented menu (hierarchy tree) or crumbs list (Yahoo-style bar: | |
| - home > grandparent > parent > currentURL). Contributed by Ian Bicking. | |
| - | |
| -\item | |
| -\end{description} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Utils} | |
| -\label{libraries.Utils} | |
| - | |
| -Package \code{Cheetah.Utils} contains non-Cheetah-specific functions and | |
| -classes that are imported by other Cheetah components. Many of these utils can | |
| -be used standalone in other applications too. | |
| - | |
| -Current Utils include: | |
| -\begin{description} | |
| -\item{Cheetah.Utils.CGIImportMixin} This is inherited by \code{Template} | |
| - objects, and provides the method, \code{.cgiImport} method | |
| - (section \ref{webware.cgiImport}). | |
| - | |
| -\item{Cheetah.Utils.Misc} A catch-all module for small functions. | |
| - \begin{description} | |
| - \item{\code{UseOrRaise(thing, errmsg='')}} Raise 'thing' if it's a | |
| - subclass of Exception, otherwise return it. Useful when one | |
| - argument does double duty as a default value or an exception to | |
| - throw. Contribyted by Mike Orr. | |
| - | |
| - \item{\code{checkKeywords(dic, legalKeywords, what='argument'}} | |
| - Verifies the dictionary does not contain any keys not listed in | |
| - 'legalKeywords'. If it does, raise TypeError. Useful for | |
| - checking the keyword arguments to a function. Contributed by | |
| - Mike Orr. | |
| - \end{description} | |
| - | |
| -\item{Cheetah.Utils.UploadFileMixin} Not implemented yet, but will contain | |
| - the \code{.uploadFile} method (or three methods) to ``safely'' copy a | |
| - form-uploaded file to a local file, to a searchList variable, or return | |
| - it. When finished, this will be inherited by \code{Template}, allowing | |
| - all templates to do this. If you want this feature, read the docstring | |
| - in the source and let us know on the mailing list what you'd like this | |
| - method to do. Contributed by Mike Orr. | |
| - | |
| -\item{Cheetah.Utils.VerifyType} Functions to verify the type of a | |
| - user-supplied function argument. Contributed by Mike Orr. | |
| -\end{description} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{Cheetah.Templates.SkeletonPage} | |
| -\label{libraries.templates.skeletonPage} | |
| - | |
| -A stock template class that may be useful for web developers is defined in | |
| -the \code{Cheetah.Templates.SkeletonPage} module. The \code{SkeletonPage} | |
| -template class is generated from the following Cheetah source code: | |
| - | |
| -\begin{verbatim} | |
| -##doc-module: A Skeleton HTML page template, that provides basic structure and utility methods. | |
| -################################################################################ | |
| -#extends Cheetah.Templates._SkeletonPage | |
| -#implements respond | |
| -################################################################################ | |
| -#cache id='header' | |
| -$docType | |
| -$htmlTag | |
| -<!-- This document was autogenerated by Cheetah(http://CheetahTemplate.org). | |
| -Do not edit it directly! | |
| - | |
| -Copyright $currentYr - $siteCopyrightName - All Rights Reserved. | |
| -Feel free to copy any javascript or html you like on this site, | |
| -provided you remove all links and/or references to $siteDomainName | |
| -However, please do not copy any content or images without permission. | |
| - | |
| -$siteCredits | |
| - | |
| ---> | |
| - | |
| - | |
| -#block writeHeadTag | |
| -<head> | |
| -<title>$title</title> | |
| -$metaTags | |
| -$stylesheetTags | |
| -$javascriptTags | |
| -</head> | |
| -#end block writeHeadTag | |
| - | |
| -#end cache header | |
| -################# | |
| - | |
| -$bodyTag | |
| - | |
| -#block writeBody | |
| -This skeleton page has no flesh. Its body needs to be implemented. | |
| -#end block writeBody | |
| - | |
| -</body> | |
| -</html> | |
| -\end{verbatim} | |
| - | |
| -You can redefine any of the blocks defined in this template by writing a new | |
| -template that \code{\#extends} SkeletonPage. (As you remember, using | |
| -\code{\#extends} makes your template implement the \code{.writeBody()} | |
| -method instead of \code{.respond()} -- which happens to be the same method | |
| -SkeletonPage expects the page content to be (note the writeBody block in | |
| -SkeletonPage).) | |
| - | |
| -\begin{verbatim} | |
| -#def bodyContents | |
| -Here's my new body. I've got some flesh on my bones now. | |
| -#end def bodyContents | |
| -\end{verbatim} | |
| - | |
| -%% @@MO: Is this still accurate? Does the child template really need to put a | |
| -%% #def around its whole content? Or by implementing .writeBody() does it | |
| -%% automatically insert itself as the writeBody portion of | |
| -%% SkeletonPage? @@TR 2005-01-06: it happens automatically at the moment. | |
| - | |
| -All of the \$placeholders used in the \code{SkeletonPage} template definition | |
| -are attributes or methods of the \code{SkeletonPage} class. You can reimplement | |
| -them as you wish in your subclass. Please read the source code of the file | |
| -\code{src/Templates/\_SkeletonPage.py} before doing so. | |
| - | |
| -You'll need to understand how to use the following methods of the | |
| -\code{SkeletonPage} class: \code{\$metaTags()}, \code{\$stylesheetTags()}, | |
| -\code{\$javascriptTags()}, and \code{\$bodyTag()}. They take the data you | |
| -define in various attributes and renders them into HTML tags. | |
| - | |
| -\begin{itemize} | |
| -\item {\bf metaTags()} -- Returns a formatted vesion of the self.\_metaTags | |
| - dictionary, using the formatMetaTags function from | |
| - \code{\_SkeletonPage.py}. | |
| -\item {\bf stylesheetTags()} -- Returns a formatted version of the | |
| - \code{self.\_stylesheetLibs} and \code{self.\_stylesheets} dictionaries. | |
| - The keys in \code{self.\_stylesheets} must be listed in the order that | |
| - they should appear in the list \code{self.\_stylesheetsOrder}, to ensure | |
| - that the style rules are defined in the correct order. | |
| -\item {\bf javascriptTags()} -- Returns a formatted version of the | |
| - \code{self.\_javascriptTags} and \code{self.\_javascriptLibs} dictionaries. | |
| - Each value in \code{self.\_javascriptTags} should be a either a code string | |
| - to include, or a list containing the JavaScript version number and the code | |
| - string. The keys can be anything. The same applies for | |
| - \code{self.\_javascriptLibs}, but the string should be the SRC filename | |
| - rather than a code string. | |
| -\item {\bf bodyTag()} -- Returns an HTML body tag from the entries in the dict | |
| - \code{self.\_bodyTagAttribs}. | |
| -\end{itemize} | |
| - | |
| -The class also provides some convenience methods that can be used as | |
| -\$placeholders in your template definitions: | |
| - | |
| -\begin{itemize} | |
| -\item {\bf imgTag(self, src, alt='', width=None, height=None, border=0)} -- | |
| - Dynamically generate an image tag. Cheetah will try to convert the | |
| - ``\code{src}'' argument to a WebKit serverSidePath relative to the | |
| - servlet's location. If width and height aren't specified they are | |
| - calculated using PIL or ImageMagick if either of these tools are available. | |
| - If all your images are stored in a certain directory you can reimplement | |
| - this method to append that directory's path to the ``\code{src}'' argument. | |
| - Doing so would also insulate your template definitions from changes in your | |
| - directory structure. | |
| -\end{itemize} | |
| - | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| diff --git a/docs/users_guide_src/links.tex b/docs/users_guide_src/links.tex | |
| deleted file mode 100755 | |
| index 1ec2f6c..0000000 | |
| --- a/docs/users_guide_src/links.tex | |
| +++ /dev/null | |
| @@ -1,112 +0,0 @@ | |
| -\section{Useful Web Links} | |
| -\label{links} | |
| - | |
| -See the wiki for more links. (The wiki is also updated more often than this | |
| -chapter is.) | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Cheetah Links} | |
| -\label{links.cheetah} | |
| - | |
| -\begin{description} | |
| -\item[Home Page] -- \url{http:www.CheetahTemplate.org/} | |
| - | |
| -\item[On-line Documentation] -- \url{http:www.CheetahTemplate.org/learn.html} | |
| - | |
| -\item[SourceForge Project Page] -- \url{http:sf.net/projects/cheetahtemplate/} | |
| - | |
| -\item[Mailing List Subscription Page] -- | |
| - \url{http://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss} | |
| - | |
| -\item[Mailing List Archive @ Geocrawler] -- | |
| - \url{http://www.geocrawler.com/lists/3/SourceForge/12986/0/} | |
| - | |
| -\item[Mailing List Archive @ Yahoo] -- | |
| - \url{http://groups.yahoo.com/group/cheetah-archive/} | |
| - | |
| -\item[CVS Repository] -- \url{http://sourceforge.net/cvs/?group\_id=28961} | |
| - | |
| -\item[CVS-commits archive] -- | |
| - \url{http://www.geocrawler.com/lists/3/SourceForge/13091/0/} | |
| - | |
| -\end{description} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Third-party Cheetah Stuff} | |
| -\label{links.thirdParty} | |
| - | |
| -\begin{itemize} | |
| -\item Steve Howell has written a photo viewer using Python. | |
| - \url{http://mountainwebtools.com/PicViewer/install.htm} | |
| -\end{itemize} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Webware Links} | |
| -\label{links.webware} | |
| - | |
| -\begin{description} | |
| -\item[Home Page] -- \url{http://webware.sf.net/} | |
| - | |
| -\item[On-line Documentation] -- \url{http://webware.sf.net/Webware/Docs/} | |
| - | |
| -\item[SourceForge Project Page] -- \url{http://sf.net/projects/webware/} | |
| - | |
| -\item[Mailing List Subscription Page] -- | |
| - \url{http://lists.sourceforge.net/lists/listinfo/webware-discuss} | |
| - | |
| -\end{description} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Python Links} | |
| -\label{links.python} | |
| - | |
| -\begin{description} | |
| -\item[Home Page] -- \url{http://www.python.org/} | |
| -\item[On-line Documentation] -- \url{http://www.python.org/doc/} | |
| -\item[SourceForge Project Page] -- \url{http://sf.net/projects/python/} | |
| -\item[The Vaults of Parnassus: Python Resources] -- | |
| - \url{http://www.vex.net/parnassus/} | |
| -\item[Python Cookbook] -- \url{http://aspn.activestate.com/ASPN/Cookbook/Python} | |
| -\end{description} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Other Useful Links} | |
| -\label{links.other} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{Python Database Modules and Open Source Databases} | |
| -\label{links.database} | |
| - | |
| -\begin{description} | |
| -\item[Python Database Topic Guide] -- \url{http://python.org/topics/database/} | |
| -\item[PostgreSQL Database] -- \url{http://www.postgresql.org/index.html} | |
| -\item[MySQL Database] -- \url{http://www.mysql.com/} | |
| -\item[A comparison of PostgreSQL and MySQL] -- | |
| - \url{http://phpbuilder.com/columns/tim20001112.php3} | |
| -\end{description} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{Other Template Systems} | |
| -\label{links.other.templateSystems} | |
| - | |
| -\begin{description} | |
| -\item[Chuck's ``Templates'' Summary Page] -- \url{http://webware.sf.net/Papers/Templates/} | |
| -\end{description} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{Other Internet development frameworks} | |
| -\label{links.internet} | |
| - | |
| -\begin{description} | |
| -\item[ZOPE (Z Object Publishing Environment)] -- \url{http://zope.org/} | |
| -\item[Server Side Java] -- \url{http://jakarta.apache.org/} | |
| -\item[PHP] -- \url{http://php.net/} | |
| -\item[IBM Websphere] -- \url{http://www.ibm.com/websphere/} | |
| -\item[Coldfusion and Spectra] -- \url{http://www.macromedia.com/} | |
| -\end{description} | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| diff --git a/docs/users_guide_src/moreverb.sty b/docs/users_guide_src/moreverb.sty | |
| deleted file mode 100755 | |
| index 92e34bb..0000000 | |
| --- a/docs/users_guide_src/moreverb.sty | |
| +++ /dev/null | |
| @@ -1,197 +0,0 @@ | |
| -%%% moreverb.sty | |
| -%%% AJCD 20 Sep 91 | |
| -%%% adds various verbatim environments using Rainer Sch\"opf's new verbatim | |
| -%%% environment. | |
| - | |
| - | |
| -%%% Marginal hacks (RF) to work `properly' with 2e | |
| -\def\filedate{1994/12/13} | |
| -\def\fileversion{v2.0} | |
| -% | |
| -\NeedsTeXFormat{LaTeX2e} | |
| -\ProvidesPackage{moreverb} | |
| - [\filedate\space \fileversion\space | |
| - LaTeX2e package for `more' verbatim enhancements] | |
| -\typeout{Package: `moreverb' | |
| - \fileversion \space <\filedate> (RF, after AJCD and RmS)} | |
| -%\typeout{English Documentation \@spaces <\docdate>} % oh no there isn't | |
| - | |
| -%%% load verbatim style if not already loaded. | |
| -\@ifundefined{verbatim@processline}{\RequirePackage{verbatim}}{} | |
| - | |
| -%%% verbatimwrite writes all text in its body to a file, the name of which it | |
| -%%% is given as an argument. Written by RmS. | |
| -\newwrite \verbatim@out | |
| -\def\verbatimwrite#1{% | |
| - \@bsphack | |
| - \immediate\openout \verbatim@out #1 | |
| - \let\do\@makeother\dospecials | |
| - \catcode`\^^M\active \catcode`\^^I=12 | |
| - \def\verbatim@processline{% | |
| - \immediate\write\verbatim@out | |
| - {\the\verbatim@line}}% | |
| - \verbatim@start} | |
| - | |
| -\def\endverbatimwrite{% | |
| - \immediate\closeout\verbatim@out | |
| - \@esphack} | |
| - | |
| -%%% Auxiliary macros and counters for expanding tabs. Use by listing and | |
| -%%% verbatimtab environments. | |
| -\newcount\tab@position \newcount\tab@size | |
| -\newcount\verbatimtabsize \verbatimtabsize=8 | |
| -\def\@xobeytab{\leavevmode\penalty\@M | |
| - {\loop\ \global\advance\tab@position-1 \ifnum\tab@position>0 \repeat}} | |
| -\begingroup | |
| - \catcode`\^^I=\active | |
| - \gdef\@vobeytabs{\catcode`\^^I\active\let^^I\@xobeytab}% | |
| -\endgroup | |
| -\def\verbatim@tabexpand#1{% | |
| - \ifx#1\@nil \let\next\par \else | |
| - \ifx#1\@xobeysp \@xobeysp\advance\tab@position-1 \else | |
| - \ifx#1\@xobeytab \@xobeytab\else | |
| - #1\advance\tab@position-1 | |
| - \fi\fi | |
| - \ifnum\tab@position=0 \tab@position\tab@size \fi | |
| - \let\next\verbatim@tabexpand | |
| - \fi\next | |
| -} | |
| - | |
| -%%% listing defines a verbatim environment with numbered lines; it takes an | |
| -%%% optional argument specifying the number of lines between numbered | |
| -%%% lines, and a mandatory argument specifying the starting line. listingcont | |
| -%%% continues from the place where listing left off. | |
| -%%% The style in which the label is set can be altered by re-defining | |
| -%%% \listinglabel. * versions are provided. | |
| -\newcount\listing@line \listing@line=1 \newcount\listing@step \listing@step=1 | |
| -% Adding an \hbox in front of the line causes a line break, so I go | |
| -% through this rigmarole to get the lines aligned nicely. I probably | |
| -% missed some obvious reason why \hboxes don't work. | |
| -\def\listinglabel#1{\rlap{\small\rm\the#1}\hskip2.5em} | |
| -\def\thelisting@line{% | |
| - \setbox0\hbox{\listinglabel\listing@line}% | |
| - \@tempcnta=\listing@line | |
| - \divide\@tempcnta\listing@step \multiply\@tempcnta\listing@step | |
| - \ifnum\listing@line=1 \unhbox0 | |
| - \else \ifnum\@tempcnta=\listing@line \unhbox0 | |
| - \else \hskip\wd0 | |
| - \fi\fi} | |
| -\def\listing{\@ifnextchar[{\@listing}{\@listing[1]}} | |
| -\def\@listing[#1]#2{% | |
| - \global\listing@line=#2\global\listing@step=#1\listingcont} | |
| -\def\listingcont{% | |
| - \tab@size=\verbatimtabsize | |
| - \def\verbatim@processline{\tab@position\tab@size | |
| - \thelisting@line \global\advance\listing@line1 | |
| - \expandafter\verbatim@tabexpand\the\verbatim@line\@nil}% | |
| - \@verbatim\frenchspacing\@vobeyspaces\@vobeytabs\verbatim@start} | |
| -\let\endlisting=\endtrivlist | |
| -\let\endlistingcont=\endtrivlist | |
| -\@namedef{listing*}{\@ifnextchar[{\@listingstar}{\@listingstar[1]}} | |
| -\def\@listingstar[#1]#2{% | |
| - \global\listing@line=#2\global\listing@step=#1\relax | |
| - \csname listingcont*\endcsname} | |
| -\@namedef{listingcont*}{% | |
| - \def\verbatim@processline{% | |
| - \thelisting@line \global\advance\listing@line1 | |
| - \the\verbatim@line\par}% | |
| - \@verbatim\verbatim@start} | |
| -\expandafter\let\csname endlisting*\endcsname =\endtrivlist | |
| -\expandafter\let\csname endlistingcont*\endcsname =\endtrivlist | |
| - | |
| -%%% file input version of listing | |
| -\def\listinginput{% | |
| - \@ifnextchar[{\@listinginput}{\@listinginput[1]}} | |
| -{\catcode`\~=\active \lccode`\~=`\^^M \lccode`\N=`\N | |
| - \lowercase{% | |
| - \gdef\@listinginput[#1]#2#3{\begingroup | |
| - \global\listing@line=#2\global\listing@step=#1 | |
| - \tab@size=\verbatimtabsize | |
| - \def\verbatim@processline{\tab@position\tab@size | |
| - \thelisting@line \global\advance\listing@line1 | |
| - \expandafter\verbatim@tabexpand\the\verbatim@line\@nil}% | |
| - \@verbatim\frenchspacing\@vobeyspaces\@vobeytabs | |
| - \def\verbatim@addtoline##1~{% | |
| - \verbatim@line\expandafter{\the\verbatim@line##1}}% | |
| - \openin\verbtab@in=#3 | |
| - \ifeof\verbtab@in\typeout{No file #3.}\else | |
| - \verbtab@oktrue | |
| - \loop | |
| - \read\verbtab@in to \verbtab@line | |
| - \ifeof\verbtab@in\verbtab@okfalse\else | |
| - \expandafter\verbatim@addtoline\verbtab@line | |
| - \verbatim@processline | |
| - \verbatim@startline | |
| - \fi | |
| - \ifverbtab@ok\repeat | |
| - \closein\verbtab@in\fi | |
| - \endtrivlist\endgroup\@doendpe}}} | |
| - | |
| -%%% verbatimcmd is a verbatim environment with the exception of the escape and | |
| -%%% grouping characters \, {, }. | |
| -\def\verbatimcmd{% | |
| - \@verbatim \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 | |
| - \frenchspacing\@vobeyspaces\verbatim@start | |
| -} | |
| -\def\endverbatimcmd{% | |
| - \let\par\relax | |
| - \def\verbatim@{\endtrivlist\endgroup}% | |
| - \begingroup} | |
| - | |
| -%%% boxedverbatim produces a verbatim environment in a framed box. | |
| -%%% written by Victor Eijkhout | |
| -\def\boxedverbatim{% | |
| - % redefine `processline' to produce only a line as wide | |
| - % as the natural width of the line | |
| - \def\verbatim@processline{% | |
| - {\setbox0=\hbox{\the\verbatim@line}% | |
| - \hsize=\wd0 \the\verbatim@line\par}}% | |
| - % save the verbatim code in a box | |
| - \setbox0=\vbox\bgroup \verbatim | |
| -} | |
| -\def\endboxedverbatim{% | |
| - \endverbatim | |
| - \egroup % close the box and `fbox' it | |
| - \fbox{\box0}% <<<=== change here for centering,... | |
| -} | |
| - | |
| -%%% verbatimtab is a verbatim environment which expands tab characters; it | |
| -%%% takes an optional argument specifying the width of tab stops | |
| -\def\verbatimtab{\futurelet\next\@verbatimtab} | |
| -\def\@verbatimtab{\if\next[ \let\next\@@verbatimtab\else | |
| - \def\next{\@@verbatimtab[\the\verbatimtabsize]}\fi\next} | |
| -\def\@@verbatimtab[#1]{% | |
| - \do@verbatimtab{#1}{% | |
| - \@verbatim\frenchspacing\@vobeyspaces\@vobeytabs\verbatim@start}% | |
| -} | |
| -\def\do@verbatimtab#1#2{% | |
| - \tab@size=#1 | |
| - \def\verbatim@processline{\tab@position\tab@size | |
| - \expandafter\verbatim@tabexpand\the\verbatim@line\@nil}#2 | |
| -} | |
| -\let\endverbatimtab=\endtrivlist | |
| - | |
| -%%% file input version of verbatimtab | |
| -\newread\verbtab@in \newif\ifverbtab@ok | |
| -\def\verbatimtabinput{% | |
| - \@ifnextchar[{\@verbatimtabinput}{\@verbatimtabinput[\the\verbatimtabsize]}} | |
| -{\catcode`\~=\active \lccode`\~=`\^^M \lccode`\N=`\N | |
| - \lowercase{% | |
| - \gdef\@verbatimtabinput[#1]#2{\begingroup | |
| - \do@verbatimtab{#1}{% | |
| - \@verbatim\frenchspacing\@vobeyspaces\@vobeytabs}% | |
| - \def\verbatim@addtoline##1~{% | |
| - \verbatim@line\expandafter{\the\verbatim@line##1}}% | |
| - \openin\verbtab@in=#2 | |
| - \ifeof\verbtab@in\typeout{No file #2.}\else | |
| - \verbtab@oktrue | |
| - \loop | |
| - \read\verbtab@in to \verbtab@line | |
| - \ifeof\verbtab@in\verbtab@okfalse\else | |
| - \expandafter\verbatim@addtoline\verbtab@line | |
| - \verbatim@processline | |
| - \verbatim@startline | |
| - \fi | |
| - \ifverbtab@ok\repeat | |
| - \closein\verbtab@in\fi | |
| - \endtrivlist\endgroup\@doendpe}}} | |
| diff --git a/docs/users_guide_src/nonHtml.tex b/docs/users_guide_src/nonHtml.tex | |
| deleted file mode 100755 | |
| index b618ab0..0000000 | |
| --- a/docs/users_guide_src/nonHtml.tex | |
| +++ /dev/null | |
| @@ -1,17 +0,0 @@ | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\section{Non-HTML Output} | |
| -\label{nonHTML} | |
| - | |
| -Cheetah can also output any other text format besides HTML. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Python source code} | |
| -\label{nonHTML.python} | |
| - | |
| -To be written. We're in the middle of working on an autoindenter to | |
| -make it easier to encode Python indentation in a Cheetah template. | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| -%# vim: sw=4 ts=4 expandtab | |
| diff --git a/docs/users_guide_src/optikLicense.tex b/docs/users_guide_src/optikLicense.tex | |
| deleted file mode 100755 | |
| index db63682..0000000 | |
| --- a/docs/users_guide_src/optikLicense.tex | |
| +++ /dev/null | |
| @@ -1,43 +0,0 @@ | |
| -\section{Optik license} | |
| -\label{optikLicense} | |
| - | |
| -The optik package (Cheetah.Utils.optik) is based on Optik 1.3, | |
| -\url{http://optik.sourceforge.net/}, \copyright 2001 Gregory P Ward | |
| -$<$gward@python.net$>$. It's unmodified from the original version except | |
| -the \code{import} statements, which have been adjusted to make them work in | |
| -this location. The following license applies to optik: | |
| - | |
| -\begin{quotation} | |
| -Redistribution and use in source and binary forms, with or without | |
| -modification, are permitted provided that the following conditions are | |
| -met: | |
| - | |
| -\begin{itemize} | |
| -\item Redistributions of source code must retain the above copyright | |
| - notice, this list of conditions and the following disclaimer. | |
| - | |
| -\item Redistributions in binary form must reproduce the above copyright | |
| - notice, this list of conditions and the following disclaimer in the | |
| - documentation and/or other materials provided with the distribution. | |
| - | |
| -\item Neither the name of the author nor the names of its | |
| - contributors may be used to endorse or promote products derived from | |
| - this software without specific prior written permission. | |
| -\end{itemize} | |
| - | |
| -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | |
| -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
| -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | |
| -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR | |
| -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
| -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
| -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
| -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
| -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
| -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| -\end{quotation} | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| diff --git a/docs/users_guide_src/otherHtml.tex b/docs/users_guide_src/otherHtml.tex | |
| deleted file mode 100755 | |
| index 89fd58a..0000000 | |
| --- a/docs/users_guide_src/otherHtml.tex | |
| +++ /dev/null | |
| @@ -1,95 +0,0 @@ | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\section{non-Webware HTML output} | |
| -\label{otherHTML} | |
| - | |
| -Cheetah can be used with all types of HTML output, not just with Webware. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Static HTML Pages} | |
| -\label{otherHTML.static} | |
| - | |
| -Some sites like Linux Gazette (\url{http://www.linuxgazette.com/}) require | |
| -completely static pages because they are mirrored on servers running completely | |
| -different software from the main site. Even dynamic sites may have one or | |
| -two pages that are static for whatever reason, and the site administrator may | |
| -wish to generate those pages from Cheetah templates. | |
| - | |
| -There's nothing special here. Just create your templates as usual. Then | |
| -compile and fill them whenever the template definition changes, and fill them | |
| -again whenever the placeholder values change. You may need an extra step to | |
| -copy the .html files to their final location. A Makefile (chapter | |
| -\ref{tips.Makefile}) can help encapsulate these steps. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{CGI scripts} | |
| -\label{otherHTML} | |
| - | |
| -Unlike Webware servlets, which don't have to worry about the HTTP headers, | |
| -CGI scripts must emit their own headers. To make a template CGI aware, add | |
| -this at the top: | |
| -\begin{verbatim} | |
| -#extends Cheetah.Tools.CGITemplate | |
| -#implements respond | |
| -$cgiHeaders#slurp | |
| -\end{verbatim} | |
| - | |
| -Or if your template is inheriting from a Python class: | |
| -\begin{verbatim} | |
| -#extends MyPythonClass | |
| -#implements respond | |
| -$cgiHeaders#slurp | |
| -\end{verbatim} | |
| - | |
| -A sample Python class: | |
| -\begin{verbatim} | |
| -from Cheetah.Tools import CGITemplate | |
| -class MyPythonClass(CGITemplate): | |
| - def cgiHeadersHook(self): | |
| - return "Content-Type: text/html; charset=koi8-r\n\n" | |
| -\end{verbatim} | |
| - | |
| - | |
| -Compile the template as usual, put the .py template module in your | |
| -cgi-bin directory and give it execute permission. \code{.cgiHeaders()} is | |
| -a ``smart'' method that outputs the headers if the module is called as a | |
| -CGI script, or outputs nothing if not. Being ``called as a CGI script'' | |
| -means the environmental variable \code{REQUEST\_METHOD} exists and | |
| -\code{self.isControlledByWebKit} is false. If you don't agree with that | |
| -definition, override \code{.isCgi()} and provide your own. | |
| - | |
| -The default header is a simple \verb+Content-type: text/html\n\n+, which works | |
| -with all CGI scripts. If you want to customize the headers (e.g., to | |
| -specify the character set), override \code{.cgiHeadersHook()} and return | |
| -a string containing all the headers. Don't forget to include the extra | |
| -newline at the end of the string: the HTTP protocol requires this empty | |
| -line to mark the end of the headers. | |
| - | |
| -To read GET/POST variables from form input, use the \code{.webInput()} method | |
| -(section \ref{webware.webInput}), or extract them yourself using Python's | |
| -\code{cgi} module or your own function. Although \code{.webInput()} was | |
| -originally written for Webware servlets, it now handles CGI scripts too. There | |
| -are a couple behavioral differences between CGI scripts and Webware servlets | |
| -regarding input variables: | |
| - | |
| -\begin{enumerate} | |
| -\item CGI scripts, using Python's \code{cgi} module, believe | |
| - \code{REQUEST\_METHOD} and recognize {\em either} GET variables {\em or} | |
| - POST variables, not both. Webware servlets, doing additional processing, | |
| - ignore \code{REQUEST\_METHOD} and recognize both, like PHP does. | |
| -\item Webware servlets can ask for cookies or session variables instead of | |
| - GET/POST variables, by passing the argument \code{src='c'} or | |
| - \code{src='s'}. CGI scripts get a \code{RuntimeError} if they try to do | |
| - this. | |
| -\end{enumerate} | |
| - | |
| -If you keep your .tmpl files in the same directory as your CGI scripts, make | |
| -sure they don't have execute permission. Apache at least refuses to serve | |
| -files in a \code{ScriptAlias} directory that don't have execute permission. | |
| - | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| -%# vim: sw=4 ts=4 expandtab | |
| diff --git a/docs/users_guide_src/output.tex b/docs/users_guide_src/output.tex | |
| deleted file mode 100755 | |
| index 742291e..0000000 | |
| --- a/docs/users_guide_src/output.tex | |
| +++ /dev/null | |
| @@ -1,548 +0,0 @@ | |
| -\section{Generating, Caching and Filtering Output} | |
| -\label{output} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Output from complex expressions: \#echo} | |
| -\label{output.echo} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#echo EXPR | |
| -\end{verbatim} | |
| - | |
| -The \code{\#echo} directive is used to echo the output from expressions that | |
| -can't be written as simple \$placeholders. | |
| - | |
| -\begin{verbatim} | |
| -Here is my #echo ', '.join(['silly']*5) # example | |
| -\end{verbatim} | |
| - | |
| -This produces: | |
| - | |
| -\begin{verbatim} | |
| -Here is my silly, silly, silly, silly, silly example. | |
| -\end{verbatim} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Executing expressions without output: \#silent} | |
| -\label{output.silent} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#silent EXPR | |
| -\end{verbatim} | |
| - | |
| -\code{\#silent} is the opposite of \code{\#echo}. It executes an expression | |
| -but discards the output. | |
| - | |
| -\begin{verbatim} | |
| -#silent $myList.reverse() | |
| -#silent $myList.sort() | |
| -Here is #silent $covertOperation() # nothing | |
| -\end{verbatim} | |
| - | |
| -If your template requires some Python code to be executed at the beginning; | |
| -(e.g., to calculate placeholder values, access a database, etc), you can put | |
| -it in a "doEverything" method you inherit, and call this method using | |
| -\code{\#silent} at the top of the template. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{One-line \#if} | |
| -\label{output.oneLineIf} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#if EXPR1 then EXPR2 else EXPR3# | |
| -\end{verbatim} | |
| - | |
| -The \code{\#if} flow-control directive (section \ref{flowControl.if}) has a | |
| -one-line counterpart akin to Perl's and C's \code{?:} operator. | |
| -If \code{EXPR1} is true, it evaluates \code{EXPR2} and outputs the result (just | |
| -like \code{\#echo\ EXPR2\#}). Otherwise it evaluates \code{EXPR3} and outputs | |
| -that result. This directive is short-circuiting, meaning the expression that | |
| -isn't needed isn't evaluated. | |
| - | |
| -You MUST include both 'then' and 'else'. If this doesn't work for you or you | |
| -don't like the style use multi-line \code{\#if} directives (section | |
| -\ref{flowControl.if}). | |
| - | |
| -The trailing \code{\#} is the normal end-of-directive character. As usual | |
| -it may be omitted if there's nothing after the directive on the same line. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Caching Output} | |
| -\label{output.caching} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{Caching individual placeholders} | |
| -\label{output.caching.placeholders} | |
| - | |
| -By default, the values of each \$placeholder is retrieved and | |
| -interpolated for every request. However, it's possible to cache the values | |
| -of individual placeholders if they don't change very often, in order to | |
| -speed up the template filling. | |
| - | |
| -To cache the value of a single \code{\$placeholder}, add an asterisk after the | |
| -\$; e.g., \code{\$*var}. The first time the template is | |
| -filled, \code{\$var} is looked up. Then whenever the template is filled again, | |
| -the cached value is used instead of doing another lookup. | |
| - | |
| -The \code{\$*} format caches ``forever''; that is, as long as the template | |
| -instance remains in memory. It's also possible to cache for a certain time | |
| -period using the form \code{\$*<interval>*variable}, where \code{<interval>} is | |
| -the interval. The time interval can be specified in seconds (5s), minutes | |
| -(15m), hours (3h), days (2d) or weeks (1.5w). The default is minutes. | |
| - | |
| -\begin{verbatim} | |
| -<HTML> | |
| -<HEAD><TITLE>$title</TITLE></HEAD> | |
| -<BODY> | |
| - | |
| -$var ${var} ## dynamic - will be reinterpolated for each request | |
| -$*var2 $*{var2} ## static - will be interpolated only once at start-up | |
| -$*5*var3 $*5*{var3} ## timed refresh - will be updated every five minutes. | |
| - | |
| -</BODY> | |
| -</HTML> | |
| -\end{verbatim} | |
| - | |
| -Note that ``every five minutes'' in the example really means every five | |
| -minutes: the variable is looked up again when the time limit is reached, | |
| -whether the template is being filled that frequently or not. Keep this in | |
| -mind when setting refresh times for CPU-intensive or I/O intensive | |
| -operations. | |
| - | |
| -If you're using the long placeholder syntax, \verb+${}+, the braces go only | |
| -around the placeholder name: \verb+$*.5h*{var.func('arg')}+. | |
| - | |
| -Sometimes it's preferable to explicitly invalidate a cached item whenever | |
| -you say so rather than at certain time intervals. You can't do this with | |
| -individual placeholders, but you can do it with cached regions, which will | |
| -be described next. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{Caching entire regions} | |
| -\label{output.caching.regions} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#cache [id=EXPR] [timer=EXPR] [test=EXPR] | |
| -#end cache | |
| -\end{verbatim} | |
| - | |
| -The \code{\#cache} directive is used to cache a region of | |
| -content in a template. The region is cached as a single unit, after | |
| -placeholders and directives inside the region have been evaluated. If there | |
| -are any \code{\$*<interval>*var} placholders inside the cache | |
| -region, they are refreshed only when {\em both} the cache region {\em and} the | |
| -placeholder are simultaneously due for a refresh. | |
| - | |
| -Caching regions offers more flexibility than caching individual placeholders. | |
| -You can specify the refresh interval using a placeholder or | |
| -expression, or refresh according to other criteria rather than a certain | |
| -time interval. | |
| - | |
| -\code{\#cache} without arguments caches the region statically, the same | |
| -way as \code{\$*var}. The region will not be automatically refreshed. | |
| - | |
| -To refresh the region at an interval, use the \code{timer=EXPRESSION} argument, | |
| -equivalent to \code{\$*<interval>*}. The expression should evaluate to a | |
| -number or string that is a valid interval (e.g., 0.5, '3m', etc). | |
| - | |
| -To refresh whenever an expression is true, use \code{test=EXPRESSION}. | |
| -The expression can be a method/function returning true or false, a boolean | |
| -placeholder, several of these joined by \code{and} and/or \code{or}, or any | |
| -other expression. If the expression contains spaces, it's easier to | |
| -read if you enclose it in \code{()}, but this is not required. | |
| - | |
| -To refresh whenever you say so, use \code{id=EXPRESSION}. Your program can | |
| -then call \code{.refreshCache(ID)} whenever it wishes. This is useful if the | |
| -cache depends on some external condition that changes infrequently but has just | |
| -changed now. | |
| - | |
| -You can combine arguments by separating them with commas. For instance, you can | |
| -specify both \code{id=} and \code{interval=}, or \code{id=} and \code{test=}. | |
| -(You can also combine interval and test although it's not very useful.) | |
| -However, repeating an argument is undefined. | |
| - | |
| -\begin{verbatim} | |
| -#cache | |
| -This is a static cache. It will not be refreshed. | |
| -$a $b $c | |
| -#end cache | |
| - | |
| -#cache timer='30m', id='cache1' | |
| -#for $cust in $customers | |
| -$cust.name: | |
| -$cust.street - $cust.city | |
| -#end for | |
| -#end cache | |
| - | |
| -#cache id='sidebar', test=$isDBUpdated | |
| -... left sidebar HTML ... | |
| -#end cache | |
| - | |
| -#cache id='sidebar2', test=($isDBUpdated or $someOtherCondition) | |
| -... right sidebar HTML ... | |
| -#end cache | |
| -\end{verbatim} | |
| - | |
| - | |
| -The \code{\#cache} directive cannot be nested. | |
| - | |
| -We are planning to add a \code{'varyBy'} keyword argument in the future that | |
| -will allow a separate cache instances to be created for a variety of conditions, | |
| -such as different query string parameters or browser types. This is inspired by | |
| -ASP.net's varyByParam and varyByBrowser output caching keywords. | |
| - | |
| -% @@MO: Can we cache by Webware sessions? What about sessions where the | |
| -% session ID is encoded as a path prefix in the URI? Need examples. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#raw} | |
| -\label{output.raw} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#raw | |
| -#end raw | |
| -\end{verbatim} | |
| - | |
| -Any section of a template definition that is inside a \code{\#raw \ldots | |
| -\#end raw} tag pair will be printed verbatim without any parsing of | |
| -\$placeholders or other directives. This can be very useful for debugging, or | |
| -for Cheetah examples and tutorials. | |
| - | |
| -\code{\#raw} is conceptually similar to HTML's \code{<PRE>} tag and LaTeX's | |
| -\code{\\verbatim\{\}} tag, but unlike those tags, \code{\#raw} does not cause | |
| -the body to appear in a special font or typeface. It can't, because Cheetah | |
| -doesn't know what a font is. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#include} | |
| -\label{output.include} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#include [raw] FILENAME_EXPR | |
| -#include [raw] source=STRING_EXPR | |
| -\end{verbatim} | |
| - | |
| -The \code{\#include} directive is used to include text from outside the | |
| -template definition. The text can come from an external file or from a | |
| -\code{\$placeholder} variable. When working with external files, Cheetah will | |
| -monitor for changes to the included file and update as necessary. | |
| - | |
| -This example demonstrates its use with external files: | |
| -\begin{verbatim} | |
| -#include "includeFileName.txt" | |
| -\end{verbatim} | |
| -The content of "includeFileName.txt" will be parsed for Cheetah syntax. | |
| - | |
| -And this example demonstrates use with \code{\$placeholder} variables: | |
| -\begin{verbatim} | |
| -#include source=$myParseText | |
| -\end{verbatim} | |
| -The value of \code{\$myParseText} will be parsed for Cheetah syntax. This is not | |
| -the same as simply placing the \$placeholder tag ``\code{\$myParseText}'' in | |
| -the template definition. In the latter case, the value of \$myParseText would | |
| -not be parsed. | |
| - | |
| -By default, included text will be parsed for Cheetah tags. The argument | |
| -``\code{raw}'' can be used to suppress the parsing. | |
| - | |
| -\begin{verbatim} | |
| -#include raw "includeFileName.txt" | |
| -#include raw source=$myParseText | |
| -\end{verbatim} | |
| - | |
| -Cheetah wraps each chunk of \code{\#include} text inside a nested | |
| -\code{Template} object. Each nested template has a copy of the main | |
| -template's searchList. However, \code{\#set} variables are visible | |
| -across includes only if the defined using the \code{\#set global} keyword. | |
| - | |
| -All directives must be balanced in the include file. That is, if you start | |
| -a \code{\#for} or \code{\#if} block inside the include, you must end it in | |
| -the same include. (This is unlike PHP, which allows unbalanced constructs | |
| -in include files.) | |
| - | |
| -% @@MO: What did we decide about #include and the searchList? Does it really | |
| -% use a copy of the searchList, or does it share the searchList with the | |
| -% parent? | |
| - | |
| -% @@MO: deleted | |
| -%These nested templates share the same \code{searchList} | |
| -%as the top-level template. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#slurp} | |
| -\label{output.slurp} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#slurp | |
| -\end{verbatim} | |
| - | |
| -The \code{\#slurp} directive eats up the trailing newline on the line it | |
| -appears in, joining the following line onto the current line. | |
| - | |
| - | |
| -It is particularly useful in \code{\#for} loops: | |
| -\begin{verbatim} | |
| -#for $i in range(5) | |
| -$i #slurp | |
| -#end for | |
| -\end{verbatim} | |
| -outputs: | |
| -\begin{verbatim} | |
| -0 1 2 3 4 | |
| -\end{verbatim} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#indent} | |
| -\label{output.indent} | |
| - | |
| -This directive is not implemented yet. When/if it's completed, it will allow | |
| -you to | |
| -\begin{enumerate} | |
| -\item indent your template definition in a natural way (e.g., the bodies | |
| - of \code{\#if} blocks) without affecting the output | |
| -\item add indentation to output lines without encoding it literally in the | |
| - template definition. This will make it easier to use Cheetah to produce | |
| - indented source code programmatically (e.g., Java or Python source code). | |
| -\end{enumerate} | |
| - | |
| -There is some experimental code that recognizes the \code{\#indent} | |
| -directive with options, but the options are purposely undocumented at this | |
| -time. So pretend it doesn't exist. If you have a use for this feature | |
| -and would like to see it implemented sooner rather than later, let us know | |
| -on the mailing list. | |
| - | |
| -The latest specification for the future \code{\#indent} directive is in the | |
| -TODO file in the Cheetah source distribution. | |
| - | |
| -% @@MO: disabled because it's not implemented and the spec is changing | |
| -% \code{\#indent} decouples the indentation in the template definition from the | |
| -% indentation in the output. Normally, Cheetah outputs indentation exactly as | |
| -% it sees it, no matter whether the indentation is on the first line of a | |
| -% paragraph, in front of a directive, or wherever. \code{\#indent} has two main | |
| -% uses: | |
| -% \begin{enumerate} | |
| -% \item To strip all indentation from source lines. This lets you indent | |
| -% multiline directives (e.g., \code{\#if}, \code{\#for}) in a natural way | |
| -% without having that indentation appear in the output. | |
| -% \item To indent every text line in the output according to a user-specified | |
| -% ``indentation level'', independent of whatever indentation the source lines | |
| -% may have. This is useful for producing Python output, or any language that | |
| -% requires strict indentation levels at certain places. To accomplish this, | |
| -% Cheetah adds a call to an indentation method at the beginning of every | |
| -% affected source line. | |
| -% \end{enumerate} | |
| -% | |
| -% To accomplish the first part, Cheetah removes leading whitespace from the | |
| -% affected source lines before the compiler see them. To accomplish the second | |
| -% part, Cheetah keeps track of the current indentation level, a value you have | |
| -% full control over. At the beginning of every affected text line, Cheetah calls | |
| -% a method that outputs the appropriate indentation string. This affects only | |
| -% lines in the template definition itself, not multiline placeholder values. | |
| -% See the \code{Indent} filter below to indent multiline placeholder values. | |
| -% | |
| -% All \code{\#indent} commands operate on the lines physically below them in | |
| -% the template definition until the next \code{\#indent}, regardless of scope. | |
| -% This means they work thorugh all other directives (\code{\#def}, \code{\#for}, | |
| -% \code{\#if}, etc) -- so that if you turn on indentation inside a \code{\#def}, | |
| -% it remains in effect past the \code{\#end def}. | |
| -% | |
| -% The following commands turn indentation on and off: | |
| -% \begin{description} | |
| -% \item{\code{\#indent on}} Strip leading whitespace and add indentation to the | |
| -% following lines. This fulfills use \#2 above. | |
| -% \item{\code{\#indent off}} Do not strip leading whitespace or add indentation. | |
| -% This is Cheetah's default behavior. | |
| -% \item{\code{\#indent strip}} Strip leading whitespace but do {\em not} add | |
| -% indentation. This fulfills use \#1 above. | |
| -% \end{description} | |
| -% | |
| -% Indentation by default uses real tabs. But you can change the indentation | |
| -% string thus: | |
| -% \begin{verbatim} | |
| -% ## Output four spaces for each indentation level. | |
| -% #indent chars ' ' | |
| -% ## Output the mail reply prefix for each indentation level. | |
| -% #indent chars '> ' | |
| -% ## Use a placeholder. | |
| -% #indent chars $indentChars | |
| -% ## Return to the default behavior. | |
| -% #indent chars '\t' | |
| -% \end{verbatim} | |
| -% | |
| -% | |
| -% The following commands change the indentation level, which is a non-negative | |
| -% integer initially at zero. All of these commands implicitly do an | |
| -% \code{\#indent on}: | |
| -% \begin{description} | |
| -% \item{\code{\#indent ++}} Increment the current indentation level. | |
| -% \item{\code{\#indent --}} Decrement the current indentation level. | |
| -% \item{\code{\#indent +3}} Add three indentation levels (or any number). | |
| -% \item{\code{\#indent -3}} Subtract three indentation levels (or any number). | |
| -% \item{\code{\#indent =3}} Set the indentation level to 3. | |
| -% \item{\code{\#indent push +2}} Save the current indentation level on a stack | |
| -% and add two. | |
| -% \item{\code{\#indent pop}} Return to the most recently pushed level. Raise | |
| -% \code{IndentationStackEmptyError} if there is no previous level. | |
| -% \end{description} | |
| -% | |
| -% The expressions after \code{+}/\code{-}/\code{=} may be numeric literals or | |
| -% Cheetah expressions. The effect is undefined if the value is negative. There | |
| -% may be whitespace after the \code{+}/\code{-}/\code{=} symbol. | |
| -% The initial implementation uses a simple preprocessor that doesn't understand | |
| -% newline characters in expressions. \code{\\n} is fine, but not a real newline. | |
| -% | |
| -% To indent multiline placeholder values using the current indentation level, | |
| -% use the \code{Indent} filter: | |
| -% \begin{verbatim} | |
| -% #filter Indent | |
| -% \end{verbatim} | |
| -% It works like the default filter but adds indentation after every newline. It | |
| -% does not strip any leading whitespace. It hooks into \code{\$self.\_indenter}, | |
| -% defined in \code{Cheetah.Utils.Indenter}. This object keeps track of the | |
| -% current indentation level. Specifically, the filter calls | |
| -% \code{\$self.\_indent()}, which is a shortcut to the indenter's | |
| -% \code{.indent()} method. This is the same thing \code{\#indent} does. | |
| -% However, the filter is usable even when indentation is in | |
| -% \code{off} or \code{strip} mode. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Ouput Filtering and \#filter} | |
| -\label{output.filter} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#filter FILTER_CLASS_NAME | |
| -#filter $PLACEHOLDER_TO_A_FILTER_INSTANCE | |
| -#filter None | |
| -\end{verbatim} | |
| - | |
| - | |
| -Output from \$placeholders is passed through an ouput filter. The default | |
| -filter merely returns a string representation of the placeholder value, | |
| -unless the value is \code{None}, in which case the filter returns an empty | |
| -string. Only top-level placeholders invoke the filter; placeholders inside | |
| -expressions do not. | |
| - | |
| -Certain filters take optional arguments to modify their behaviour. To pass | |
| -arguments, use the long placeholder syntax and precede each filter argument by | |
| -a comma. By convention, filter arguments don't take a \code{\$} prefix, to | |
| -avoid clutter in the placeholder tag which already has plenty of dollar signs. | |
| -For instance, the MaxLen filter takes an argument 'maxlen': | |
| - | |
| -\begin{verbatim} | |
| -${placeholderName, maxlen=20} | |
| -${functionCall($functionArg), maxlen=$myMaxLen} | |
| -\end{verbatim} | |
| - | |
| -To change the output filter, use the \code{'filter'} keyword to the | |
| -\code{Template} class constructor, or the \code{\#filter} | |
| -directive at runtime (details below). You may use \code{\#filter} as often as | |
| -you wish to switch between several filters, if certain \code{\$placeholders} | |
| -need one filter and other \code{\$placeholders} need another. | |
| - | |
| -The standard filters are in the module \code{Cheetah.Filters}. Cheetah | |
| -currently provides: | |
| - | |
| -\begin{description} | |
| -\item{\code{Filter}} | |
| - \\ The default filter, which converts None to '' and everything else to | |
| - \code{str(whateverItIs)}. This is the base class for all other filters, | |
| - and the minimum behaviour for all filters distributed with Cheetah. | |
| -\item{\code{ReplaceNone}} | |
| - \\ Same. | |
| -\item{\code{MaxLen}} | |
| - \\ Same, but truncate the value if it's longer than a certain length. | |
| - Use the 'maxlen' filter argument to specify the length, as in the | |
| - examples above. If you don't specify 'maxlen', the value will not be | |
| - truncated. | |
| -\item{\code{Pager}} | |
| - \\ Output a "pageful" of a long string. After the page, output HTML | |
| - hyperlinks to the previous and next pages. This filter uses several | |
| - filter arguments and environmental variables, which have not been | |
| - documented yet. | |
| -\item{\code{WebSafe}} | |
| - \\ Same as default, but convert HTML-sensitive characters ('$<$', '\&', | |
| - '$>$') | |
| - to HTML entities so that the browser will display them literally rather | |
| - than interpreting them as HTML tags. This is useful with database values | |
| - or user input that may contain sensitive characters. But if your values | |
| - contain embedded HTML tags you want to preserve, you do not want this | |
| - filter. | |
| - | |
| - The filter argument 'also' may be used to specify additional characters to | |
| - escape. For instance, say you want to ensure a value displays all on one | |
| - line. Escape all spaces in the value with '\ ', the non-breaking | |
| - space: | |
| -\begin{verbatim} | |
| -${$country, also=' '}} | |
| -\end{verbatim} | |
| -\end{description} | |
| - | |
| -To switch filters using a class object, pass the class using the | |
| -{\bf filter} argument to the Template constructor, or via a placeholder to the | |
| -\code{\#filter} directive: \code{\#filter \$myFilterClass}. The class must be | |
| -a subclass of \code{Cheetah.Filters.Filter}. When passing a class object, the | |
| -value of {\bf filtersLib} does not matter, and it does not matter where the | |
| -class was defined. | |
| - | |
| -To switch filters by name, pass the name of the class as a string using the | |
| -{\bf filter} argument to the Template constructor, or as a bare word (without | |
| -quotes) to the \code{\#filter} directive: \code{\#filter TheFilter}. The | |
| -class will be looked up in the {\bf filtersLib}. | |
| - | |
| -The filtersLib is a module containing filter classes, by default | |
| -\code{Cheetah.Filters}. All classes in the module that are subclasses of | |
| -\code{Cheetah.Filters.Filter} are considered filters. If your filters are in | |
| -another module, pass the module object as the {\bf filtersLib} argument to the | |
| -Template constructor. | |
| - | |
| -Writing a custom filter is easy: just override the \code{.filter} method. | |
| -\begin{verbatim} | |
| - def filter(self, val, **kw): # Returns a string. | |
| -\end{verbatim} | |
| -Return the {\em string} that should be output for `val'. `val' may be any | |
| -type. Most filters return `' for \code{None}. Cheetah passes one keyword | |
| -argument: \verb+kw['rawExpr']+ is the placeholder name as it appears in | |
| -the template definition, including all subscripts and arguments. If you use | |
| -the long placeholder syntax, any options you pass appear as keyword | |
| -arguments. Again, the return value must be a string. | |
| - | |
| -You can always switch back to the default filter this way: | |
| -\code{\#filter None}. This is easy to remember because "no filter" means the | |
| -default filter, and because None happens to be the only object the default | |
| -filter treats specially. | |
| - | |
| -We are considering additional filters; see | |
| -\url{http://webware.colorstudy.net/twiki/bin/view/Cheetah/MoreFilters} | |
| -for the latest ideas. | |
| - | |
| -%% @@MO: Is '#end filter' implemented? Will it be? Can filters nest? | |
| -%% Will '#end filter' and '#filter None' be equivalent? | |
| - | |
| -%% @@MO: Tavis TODO: fix the description of the Pager filter. It needs a howto. | |
| - | |
| -%% @@MO: How about using settings to provide default arguments for filters? | |
| -%% Each filter could look up FilterName (or FilterNameDefaults) setting, | |
| -%% whose value would be a dictionary containing keyword/value pairs. These | |
| -%% would be overridden by same-name keys passed by the placeholder. | |
| - | |
| -%% @@MO: If sed-filters (#sed) get added to Cheetah, give them a section here. | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| - | |
| -% vim: shiftwidth=4 tabstop=4 expandtab | |
| diff --git a/docs/users_guide_src/parserInstructions.tex b/docs/users_guide_src/parserInstructions.tex | |
| deleted file mode 100755 | |
| index bfd6bc2..0000000 | |
| --- a/docs/users_guide_src/parserInstructions.tex | |
| +++ /dev/null | |
| @@ -1,116 +0,0 @@ | |
| -\section{Instructions to the Parser/Compiler} | |
| -\label{parserInstructions} | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#breakpoint} | |
| -\label{parserInstructions.breakpoint} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#breakpoint | |
| -\end{verbatim} | |
| - | |
| - | |
| -\code{\#breakpoint} is a debugging tool that tells the parser to stop | |
| -parsing at a specific point. All source code from that point on will be ignored. | |
| - | |
| -The difference between \code{\#breakpoint} and \code{\#stop} is that | |
| -\code{\#stop} occurs in normal templates (e.g., inside an \code{\#if}) but | |
| -\code{\#breakpoint} is used only when debugging Cheetah. Another difference is | |
| -that \code{\#breakpoint} operates at compile time, while \code{\#stop} is | |
| -executed at run time while filling the template. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{\#compiler-settings} | |
| -\label{parserInstructions.compiler-settings} | |
| - | |
| -Syntax: | |
| -\begin{verbatim} | |
| -#compiler-settings | |
| -key = value (no quotes) | |
| -#end compiler-settings | |
| - | |
| -#compiler-settings reset | |
| -\end{verbatim} | |
| - | |
| - | |
| -The \code{\#compiler-settings} directive overrides Cheetah's standard settings, | |
| -changing how it parses source code and generates Python code. This | |
| -makes it possible to change the behaviour of Cheetah's parser/compiler for a | |
| -certain template, or within a portion of the template. | |
| - | |
| -The \code{reset} argument reverts to the default settings. With \code{reset}, | |
| -there's no end tag. | |
| - | |
| -Here are some examples of what you can do: | |
| -\begin{verbatim} | |
| -$myVar | |
| -#compiler-settings | |
| -cheetahVarStartToken = @ | |
| -#end compiler-settings | |
| -@myVar | |
| -#compiler-settings reset | |
| -$myVar | |
| -\end{verbatim} | |
| - | |
| - | |
| -\begin{verbatim} | |
| -## normal comment | |
| -#compiler-settings | |
| -commentStartToken = // | |
| -#end compiler-settings | |
| - | |
| -// new style of comment | |
| - | |
| -#compiler-settings reset | |
| - | |
| -## back to normal comments | |
| -\end{verbatim} | |
| - | |
| -\begin{verbatim} | |
| -#slurp | |
| -#compiler-settings | |
| -directiveStartToken = % | |
| -#end compiler-settings | |
| - | |
| -%slurp | |
| -%compiler-settings reset | |
| - | |
| -#slurp | |
| -\end{verbatim} | |
| - | |
| -Here's a partial list of the settings you can change: | |
| -\begin{enumerate} | |
| -\item syntax settings | |
| - \begin{enumerate} | |
| - \item cheetahVarStartToken | |
| - \item commentStartToken | |
| - \item multilineCommentStartToken | |
| - \item multilineCommentEndToken | |
| - \item directiveStartToken | |
| - \item directiveEndToken | |
| - \end{enumerate} | |
| -\item code generation settings | |
| - \begin{enumerate} | |
| - \item commentOffset | |
| - \item outputRowColComments | |
| - \item defDocStrMsg | |
| - \item useNameMapper | |
| - \item useAutocalling | |
| - \item reprShortStrConstants | |
| - \item reprNewlineThreshold | |
| - \end{enumerate} | |
| -\end{enumerate} | |
| -The meaning of these settings and their default values will be documented in | |
| -the future. | |
| - | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| - | |
| - | |
| - | |
| - | |
| diff --git a/docs/users_guide_src/tipsAndTricks.tex b/docs/users_guide_src/tipsAndTricks.tex | |
| deleted file mode 100755 | |
| index 8a16fb4..0000000 | |
| --- a/docs/users_guide_src/tipsAndTricks.tex | |
| +++ /dev/null | |
| @@ -1,544 +0,0 @@ | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\section{Tips, Tricks and Troubleshooting} | |
| -\label{tips} | |
| - | |
| -This chapter contains short stuff that doesn't fit anywhere else. | |
| - | |
| -See the Cheetah FAQ for more specialized issues and for troubleshooting tips. | |
| -Check the wiki periodically for recent tips contributed by users. If you | |
| -get stuck and none of these resources help, ask on the mailing list. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Placeholder Tips} | |
| -\label{tips.placeholder} | |
| - | |
| -Here's how to do certain important lookups that may not be obvious. | |
| -For each, we show first the Cheetah expression and then the Python equivalent, | |
| -because you can use these either in templates or in pure Python subclasses. | |
| -The Cheetah examples use NameMapper shortcuts (uniform dotted notation, | |
| -autocalling) as much as possible. | |
| - | |
| -To verify whether a variable exists in the searchList: | |
| -\begin{verbatim} | |
| -$varExists('theVariable') | |
| -self.varExists('theVariable') | |
| -\end{verbatim} | |
| -This is useful in \code{\#if} or \code{\#unless} constructs to avoid a | |
| -\code{\#NameMapper.NotFound} error if the variable doesn't exist. For instance, | |
| -a CGI GET parameter that is normally supplied but in this case the user typed | |
| -the URL by hand and forgot the parameter (or didn't know about it). | |
| -(\code{.hasVar} is a synonym for \code{.varExists}.) | |
| - | |
| -To look up a variable in the searchList from a Python method: | |
| -\begin{verbatim} | |
| -self.getVar('theVariable') | |
| -self.getVar('theVariable', myDefault) | |
| -\end{verbatim} | |
| -This is the equivalent to \code{\$theVariable} in the template. If the | |
| -variable is missing, it returns the second argument, \code{myDefault}, if | |
| -present, or raises \code{NameMapper.NotFound} if there is no second argument. | |
| -However, it usually easier to write your method so that all needed searchList | |
| -values come in as method arguments. That way the caller can just use a | |
| -\code{\$placeholder} to specify the argument, which is less verbose than you | |
| -writing a getVar call. | |
| - | |
| -To do a ``safe'' placeholder lookup that returns a default value if the | |
| -variable is missing: | |
| -\begin{verbatim} | |
| -$getVar('theVariable', None) | |
| -$getVar('theVariable', $myDefault) | |
| -\end{verbatim} | |
| - | |
| -To get an environmental variable, put \code{os.environ} on the searchList as a | |
| -container. Or read the envvar in Python code and set a placeholder variable | |
| -for it. | |
| - | |
| -Remember that variables found earlier in the searchList override same-name | |
| -variables located in a later searchList object. Be careful when adding objects | |
| -containing other variables besides the ones you want (e.g., \code{os.environ}, | |
| -CGI parameters). The "other" variables may override variables your application | |
| -depends on, leading to hard-to-find bugs. Also, users can inadvertently or | |
| -maliciously set an environmental variable or CGI parameter you didn't expect, | |
| -screwing up your program. To avoid all this, know what your namespaces | |
| -contain, and place the namespaces you have the most control over first. For | |
| -namespaces that could contain user-supplied "other" variables, don't put the | |
| -namespace itself in the searchList; instead, copy the needed variables into | |
| -your own "safe" namespace. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Diagnostic Output} | |
| -\label{tips.diagnostic} | |
| - | |
| -If you need send yourself some debugging output, you can use \code{\#silent} to | |
| -output it to standard error: | |
| -\begin{verbatim} | |
| -#silent $sys.stderr.write("Incorrigible var is '$incorrigible'.\n") | |
| -#silent $sys.stderr.write("Is 'unknown' in the searchList? " + | |
| - $getVar("unknown", "No.") + "\n" ) | |
| -\end{verbatim} | |
| -(Tip contributed by Greg Czajkowski.) | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{When to use Python methods} | |
| -\label{tips.pythonMethods} | |
| - | |
| -You always have a choice whether to code your methods as Cheetah \code{\#def} | |
| -methods or Python methods (the Python methods being located in a class your | |
| -template inherits). So how do you choose? | |
| - | |
| -Generally, if the method consists mostly of text and placeholders, use a | |
| -Cheetah method (a \code{\#def} method). That's why \code{\#def} exists, to | |
| -take the tedium out of writing those kinds of methods. And if you have a | |
| -couple \code{\#if} stanzas to \code{\#set} some variables, followed by a | |
| -\code{\#for} loop, no big deal. But if your method consists mostly of | |
| -directives and only a little text, you're better off writing it in Python. | |
| -Especially be on the watch for extensive use of \code{\#set}, \code{\#echo} and | |
| -\code{\#silent} in a Cheetah method--it's a sure sign you're probably using the | |
| -wrong language. Of course, though, you are free to do so if you wish. | |
| - | |
| -Another thing that's harder to do in Cheetah is adjacent or nested | |
| -multiline stanzas (all those directives with an accompanying \code{\#end} | |
| -directive). Python uses indentation to show the beginning and end of nested | |
| -stanzas, but Cheetah can't do that because any indentation shows up in the | |
| -output, which may not be desired. So unless all those extra spaces and tabs | |
| -in the output are acceptable, you have to keep directives flush with the left | |
| -margin or the preceding text. | |
| - | |
| -The most difficult decisions come when you have conflicting goals. What if | |
| -a method generates its output in parts (i.e., output concatenation), contains | |
| -many searchList placeholders and lots of text, {\em and} requires lots of | |
| -\code{\#if \ldots \#set \ldots \#else \#set \ldots \#end if} stanzas. A Cheetah | |
| -method would be more advantageous in some ways, but a Python method in others. | |
| -You'll just have to choose, perhaps coding groups of methods all the same | |
| -way. Or maybe you can split your method into two, one Cheetah and one Python, | |
| -and have one method call the other. Usually this means the Cheetah method | |
| -calling the Python method to calculate the needed values, then the Cheetah | |
| -method produces the output. One snag you might run into though is that | |
| -\code{\#set} currently can set only one variable per statement, so if your | |
| -Python method needs to return multiple values to your Cheetah method, you'll | |
| -have to do it another way. | |
| - | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Calling superclass methods, and why you have to} | |
| -\label{tips.callingSuperclassMethods} | |
| - | |
| -If your template or pure Python class overrides a standard method or attribute | |
| -of \code{Template} or one of its base classes, you should call the superclass | |
| -method in your method to prevent various things from breaking. The most common | |
| -methods to override are \code{.awake} and \code{.\_\_init\_\_}. \code{.awake} | |
| -is called automatically by Webware early during the web transaction, so it makes | |
| -a convenient place to put Python initialization code your template needs. | |
| -You'll definitely want to call the superclass \code{.awake} because it sets up | |
| -many wonderful attributes and methods, such as those to access the CGI input | |
| -fields. | |
| - | |
| -There's nothing Cheetah-specific to calling superclass methods, but | |
| -because it's vital, we'll recap the standard Python techniques | |
| -here. We mention only the solution for old-style classes because | |
| -Cheetah classes are old-style (in other Python documentation, you will | |
| -find the technique for new-style classes, but they are not listed here | |
| -because they cannot be used with Cheetah if you use | |
| -dynamically-compiled templates). | |
| - | |
| -\begin{verbatim} | |
| -from Cheetah.Template import Template | |
| -class MyClass(Template): | |
| - def awake(self, trans): | |
| - Template.awake(self, trans) | |
| - ... great and exciting features written by me ... | |
| -\end{verbatim} | |
| - | |
| -[ @@MO: Need to test this. .awake is in Servlet, which is a superclass | |
| -of Template. Do we really need both imports? Can we call | |
| -Template.awake? ] | |
| - | |
| -To avoid hardcoding the superclass name, you can use this | |
| -function \code{callbase()}, which emulates \code{super()} for older versions of | |
| -Python. It also works even \code{super()} does exist, so you don't have to | |
| -change your servlets immediately when upgrading. Note that the argument | |
| -sequence is different than \code{super} uses. | |
| - | |
| -\begin{verbatim} | |
| -=========================================================================== | |
| -# Place this in a module SOMEWHERE.py . Contributed by Edmund Lian. | |
| -class CallbaseError(AttributeError): | |
| - pass | |
| - | |
| -def callbase(obj, base, methodname='__init__', args=(), kw={}, | |
| - raiseIfMissing=None): | |
| - try: method = getattr(base, methodname) | |
| - except AttributeError: | |
| - if raiseIfMissing: | |
| - raise CallbaseError, methodname | |
| - return None | |
| - if args is None: args = () | |
| - return method(obj, *args, **kw) | |
| -=========================================================================== | |
| -# Place this in your class that's overriding .awake (or any method). | |
| -from SOMEWHERE import callbase | |
| -class MyMixin: | |
| - def awake(self, trans): | |
| - args = (trans,) | |
| - callbase(self, MyMixin, 'awake', args) | |
| - ... everything else you want to do ... | |
| -=========================================================================== | |
| -\end{verbatim} | |
| - | |
| -% @@MO: Edmund wants us to mention delegation too, as an alternative to | |
| -% inheritance. Contact elian@inbrief.net for details. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{All methods} | |
| -\label{tips.allMethods} | |
| - | |
| -Here is a list of all the standard methods and attributes that can be accessed | |
| -from a placeholder. Some of them exist for you to call, others are mainly used | |
| -by Cheetah internally but you can call them if you wish, and others are only | |
| -for internal use by Cheetah or Webware. Do not use these method names in mixin | |
| -classes (\code{\#extends}, section \ref{inheritanceEtc.extends}) unless you | |
| -intend to override the standard method. | |
| - | |
| -Variables with a star prefix ({\bf *}) are frequently used in templates or in | |
| -pure Python classes. | |
| - | |
| -\paragraph*{Inherited from Cheetah.Template} | |
| - | |
| -\begin{description} | |
| -\item{{\bf compile(source=None, file=None, moduleName=None, | |
| - mainMethodName='respond')}} Compile the template. Automatically called | |
| - by \code{.\_\_init\_\_}. | |
| -\item{{\bf generatedModuleCode()}} Return the module code the compiler | |
| - generated, or \code{None} if no compilation took place. | |
| -\item{{\bf generatedClassCode()}} Return the class code the compiler | |
| - generated, or \code{None} if no compilation took place. | |
| -\item{{\bf * searchList()}} Return a reference to the underlying search list. | |
| - (a list of objects). Use this to print out your searchList for debugging. | |
| - Modifying the returned list will affect your placeholder searches! | |
| -\item{{\bf * errorCatcher()}} Return a reference to the current error | |
| - catcher. | |
| -\item{{\bf * refreshCache(cacheKey=None)}} If 'cacheKey' is not \code{None}, | |
| - refresh that item in the cache. If \code{None}, delete all items in the | |
| - cache so they will be recalculated the next time they are encountered. | |
| -\item{{\bf * shutdown()}} Break reference cycles before discarding a servlet. | |
| -\item{{\bf * getVar(varName, default=NoDefault, autoCall=True)}} Look up a | |
| - variable in the searchList. Same as \code{\$varName} but allows you to | |
| - specify a default value and control whether autocalling occurs. | |
| -\item{{\bf * varExists(varName, autoCall=True)}} | |
| -\item{{\bf * getFileContents(path)}} Read the named file. If used as a | |
| - placeholder, inserts the file's contents in the output without | |
| - interpretation, like \code{\#include\ raw}. If used in an expression, | |
| - returns the file's content (e.g., to assign it to a variable). | |
| -\item{{\bf runAsMainProgram()}} This is what happens if you run a | |
| - .py template module as a standalone program. | |
| -\end{description} | |
| - | |
| -%Private methods: {\bf \_bindCompiledMethod}, {\bf \_bindFunctionAsMethod}, | |
| -%{\bf \_includeCheetahSource}, {\bf \_genTmpFilename}, | |
| -%{\bf \_importAsDummyModule}, {\bf \_makeDummyPackageForDir}, | |
| -%{\bf \_importFromDummyPackage}, {\bf \_importModuleFromDirectory}. | |
| -% | |
| -%Other private attributes: | |
| -%\begin{description} | |
| -%\item{{\bf * \_fileMtime}} Time the template definition was modified, in | |
| -% Unix ticks. \code{None} if the template definition came from a string or | |
| -% file handle rather than a named file, same for the next three variables. | |
| -%\item{{\bf * \_fileDirName}} The directory containing the template definition. | |
| -%\item{{\bf * \_fileBaseName}} The basename of the template definition file. | |
| -%\item{{\bf * \_filePath}} The directory+filename of the template definition. | |
| -%\end{description} | |
| - | |
| -\paragraph*{Inherited from Cheetah.Utils.WebInputMixin} | |
| - | |
| -\begin{description} | |
| -\item{{\bf nonNumericInputError}} Exception raised by \code{.webInput}. | |
| -\item{{\bf * webInput(...)}} Convenience method to access GET/POST variables | |
| - from a Webware servlet or CGI script, or Webware cookie or session | |
| - variables. See section \ref{webware.webInput} for usage information. | |
| -\end{description} | |
| - | |
| -\paragraph*{Inherited from Cheetah.SettingsManager} | |
| - | |
| -\begin{description} | |
| -\item{{\bf setting(name, default=NoDefault)}} Get a compiler setting. | |
| -\item{{\bf hasSetting(name)}} Does this compiler setting exist? | |
| -\item{{\bf setSetting(name, value)}} Set setting 'name' to 'value'. | |
| - See \code{\#compiler-settings}, section | |
| - \ref{parserInstructions.compiler-settings}. | |
| -\item{{\bf settings()}} Return the underlying settings dictionary. (Warning: | |
| - modifying this dictionary will change Cheetah's behavior.) | |
| -\item{{\bf copySettings()}} Return a copy of the underlying settings | |
| - dictionary. | |
| -\item{{\bf deepcopySettings()}} Return a deep copy of the underlying settings | |
| - dictionary. See Python's \code{copy} module. | |
| -\item{{\bf updateSettings(newSettings, merge=True)}} Update Cheetah's | |
| - compiler settings from the 'newSettings' dictionary. If 'merge' is true, | |
| - update only the names in newSettings and leave the other names alone. | |
| - (The SettingsManager is smart enough to update nested dictionaries one | |
| - key at a time rather than overwriting the entire old dictionary.) | |
| - If 'merge' is false, delete all existing settings so that the new ones are | |
| - the only settings. | |
| -\item{{\bf updateSettingsFromPySrcStr(theString, merge=True)}} Same, | |
| - but pass a string of \code{name=value} pairs rather | |
| - than a dictionary, the same as you would provide in a | |
| - \code{\#compiler-settings} directive, section | |
| - \ref{parserInstructions.compiler-settings}. | |
| -\item{{\bf updateSettingsFromPySrcFile(path, merge=True)}} Same, but | |
| - exec a Python source file and use the variables it contains as the new | |
| - settings. (e.g., \code{cheetahVarStartToken\ =\ "@"}). | |
| -\item{{\bf updateSettingsFromConfigFile(path, **kw)}} Same, but get the new | |
| - settings from a text file in ConfigParser format (similar to Windows' | |
| - *.ini file format). See Python's \code{ConfigParser} module. | |
| -\item{{\bf updateSettingsFromConfigFileObj}} Same, but read the open file | |
| - object 'inFile' for the new settings. | |
| -\item{{\bf updateSettingsFromConfigStr(configStr, convert=True, merge=True}} | |
| - Same, but read the new settings from a string in ConfigParser format. | |
| -\item{{\bf writeConfigFile(path)}} Write the current compiler settings to | |
| - a file named 'path' in *.ini format. | |
| -\item{{\bf getConfigString()}} Return a string containing the current | |
| - compiler settings in *.ini format. | |
| -\end{description} | |
| - | |
| -\paragraph*{Inherited from Cheetah.Servlet} | |
| - | |
| -{\em Do not override these in a subclass or assign to them as attributes | |
| -if your template will be used as a servlet,} otherwise Webware will behave | |
| -unpredictably. However, it {\em is} OK to put same-name variables in the | |
| -searchList, because Webware does not use the searchList. | |
| - | |
| -EXCEPTION: It's OK to override {\bf awake} and {\bf sleep} as long as you | |
| -call the superclass methods. (See section | |
| -\ref{tips.callingSuperclassMethods}.) | |
| - | |
| -\begin{description} | |
| -\item{{\bf * isControlledByWebKit}} True if this template instance is | |
| - part of a live transaction in a running WebKit servlet. | |
| -\item{{\bf * isWebwareInstalled}} True if Webware is installed and the | |
| - template instance inherits from WebKit.Servlet. If not, it inherits | |
| - from Cheetah.Servlet.DummyServlet. | |
| -\item{{\bf * awake(transaction)}} Called by WebKit at the beginning of | |
| - the web transaction. | |
| -\item{{\bf * sleep(transaction)}} Called by WebKit at the end of the | |
| - web transaction. | |
| -\item{{\bf * respond(transaction)}} Called by WebKit to produce the | |
| - web transaction content. For a template-servlet, this means | |
| - filling the template. | |
| -\item{{\bf shutdown()}} Break reference cycles before deleting instance. | |
| -\item{{\bf * serverSidePath()}} The filesystem pathname of the | |
| - template-servlet (as opposed to the URL path). | |
| -\item{{\bf transaction}} The current Webware transaction. | |
| -\item{{\bf application}} The current Webware application. | |
| -\item{{\bf response}} The current Webware response. | |
| -\item{{\bf request}} The current Webware request. | |
| -\item{{\bf session}} The current Webware session. | |
| -\item{{\bf write}} Call this method to insert text in the filled template | |
| - output. | |
| -\end{description} | |
| - | |
| -Several other goodies are available to template-servlets under the | |
| -\code{request} attribute, see section \ref{webware.input}. | |
| - | |
| -\code{transaction}, \code{response}, \code{request} and \code{session} are | |
| -created from the current transaction when WebKit calls \code{awake}, and don't | |
| -exist otherwise. Calling \code{awake} yourself (rather than letting WebKit | |
| -call it) will raise an exception because the \code{transaction} argument won't | |
| -have the right attributes. | |
| - | |
| -\paragraph*{Inherited from WebKit.Servlet} | |
| -These are accessible only if Cheetah knows Webware is installed. This | |
| -listing is based on a CVS snapshot of Webware dated 22 September 2002, and | |
| -may not include more recent changes. | |
| - | |
| -The same caveats about overriding these methods apply. | |
| - | |
| -\begin{description} | |
| -\item{name()} The simple name of the class. Used by Webware's logging and | |
| - debugging routines. | |
| -\item{log()} Used by Webware's logging and debugging routines. | |
| -\item{canBeThreaded()} True if the servlet can be multithreaded. | |
| -\item{canBeReused()} True if the servlet can be used for another transaction | |
| - after the current transaction is finished. | |
| -\item{serverSideDir()} Depreciated by \code{.serverSidePath()}. | |
| -\end{description} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Optimizing templates} | |
| -\label{tips.optimizing} | |
| - | |
| -Here are some things you can do to make your templates fill faster and user | |
| -fewer CPU cycles. Before you put a lot of energy into this, however, make | |
| -sure you really need to. In many situations, templates appear to initialize | |
| -and fill instantaneously, so no optimization is necessary. If you do find a | |
| -situation where your templates are filling slowly or taking too much memory or | |
| -too many CPU cycles, we'd like to hear about it on the mailing list. | |
| - | |
| -Cache \$placeholders whose values don't change frequently. (Section | |
| -\ref{output.caching}). | |
| - | |
| -Use \code{\#set} for values that are very frequently used, especially if they | |
| -come out of an expensive operation like a deeply.nested.structure or a database | |
| -lookup. \code{\#set} variables are set to Python local variables, which have a | |
| -faster lookup time than Python globals or values from Cheetah's searchList. | |
| - | |
| -Moving variable lookups into Python code may provide a speedup in certain | |
| -circumstances. If you're just reading \code{self} attributes, there's no | |
| -reason to use NameMapper lookup (\$placeholders) for them. NameMapper does | |
| -a lot more work than simply looking up a \code{self} attribute. | |
| - | |
| -On the other hand, if you don't know exactly where the value will come from | |
| -(maybe from \code{self}, maybe from the searchList, maybe from a CGI input | |
| -variable, etc), it's easier to just make that an argument to your method, and | |
| -then the template can handle all the NameMapper lookups for you: | |
| -\begin{verbatim} | |
| -#silent $myMethod($arg1, $arg2, $arg3) | |
| -\end{verbatim} | |
| -Otherwise you'd have to call \code{self.getVar('arg1')} etc in your | |
| -method, which is more wordy, and tedious. | |
| - | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{PSP-style tags} | |
| -\label{tips.PSP} | |
| - | |
| -\code{<\%= \ldots \%>} and \code{<\% \ldots \%>} allow an escape | |
| -to Python syntax inside the template. You do not need it to use Cheetah | |
| -effectively, and we're hard pressed to think of a case to recommend it. | |
| -Nevertheless, it's there in case you encounter a situation you can't | |
| -express adequately in Cheetah syntax. For instance, to set a local | |
| -variable to an elaborate initializer. | |
| - | |
| -\code{<\%= \ldots \%>} encloses a Python expression whose result will | |
| -be printed in the output. | |
| - | |
| -\code{<\% \ldots \%>} encloses a Python statement or expression (or set of | |
| -statements or expressions) that will be included as-is into the generated | |
| -method. The statements themselves won't produce any output, but you can use | |
| -the local function \code{write(EXPRESSION)} to produce your own output. | |
| -(Actually, it's a method of a file-like object, but it looks like a local | |
| -function.) This syntax also may be used to set a local variable with a | |
| -complicated initializer. | |
| - | |
| -To access Cheetah services, you must use Python code like you would in an | |
| -inherited Python class. For instance, use \code{self.getVar()} to look up | |
| -something in the searchList. | |
| - | |
| -{\em Warning:} {\bf No error checking is done!} If you write: | |
| -\begin{verbatim} | |
| -<% break %> ## Wrong! | |
| -\end{verbatim} | |
| -you'll get a \code{SyntaxError} when you fill the template, but that's what you | |
| -deserve. | |
| - | |
| -Note that these are PSP-{\em style} tags, not PSP tags. A Cheetah template | |
| -is not a PSP document, and you can't use PSP commands in it. | |
| - | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Makefiles} | |
| -\label{tips.Makefile} | |
| - | |
| -If your project has several templates and you get sick of typing | |
| -``cheetah compile FILENAME.tmpl'' all the time--much less remembering which | |
| -commands to type when--and your system has the \code{make} | |
| -command available, consider building a Makefile to make your life easier. | |
| - | |
| -Here's a simple Makefile that controls two templates, ErrorsTemplate and | |
| -InquiryTemplate. Two external commands, \code{inquiry} and \code{receive}, | |
| -depend on ErrorsTemplate.py. Aditionally, InquiryTemplate | |
| -itself depends on ErrorsTemplate. | |
| - | |
| -\begin{verbatim} | |
| -all: inquiry receive | |
| - | |
| -.PHONY: all receive inquiry printsource | |
| - | |
| -printsource: | |
| - a2ps InquiryTemplate.tmpl ErrorsTemplate.tmpl | |
| - | |
| -ErrorsTemplate.py: ErrorsTemplate.tmpl | |
| - cheetah compile ErrorsTemplate.tmpl | |
| - | |
| -InquiryTemplate.py: InquiryTemplate.tmpl ErrorsTemplate.py | |
| - cheetah compile InquiryTemplate.tmpl | |
| - | |
| -inquiry: InquiryTemplate.py ErrorsTemplate.py | |
| - | |
| -receive: ErrorsTemplate.py | |
| -\end{verbatim} | |
| - | |
| -Now you can type \code{make} anytime and it will recompile all the templates | |
| -that have changed, while ignoring the ones that haven't. Or you can | |
| -recompile all the templates \code{receive} needs by typing \code{make receive}. | |
| -Or you can recompile only ErrorsTemplate by typing | |
| -\code{make ErrorsTemplate}. There's also another target, ``printsource'': | |
| -this sends a Postscript version of the project's source files to the printer. | |
| -The .PHONY target is explained in the \code{make} documentation; essentially, | |
| -you have it depend on every target that doesn't produce an output file with | |
| -the same name as the target. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Using Cheetah in a Multi-Threaded Application} | |
| -\label{tips.threads} | |
| - | |
| -Template classes may be shared freely between threads. However, template | |
| -instances should not be shared unless you either: | |
| -\begin{itemize} | |
| -\item Use a lock (mutex) to serialize template fills, to prevent two threads | |
| -from filling the template at the same time. | |
| -\item Avoid thread-unsafe features: | |
| - \begin{itemize} | |
| - \item Modifying searchList values or instance variables. | |
| - \item Caching (\code{\$*var}, \code{\#cache}, etc). | |
| - \item \code{\#set global}, \code{\#filter}, \code{\#errorCatcher}. | |
| - \end{itemize} | |
| - Any changes to these in one thread will be visible in other threads, | |
| - causing them to give inconsistent output. | |
| -\end{itemize} | |
| - | |
| -About the only advantage in sharing a template instance is building up the | |
| -placeholder cache. But template instances are so low overhead that it | |
| -probably wouldn't take perceptibly longer to let each thread instantiate its | |
| -own template instance. Only if you're filling templates several times a | |
| -second would the time difference be significant, or if some of the placeholders | |
| -trigger extremely slow calculations (e.g., parsing a long text file each time). | |
| -The biggest overhead in Cheetah is importing the \code{Template} module in | |
| -the first place, but that has to be done only once in a long-running | |
| -application. | |
| - | |
| -You can use Python's \code{mutex} module for the lock, or any similar | |
| -mutex. If you have to change searchList values or instance variables | |
| -before each fill (which is usually the case), lock the mutex before | |
| -doing this, and unlock it only after the fill is complete. | |
| - | |
| -For Webware servlets, you're probably better off using Webware's servlet | |
| -caching rather than Cheetah's caching. Don't override the servlet's | |
| -\code{.canBeThreaded()} method unless you avoid the unsafe operations | |
| -listed above. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Using Cheetah with gettext} | |
| -\label{tips.gettext} | |
| - | |
| -{\bf gettext} is a project for creating internationalized applications. For | |
| -more details, visit \url{http://docs.python.org/lib/module-gettext.html}. | |
| -gettext can be used with Cheetah to create internationalized applications, even | |
| -for CJK character sets, but you must keep a couple things in mind: | |
| -\begin{itemize} | |
| -\item xgettext is used on compiled templates, not on the templates themselves. | |
| -\item The way the NameMapper syntax gets compiled to Python gets in the way of | |
| -the syntax that xgettext recognizes. Hence, a special case exists for the | |
| -functions \code{_}, \code{N_}, and \code{ngettext}. If you need to use a | |
| -different set of functions for marking strings for translation, you must set | |
| -the Cheetah setting \code{gettextTokens} to a list of strings representing the | |
| -names of the functions you are using to mark strings for translation. | |
| -\end{itemize} | |
| - | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| diff --git a/docs/users_guide_src/users_guide.tex b/docs/users_guide_src/users_guide.tex | |
| deleted file mode 100755 | |
| index 74949cf..0000000 | |
| --- a/docs/users_guide_src/users_guide.tex | |
| +++ /dev/null | |
| @@ -1,54 +0,0 @@ | |
| - | |
| -\documentclass{howto} | |
| -\usepackage{moreverb} %% Verbatim Code Listings | |
| - | |
| -\title{Cheetah Users' Guide} | |
| -\release{0.9.17rc1} | |
| - | |
| -\author{Edited by Mike Orr and Tavis Rudd} | |
| -\authoraddress{\email{cheetahtemplate-discuss@lists.sourceforge.net}} | |
| - | |
| -\begin{document} | |
| -\maketitle | |
| - | |
| -% @@MO: Picture of cheetah from web site. | |
| - | |
| -\tableofcontents | |
| - | |
| -\copyright{Copyright 2001-2005, The Cheetah Development Team. | |
| - This document may be copied and modified under the terms of the | |
| - {\bf Open Publication License} \url{http://www.opencontent.org/openpub/} } | |
| - | |
| - %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| - \include{introduction} | |
| - \include{glossary} | |
| - \include{gettingStarted} | |
| - \include{howItWorks} | |
| - \include{language} | |
| - \include{comments} | |
| - \include{output} | |
| - \include{inheritanceEtc} | |
| - \include{flowControl} | |
| - \include{errorHandling} | |
| - \include{parserInstructions} | |
| - \include{moduleFormatting} | |
| - \include{tipsAndTricks} | |
| - \include{webware} | |
| - \include{otherHtml} | |
| - \include{nonHtml} | |
| - \include{nonHTML} | |
| - \include{libraries} | |
| - \include{editors} | |
| - | |
| - %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| - \appendix | |
| - \include{links} | |
| - \include{examples} | |
| - \include{comparisons} | |
| - \include{optikLicense} | |
| - | |
| -\end{document} | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| diff --git a/docs/users_guide_src/webware.tex b/docs/users_guide_src/webware.tex | |
| deleted file mode 100755 | |
| index a5702d8..0000000 | |
| --- a/docs/users_guide_src/webware.tex | |
| +++ /dev/null | |
| @@ -1,575 +0,0 @@ | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\section{Using Cheetah with Webware} | |
| -\label{webware} | |
| - | |
| -{\bf Webware for Python} is a 'Python-Powered Internet Platform' that runs | |
| -servlets in a manner similar to Java servlets. {\bf WebKit} is the name of | |
| -Webware's application server. For more details, please visit | |
| -\url{http://webware.sourceforge.net/}. | |
| - | |
| -All comments below refer to the official version of Webware, the DamnSimple! | |
| -offshoot at ?, and the now-abandoned WebwareExperimental implementation at | |
| -\url{http://sourceforge.net/projects/expwebware/}, except where noted. All the | |
| -implementations are 95\% identical to the servlet writer: their differences lie | |
| -in their internal structure and configuration files. One difference is that | |
| -the executable you run to launch standard Webware is called \code{AppServer}, | |
| -whereas in WebwareExperimental it's called \code{webkit}. But to servlets | |
| -they're both "WebKit, Webware's application server", so it's one half dozen to | |
| -the other. In this document, we generally use the term {\bf WebKit} to refer | |
| -to the currently-running application server. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Installing Cheetah on a Webware system} | |
| -\label{webware.installing} | |
| - | |
| -Install Cheetah after you have installed Webware, following the instructions in | |
| -chapter \ref{gettingStarted}. | |
| - | |
| -The standard Cheetah test suite ('cheetah test') does not test Webware features. | |
| -We plan to build a test suite that can run as a Webware servlet, containing | |
| -Webware-specific tests, but that has not been built yet. In the meantime, you | |
| -can make a simple template containing something like "This is a very small | |
| -template.", compile it, put the *.py template module in a servlet | |
| -directory, and see if Webware serves it up OK. | |
| - | |
| -{\em You must not have a Webware context called "Cheetah".} If you do, Webware | |
| -will mistake that directory for the Cheetah module directory, and all | |
| -template-servlets will bomb out with a "ImportError: no module named Template". | |
| -(This applies only to the standard Webware; WebwareExperimental does not have | |
| -contexts.) | |
| - | |
| -If Webware complains that it cannot find your servlet, make sure | |
| -'.tmpl' is listed in 'ExtensionsToIgnore' in your 'Application.config' file. | |
| - | |
| -% @@MO: Should explain extension cascading and how without it, standard | |
| -% Webware pretends a file doesn't exist if it finds two or more servable files | |
| -% that match the URL. | |
| - | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Containment vs Inheritance} | |
| -\label{webware.background} | |
| - | |
| -Because Cheetah's core is flexible, there are many ways to integrate it with | |
| -Webware servlets. There are two broad strategies: the {\bf Inheritance | |
| -approach} and the {\bf Containment approach}. The difference is | |
| -that in the Inheritance approach, your template object \code{\em is} the | |
| -servlet, whereas in the Containment approach, the servlet is not a template but | |
| -merely {\em uses} template(s) for portion(s) of its work. | |
| - | |
| -The Inheritance approach is recommended for new sites because it's simpler, and | |
| -because it scales well for large sites with a | |
| -site->section->subsection->servlet hierarchy. The Containment approach is | |
| -better for existing servlets that you don't want to restructure. For instance, | |
| -you can use the Containment approach to embed a discussion-forum table at the | |
| -bottom of a web page. | |
| - | |
| -However, most people who use Cheetah extensively seem | |
| -to prefer the Inheritance approach because even the most analytical servlet | |
| -needs to produce {\em some} output, and it has to fit the site's look and feel | |
| -{\em anyway}, so you may as well use a template-servlet as the place to put the | |
| -output. Especially since it's so easy to add a template-servlet to a site once | |
| -the framework is established. So we recommend you at least evaluate the | |
| -effort that would be required to convert your site framework to template | |
| -superclasses as described below, vs the greater flexibility and manageability | |
| -it might give the site over the long term. You don't necessarily have to | |
| -convert all your existing servlets right away: just build common site templates | |
| -that are visually and behaviorally compatible with your specification, and use | |
| -them for new servlets. Existing servlets can be converted later, if at all. | |
| - | |
| -Edmund Liam is preparing a section on a hybrid approach, in which the | |
| -servlet is not a template, but still calls template(s) in an inheritance | |
| -chain to produce the output. The advantage of this approach is that you | |
| -aren't dealing with \code{Template} methods and Webware methods in the | |
| -same object. | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{The Containment Approach} | |
| -\label{webware.containment} | |
| - | |
| -In the Containment approach, your servlet is not a template. Instead, it | |
| -it makes its own arrangements to create and use template object(s) for whatever | |
| -it needs. The servlet must explicitly call the template objects' | |
| -\code{.respond()} (or \code{.\_\_str\_\_()}) method each time it needs to fill | |
| -the template. This does not present the output to the user; it merely gives | |
| -the output to the servlet. The servlet then calls its | |
| -\code{\#self.response().write()} method to send the output to the user. | |
| - | |
| -The developer has several choices for managing her templates. She can store the | |
| -template definition in a string, file or database and call | |
| -\code{Cheetah.Template.Template} manually on it. Or she can put the | |
| -template definition in a *.tmpl file and use {\bf cheetah compile} (section | |
| -\ref{howWorks.cheetah-compile}) to convert it to a Python class in a *.py | |
| -module, and then import it into her servlet. | |
| - | |
| -Because template objects are not thread safe, you should not store one | |
| -in a module variable and allow multiple servlets to fill it simultaneously. | |
| -Instead, each servlet should instantiate its own template object. Template | |
| -{\em classes}, however, are thread safe, since they don't change once created. | |
| -So it's safe to store a template class in a module global variable. | |
| - | |
| -% @@MO: Example of containment. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{The Inheritance Approach} | |
| -\label{webware.inheritance} | |
| - | |
| -In the Inheritance approach, your template object doubles as as Webware | |
| -servlet, thus these are sometimes called {\bf template-servlets}. {\bf cheetah | |
| -compile} (section \ref{howWorks.cheetah-compile}) automatically creates modules | |
| -containing valid Webware servlets. A servlet is a subclass of Webware's | |
| -\code{WebKit.HTTPServlet} class, contained in a module with the same name as | |
| -the servlet. WebKit uses the request URL to find the module, and then | |
| -instantiates the servlet/template. The servlet must have a \code{.respond()} | |
| -method (or \code{.respondToGet()}, \code{.respondToPut()}, etc., but the | |
| -Cheetah default is \code{.respond()}). Servlets created by \code{cheetah | |
| -compile} meet all these requirements. | |
| - | |
| -(Cheetah has a Webware plugin that automatically converts a \code{.tmpl servlet | |
| -file} into a \code{.py servlet file} when the \code{.tmpl servlet file} is | |
| -requested by a browser. However, that plugin is currently unavailable because | |
| -it's being redesigned. For now, use \code{cheetah compile} instead.) | |
| - | |
| -What about logic code? Cheetah promises to keep content (the placeholder | |
| -values), graphic design (the template definition and is display logic), and | |
| -algorithmic logic (complex calculations and side effects) separate. How? | |
| -Where do you do form processing? | |
| - | |
| -The answer is that your template class can inherit from a pure Python class | |
| -containing the analytical logic. You can either use the \code{\#extends} | |
| -directive in Cheetah to indicate the superclass(es), or write a Python | |
| -\code{class} statement to do the same thing. See the template | |
| -\code{Cheetah.Templates.SkeletonPage.tmpl} and its pure Python class | |
| -\code{Cheetah.Templates.\_SkeletonPage.py} for an example of a template | |
| -inheriting logic code. (See sections \ref{inheritanceEtc.extends} and | |
| -\ref{inheritanceEtc.implements} for more information about \code{\#extends} and | |
| -\code{\#implements}. They have to be used a certain right way.) | |
| - | |
| -If \code{\#WebKit.HTTPServlet} is not available, Cheetah fakes it with a | |
| -dummy class to satisfy the dependency. This allows servlets to be tested on | |
| -the command line even on systems where Webware is not installed. This works | |
| -only with servlets that don't call back into WebKit for information about the | |
| -current web transaction, since there is no web transaction. Trying to access | |
| -form input, for instance, will raise an exception because it depends on a | |
| -live web request object, and in the dummy class the request object is | |
| -\code{None}. | |
| - | |
| -Because Webware servlets must be valid Python modules, and ``cheetah compile'' | |
| -can produce only valid module names, if you're converting an existing site that | |
| -has .html filenames with hyphens (-), extra dots (.), etc, you'll have to | |
| -rename them (and possibly use redirects). | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Site frameworks} | |
| -\label{webware.siteFrameworks} | |
| - | |
| -Web sites are normally arranged hierarchically, with certain features common | |
| -to every page on the site, other features common to certain sections or | |
| -subsections, and others unique to each page. You can model this easily with | |
| -a hierarchy of classes, with specific servlets inheriting from their more | |
| -general superclasses. Again, you can do this two ways, using Cheetah's | |
| -{\bf Containment} approach or {\bf Inheritance} approach. | |
| - | |
| -In the Inheritance approach, parents provide \code{\#block}s and children | |
| -override them using \code{\#def}. Each child \code{\#extend}s its immediate | |
| -parent. Only the leaf servlets need to be under WebKit's document root | |
| -directory. The superclass servlets can live anywhere in the filesystem | |
| -that's in the Python path. (You may want to modify your WebKit startup | |
| -script to add that library directory to your \code{PYTHONPATH} before starting | |
| -WebKit.) | |
| - | |
| -% @@MO Examples: simple, IronSite, SkeletonPage. | |
| - | |
| -Section \ref{libraries.templates.skeletonPage} contains information on a stock | |
| -template that simplifies defining the basic HTML structure of your web | |
| -page templates. | |
| - | |
| -In the Containment approach, your hierarchy of servlets are not templates, but | |
| -each uses one or more templates as it wishes. Children provide callback | |
| -methods to to produce the various portions of the page that are their | |
| -responsibility, and parents call those methods. Webware's \code{WebKit.Page} | |
| -and \code{WebKit.SidebarPage} classes operate like this. | |
| - | |
| -% @@MO Show examples of WebKit.Page and WebKit.SidebarPage. | |
| - | |
| -Note that the two approaches are not compatible! \code{WebKit.Page} was not | |
| -designed to intermix with \code{Cheetah.Templates.SkeletonPage}. Choose either | |
| -one or the other, or expect to do some integration work. | |
| - | |
| -If you come up with a different strategy you think is worth noting in this | |
| -chapter, let us know. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Directory structure} | |
| -\label{webware.directoryStructure} | |
| - | |
| -Here's one way to organize your files for Webware+Cheetah. | |
| - | |
| -\begin{verbatim} | |
| -www/ # Web root directory. | |
| - site1.example.com/ # Site subdirectory. | |
| - apache/ # Web server document root (for non-servlets). | |
| - www/ # WebKit document root. | |
| - index.py # http://site1.example.com/ | |
| - index.tmpl # Source for above. | |
| - servlet2.py # http://site1.example.com/servlet2 | |
| - servlet2.tmpl # Source for above. | |
| - lib/ # Directory for helper classes. | |
| - Site.py # Site superclass ("#extends Site"). | |
| - Site.tmpl # Source for above. | |
| - Logic.py # Logic class inherited by some template. | |
| - webkit.config # Configuration file (for WebwareExperimental). | |
| - Webware/ # Standard Webware's MakeAppWorkDir directory. | |
| - AppServer # Startup program (for standard Webware). | |
| - Configs/ # Configuration directory (for standard Webware). | |
| - Application.config | |
| - # Configuration file (for standard Webware). | |
| - site2.example.org/ # Another virtual host on this computer.... | |
| -\end{verbatim} | |
| - | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Initializing your template-servlet with Python code} | |
| -\label{webware.calculations} | |
| - | |
| -If you need a place to initialize variables or do calculations for your | |
| -template-servlet, you can put it in an \code{.awake()} method because WebKit | |
| -automatically calls that early when processing the web transaction. If you | |
| -do override \code{.awake()}, be sure to call the superclass \code{.awake} | |
| -method. You probably want to do that first so that you have access to the | |
| -web transaction data \code{Servlet.awake} provides. You don't have to worry | |
| -about whether your parent class has its own \code{.awake} method, just call | |
| -it anyway, and somebody up the inheritance chain will respond, or at minimum | |
| -\code{Servlet.awake} will respond. Section | |
| -\ref{tips.callingSuperclassMethods} gives examples of how to call a | |
| -superclass method. | |
| - | |
| -As an alternative, you can put all your calculations in your own method and | |
| -call it near the top of your template. (\code{\#silent}, section | |
| -\ref{output.silent}). | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Form processing} | |
| -\label{webware.form} | |
| - | |
| -There are many ways to display and process HTML forms with Cheetah. | |
| -But basically, all form processing involves two steps. | |
| -\begin{enumerate} | |
| -\item{} Display the form. | |
| -\item{} In the next web request, read the parameters the user submitted, | |
| -check for user errors, perform any side effects (e.g., reading/writing a | |
| -database or session data) and present the user an HTML response or another | |
| -form. | |
| -\end{enumerate} | |
| - | |
| -The second step may involve choosing between several templates to fill (or | |
| -several servlets to redirect to), or a big if-elif-elif-else construct to | |
| -display a different portion of the template depending on the situation. | |
| - | |
| -In the oldest web applications, step 1 and step 2 were handled by separate | |
| -objects. Step 1 was a static HTML file, and step 2 was a CGI script. | |
| -Frequently, a better strategy is to have a single servlet handle both steps. | |
| -That way, the servlet has better control over the entire situation, and if | |
| -the user submits unacceptable data, the servlet can redisplay the form with a | |
| -"try again" error message at the top and and all the previous input filled in. | |
| -The servlet can use the presence or absence of certain CGI parameters (e.g., | |
| -the submit button, or a hidden mode field) to determine which step to take. | |
| - | |
| -One neat way to build a servlet that can handle both the form displaying and | |
| -form processing is like this: | |
| - | |
| -\begin{enumerate} | |
| -\item Put your form HTML into an ordinary template-servlet. In each input | |
| - field, use a placeholder for the value of the \code{VALUE=} attribue. | |
| - Place another placeholder next to each field, for that field's error | |
| - message. | |
| -\item Above the form, put a \code{\$processFormData} method call. | |
| -\item Define that method in a Python class your template \code{\#extend}s. (Or | |
| - if it's a simple method, you can define it in a \code{\#def}.) The method | |
| - should: | |
| - \begin{enumerate} | |
| - \item Get the form input if any. | |
| - \item If the input variable corresponding to the submit field is empty, | |
| - there is no form input, so we're showing the form for the first time. | |
| - Initialize all VALUE= variables to their default value (usually ""), | |
| - and all error variables to "". Return "", which will be the value for | |
| - \code{\$processFormData}. | |
| - \item If the submit variable is not empty, fill the VALUE= variables with | |
| - the input data the user just submitted. | |
| - \item Now check the input for errors and put error messages in the error | |
| - placeholders. | |
| - \item If there were any user errors, return a general error message | |
| - string; this will be the value for \code{\$processFormData}. | |
| - \item If there were no errors, do whatever the form's job is (e.g., update | |
| - a database) and return a success message; this will be the value for | |
| - \code{\$processFormData}. | |
| - \end{enumerate} | |
| -\item The top of the page will show your success/failure message (or nothing | |
| -the first time around), with the form below. If there are errors, the user | |
| -will have a chance to correct them. After a successful submit, the form will | |
| -appear again, so the user can either review their entry, or change it and | |
| -submit it again. Depending on the application, this may make the servlet | |
| -update the same database record again, or it may generate a new record. | |
| -\end{enumerate} | |
| - | |
| -% @@MO: Example of a template that shows a form and then processes the input. | |
| - | |
| -\code{FunFormKit} is a third-party Webware package that makes it easier to | |
| -produce forms and handle their logic. It has been successfully been used with | |
| -Cheetah. You can download FunFormKit from | |
| -\url{http://colorstudy.net/software/funformkit/} and try it out for yourself. | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Form input, cookies, session variables and web server variables} | |
| -\label{webware.input} | |
| - | |
| -General variable tips that also apply to servlets are in section | |
| -\ref{tips.placeholder}. | |
| - | |
| -To look up a CGI GET or POST parameter (with POST overriding): | |
| -\begin{verbatim} | |
| -$request.field('myField') | |
| -self.request().field('myField') | |
| -\end{verbatim} | |
| -These will fail if Webware is not available, because \code{\$request} | |
| -(aka \code{self.request()} will be \code{None} rather than a Webware | |
| -\code{WebKit.Request} object. If you plan to read a lot of CGI parameters, | |
| -you may want to put the \code{.fields} method into a local variable for | |
| -convenience: | |
| -\begin{verbatim} | |
| -#set $fields = $request.fields | |
| -$fields.myField | |
| -\end{verbatim} | |
| -But remember to do complicated calculations in Python, and assign the results | |
| -to simple variables in the searchList for display. These \code{\$request} | |
| -forms are useful only for occasions where you just need one or two simple | |
| -request items that going to Python for would be overkill. | |
| - | |
| -To get a cookie or session parameter, subsitute ``cookie'' or ``session'' for | |
| -``field'' above. To get a dictionary of all CGI parameters, substitute | |
| -``fields'' (ditto for ``cookies''). To verify a field exists, | |
| -substitute ``hasField'' (ditto for ``hasCookie''). | |
| - | |
| -Other useful request goodies: | |
| -\begin{verbatim} | |
| -## Defined in WebKit.Request | |
| -$request.field('myField', 'default value') | |
| -$request.time ## Time this request began in Unix ticks. | |
| -$request.timeStamp ## Time in human-readable format ('asctime' format). | |
| -## Defined in WebKit.HTTPRequest | |
| -$request.hasField.myField ## Is a CGI parameter defined? | |
| -$request.fields ## Dictionary of all CGI parameters. | |
| -$request.cookie.myCookie ## A cookie parameter (also .hasCookie, .cookies). | |
| -$request.value.myValue ## A field or cookie variable (field overrides) | |
| - ## (also .hasValue). | |
| -$request.session.mySessionVar # A session variable. | |
| -$request.extraURLPath ## URL path components to right of servlet, if any. | |
| -$request.serverDictionary ## Dict of environmental vars from web server. | |
| -$request.remoteUser ## Authenticated username. HTTPRequest.py source | |
| - ## suggests this is broken and always returns None. | |
| -$request.remoteAddress ## User's IP address (string). | |
| -$request.remoteName ## User's domain name, or IP address if none. | |
| -$request.urlPath ## URI of this servlet. | |
| -$request.urlPathDir ## URI of the directory containing this servlet. | |
| -$request.serverSidePath ## Absolute path of this servlet on local filesystem. | |
| -$request.serverURL ## URL of this servlet, without "http://" prefix, | |
| - ## extra path info or query string. | |
| -$request.serverURLDir ## URL of this servlet's directory, without "http://". | |
| -$log("message") ## Put a message in the Webware server log. (If you | |
| - ## define your own 'log' variable, it will override | |
| - ## this; use $self.log("message") in that case. | |
| -\end{verbatim} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection{.webInput()} | |
| -\label{webware.webInput} | |
| - | |
| -From the method docstring: | |
| - | |
| -\begin{verbatim} | |
| - def webInput(self, names, namesMulti=(), default='', src='f', | |
| - defaultInt=0, defaultFloat=0.00, badInt=0, badFloat=0.00, debug=False): | |
| - | |
| -This method places the specified GET/POST fields, cookies or session variables | |
| -into a dictionary, which is both returned and put at the beginning of the | |
| -searchList. It handles: | |
| - * single vs multiple values | |
| - * conversion to integer or float for specified names | |
| - * default values/exceptions for missing or bad values | |
| - * printing a snapshot of all values retrieved for debugging | |
| -All the 'default*' and 'bad*' arguments have "use or raise" behavior, meaning | |
| -that if they're a subclass of Exception, they're raised. If they're anything | |
| -else, that value is substituted for the missing/bad value. | |
| - | |
| -The simplest usage is: | |
| - | |
| - #silent $webInput(['choice']) | |
| - $choice | |
| - | |
| - dic = self.webInput(['choice']) | |
| - write(dic['choice']) | |
| - | |
| -Both these examples retrieves the GET/POST field 'choice' and print it. If you | |
| -leave off the "#silent", all the values would be printed too. But a better way | |
| -to preview the values is | |
| - | |
| - #silent $webInput(['name'], $debug=1) | |
| - | |
| -because this pretty-prints all the values inside HTML <PRE> tags. | |
| - | |
| -Since we didn't specify any coversions, the value is a string. It's a "single" | |
| -value because we specified it in 'names' rather than 'namesMulti'. Single | |
| -values work like this: | |
| - * If one value is found, take it. | |
| - * If several values are found, choose one arbitrarily and ignore the rest. | |
| - * If no values are found, use or raise the appropriate 'default*' value. | |
| - | |
| -Multi values work like this: | |
| - * If one value is found, put it in a list. | |
| - * If several values are found, leave them in a list. | |
| - * If no values are found, use the empty list ([]). The 'default*' | |
| - arguments are *not* consulted in this case. | |
| - | |
| -Example: assume 'days' came from a set of checkboxes or a multiple combo box | |
| -on a form, and the user chose "Monday", "Tuesday" and "Thursday". | |
| - | |
| - #silent $webInput([], ['days']) | |
| - The days you chose are: #slurp | |
| - #for $day in $days | |
| - $day #slurp | |
| - #end for | |
| - | |
| - dic = self.webInput([], ['days']) | |
| - write("The days you chose are: ") | |
| - for day in dic['days']: | |
| - write(day + " ") | |
| - | |
| -Both these examples print: "The days you chose are: Monday Tuesday Thursday". | |
| - | |
| -By default, missing strings are replaced by "" and missing/bad numbers by zero. | |
| -(A "bad number" means the converter raised an exception for it, usually because | |
| -of non-numeric characters in the value.) This mimics Perl/PHP behavior, and | |
| -simplifies coding for many applications where missing/bad values *should* be | |
| -blank/zero. In those relatively few cases where you must distinguish between | |
| -""/zero on the one hand and missing/bad on the other, change the appropriate | |
| -'default*' and 'bad*' arguments to something like: | |
| - * None | |
| - * another constant value | |
| - * $NonNumericInputError/self.NonNumericInputError | |
| - * $ValueError/ValueError | |
| -(NonNumericInputError is defined in this class and is useful for | |
| -distinguishing between bad input vs a TypeError/ValueError | |
| -thrown for some other reason.) | |
| - | |
| -Here's an example using multiple values to schedule newspaper deliveries. | |
| -'checkboxes' comes from a form with checkboxes for all the days of the week. | |
| -The days the user previously chose are preselected. The user checks/unchecks | |
| -boxes as desired and presses Submit. The value of 'checkboxes' is a list of | |
| -checkboxes that were checked when Submit was pressed. Our task now is to | |
| -turn on the days the user checked, turn off the days he unchecked, and leave | |
| -on or off the days he didn't change. | |
| - | |
| - dic = self.webInput([], ['dayCheckboxes']) | |
| - wantedDays = dic['dayCheckboxes'] # The days the user checked. | |
| - for day, on in self.getAllValues(): | |
| - if not on and wantedDays.has_key(day): | |
| - self.TurnOn(day) | |
| - # ... Set a flag or insert a database record ... | |
| - elif on and not wantedDays.has_key(day): | |
| - self.TurnOff(day) | |
| - # ... Unset a flag or delete a database record ... | |
| - | |
| -'source' allows you to look up the variables from a number of different | |
| -sources: | |
| - 'f' fields (CGI GET/POST parameters) | |
| - 'c' cookies | |
| - 's' session variables | |
| - 'v' "values", meaning fields or cookies | |
| - | |
| -In many forms, you're dealing only with strings, which is why the | |
| -'default' argument is third and the numeric arguments are banished to | |
| -the end. But sometimes you want automatic number conversion, so that | |
| -you can do numeric comparisons in your templates without having to | |
| -write a bunch of conversion/exception handling code. Example: | |
| - | |
| - #silent $webInput(['name', 'height:int']) | |
| - $name is $height cm tall. | |
| - #if $height >= 300 | |
| - Wow, you're tall! | |
| - #else | |
| - Pshaw, you're short. | |
| - #end if | |
| - | |
| - dic = self.webInput(['name', 'height:int']) | |
| - name = dic[name] | |
| - height = dic[height] | |
| - write("%s is %s cm tall." % (name, height)) | |
| - if height > 300: | |
| - write("Wow, you're tall!") | |
| - else: | |
| - write("Pshaw, you're short.") | |
| - | |
| -To convert a value to a number, suffix ":int" or ":float" to the name. The | |
| -method will search first for a "height:int" variable and then for a "height" | |
| -variable. (It will be called "height" in the final dictionary.) If a numeric | |
| -conversion fails, use or raise 'badInt' or 'badFloat'. Missing values work | |
| -the same way as for strings, except the default is 'defaultInt' or | |
| -'defaultFloat' instead of 'default'. | |
| - | |
| -If a name represents an uploaded file, the entire file will be read into | |
| -memory. For more sophisticated file-upload handling, leave that name out of | |
| -the list and do your own handling, or wait for Cheetah.Utils.UploadFileMixin. | |
| - | |
| -This mixin class works only in a subclass that also inherits from | |
| -Webware's Servlet or HTTPServlet. Otherwise you'll get an AttributeError | |
| -on 'self.request'. | |
| - | |
| -EXCEPTIONS: ValueError if 'source' is not one of the stated characters. | |
| -TypeError if a conversion suffix is not ":int" or ":float". | |
| -\end{verbatim} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{More examples} | |
| -\label{webware.examples} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection*{Example A -- a standalone servlet} | |
| -%\label{} | |
| - | |
| -% @@MO: | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection*{Example B -- a servlet under a site framework} | |
| -%\label{} | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsubsection*{Example C -- several servlets with a common template} | |
| -%\label{} | |
| - | |
| - | |
| - | |
| - | |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
| -\subsection{Other Tips} | |
| -\label{webware.otherTips} | |
| - | |
| -If your servlet accesses external files (e.g., via an \code{\#include} | |
| -directive), remember that the current directory is not necessarily directory | |
| -the servlet is in. It's probably some other directory WebKit chose. To find a | |
| -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 main method, read the chapter on inheritance (sections | |
| -\ref{inheritanceEtc.extends} and \ref{inheritanceEtc.implements}). This may | |
| -help you avoid buggy servlets. | |
| - | |
| -% Local Variables: | |
| -% TeX-master: "users_guide" | |
| -% End: | |
| -%# vim: sw=4 ts=4 expandtab | |
| diff --git a/src/Compiler.py b/src/Compiler.py | |
| index 71eeeb9..be3b63f 100644 | |
| --- a/src/Compiler.py | |
| +++ b/src/Compiler.py | |
| @@ -853,7 +853,8 @@ class MethodCompiler(GenUtils): | |
| return self.nextCacheID() | |
| def startCallRegion(self, functionName, args, lineCol, regionTitle='CALL'): | |
| - class CallDetails: pass | |
| + class CallDetails(object): | |
| + pass | |
| callDetails = CallDetails() | |
| callDetails.ID = ID = self.nextCallRegionID() | |
| callDetails.functionName = functionName | |
| @@ -1023,6 +1024,8 @@ class AutoMethodCompiler(MethodCompiler): | |
| MethodCompiler._setupState(self) | |
| self._argStringList = [ ("self",None) ] | |
| self._streamingEnabled = True | |
| + self._isClassMethod = None | |
| + self._isStaticMethod = None | |
| def _useKWsDictArgForPassingTrans(self): | |
| alreadyHasTransArg = [argname for argname,defval in self._argStringList | |
| @@ -1030,6 +1033,16 @@ class AutoMethodCompiler(MethodCompiler): | |
| return (self.methodName()!='respond' | |
| and not alreadyHasTransArg | |
| and self.setting('useKWsDictArgForPassingTrans')) | |
| + | |
| + def isClassMethod(self): | |
| + if self._isClassMethod is None: | |
| + self._isClassMethod = '@classmethod' in self._decorators | |
| + return self._isClassMethod | |
| + | |
| + def isStaticMethod(self): | |
| + if self._isStaticMethod is None: | |
| + self._isStaticMethod = '@staticmethod' in self._decorators | |
| + return self._isStaticMethod | |
| def cleanupState(self): | |
| MethodCompiler.cleanupState(self) | |
| @@ -1071,7 +1084,7 @@ class AutoMethodCompiler(MethodCompiler): | |
| if self._initialMethodComment: | |
| self.addChunk(self._initialMethodComment) | |
| - if self._streamingEnabled: | |
| + if self._streamingEnabled and not self.isClassMethod() and not self.isStaticMethod(): | |
| if self._useKWsDictArgForPassingTrans() and self._kwargsName: | |
| self.addChunk('trans = %s.get("trans")'%self._kwargsName) | |
| self.addChunk('if (not trans and not self._CHEETAH__isBuffering' | |
| @@ -1099,9 +1112,11 @@ class AutoMethodCompiler(MethodCompiler): | |
| pass | |
| elif allowSearchListAsMethArg and 'searchList' in argNames: | |
| self.addChunk('SL = searchList') | |
| - else: | |
| + elif not self.isClassMethod() and not self.isStaticMethod(): | |
| self.addChunk('SL = self._CHEETAH__searchList') | |
| - if self.setting('useFilters'): | |
| + else: | |
| + self.addChunk('SL = [KWS]') | |
| + if self.setting('useFilters') and not self.isClassMethod() and not self.isStaticMethod(): | |
| self.addChunk('_filter = self._CHEETAH__currentFilter') | |
| self.addChunk('') | |
| self.addChunk("#" *40) | |
| @@ -1128,6 +1143,11 @@ class AutoMethodCompiler(MethodCompiler): | |
| argStringChunks = [] | |
| for arg in self._argStringList: | |
| chunk = arg[0] | |
| + if chunk == 'self' and self.isClassMethod(): | |
| + chunk = 'cls' | |
| + if chunk == 'self' and self.isStaticMethod(): | |
| + # Skip the "self" method for @staticmethod decorators | |
| + continue | |
| if not arg[1] == None: | |
| chunk += '=' + arg[1] | |
| argStringChunks.append(chunk) | |
| diff --git a/src/Tests/Template.py b/src/Tests/Template.py | |
| index bca1b30..53e3a99 100644 | |
| --- a/src/Tests/Template.py | |
| +++ b/src/Tests/Template.py | |
| @@ -322,6 +322,36 @@ class TryExceptImportTest(TemplateTest): | |
| klass = Template.compile(source=source, compilerSettings={'useLegacyImportMode' : False}) | |
| t = klass(namespaces={'foo' : 1234}) | |
| +class ClassMethodSupport(TemplateTest): | |
| + def test_BasicDecorator(self): | |
| + template = ''' | |
| + #@classmethod | |
| + #def myClassMethod() | |
| + #return '$foo = %s' % $foo | |
| + #end def | |
| + ''' | |
| + template = Template.compile(source=template) | |
| + try: | |
| + rc = template.myClassMethod(foo='bar') | |
| + assert rc == '$foo = bar', (rc, 'Template class method didn\'t return what I expected') | |
| + except AttributeError, ex: | |
| + self.fail(ex) | |
| + | |
| +class StaticMethodSupport(TemplateTest): | |
| + def test_BasicDecorator(self): | |
| + template = ''' | |
| + #@staticmethod | |
| + #def myStaticMethod() | |
| + #return '$foo = %s' % $foo | |
| + #end def | |
| + ''' | |
| + template = Template.compile(source=template) | |
| + try: | |
| + rc = template.myStaticMethod(foo='bar') | |
| + assert rc == '$foo = bar', (rc, 'Template class method didn\'t return what I expected') | |
| + except AttributeError, ex: | |
| + self.fail(ex) | |
| + | |
| diff --git a/src/Version.py b/src/Version.py | |
| index 30bf439..390053d 100644 | |
| --- a/src/Version.py | |
| +++ b/src/Version.py | |
| @@ -1,5 +1,5 @@ | |
| -Version = '2.1.1' | |
| -VersionTuple = (2,1,1,'final',0) | |
| +Version = '2.1.2' | |
| +VersionTuple = (2,1,2,'final',0) | |
| MinCompatibleVersion = '2.0rc6' | |
| MinCompatibleVersionTuple = (2,0,0,'candidate',6) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment