e0db353cfefb9bde9cce31d6a2c2d2762dc1de4a kate Wed Sep 12 17:19:14 2018 -0700 IMplement fieldName> expansion in trackDb url setting. refs #22078 diff --git src/hg/hgc/hgc.c src/hg/hgc/hgc.c index 1307b9e..42c61c1 100644 --- src/hg/hgc/hgc.c +++ src/hg/hgc/hgc.c @@ -885,73 +885,76 @@ if (sameWord(urlSetting, "url")) url = tdb->url; else url = trackDbSetting(tdb, urlSetting); return url; } void printIframe(struct trackDb *tdb, char *itemName) /* print an iframe with the URL specified in trackDb (iframeUrl), can have * the standard codes in it (like $$ for itemName, etc) */ { char *url = getUrlSetting(tdb, "iframeUrl"); if (url==NULL) return; -char *eUrl = replaceInUrl(url, itemName, cart, database, seqName, winStart, winEnd, tdb->track, FALSE); +char *eUrl = replaceInUrl(url, itemName, cart, database, seqName, winStart, winEnd, + tdb->track, FALSE, NULL); if (eUrl==NULL) return; char *iframeOptions = trackDbSettingOrDefault(tdb, "iframeOptions", "width='100%%' height='1024'"); // Resizing requires the hgcDetails pages to include a bit of javascript. // // Explanation how this works and why the javascript is needed: // http://stackoverflow.com/questions/153152/resizing-an-iframe-based-on-content // In short: // - iframes have a fixed size in html, resizing can only be done in javascript // - the iframed page cannot call the resize() function in the hgc html directly, as they have // been loaded from different webservers // - one way around it is that the iframed page includes a helper page on our server and // send their size to the helper page (pages can call functions of included pages) // - the helper page then sends the size back to hgc (pages on the same server can // call each others' functions) // width='%s' height='%s' src='%s' seamless scrolling='%s' frameborder='%s' printf(" \ \ \ \
", eUrl, iframeOptions);
}
-void printCustomUrlWithLabel(struct trackDb *tdb, char *itemName, char *itemLabel, char *urlSetting, boolean encode)
+void printCustomUrlWithLabel(struct trackDb *tdb, char *itemName, char *itemLabel,
+ char *urlSetting, boolean encode, struct slPair *fields)
/* Print custom URL specified in trackDb settings. */
{
char urlLabelSetting[32];
// replace the $$ and other wildchards with the url given in tdb
char *url = getUrlSetting(tdb, urlSetting);
//char* eUrl = constructUrl(tdb, url, itemName, encode);
if (url==NULL || isEmpty(url))
return;
-char* eUrl = replaceInUrl(url, itemName, cart, database, seqName, winStart, winEnd, tdb->track, encode);
+char *eUrl = replaceInUrl(url, itemName, cart, database, seqName, winStart, winEnd, tdb->track,
+ encode, fields);
if (eUrl==NULL)
return;
/* create the url label setting for trackDb from the url
setting prefix */
safef(urlLabelSetting, sizeof(urlLabelSetting), "%sLabel", urlSetting);
char *linkLabel = trackDbSettingOrDefault(tdb, urlLabelSetting, "Outside Link:");
// if we got no item name from hgTracks or the item name does not appear in the URL
// there is no need to show the item name at all
if (isEmpty(itemName) || !stringIn("$$", url))
{
printf("%s
",eUrl, linkLabel);
return;
}
@@ -962,44 +965,58 @@
if (sameWord(tdb->table, "npredGene"))
{
printf("%s (%s)
\n", itemName, "NCBI MapView");
}
else
{
char *label = itemName;
if (isNotEmpty(itemLabel) && sameString(itemName, itemLabel))
label = itemLabel;
printf("%s
\n", label);
}
//freeMem(&eUrl); small memory leak
}
-void printCustomUrl(struct trackDb *tdb, char *itemName, boolean encode)
-/* Wrapper to call printCustomUrlWithLabel using the url setting in trackDb */
+void printCustomUrlWithFields(struct trackDb *tdb, char *itemName, char *itemLabel, boolean encode, struct slPair *fields)
+/* Wrapper to call printCustomUrlWithLabel with additional fields to substitute */
{
char urlSetting[10];
safef(urlSetting, sizeof(urlSetting), "url");
-printCustomUrlWithLabel(tdb, itemName, itemName, urlSetting, encode);
+printCustomUrlWithLabel(tdb, itemName, itemName, urlSetting, encode, fields);
+}
+
+void printCustomUrl(struct trackDb *tdb, char *itemName, boolean encode)
+/* Wrapper to call printCustomUrlWithLabel using the url setting in trackDb */
+{
+printCustomUrlWithFields(tdb, itemName, itemName, encode, NULL);
+}
+
+void printOtherCustomUrlWithFields(struct trackDb *tdb, char *itemName, char *urlSetting,
+ boolean encode, struct slPair *fields)
+/* Wrapper to call printCustomUrlWithLabel to use another url setting other than url in trackDb e.g. url2, this allows the use of multiple urls for a track
+ to be set in trackDb. */
+{
+printCustomUrlWithLabel(tdb, itemName, itemName, urlSetting, encode, fields);
}
void printOtherCustomUrl(struct trackDb *tdb, char *itemName, char* urlSetting, boolean encode)
/* Wrapper to call printCustomUrlWithLabel to use another url setting other than url in trackDb e.g. url2, this allows the use of multiple urls for a track
to be set in trackDb. */
{
-printCustomUrlWithLabel(tdb, itemName, itemName, urlSetting, encode);
+printCustomUrlWithLabel(tdb, itemName, itemName, urlSetting, encode, NULL);
}
void genericSampleClick(struct sqlConnection *conn, struct trackDb *tdb,
char *item, int start, int smpSize)
/* Handle click in generic sample (wiggle) track. */
{
char table[64];
boolean hasBin;
struct sample *smp;
char query[512];
struct sqlResult *sr;
char **row;
boolean firstTime = TRUE;
hFindSplitTable(database, seqName, tdb->table, table, &hasBin);
@@ -1432,31 +1449,31 @@
}
// a | character can optionally be used to separate the ID used for $$ from the name shown in the link (like in Wikimedia markup)
char *idForUrl = itemName;
boolean encode = TRUE;
if (strstr(itemName, "|"))
{
char *parts[2];
chopString(itemName, "|", parts, ArraySize(parts));
idForUrl = parts[0];
itemName = parts[1];
encode = FALSE; // assume the link is already encoded
}
char *idUrl = replaceInUrl(url, idForUrl, cart, database, seqName, winStart,
- winEnd, tdb->track, encode);
+ winEnd, tdb->track, encode, NULL);
printf("%s", idUrl, itemName);
}
printf("\n");
freeMem(slIds);
//freeMem(idNames);
}
int extraFieldsStart(struct trackDb *tdb, int fieldCount, struct asObject *as)
/* return the index of the first extra field */
{
int start = 0;
char *type = cloneString(tdb->type);
char *word = nextWord(&type);
if (word && (sameWord(word,"bed") || sameWord(word,"bigBed") || sameWord(word,"bigGenePred") || sameWord(word,"bigPsl") || sameWord(word,"bigBarChart")))
{
@@ -1488,30 +1505,56 @@
{
struct slPair *slp;
AllocVar(slp);
char *fieldName = col->name;
char *fieldVal = fields[count];
slp->name = fieldName;
slp->val = fieldVal;
slAddHead(&extraFields, slp);
count++;
//printf("name %s, val %s, idx %d
", fieldName, fieldVal, count);
}
slReverse(extraFields);
return extraFields;
}
+struct slPair *getFields(struct trackDb *tdb, char **row)
+/* return field names and their values as a list of slPairs. */
+// TODO: refactor with getExtraFields
+{
+struct asObject *as = asForDb(tdb, database);
+if (as == NULL)
+ return NULL;
+int fieldCount = slCount(as->columnList);
+struct slPair *fields = NULL;
+struct asColumn *col = as->columnList;
+int count = 0;
+for (count = 0; col != NULL && count < fieldCount; col = col->next)
+ {
+ struct slPair *field;
+ AllocVar(field);
+ char *fieldName = col->name;
+ char *fieldVal = row[count];
+ field->name = fieldName;
+ field->val = fieldVal;
+ slAddHead(&fields, field);
+ count++;
+ }
+slReverse(fields);
+return fields;
+}
+
int extraFieldsPrint(struct trackDb *tdb,struct sqlResult *sr,char **fields,int fieldCount)
// Any extra bed or bigBed fields (defined in as and occurring after N in bed N + types.
// sr may be null for bigBeds.
// Returns number of extra fields actually printed.
{
struct asObject *as = asForDb(tdb, database);
if (as == NULL)
return 0;
// We are trying to print extra fields so we need to figure out how many fields to skip
int start = extraFieldsStart(tdb, fieldCount, as);
struct asColumn *col = as->columnList;
char *urlsStr = trackDbSettingClosestToHomeOrDefault(tdb, "urls", NULL);
struct hash* fieldToUrl = hashFromString(urlsStr);
@@ -4064,42 +4107,44 @@
type = words[0];
if (sameString(type, "maf") || sameString(type, "wigMaf") || sameString(type, "bigMaf") || sameString(type, "netAlign")
|| sameString(type, "encodePeak"))
headerItem = NULL;
else if (( sameString(type, "narrowPeak")
|| sameString(type, "broadPeak")
|| sameString(type, "gappedPeak") )
&& headerItem
&& sameString(headerItem, ".") )
headerItem = NULL;
}
/* Print header. */
genericHeader(tdb, headerItem);
+if (differentString(type, "bigInteract") && differentString(type, "interact"))
+ {
+ // skip generic URL code as these may have multiple items returned for a click
itemForUrl = getIdInUrl(tdb, item);
if (itemForUrl != NULL && trackDbSetting(tdb, "url"))
{
printCustomUrl(tdb, itemForUrl, item == itemForUrl);
printIframe(tdb, itemForUrl);
}
-
+ }
if (plus != NULL)
{
fputs(plus, stdout);
}
-
if (container != NULL)
{
genericContainerClick(conn, container, tdb, item, itemForUrl);
}
else if (wordCount > 0)
{
type = words[0];
if (sameString(type, "bed"))
{
int num = 0;
if (wordCount > 1)
num = atoi(words[1]);
if (num < 3) num = 3;
genericBedClick(conn, tdb, item, start, num);
}
@@ -4118,32 +4163,31 @@
}
else if (sameString(type, "sample"))
{
int num = 9;
genericSampleClick(conn, tdb, item, start, num);
}
else if (sameString(type, "genePred"))
{
char *pepTable = NULL, *mrnaTable = NULL;
if ((wordCount > 1) && !sameString(words[1], "."))
pepTable = words[1];
if ((wordCount > 2) && !sameString(words[2], "."))
mrnaTable = words[2];
genericGenePredClick(conn, tdb, item, start, pepTable, mrnaTable);
}
- else if ( sameString(type, "bigPsl"))
- {
+ else if ( sameString(type, "bigPsl")) {
genericBigPslClick(conn, tdb, item, start, end);
}
else if (sameString(type, "psl"))
{
char *subType = ".";
if (wordCount > 1)
subType = words[1];
genericPslClick(conn, tdb, item, start, subType);
}
else if (sameString(type, "netAlign"))
{
if (wordCount < 3)
errAbort("Missing field in netAlign track type field");
genericNetClick(conn, tdb, item, start, words[1], words[2]);
}
@@ -11957,31 +12001,31 @@
{
if (!dbToLabel)
errAbort("can not find trackDb dbPrefixLabels to correspond with dbPrefixUrls\n");
char *databasePrefix = cloneString(database);
while (strlen(databasePrefix) && isdigit(lastChar(databasePrefix)))
trimLastChar(databasePrefix);
struct hashEl *hel = hashLookup(dbToUrl, databasePrefix);
if (hel)
{
struct hashEl *label = hashLookup(dbToLabel, databasePrefix);
if (!label)
errAbort("missing trackDb dbPrefixLabels for database prefix: '%s'\n", databasePrefix);
char *url = (char *)hel->val;
char *labelStr = (char *)label->val;
char *idUrl = replaceInUrl(url, nrl->externalId, cart, database,
- nrl->externalId, winStart, winEnd, tdb->track, TRUE);
+ nrl->externalId, winStart, winEnd, tdb->track, TRUE, NULL);
printf("%s: ", labelStr);
printf("%s
\n",
idUrl, nrl->externalId);
}
}
}
}
if (differentWord(nrl->locusLinkId, ""))
{
printf("Entrez Gene: ");
printf("",
nrl->locusLinkId);
printf("%s
\n", nrl->locusLinkId);
}
@@ -24980,31 +25024,31 @@
bed = bedLoadN(row+hasBin, 12);
int lastBlk = bed->blockCount - 1;
int endForUrl = (bed->chromStart + bed->chromStarts[lastBlk] +
bed->blockSizes[lastBlk]);
char *endFudge = trackDbSetting(tdb, "endFudge");
if (endFudge && !strstr(bed->name, "OEA"))
endForUrl += atoi(endFudge);
char sampleName[16];
safecpy(sampleName, sizeof(sampleName),
tdb->table + strlen(KIDD_EICHLER_DISC_PREFIX));
touppers(sampleName);
char itemPlus[2048];
safef(itemPlus, sizeof(itemPlus),
"%s&o=%d&t=%d&g=%s_discordant&%s_discordant=full",
cgiEncode(item), start, endForUrl, sampleName, sampleName);
- printCustomUrlWithLabel(tdb, itemPlus, item, "url", FALSE);
+ printCustomUrlWithLabel(tdb, itemPlus, item, "url", FALSE, NULL);
printKiddEichlerNcbiLinks(tdb, bed->name);
printf("Score: %d
\n", bed->score);
printPosOnChrom(bed->chrom, bed->chromStart, bed->chromEnd, bed->strand,
TRUE, bed->name);
}
sqlFreeResult(&sr);
printTrackHtml(tdb);
}
void doBedDetail(struct trackDb *tdb, struct customTrack *ct, char *itemName)
/* generate the detail page for a custom track of bedDetail type */
{
char *table;
struct bedDetail *r = NULL;
struct sqlConnection *conn;