Getting Started with Exhibit

From SIMILE Widgets
Jump to: navigation, search


Contents

Ready, Set, Go!

You need a text editor. Any good old text editor would do, even Notepad on Windows or TextEdit on MacOS. If you want a more sophisticated text editor, check out our recommended tools.

We assume you know a little bit of HTML. Don't worry: most of this tutorial involves copying and pasting code that we provide. The whole HTML file is available at the end in case you make a mistake and can't figure out what has gone wrong.

Your First Exhibit

Start up your text editor and copy and paste this code into it.

 <html>
 <head>
    <title>MIT Nobel Prize Winners</title>
  
    <link href="nobelists.js" type="application/json" rel="exhibit/data" />
  
    <script src="http://api.simile-widgets.org/exhibit/2.2.0/exhibit-api.js"
            type="text/javascript"></script>

    <style>
    </style>
 </head> 
 <body>
    <h1>MIT Nobel Prize Winners</h1>
    <table width="100%">
        <tr valign="top">
            <td ex:role="viewPanel">
                <div ex:role="view"></div>
            </td>
            <td width="25%">
                browsing controls here...
            </td>
        </tr>
    </table>
 </body>
 </html>

Name that file something like nobelists.html.

Next, download this data file to the same directory as the HTML file (and make sure it's named nobelists.js). The previous link fails for some users; you may download substantially the same file from here as well.

Finally, go to the directory where you saved those 2 files (using Explorer on Windows or Finder on Mac) and drag nobelists.html into your web browser.

That's it! You should now see a web page that shows 63 people's names and information. Not too exciting yet but this is just the beginning. You might note that the page says "63 Nobelist" instead of "63 Nobelists"—we'll fix that later on.

Supporting Filtering and Sorting

Filtering

If you look at each person's information, you see several fields such as "discipline" (the field in which they won their Nobel prize), "relationship" (how they are/were related to MIT), "shared" (whether they received their prize alone or shared it with others), etc. These fields are useful for filtering and sorting this data set.

Find within the HTML code (nobelists.html) the text "browsing controls here..." and replace it with

 <div ex:role="facet" ex:expression=".discipline" ex:facetLabel="Discipline"></div>
 <div ex:role="facet" ex:expression=".relationship" ex:facetLabel="Relationship"></div>
 <div ex:role="facet" ex:expression=".shared" ex:facetLabel="Shared?"></div>
 <div ex:role="facet" ex:expression=".deceased" ex:facetLabel="Deceased?"></div>

Save the file, switch back to your browser, and reload the nobelists.html file. You should now see several boxes on the right side labeled "Discipline", "Relationship", "Shared?", and "Deceased?". These boxes are called facets—different angles or aspects of the data set by which you can analyze the data set.

Notice the gray numbers in front of the values inside these facets. The number "2" in front of "Peace" inside the "discipline" facet tells you that there are 2 people who received the Peace prize. Click on "Peace" and the page will now show only those 2 people (rather than 63 people originally).

By adding those div elements as shown above, you have implemented the filtering feature in about 10 seconds. (If you have ever done server-side programming, you might want to think of how much time it would have taken you to implement filtering using whatever server-side publishing frameworks you're familiar with.)

Searching

You can also add text search to your exhibit by adding a facet of type TextSearch:

 <div ex:role="facet" ex:facetClass="TextSearch"></div>

That's it. As you type into the search text box, the exhibit gets filtered.

Sorting

You can already change the sorting order of the nobelists by clicking on "labels" after "sorted by". But if you want to set a specific sorting order at the beginning, you can change <div ex:role="view"></div> to:

 <div ex:role="view" ex:orders=".discipline, .nobel-year"></div>

You can also restrict the properties by which your users can sort by using the ex:possibleOrders attribute:

 <div ex:role="view"
       ex:orders=".discipline, .nobel-year"
       ex:possibleOrders=".label, .last-name, .discipline, .relationship, .shared, .deceased, .nobel-year">
 </div>

Inspecting the Data File

So far, you have only touched 2 files: an .html file and a .js file. One specifies the presentation of the web page and the other stores the data.

Open up the file nobelists.js in your text editor and take a look at it. It's written in the JSON format (but the syntax is a bit more relaxed). There is an array of items (you can think of them as database records). Each item looks like this:

   {   type :                  "Nobelist",
       label :                 "Horst L. St\u00F6rmer",
       discipline :            "Physics",
       shared :                "yes",
       "last-name" :           "St\u00F6rmer",
       "nobel-year" :          "1998",
       relationship :          "research",
       "co-winner" :           [
           "Robert B. Laughlin",
           "Daniel C. Tsui"
       ],
       "relationship-detail" : "MIT researcher at MIT Magnet Lab",
       imageURL :              "http ://people.csail.mit.edu/dfhuynh/projects/nobelists/images/horst-l-stormer.png"
   },

That's basically a bunch of properties and property values. For example, the property shared has the value "yes". Horst L. Störmer won his Nobel prizes with two other people, and so the property co-winner has 2 values, which are encoded as elements of an array. That just means you list the values between [ and ], separated by commas.

Properties whose names contain non-alphanumeric characters (e.g., - in last-name) must be surrounded by double or single quotes. But if you don't like to quote property names, you can use a different naming convention (e.g., imageURL instead of "image-url").

Each item must have a label property value. (There are exceptions but this is for 99% of the cases.) The type property value specifies the type of the item; otherwise, the item's type defaults to Item.

Aside from these few restrictions, you can put pretty much anything into your data file.

How Does Exhibit Work?

The file nobelists.html has a reference to the Javascript file exhibit-api.js. That's how you include Exhibit. Here's roughly what happens when the web page is loaded:

  • The code of exhibit-api.js is loaded and it automatically pulls in some more code.
  • A lightweight database is created and the data files are loaded into it.
  • An Exhibit object is created. It reads the various ex: attributes in the HTML code to configure its user interface. It then reads data out of the lightweight database and construct its user interface

The most important thing to remember is that everything happens inside the web browser. The user's web browser loads the entire data set and performs all computation (sorting, filtering, etc.) locally, which provides much of the power of the Exhibit approach. In contrast, on other web sites that support sorting and filtering, most of the computations happen on the web servers.

Note that so far in this tutorial, you have not had to install, configure, or manage any database or to write a single line of server-side script (in PHP, ASP, JSP, CGI, etc.). And throughout the rest of this tutorial, you still won't have to do any such thing. Skeptical? Let's continue.

Lenses

Right now the information of each Nobelist is displayed in a table of property/value. That's generic and ugly. We can do better.

Insert this table inside the div element with the id exhibit-view-panel (either before or after the inner div element that is already there):

   <table ex:role="lens" class="nobelist">
       <tr>
           <td><img ex:src-content=".imageURL" /></td>
           <td>
               <div ex:content=".label" class="name"></div>
               <div>
                   <span ex:content=".discipline" class="discipline"></span>, 
                   <span ex:content=".nobel-year" class="year"></span>
               </div>
               <div ex:if-exists=".co-winner" class="co-winners">Co-winners: 
                   <span ex:content=".co-winner"></span>
               </div>
               <div ex:content=".relationship-detail" class="relationship"></div>
           </td>
       </tr>
   </table>

Then, find the style element in the HTML code and change it as follows:

   <style>
       body {
           margin: 1in;
       }
       table.nobelist {
           border:     1px solid #ddd;
           padding:    0.5em;
       }
       div.name {
           font-weight: bold;
           font-size:   120%;
       }
       .discipline {
       }
       .year {
           font-style:  italic;
       }
       .relationship {
           color:  #888;
       }
       .co-winners {
       }
   </style>

Save and reload in the browser. The Nobelists should now be presented in a more custom manner.

What you have just done is specifying a lens template and some CSS styles. The lens template is used to generate the rendition of each Nobelist. In the lens template, the ex:content attribute values specify what properties to stuff into the corresponding HTML elements. For example,

 <div ex:content=".label" class="name"></div>

causes a div element to be generated and stuffed with the label property value of the Nobelist (whose rendition is being generated). In addition to generating text, we can also generate images by including an img element and specifying its src attribute value to be generated, say, from the imageURL property value:

 <img ex:src-content=".imageURL" />

To generate any attribute value, simply prepend its name with ex: and append -content.

Note that some Nobelists have co-winners recorded in the data file, but not all. (We only have information about co-winners who are also related to MIT.) We use the ex:if-exists attribute value to include a part of the template conditionally:

   <div ex:if-exists=".co-winner" class="co-winners">Co-winners: 
       <span ex:content=".co-winner"></span>
   </div>

If we did not use ex:if-exists, then we would have gotten a lot of "Co-winners:" without anything to follow.

Schema

Properties

Filter the "discipline" facet to only "Physics", "relationship" to only "research", and "shared" to "yes". You should get 5 Nobelists.

Note that the fourth Nobelist, Horst L. Störmer, shared his prize with two others: Robert B. Laughlin and Daniel C. Tsui. You can readily see Daniel C. Tsui right after Störmer, but you can't see Laughlin as he is not a researcher and has been filtered out.

However, Laughlin does appear in the rendition of Störmer, so it would be nice to be able to click on Laughlin's name and get some information about him right there and then. We can do this by adding some schema to our data, to say that co-winner property values, such as "Robert B. Laughlin", actually mean items. Open the file nobelists.js and modify the beginning so that it looks like this:

   {
       properties: {
           "co-winner" : {
               valueType: "item"
           }
       },
       "items" : [
           {   type :                  "Nobelist",
               label :                 "Burton Richter",
               discipline :            "Physics",
               shared :                "yes",
   
   
   ...the rest of the file...

Now, open up another browser window (or tab) and drag the file nobelists.js into it and make sure that the latest version is displayed. If not, hit the browser's Refresh button. Once that's done, switch to the browser window displaying that HTML file and refresh it. Select the same filters as above. You should now see that Robert B. Laughlin's name appears in blue and is underlined. Click on it.

Types

Notice that the number of Nobelists shown on the page is ungrammatical, e.g., "5 Nobelist" instead of "5 Nobelists". Modify the beginning of the file nobelists.js as follows:

   {
       types: {
           "Nobelist" : {
               pluralLabel: "Nobelists"
           }
       },
       properties: {
           "co-winner" : {
               valueType: "item"
           }
       },
   
   ...the rest of the file...

Switch to the browser window displaying the .js file and refresh it. Then switch to the window displaying the .html file and refresh it to see the change.

The key point of this step is that the web page can look and behave better not just by fine-tuning the HTML code but also by improving the data.

Timeline View

Since we have the years when the Nobelists won their prizes, we can plot them on a time line. Exhibit itself doesn't implement time lines and it has to include the Timeline widget. Since the Timeline widget is bulky, Exhibit doesn't include it by default. You have to include the time extension to Exhibit. Open the file nobelists.html, find the reference to exhibit-api.js and add the following script element after it:

 <script src="http://api.simile-widgets.org/exhibit/2.2.0/extensions/time/time-extension.js"
     type="text/javascript"></script>

Then add this view before the view that's already there:

 <div ex:role="view"
     ex:viewClass="Timeline"
     ex:start=".nobel-year"
     ex:colorKey=".discipline">
 </div>

Save and reload in the browser. That's it! If you want the timeline and tile views to be stacked up, rather then shown as tabs, remove the ex:role="viewPanel" attribute to a simple td above the "lens" table.

 <td ex:role="viewPanel">

The ex:start attribute value in the code you just inserted specifies which property to use as the starting date/time, and the ex:colorKey attribute value specifies which property to use to color-code the markers on the time line.

Tabular View

While we're at it, let's make a tabular view. Insert the following code just like you did for creating the time line view:

 <div ex:role="exhibit-view"
     ex:viewClass="Exhibit.TabularView"
     ex:columns=".label, .imageURL, .discipline, .nobel-year, .relationship-detail"
     ex:columnLabels="name, photo, discipline, year, relationship with MIT"
     ex:columnFormats="list, image, list, list, list"
     ex:sortColumn="3"
     ex:sortAscending="false">
 </div>

Save and reload in the browser. Then click on "Table". Take a moment to read the code you just inserted; it should be relatively comprehensible. Of note is the ex:columnFormats attribute value, which is used to make sure that the photos are displayed as images rather than as URLs. You should restore the ex:role="viewPanel" attribute to the td above the "lens" table to show the view options as tabs, since the tile and table views are quite similar.

Final HTML Code

Here is the whole HTML file:

<html>
<head>
   <title>MIT Nobel Prize Winners</title>
 
   <link href="nobelists.js" type="application/json" rel="exhibit/data" />
 
   <script src="http://api.simile-widgets.org/exhibit/2.2.0/exhibit-api.js"
           type="text/javascript"></script>
           
   <script src="http://api.simile-widgets.org/exhibit/2.2.0/extensions/time/time-extension.js"
           type="text/javascript"></script>
           
   <style>
       body {
           margin: 1in;
       }
       table.nobelist {
           border:     1px solid #ddd;
           padding:    0.5em;
       }
       div.name {
           font-weight: bold;
           font-size:   120%;
       }
       .discipline {
       }
       .year {
           font-style:  italic;
       }
       .relationship {
           color:  #888;
       }
       .co-winners {
       }
   </style>
</head> 
<body>
   <h1>MIT Nobel Prize Winners</h1>
   <table width="100%">
       <tr valign="top">
           <td ex:role="viewPanel">
               <table ex:role="lens" class="nobelist">
                   <tr>
                       <td><img ex:src-content=".imageURL" /></td>
                       <td>
                           <div ex:content=".label" class="name"></div>
                           <div>
                               <span ex:content=".discipline" class="discipline"></span>, 
                               <span ex:content=".nobel-year" class="year"></span>
                           </div>
                           <div ex:if-exists=".co-winner" class="co-winners">Co-winners: 
                               <span ex:content=".co-winner"></span>
                           </div>
                           <div ex:content=".relationship-detail" class="relationship"></div>
                       </td>
                   </tr>
               </table>
               <div ex:role="exhibit-view"
                   ex:viewClass="Exhibit.TabularView"
                   ex:columns=".label, .imageURL, .discipline, .nobel-year, .relationship-detail"
                   ex:columnLabels="name, photo, discipline, year, relationship with MIT"
                   ex:columnFormats="list, image, list, list, list"
                   ex:sortColumn="3"
                   ex:sortAscending="false">
               </div>
              <div ex:role="view"
                   ex:viewClass="Timeline"
                   ex:start=".nobel-year"
                   ex:colorKey=".discipline">
               </div>
               <div ex:role="view"
                   ex:orders=".discipline, .nobel-year"
                   ex:possibleOrders=".label, .last-name, .discipline, .relationship, .shared, .deceased, .nobel-year">
               </div>
            </td>
           <td width="25%">
               <div ex:role="facet" ex:facetClass="TextSearch"></div>
               <div ex:role="facet" ex:expression=".discipline" ex:facetLabel="Discipline"></div>
               <div ex:role="facet" ex:expression=".relationship" ex:facetLabel="Relationship"></div>
               <div ex:role="facet" ex:expression=".shared" ex:facetLabel="Shared?"></div>
               <div ex:role="facet" ex:expression=".deceased" ex:facetLabel="Deceased?"></div>
           </td>
       </tr>
   </table>
</body>
</html>

Summary

This tutorial shows you how to start making an exhibit by creating two files: an HTML file and a JSON file. Then, by adding more code to the HTML file or the JSON file, you make the exhibit web page look and behave better—supporting filtering and sorting, providing more views, presenting items in custom ways, etc. All of this can be done without ever touching a web server or a database.

(Note that while you're waiting for us to fill in the documentation, just copy our existing Examples_of_Simile_Widgets to kick-start your own exhibits.)

Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox