diff options
Diffstat (limited to 'docs/users_guide_2_src/07_output.txt')
-rwxr-xr-x | docs/users_guide_2_src/07_output.txt | 548 |
1 files changed, 548 insertions, 0 deletions
diff --git a/docs/users_guide_2_src/07_output.txt b/docs/users_guide_2_src/07_output.txt new file mode 100755 index 0000000..742291e --- /dev/null +++ b/docs/users_guide_2_src/07_output.txt @@ -0,0 +1,548 @@ +\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 |