Skip to content

Commit 311f6a1

Browse files
author
Richard Jones
committed
some progress
1 parent 96ee06a commit 311f6a1

File tree

1 file changed

+159
-162
lines changed

1 file changed

+159
-162
lines changed

doc/customizing.txt

Lines changed: 159 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Customising Roundup
33
===================
44

5-
:Version: $Revision: 1.16 $
5+
:Version: $Revision: 1.17 $
66

77
.. contents::
88

@@ -515,6 +515,12 @@ Create a node in the database. This is generally used to create nodes in the
515515
"definitional" classes like "priority" and "status".
516516

517517

518+
Examples of adding to your schema
519+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
520+
521+
TODO
522+
523+
518524
Detectors - adding behaviour to your tracker
519525
--------------------------------------------
520526
.. _detectors:
@@ -581,137 +587,179 @@ scripts. In both cases, the scripts determine which instance is being accessed
581587
control on to the instance interfaces.Client class which handles the rest of
582588
the access through its main() method. This means that you can do pretty much
583589
anything you want as a web interface to your instance.
590+
584591
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+
589678

590679
Repurcussions of changing the instance schema
591680
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
592681

593682
If you choose to change the `instance schema`_ you will need to ensure the web
594683
interface knows about it:
595684

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
597686
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.
603689

604-
Overall Look - the Header and Footer
605-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
690+
Overall Look - "page" template
691+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
606692

607-
The header and footer are generated by Python code. The default code is in
693+
The "page" template in your instances
608694
roundup.cgi_client.Class. This class is mixed-in to your instance through the
609695
instance's interfaces module. This means you can override the header and
610696
footer with your own code. This allows you to use a sidebar navigation scheme,
611697
for example.
612698

613699

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+
614749
Displaying Properties
615750
~~~~~~~~~~~~~~~~~~~~~
616751

617752
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
621757
displayed in an editable field.
622758

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-
707759

708760
Index Views
709761
~~~~~~~~~~~
710762

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-
715763
Index View Specifiers
716764
:::::::::::::::::::::
717765

@@ -750,66 +798,15 @@ Associated with each item class is a default layout specifier. The layout
750798
specifier in the above example is the default layout to be provided with the
751799
default bug-tracker schema described above in section 4.4.
752800

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+
::::::::::::::::::::
765803

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
804805

805-
Sorting
806-
:::::::
806+
Searching Views
807+
~~~~~~~~~~~~~~~
807808

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
813810

814811
Item Views
815812
~~~~~~~~~~

0 commit comments

Comments
 (0)