[Checkins] SVN: zope2book/trunk/ Restify ZPT chapter.

Tres Seaver tseaver at palladion.com
Tue Feb 10 15:52:11 EST 2009


Log message for revision 96420:
  Restify ZPT chapter.

Changed:
  D   zope2book/trunk/ZPT.stx
  A   zope2book/trunk/source/ZPT.rst
  U   zope2book/trunk/source/index.rst

-=-
Deleted: zope2book/trunk/ZPT.stx
===================================================================
--- zope2book/trunk/ZPT.stx	2009-02-10 19:54:42 UTC (rev 96419)
+++ zope2book/trunk/ZPT.stx	2009-02-10 20:52:11 UTC (rev 96420)
@@ -1,978 +0,0 @@
-Using Zope Page Templates
-
-  *Page Templates* are a web page generation tool.  They help programmers and
-  designers collaborate in producing dynamic web pages for Zope web
-  applications.  Designers can use them to maintain pages without having to
-  abandon their tools, while preserving the work required to embed those pages
-  in an application.
-
-  In this chapter, you'll learn the basic features of *Page Templates*,
-  including how you can use them in your website to create dynamic web pages
-  easily.  The next chapter walks you through a "hands on" example showing how
-  to build a Zope web application using scripts and *Page Templates*.  In the
-  chapter entitled "Advanced Page Templates":AdvZPT.stx, you'll learn about
-  advanced *Page Template* features.
-
-  The goal of *Page Templates* is to allow designers and programmers to work
-  together easily.  A designer can use a WYSIWYG HTML editor to create a
-  template, then a programmer can edit it to make it part of an application.
-  If required, the designer can load the template *back* into his editor and
-  make further changes to its structure and appearance.  By taking reasonable
-  steps to preserve the changes made by the programmer, the designer will not
-  disrupt the application.
-
-  *Page Templates* aim at this goal by adopting three principles:
-
-  1. Play nicely with editing tools.
-
-  2. What you see is very similar to what you get.
-
-  3. Keep code out of templates, except for structural logic.
-
-  A Page Template is like a model of the pages that it will generate.  In
-  particular, it is parseable by most HTML tools.
-
-  Zope Page Templates versus DTML
-
-    *Page Templates* use the *Template Attribute Language* (*TAL*), while
-    *DTML Methods*, *DTML Documents* and *SQL Methods* use the *Document
-    Template Markup Language* (*DTML*).  You may wonder why Zope needs two
-    different template languages.
-
-    First of all, there are historical reasons.  *Page Templates* are a
-    relative new technology.  Zope 2.5 was the first release that shipped with
-    *Page Templates*.  There are still many products and howtos that use
-    *DTML* for tasks *Page Templates* are designed for.  And some people still
-    prefer working with *DTML*.
-
-    Secondly, *DTML* and *Page Templates* have different strengths and
-    weaknesses.  *Page Templates* are aimed at HTML designers.  Once an HTML
-    page has been "dynamicized" by inserting *DTML* into it, the resulting
-    page typically becomes un-parseable for HTML tools, making it difficult to
-    work with outside Zope.  *Page Templates* also enforce separation of
-    presentation, logic and content (data).  This increases the scalability of
-    content management and website development efforts that use these systems.
-    And *Page Templates* give you better control over name lookups, while
-    *DTML*'s namespace model adds too much "magic".
-
-    But *DTML* has its strengths if we are dealing with something else than
-    HTML/XML presentation, such as dynamically generated email messages and
-    SQL queries.  So *DTML* is not a "dead end" and for some advanced tasks
-    you might want to learn *DTML*, too.
-
-  HTML Page Templates
-
-    *Page Templates* can operate in two modes: *HTML Mode* and *XML Mode*.
-    Later in this chapter we will show you how to use the *XML Mode*, but in
-    most cases we want to use the *HTML Mode* which is also the default mode.
-    For the *HTML Mode* the *Content-Type* has to be set to 'text/html'.
-
-    HTML isn't XML-conform and can't be extended by a template language.  So
-    while rendered HTML *Page Templates* should return valid HTML, their
-    source code isn't valid HTML or XML.  But the *Template Attribute
-    Language* (*TAL*) does a good job in hiding itself in HTML tags, so most
-    HTML tools will be able to parse the source of HTML *Page Templates* and
-    just ignore the *TAL* attributes.
-
-    As you might already know, XHTML is a XML-conform reformulation of HTML
-    and widely used in our days.  Nevertheless, generating HTML and XHTML
-    with *Page Templates* works exactly the same way.  While the *HTML Mode*
-    doesn't enforce well-formed XML, it's absolutely fine to use this mode
-    also for XHTML.
-
-    How Page Templates Work
-
-      *Page Templates* use the *Template Attribute Language* (*TAL*).  *TAL*
-      consists of special tag attributes.  For example, a dynamic page
-      headline might look like this::
-
-        <h1 tal:content="context/title">Sample Page Title</h1>
-
-      The 'tal:content' attribute is a *TAL* statement.  Since it has an XML
-      namespace (the 'tal:' part) most editing tools will not complain that
-      they don't understand it, and will not remove it.  It will not change
-      the structure or appearance of the template when loaded into a WYSIWYG
-      editor or a web browser.  The name *content* indicates that it will set
-      the text contained by the 'h1' tag, and the value 'context/title' is an
-      expression providing the text to insert into the tag.  Given the text
-      specified by 'context/title' resolves to "Susan Jones Home Page", the
-      generated HTML snippet looks like this::
-
-        <h1>Susan Jones Home Page</h1>
-
-      All *TAL* statements consist of tag attributes whose name starts with
-      'tal:' and all *TAL* statements have values associated with them.  The
-      value of a *TAL* statement is shown inside quotes.  See Appendix C,
-      "Zope Page Templates Reference":AppendixC.stx, for more information on
-      *TAL*.
-
-      To the HTML designer using a WYSIWYG tool, the dynamic headline example
-      is perfectly parseable HTML, and shows up in their editor looking like a
-      headline should look like.  In other words, *Page Templates* play nicely
-      with editing tools.
-
-      This example also demonstrates the principle that "What you see is very
-      similar to what you get".  When you view the template in an editor, the
-      headline text will act as a placeholder for the dynamic headline text.
-      The template provides an example of how generated documents will look.
-
-      When this template is saved in Zope and viewed by a user, Zope turns the
-      dummy content into dynamic content, replacing "Sample Page Title" with
-      whatever 'context/title' resolves to.  In this case, 'context/title'
-      resolves to the title of the object to which the template is applied.
-      This substitution is done dynamically, when the template is viewed.
-
-      There are template statements for replacing entire tags, their contents,
-      or just some of their attributes.  You can repeat a tag several times or
-      omit it entirely.  You can join parts of several templates together, and
-      specify simple error handling.  All of these capabilities are used to
-      generate document structures.  Despite these capabilities, you **can't**
-      create subroutines or classes, perform complex flow control, or easily
-      express complex algorithms using a *Page Template*.  For these tasks,
-      you should use Python-based Scripts or application components.
-
-      The *Page Template* language is deliberately not as powerful and
-      general-purpose as it could be.  It is meant to be used inside of a
-      framework (such as Zope) in which other objects handle business logic
-      and tasks unrelated to page layout.
-
-      For instance, template language would be useful for rendering an invoice
-      page, generating one row for each line item, and inserting the
-      description, quantity, price, and so on into the text for each row.  It
-      would not be used to create the invoice record in a database or to
-      interact with a credit card processing facility.
-
-    Creating a Page Template
-
-      If you design pages, you will probably use FTP or WebDAV instead of the
-      Zope Management Interface (ZMI) to edit *Page Templates*.  See "Remote
-      Editing With FTP and WebDAV" in the "Advanced":AdvZPT.stx chapter for
-      information on editing *Page Templates* remotely.  For the small
-      examples in this chapter, it is easier to use the ZMI.
-
-      Use your web browser to log into the Zope Management Interface as a
-      manager.  Create a *Folder* to work in named 'template_test' in the root
-      of your Zope.  Visit this folder and choose *Page Template* from Zope's
-      add list (do *NOT* choose DTML Method or DTML Document, the following
-      examples only work inside a Page Template).  Type 'simple_page' in the
-      add form's *Id* field, then push the *Add and Edit* button.
-
-      You should now see the main editing page for the new *Page Template*.
-      The title is blank and the default template text is in the editing area.
-
-      Now let's create a simple dynamic page.  Type the words 'a Simple Page'
-      in the *Title* field.  Then, edit the template text to look like this::
-
-        <html>
-          <body>
-            <p>
-              This is <b tal:content="template/title">the Title</b>.
-            </p>
-          </body>
-        </html>
-
-      Now push the *Save Changes* button.  Zope should show a message
-      confirming that your changes have been saved.
-
-      If you get an error message, check to make sure you typed the example
-      correctly and save it again.  Using an external editor, an HTML comment
-      starting with *Page Template Diagnostics* is added to the template text
-      to show you something went wrong.  You don't need to erase the error
-      comment; once the error is corrected it will go away.
-
-      Click on the *Test* tab.  You should see a page with "This is **a Simple
-      Page**." at the top.  Notice that the title is bold.  This is because
-      the 'tal:content' statement just replaces the content of the *bold* tag.
-
-      Back up, then click on the *Browse HTML source* link under the
-      *Content-Type* field.  This will show you the *unrendered* source of the
-      template.  You should see, "This is **the Title**." The bold text acts
-      as a placeholder for the dynamic title text.  Back up again, so that you
-      are ready to edit the example further.
-
-      You can find two options on the *Edit* tab we will not touch for now:
-      The *Content-Type* field allows you to specify the content type of
-      your page.  Changing that value switches the *Page Template* into *XML
-      Mode*, discussed later in this chapter.  The *Expand macros with
-      editing* control is explained in the "Macros" section of this chapter.
-
-    *TALES* Expressions
-
-      The expression "template/title" in your simple Page Template is a *path
-      expression*.  This is the most common type of expression.  There are
-      several other types of expressions defined by the *TAL Expression
-      Syntax* (*TALES*) specification.  For more information on TALES see the
-      "Zope Page Templates Reference Appendix":AppendixC.stx.
-
-      Path Expressions
-
-        The 'template/title' *path expression* fetches the *title* attribute
-        of the template.  Here are some other common path expressions:
-
-        o 'context/objectValues': A list of the sub-objects of the folder on
-          which the template is called.
-
-        o 'request/URL': The URL of the current web request.
-
-        o 'user/getUserName': The authenticated user's login name.
-
-        From the last chapter you should already be familiar with the context
-        variable that is also available in *Python-based Scripts* and the
-        attribute 'objectValues' that specifies an API method.  The other two
-        examples are just to show you the pattern.  You will learn more about
-        them later in the book.
-
-        To see what these examples return, just copy the following lines into
-        a *Page Template* and select the *Test* tab.  You'll notice that
-        'context/objectValues' returns a list that needs further treatment to
-        be useful.  We'll come back to that later in this chapter::
-
-          <p tal:content="context/objectValues"></p>
-          <p tal:content="request/URL"></p>
-          <p tal:content="user/getUserName"></p>
-
-        Every *path expression* starts with a variable name.  The available
-        variable names refer either to objects like *context*, *request* or
-        *user* that are bound to every *Page Template* by default or variables
-        defined within the *Page Template* using TAL.  Note that *here* is an
-        old alias of *context* and still used in many places.
-
-        The small set of built-in variables such as *request* and *user* is
-        described in the chapter entitled "Advanced Page
-        Templates":AdvZPT.stx.  You will also learn how to define your own
-        variables in that chapter.
-
-        If the variable itself returns the value you want, you are done.
-        Otherwise, you add a slash ('/') and the name of a sub-object or
-        attribute.  You may need to work your way through several
-        sub-objects to get to the value you're looking for.
-
-      Python Expressions
-
-        A good rule of thumb is that if you need Python to express your logic,
-        you better factor out the code into a script.  But Zope is a good tool
-        for prototyping and sometimes it would be overkill to write a script
-        for one line of code.  And looking at existing products you will see
-        quite often 'Python expressions', so it's better to know them.
-
-        Recall the first example of this chapter::
-
-          <h1 tal:content="context/title">Sample Page Title</h1>
-
-        Let's try to rewrite it using a *Python expression*::
-
-          <h1 tal:content="python: context.getProperty('title')">Sample Page
-           Title</h1>
-
-        While *path expressions* are the default, we need a prefix to indicate
-        other expression types.  This expression with the prefix 'python:'
-        does (at least here) the same as the *path expression* above, but we
-        have to know that 'title' is a property of the context object and how
-        to access properties.  *Path expressions* try different ways to access
-        'title', so in general they are more flexible, but less explicit.
-
-        There are some simple things you can't do with *path expressions*.
-        The most common are comparing values like in::
-
-          "python: variable1 == variable2"
-
-        ... or passing arguments to methods, e.g.::
-
-          "python: context.objectValues(['Folder'])"
-
-    *TAL* Attributes
-
-      *Page Templates* are example pages or snippets.  *TAL* statements define
-      how to convert them dynamically.  Depending on the used *TAL* attribute
-      they substitute example content or attributes by dynamic values, or
-      remove or repeat example elements depending on dynamic values.
-
-      Inserting Text
-
-        In your "simple_page" template, you used the 'tal:content' statement
-        on a *bold* tag.  When you tested it, Zope replaced the content of the
-        HTML *bold* element with the title of the template.
-
-        This is easy as long as we want to replace the complete content of an
-        HTML element.  But what if we want to replace only some words within
-        an element?
-
-        In order to place dynamic text inside of other text, you typically use
-        'tal:replace' on an additional 'span' tag.  For example, add the
-        following lines to your example::
-
-          <p>The URL is
-            <span tal:replace="request/URL">
-              http://www.example.com</span>.</p>
-
-        The 'span' tag is structural, not visual, so this looks like "The URL
-        is http://www.example.com." when you view the source in an editor or
-        browser.  When you view the rendered version, however, it may look
-        something like::
-
-          The URL is http://localhost:8080/template_test/simple_page.
-
-        If you look at the source code of the rendered version, the *span*
-        tags are removed.
-
-        To see the difference between 'tal:replace' and 'tal:content', create
-        a page template and include the following in the body::
-
-          <b tal:content="template/title"></b>
-          <b tal:content="request/URL"></b>
-          <b tal:content="user/getUserName"></b>
-          <b tal:replace="template/title"></b>
-          <b tal:replace="request/URL"></b>
-          <b tal:replace="user/getUserName"></b>
-
-        There are two other ways to add elements that are only needed for
-        *TAL* attributes and that are removed again in the rendered version::
-
-          <p>The URL is
-            <span tal:content="request/URL" tal:omit-tag="">
-              http://www.example.com</span>.</p>
-
-        ... which is more useful in other situations and will be discussed
-        there and::
-
-          <p>The URL is
-            <tal:span tal:content="request/URL">
-              http://www.example.com</tal:span>.</p>
-
-        While you can get really far by using HTML elements and 'tal:replace'
-        or 'tal:omit-tag', some people prefer to use *TAL* elements if the
-        elements are only used to add *TAL* attributes.  *TAL* is an attribute
-        language and doesn't define any elements like 'tal:span', but it uses
-        a complete XML namespace and allows to use any element name you like.
-        They are silently removed while the *Page Template* is rendered.
-
-        This is useful for using speaking names like 'tal:loop', 'tal:case' or
-        'tal:span' and to insert additional elements where HTML doesn't allow
-        elements like 'span' or 'div'.  And if her browser or editor also
-        ignores these tags, the designer will have less trouble with *TAL*
-        elements than with additional HTML elements.
-
-      Repeating Structures
-
-        Let's start with a simple three-liner::
-
-          <p tal:repeat="number python: range(4)" tal:content="number">
-            999
-          </p>
-
-        'number' is our *repeat variable* and 'range(4)' is a *Python
-        expression* that returns the list '[0, 1, 2, 3]'.  If this code is
-        rendered, the 'repeat' statement repeats the *paragraph* element for
-        each value of the sequence, replacing the variable 'number' by the
-        current sequence value.  So the rendered page will not show the
-        example number '999', but 4 *paragraph* elements containing the
-        numbers of our list.
-
-        In most cases we want to iterate over more complex sequences.  Our
-        next example shows how to use a sequence of (references to) objects.
-        The 'simple_page' template could be improved by adding an item list,
-        in the form of a list of the objects that are in the same *Folder* as
-        the template.  You will make a table that has a row for each object,
-        and columns for the id, meta-type and title.  Add these lines to the
-        bottom of your example template::
-
-          <table border="1" width="100%">
-            <tr>
-              <th>Id</th>
-              <th>Meta-Type</th>
-              <th>Title</th>
-            </tr>
-            <tr tal:repeat="item context/objectValues">
-              <td tal:content="item/getId">Id</td>
-              <td tal:content="item/meta_type">Meta-Type</td>
-              <td tal:content="item/title">Title</td>
-            </tr>
-          </table>
-
-        The 'tal:repeat' statement on the table row means "repeat this row for
-        each item in my context's list of object values".  The *repeat*
-        statement puts the objects from the list into the *item* variable one
-        at a time (this is called the *repeat variable*), and makes a copy of
-        the row using that variable.  The value of 'item/getId' in each row is
-        the Id of the object for that row, and likewise with 'item/meta_type'
-        and 'item/title'.
-
-        You can use any name you like for the repeat variable ("item" is only
-        an example), as long as it starts with a letter and contains only
-        letters, numbers, and underscores ('_').  The repeat variable is only
-        defined in the repeat tag.  If you try to use it above or below the
-        *tr* tag you will get an error.
-
-        You can also use the repeat variable name to get information about the
-        current repetition.  See "Advanced Page Templates":AdvZPT.stx.
-
-        Now view the page and notice how it lists all the objects in the same
-        folder as the template.  Try adding or deleting objects from the
-        folder and notice how the page reflects these changes.
-
-      Conditional Elements
-
-        Using Page Templates you can dynamically query your environment and
-        selectively insert text depending on conditions.  For example, you
-        could display special information in response to a cookie::
-
-          <p tal:condition="request/cookies/verbose | nothing">
-            Here's the extra information you requested.
-          </p>
-
-        This paragraph will be included in the output only if there is a
-        'verbose' cookie set.  The expression, 'request/cookies/verbose |
-        nothing' is true only when there is a cookie named 'verbose' set.
-        You'll learn more about this kind of expression in the chapter
-        entitled "Advanced Page Templates":AdvZPT.stx.
-
-        Using the 'tal:condition' statement you can check all kinds of
-        conditions.  A 'tal:condition' statement leaves the tag and its
-        contents in place if its expression has a true value, but removes them
-        if the value is false.  Zope considers the number zero, a  blank
-        string, an empty list, and the built-in variable 'nothing' to be false
-        values.  Nearly every other value is true, including non-zero numbers,
-        and strings with anything in them (even spaces!).
-
-        Another common use of conditions is to test a sequence to see if it is
-        empty before looping over it.  For example in the last section you saw
-        how to draw a table by iterating over a collection of objects.  Here's
-        how to add a check to the page so that if the list of objects is empty
-        no table is drawn.
-
-        To allow you to see the effect, we first have to modify that example
-        a bit, showing only *Folder* objects in the context folder.  Because
-        we can't specify parameters using *path expressions* like
-        'context/objectValues', we first convert it into the *Python
-        expression* 'context.objectValues()' and then add the argument that
-        tells the 'objectValues' method to return only sub-folders::
-
-          <tr tal:repeat="item python: context.objectValues(['Folder'])">
-
-        If you did not add any sub-folders to the *template_test* folder so
-        far, you will notice that using the *Test* tab the table header is
-        still shown even if we have no table body.  To avoid this we add a
-        'tal:condition' statement in the table tag.  The complete table now
-        looks like this::
-
-          <table tal:condition="python: context.objectValues(['Folder'])"
-                 border="1" width="100%">
-            <tr>
-              <th>Id</th>
-              <th>Meta-Type</th>
-              <th>Title</th>
-            </tr>
-            <tr tal:repeat="item python: context.objectValues(['Folder'])">
-              <td tal:content="item/getId">Id</td>
-              <td tal:content="item/meta_type">Meta-Type</td>
-              <td tal:content="item/title">Title</td>
-            </tr>
-          </table>
-
-        If the list of sub-folders is an empty list, the condition is false
-        and the entire table is omitted.  You can verify this by using the
-        *Test* tab again.
-
-        Go and add three Folders named '1', '2', and '3' to the
-        *template_test* folder in which your *simple_page* template lives.
-        Revisit the *simple_page* template and view the rendered output via
-        the *Test* tab.  You will see a table that looks much like the below::
-
-          Id          Meta-Type          Title
-          1           Folder
-          2           Folder
-          3           Folder
-
-      Changing Attributes
-
-        Most, if not all, of the objects listed by your template have an
-        *icon* attribute that contains the path to the icon for that kind of
-        object.  In order to show this icon in the meta-type column, you will
-        need to insert this path into the 'src' attribute of an 'img' tag.
-        Edit the table cell in the meta-type column of the above example to
-        look like this::
-
-          <td><img src="/misc_/OFSP/File_icon.gif"
-                   tal:attributes="src item/icon" />
-            <span tal:replace="item/meta_type">Meta-Type</span></td>
-
-        The 'tal:attributes' statement replaces the 'src' attribute of the
-        'img' tag with the value of 'item/icon'.  The
-        'src="/misc_/OFSP/File_icon.gif"' attribute in the template acts as a
-        placeholder.
-
-        Notice that we've replaced the 'tal:content' attribute on the table
-        cell with a 'tal:replace' statement on a 'span' tag.  This change
-        allows you to have both an image and text in the table cell.
-
-  XML Page Templates
-
-    Creating XML with *Page Templates* is almost exactly like creating HTML.
-    You switch to *XML Mode* by setting the *content-type* field to
-    'text/xml' or whatever the content-type for your XML should be.
-
-    In *XML Mode* no "loose" markup is allowed.  Zope assumes that your
-    template is well-formed XML.  Zope also requires an explicit TAL and METAL
-    XML namespace declarations in order to emit XML.  For example, if you wish
-    to emit XHTML, you might put your namespace declarations on the 'html'
-    tag::
-
-      <html xmlns:tal="http://xml.zope.org/namespaces/tal"
-        xmlns:metal="http://xml.zope.org/namespaces/metal">
-
-    To browse the source of an XML template you go to 'source.xml' rather than
-    'source.html'.
-
-  Debugging and Testing
-
-    Zope helps you find and correct problems in your *Page Templates*.  Zope
-    notices problems at two different times: when you're editing a *Page
-    Template*, and when you're viewing a *Page Template*.  Zope catches
-    different types of problems when you're editing and than when you're
-    viewing a *Page Template*.
-
-    You may have already seen the trouble-shooting comments that Zope inserts
-    into your Page Templates when it runs into problems.  These comments tell
-    you about problems that Zope finds while you're editing your templates.
-    The sorts of problems that Zope finds when you're editing are mostly
-    errors in your *TAL* statements.  For example::
-
-      <!-- Page Template Diagnostics
-       Compilation failed
-       TAL.TALDefs.TALError: bad TAL attribute: 'contents', at line 10, column 1
-      -->
-
-    This diagnostic message lets you know that you mistakenly used
-    'tal:contents' rather than 'tal:content' on line 10 of your template.
-    Other diagnostic messages will tell you about problems with your template
-    expressions and macros.
-
-    When you're using the Zope management interface to edit *Page Templates*
-    it's easy to spot these diagnostic messages, because they are shown in the
-    "Errors" header of the management interface page when you save the *Page
-    Template*.  However, if you're using WebDAV or FTP it's easy to miss these
-    messages.  For example, if you save a template to Zope with FTP, you won't
-    get an FTP error telling you about the problem.  In fact, you'll have to
-    reload the template from Zope to see the diagnostic message.  When using
-    FTP and WebDAV it's a good idea to reload templates after you edit them to
-    make sure that they don't contain diagnostic messages.
-
-    If you don't notice the diagnostic message and try to render a template
-    with problems you'll see a message like this::
-
-      Error Type: PTRuntimeError
-      Error Value: Page Template hello.html has errors.
-
-    That's your signal to reload the template and check out the diagnostic
-    message.
-
-    In addition to diagnostic messages when editing, you'll occasionally get
-    regular Zope errors when viewing a Page Template.  These problems are
-    usually due to problems in your template expressions.  For example, you
-    might get an error if an expression can't locate a variable::
-
-      Error Type: KeyError
-      Error Value: 'unicorn'
-
-    This error message tells you that it cannot find the *unicorn* variable.
-    To help you figure out what went wrong, Zope includes information about
-    the environment in the traceback.  This information will be available in
-    your *error_log* (in your Zope root folder).  The traceback will include
-    information about the place where the error occurred and the environment::
-
-      URL: /sandbox/demo
-      Line 1, Column 14
-      Expression: standard:'context/unicorn'
-      Names:
-        {'container': <Folder instance at 019AC4D0>,
-         'context': <Application instance at 01736F78>,
-         'default': <Products.PageTemplates.TALES.Default instance at 0x012F9D00>,
-         ...
-         'root': <Application instance at 01736F78>,
-         'template': <ZopePageTemplate at /sandbox/demo>,
-         'traverse_subpath': [],
-         'user': admin}
-
-    This information is a bit cryptic, but with a little detective work it can
-    help you figure out what went wrong.  In this case, it tells us that the
-    'context' variable is an "Application instance".  This means that it is
-    the top-level Zope folder (notice how 'root' variable is the same
-    "Application instance").  Perhaps the problem is that you wanted to apply
-    the template to a folder that had a *unicorn* property, but the root on
-    which you called the template hasn't such a property.
-
-  Macros
-
-    So far, you've seen how *Page Templates* can be used to add dynamic
-    behavior to individual web pages.  Another feature of page templates is
-    the ability to reuse look and feel elements across many pages.
-
-    For example, with *Page Templates*, you can have a site that has a
-    standard look and feel.  No matter what the "content" of a page, it will
-    have a standard header, side-bar, footer, and/or other page elements.
-    This is a very common requirement for websites.
-
-    You can reuse presentation elements across pages with *macros*.  Macros
-    define a section of a page that can be reused in other pages.  A macro can
-    be an entire page, or just a chunk of a page such as a header or footer.
-    After you define one or more macros in one *Page Template*, you can use
-    them in other *Page Templates*.
-
-    Using Macros
-
-      You can define macros with tag attributes similar to *TAL* statements.
-      Macro tag attributes are called *Macro Expansion Tag Attribute Language*
-      (*METAL*) statements.  Here's an example macro definition::
-
-        <p metal:define-macro="copyright">
-          Copyright 2001, <em>Foo, Bar, and Associates</em> Inc.
-        </p>
-
-      This 'metal:define-macro' statement defines a macro named "copyright".
-      The macro consists of the 'p' element (including all contained elements,
-      ending with the closing 'p' tag).
-
-      Macros defined in a Page Template are stored in the template's *macros*
-      attribute.  You can use macros from other *Page Templates* by referring
-      to them through the *macros* attribute of the *Page Template* in which
-      they are defined.  For example, suppose the *copyright* macro is in a
-      *Page Template* called "master_page".  Here's how to use the *copyright*
-      macro from another *Page Template*::
-
-        <hr />
-        <b metal:use-macro="container/master_page/macros/copyright">
-          Macro goes here
-        </b>
-
-      In this *Page Template*, the 'b' element will be completely replaced by
-      the macro when Zope renders the page::
-
-        <hr />
-        <p>
-          Copyright 2001, <em>Foo, Bar, and Associates</em> Inc.
-        </p>
-
-      If you change the macro (for example, if the copyright holder changes)
-      then all *Page Templates* that use the macro will automatically reflect
-      the change.
-
-      Notice how the macro is identified by a *path expression* using the
-      'metal:use-macro' statement.  The 'metal:use-macro' statement replaces
-      the statement element with the named macro.
-
-    Macro Details
-
-      The 'metal:define-macro' and 'metal:use-macro' statements are pretty
-      simple.  However there are a few subtleties to using them which are
-      worth mentioning.
-
-      A macro's name must be unique within the Page Template in which it is
-      defined.  You can define more than one macro in a template, but they all
-      need to have different names.
-
-      Normally you'll refer to a macro in a 'metal:use-macro' statement with a
-      path expression.  However, you can use any expression type you wish so
-      long as it returns a macro.  For example::
-
-        <p metal:use-macro="python:context.getMacro()">
-          Replaced with a dynamically determined macro,
-          which is located by the getMacro script.
-        </p>
-
-      In this case the path expression returns a macro defined dynamically by
-      the 'getMacro' script.  Using *Python expressions* to locate macros lets
-      you dynamically vary which macro your template uses.  An example
-      of the body of a "getMacro" Python script is as follows::
-
-        return container.ptMacros.macros['amacroname']
-
-      You can use the 'default' variable with the 'metal:use-macro'
-      statement::
-
-        <p metal:use-macro="default">
-          This content remains - no macro is used
-        </p>
-
-      The result is the same as using *default* with 'tal:content' and
-      'tal:replace'.  The "default" content in the tag doesn't change when it
-      is rendered.  This can be handy if you need to conditionally use a macro
-      or fall back on the default content if it doesn't exist.
-
-      If you try to use the 'nothing' variable with 'metal:use-macro' you will
-      get an error, since 'nothing' is not a macro.  If you want to use
-      'nothing' to conditionally include a macro, you should instead enclose
-      the 'metal:use-macro' statement with a 'tal:condition' statement.
-
-      Zope handles macros first when rendering your templates.  Then Zope
-      evaluates TAL expressions.  For example, consider this macro::
-
-        <p metal:define-macro="title"
-           tal:content="template/title">
-          template's title
-        </p>
-
-      When you use this macro it will insert the title of the template in
-      which the macro is used, *not* the title of the template in which the
-      macro is defined.  In other words, when you use a macro, it's like
-      copying the text of a macro into your template and then rendering your
-      template.
-
-      If you check the *Expand macros when editing* option on the *Page
-      Template* *Edit* view, then any macros that you use will be expanded in
-      your template's source.  When you're editing in the ZMI, rather than
-      using a WYSIWYG editing tool, it's more convenient not to expand macros
-      when editing.  This is the default for newly created templates.  When
-      using WYSIWYG tools, however, it is often desirable to have the macros
-      expanded so you are editing a complete page.  In this case, check the
-      *Expand macros...* checkbox before editing the page.
-
-    Using Slots
-
-      Macros are much more useful if you can override parts of them when you
-      use them.  You can do this by defining *slots* in the macro that you can
-      fill in when you use the template.  For example, consider a side bar
-      macro::
-
-        <div metal:define-macro="sidebar">
-          Links
-          <ul>
-            <li><a href="/">Home</a></li>
-            <li><a href="/products">Products</a></li>
-            <li><a href="/support">Support</a></li>
-            <li><a href="/contact">Contact Us</a></li>
-          </ul>
-        </div>
-
-      This macro is fine, but suppose you'd like to include some additional
-      information in the sidebar on some pages.  One way to accomplish this is
-      with slots::
-
-        <div metal:define-macro="sidebar">
-          Links
-          <ul>
-            <li><a href="/">Home</a></li>
-            <li><a href="/products">Products</a></li>
-            <li><a href="/support">Support</a></li>
-            <li><a href="/contact">Contact Us</a></li>
-          </ul>
-          <span metal:define-slot="additional_info"></span>
-        </div>
-
-      When you use this macro you can choose to fill the slot like so::
-
-        <p metal:use-macro="container/master.html/macros/sidebar">
-          <b metal:fill-slot="additional_info">
-            Make sure to check out our <a href="/specials">specials</a>.
-          </b>
-        </p>
-
-      When you render this template the side bar will include the extra
-      information that you provided in the slot::
-
-        <div>
-          Links
-          <ul>
-            <li><a href="/">Home</a></li>
-            <li><a href="/products">Products</a></li>
-            <li><a href="/support">Support</a></li>
-            <li><a href="/contact">Contact Us</a></li>
-          </ul>
-          <b>
-            Make sure to check out our <a href="/specials">specials</a>.
-          </b>
-        </div>
-
-      Notice how the 'span' element that defines the slot is replaced with the
-      'b' element that fills the slot.
-
-    Customizing Default Presentation
-
-      A common use of slot is to provide default presentation which you can
-      customize.  In the slot example in the last section, the slot definition
-      was just an empty 'span' element.  However, you can provide default
-      presentation in a slot definition.  For example, consider this revised
-      sidebar macro::
-
-        <div metal:define-macro="sidebar">
-          <div metal:define-slot="links">
-          Links
-          <ul>
-            <li><a href="/">Home</a></li>
-            <li><a href="/products">Products</a></li>
-            <li><a href="/support">Support</a></li>
-            <li><a href="/contact">Contact Us</a></li>
-          </ul>
-          </div>
-          <span metal:define-slot="additional_info"></span>
-        </div>
-
-      Now the sidebar is fully customizable.  You can fill the 'links' slot to
-      redefine the sidebar links.  However, if you choose not to fill the
-      'links' slot then you'll get the default links, which appear inside the
-      slot.
-
-      You can even take this technique further by defining slots inside of
-      slots.  This allows you to override default presentation with a fine
-      degree of precision.  Here's a sidebar macro that defines slots within
-      slots::
-
-        <div metal:define-macro="sidebar">
-          <div metal:define-slot="links">
-          Links
-          <ul>
-            <li><a href="/">Home</a></li>
-            <li><a href="/products">Products</a></li>
-            <li><a href="/support">Support</a></li>
-            <li><a href="/contact">Contact Us</a></li>
-            <span metal:define-slot="additional_links"></span>
-          </ul>
-          </div>
-          <span metal:define-slot="additional_info"></span>
-        </div>
-
-      If you wish to customize the sidebar links you can either fill the
-      'links' slot to completely override the links, or you can fill the
-      'additional_links' slot to insert some extra links after the default
-      links.  You can nest slots as deeply as you wish.
-
-    Combining METAL and TAL
-
-      You can use both *METAL* and *TAL* statements on the same elements.  For
-      example::
-
-        <ul metal:define-macro="links"
-            tal:repeat="link context/getLinks">
-          <li>
-            <a href="link url"
-               tal:attributes="href link/url"
-               tal:content="link/name">link name</a>
-          </li>
-        </ul>
-
-      In this case, 'getLinks' is an (imaginary) Script that assembles a list
-      of link objects, possibly using a Catalog query.
-
-      Since METAL statements are evaluated before *TAL* statements, there are
-      no conflicts.  This example is also interesting since it customizes a
-      macro without using slots.  The macro calls the 'getLinks' Script to
-      determine the links.  You can thus customize your site's links by
-      redefining the 'getLinks' Script at different locations within your
-      site.
-
-      It's not always easy to figure out the best way to customize look and
-      feel in different parts of your site.  In general you should use slots
-      to override presentation elements, and you should use Scripts to provide
-      content dynamically.  In the case of the links example, it's arguable
-      whether links are content or presentation.  Scripts probably provide a
-      more flexible solution, especially if your site includes link content
-      objects.
-
-    Whole Page Macros
-
-      Rather than using macros for chunks of presentation shared between
-      pages, you can use macros to define entire pages.  Slots make this
-      possible.  Here's an example macro that defines an entire page::
-
-        <html metal:define-macro="page">
-          <head>
-            <title tal:content="context/title">The title</title>
-          </head>
-
-          <body>
-            <h1 metal:define-slot="headline"
-                tal:content="context/title">title</h1>
-
-            <p metal:define-slot="body">
-              This is the body.
-            </p>
-
-            <span metal:define-slot="footer">
-              <p>Copyright 2001 Fluffy Enterprises</p>
-            </span>
-
-          </body>
-        </html>
-
-      This macro defines a page with three slots, 'headline', 'body', and
-      'footer'.  Notice how the 'headline' slot includes a *TAL* statement to
-      dynamically determine the headline content.
-
-      You can then use this macro in templates for different types of content,
-      or different parts of your site.  For example here's how a template for
-      news items might use this macro::
-
-        <html metal:use-macro="container/master.html/macros/page">
-
-          <h1 metal:fill-slot="headline">
-            Press Release:
-            <span tal:replace="context/getHeadline">Headline</span>
-          </h1>
-
-          <p metal:fill-slot="body"
-             tal:content="context/getBody">
-            News item body goes here
-          </p>
-
-        </html>
-
-      This template redefines the 'headline' slot to include the words "Press
-      Release" and call the 'getHeadline' method on the current object.  It
-      also redefines the 'body' slot to call the 'getBody' method on the
-      current object.
-
-      The powerful thing about this approach is that you can now change the
-      'page' macro and the press release template will be automatically
-      updated.  For example you could put the body of the page in a table and
-      add a sidebar on the left and the press release template would
-      automatically use these new presentation elements.
-
-      This is a much more flexible solution to control page look and feel then
-      the DTML 'standard_html_header' and 'standard_html_footer' solution.  In
-      fact, Zope comes with a stock page template in the root folder named
-      'standard_template.pt' that includes a whole page macro with a 'head'
-      and 'body' slot.  Here's how you might use this macro in a template::
-
-        <html metal:use-macro="context/standard_template.pt/macros/page">
-          <div metal:fill-slot="body">
-            <h1 tal:content="context/title">Title</h1>
-            <p tal:content="context/getBody">Body text goes here</p>
-          </div>
-        </html>
-
-      Using the 'standard_template.pt' macro is very similar to using other
-      whole page macros.  The only subtlety worth pointing out is the path
-      used to locate the macro.  In this example the path begins with
-      'context'.  This means that Zope will search for the
-      'standard_template.pt' object using acquisition starting at the object
-      that the template is applied to.  This allows you to customize the look
-      and feel of templates by creating custom 'standard_template.pt' objects
-      in various locations.  You can choose to start the path to the macro
-      with *root* or with *container*, as well as with *context*.  If the path
-      begins with *root* then you will always get the standard template which
-      is located in the root folder.  If the path begins with *container* then
-      Zope will search for a standard template using acquisition starting in
-      the folder where the template is defined.  This allows you to customize
-      look and feel of templates, but does not allow you to customize the look
-      and feel of different objects based on their location in the site.
-
-  Using Templates with Content
-
-    In general Zope supports content, presentation and logic components.
-    *Page Templates* are presentation components and they can be used to
-    display content components.
-
-    Zope ships with several content components: ZSQL Methods, Files, and
-    Images.  DTML Documents and methods are not really pure content components
-    since they can hold content and execute DTML code.  You can use Files for
-    textual content since you can edit the contents of Files if the file is
-    less than 64K and contains text.  However, the File object is fairly basic
-    and may not provide all of the features or metadata that you need.
-
-    Zope's "Content Management Framework":http://cmf.zope.org (CMF) solves
-    this problem by providing an assortment of rich content components.  The
-    CMF is Zope's content management add on.  It introduces all kinds of
-    enhancements including workflow, skins and content objects.  The CMF makes
-    a lot of use of *Page Templates*.  A later release of Zope will probably
-    include technologies "from and inspired
-    by":http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/FrontPage
-    the CMF.

Copied: zope2book/trunk/source/ZPT.rst (from rev 96419, zope2book/trunk/ZPT.stx)
===================================================================
--- zope2book/trunk/source/ZPT.rst	                        (rev 0)
+++ zope2book/trunk/source/ZPT.rst	2009-02-10 20:52:11 UTC (rev 96420)
@@ -0,0 +1,998 @@
+Using Zope Page Templates
+=========================
+
+*Page Templates* are a web page generation tool.  They help programmers and
+designers collaborate in producing dynamic web pages for Zope web
+applications.  Designers can use them to maintain pages without having to
+abandon their tools, while preserving the work required to embed those pages
+in an application.
+
+In this chapter, you'll learn the basic features of *Page Templates*,
+including how you can use them in your website to create dynamic web pages
+easily.  The next chapter walks you through a "hands on" example showing how
+to build a Zope web application using scripts and *Page Templates*.  In the
+chapter entitled `Advanced Page Templates <AdvZPT.html>`_, you'll learn about
+advanced *Page Template* features.
+
+The goal of *Page Templates* is to allow designers and programmers to work
+together easily.  A designer can use a WYSIWYG HTML editor to create a
+template, then a programmer can edit it to make it part of an application.
+If required, the designer can load the template *back* into his editor and
+make further changes to its structure and appearance.  By taking reasonable
+steps to preserve the changes made by the programmer, the designer will not
+disrupt the application.
+
+*Page Templates* aim at this goal by adopting three principles:
+
+1. Play nicely with editing tools.
+
+2. What you see is very similar to what you get.
+
+3. Keep code out of templates, except for structural logic.
+
+A Page Template is like a model of the pages that it will generate.  In
+particular, it is parseable by most HTML tools.
+
+Zope Page Templates versus DTML
+-------------------------------
+
+*Page Templates* use the *Template Attribute Language* (*TAL*), while
+*DTML Methods*, *DTML Documents* and *SQL Methods* use the *Document
+Template Markup Language* (*DTML*).  You may wonder why Zope needs two
+different template languages.
+
+First of all, there are historical reasons.  *Page Templates* are a
+relative new technology.  Zope 2.5 was the first release that shipped with
+*Page Templates*.  There are still many products and howtos that use
+*DTML* for tasks *Page Templates* are designed for.  And some people still
+prefer working with *DTML*.
+
+Secondly, *DTML* and *Page Templates* have different strengths and
+weaknesses.  *Page Templates* are aimed at HTML designers.  Once an HTML
+page has been "dynamicized" by inserting *DTML* into it, the resulting
+page typically becomes un-parseable for HTML tools, making it difficult to
+work with outside Zope.  *Page Templates* also enforce separation of
+presentation, logic and content (data).  This increases the scalability of
+content management and website development efforts that use these systems.
+And *Page Templates* give you better control over name lookups, while
+*DTML*'s namespace model adds too much "magic".
+
+But *DTML* has its strengths if we are dealing with something else than
+HTML/XML presentation, such as dynamically generated email messages and
+SQL queries.  So *DTML* is not a "dead end" and for some advanced tasks
+you might want to learn *DTML*, too.
+
+HTML Page Templates
+-------------------
+
+*Page Templates* can operate in two modes: *HTML Mode* and *XML Mode*.
+Later in this chapter we will show you how to use the *XML Mode*, but in
+most cases we want to use the *HTML Mode* which is also the default mode.
+For the *HTML Mode* the *Content-Type* has to be set to 'text/html'.
+
+HTML isn't XML-conform and can't be extended by a template language.  So
+while rendered HTML *Page Templates* should return valid HTML, their
+source code isn't valid HTML or XML.  But the *Template Attribute
+Language* (*TAL*) does a good job in hiding itself in HTML tags, so most
+HTML tools will be able to parse the source of HTML *Page Templates* and
+just ignore the *TAL* attributes.
+
+As you might already know, XHTML is a XML-conform reformulation of HTML
+and widely used in our days.  Nevertheless, generating HTML and XHTML
+with *Page Templates* works exactly the same way.  While the *HTML Mode*
+doesn't enforce well-formed XML, it's absolutely fine to use this mode
+also for XHTML.
+
+How Page Templates Work
+~~~~~~~~~~~~~~~~~~~~~~~
+
+*Page Templates* use the *Template Attribute Language* (*TAL*).  *TAL*
+consists of special tag attributes.  For example, a dynamic page
+headline might look like this::
+
+  <h1 tal:content="context/title">Sample Page Title</h1>
+
+The 'tal:content' attribute is a *TAL* statement.  Since it has an XML
+namespace (the 'tal:' part) most editing tools will not complain that
+they don't understand it, and will not remove it.  It will not change
+the structure or appearance of the template when loaded into a WYSIWYG
+editor or a web browser.  The name *content* indicates that it will set
+the text contained by the 'h1' tag, and the value 'context/title' is an
+expression providing the text to insert into the tag.  Given the text
+specified by 'context/title' resolves to "Susan Jones Home Page", the
+generated HTML snippet looks like this::
+
+  <h1>Susan Jones Home Page</h1>
+
+All *TAL* statements consist of tag attributes whose name starts with
+'tal:' and all *TAL* statements have values associated with them.  The
+value of a *TAL* statement is shown inside quotes.  See Appendix C,
+`Zope Page Templates Reference <AppendixC.html>`_, for more information
+on *TAL*.
+
+To the HTML designer using a WYSIWYG tool, the dynamic headline example
+is perfectly parseable HTML, and shows up in their editor looking like a
+headline should look like.  In other words, *Page Templates* play nicely
+with editing tools.
+
+This example also demonstrates the principle that "What you see is very
+similar to what you get".  When you view the template in an editor, the
+headline text will act as a placeholder for the dynamic headline text.
+The template provides an example of how generated documents will look.
+
+When this template is saved in Zope and viewed by a user, Zope turns the
+dummy content into dynamic content, replacing "Sample Page Title" with
+whatever 'context/title' resolves to.  In this case, 'context/title'
+resolves to the title of the object to which the template is applied.
+This substitution is done dynamically, when the template is viewed.
+
+There are template statements for replacing entire tags, their contents,
+or just some of their attributes.  You can repeat a tag several times or
+omit it entirely.  You can join parts of several templates together, and
+specify simple error handling.  All of these capabilities are used to
+generate document structures.  Despite these capabilities, you **can't**
+create subroutines or classes, perform complex flow control, or easily
+express complex algorithms using a *Page Template*.  For these tasks,
+you should use Python-based Scripts or application components.
+
+The *Page Template* language is deliberately not as powerful and
+general-purpose as it could be.  It is meant to be used inside of a
+framework (such as Zope) in which other objects handle business logic
+and tasks unrelated to page layout.
+
+For instance, template language would be useful for rendering an invoice
+page, generating one row for each line item, and inserting the
+description, quantity, price, and so on into the text for each row.  It
+would not be used to create the invoice record in a database or to
+interact with a credit card processing facility.
+
+Creating a Page Template
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you design pages, you will probably use FTP or WebDAV instead of the
+Zope Management Interface (ZMI) to edit *Page Templates*.  See "Remote
+Editing With FTP and WebDAV" in the `Advanced Page Templates`_ chapter for
+information on editing *Page Templates* remotely.  For the small
+examples in this chapter, it is easier to use the ZMI.
+
+Use your web browser to log into the Zope Management Interface as a
+manager.  Create a *Folder* to work in named 'template_test' in the root
+of your Zope.  Visit this folder and choose *Page Template* from Zope's
+add list (do *NOT* choose DTML Method or DTML Document, the following
+examples only work inside a Page Template).  Type 'simple_page' in the
+add form's *Id* field, then push the *Add and Edit* button.
+
+You should now see the main editing page for the new *Page Template*.
+The title is blank and the default template text is in the editing area.
+
+Now let's create a simple dynamic page.  Type the words 'a Simple Page'
+in the *Title* field.  Then, edit the template text to look like this::
+
+  <html>
+    <body>
+      <p>
+        This is <b tal:content="template/title">the Title</b>.
+      </p>
+    </body>
+  </html>
+
+Now push the *Save Changes* button.  Zope should show a message
+confirming that your changes have been saved.
+
+If you get an error message, check to make sure you typed the example
+correctly and save it again.  Using an external editor, an HTML comment
+starting with *Page Template Diagnostics* is added to the template text
+to show you something went wrong.  You don't need to erase the error
+comment; once the error is corrected it will go away.
+
+Click on the *Test* tab.  You should see a page with "This is **a Simple
+Page**." at the top.  Notice that the title is bold.  This is because
+the 'tal:content' statement just replaces the content of the *bold* tag.
+
+Back up, then click on the *Browse HTML source* link under the
+*Content-Type* field.  This will show you the *unrendered* source of the
+template.  You should see, "This is **the Title**." The bold text acts
+as a placeholder for the dynamic title text.  Back up again, so that you
+are ready to edit the example further.
+
+You can find two options on the *Edit* tab we will not touch for now:
+The *Content-Type* field allows you to specify the content type of
+your page.  Changing that value switches the *Page Template* into *XML
+Mode*, discussed later in this chapter.  The *Expand macros with
+editing* control is explained in the "Macros" section of this chapter.
+
+*TALES* Expressions
+~~~~~~~~~~~~~~~~~~~
+
+The expression "template/title" in your simple Page Template is a *path
+expression*.  This is the most common type of expression.  There are
+several other types of expressions defined by the *TAL Expression
+Syntax* (*TALES*) specification.  For more information on TALES see
+Appendix C, `Zope Page Templates Reference`_.
+
+Path Expressions
+%%%%%%%%%%%%%%%%
+
+The 'template/title' *path expression* fetches the *title* attribute
+of the template.  Here are some other common path expressions:
+
+- 'context/objectValues': A list of the sub-objects of the folder on
+  which the template is called.
+
+- 'request/URL': The URL of the current web request.
+
+- 'user/getUserName': The authenticated user's login name.
+
+From the last chapter you should already be familiar with the context
+variable that is also available in *Python-based Scripts* and the
+attribute 'objectValues' that specifies an API method.  The other two
+examples are just to show you the pattern.  You will learn more about
+them later in the book.
+
+To see what these examples return, just copy the following lines into
+a *Page Template* and select the *Test* tab.  You'll notice that
+'context/objectValues' returns a list that needs further treatment to
+be useful.  We'll come back to that later in this chapter::
+
+  <p tal:content="context/objectValues"></p>
+  <p tal:content="request/URL"></p>
+  <p tal:content="user/getUserName"></p>
+
+Every *path expression* starts with a variable name.  The available
+variable names refer either to objects like *context*, *request* or
+*user* that are bound to every *Page Template* by default or variables
+defined within the *Page Template* using TAL.  Note that *here* is an
+old alias of *context* and still used in many places.
+
+The small set of built-in variables such as *request* and *user* is
+described in the chapter entitled `Advanced Page Templates`_.
+You will also learn how to define your own variables in that chapter.
+
+If the variable itself returns the value you want, you are done.
+Otherwise, you add a slash ('/') and the name of a sub-object or
+attribute.  You may need to work your way through several
+sub-objects to get to the value you're looking for.
+
+Python Expressions
+%%%%%%%%%%%%%%%%%%
+
+A good rule of thumb is that if you need Python to express your logic,
+you better factor out the code into a script.  But Zope is a good tool
+for prototyping and sometimes it would be overkill to write a script
+for one line of code.  And looking at existing products you will see
+quite often 'Python expressions', so it's better to know them.
+
+Recall the first example of this chapter::
+
+  <h1 tal:content="context/title">Sample Page Title</h1>
+
+Let's try to rewrite it using a *Python expression*::
+
+  <h1 tal:content="python: context.getProperty('title')">Sample Page
+   Title</h1>
+
+While *path expressions* are the default, we need a prefix to indicate
+other expression types.  This expression with the prefix 'python:'
+does (at least here) the same as the *path expression* above, but we
+have to know that 'title' is a property of the context object and how
+to access properties.  *Path expressions* try different ways to access
+'title', so in general they are more flexible, but less explicit.
+
+There are some simple things you can't do with *path expressions*.
+The most common are comparing values like in::
+
+  "python: variable1 == variable2"
+
+... or passing arguments to methods, e.g.::
+
+  "python: context.objectValues(['Folder'])"
+
+*TAL* Attributes
+~~~~~~~~~~~~~~~~
+
+*Page Templates* are example pages or snippets.  *TAL* statements define
+how to convert them dynamically.  Depending on the used *TAL* attribute
+they substitute example content or attributes by dynamic values, or
+remove or repeat example elements depending on dynamic values.
+
+Inserting Text
+%%%%%%%%%%%%%%
+
+  In your "simple_page" template, you used the 'tal:content' statement
+  on a *bold* tag.  When you tested it, Zope replaced the content of the
+  HTML *bold* element with the title of the template.
+
+  This is easy as long as we want to replace the complete content of an
+  HTML element.  But what if we want to replace only some words within
+  an element?
+
+  In order to place dynamic text inside of other text, you typically use
+  'tal:replace' on an additional 'span' tag.  For example, add the
+  following lines to your example::
+
+    <p>The URL is
+      <span tal:replace="request/URL">
+        http://www.example.com</span>.</p>
+
+  The 'span' tag is structural, not visual, so this looks like "The URL
+  is http://www.example.com." when you view the source in an editor or
+  browser.  When you view the rendered version, however, it may look
+  something like::
+
+    The URL is http://localhost:8080/template_test/simple_page.
+
+  If you look at the source code of the rendered version, the *span*
+  tags are removed.
+
+  To see the difference between 'tal:replace' and 'tal:content', create
+  a page template and include the following in the body::
+
+    <b tal:content="template/title"></b>
+    <b tal:content="request/URL"></b>
+    <b tal:content="user/getUserName"></b>
+    <b tal:replace="template/title"></b>
+    <b tal:replace="request/URL"></b>
+    <b tal:replace="user/getUserName"></b>
+
+  There are two other ways to add elements that are only needed for
+  *TAL* attributes and that are removed again in the rendered version::
+
+    <p>The URL is
+      <span tal:content="request/URL" tal:omit-tag="">
+        http://www.example.com</span>.</p>
+
+  ... which is more useful in other situations and will be discussed
+  there and::
+
+    <p>The URL is
+      <tal:span tal:content="request/URL">
+        http://www.example.com</tal:span>.</p>
+
+  While you can get really far by using HTML elements and 'tal:replace'
+  or 'tal:omit-tag', some people prefer to use *TAL* elements if the
+  elements are only used to add *TAL* attributes.  *TAL* is an attribute
+  language and doesn't define any elements like 'tal:span', but it uses
+  a complete XML namespace and allows to use any element name you like.
+  They are silently removed while the *Page Template* is rendered.
+
+  This is useful for using speaking names like 'tal:loop', 'tal:case' or
+  'tal:span' and to insert additional elements where HTML doesn't allow
+  elements like 'span' or 'div'.  And if her browser or editor also
+  ignores these tags, the designer will have less trouble with *TAL*
+  elements than with additional HTML elements.
+
+Repeating Structures
+%%%%%%%%%%%%%%%%%%%%
+
+Let's start with a simple three-liner::
+
+  <p tal:repeat="number python: range(4)" tal:content="number">
+    999
+  </p>
+
+'number' is our *repeat variable* and 'range(4)' is a *Python
+expression* that returns the list '[0, 1, 2, 3]'.  If this code is
+rendered, the 'repeat' statement repeats the *paragraph* element for
+each value of the sequence, replacing the variable 'number' by the
+current sequence value.  So the rendered page will not show the
+example number '999', but 4 *paragraph* elements containing the
+numbers of our list.
+
+In most cases we want to iterate over more complex sequences.  Our
+next example shows how to use a sequence of (references to) objects.
+The 'simple_page' template could be improved by adding an item list,
+in the form of a list of the objects that are in the same *Folder* as
+the template.  You will make a table that has a row for each object,
+and columns for the id, meta-type and title.  Add these lines to the
+bottom of your example template::
+
+  <table border="1" width="100%">
+    <tr>
+      <th>Id</th>
+      <th>Meta-Type</th>
+      <th>Title</th>
+    </tr>
+    <tr tal:repeat="item context/objectValues">
+      <td tal:content="item/getId">Id</td>
+      <td tal:content="item/meta_type">Meta-Type</td>
+      <td tal:content="item/title">Title</td>
+    </tr>
+  </table>
+
+The 'tal:repeat' statement on the table row means "repeat this row for
+each item in my context's list of object values".  The *repeat*
+statement puts the objects from the list into the *item* variable one
+at a time (this is called the *repeat variable*), and makes a copy of
+the row using that variable.  The value of 'item/getId' in each row is
+the Id of the object for that row, and likewise with 'item/meta_type'
+and 'item/title'.
+
+You can use any name you like for the repeat variable ("item" is only
+an example), as long as it starts with a letter and contains only
+letters, numbers, and underscores ('_').  The repeat variable is only
+defined in the repeat tag.  If you try to use it above or below the
+*tr* tag you will get an error.
+
+You can also use the repeat variable name to get information about the
+current repetition.  See `Advanced Page Templates`_.
+
+Now view the page and notice how it lists all the objects in the same
+folder as the template.  Try adding or deleting objects from the
+folder and notice how the page reflects these changes.
+
+Conditional Elements
+%%%%%%%%%%%%%%%%%%%%
+
+Using Page Templates you can dynamically query your environment and
+selectively insert text depending on conditions.  For example, you
+could display special information in response to a cookie::
+
+  <p tal:condition="request/cookies/verbose | nothing">
+    Here's the extra information you requested.
+  </p>
+
+This paragraph will be included in the output only if there is a
+'verbose' cookie set.  The expression, 'request/cookies/verbose |
+nothing' is true only when there is a cookie named 'verbose' set.
+You'll learn more about this kind of expression in the chapter
+entitled `Advanced Page Templates`_.
+
+Using the 'tal:condition' statement you can check all kinds of
+conditions.  A 'tal:condition' statement leaves the tag and its
+contents in place if its expression has a true value, but removes them
+if the value is false.  Zope considers the number zero, a  blank
+string, an empty list, and the built-in variable 'nothing' to be false
+values.  Nearly every other value is true, including non-zero numbers,
+and strings with anything in them (even spaces!).
+
+Another common use of conditions is to test a sequence to see if it is
+empty before looping over it.  For example in the last section you saw
+how to draw a table by iterating over a collection of objects.  Here's
+how to add a check to the page so that if the list of objects is empty
+no table is drawn.
+
+To allow you to see the effect, we first have to modify that example
+a bit, showing only *Folder* objects in the context folder.  Because
+we can't specify parameters using *path expressions* like
+'context/objectValues', we first convert it into the *Python
+expression* 'context.objectValues()' and then add the argument that
+tells the 'objectValues' method to return only sub-folders::
+
+  <tr tal:repeat="item python: context.objectValues(['Folder'])">
+
+If you did not add any sub-folders to the *template_test* folder so
+far, you will notice that using the *Test* tab the table header is
+still shown even if we have no table body.  To avoid this we add a
+'tal:condition' statement in the table tag.  The complete table now
+looks like this::
+
+  <table tal:condition="python: context.objectValues(['Folder'])"
+         border="1" width="100%">
+    <tr>
+      <th>Id</th>
+      <th>Meta-Type</th>
+      <th>Title</th>
+    </tr>
+    <tr tal:repeat="item python: context.objectValues(['Folder'])">
+      <td tal:content="item/getId">Id</td>
+      <td tal:content="item/meta_type">Meta-Type</td>
+      <td tal:content="item/title">Title</td>
+    </tr>
+  </table>
+
+If the list of sub-folders is an empty list, the condition is false
+and the entire table is omitted.  You can verify this by using the
+*Test* tab again.
+
+Go and add three Folders named '1', '2', and '3' to the
+*template_test* folder in which your *simple_page* template lives.
+Revisit the *simple_page* template and view the rendered output via
+the *Test* tab.  You will see a table that looks much like the below::
+
+  Id          Meta-Type          Title
+  1           Folder
+  2           Folder
+  3           Folder
+
+Changing Attributes
+%%%%%%%%%%%%%%%%%%%
+
+Most, if not all, of the objects listed by your template have an
+*icon* attribute that contains the path to the icon for that kind of
+object.  In order to show this icon in the meta-type column, you will
+need to insert this path into the 'src' attribute of an 'img' tag.
+Edit the table cell in the meta-type column of the above example to
+look like this::
+
+  <td><img src="/misc_/OFSP/File_icon.gif"
+           tal:attributes="src item/icon" />
+    <span tal:replace="item/meta_type">Meta-Type</span></td>
+
+The 'tal:attributes' statement replaces the 'src' attribute of the
+'img' tag with the value of 'item/icon'.  The 'src` attribute in the
+template (whose value is "/misc\_/OFSP/File_icon.gif") acts as a placeholder.
+
+Notice that we've replaced the 'tal:content' attribute on the table
+cell with a 'tal:replace' statement on a 'span' tag.  This change
+allows you to have both an image and text in the table cell.
+
+XML Page Templates
+------------------
+
+Creating XML with *Page Templates* is almost exactly like creating HTML.
+You switch to *XML Mode* by setting the *content-type* field to
+'text/xml' or whatever the content-type for your XML should be.
+
+In *XML Mode* no "loose" markup is allowed.  Zope assumes that your
+template is well-formed XML.  Zope also requires an explicit TAL and METAL
+XML namespace declarations in order to emit XML.  For example, if you wish
+to emit XHTML, you might put your namespace declarations on the 'html'
+tag::
+
+  <html xmlns:tal="http://xml.zope.org/namespaces/tal"
+    xmlns:metal="http://xml.zope.org/namespaces/metal">
+
+To browse the source of an XML template you go to 'source.xml' rather than
+'source.html'.
+
+Debugging and Testing
+
+Zope helps you find and correct problems in your *Page Templates*.  Zope
+notices problems at two different times: when you're editing a *Page
+Template*, and when you're viewing a *Page Template*.  Zope catches
+different types of problems when you're editing and than when you're
+viewing a *Page Template*.
+
+You may have already seen the trouble-shooting comments that Zope inserts
+into your Page Templates when it runs into problems.  These comments tell
+you about problems that Zope finds while you're editing your templates.
+The sorts of problems that Zope finds when you're editing are mostly
+errors in your *TAL* statements.  For example::
+
+  <!-- Page Template Diagnostics
+   Compilation failed
+   TAL.TALDefs.TALError: bad TAL attribute: 'contents', at line 10, column 1
+  -->
+
+This diagnostic message lets you know that you mistakenly used
+'tal:contents' rather than 'tal:content' on line 10 of your template.
+Other diagnostic messages will tell you about problems with your template
+expressions and macros.
+
+When you're using the Zope management interface to edit *Page Templates*
+it's easy to spot these diagnostic messages, because they are shown in the
+"Errors" header of the management interface page when you save the *Page
+Template*.  However, if you're using WebDAV or FTP it's easy to miss these
+messages.  For example, if you save a template to Zope with FTP, you won't
+get an FTP error telling you about the problem.  In fact, you'll have to
+reload the template from Zope to see the diagnostic message.  When using
+FTP and WebDAV it's a good idea to reload templates after you edit them to
+make sure that they don't contain diagnostic messages.
+
+If you don't notice the diagnostic message and try to render a template
+with problems you'll see a message like this::
+
+  Error Type: PTRuntimeError
+  Error Value: Page Template hello.html has errors.
+
+That's your signal to reload the template and check out the diagnostic
+message.
+
+In addition to diagnostic messages when editing, you'll occasionally get
+regular Zope errors when viewing a Page Template.  These problems are
+usually due to problems in your template expressions.  For example, you
+might get an error if an expression can't locate a variable::
+
+  Error Type: KeyError
+  Error Value: 'unicorn'
+
+This error message tells you that it cannot find the *unicorn* variable.
+To help you figure out what went wrong, Zope includes information about
+the environment in the traceback.  This information will be available in
+your *error_log* (in your Zope root folder).  The traceback will include
+information about the place where the error occurred and the environment::
+
+  URL: /sandbox/demo
+  Line 1, Column 14
+  Expression: standard:'context/unicorn'
+  Names:
+    {'container': <Folder instance at 019AC4D0>,
+     'context': <Application instance at 01736F78>,
+     'default': <Products.PageTemplates.TALES.Default instance at 0x012F9D00>,
+     ...
+     'root': <Application instance at 01736F78>,
+     'template': <ZopePageTemplate at /sandbox/demo>,
+     'traverse_subpath': [],
+     'user': admin}
+
+This information is a bit cryptic, but with a little detective work it can
+help you figure out what went wrong.  In this case, it tells us that the
+'context' variable is an "Application instance".  This means that it is
+the top-level Zope folder (notice how 'root' variable is the same
+"Application instance").  Perhaps the problem is that you wanted to apply
+the template to a folder that had a *unicorn* property, but the root on
+which you called the template hasn't such a property.
+
+Macros
+------
+
+So far, you've seen how *Page Templates* can be used to add dynamic
+behavior to individual web pages.  Another feature of page templates is
+the ability to reuse look and feel elements across many pages.
+
+For example, with *Page Templates*, you can have a site that has a
+standard look and feel.  No matter what the "content" of a page, it will
+have a standard header, side-bar, footer, and/or other page elements.
+This is a very common requirement for websites.
+
+You can reuse presentation elements across pages with *macros*.  Macros
+define a section of a page that can be reused in other pages.  A macro can
+be an entire page, or just a chunk of a page such as a header or footer.
+After you define one or more macros in one *Page Template*, you can use
+them in other *Page Templates*.
+
+Using Macros
+~~~~~~~~~~~~
+
+You can define macros with tag attributes similar to *TAL* statements.
+Macro tag attributes are called *Macro Expansion Tag Attribute Language*
+(*METAL*) statements.  Here's an example macro definition::
+
+  <p metal:define-macro="copyright">
+    Copyright 2001, <em>Foo, Bar, and Associates</em> Inc.
+  </p>
+
+This 'metal:define-macro' statement defines a macro named "copyright".
+The macro consists of the 'p' element (including all contained elements,
+ending with the closing 'p' tag).
+
+Macros defined in a Page Template are stored in the template's *macros*
+attribute.  You can use macros from other *Page Templates* by referring
+to them through the *macros* attribute of the *Page Template* in which
+they are defined.  For example, suppose the *copyright* macro is in a
+*Page Template* called "master_page".  Here's how to use the *copyright*
+macro from another *Page Template*::
+
+  <hr />
+  <b metal:use-macro="container/master_page/macros/copyright">
+    Macro goes here
+  </b>
+
+In this *Page Template*, the 'b' element will be completely replaced by
+the macro when Zope renders the page::
+
+  <hr />
+  <p>
+    Copyright 2001, <em>Foo, Bar, and Associates</em> Inc.
+  </p>
+
+If you change the macro (for example, if the copyright holder changes)
+then all *Page Templates* that use the macro will automatically reflect
+the change.
+
+Notice how the macro is identified by a *path expression* using the
+'metal:use-macro' statement.  The 'metal:use-macro' statement replaces
+the statement element with the named macro.
+
+Macro Details
+~~~~~~~~~~~~~
+
+The 'metal:define-macro' and 'metal:use-macro' statements are pretty
+simple.  However there are a few subtleties to using them which are
+worth mentioning.
+
+A macro's name must be unique within the Page Template in which it is
+defined.  You can define more than one macro in a template, but they all
+need to have different names.
+
+Normally you'll refer to a macro in a 'metal:use-macro' statement with a
+path expression.  However, you can use any expression type you wish so
+long as it returns a macro.  For example::
+
+  <p metal:use-macro="python:context.getMacro()">
+    Replaced with a dynamically determined macro,
+    which is located by the getMacro script.
+  </p>
+
+In this case the path expression returns a macro defined dynamically by
+the 'getMacro' script.  Using *Python expressions* to locate macros lets
+you dynamically vary which macro your template uses.  An example
+of the body of a "getMacro" Python script is as follows::
+
+  return container.ptMacros.macros['amacroname']
+
+You can use the 'default' variable with the 'metal:use-macro'
+statement::
+
+  <p metal:use-macro="default">
+    This content remains - no macro is used
+  </p>
+
+The result is the same as using *default* with 'tal:content' and
+'tal:replace'.  The "default" content in the tag doesn't change when it
+is rendered.  This can be handy if you need to conditionally use a macro
+or fall back on the default content if it doesn't exist.
+
+If you try to use the 'nothing' variable with 'metal:use-macro' you will
+get an error, since 'nothing' is not a macro.  If you want to use
+'nothing' to conditionally include a macro, you should instead enclose
+the 'metal:use-macro' statement with a 'tal:condition' statement.
+
+Zope handles macros first when rendering your templates.  Then Zope
+evaluates TAL expressions.  For example, consider this macro::
+
+  <p metal:define-macro="title"
+     tal:content="template/title">
+    template's title
+  </p>
+
+When you use this macro it will insert the title of the template in
+which the macro is used, *not* the title of the template in which the
+macro is defined.  In other words, when you use a macro, it's like
+copying the text of a macro into your template and then rendering your
+template.
+
+If you check the *Expand macros when editing* option on the *Page
+Template* *Edit* view, then any macros that you use will be expanded in
+your template's source.  When you're editing in the ZMI, rather than
+using a WYSIWYG editing tool, it's more convenient not to expand macros
+when editing.  This is the default for newly created templates.  When
+using WYSIWYG tools, however, it is often desirable to have the macros
+expanded so you are editing a complete page.  In this case, check the
+*Expand macros...* checkbox before editing the page.
+
+Using Slots
+~~~~~~~~~~~
+
+Macros are much more useful if you can override parts of them when you
+use them.  You can do this by defining *slots* in the macro that you can
+fill in when you use the template.  For example, consider a side bar
+macro::
+
+  <div metal:define-macro="sidebar">
+    Links
+    <ul>
+      <li><a href="/">Home</a></li>
+      <li><a href="/products">Products</a></li>
+      <li><a href="/support">Support</a></li>
+      <li><a href="/contact">Contact Us</a></li>
+    </ul>
+  </div>
+
+This macro is fine, but suppose you'd like to include some additional
+information in the sidebar on some pages.  One way to accomplish this is
+with slots::
+
+  <div metal:define-macro="sidebar">
+    Links
+    <ul>
+      <li><a href="/">Home</a></li>
+      <li><a href="/products">Products</a></li>
+      <li><a href="/support">Support</a></li>
+      <li><a href="/contact">Contact Us</a></li>
+    </ul>
+    <span metal:define-slot="additional_info"></span>
+  </div>
+
+When you use this macro you can choose to fill the slot like so::
+
+  <p metal:use-macro="container/master.html/macros/sidebar">
+    <b metal:fill-slot="additional_info">
+      Make sure to check out our <a href="/specials">specials</a>.
+    </b>
+  </p>
+
+When you render this template the side bar will include the extra
+information that you provided in the slot::
+
+  <div>
+    Links
+    <ul>
+      <li><a href="/">Home</a></li>
+      <li><a href="/products">Products</a></li>
+      <li><a href="/support">Support</a></li>
+      <li><a href="/contact">Contact Us</a></li>
+    </ul>
+    <b>
+      Make sure to check out our <a href="/specials">specials</a>.
+    </b>
+  </div>
+
+Notice how the 'span' element that defines the slot is replaced with the
+'b' element that fills the slot.
+
+Customizing Default Presentation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A common use of slot is to provide default presentation which you can
+customize.  In the slot example in the last section, the slot definition
+was just an empty 'span' element.  However, you can provide default
+presentation in a slot definition.  For example, consider this revised
+sidebar macro::
+
+  <div metal:define-macro="sidebar">
+    <div metal:define-slot="links">
+    Links
+    <ul>
+      <li><a href="/">Home</a></li>
+      <li><a href="/products">Products</a></li>
+      <li><a href="/support">Support</a></li>
+      <li><a href="/contact">Contact Us</a></li>
+    </ul>
+    </div>
+    <span metal:define-slot="additional_info"></span>
+  </div>
+
+Now the sidebar is fully customizable.  You can fill the 'links' slot to
+redefine the sidebar links.  However, if you choose not to fill the
+'links' slot then you'll get the default links, which appear inside the
+slot.
+
+You can even take this technique further by defining slots inside of
+slots.  This allows you to override default presentation with a fine
+degree of precision.  Here's a sidebar macro that defines slots within
+slots::
+
+  <div metal:define-macro="sidebar">
+    <div metal:define-slot="links">
+    Links
+    <ul>
+      <li><a href="/">Home</a></li>
+      <li><a href="/products">Products</a></li>
+      <li><a href="/support">Support</a></li>
+      <li><a href="/contact">Contact Us</a></li>
+      <span metal:define-slot="additional_links"></span>
+    </ul>
+    </div>
+    <span metal:define-slot="additional_info"></span>
+  </div>
+
+If you wish to customize the sidebar links you can either fill the
+'links' slot to completely override the links, or you can fill the
+'additional_links' slot to insert some extra links after the default
+links.  You can nest slots as deeply as you wish.
+
+Combining METAL and TAL
+~~~~~~~~~~~~~~~~~~~~~~~
+
+You can use both *METAL* and *TAL* statements on the same elements.  For
+example::
+
+  <ul metal:define-macro="links"
+      tal:repeat="link context/getLinks">
+    <li>
+      <a href="link url"
+         tal:attributes="href link/url"
+         tal:content="link/name">link name</a>
+    </li>
+  </ul>
+
+In this case, 'getLinks' is an (imaginary) Script that assembles a list
+of link objects, possibly using a Catalog query.
+
+Since METAL statements are evaluated before *TAL* statements, there are
+no conflicts.  This example is also interesting since it customizes a
+macro without using slots.  The macro calls the 'getLinks' Script to
+determine the links.  You can thus customize your site's links by
+redefining the 'getLinks' Script at different locations within your
+site.
+
+It's not always easy to figure out the best way to customize look and
+feel in different parts of your site.  In general you should use slots
+to override presentation elements, and you should use Scripts to provide
+content dynamically.  In the case of the links example, it's arguable
+whether links are content or presentation.  Scripts probably provide a
+more flexible solution, especially if your site includes link content
+objects.
+
+Whole Page Macros
+~~~~~~~~~~~~~~~~~
+
+Rather than using macros for chunks of presentation shared between
+pages, you can use macros to define entire pages.  Slots make this
+possible.  Here's an example macro that defines an entire page::
+
+  <html metal:define-macro="page">
+    <head>
+      <title tal:content="context/title">The title</title>
+    </head>
+
+    <body>
+      <h1 metal:define-slot="headline"
+          tal:content="context/title">title</h1>
+
+      <p metal:define-slot="body">
+        This is the body.
+      </p>
+
+      <span metal:define-slot="footer">
+        <p>Copyright 2001 Fluffy Enterprises</p>
+      </span>
+
+    </body>
+  </html>
+
+This macro defines a page with three slots, 'headline', 'body', and
+'footer'.  Notice how the 'headline' slot includes a *TAL* statement to
+dynamically determine the headline content.
+
+You can then use this macro in templates for different types of content,
+or different parts of your site.  For example here's how a template for
+news items might use this macro::
+
+  <html metal:use-macro="container/master.html/macros/page">
+
+    <h1 metal:fill-slot="headline">
+      Press Release:
+      <span tal:replace="context/getHeadline">Headline</span>
+    </h1>
+
+    <p metal:fill-slot="body"
+       tal:content="context/getBody">
+      News item body goes here
+    </p>
+
+  </html>
+
+This template redefines the 'headline' slot to include the words "Press
+Release" and call the 'getHeadline' method on the current object.  It
+also redefines the 'body' slot to call the 'getBody' method on the
+current object.
+
+The powerful thing about this approach is that you can now change the
+'page' macro and the press release template will be automatically
+updated.  For example you could put the body of the page in a table and
+add a sidebar on the left and the press release template would
+automatically use these new presentation elements.
+
+This is a much more flexible solution to control page look and feel then
+the DTML 'standard_html_header' and 'standard_html_footer' solution.  In
+fact, Zope comes with a stock page template in the root folder named
+'standard_template.pt' that includes a whole page macro with a 'head'
+and 'body' slot.  Here's how you might use this macro in a template::
+
+  <html metal:use-macro="context/standard_template.pt/macros/page">
+    <div metal:fill-slot="body">
+      <h1 tal:content="context/title">Title</h1>
+      <p tal:content="context/getBody">Body text goes here</p>
+    </div>
+  </html>
+
+Using the 'standard_template.pt' macro is very similar to using other
+whole page macros.  The only subtlety worth pointing out is the path
+used to locate the macro.  In this example the path begins with
+'context'.  This means that Zope will search for the
+'standard_template.pt' object using acquisition starting at the object
+that the template is applied to.  This allows you to customize the look
+and feel of templates by creating custom 'standard_template.pt' objects
+in various locations.  You can choose to start the path to the macro
+with *root* or with *container*, as well as with *context*.  If the path
+begins with *root* then you will always get the standard template which
+is located in the root folder.  If the path begins with *container* then
+Zope will search for a standard template using acquisition starting in
+the folder where the template is defined.  This allows you to customize
+look and feel of templates, but does not allow you to customize the look
+and feel of different objects based on their location in the site.
+
+Using Templates with Content
+============================
+
+In general Zope supports content, presentation and logic components.
+*Page Templates* are presentation components and they can be used to
+display content components.
+
+Zope ships with several content components: ZSQL Methods, Files, and
+Images.  DTML Documents and methods are not really pure content components
+since they can hold content and execute DTML code.  You can use Files for
+textual content since you can edit the contents of Files if the file is
+less than 64K and contains text.  However, the File object is fairly basic
+and may not provide all of the features or metadata that you need.
+
+Zope's `Content Management Framework <http://cmf.zope.org>`_ (CMF) solves
+this problem by providing an assortment of rich content components.  The
+CMF is Zope's content management add on.  It introduces all kinds of
+enhancements including workflow, skins and content objects.  The CMF makes
+a lot of use of *Page Templates*.  A later release of Zope will probably
+include technologies `from and inspired by
+<http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/FrontPage>`_
+the CMF.

Modified: zope2book/trunk/source/index.rst
===================================================================
--- zope2book/trunk/source/index.rst	2009-02-10 19:54:42 UTC (rev 96419)
+++ zope2book/trunk/source/index.rst	2009-02-10 20:52:11 UTC (rev 96420)
@@ -20,8 +20,9 @@
    BasicObject.rst
    Acquisition.rst
    DTML.rst
+   ZPT.rst
+   AppendixA.rst
    Contributions.rst
-   AppendixA.rst
 
 Indices and tables
 ------------------



More information about the Checkins mailing list