A typical page served to a browser is made up from several component pages. The idea is to have reusable parts (widgets, skins), a bit like in a programming language where code that may be used more than once makes up a procedure. The complete page may have the following structure.
master
|
The "root" page includes the "widget" and wraps itself in the "master". That page in turn includes the "top" and "bottom".
The parts are
put together with the <include>
tag (in the diagram below,
black links going right) and
the <master>
tag (brown link going left);
and the concept is similar to a procedure call. The structure
of the composite page looks like this as a graph.
root | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
code | template | |||||||||||||||||||||
master | code | template | code | template | widget | |||||||||||||||||
code | template | code | template | |||||||||||||||||||
top | bottom |
Any (sub)page can have 0 or 1 master and 0 or more included
pages. Each page has its own separate scope for
variables. Arguments can be passed to dependent pages as
attributes to <inlcude>
, or as properties to
<master>
. The directed graph of pages will
often be be acyclic, as in the example, but this is not
required.
Sometimes it is of interest in which order the different
parts are evaluated. The "code" always runs first, followed by
the template. The <inlcude>
tag causes the
subpage to be evaluated at this point of the template, and the
rest of the including template is evaluated after that's done.
This is like a procedure call. In contrast, the
<master>
tag is deferred until the whole
slave page ("root" in the example) is done. For our example,
the following order results.
root.tcl | |||
root.adp | (beginning and middle) | ||
widget.tcl | |||
widget.adp | |||
root.adp | (end) | ||
master.tcl | |||
master.adp | (beginning) | ||
top.tcl | |||
top.adp | |||
master.adp | (middle, containing <slave> tag) | ||
bottom.tcl | |||
bottom.adp | |||
master.adp | (end) |
Here we assume the ACS/Tcl situation, where the "code" is a Tcl script in a .tcl file. The template is a .adp file.
The graph of the overall structure has five nodes, shown as a code/template pair. This is the standard situation, where the "code" part sets up datasources and the template uses them. In some situations, the following facility can help to reduce duplication or to handle special situations more effectively.
The "code" part can divert to another page by calling
template::set_file
to modify the file name stub of
the page being processed. For convenience,
ad_return_template
can be used with the same
effect; it is a wrapper for template::set_file
, and
it supplies the current file as the reference path. Neither
affects the flow of control; the script runs to completion. If
at the end the name is changed, the template of the original
page is not used; instead the new page is processed, code first,
then template. As that page's code can call
set_file
again, we get the following picure.
code A | (template A ignored) | |
code B | (template B ignored) | |
... | ||
code Z | template Z |
This assumes page "A" was originally wanted. An arrow () exits from code
which calls template::set_file
(directly or through
ad_return_template
). All scripts and the template
are executed in the same scope, i.e., they share
variables.
Furthermore either of the final files can be omitted if it is not needed, giving three basic possibilities.
a) | code | template | |
b) | (no code) | template | |
c) | code | (no template) |
It is an error to omit both parts; this is a special case intended to speed up debugging.