5bec29ddc58c05e2609f5c2409c93ce301e541fd
angie
  Tue May 19 10:11:35 2020 -0700
VCF details: replace hardcoded URLs for ExAC and gnomAD tracks with enhanced substitution variable support so urls can be specified by trackDb.  refs #25595
vcfClick.c still has custom code for ExAC and gnomAD url labels in case the item ID is ".".
trackDb now has alpha and beta,public stanzas for ExAC and GnomAD variants tracks because
the new url setting is not correctly transformed with the current code release on beta/RR.
The url settings have an extra "&ignore=$$" because of some logic in printCustomUrlWithLabel
that suppresses the item name from being used as label if $$ is not included in the url
setting.  I don't agree with that logic, but adding "&ignore=$$" is an easy workaround that
does not break the exac/gnomad website.

diff --git src/hg/hgc/vcfClick.c src/hg/hgc/vcfClick.c
index d5f2435..f272dcc 100644
--- src/hg/hgc/vcfClick.c
+++ src/hg/hgc/vcfClick.c
@@ -452,60 +452,58 @@
 	dyStringPrintf(dy, "(%c)", leftBase);
     abbreviateLongSeq(rec->alleles[i], endLength, showLength, dy);
     if (encodeHtml)
 	displayAls[i] = htmlEncode(dy->string);
     else
 	displayAls[i] = cloneString(dy->string);
     }
 }
 
 static void vcfRecordDetails(struct trackDb *tdb, struct vcfRecord *rec)
 /* Display the contents of a single line of VCF, assumed to be from seqName
  * (using seqName instead of rec->chrom because rec->chrom might lack "chr"). */
 {
 if (isNotEmpty(rec->name) && differentString(rec->name, "."))
     printf("<B>Name:</B> %s<BR>\n", rec->name);
-if (sameString(tdb->track, "exacVariants"))
-    {
-    printf("<b>ExAC:</b> "
-           "<a href=\"http://exac.broadinstitute.org/variant/%s-%d-%s-%s\" "
-           "target=_blank>%s:%d %s/%s</a><br>\n",
-           skipChr(rec->chrom), rec->chromStart+1, rec->alleles[0], rec->alleles[1],
-           skipChr(rec->chrom), rec->chromStart+1, rec->alleles[0], rec->alleles[1]);
-    }
-if (sameString(tdb->track, "gnomadGenomesVariants") || sameString(tdb->track, "gnomadExomesVariants"))
-    {
-    printf("<b>gnomAD:</b> "
-           "<a href=\"http://gnomad.broadinstitute.org/variant/%s-%d-%s-%s\" "
-           "target=_blank>%s:%d %s/%s</a><br>\n",
-           skipChr(rec->chrom), rec->chromStart+1, rec->alleles[0], rec->alleles[1],
-           skipChr(rec->chrom), rec->chromStart+1, rec->alleles[0], rec->alleles[1]);
-    }
+// Add some special URL substitution variables for ExAC/GnomAD-style links
+struct slPair *substFields = slPairNew("ref", rec->alleles[0]);
+substFields->next = slPairNew("firstAlt", rec->alleles[1]);
+char posString[64];
+safef(posString, sizeof posString, "%d", rec->chromStart+1);
+substFields->next->next = slPairNew("pos", posString);
+char *label = rec->name;
+if ((isEmpty(rec->name) || sameString(rec->name, ".")) &&
+    (startsWith("exac", tdb->track) || startsWith("gnomad", tdb->track)))
+    {
+    struct dyString *dyLabel = dyStringCreate("%s-%s-%s-%s", skipChr(rec->chrom), posString,
+                                              rec->alleles[0], rec->alleles[1]);
+    label = dyStringCannibalize(&dyLabel);
+    }
+printCustomUrlWithFields(tdb, rec->name, label, TRUE, substFields);
 // Since these are variants, if it looks like a dbSNP or dbVar ID, provide a link:
 if (regexMatch(rec->name, "^rs[0-9]+$"))
     {
     printf("<B>dbSNP:</B> ");
     printDbSnpRsUrl(rec->name, "%s", rec->name);
     puts("<BR>");
     }
 else if (regexMatch(rec->name, "^[en]ss?v[0-9]+$"))
     {
     printf("<B>dbVar:</B> ");
     printf("<A HREF=\"https://www.ncbi.nlm.nih.gov/dbvar/variants/%s/\" "
 	   "TARGET=_BLANK>%s</A><BR>\n", rec->name, rec->name);
     }
-printCustomUrl(tdb, rec->name, TRUE);
 boolean hapClustEnabled = cartOrTdbBoolean(cart, tdb, VCF_HAP_ENABLED_VAR, TRUE);
 if (hapClustEnabled && rec->file != NULL && rec->file->genotypeCount > 1)
     {
     char *hapMethod = cartOrTdbString(cart, tdb, VCF_HAP_METHOD_VAR, VCF_DEFAULT_HAP_METHOD);
     char *hapOrSample = vcfHaplotypeOrSample(cart);
     if (sameString(hapMethod, VCF_HAP_METHOD_CENTER_WEIGHTED))
         {
         static char *formName = "vcfCfgHapCenter";
         printf("<FORM NAME=\"%s\" ACTION=\"%s\">\n", formName, hgTracksName());
         cartSaveSession(cart);
         printf("<TABLE cellpadding=0><TR><TD colspan=2>"
                "<B>%s sorting order:</B> ", hapOrSample);
         vcfCfgHaplotypeCenter(cart, tdb, tdb->track, FALSE, rec->file, rec->name,
                               seqName, rec->chromStart, formName);
         printf("</TABLE></FORM>\n");