Mercurial > p > roundup > code
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> </td> | 1675 <td> </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> </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> </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"> |
