Project classifiers (aka labels)
Consider merging this page with Multi-Project Support for Trac
In order to provide an structured solution so as not to limit the possible ways of grouping projects it is convenient to introduce the concept of project labels. Main goals are the following :
- Offer a structured mechanism to identify a group of projects no matter what hierarchy is involved .
 - Encapsulate these details at the API level while determining (multi)project context.
 
Considering the reference example, 
in spite of searching for tickets 
in Family A and Family B but not in Tools and 3rdParty when needed, 
a label containing both projects has to be created (either explicitly or 
implicitly, see below) .
This document also suggests alternatives and approaches to implement some features defined in Multi-Project Support for Trac. Some content may actually overlap aforementioned specification.
URL space for different projects
A constraint should be imposed in order to simplify dispatching strategy so as to map projects to URLs. Project short name MUST be unique in the context of an environment.
- host mapping: the name of the (virtual) host used to access the Trac environment is taken to be the name of the project. A given host can be configured to be an alias for the default, top-level project. Label names are not allowed to be used this way.
 - prefix mapping: if the 
PATH_INFOstarts with/p/<project name>/prefix, name of a project will be taken to be<project_name>. Otherwise if it starts with/l/<label_name>/then the request is addressed to the set of projects included in label<label_name>. In general this is less ambiguous than the mapping suggested in original proposal. Explanation and implementation details provided below. 
The Data Model and the API
Labels may be considered as resources bound to the environment rather 
than to particular projects (e.g. like Changeset and Source which belong 
to a given repository - see MultiRepos). Hence only an 
additional labels table is also needed, and it can take the form of a 
resource table specialization from the GenericTrac. Project labels should 
have at least short name (and maybe description) field. Project labels can be 
linked explicitly to projects and labels (if using nested labels).
These connections can take the form of relations from 
Trac Relations.
I think it is vital that labels be first-class objects with history (like tickets, not milestones). Say I have a
.../l/Label1link somewhere in a wiki page or ticket description or something. Today Label1 points to ProjectA, ProjectB, and ProjectC but for whatever administrative reason, ProjectC gets reclassified or cancelled or something. I might click through my link and wonder where all the ProjectC stuff went. If labels have history, I can go look and see, "Oh, Bob cancelled Project C yesterday. He said, 'Customer Foo cancelled their order.'" — Chris Nelson, 4 Jan 2012
URL prefix mapping explained
Project-specific URLs will start with /p/<project name> prefix. 
Requests involving multiple projects will be made available on a per-label 
basis at URLs starting with /l/<label name> prefix. Remaining path after 
this will be used to select what instance of IRequestHandler should process 
the request. Examples below illustrate some use cases. In all cases  
multi-project environment root URL is http://server.com/path/to/trac/ and 
it will contain the reference project hierarchy used throughout this document :
| URL | Target projects | Comments | 
 http://server.com/path/to/trac/  |  top-level project (i.e. '' )  | |
 http://server.com/path/to/trac/roadmap  |  top-level project (i.e. '' )  | Top-level milestone view. This may be used to show top-level (e.g. product, current year, …) milestones. | 
 http://server.com/path/to/trac/p/FamilyB/roadmap  | project FamilyB | FamilyB project-specific milestones. | 
 http://server.com/path/to/trac/p/product_c/roadmap  | project product_c | product c project-specific milestones. | 
 http://server.com/path/to/trac/l/javascript/roadmap  | all projects in label javascript | display milestones for javascript projects. | 
By doing things this way request dispatch may be implemented as a combination of 
two existing architectural features , namely request filters and 
request handlers. First of all by supporting multi-project 
specifications the context associated to the request has to contain 
information about target project(s) . One component acting as a request filter  
intercepts the request before match is performed. If any multiproject 
prefix (i.e. /p/<project name> or /l/<label name>) is detected then 
project resolution takes place. Single-project requests only 
need to add corresponding internal project resource to context. 
In the case of labels the context should contain label name as well as a 
list of resources identifying target projects . In the case of 
more complex project selector expressions the context should contain the 
expression itself, the instance of IProjectLabelManager matching label name, 
and the list of resource objects identifying target projects . If this 
advanced feature will be supported, it may be considered as a generic way to 
encapsulate multi-project context in spite of having flexibility and uniformity, 
considering the fact that first two variants are just particular cases. 
Aforementioned data may be retrieved right away at dispatch time or loaded 
on demand.
Immediately after multi-project context resolution, the request filter rewrites 
PATH_INFO by removing project selection prefix. The request is then 
matched as usual so as to determine the handler responsible for processing it 
(e.g. wiki, ticket, …). The target instance of IRequestHandler will 
rely on request context so as to determine target projects involved and 
build the response accordingly.
Advanced labels features
Subsequent sub-sections deal with some advanced features that may be useful 
under certain circumstances but may also over-complicate core design . 
Nonetheless I mention them here for the sake of 
could not find the right word.
Project alias
A label related to a single project may be considered a project alias. This scenario may happen when two or more projects are merged and previous project name is to be kept so as not to break external references, for instance.
Nested labels
It might be convenient as well to provide a way to specify a hierarchy of 
labels (rather than projects). In order to illustrate this with a particular 
example which might be very common in practice, let's consider we have the 
sample hierarchy of projects 
and still need to 
group them according to programming languages and frameworks used to build 
them (let them be explicit project dependencies or not). In that case it will 
be useful to have some labels like javascript, python, c#, vb.net, 
f#, ruby, php and so on. Let's also consider a similar situation 
and project classification also includes frameworks, so there are further 
tags like e.g. trac, wcf, jquery, mootools, wpf, django, dojo, … 
Nonetheless :
- It may be useful to know which projects are related to .NET framework.
 - It may be useful to ease the process by tagging projects using a single label identifying a framework and having them auto-magically included in the label for the corresponding programming language .
 
In order to do that the following label hierarchy might help :
+-- python | +-- trac | +-- django +-- ruby +-- javascript | +-- jquery | +-- dojo | +-- mootools +-- .net | +-- .net languages | | +-- c# | | +-- vb.net | | +-- f# | +-- .net technologies | | +-- wpf | | +-- wcf | | +-- wwf +-- php
For instance , Trac-Hacks website may be one such 
example where there's a flat one-level project hierarchy and labels to group 
hacks. In Apendix B it is possible to see 
sample label hierarchy based on hack classifiers available at present. Idea
is , for instance, that if somebody tags a project using macro label then 
it also belongs auto-magically in plugins label. 
There's another precision that needs to be mentioned up to this point and it 
is whether it is more convenient to define label relationships using graphs 
rather than a tree . Considering the same case mentioned above , 
labels like iron_python , iron_ruby would be hard to 
classify considering aforementioned hierarchy as they may be related to both 
.net and (python | ruby) (same reasoning for e.g. jpype , jython for 
python & java; rython , unholy for python & ruby … and it's 
possible to find more examples even in totally different business domains).
Project context extensions
It may be useful to be able to specify special project groups like :
- all parents of project A
 - direct children of project B
 - descendant of project C
 *all the projects (mentioned in original Multi-Project specification)- glob pattern (mentioned in original Multi-Project specification)
 !prefix to exclude projects (mentioned in original Multi-Project specification)- comma-separated list of project names (e.g. 
FamilyA,product_d,3rdParty) - XPath expressions
 
These are just a few examples. In order to prepare the system for flexibilty 
and maybe allow the definition of other project selector expressions (e.g. in 
plugins) it is convenient to introduce a new interface 
(namely IProjectLabelManager) used to determine which projects belong in a 
given label, provided its name. Selection should work using a chain of 
responsibilty similar to the one already used for IRequestHandler. All 
instances of IProjectLabelManager are requested to expand a project selector 
expression. This will consist of returning a list of project names matching 
a given label name (aka project selector expression ⇐ this seems to be 
more generic ;) , or None if such match is not found. In the later case 
the next instance of IProjectLabelManager is considered and so on … until 
either a match is found (and subsequent request handling takes place) or all 
options are exhausted (and error handling occurs e.g. HTTP 404 Not Found 
returned to the client) . 
User interface
Considering everything mentioned up to this point , the following variants of project selector GUI control are suggested.
Project selector (drop-down menu)
The use of labels makes possible to present a flat drop-down menu to the user in order to select a set of projects like shown below. This may be considered more appropriate than always having to display a hierarchy.
PS: Create new label … option should be visible only if user can create labels. If the user can modify labels (i.e. classify projects in categories) then it may be useful to include shortcut links to update projects membership. In both cases a dialog (see picture below) should be displayed.
Project selector (tree view)
Another option is to provide a more ellaborate version of the box suggested in Multi-Project Support specification. One of the benefits is that it will be possible to select either projects or labels. It should look like this
Once label is selected then target projects should be highlighted like above.
Ideally it should be possible to drag a project & drop it on an item representing a label in order to add that project to that label (a confirmation box may be shown so as to detect mistakes).
Label membership editor dialog box may be displayed as well so as to edit a label if user clicks on Edit link.
Appendix A : Other systems supporting labels
Other similar examples of the use of labels in other products are :
- Google+ circles which allow to group people,
 - GMail contact groups which serve to a similar purpose
 - GMail labels which allow to mark e-mails
 
Other instances of similar label hierarchies :
- GMail nested labels.
 
Appendix B : Proposed label hierarchy for Trac-Hacks
This section considers just a subset of Trac-Hacks classifiers.
+-- supported-version | +-- 0.1 | +-- 0.10 | +-- 0.10.4 | +-- 0.11 | +-- 0.11.5 | +-- 0.11.6 | +-- 0.12 | +-- 0.12-compatible | +-- 0.12dev | +-- 0.13 | +-- 0.3.4 | +-- 0.4 | +-- 0.5 | +-- 0.5dev | +-- 0.8 | +-- 0.9 | +-- 0.9.1 | +-- 0.9.2 | +-- 0.9.6 | +-- 1.1dev | +-- trunk | +-- anyrelease +-- db | +-- sql | +-- sqlalchemy | +-- sqlite | | +-- sqlite3 | +-- postgresql | +-- mysql +-- plugin | +-- macro | +-- theme +-- scripts +-- patch +-- integration +-- translation +-- workflow


