[[PageOutline(2-5,Contents,pullout)]] = Cross-References in Trac {{{#!box info '''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 [googlegroups:trac-dev:a24e93656922487c 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) * ~~summary facet~~ (seems that it was never intended to support wiki formatting, see #1888) * description facet (done) * comments facets (done) * attachment comment facets (depends-on #787) * Changeset * log message facet * Report * ~~title facet~~ (see summary facet above) * description facet * Milestone * ~~title facet~~ (see summary facet above) * description facet * Source * (no facet, only available as a target) To check the status on cross-references, see the [kwquery:xref list of issues]. == Relations 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. == Displaying Cross-References Each resource page has a navigation link '''Cross References''', which leads to a page displaying the relations ('''Incoming''' and '''Outgoing''') and the '''Backlinks''': [[Image(trac-xref.png)]] === 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 `<>`, which can be nicely rendered in HTML as [[html(«the-relation)]]LinkToTargetedObject[[html(»)]]. Example, using the `tag` relation (should it be `has-tag`?): Writing {{{ <> }}} 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 `xref` tag. Multiple targets should be supported too: {{{ <> }}} Would tag this page with all those 3 objects. ''Undecided issue:'' [[BR]] 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 matching the `rel`. 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 `<>`, then specifying: * `<>` should result in `B` * `<>` should result in `A` Some concrete examples: * `<<*rel* *tgt*>>` would refer to the source objects related to the specified target object `*tgt*` by the relation `*rel*`. Examples: * `<>` all the objects having the `xref` tag * `<>` all the objects that depend on the ticket !#123 * Special object patterns: "." and "%" * `<>` all the objects that depend on the current object * `<>` same as above, "." is the target if none given * `<>` all the objects having a tag which name starts with `CS103` * `<<*src* *rel*>>` would refer to the target objects related to the specified source object `*src*` by the relation `*rel*`. Examples: * `<<. 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 [source:sandbox/trac-xref 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. 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 * Other relationships: #449, #508 === 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. 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(<>)]]` objects, or, in Python code, {{{#!python components = WikiPage(self.env, 'ComponentTemplate').sources('is-a') }}} Of course, the !ComponentTemplate ''is-a'' !TemplateTemplate. == Discussion === Backlinks? '''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.