Mercurial > p > roundup > code
comparison doc/customizing.txt @ 1083:40fc5f8cd55c
more doc
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Mon, 09 Sep 2002 07:55:24 +0000 |
| parents | 954ad22eb7d9 |
| children | 43ab730ee194 |
comparison
equal
deleted
inserted
replaced
| 1082:38b3a28b9e72 | 1083:40fc5f8cd55c |
|---|---|
| 1 =================== | 1 =================== |
| 2 Customising Roundup | 2 Customising Roundup |
| 3 =================== | 3 =================== |
| 4 | 4 |
| 5 :Version: $Revision: 1.21 $ | 5 :Version: $Revision: 1.22 $ |
| 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:: |
| 284 # subjects. To disable, comment out the variable below or leave it blank. | 284 # subjects. To disable, comment out the variable below or leave it blank. |
| 285 # Examples: | 285 # Examples: |
| 286 MAIL_DEFAULT_CLASS = 'issue' # use "issue" class by default | 286 MAIL_DEFAULT_CLASS = 'issue' # use "issue" class by default |
| 287 #MAIL_DEFAULT_CLASS = '' # disable (or just comment the var out) | 287 #MAIL_DEFAULT_CLASS = '' # disable (or just comment the var out) |
| 288 | 288 |
| 289 # Define what index links are available in the header, and what their | |
| 290 # labels are. Each key is used to look up one of the index specifications | |
| 291 # below - so 'DEFAULT' will use 'DEFAULT_INDEX'. | |
| 292 # Where the FILTERSPEC has 'assignedto' with a value of None, it will be | |
| 293 # replaced by the id of the logged-in user. | |
| 294 HEADER_INDEX_LINKS = ['DEFAULT', 'UNASSIGNED', 'USER'] | |
| 295 | |
| 296 # list the classes that users are able to add nodes to | |
| 297 HEADER_ADD_LINKS = ['issue'] | |
| 298 | |
| 299 # list the classes that users can search | |
| 300 HEADER_SEARCH_LINKS = ['issue'] | |
| 301 | |
| 302 # list search filters per class | |
| 303 SEARCH_FILTERS = ['ISSUE_FILTER', 'SUPPORT_FILTER'] | |
| 304 | |
| 305 # Now the DEFAULT display specification. TODO: describe format | |
| 306 DEFAULT_INDEX = { | |
| 307 'LABEL': 'All Issues', | |
| 308 'CLASS': 'issue', | |
| 309 'SORT': ['-activity'], | |
| 310 'GROUP': ['priority'], | |
| 311 'FILTER': ['status'], | |
| 312 'COLUMNS': ['id','activity','title','creator','assignedto'], | |
| 313 'FILTERSPEC': { | |
| 314 'status': ['-1', '1', '2', '3', '4', '5', '6', '7'], | |
| 315 }, | |
| 316 } | |
| 317 | |
| 318 # The "unsassigned issues" index | |
| 319 UNASSIGNED_INDEX = { | |
| 320 'LABEL': 'Unassigned Issues', | |
| 321 'CLASS': 'issue', | |
| 322 'SORT': ['-activity'], | |
| 323 'GROUP': ['priority'], | |
| 324 'FILTER': ['status', 'assignedto'], | |
| 325 'COLUMNS': ['id','activity','title','creator','status'], | |
| 326 'FILTERSPEC': { | |
| 327 'status': ['-1', '1', '2', '3', '4', '5', '6', '7'], | |
| 328 'assignedto': ['-1'], | |
| 329 }, | |
| 330 } | |
| 331 | |
| 332 # The "my issues" index -- note that the user's id will replace the | |
| 333 # 'CURRENT USER' value of the "assignedto" filterspec | |
| 334 USER_INDEX = { | |
| 335 'LABEL': 'My Issues', | |
| 336 'CLASS': 'issue', | |
| 337 'SORT': ['-activity'], | |
| 338 'GROUP': ['priority'], | |
| 339 'FILTER': ['status', 'assignedto'], | |
| 340 'COLUMNS': ['id','activity','title','creator','status'], | |
| 341 'FILTERSPEC': { | |
| 342 'status': ['-1', '1', '2', '3', '4', '5', '6', '7'], | |
| 343 'assignedto': 'CURRENT USER', | |
| 344 }, | |
| 345 } | |
| 346 | |
| 347 ISSUE_FILTER = { | |
| 348 'CLASS': 'issue', | |
| 349 'FILTER': ['status', 'priority', 'assignedto', 'creator'] | |
| 350 } | |
| 351 | |
| 352 SUPPORT_FILTER = { | |
| 353 'CLASS': 'issue', | |
| 354 'FILTER': ['status', 'priority', 'assignedto', 'creator'] | |
| 355 } | |
| 356 | |
| 357 | |
| 358 Instance Schema | 289 Instance Schema |
| 359 --------------- | 290 --------------- |
| 360 | 291 |
| 361 Note: if you modify the schema, you'll most likely need to edit the | 292 Note: if you modify the schema, you'll most likely need to edit the |
| 362 `web interface`_ HTML template files and `detectors`_ to reflect | 293 `web interface`_ HTML template files and `detectors`_ to reflect |
| 403 | 334 |
| 404 issue = IssueClass(db, "issue", assignedto=Link("user"), | 335 issue = IssueClass(db, "issue", assignedto=Link("user"), |
| 405 topic=Multilink("keyword"), priority=Link("priority"), status=Link | 336 topic=Multilink("keyword"), priority=Link("priority"), status=Link |
| 406 ("status")) | 337 ("status")) |
| 407 issue.setkey('title') | 338 issue.setkey('title') |
| 339 | |
| 340 XXX security definitions | |
| 408 | 341 |
| 409 Classes and Properties - creating a new information store | 342 Classes and Properties - creating a new information store |
| 410 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 343 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 411 | 344 |
| 412 In the instance above, we've defined 7 classes of information: | 345 In the instance above, we've defined 7 classes of information: |
| 590 control on to the instance interfaces.Client class which handles the rest of | 523 control on to the instance interfaces.Client class which handles the rest of |
| 591 the access through its main() method. This means that you can do pretty much | 524 the access through its main() method. This means that you can do pretty much |
| 592 anything you want as a web interface to your instance. | 525 anything you want as a web interface to your instance. |
| 593 | 526 |
| 594 Figuring out what is displayed | 527 Figuring out what is displayed |
| 595 :::::::::::::::::::::::::::::: | 528 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 596 | 529 |
| 597 Most customisation of the web view can be done by modifying the templates in | 530 Most customisation of the web view can be done by modifying the templates in |
| 598 the instance **html** directory. There are several types of files in there: | 531 the instance **html** directory. There are several types of files in there: |
| 599 | 532 |
| 600 page | 533 page |
| 611 displays a list of *classname* items | 544 displays a list of *classname* items |
| 612 *classname*.search | 545 *classname*.search |
| 613 displays a search page for *classname* items | 546 displays a search page for *classname* items |
| 614 _generic.index | 547 _generic.index |
| 615 used to display a list of items where there is no *classname*.index available | 548 used to display a list of items where there is no *classname*.index available |
| 549 _generic.help | |
| 550 used to display a "class help" page where there is no *classname*.help | |
| 616 user.register | 551 user.register |
| 617 a special page just for the user class that renders the registration page | 552 a special page just for the user class that renders the registration page |
| 618 style.css | 553 style.css |
| 619 a static file that is served up as-is | 554 a static file that is served up as-is |
| 620 | 555 |
| 621 How requests are processed | 556 How requests are processed |
| 622 :::::::::::::::::::::::::: | 557 ~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 623 | 558 |
| 624 The basic processing of a web request proceeds as follows: | 559 The basic processing of a web request proceeds as follows: |
| 625 | 560 |
| 626 1. figure out who we are, defaulting to the "anonymous" user | 561 1. figure out who we are, defaulting to the "anonymous" user |
| 627 2. figure out what the request is for - we call this the "context" | 562 2. figure out what the request is for - we call this the "context" |
| 641 granted for the action to take place | 576 granted for the action to take place |
| 642 - NotFound (raised wherever it needs to be) | 577 - NotFound (raised wherever it needs to be) |
| 643 this exception percolates up to the CGI interface that called the client | 578 this exception percolates up to the CGI interface that called the client |
| 644 | 579 |
| 645 Determining web context | 580 Determining web context |
| 646 ::::::::::::::::::::::: | 581 ~~~~~~~~~~~~~~~~~~~~~~~ |
| 647 | 582 |
| 648 To determine the "context" of a request, we look at the URL and the special | 583 To determine the "context" of a request, we look at the URL and the special |
| 649 request variable ``:template``. The URL path after the instance identifier | 584 request variable ``:template``. The URL path after the instance identifier |
| 650 is examined. Typical URL paths look like: | 585 is examined. Typical URL paths look like: |
| 651 | 586 |
| 688 - only classname suplied: "index" | 623 - only classname suplied: "index" |
| 689 - full item designator supplied: "item" | 624 - full item designator supplied: "item" |
| 690 | 625 |
| 691 | 626 |
| 692 Performing actions in web requests | 627 Performing actions in web requests |
| 693 :::::::::::::::::::::::::::::::::: | 628 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 694 | 629 |
| 695 When a user requests a web page, they may optionally also request for an | 630 When a user requests a web page, they may optionally also request for an |
| 696 action to take place. As described in `how requests are processed`_, the | 631 action to take place. As described in `how requests are processed`_, the |
| 697 action is performed before the requested page is generated. Actions are | 632 action is performed before the requested page is generated. Actions are |
| 698 triggered by using a ``:action`` CGI variable, where the value is one of: | 633 triggered by using a ``:action`` CGI variable, where the value is one of: |
| 800 | 735 |
| 801 | 736 |
| 802 How the templates work | 737 How the templates work |
| 803 ~~~~~~~~~~~~~~~~~~~~~~ | 738 ~~~~~~~~~~~~~~~~~~~~~~ |
| 804 | 739 |
| 805 Roundup's templates consist of two core technologies: | 740 Roundup's templates consist of special attributes on your template tags. These |
| 806 | 741 attributes form the Template Attribute Language, or TAL. The commands are: |
| 807 TAL - Template Attribute Language | 742 |
| 808 This is the syntax which is woven into the HTML using the ``tal:`` tag | 743 |
| 809 attributes. A TAL parser pulls out the TAL commands from the attributes | 744 tal:define="variable expression; variable expression; ..." |
| 810 runs them using some expression engine. TAL gives us the following commands: | |
| 811 | |
| 812 tal:define="variable expression; variable expression; ..." | |
| 813 Define a new variable that is local to this tag and its contents. For | 745 Define a new variable that is local to this tag and its contents. For |
| 814 example:: | 746 example:: |
| 815 | 747 |
| 816 <html tal:define="title request/description"> | 748 <html tal:define="title request/description"> |
| 817 <head><title tal:content="title"></title></head> | 749 <head><title tal:content="title"></title></head> |
| 819 | 751 |
| 820 In the example, the variable "title" is defined as being the result of the | 752 In the example, the variable "title" is defined as being the result of the |
| 821 expression "request/description". The tal:content command inside the <html> | 753 expression "request/description". The tal:content command inside the <html> |
| 822 tag may then use the "title" variable. | 754 tag may then use the "title" variable. |
| 823 | 755 |
| 824 tal:condition="expression" | 756 tal:condition="expression" |
| 825 Only keep this tag and its contents if the expression is true. For example:: | 757 Only keep this tag and its contents if the expression is true. For example:: |
| 826 | 758 |
| 827 <p tal:condition="python:request.user.hasPermission('View', 'issue')"> | 759 <p tal:condition="python:request.user.hasPermission('View', 'issue')"> |
| 828 Display some issue information. | 760 Display some issue information. |
| 829 </p> | 761 </p> |
| 832 user has the View permission for issues. We consider the number zero, a | 764 user has the View permission for issues. We consider the number zero, a |
| 833 blank string, an empty list, and the built-in variable nothing to be false | 765 blank string, an empty list, and the built-in variable nothing to be false |
| 834 values. Nearly every other value is true, including non-zero numbers, and | 766 values. Nearly every other value is true, including non-zero numbers, and |
| 835 strings with anything in them (even spaces!). | 767 strings with anything in them (even spaces!). |
| 836 | 768 |
| 837 tal:repeat="variable expression" | 769 tal:repeat="variable expression" |
| 838 Repeat this tag and its contents for each element of the sequence that the | 770 Repeat this tag and its contents for each element of the sequence that the |
| 839 expression returns, defining a new local variable and a special "repeat" | 771 expression returns, defining a new local variable and a special "repeat" |
| 840 variable for each element. For example:: | 772 variable for each element. For example:: |
| 841 | 773 |
| 842 <tr tal:repeat="u user/list"> | 774 <tr tal:repeat="u user/list"> |
| 846 </tr> | 778 </tr> |
| 847 | 779 |
| 848 The example would iterate over the sequence of users returned by | 780 The example would iterate over the sequence of users returned by |
| 849 "user/list" and define the local variable "u" for each entry. | 781 "user/list" and define the local variable "u" for each entry. |
| 850 | 782 |
| 851 tal:replace="expression" | 783 tal:replace="expression" |
| 852 Replace this tag with the result of the expression. For example:: | 784 Replace this tag with the result of the expression. For example:: |
| 853 | 785 |
| 854 <span tal:replace="request/user/realname"></span> | 786 <span tal:replace="request/user/realname"></span> |
| 855 | 787 |
| 856 The example would replace the <span> tag and its contents with the user's | 788 The example would replace the <span> tag and its contents with the user's |
| 857 realname. If the user's realname was "Bruce" then the resultant output | 789 realname. If the user's realname was "Bruce" then the resultant output |
| 858 would be "Bruce". | 790 would be "Bruce". |
| 859 | 791 |
| 860 tal:content="expression" | 792 tal:content="expression" |
| 861 Replace the contents of this tag with the result of the expression. For | 793 Replace the contents of this tag with the result of the expression. For |
| 862 example:: | 794 example:: |
| 863 | 795 |
| 864 <span tal:content="request/user/realname">user's name appears here</span> | 796 <span tal:content="request/user/realname">user's name appears here</span> |
| 865 | 797 |
| 866 The example would replace the contents of the <span> tag with the user's | 798 The example would replace the contents of the <span> tag with the user's |
| 867 realname. If the user's realname was "Bruce" then the resultant output | 799 realname. If the user's realname was "Bruce" then the resultant output |
| 868 would be "<span>Bruce</span>". | 800 would be "<span>Bruce</span>". |
| 869 | 801 |
| 870 tal:attributes="attribute expression; attribute expression; ..." | 802 tal:attributes="attribute expression; attribute expression; ..." |
| 871 Set attributes on this tag to the results of expressions. For example:: | 803 Set attributes on this tag to the results of expressions. For example:: |
| 872 | 804 |
| 873 <a tal:attributes="href string:user${request/user/id}">My Details</a> | 805 <a tal:attributes="href string:user${request/user/id}">My Details</a> |
| 874 | 806 |
| 875 In the example, the "href" attribute of the <a> tag is set to the value of | 807 In the example, the "href" attribute of the <a> tag is set to the value of |
| 876 the "string:user${request/user/id}" expression, which will be something | 808 the "string:user${request/user/id}" expression, which will be something |
| 877 like "user123". | 809 like "user123". |
| 878 | 810 |
| 879 tal:omit-tag="expression" | 811 tal:omit-tag="expression" |
| 880 Remove this tag (but not its contents) if the expression is true. For | 812 Remove this tag (but not its contents) if the expression is true. For |
| 881 example:: | 813 example:: |
| 882 | 814 |
| 883 <span tal:omit-tag="python:1">Hello, world!</span> | 815 <span tal:omit-tag="python:1">Hello, world!</span> |
| 884 | 816 |
| 885 would result in output of:: | 817 would result in output of:: |
| 886 | 818 |
| 887 Hello, world! | 819 Hello, world! |
| 888 | 820 |
| 889 Note that the commands on a given tag are evaulated in the order above, so | 821 Note that the commands on a given tag are evaulated in the order above, so |
| 890 *define* comes before *condition*, and so on. | 822 *define* comes before *condition*, and so on. |
| 891 | 823 |
| 892 Additionally, a tag is defined, tal:block, which is removed from output. Its | 824 Additionally, a tag is defined, tal:block, which is removed from output. Its |
| 893 content is not, but the tag itself is (so don't go using any tal:attributes | 825 content is not, but the tag itself is (so don't go using any tal:attributes |
| 894 commands on it). This is useful for making arbitrary blocks of HTML | 826 commands on it). This is useful for making arbitrary blocks of HTML |
| 895 conditional or repeatable (very handy for repeating multiple table rows, | 827 conditional or repeatable (very handy for repeating multiple table rows, |
| 896 which would othewise require an illegal tag placement to effect the repeat). | 828 which would othewise require an illegal tag placement to effect the repeat). |
| 897 | 829 |
| 898 TALES - TAL Expression Syntax | 830 The expressions you may use in the attibute values may be one of the following |
| 899 The expression engine used in this case is TALES, which runs the expressions | 831 three forms: |
| 900 that form the tag attribute values. TALES expressions come in three | 832 |
| 901 flavours: | 833 Path Expressions - eg. ``item/status/checklist`` |
| 902 | |
| 903 Path Expressions - eg. ``item/status/checklist`` | |
| 904 These are object attribute / item accesses. Roughly speaking, the path | 834 These are object attribute / item accesses. Roughly speaking, the path |
| 905 ``item/status/checklist`` is broken into parts ``item``, ``status`` | 835 ``item/status/checklist`` is broken into parts ``item``, ``status`` |
| 906 and ``checklist``. The ``item`` part is the root of the expression. | 836 and ``checklist``. The ``item`` part is the root of the expression. |
| 907 We then look for a ``status`` attribute on ``item``, or failing that, a | 837 We then look for a ``status`` attribute on ``item``, or failing that, a |
| 908 ``status`` item (as in ``item['status']``). If that | 838 ``status`` item (as in ``item['status']``). If that |
| 910 left with is evaluated to get a string - methods are called, objects are | 840 left with is evaluated to get a string - methods are called, objects are |
| 911 stringified. Path expressions may have an optional ``path:`` prefix, though | 841 stringified. Path expressions may have an optional ``path:`` prefix, though |
| 912 they are the default expression type, so it's not necessary. | 842 they are the default expression type, so it's not necessary. |
| 913 | 843 |
| 914 XXX | components of expressions | 844 XXX | components of expressions |
| 845 | |
| 915 XXX "nothing" and "default" | 846 XXX "nothing" and "default" |
| 916 | 847 |
| 917 String Expressions - eg. ``string:hello ${user/name}`` | 848 String Expressions - eg. ``string:hello ${user/name}`` |
| 918 These expressions are simple string interpolations (though they can be just | 849 These expressions are simple string interpolations (though they can be just |
| 919 plain strings with no interpolation if you want. The expression in the | 850 plain strings with no interpolation if you want. The expression in the |
| 920 ``${ ... }`` is just a path expression as above. | 851 ``${ ... }`` is just a path expression as above. |
| 921 | 852 |
| 922 Python Expressions - eg. ``python: 1+1`` | 853 Python Expressions - eg. ``python: 1+1`` |
| 923 These expressions give the full power of Python. All the "root level" | 854 These expressions give the full power of Python. All the "root level" |
| 924 variables are available, so ``python:item.status.checklist()`` would be | 855 variables are available, so ``python:item.status.checklist()`` would be |
| 925 equivalent to ``item/status/checklist``, assuming that ``checklist`` is | 856 equivalent to ``item/status/checklist``, assuming that ``checklist`` is |
| 926 a method. | 857 a method. |
| 927 | 858 |
| 948 name to value | 879 name to value |
| 949 *instance* | 880 *instance* |
| 950 The current instance | 881 The current instance |
| 951 *db* | 882 *db* |
| 952 The current database, through which db.config may be reached. | 883 The current database, through which db.config may be reached. |
| 884 *nothing* | |
| 885 XXX a special variable | |
| 886 *default* | |
| 887 XXX a special variable | |
| 953 | 888 |
| 954 The context variable | 889 The context variable |
| 955 :::::::::::::::::: | 890 :::::::::::::::::::: |
| 956 | 891 |
| 957 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 |
| 958 (see `determining web context`_ for how we figure this out): | 893 (see `determining web context`_ for how we figure this out): |
| 959 | 894 |
| 960 1. if we're looking at a "home" page, then it's None | 895 1. if we're looking at a "home" page, then it's None |
| 988 base the base URL for this instance | 923 base the base URL for this instance |
| 989 user a HTMLUser instance for this user | 924 user a HTMLUser instance for this user |
| 990 classname the current classname (possibly None) | 925 classname the current classname (possibly None) |
| 991 template the current template (suffix, also possibly None) | 926 template the current template (suffix, also possibly None) |
| 992 form the current CGI form variables in a FieldStorage | 927 form the current CGI form variables in a FieldStorage |
| 993 **Index page specific variables (indexing arguments)** | 928 =========== ================================================================ |
| 929 | |
| 930 **Index page specific variables (indexing arguments)** | |
| 931 | |
| 932 =========== ================================================================ | |
| 933 Variable Holds | |
| 934 =========== ================================================================ | |
| 994 columns dictionary of the columns to display in an index page | 935 columns dictionary of the columns to display in an index page |
| 995 show a convenience access to columns - request/show/colname will | 936 show a convenience access to columns - request/show/colname will |
| 996 be true if the columns should be displayed, false otherwise | 937 be true if the columns should be displayed, false otherwise |
| 997 sort index sort column (direction, column name) | 938 sort index sort column (direction, column name) |
| 998 group index grouping property (direction, column name) | 939 group index grouping property (direction, column name) |
| 999 filter properties to filter the index on | 940 filter properties to filter the index on |
| 1000 filterspec values to filter the index on | 941 filterspec values to filter the index on |
| 1001 search_text text to perform a full-text search on for an index | 942 search_text text to perform a full-text search on for an index |
| 1002 ----------- ---------------------------------------------------------------- | 943 =========== ================================================================ |
| 1003 | 944 |
| 1004 | 945 |
| 1005 Displaying Properties | 946 Displaying Properties |
| 1006 ~~~~~~~~~~~~~~~~~~~~~ | 947 ~~~~~~~~~~~~~~~~~~~~~ |
| 1007 | 948 |
