Edgewall Software

Version 5 (modified by Christian Boos, 19 years ago) ( diff )

Much more details about the relations and some current status info

Cross-References in Trac

As Trac is a little bit more than a Wiki, its backlinks are a little bit more powerful than traditional backlinks…

Therefore we will rather talk about cross-references.

A cross-reference is a link from a Trac object (the source) to another Trac object (the destination).

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
  • Ticket (has the Cross-references navigation link)
    • summary facet (seems that it was never intended to support wiki formatting, see #1888)
    • description facet (done)
    • comments facets (done)
    • attachment comment facets
    • (more to come…)
  • Changeset
    • log message facet
  • Report
    • title facet
    • description facet
  • Milestone
    • title facet
    • description facet
  • Source
    • (no facet, only available as a target)

Relations

A cross-reference is also called a relation when an explicit semantic is attached to the link from the source object to the destination object.

If there's 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 (see the TagIt macro), which could be reimplemented on top of relations, is another.

Creating Explicit Relations with the UI

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. 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 <<...>>, which can be nicely rendered in HTML by «...».

Example, with the tag relation: Writing

<<tag xref>>

would relate the Trac object to which this wiki text belongs to the Wiki page named "xref", using the explicit relation tag (i.e. this would tag the current page with the xref tag).

Multiple targets should be supported too:

<<tag xref, idea, #1242>>

Would tag this page with the all those 3 objects

Undecided issue:
In the above, I assume that unrecognized words should be taken as wiki page names, so that one can write idea instead of IdeaTag or wiki:idea. 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 rel
  • 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 matchin the rel

The relation description rel can be using a similar syntax to the wiki one:

  • <<*rel* ...>> would refer to the source objects related to the specified target by relation *rel*
    • <<tag xref>> all the objects having the xref tag
    • <<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 CS103
  • <<... *rel*>> would refer to the target objects related to the specified source by relation *rel*
    • <<. 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.

Implementation Notes

The xref branch currently contains an implementation for it. It's kept in sync with all my other branches (TracDiff and InterTrac) and, as such, is also kept in sync with the trunk on a regular basis.

See also:

  • The original enhancement request ticket: #1242
  • Backlink support: #611 and #646
  • Relationship and ticket dependencies support: #31, #226 and #886
  • Wiki Page renames: #1106

Refactoring Ideas

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 tag relation 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 (1). The advantage would be that a ticket could have multiple components, and that the component could be documented 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

(1)
… 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…

Attachments (1)

Download all attachments as: .zip

Note: See TracWiki for help on using the wiki.