d156aaa50bbe78b0c05da8cde9cd837d88d659fc
chmalee
  Wed Aug 19 12:03:49 2020 -0700
hgc and hgTrackUi can query a 'relatedTrack' table to print a list of related tracks to the one being looked at along with a reason for the relation, refs #25721

diff --git src/hg/hgTrackUi/hgTrackUi.c src/hg/hgTrackUi/hgTrackUi.c
index de8a88c..1a409fd 100644
--- src/hg/hgTrackUi/hgTrackUi.c
+++ src/hg/hgTrackUi/hgTrackUi.c
@@ -3188,41 +3188,45 @@
 char setting[128];
 
 // NOTE: Currently only composite multi-view tracks because
 // reset relies upon all cart vars following naming convention:
 //   {track}.{varName}...  ( One exception supported: {track}_sel ).
 
 if (trackDbLocalSetting(tdb, "container"))
     {
     /* For the moment, be a composite... */
     tdbMarkAsComposite(tdb);
     }
 if (ajax && cartOptionalString(cart, "descriptionOnly"))
     {
     //struct trackDb *tdbParent = tdbFillInAncestry(cartString(cart, "db"),tdb);
     if (tdb->html != NULL && tdb->html[0] != 0)
+        {
+        printRelatedTracks(database,trackHash,tdb,cart);
         puts(tdb->html);
+        }
     else
         {
         struct trackDb *tdbParent = tdb->parent;
         for (;tdbParent && (tdbParent->html == NULL || tdbParent->html[0] == 0);
               tdbParent = tdbParent->parent )
             ; // Get the first parent that has html
         if (tdbParent != NULL && tdbParent->html != NULL && tdbParent->html[0])
             {
             printf("<h2 style='color:%s'>Retrieved from %s Track...</h2>\n",
                    COLOR_DARKGREEN,tdbParent->shortLabel);
+            printRelatedTracks(database,trackHash,tdb,cart);
             puts(tdbParent->html);
             }
         else
             printf("<h2>No description found for: %s.</h2>",tdbParent?tdbParent->track:tdb->track);
         }
     cartRemove(cart,"descriptionOnly"); // This is a once only request and should be deleted
     return;
     }
 if (tdbIsContainer(tdb))
     {
     safef(setting,sizeof(setting),"%s.%s",tdb->track,RESET_TO_DEFAULTS);
     // NOTE: if you want track vis to not be reset, move to after vis dropdown
     if (1 == cartUsualInt(cart, setting, 0))
         cartRemoveAllForTdbAndChildren(cart,tdb);
     else if (!ajax) // Overkill on !ajax, because ajax shouldn't be called for a composite
@@ -3461,30 +3465,31 @@
     cgiMakeHiddenVar(CT_SELECTED_TABLE_VAR, tdb->track);
     puts("</FORM>\n");
     if (ct->bbiFile)
 	{
 	time_t timep = bbiUpdateTime(ct->bbiFile);
 	printBbiUpdateTime(&timep);
 	}
     else
         printUpdateTime(CUSTOM_TRASH, ct->tdb, ct);
     }
 
 if (!ct)
     {
     /* Print data version setting, if any */
     cgiDown(0.7);
+    printRelatedTracks(database,trackHash,tdb,cart);
     printDataVersion(database, tdb);
 
     /* Print lift information from trackDb, if any */
     trackDbPrintOrigAssembly(tdb, database);
 
     printUpdateTime(database, tdb, NULL);
     }
 
 if (tdb->html != NULL && tdb->html[0] != 0)
     {
     char *browserVersion;
     if (btIE == cgiClientBrowser(&browserVersion, NULL, NULL) && *browserVersion < '8')
         htmlHorizontalLine();
     else // Move line down, since <H2>Description (in ->html) is proceded by too much space
         printf("<HR ALIGN='bottom' style='position:relative; top:1em;'>");