|
2 | 2 | Customising Roundup |
3 | 3 | =================== |
4 | 4 |
|
5 | | -:Version: $Revision: 1.16 $ |
| 5 | +:Version: $Revision: 1.17 $ |
6 | 6 |
|
7 | 7 | .. contents:: |
8 | 8 |
|
@@ -515,6 +515,12 @@ Create a node in the database. This is generally used to create nodes in the |
515 | 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 | 524 | Detectors - adding behaviour to your tracker |
519 | 525 | -------------------------------------------- |
520 | 526 | .. _detectors: |
@@ -581,137 +587,179 @@ scripts. In both cases, the scripts determine which instance is being accessed |
581 | 587 | control on to the instance interfaces.Client class which handles the rest of |
582 | 588 | the access through its main() method. This means that you can do pretty much |
583 | 589 | anything you want as a web interface to your instance. |
| 590 | + |
584 | 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 |
586 | | -views. The newitem view is optional - the item view will be used if the newitem |
587 | | -view doesn't exist. The header and footer that wrap the various views give the |
588 | | -pages an overall look. |
| 592 | +the instance **html** directory. There are several types of files in there: |
| 593 | + |
| 594 | +page |
| 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 | 679 | Repurcussions of changing the instance schema |
591 | 680 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
592 | 681 |
|
593 | 682 | If you choose to change the `instance schema`_ you will need to ensure the web |
594 | 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 | 686 | properties added or removed, |
598 | | -2. The default page header relies on the existence of, and some values of |
599 | | - the priority, status, assignedto and activity classes. If you change any |
600 | | - of these (specifically if you remove any of the classes or their default |
601 | | - values) you will need to implement your own pagehead() method in your |
602 | | - instance's interfaces.py module. |
| 687 | +2. The "page" template may require links to be changed, as might the "home" |
| 688 | + page's content arguments. |
603 | 689 |
|
604 | | -Overall Look - the Header and Footer |
605 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 690 | +Overall Look - "page" template |
| 691 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
606 | 692 |
|
607 | | -The header and footer are generated by Python code. The default code is in |
| 693 | +The "page" template in your instances |
608 | 694 | roundup.cgi_client.Class. This class is mixed-in to your instance through the |
609 | 695 | instance's interfaces module. This means you can override the header and |
610 | 696 | footer with your own code. This allows you to use a sidebar navigation scheme, |
611 | 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 | 749 | Displaying Properties |
615 | 750 | ~~~~~~~~~~~~~~~~~~~~~ |
616 | 751 |
|
617 | 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 |
619 | | -possibilities. For example, in an index view, a string property may just be |
620 | | -printed as a plain string, but in an editor view, that property should be |
| 753 | +editors, and as search arguments. |
| 754 | +For each type of property, there are several display possibilities. |
| 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 | 757 | displayed in an editable field. |
622 | 758 |
|
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 | | - |
707 | 759 |
|
708 | 760 | Index Views |
709 | 761 | ~~~~~~~~~~~ |
710 | 762 |
|
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 | | - |
715 | 763 | Index View Specifiers |
716 | 764 | ::::::::::::::::::::: |
717 | 765 |
|
@@ -750,66 +798,15 @@ Associated with each item class is a default layout specifier. The layout |
750 | 798 | specifier in the above example is the default layout to be provided with the |
751 | 799 | default bug-tracker schema described above in section 4.4. |
752 | 800 |
|
753 | | -Filter Section |
754 | | -:::::::::::::: |
755 | | - |
756 | | -The template for a filter section provides the filtering widgets at the top of |
757 | | -the index view. Fragments enclosed in <property>...</property> tags are |
758 | | -included or omitted depending on whether the view specifier requests a filter |
759 | | -for a particular property. |
760 | | - |
761 | | -A property must appear in the filter template for it to be available as a |
762 | | -filter. |
763 | | - |
764 | | -Here's a simple example of a filter template.:: |
| 801 | +Filtering of indexes |
| 802 | +:::::::::::::::::::: |
765 | 803 |
|
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 | +TODO |
804 | 805 |
|
805 | | -Sorting |
806 | | -::::::: |
| 806 | +Searching Views |
| 807 | +~~~~~~~~~~~~~~~ |
807 | 808 |
|
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. |
| 809 | +TODO |
813 | 810 |
|
814 | 811 | Item Views |
815 | 812 | ~~~~~~~~~~ |
|
0 commit comments