comparison doc/customizing.txt @ 1213:3a5e05edcd87

added doc for METAL
author Richard Jones <richard@users.sourceforge.net>
date Wed, 25 Sep 2002 06:20:09 +0000
parents e2b5f02cefe3
children 3ed25834f33c
comparison
equal deleted inserted replaced
1212:8372eec95841 1213:3a5e05edcd87
1 =================== 1 ===================
2 Customising Roundup 2 Customising Roundup
3 =================== 3 ===================
4 4
5 :Version: $Revision: 1.43 $ 5 :Version: $Revision: 1.44 $
6 6
7 .. This document borrows from the ZopeBook section on ZPT. The original is at: 7 .. This document borrows from the ZopeBook section on ZPT. The original is at:
8 http://www.zope.org/Documentation/Books/ZopeBook/current/ZPT.stx 8 http://www.zope.org/Documentation/Books/ZopeBook/current/ZPT.stx
9 9
10 .. contents:: 10 .. contents::
471 The basic processing of a web request proceeds as follows: 471 The basic processing of a web request proceeds as follows:
472 472
473 1. figure out who we are, defaulting to the "anonymous" user 473 1. figure out who we are, defaulting to the "anonymous" user
474 2. figure out what the request is for - we call this the "context" 474 2. figure out what the request is for - we call this the "context"
475 3. handle any requested action (item edit, search, ...) 475 3. handle any requested action (item edit, search, ...)
476 4. render a template, resulting in HTML output 476 4. render the template requested by the context, resulting in HTML output
477 477
478 In some situations, exceptions occur: 478 In some situations, exceptions occur:
479 479
480 - HTTP Redirect (generally raised by an action) 480 - HTTP Redirect (generally raised by an action)
481 - SendFile (generally raised by determine_context) 481 - SendFile (generally raised by determine_context)
630 630
631 Most customisation of the web view can be done by modifying the templates in 631 Most customisation of the web view can be done by modifying the templates in
632 the tracker **html** directory. There are several types of files in there: 632 the tracker **html** directory. There are several types of files in there:
633 633
634 **page** 634 **page**
635 This template defines the overall look of your tracker. When you 635 This template usually defines the overall look of your tracker. When you
636 view an issue, it appears inside this template. When you view an index, it 636 view an issue, it appears inside this template. When you view an index, it
637 also appears inside this template. It will have a ``tal:content`` or 637 also appears inside this template. This template defines a macro which is
638 ``tal:replace`` command with the expression ``structure content`` which 638 used by almost all other templates as a wrapper for their content, using its
639 will show the issue, list of issues or whatever. 639 "content" slot. It will also define the "head_title" and "body_title" slots
640 to allow setting of the page title.
640 **home** 641 **home**
641 the default page displayed when no other page is indicated by the user 642 the default page displayed when no other page is indicated by the user
642 **home.classlist** 643 **home.classlist**
643 a special version of the default page that lists the classes in the tracker 644 a special version of the default page that lists the classes in the tracker
644 **classname.item** 645 **classname.item**
668 669
669 How the templates work 670 How the templates work
670 ---------------------- 671 ----------------------
671 672
672 Roundup's templates consist of special attributes on your template tags. These 673 Roundup's templates consist of special attributes on your template tags. These
673 attributes form the Template Attribute Language, or TAL. The commands are: 674 attributes form the Template Attribute Language, or TAL. The basic tag
674 675 commands are:
675 676
676 **tal:define="variable expression; variable expression; ..."** 677 **tal:define="variable expression; variable expression; ..."**
677 Define a new variable that is local to this tag and its contents. For 678 Define a new variable that is local to this tag and its contents. For
678 example:: 679 example::
679 680
785 **Python Expressions** - eg. ``python: 1+1`` 786 **Python Expressions** - eg. ``python: 1+1``
786 These expressions give the full power of Python. All the "root level" 787 These expressions give the full power of Python. All the "root level"
787 variables are available, so ``python:item.status.checklist()`` would be 788 variables are available, so ``python:item.status.checklist()`` would be
788 equivalent to ``item/status/checklist``, assuming that ``checklist`` is 789 equivalent to ``item/status/checklist``, assuming that ``checklist`` is
789 a method. 790 a method.
791
792 Tag macros, which are used in forming the basic structure of your pages,
793 are handled with the following commands:
794
795 **metal:define-macro="macro name"**
796 Define that the tag and its contents are now a macro that may be inserted
797 into other templates using the *use-macro* command. For example::
798
799 <html metal:define-macro="page">
800 ...
801 </html>
802
803 defines a macro called "page" using the ``<html>`` tag and its contents.
804 Once defined, macros are stored on the template they're defined on in the
805 ``macros`` attribute. You can access them later on through the ``templates``
806 variable, eg. the most common ``templates/page/macros/page`` to access the
807 "page" macro of the "page" template.
808
809 **metal:use-macro="path expression"**
810 Use a macro, which is identified by the path expression (see above). This
811 will replace the current tag with the identified macro contents. For
812 example::
813
814 <tal:block metal:use-macro="templates/page/macros/page">
815 ...
816 </tal:block>
817
818 will replace the tag and its contents with the "page" macro of the "page"
819 template.
820
821 **metal:define-slot="slot name"** and **metal:fill-slot="slot name"**
822 To define *dynamic* parts of the macro, you define "slots" which may be
823 filled when the macro is used with a *use-macro* command. For example, the
824 ``templates/page/macros/page`` macro defines a slot like so::
825
826 <title metal:define-slot="head_title">title goes here</title>
827
828 In your *use-macro* command, you may now use a *fill-slot* command like
829 this::
830
831 <title metal:fill-slot="head_title">My Title</title>
832
833 where the tag that fills the slot completely replaces the one defined as
834 the slot in the macro.
835
790 836
791 Information available to templates 837 Information available to templates
792 ---------------------------------- 838 ----------------------------------
793 839
794 Note: this is implemented by roundup.cgi.templating.RoundupPageTemplate 840 Note: this is implemented by roundup.cgi.templating.RoundupPageTemplate
810 name to value 856 name to value
811 **tracker** 857 **tracker**
812 The current tracker 858 The current tracker
813 **db** 859 **db**
814 The current database, through which db.config may be reached. 860 The current database, through which db.config may be reached.
861 **templates**
862 Access to all the tracker templates by name. Used mainly in *use-macro*
863 commands.
864 **utils**
865 This variable makes available some utility functions like batching.
815 **nothing** 866 **nothing**
816 This is a special variable - if an expression evaluates to this, then the 867 This is a special variable - if an expression evaluates to this, then the
817 tag (in the case of a tal:replace), its contents (in the case of 868 tag (in the case of a tal:replace), its contents (in the case of
818 tal:content) or some attributes (in the case of tal:attributes) will not 869 tal:content) or some attributes (in the case of tal:attributes) will not
819 appear in the the output. So for example:: 870 appear in the the output. So for example::
832 <span tal:replace="default">Hello, World!</span> 883 <span tal:replace="default">Hello, World!</span>
833 884
834 would result in:: 885 would result in::
835 886
836 <span>Hello, World!</span> 887 <span>Hello, World!</span>
837
838 **utils**
839 This variable makes available some utility functions like batching.
840 888
841 The context variable 889 The context variable
842 ~~~~~~~~~~~~~~~~~~~~ 890 ~~~~~~~~~~~~~~~~~~~~
843 891
844 The *context* variable is one of three things based on the current context 892 The *context* variable is one of three things based on the current context
1076 db/user 1124 db/user
1077 python:db.user 1125 python:db.user
1078 1126
1079 The access results in a `hyperdb class wrapper`_. 1127 The access results in a `hyperdb class wrapper`_.
1080 1128
1081 1129 The templates variable
1082 The util variable 1130 ~~~~~~~~~~~~~~~~~~~~~~
1083 ~~~~~~~~~~~~~~~~~ 1131
1132 Note: this is implemented by the roundup.cgi.templating.Templates class.
1133
1134 This variable doesn't have any useful methods defined. It supports being
1135 used in expressions to access the templates, and subsequently the template
1136 macros. You may access the templates using the following path expression::
1137
1138 templates/name
1139
1140 or the python expression::
1141
1142 templates[name]
1143
1144 where "name" is the name of the template you wish to access. The template you
1145 get access to has one useful attribute, "macros". To access a specific macro
1146 (called "macro_name"), use the path expression::
1147
1148 templates/name/macros/macro_name
1149
1150 or the python expression::
1151
1152 templates[name].macros[macro_name]
1153
1154
1155 The utils variable
1156 ~~~~~~~~~~~~~~~~~~
1084 1157
1085 Note: this is implemented by the roundup.cgi.templating.TemplatingUtils class. 1158 Note: this is implemented by the roundup.cgi.templating.TemplatingUtils class.
1086 1159
1087 =============== ============================================================= 1160 =============== =============================================================
1088 Method Description 1161 Method Description
1544 1617
1545 The link was for the item template for the category object. This translates 1618 The link was for the item template for the category object. This translates
1546 into the system looking for a file called ``category.item`` in the ``html`` 1619 into the system looking for a file called ``category.item`` in the ``html``
1547 tracker directory. This is the file that we are going to write now. 1620 tracker directory. This is the file that we are going to write now.
1548 1621
1549 First we add an id tag in a comment which doesn't affect the outcome 1622 First we add an info tag in a comment which doesn't affect the outcome
1550 of the code at all but is essential for managing the changes to this 1623 of the code at all but is useful for debugging. If you load a page in a
1551 file. It is useful for debugging however, if you load a page in a
1552 browser and look at the page source, you can see which sections come 1624 browser and look at the page source, you can see which sections come
1553 from which files by looking for these comments:: 1625 from which files by looking for these comments::
1554 1626
1555 <!-- dollarId: category.item,v 1.3 2002/05/22 00:32:34 me Exp dollar--> 1627 <!-- category.item -->
1628
1629 Next we need to add in the METAL macro stuff so we get the normal page
1630 trappings::
1631
1632 <tal:block metal:use-macro="templates/page/macros/page">
1633 <title metal:fill-slot="head_title">Category editing</title>
1634 <td class="page-header-top" metal:fill-slot="body_title">
1635 <h2>Category editing</h2>
1636 </td>
1637 <td class="content" metal:fill-slot="content">
1556 1638
1557 Next we need to setup up a standard HTML form, which is the whole 1639 Next we need to setup up a standard HTML form, which is the whole
1558 purpose of this file. We link to some handy javascript which sends the form 1640 purpose of this file. We link to some handy javascript which sends the form
1559 through only once. This is to stop users hitting the send button 1641 through only once. This is to stop users hitting the send button
1560 multiple times when they are impatient and thus having the form sent 1642 multiple times when they are impatient and thus having the form sent
1585 <tr> 1667 <tr>
1586 <th nowrap>Name</th> 1668 <th nowrap>Name</th>
1587 <td tal:content="structure python:context.name.field(size=60)">name</td> 1669 <td tal:content="structure python:context.name.field(size=60)">name</td>
1588 </tr> 1670 </tr>
1589 1671
1590 Finally a submit button so that the user can submit the new category:: 1672 Then a submit button so that the user can submit the new category::
1591 1673
1592 <tr> 1674 <tr>
1593 <td>&nbsp;</td> 1675 <td>&nbsp;</td>
1594 <td colspan=3 tal:content="structure context/submit"> 1676 <td colspan=3 tal:content="structure context/submit">
1595 submit button will go here 1677 submit button will go here
1596 </td> 1678 </td>
1597 </tr> 1679 </tr>
1598 1680
1681 Finally we finish off the tags we used at the start to do the METAL stuff::
1682
1683 </td>
1684 </tal:block>
1685
1599 So putting it all together, and closing the table and form we get:: 1686 So putting it all together, and closing the table and form we get::
1600 1687
1601 <!-- dollarId: category.item,v 1.3 2002/05/22 00:32:34 richard Exp dollar--> 1688 <!-- category.item -->
1602 1689 <tal:block metal:use-macro="templates/page/macros/page">
1603 <form method="POST" onSubmit="return submit_once()" 1690 <title metal:fill-slot="head_title">Category editing</title>
1604 enctype="multipart/form-data"> 1691 <td class="page-header-top" metal:fill-slot="body_title">
1605 1692 <h2>Category editing</h2>
1606 <input type="hidden" name=":required" value="name"> 1693 </td>
1607 1694 <td class="content" metal:fill-slot="content">
1608 <table class="form"> 1695 <form method="POST" onSubmit="return submit_once()"
1609 <tr><th class="header" colspan=2>Category</th></tr> 1696 enctype="multipart/form-data">
1610 1697
1611 <tr> 1698 <input type="hidden" name=":required" value="name">
1612 <th nowrap>Name</th> 1699
1613 <td tal:content="structure python:context.name.field(size=60)">name</td> 1700 <table class="form">
1614 </tr> 1701 <tr><th class="header" colspan=2>Category</th></tr>
1615 1702
1616 <tr> 1703 <tr>
1617 <td>&nbsp;</td> 1704 <th nowrap>Name</th>
1618 <td colspan=3 tal:content="structure context/submit"> 1705 <td tal:content="structure python:context.name.field(size=60)">name</td>
1619 submit button will go here 1706 </tr>
1620 </td> 1707
1621 </tr> 1708 <tr>
1622 </table> 1709 <td>&nbsp;</td>
1623 </form> 1710 <td colspan=3 tal:content="structure context/submit">
1711 submit button will go here
1712 </td>
1713 </tr>
1714 </table>
1715 </form>
1716 </td>
1717 </tal:block>
1624 1718
1625 This is quite a lot to just ask the user one simple question, but 1719 This is quite a lot to just ask the user one simple question, but
1626 there is a lot of setup for basically one line (the form line) to do 1720 there is a lot of setup for basically one line (the form line) to do
1627 its work. To add another field to "category" would involve one more line 1721 its work. To add another field to "category" would involve one more line
1628 (well maybe a few extra to get the formatting correct). 1722 (well maybe a few extra to get the formatting correct).
1896 </form> 1990 </form>
1897 1991
1898 The next page has the usual issue entry information, with the addition of 1992 The next page has the usual issue entry information, with the addition of
1899 the following form fragments:: 1993 the following form fragments::
1900 1994
1901
1902 <form method="POST" onSubmit="return submit_once()" 1995 <form method="POST" onSubmit="return submit_once()"
1903 enctype="multipart/form-data" tal:condition="context/is_edit_ok" 1996 enctype="multipart/form-data" tal:condition="context/is_edit_ok"
1904 tal:define="cat request/form/category/value"> 1997 tal:define="cat request/form/category/value">
1905 1998
1906 <input type="hidden" name=":template" value="add_page2"> 1999 <input type="hidden" name=":template" value="add_page2">

Roundup Issue Tracker: http://roundup-tracker.org/