3a7b96f45d10bd58419c89a43fbd1ccf8e0b88da
markd
  Thu May 10 18:09:50 2012 -0700
Added facility (itemDetailsHtml) for having a table containing HTML fragments to display on generic BED, genePred, and PSL tables. This provides an easy way for mirror sites to create specialized details pages without modifying the C code.
diff --git src/hg/hgc/hgc.c src/hg/hgc/hgc.c
index de4f670..4dcccbf 100644
--- src/hg/hgc/hgc.c
+++ src/hg/hgc/hgc.c
@@ -223,30 +223,31 @@
 #include "atomDb.h"
 #include "pcrResult.h"
 #include "twoBit.h"
 #include "itemConf.h"
 #include "chromInfo.h"
 #include "gbWarn.h"
 #include "lsSnpPdbChimera.h"
 #include "mammalPsg.h"
 #include "net.h"
 #include "jsHelper.h"
 #include "virusClick.h"
 #include "gwasCatalog.h"
 #include "parClick.h"
 #include "mdb.h"
 #include "yaleGencodeAssoc.h"
+#include "itemDetailsHtml.h"
 
 static char *rootDir = "hgcData";
 
 #define LINESIZE 70  /* size of lines in comp seq feature */
 
 struct cart *cart;	/* User's settings. */
 char *seqName;		/* Name of sequence we're working on. */
 int winStart, winEnd;   /* Bounds of sequence. */
 char *database;		/* Name of mySQL database. */
 char *organism;		/* Colloquial name of organism. */
 char *genome;		/* common name, e.g. Mouse, Human */
 char *scientificName;	/* Scientific name of organism. */
 
 struct hash *trackHash;	/* A hash of all tracks - trackDb valued */
 
@@ -593,30 +594,31 @@
 /* obtain and parse the CDS, errAbort if not found or invalid */
 {
 char query[256];
 safef(query, sizeof(query), "select cds.name from gbCdnaInfo,cds where (acc=\"%s\") and (cds.id=cds)",
       acc);
 
 char *cdsStr = sqlQuickString(conn, query);
 if (cdsStr == NULL)
     errAbort("no CDS found for %s", acc);
 struct genbankCds cds;
 if (!genbankCdsParse(cdsStr, &cds))
     errAbort("can't parse CDS for %s: %s", acc, cdsStr);
 return cds;
 }
 
+
 void printCappedSequence(int start, int end, int extra)
 /* Print DNA from start to end including extra at either end.
  * Capitalize bits from start to end. */
 {
 struct dnaSeq *seq;
 int s, e, i;
 struct cfm *cfm;
 
 if (!clipToChrom(&start, &end))
     return;
 s = start - extra;
 e = end + extra;
 clipToChrom(&s, &e);
 
 printf("<P>Here is the sequence around this feature: bases %d to %d of %s. "
@@ -883,30 +885,47 @@
 {
 int i;
 struct dyString *s = newDyString(256), *d = NULL;
 
 dyStringAppend(s, orig);
 for (i=0; i<subCount; ++i)
     {
     d = dyStringSub(s->string, in[i], out[i]);
     dyStringFree(&s);
     s = d;
     d = NULL;
     }
 return s;
 }
 
+void printItemDetailsHtml(struct trackDb *tdb, char *itemName)
+/* if track has an itemDetailsHtml, retrieve and print the HTML */
+{
+char *tableName = trackDbSetting(tdb, "itemDetailsHtmlTable");
+if (tableName != NULL)
+    {
+    struct sqlConnection *conn = hAllocConn(database);
+    struct itemDetailsHtml *html, *htmls
+        = sqlQueryObjs(conn, (sqlLoadFunc)itemDetailsHtmlLoad, sqlQueryMulti,
+                       "select name, html from %s where name = '%s'", tableName, itemName);
+    for (html = htmls; html != NULL; html = html->next)
+        printf("<br>\n%s\n", html->html);
+    itemDetailsHtmlFreeList(&htmls);
+    hFreeConn(&conn);
+    }
+}
+
 char *getIdInUrl(struct trackDb *tdb, char *itemName)
 /* If we have an idInUrlSql tag, look up itemName in that, else just
  * return itemName. */
 {
 char *sql = trackDbSetting(tdb, "idInUrlSql");
 char *id = itemName;
 if (sql != NULL)
     {
     char buf[256];
     safef(buf, sizeof(buf), sql, itemName);
     struct sqlConnection *conn = hAllocConn(database);
     id = sqlQuickString(conn, buf);
     hFreeConn(&conn);
     }
 return id;
@@ -1541,30 +1560,31 @@
 	{
 	interactionPrintPos( bed, bedSize, tdb);
 	}
     else
 	bedPrintPos(bed, bedSize, tdb);
 
     extraFieldsPrint(tdb,sr,row,sqlCountColumns(sr));
     // check for seq1 and seq2 in columns 7+8 (eg, pairedTagAlign)
     char *setting = trackDbSetting(tdb, BASE_COLOR_USE_SEQUENCE);
     if (bedSize == 6 && setting && sameString(setting, "seq1Seq2"))
 	printf("<br><B>Sequence 1:</B> %s<br><B>Sequence 2:</B> %s<br>\n",row[hasBin+6], row[hasBin+7]);
     printCompareGenomeLinks(tdb,bed->name);
     }
 sqlFreeResult(&sr);
 getBedTopScorers(conn, tdb, table, item, start, bedSize);
+printItemDetailsHtml(tdb, item);
 }
 
 #define INTRON 10
 #define CODINGA 11
 #define CODINGB 12
 #define UTR5 13
 #define UTR3 14
 #define STARTCODON 15
 #define STOPCODON 16
 #define SPLICESITE 17
 #define NONCONSPLICE 18
 #define INFRAMESTOP 19
 #define INTERGENIC 20
 #define REGULATORY 21
 #define LABEL 22
@@ -2763,30 +2783,31 @@
     struct sqlResult *sr = sqlGetResult(conn, query);
     char **row;
     while ((row = sqlNextRow(sr)) != NULL)
         {
 	struct kg1ToKg2 *x = kg1ToKg2Load(row);
 	printf("<B>Old ID:</B> %s<BR>\n", x->oldId);
 	printf("<B>New ID:</B> %s<BR>\n", naForEmpty(x->newId));
 	printf("<B>Old/New Mapping:</B> %s<BR>\n", x->status);
 	if (x->note[0] != 0)
 	    printf("<B>Notes:</B> %s<BR>\n", x->note);
 	printf("<BR>\n");
 	}
     sqlFreeResult(&sr);
     }
 geneShowCommon(item, tdb, pepTable);
+printItemDetailsHtml(tdb, item);
 }
 
 void pslDumpHtml(struct psl *pslList)
 /* print out psl header and data */
 {
 struct psl* psl;
 printf("<PRE><TT>\n");
 printf("#match\tmisMatches\trepMatches\tnCount\tqNumInsert\tqBaseInsert\ttNumInsert\tBaseInsert\tstrand\tqName\tqSize\tqStart\tqEnd\ttName\ttSize\ttStart\ttEnd\tblockCount\tblockSizes\tqStarts\ttStarts\n");
 for (psl = pslList; psl != NULL; psl = psl->next)
     {
     pslTabOut(psl, stdout);
     }
 printf("</TT></PRE>\n");
 }
 
@@ -2801,30 +2822,31 @@
  * set it up so they can click through to the alignment. */
 if (hGenBankHaveSeq(database, item, NULL))
     {
     printf("<H3>%s/Genomic Alignments</H3>", item);
     if (sameString("protein", subType))
         printAlignments(pslList, start, "htcProteinAli", tdb->table, item);
     else
         printAlignments(pslList, start, "htcCdnaAli", tdb->table, item);
     }
 else
     {
     /* just dump the psls */
     pslDumpHtml(pslList);
     }
 pslFreeList(&pslList);
+printItemDetailsHtml(tdb, item);
 }
 
 
 static char *getParentTableName(struct trackDb *tdb)
 /* Get the track table or composite track parent table if applicable. */
 {
 tdb = trackDbTopLevelSelfOrParent(tdb);
 return tdb->table;
 }
 
 static char *getParentTrackName(struct trackDb *tdb)
 /* Get the track name or composite track parent name if applicable. */
 {
 tdb = trackDbTopLevelSelfOrParent(tdb);
 return tdb->track;