e0db353cfefb9bde9cce31d6a2c2d2762dc1de4a
kate
  Wed Sep 12 17:19:14 2018 -0700
IMplement fieldName> expansion in trackDb url setting. refs #22078

diff --git src/hg/lib/hui.c src/hg/lib/hui.c
index a346b9d..3924704 100644
--- src/hg/lib/hui.c
+++ src/hg/lib/hui.c
@@ -8996,33 +8996,33 @@
 
 dyStringAppend(s, orig);
 for (i=0; i<subCount; ++i)
     {
     fflush(stdout);
     if (out[i]==NULL)
         continue;
     d = dyStringSub(s->string, in[i], out[i]);
     dyStringFree(&s);
     s = d;
     d = NULL;
     }
 return s;
 }
 
-char *replaceInUrl(char *url, char *idInUrl, struct cart* cart, char *db, char *seqName, int winStart, \
-    int winEnd, char *track, boolean encode) 
-/* replace $$ in url with idInUrl. Supports many other wildchards 
+char *replaceInUrl(char *url, char *idInUrl, struct cart *cart, char *db, char *seqName, 
+                        int winStart, int winEnd, char *track, boolean encode, struct slPair *fields) 
+/* replace $$ in url with idInUrl. Supports many other wildchards, and custom fields $<field>
  * XX Do we have readable docs for these parameters somewhere?
  * Look at http://genome.ucsc.edu/goldenpath/help/trackDb/trackDbHub.html */
 {
 struct dyString *uUrl = NULL;
 struct dyString *eUrl = NULL;
 char startString[64], endString[64];
 char *ins[13], *outs[13];
 char *eItem = (encode ? cgiEncode(idInUrl) : cloneString(idInUrl));
 
 char *scName = NULL;
 // try to avoid the mysql query it not necessary
 if (stringIn("$n", url))
     {
     char *tmp = hScientificName(db);
     scName = replaceChars(tmp, " ", "_");
@@ -9093,50 +9093,69 @@
     outs[10] = endString;
     }
 
 ins[11] = "$n";
 outs[11] = scName;
 
 ins[12] = "$taxId";
 outs[12] = taxId;
 
 uUrl = subMulti(url, ArraySize(ins), ins, outs);
 outs[0] = eItem;
 eUrl = subMulti(url, ArraySize(ins), ins, outs);
 freeDyString(&uUrl);
 freeMem(eItem);
 freeMem(scName);
+
+// substitute $<fieldName> variables
+if (!fields)
     return eUrl->string;
+
+int fieldCount = slCount(fields);
+char **fieldNames = NULL, **fieldVals = NULL;
+AllocArray(fieldNames, fieldCount);
+AllocArray(fieldVals, fieldCount);
+int i;
+struct slPair *field;
+for (i=0, field=fields; i<fieldCount; i++, field=field->next)
+    {
+    char buf[64];
+    safef(buf, sizeof buf, "$<%s>", field->name);
+    fieldNames[i] = cloneString(buf);
+    fieldVals[i] = (char *)field->val;
+    }
+struct dyString *fUrl = subMulti(eUrl->string, fieldCount, fieldNames, fieldVals);
+    return fUrl->string;
 }
 
 char *checkDataVersion(char *database, struct trackDb *tdb)
 /* see if trackDb has a dataVersion setting and check that file for version */
 {
 // try the metadata
 metadataForTable(database, tdb, NULL);
 char *version = (char *)metadataFindValue(tdb, "dataVersion");
 
 // try trackDb itself, this automatically will go up the hierarchy
 if (version == NULL)
     version = trackDbSetting(tdb, "dataVersion");
 
 if (version != NULL)
     {
     // dataVersion can also be the path to a local file, for otto tracks
     if (!trackHubDatabase(database) && !isHubTrack(tdb->table) && startsWith("/", version))
         {
-        char *path = replaceInUrl(version, "", NULL, database, "", 0, 0, tdb->track, FALSE);
+        char *path = replaceInUrl(version, "", NULL, database, "", 0, 0, tdb->track, FALSE, NULL);
         struct lineFile* lf = lineFileMayOpen(path, TRUE);
         if (lf)
             version = lineFileReadAll(lf);
         else
             version = NULL;
         lineFileClose(&lf);
         }
     }
 return version;
 }
 
 void printDataVersion(char *database, struct trackDb *tdb)
 /* If this annotation has a dataVersion setting, print it.
  * check hgFixed.trackVersion, meta data and trackDb 'dataVersion'. */
 {