Edgewall Software
Home
Trac
Trac Hacks
Genshi
Babel
Bitten
Home
Download
Documentation
Mailing Lists
License
FAQ
Search:
Login
Preferences
Help/Guide
About Trac
Wiki
Timeline
Roadmap
Browse Source
View Tickets
New Ticket
Search
Context Navigation
-1
Start Page
Index
History
Editing TracDev/Proposals/ProjectLabels
Adjust edit area height:
8
12
16
20
24
28
32
36
40
Edit side-by-side
= Project classifiers (aka labels) = #Introduction Consider merging this page with [wiki:TracDev/Proposals/MultipleProject 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 [wiki:TracDev/Proposals/MultipleProject#ProjectTree 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 [#SpecialLabels below]) . This document also suggests alternatives and approaches to implement some features defined in [wiki:TracDev/Proposals/MultipleProject Multi-Project Support for Trac]. Some content may actually overlap aforementioned specification. == URL space for different projects == #UrlMapping A constraint should be imposed in order to simplify dispatching strategy so as to map projects to ''URL''s. 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_INFO` starts 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 [wiki:TracDev/Proposals/MultipleProject#URLspacefordifferentprojects mapping suggested in original proposal]. Explanation and implementation details provided [#UrlExplained below]. == The Data Model and the API == #DataModelApi 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 [#NestedLabels nested labels]). These connections can take the form of ''relations'' from [wiki:TracDev/Proposals/TracRelations Trac Relations]. I think it is vital that labels be first-class objects with history (like tickets, not milestones). Say I have a `.../l/Label1` link 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 === #UrlExplained Project-specific URLs will start with `/p/<project name>` prefix. Requests involving multiple projects will be made available on a per-label basis at ''URL''s 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 [#SpecialLabels 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 == #LabelsAdvanced 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 === #LabelAlias 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 === #NestedLabels 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 [wiki:TracDev/Proposals/MultipleProject#ProjectTree 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 , [http://trac-hacks.org Trac-Hacks] website may be one such example where there's a flat one-level project hierarchy and labels to group hacks. In [#TracHacksLabels 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 === #SpecialLabels 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 [wiki:TracDev/Proposals/MultipleProject#URLspacefordifferentprojects original Multi-Project specification]) - glob pattern (mentioned in [wiki:TracDev/Proposals/MultipleProject#URLspacefordifferentprojects original Multi-Project specification]) - `!` prefix to exclude projects (mentioned in [wiki:TracDev/Proposals/MultipleProject#URLspacefordifferentprojects 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 == #LabelsGUI Considering everything mentioned up to this point , the following variants of project selector GUI control are suggested. === Project selector (drop-down menu) === #LabelsMenu 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. {{{ #!html <select id="SampleProjectMenu" name="field_milestone"> <option></option> <optgroup label="Projects"> <option>Top-level</option> <option>Family A</option> <option> product a</option> <option> product b</option> <option>Family B</option> <option> product c</option> <option> product d</option> <option>Tools</option> <option>3rdParty</option> </optgroup> <optgroup label="Labels"> <option>Product families</option> <option selected="true">Products</option> <option><i>Create new label ...</i></option> </optgroup> </select> }}} '''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. {{{ #!html <div id="SampleLabelsEditor" style="width:50%;margin-left:auto;margin-right:auto;background-color:#666666;"> <div style="background-color:#666666;color:#ffffff;">Create new label</div> <div style="background-color:#ffffff;padding:15px;"> <label for="label_id">Label ID :</label> <input type="text" id="label_id"></input> <br/> <label for="label_name">Label name :</label> <input type="text" id="label_name"></input> <br/> <fieldset style="display: inline;clear:both;"> <legend>Select projects</legend> <form> <ul style="list-style-type: none"> <li> <input type="checkbox">Top-level</input> <ul style="list-style-type: none"> <li> <input type="checkbox" checked="checked"><b>Family A</b></input> <ul style="list-style-type: none"> <li><input type="checkbox">product a</input></li> <li><input type="checkbox">product b</input></li> </ul> </li> <li> <input type="checkbox" checked="checked"><b>Family B</b></input> <ul style="list-style-type: none"> <li ><input type="checkbox">product c</input></li> <li><input type="checkbox">product d</input></li> </ul> </li> <li><input type="checkbox">Tools</input></li> <li><input type="checkbox">3rdParty</input></li> </ul> </li> </ul> </form> </fieldset> <br/> <button>Ok</button> <button>Cancel</button> </div> </div> }}} === Project selector (tree view) === #LabelsTreeView Another option is to provide a more ellaborate version of the box suggested in [wiki:TracDev/Proposals/MultipleProject 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 {{{ #!html <fieldset style="display: inline" id="SampleProjectTreeView"> <legend>Project Selector</legend> <form> <ul style="list-style-type: none"> <li> <input type="checkbox">Top-level</input> <ul style="list-style-type: none"> <li> <input type="checkbox"><b style="background-color: #ffffcc;border:1px dashed #999999;">Family A</b></input> <ul style="list-style-type: none"> <li><input type="checkbox">product a</input></li> <li><input type="checkbox">product b</input></li> </ul> </li> <li> <input type="checkbox"><b style="background-color: #ffffcc;border:1px dashed #999999;">Family B</b></input> <ul style="list-style-type: none"> <li ><input type="checkbox">product c</input></li> <li><input type="checkbox">product d</input></li> </ul> </li> <li><input type="checkbox">Tools</input></li> <li><input type="checkbox">3rdParty</input></li> </ul> </li> </ul> <ul style="list-style-type: none"> <li style="background-color: #999999; color: #ffffff"> <input type="checkbox" checked="checked"><b>Product families</b><a href="#SampleProjectTreeView" style="font-size:11px;margin-left:3px;">Edit</a></input> </li> <li style="background-color: #CCCCCC"> <input type="checkbox">Products<a href="#SampleProjectTreeView" style="font-size:11px;margin-left:3px;">Edit</a></input> </li> <li style="background-color: #999999; color: #ffffff"> <input type="checkbox"><b>All except product b</b><a href="#SampleProjectTreeView" style="font-size:11px;margin-left:3px;">Edit</a></input> </li> <li> <button>New label ...</button> </li> </ul> </form> </fieldset> }}} 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 == #SimilarSystems Other similar examples of the use of labels in other products are : - [http://support.google.com/plus/bin/answer.py?hl=en&answer=1047805&topic=1257347&ctx=topic 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 == #TracHacksLabels This section considers just a subset of [http://trac-hacks.org 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 }}}
Note:
See
WikiFormatting
and
TracWiki
for help on editing wiki content.
Change information
Your email or username:
E-mail address and name can be saved in the
Preferences
Comment about this change (optional):
Note:
See
TracWiki
for help on using the wiki.