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

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