summaryrefslogtreecommitdiff
path: root/docs/users_guide_src/output.tex
diff options
context:
space:
mode:
Diffstat (limited to 'docs/users_guide_src/output.tex')
-rwxr-xr-xdocs/users_guide_src/output.tex548
1 files changed, 548 insertions, 0 deletions
diff --git a/docs/users_guide_src/output.tex b/docs/users_guide_src/output.tex
new file mode 100755
index 0000000..742291e
--- /dev/null
+++ b/docs/users_guide_src/output.tex
@@ -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 '\&nbsp', 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