Mercurial > p > roundup > code
comparison doc/customizing.txt @ 1057:8b9feca82090
some progress
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Fri, 06 Sep 2002 03:08:35 +0000 |
| parents | f89b8d32291b |
| children | a55ef5a98fd3 |
comparison
equal
deleted
inserted
replaced
| 1056:1c2a2ecc1b03 | 1057:8b9feca82090 |
|---|---|
| 1 =================== | 1 =================== |
| 2 Customising Roundup | 2 Customising Roundup |
| 3 =================== | 3 =================== |
| 4 | 4 |
| 5 :Version: $Revision: 1.16 $ | 5 :Version: $Revision: 1.17 $ |
| 6 | 6 |
| 7 .. contents:: | 7 .. contents:: |
| 8 | 8 |
| 9 | 9 |
| 10 What You Can Do | 10 What You Can Do |
| 513 | 513 |
| 514 Create a node in the database. This is generally used to create nodes in the | 514 Create a node in the database. This is generally used to create nodes in the |
| 515 "definitional" classes like "priority" and "status". | 515 "definitional" classes like "priority" and "status". |
| 516 | 516 |
| 517 | 517 |
| 518 Examples of adding to your schema | |
| 519 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 520 | |
| 521 TODO | |
| 522 | |
| 523 | |
| 518 Detectors - adding behaviour to your tracker | 524 Detectors - adding behaviour to your tracker |
| 519 -------------------------------------------- | 525 -------------------------------------------- |
| 520 .. _detectors: | 526 .. _detectors: |
| 521 | 527 |
| 522 The detectors in your instance fire before (*auditors*) and after (*reactors*) | 528 The detectors in your instance fire before (*auditors*) and after (*reactors*) |
| 579 scripts. In both cases, the scripts determine which instance is being accessed | 585 scripts. In both cases, the scripts determine which instance is being accessed |
| 580 (the first part of the URL path inside the scope of the CGI handler) and pass | 586 (the first part of the URL path inside the scope of the CGI handler) and pass |
| 581 control on to the instance interfaces.Client class which handles the rest of | 587 control on to the instance interfaces.Client class which handles the rest of |
| 582 the access through its main() method. This means that you can do pretty much | 588 the access through its main() method. This means that you can do pretty much |
| 583 anything you want as a web interface to your instance. | 589 anything you want as a web interface to your instance. |
| 590 | |
| 584 Most customisation of the web view can be done by modifying the templates in | 591 Most customisation of the web view can be done by modifying the templates in |
| 585 the instance html directory. These are divided into index, item and newitem | 592 the instance **html** directory. There are several types of files in there: |
| 586 views. The newitem view is optional - the item view will be used if the newitem | 593 |
| 587 view doesn't exist. The header and footer that wrap the various views give the | 594 page |
| 588 pages an overall look. | 595 defines the overall look of your tracker. When you |
| 596 view an issue, it appears inside this template. When you view an index, it | |
| 597 also appears inside this template. | |
| 598 home | |
| 599 the default page displayed when no other page is indicated by the user | |
| 600 home.classlist | |
| 601 a special version of the default page that lists the classes in the tracker | |
| 602 *classname*.item | |
| 603 displays an item of the *classname* class | |
| 604 *classname*.index | |
| 605 displays a list of *classname* items | |
| 606 *classname*.search | |
| 607 displays a search page for *classname* items | |
| 608 _generic.index | |
| 609 used to display a list of items where there is no *classname*.index available | |
| 610 user.register | |
| 611 a special page just for the user class that renders the registration page | |
| 612 style.css | |
| 613 a static file that is served up as-is | |
| 614 | |
| 615 The basic processing of a web request proceeds as follows: | |
| 616 | |
| 617 1. figure out who we are, defaulting to the "anonymous" user | |
| 618 2. figure out what the request is for - we call this the "context" | |
| 619 3. handle any requested action (item edit, search, ...) | |
| 620 4. render a template, resulting in HTML output | |
| 621 | |
| 622 In some situations, exceptions occur: | |
| 623 - HTTP Redirect (generally raised by an action) | |
| 624 - SendFile (generally raised by determine_context) | |
| 625 here we serve up a FileClass "content" property | |
| 626 - SendStaticFile (generally raised by determine_context) | |
| 627 here we serve up a file from the tracker "html" directory | |
| 628 - Unauthorised (generally raised by an action) | |
| 629 here the action is cancelled, the request is rendered and an error | |
| 630 message is displayed indicating that permission was not | |
| 631 granted for the action to take place | |
| 632 - NotFound (raised wherever it needs to be) | |
| 633 this exception percolates up to the CGI interface that called the client | |
| 634 | |
| 635 To determine the "context" of a request, we look at the URL and the special | |
| 636 request variable ``:template``. The URL path after the instance identifier | |
| 637 is examined. Typical URL paths look like: | |
| 638 | |
| 639 1. ``/tracker/issue`` | |
| 640 2. ``/tracker/issue1`` | |
| 641 3. ``/tracker/_file/style.css`` | |
| 642 4. ``/cgi-bin/roundup.cgi/tracker/file1`` | |
| 643 5. ``/cgi-bin/roundup.cgi/tracker/file1/kitten.png`` | |
| 644 | |
| 645 where the "instance identifier" is "tracker" in the above cases. That means | |
| 646 we're looking at "issue", "issue1", "_file/style.css", "file1" and | |
| 647 "file1/kitten.png" in the cases above. The path is generally only one | |
| 648 entry long - longer paths are handled differently. | |
| 649 | |
| 650 a. if there is no path, then we are in the "home" context. | |
| 651 b. if the path starts with "_file" (as in example 3, | |
| 652 "/tracker/_file/style.css"), then the additional path entry, | |
| 653 "style.css" specifies the filename of a static file we're to serve up | |
| 654 from the instance "html" directory. Raises a SendStaticFile | |
| 655 exception. | |
| 656 c. if there is something in the path (as in example 1, "issue"), it identifies | |
| 657 the tracker class we're to display. | |
| 658 d. if the path is an item designator (as in examples 2 and 4, "issue1" and | |
| 659 "file1"), then we're to display a specific item. | |
| 660 e. if the path starts with an item designator and is longer than | |
| 661 one entry (as in example 5, "file1/kitten.png"), then we're assumed | |
| 662 to be handling an item of a | |
| 663 FileClass, and the extra path information gives the filename | |
| 664 that the client is going to label the download with (ie | |
| 665 "file1/kitten.png" is nicer to download than "file1"). This | |
| 666 raises a SendFile exception. | |
| 667 | |
| 668 Both b. and e. stop before we bother to | |
| 669 determine the template we're going to use. That's because they | |
| 670 don't actually use templates. | |
| 671 | |
| 672 The template used is specified by the ``:template`` CGI variable, | |
| 673 which defaults to: | |
| 674 | |
| 675 - only classname suplied: "index" | |
| 676 - full item designator supplied: "item" | |
| 677 | |
| 589 | 678 |
| 590 Repurcussions of changing the instance schema | 679 Repurcussions of changing the instance schema |
| 591 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 680 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 592 | 681 |
| 593 If you choose to change the `instance schema`_ you will need to ensure the web | 682 If you choose to change the `instance schema`_ you will need to ensure the web |
| 594 interface knows about it: | 683 interface knows about it: |
| 595 | 684 |
| 596 1. Index, item and filter pages for the relevant classes may need to have | 685 1. Index, item and search pages for the relevant classes may need to have |
| 597 properties added or removed, | 686 properties added or removed, |
| 598 2. The default page header relies on the existence of, and some values of | 687 2. The "page" template may require links to be changed, as might the "home" |
| 599 the priority, status, assignedto and activity classes. If you change any | 688 page's content arguments. |
| 600 of these (specifically if you remove any of the classes or their default | 689 |
| 601 values) you will need to implement your own pagehead() method in your | 690 Overall Look - "page" template |
| 602 instance's interfaces.py module. | 691 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 603 | 692 |
| 604 Overall Look - the Header and Footer | 693 The "page" template in your instances |
| 605 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 606 | |
| 607 The header and footer are generated by Python code. The default code is in | |
| 608 roundup.cgi_client.Class. This class is mixed-in to your instance through the | 694 roundup.cgi_client.Class. This class is mixed-in to your instance through the |
| 609 instance's interfaces module. This means you can override the header and | 695 instance's interfaces module. This means you can override the header and |
| 610 footer with your own code. This allows you to use a sidebar navigation scheme, | 696 footer with your own code. This allows you to use a sidebar navigation scheme, |
| 611 for example. | 697 for example. |
| 612 | 698 |
| 613 | 699 |
| 700 PageTemplates in a Nutshell | |
| 701 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 702 | |
| 703 PageTemplates consist of two core technologies: | |
| 704 | |
| 705 TAL - Template Attribute Language | |
| 706 This is the syntax which is woven into the HTML using the ``tal:`` tag | |
| 707 attributes. A TAL parser pulls out the TAL commands from the attributes | |
| 708 runs them using some expression engine. TAL gives: | |
| 709 | |
| 710 tal:define | |
| 711 tal:replace | |
| 712 tal:content | |
| 713 tal:repeat | |
| 714 tal:attributes | |
| 715 | |
| 716 Additionally, a tag is defined, tal:block, which is removed from output. Its | |
| 717 content is not, but the tag itself is (so don't go using any tal:attributes | |
| 718 commands on it). This is useful for making arbitrary blocks of HTML | |
| 719 conditional or repeatable (very handy for repeating multiple table rows, | |
| 720 which would othewise require an illegal tag placement to effect the repeat). | |
| 721 | |
| 722 TALES - TAL Expression Syntax | |
| 723 The expression engine used in this case is TALES, which runs the expressions | |
| 724 that form the tag attribute values. TALES expressions come in three | |
| 725 flavours: | |
| 726 | |
| 727 Path Expressions - eg. ``item/status/checklist`` | |
| 728 These are object attribute / item accesses. Roughly speaking, the path | |
| 729 ``item/status/checklist`` is broken into parts ``item``, ``status`` | |
| 730 and ``checklist``. The ``item`` part is the root of the expression. | |
| 731 We then look for a ``status`` attribute on ``item``, or failing that, a | |
| 732 ``status`` item (as in ``item['status']``). If that | |
| 733 fails, the path expression fails. When we get to the end, the object we're | |
| 734 left with is evaluated to get a string - methods are called, objects are | |
| 735 stringified. Path expressions may have an optional ``path:`` prefix, though | |
| 736 they are the default expression type, so it's not necessary. | |
| 737 | |
| 738 String Expressions - eg. ``string:hello ${user/name}`` | |
| 739 These expressions are simple string interpolations (though they can be just | |
| 740 plain strings with no interpolation if you want. The expression in the | |
| 741 ``${ ... }`` is just a path expression as above. | |
| 742 | |
| 743 Python Expressions - eg. ``python: 1+1`` | |
| 744 These expressions give the full power of Python. All the "root level" | |
| 745 variables are available, so ``python:item.status.checklist()`` would be | |
| 746 equivalent to ``item/status/checklist``, assuming that ``checklist`` is | |
| 747 a method. | |
| 748 | |
| 614 Displaying Properties | 749 Displaying Properties |
| 615 ~~~~~~~~~~~~~~~~~~~~~ | 750 ~~~~~~~~~~~~~~~~~~~~~ |
| 616 | 751 |
| 617 Properties appear in the user interface in three contexts: in indices, in | 752 Properties appear in the user interface in three contexts: in indices, in |
| 618 editors, and as filters. For each type of property, there are several display | 753 editors, and as search arguments. |
| 619 possibilities. For example, in an index view, a string property may just be | 754 For each type of property, there are several display possibilities. |
| 620 printed as a plain string, but in an editor view, that property should be | 755 For example, in an index view, a string property may just be |
| 756 printed as a plain string, but in an editor view, that property may be | |
| 621 displayed in an editable field. | 757 displayed in an editable field. |
| 622 | |
| 623 The display of a property is handled by functions in the htmltemplate module. | |
| 624 Displayer functions are triggered by <display> tags in templates. The call | |
| 625 attribute of the tag provides a Python expression for calling the displayer | |
| 626 function. The three standard arguments are inserted in front of the arguments | |
| 627 given. For example, the occurrence of:: | |
| 628 | |
| 629 <display call="plain('status')"> | |
| 630 | |
| 631 in a template triggers a call the "plain" function. The displayer functions can | |
| 632 accept extra arguments to further specify details about the widgets that should | |
| 633 be generated. By defining new displayer functions, the user interface can be | |
| 634 highly customized. | |
| 635 | |
| 636 +-----------------------------------------------------------------------------+ | |
| 637 |The displayer functions are | | |
| 638 +---------+-------------------------------------------------------------------+ | |
| 639 |plain |Display a String property directly. | | |
| 640 | |Display a Date property in a specified time zone with an option to | | |
| 641 | |omit the time from the date stamp. | | |
| 642 | |For a Link or Multilink property, display the key strings of the | | |
| 643 | |linked nodes (or the ids if the linked class has no key property). | | |
| 644 | |Options: | | |
| 645 | |escape (boolean) - HTML-escape the resulting text. | | |
| 646 +---------+-------------------------------------------------------------------+ | |
| 647 |field |Display a property like the plain displayer above, but in a form | | |
| 648 | |field to be edited. Strings, Dates and Intervals use TEXT fields, | | |
| 649 | |Links use SELECT fields and Multilinks use SELECT MULTIPLE fields. | | |
| 650 | |Options: | | |
| 651 | |size (number) - width of TEXT fields. | | |
| 652 | |height (number) - number of nows in SELECT MULTIPLE tags. | | |
| 653 | |showid (boolean) - true includes the id of linked nodes in the | | |
| 654 | |SELECT MULTIPLE fields. | | |
| 655 +---------+-------------------------------------------------------------------+ | |
| 656 |menu |For a Links and Multilinks, display the same field as would be | | |
| 657 | |generated using field. | | |
| 658 +---------+-------------------------------------------------------------------+ | |
| 659 |link |For a Link or Multilink property, display the names of the linked | | |
| 660 | |nodes, hyperlinked to the item views on those nodes. | | |
| 661 | |For other properties, link to this node with the property as the | | |
| 662 | |text. | | |
| 663 | |Options: | | |
| 664 | |property (property name) - the property to use in the second case. | | |
| 665 | |showid - use the linked node id as the link text (linked node | | |
| 666 | |"value" will be set as a tooltip) | | |
| 667 +---------+-------------------------------------------------------------------+ | |
| 668 |count |For a Multilink property, display a count of the number of links in| | |
| 669 | |the list. | | |
| 670 | |Arguments: | | |
| 671 | |property (property name) - the property to use. | | |
| 672 +---------+-------------------------------------------------------------------+ | |
| 673 |reldate |Display a Date property in terms of an interval relative to the | | |
| 674 | |current date (e.g. "+ 3w", "- 2d"). | | |
| 675 | |Arguments: | | |
| 676 | |property (property name) - the property to use. | | |
| 677 | |Options: | | |
| 678 | |pretty (boolean) - display the relative date in an English form. | | |
| 679 +---------+-------------------------------------------------------------------+ | |
| 680 |download |For a Link or Multilink property, display the names of the linked | | |
| 681 | |nodes, hyperlinked to the item views on those nodes. | | |
| 682 | |For other properties, link to this node with the property as the | | |
| 683 | |text. | | |
| 684 | |In all cases, append the name (key property) of the item to the | | |
| 685 | |path so it is the name of the file being downloaded. | | |
| 686 | |Arguments: | | |
| 687 | |property (property name) - the property to use. | | |
| 688 +---------+-------------------------------------------------------------------+ | |
| 689 |checklist|For a Link or Multilink property, display checkboxes for the | | |
| 690 | |available choices to permit filtering. | | |
| 691 | |Arguments: | | |
| 692 | |property (property name) - the property to use. | | |
| 693 +---------+-------------------------------------------------------------------+ | |
| 694 |note |Display the special notes field, which is a text area for entering | | |
| 695 | |a note to go along with a change. | | |
| 696 +---------+-------------------------------------------------------------------+ | |
| 697 |list |List the nodes specified by property using the standard index for | | |
| 698 | |the class. | | |
| 699 | |Arguments: | | |
| 700 | |property (property name) - the property to use. | | |
| 701 +---------+-------------------------------------------------------------------+ | |
| 702 |history |List the history of the item. | | |
| 703 +---------+-------------------------------------------------------------------+ | |
| 704 |submit |Add a submit button for the item. | | |
| 705 +---------+-------------------------------------------------------------------+ | |
| 706 | 758 |
| 707 | 759 |
| 708 Index Views | 760 Index Views |
| 709 ~~~~~~~~~~~ | 761 ~~~~~~~~~~~ |
| 710 | |
| 711 An index view contains two sections: a filter section and an index section. The | |
| 712 filter section provides some widgets for selecting which items appear in the | |
| 713 index. The index section is a table of items. | |
| 714 | 762 |
| 715 Index View Specifiers | 763 Index View Specifiers |
| 716 ::::::::::::::::::::: | 764 ::::::::::::::::::::: |
| 717 | 765 |
| 718 An index view specifier (URL fragment) looks like this (whitespace has been | 766 An index view specifier (URL fragment) looks like this (whitespace has been |
| 748 | 796 |
| 749 Associated with each item class is a default layout specifier. The layout | 797 Associated with each item class is a default layout specifier. The layout |
| 750 specifier in the above example is the default layout to be provided with the | 798 specifier in the above example is the default layout to be provided with the |
| 751 default bug-tracker schema described above in section 4.4. | 799 default bug-tracker schema described above in section 4.4. |
| 752 | 800 |
| 753 Filter Section | 801 Filtering of indexes |
| 754 :::::::::::::: | 802 :::::::::::::::::::: |
| 755 | 803 |
| 756 The template for a filter section provides the filtering widgets at the top of | 804 TODO |
| 757 the index view. Fragments enclosed in <property>...</property> tags are | 805 |
| 758 included or omitted depending on whether the view specifier requests a filter | 806 Searching Views |
| 759 for a particular property. | 807 ~~~~~~~~~~~~~~~ |
| 760 | 808 |
| 761 A property must appear in the filter template for it to be available as a | 809 TODO |
| 762 filter. | |
| 763 | |
| 764 Here's a simple example of a filter template.:: | |
| 765 | |
| 766 <property name=status> | |
| 767 <display call="checklist('status')"> | |
| 768 </property> | |
| 769 <br> | |
| 770 <property name=priority> | |
| 771 <display call="checklist('priority')"> | |
| 772 </property> | |
| 773 <br> | |
| 774 <property name=fixer> | |
| 775 <display call="menu('fixer')"> | |
| 776 </property> | |
| 777 | |
| 778 The standard index generation code appends a section to the index pages which | |
| 779 allows selection of the filters - from those which are defined in the filter | |
| 780 template. | |
| 781 | |
| 782 Index Section | |
| 783 ::::::::::::: | |
| 784 | |
| 785 The template for an index section describes one row of the index table. | |
| 786 Fragments enclosed in <property>...</property> tags are included or omitted | |
| 787 depending on whether the view specifier requests a column for a particular | |
| 788 property. The table cells should contain <display> tags to display the values | |
| 789 of the item's properties. | |
| 790 | |
| 791 Here's a simple example of an index template.:: | |
| 792 | |
| 793 <tr> | |
| 794 <property name=title> | |
| 795 <td><display call="plain('title', max=50)"></td> | |
| 796 </property> | |
| 797 <property name=status> | |
| 798 <td><display call="plain('status')"></td> | |
| 799 </property> | |
| 800 <property name=fixer> | |
| 801 <td><display call="plain('fixer')"></td> | |
| 802 </property> | |
| 803 </tr> | |
| 804 | |
| 805 Sorting | |
| 806 ::::::: | |
| 807 | |
| 808 String and Date values are sorted in the natural way. Link properties are | |
| 809 sorted according to the value of the "order" property on the linked nodes if it | |
| 810 is present; or otherwise on the key string of the linked nodes; or finally on | |
| 811 the node ids. Multilink properties are sorted according to how many links are | |
| 812 present. | |
| 813 | 810 |
| 814 Item Views | 811 Item Views |
| 815 ~~~~~~~~~~ | 812 ~~~~~~~~~~ |
| 816 | 813 |
| 817 An item view contains an editor section and a spool section. At the top of an | 814 An item view contains an editor section and a spool section. At the top of an |
