Cross-References in Trac
Note: these ideas were once explored in an experimental branch (log:sandbox/trac-xref@2826), based on some old Trac 0.10dev version.
There is no plan to integrate this feature in Trac core. See also this mail.
As Trac is more than a wiki, its backlinks are of a more complex nature than traditional backlinks. Therefore the term cross-references will be used in favor of backlinks.
A cross-reference is a link from a Trac object (the source) to another Trac object (the target).
Usually, such links are created after processing some wiki text attached to the source object (a facet of that object).
Here's the current list of Trac objects that can reference each other, along with their facets:
- Wiki page (has the Cross-references navigation link)
- content facet (done)
- attachment comment facets (depends-on #787)
- Ticket (has the Cross-references navigation link)
- log message facet
title facet(see summary facet above)
- description facet
title facet(see summary facet above)
- description facet
- (no facet, only available as a target)
To check the status on cross-references, see the list of issues.
A cross-reference is also called a relation when an explicit semantic is attached to the link from the source object to the target object.
If there is no relation defined, one simply knows that the two objects are somehow related, like with traditional backlinks.
However, in the cross-references listing, for each backlink, Trac will also show an excerpt of the source Wiki text containing the link, so that the implicit semantic can be easily guessed.
Those relations can be used to fulfill many needs. The ticket dependencies and other ticket relationships are one example (see #886). The
tag feature, which could be reimplemented on top of relations, is another.
Each resource page has a navigation link Cross References, which leads to a page displaying the relations (Incoming and Outgoing) and the Backlinks:
Creating Explicit Relations with the User Interface
This should be the normal way to create explicit relations. For example, the ticket form could be extended to include a duplicate of field, activated when the resolution type is set to duplicate (see #1395). The content of that field would be a facet for the ticket and any reference found in the facet will create a specific duplicate-of relation, with the ticket as a source and the reference as a target.
Wiki Syntax for Explicit Relations
If one wants maximum flexibility, it can be convenient to use a specific wiki syntax for creating an explicit relation from the current object to any other Trac object.
I would propose using
<<the-relation LinkToTargetedObject>>, which can be nicely rendered in HTML as
Example, using the
tag relation (should it be
would relate the Trac object to which this wiki text belongs to the Wiki page named "xref", using the explicit relation
tag. This would
tag the current page with the
Multiple targets should be supported too:
<<tag xref, idea, #1242>>
Would tag this page with all those 3 objects.
In the above, I assume that unrecognized words should be taken as wiki page names, so that one can write
idea instead of
However, in a facet (like in the duplicate of example above), it might be convenient to add a description to the reference, like
this is quite similar to #123, and just a rewording of #431.
In that case, only recognized links should be taken as targets, of course.
Displaying Relations in the Wiki
Also, a few macros could be created to make a powerful usage of the relations:
Relations(rel)would provide a brief listing of Trac objects matching the
Closure(rel)would provide a brief listing of all Trac objects in the transitive closure of the specified relation.
Count(rel)would provide a count of the objects matching the
The relation description
rel could be written using a similar syntax to the one used for the wiki and described above.
The idea being that if there exists a relation
<<A relates-to B>>, then specifying:
<<A relates-to>>should result in
<<relates-to B>>should result in
Some concrete examples:
<<*rel* *tgt*>>would refer to the source objects related to the specified target object
*tgt*by the relation
<<tag xref>>all the objects having the
<<depends-on #123>>all the objects that depend on the ticket #123
- Special object patterns: "." and "%"
<<depends-on .>>all the objects that depend on the current object
<<depends-on>>same as above, "." is the target if none given
<<tag CS103/%>>all the objects having a tag which name starts with
<<*src* *rel*>>would refer to the target objects related to the specified source object
*src*by the relation
<<. tag>>would list all tags of the current object
<<% tag>>would list all tags of any object
<<. depends-on>>would list all the objects (usually tickets) on which the current object (usually a ticket) depends.
The xref branch currently contains an implementation of the cross-references, plus the infrastructure needed for the relations. That branch is kept in sync with all my other branches (TracDiff and InterTrac, which now both have been merged into trunk) and, as such, it is also quite in sync with the trunk.
- The original enhancement request ticket: #1242
- Backlink support: #611 and #646
- Relationship and ticket dependencies support: #31, #226 and #886
- Wiki Page renames: #1106
- Other relationships: #449, #508
It should be noted that this general mechanism could be used to reimplement a few things in Trac so that they become more general:
- the ticket keywords could be reimplemented by using the
tagrelation described above. Unifying keywords and tags would enable to attach them to any Trac Object (see #695). In addition, one could fill the keyword list by picking in a list of already existing keywords.
- the ticket components could be be reimplemented using a has-component relation, with the components being wiki pages. The advantage would be that a ticket could have multiple components (#1730), and that the component could be documented (#1233) and used in a meaningful way in other relationships (e.g. #548, #1678 and TracMultipleProjects/SingleEnvironment#UsingComponentobjects).
- idem for the versions, using a has-version relation.
Components would be Wiki pages created from a ComponentTemplate page, therefore having an is-a relationship to the above ComponentTemplate page.
This makes it simple to retrieve all components:
those are the
[[Relation(<<is-a ComponentTemplate>>)]] objects, or, in Python code,
components = WikiPage(self.env, 'ComponentTemplate').sources('is-a')
Of course, the ComponentTemplate is-a TemplateTemplate.
Q: This feature was cited in a Trac feature request comment as supporting automatic back-links in wiki pages, but this descriptions sounds like something different. Am I reading it wrong?
A: Well, the TracCrossReferences scope is much wider than simple back links, but nevertheless back links are implemented here. Look at the snapshot again.