Using Wibbit

Warning: this page describes an earlier version of wibit that drew its data from tables in a page. The current extension at [1] is a semantic mediawiki extension that draws its data using semantic mediawiki queries.

This is an extension to the Mediawiki package (you know, the thing you're using right now to view this page!) to allow you to embed Exhibits in a wiki page. Best of all, you can use data directly from tables right there in that page and others across the wiki. First you will need to make sure the wiki has the extension installed (See Installing Wibbit, for how to install it). Then, you will edit the pages that you want to put the exhibits in using the special syntax explained below.

Tables as Data

Exhibit is a way to display and deal with data. A standalone exhibit uses json files hosted along with the page the exhibit is on. Wibbit, in contrast, uses tables in wikis. The advantage of this is that anyone can edit the tables, so the data can be both edited and expanded easily and collaboratively. Also, visitors without Javascript have some access to the structured data.

The data, in turn, is composed of items, each of which has properties. For a fuller description of exhibit's data model, see its own wiki page. Here we will just explain the tabular wiki aspect of it.

Each item is represented by a row in the table. Each property of that item is a column. A page can have multiple tables which Exhibit can draw from, but any given table can only be used for one item type. So perhaps you could have an exhibit about historical literature. It might make sense to have one table for all the books with information like when it was published, who the author was, how many pages it has, etc. Then you could have another table for the authors, which would include information like when and where they were born and when and where they died, all the books they've written, and so on.

In order for exhibit to find the tables you want to use on the page you will have to give each an "id" to which you can refer to it. So the top of the 'authors' table might look like:

 {| id="authors"
  |-
  !Name
  

or something like that.

All other schema data relating to authors and books is taken care of in the <source> tag of the exhibit, which is covered below.

Wiki Syntax for Exhibits

Adding an exhibit to a wiki is very straightforward! The syntax is composed of nested tags, very reminiscent of XML.

To begin, create the root pair of Exhibit tags: <exhibit> and </exhibit>.

Every exhibit needs a data source. You can indicate this inside <source> tags. You can draw data from most tables anywhere in the wiki. Each table gets its own source tags. So to create a very simple wiki from a table right there in the page, this is all you need to do:

 <exhibit>
   <source id="Presidents" />
 </exhibit>

Notice the "Presidents" id. This id tells exhibit to draw data from the table in your wiki page with the attribute id="Presidents".

And that's all there is to it! Of course, it's possible to highly configure your exhibit, so for that read on below.

Tag Syntax

The Exhibit Extension for Mediawiki had tags and attributes that you can use for additional specifications, beyond simply the source of your data. If you are not familiar with HTML/XML, tags and attributes are entered like this:

  <tag attribute="value"></tag>

or

  <tag attribute="value" />

Source

As mentioned above, you use the <source> tag to indicate from which table you would like to extract your data. You always need the id attribute, but there are also more attributes that enable additional configuration options.

The first attribute you can add is hideTable. By default, when an exhibit is created, its respective table becomes hidden. However, if you want it to be displayed, set the hideTable attribute to be false:

  <source id="Presidents" hideTable="false" />

Source Columns

Another attribute that you can include is the columns attribute. This attribute specifies names for the properties assigned by each column, in the same way that a column header specifies the property of each row under it. If you have a table that looks like:

First Name Class Year Hometown
Margaret 2010 Irvington, NY

you want your source tag to look like this:

  <source id="People" columns="label,classyear,hometown" />

This is attribute is usually necessary if you have more than one data source. Let's say you wanted to add two more data table to the one shown above. They look like this:

First Name Class Year Hometown
Gabe 2007 Cayucos, CA
First Name Favorite OS Favorite Number
Margaret Mac OS X 9
Gabe Mac OS X 37

Even though these tables all have different formats, you can still merge their data! All you have to do is use the columns attribute.

 <source id="More People" columns="label,classyear,hometown" />
 <source id="People Info" columns="label,favos,favnum" />

As long as you include a label column, the data will merge.

Note: By default, the column property names are set to be under-case, one-word versions of your table headers. So the header "First Name" would have the property name "firstname." If you read below, you will see how you use these names to access your data inside exhibit configuration specifications. The columns attribute is here in case you want to rename these names. However, notice the label name. It is crucial that you have a column named label, otherwise Exhibit will not know what your items are called!

Source Types and Labels

Within the columns attribute, you can specify data types for the different properties specified by each column. This is especially useful for numbers, which are sorted differently than plain text. Just add :[type] to any columns property to include a type. Following the example above, you would type:

 <source id="People Info" columns="label,favos,favnum:number" />

You can also use a type attribute specify a type for the entire data set included in your source tag. Doing this will create a "type" property for each item in the data set. Once again, following the example from above you would do this by typing:

 <source id="People" type="person" />

You can also specify the labels that Exhibit will use when displaying your data. You can assign item types a label, as well as a plural label (used when displaying multiple items). Just type label and pluralLabel attributes like this:

 <source id="People" type="person" label="Person" pluralLabel="People" />

View

The <view> tag allows you to specify different ways to view your data. There are many views, and each have many attributes for different configuration options. You will always need a viewClass attribute within the view tag, but beyond that, every view class has it's own attributes.

 <view viewClass="Tabular" />

Tabular View

This Tabular view lets you display your exhibit in a nice table. Here is an example tabular view configuration tag:

 <view viewClass="Tabular" 
     label="Table" 
     columns=".label, .role, .classyear, .hometown" 
     columnLabels="Name, Role, Class Year, Hometown"
     sortAscending="false" 
     />

You'll notice several different attributes, mostly self explanatory. label refers to the title that you'll want the visitors to see. columns refer to the properties of the exhibit that you want to show up in the generated table. Each property gets its own column. The properties are referenced by a period and then their names. For more information about what these are see the source section above. columnLabels are the nice human-readable headings in the table. Lastly, the default table sorts the first column in an ascending manner. To change this sort to descending, you can set the sortAscending to false. You can always change the sort on the table once it appears by clicking on the headings.

Map View

The map view allows you to place your data on a Google map. Here is an example map view configuration tag:

 <view viewClass="Map" 
       label="Map" 
       latlng=".latlng"
       icon=".photo"
       shapeWidth="50"
       shapeHeight="50"
       iconScale="0.5"
       colorKey=".party"
       colorCoder="party-colors"
       />

The label attribute is the human readable name of this view, which will appear at the top. latlong tells the exhibit from which property to get the latitude and longitude coordinates in order to place the items on the map. In order to determine the name of the property your data will have, check the source section above.

icon, shapeWidth, shapeHeight, and iconScale, all serve to specify what sort of marker appears at the proper points on the map. Without any of them, just a generic bubble will appear. If, for instance, you want each marker to have a unique picture in it associated with the item, do something like in the example, which refers to a photo property of each item which has a url with a picture.

Alternatively to specifying custom icons, or in addition to if some items lack a custom photo, you can specify a color coder. This allows you to color your items based on a property. For instance, if many of your items have a politicalparty property, then you could color the Republicans red and the Democrats blue. The colorKey attribute specifies which property to look in, and the colorCoder refers to the id of a Color Coder you specified elsewhere. For more information, see the color coder section below.

Timeline View

The timeline view allows you to create a timeline with your data. Here is an example timeline view configuration:

 <view viewClass="Timeline"
       label="Terms"
       proxy=".presidency"
       start=".inDate"
       end=".outDate"
       colorKey=".party"
       colorCoder="party-colors"
       />

The proxy attribute is where you specify which property you want you want to display on your timeline, and the start and end attributes let you indicate when you want your time blocks to start and end. If you want, you only need to indicate a start property, and a point will be plotted on the timeline at that point.

For information on how to create a color coder, check out the Coder section of this page.

Tile and Thumbnail View

The tile view is the default view for Exhibit if you do not specify a view, but it can create great displays with the help of a lens. The thumbnail view is configured in a similar manner. Here is an example thumbnail view configuration:

 <view viewClass="Thumbnail"
       label="Photos"
       orders=".party"
       possibleOrders=".religion, .party, .birth, .death, .term"
       />

The orders attribute determines the order in which your items are displayed, and the possibleOrders attribute creates options at the top of the Exhibit for users to choose an order for themselves.

Facet

The <facet> tag allows you to enable faceted browsing inside your exhibit.

The expression attribute creates a facet that browses through all the values of a certain property in your exhibit. The value of this attribute needs to be the name of a property in your exhibit. If you don't know what this is, look above in the source tag and columns attribute section of this article.

  <facet expression=".birthday" />

Note: The name of the property needs to be preceded by "." for exhibit to interpret it. See The power of . and ! for more details.

The facetClass attribute creates different types of facets for your exhibit. The most common use of this attribute is to create a text search box for your exhibit.

  <facet facetClass="TextSearch" />

The position attribute gives you the power to choose where you want your facet to be positioned on the page. Choose from "top," "bottom," "left," and "right." If you omit this attribute, the default is right.

 <facet position="top" />

Lens

You can use lenses in a wiki-based exhibit, just like an ordinary one. To specify a lens, use the <lens> tag.

Then, within the <lens> tags, just specify a lens like you normally would, with divs, spans, ex:if attributes, and so on. You can't add event handlers or script tags, though.

For those unfamiliar with exhibits, lenses are very powerful. They work in Tile View and Thumbnail View. What happens is as exhibit is rendering each item in its database, it gives that item to the lens, which renders it as you like. You can access all of that items properties using . notation. So, as you are designing your lens, think of a typical item in your exhibit, and design the lens with that in mind. Then when Exhibit displays all the items, each item will display just as that one you had in mind.

Here is an example lens:

 <lens>
    <div ex:role="lens" style="display:none">
      <table>
        <tr>
          <th>President</th><th>Party</th>
        </tr>
        <tr>
          <td><span ex:content=".president"></span></td>
          <td><span ex:content=".party"></span></td>
        </tr>
      </table>
    </div>
  </lens>

Now keep in mind, that you look through this lens at every item that's going to get displayed. So, .president will mean something different each time. One time you might get something like this:

President Party
Bill Clinton Democrat

Feel free to make the lens as complicated as you want. You can specify background colors, and images, and links, and so on. Rememebr, if you want the exhibit data to pop in, use an ex:content=".whatever" attribute of the thing you want it to show up in.

If you want the exhibit data to show up in the attribute, you can do that too. Simply take the attribute you want filled in, put 'ex:' in front of it and '-content=".blah"' after it. So, if you want the href attribute of a link filled in with some link you have in the data, that can be done with something like the following:

 <a ex:href-content=".exhibitlink">Click here!</a>

You can go even further, though. Suppose you want just part of the attribute to get filled in. For that you use -subcontent instead of -content, and indicate where you want it filled in with {{ }}. If you've chosen to display each president, say, in a table, and you want a unique id for each table (e.g. id="prez-table-clinton"), you can do something like the following:

 <table ex:id-subcontent="prez-table-{{.president}}">

Conditionals

But let's not stop just yet. You can put conditional expressions in there as well. If you don't want some part of the DOM tree to show up if you don't have any exhibit data for it. You can use ex:if-exists=".someproperty" in the div or table or whatever is at the top of the tree. For instance, consider:

 
  <div ex:if-exists=".party">
    <span ex:content=".president"></span> belonged to the 
    <span ex:content=".party"></span> Party.
  </div>
  

The result will be something that says "Clinton belonged to the Democratic Party", if the president item has a field for party. If it doesn't, nothing will show up at all.

It is also possible to have an "else" to the conditional. Look at:

 
  <div ex:if(exists(.party))>
    <div id="1">
    </div>
    <div id="2">
    </div>
  </div>
  

If party exists this time, then what will show up will be the 1st div block, otherwise the second one. Note, that the id is not necessary. I just put it there to clearly distinguish that there were two blocks within the conditional div.

The power of . and !

It is possible in lenses to access more than just simple fields of items. If those fields are themselves items, you can use the dot notation further. You can also use ! to go the other way.

Suppose you have an exhibit with counties and states. Maybe one table is of states and different properties. A snippet of it might look like this:

State Population Land Area (sq. miles)
Massachusetts 6349097 10555

Also, a separate table might be of counties. Again, a snippet of it:

County Population Founded Year County Of
Middlesex 1465396 1643 Massachusetts

Now notice that the county table has a column "county-of" which points to a state. This semantically connects Middlesex county to the state of Massachusetts.

Now if we were looking at the Middlesex item through a lens, we could access its state with .countyof. But what if we were looking through the lens at the Massachusetts item? How do we get at the fact that Middlesex is in the state of Massachusetts? The answer is with the "!" operator. !countyof looks through the database for things that say the current item's label in their countyof property. We see that Middlesex is one such item. So, consider looking through a lens at the Massachusetts item with the following bit in it:

 
  <div>I, as a state, contain the following counties:
    <span ex:content="!countyof.label"></span>
  </div>
  

The first thing it sees is !countyof. So what exhibit does is take the label of the item being looked at through the lens, say "Massachusetts", and then look for items that have a "countyof" property that says "Massachusetts". Once it finds these items, in this case the "Middlesex" county will be one such item, it looks for the property "label", which in this case is "Middlesex". Notice that prior to getting the "label" property, what you had was the item, and not the text.

So the result of all this is something like:

  <span>Middlesex</span>

What if there were multiple counties in our table that pointed to Massachusetts? In that case !countyof will return the whole slew of them, !countyof.label will return all of the labels, and the result will be something like this:

 <span>Middlesex, Essex, Suffolk, and Worcester</span>

But we can deal with this bunch of items more powerfully than listing them all out. That's the next section.

Sets of Items

In the course of getting at properties through a lens, you may end up with a set of items. In the previous section this occurred when we used !countyof. Or, perhaps we're using a lens on a book item and do .author, and there are multiple authors.

In any case, when we have a set of items there are two paths we can take.

If the ex:content=".author" that retrieves this set is just a span or div or something all by its lonesome, exhibit will do its best to fill it in with each item. It'll do this by separating them with commas, and an "and" before the last one. So

 <span ex:content=".author"></span>

will yield

 <span>Bob, Jane, Joe, and Mary</span>

However, if each author is itself an item (if you had a table of authors as well as books), then you might want to do something else with it. Suppose each author had an age you wanted to appear in the lens.

If the span or div that pulls out the set of items has children elements (maybe more spans and divs and links or whatever), then it will give those children elements to each of the items in the set. It's almost like a little baby lens that you look at each item in the set through. So, if you had this in the lens:

 <div ex:content=".author">
    By: <span ex:content=".label"></span>, age <span ex:content=".age"></span>.
  </div>

then the exhibit will do the following: It will find the set of authors. Exhibit sees that that div has children elements, so it will recreate that div for each of the authors. So in this example, that div will be like a lens that looks through each of Bob, Jane, Joe, and Mary in turn, getting their label and their age. The final output will be:

 
  <div>
    By: <span>Bob</span>, age <span>35</span>.
  </div>
  <div>
    By: <span>Jane</span>, age <span>43</span>.
  </div>
  <div>
    By: <span>Joe</span>, age <span>62</span>.
  </div>
  <div>
    By: <span>Mary</span>, age <span>22</span>.
  </div>
  

This is a very powerful tool. One good use for it is in generating a table. if you put the ex:content=".author" in the <tr> element, and then specify a <td> within, then the table will grow to hold all the authors.

Color/Size/Icon Coder

The coder feature allows you to color code items on the Timeline view, or code items by color or size on the Map view. Here is an example configuration:

 <coder coderClass="Color" id="role-colors">
    <code color="red">Republican</code>
    <code color="blue">Democrat</code>
    <code case="others" color="#aaa">Other Roles</code>
    <code case="missing" color="#ccc">Other Roles</code>
    <code case="mixed" color="#fff">Other Roles</code>
 </coder>

You need the coderClass attribute to indicate which kind of coder you want. The id attribute is also important because you need to refer back to your coder later, in the configurations for the Map or Timeline views. Be sure to check there to see the rest of the configuration to ensure the coding works. The code tags specify what to code by, and how to code it. For example, to specify that all Republicans are coded as Red, do as you see above. If items are completely missing the property that the coding is based on, then the missing case refers to them. If they have the property, but a color is not specified for it, then others refers to it. Mixed is if more than one item gets placed at the same point and they have different values for that property.

You can also make coders that code using a size gradient or a color gradient. You just need to specify a gradientPoints attribute. These graident points consist of two pairs. The first item in a pair represents the value of a data point, and the the second item represents the corresponding size or color you would like that data point's icon to have. By specifying two points, Exhibit can figure out how to fill in the rest of the points, but you can also specify more points for different gradient patterns.

 <coder coderClass="SizeGradient" id="size-coder" gradientPoints="0, 30; 850000, 70" /> 
 <coder coderClass="ColorGradient" id="color-coder" 
   gradientPoints="gradientPoints="-40, #000088; 0, #ffffff; 50, #ff0000" />

BibTeX

Wibbit can be used as a BibTeX repository. Not only can anyone add entries to it, but anyone can set up their own external web page somewhere and draw out just the entries they want from it.

An example use scenario may be something like follows:

A group can all add their own publications to the BibTeX repository in the wiki. These are all compiled on that wiki page, and can be viewed and filtered using the Exhibit that everybody knows and loves. Anyone interested in the group's publications can go there and see them all, filter by author or year or type, or whatever strikes their fancy.

Now consider an individual member of the group, setting up her own personal web page. She can, with a simple link on that page, extract out just her own publications to display in her own exhibit. Any new, relevant, publications added to the group wiki will be automatically incorporated into her peronsal web page. This way she (along with all her group colleagues) can continue to update the group's repository on the wiki whenever new publications come out, and be confident that her own personal page is always up to date.

A demonstration of this principle is set up involving a book club. Anyone who has some books they want to read can add it to that list. I then have my own personal reading list which gets out just my own books that I want to read from that page.

<bibtex> tags

If you already have BibTeX files lying around, then making them into an exhibit on your wiki is very easy. Simply copy and paste all the BibTeX Entries into the wiki page, putting them between <bibtex> tags. Perhaps you're the author of a book that you'd like in the wiki. You could do something like this:

 
  <bibtex>
    @book{my-wonderful-book,
        title = "What a Wonderful Book this is!",
        author = "Norbert Ukulele",
        isbn = "978-0123456789"
    }
  </bibtex>
  

That's it. Wibbit will see the tags, and parse the entries into a table with the fields as the headers. Its id is automatically set as "bibtextable" and its itemType is automatically set as "Publication" (making this customizable is on our todos). Now that there is a table on the page with the id specified -- you guessed it! -- you can bring it into your exhibit.

 
  <exhibit>
    <source id="bibtextable" />
  </exhibit>
  

One thing to note is that we don't really check for "correct" BibTeX. Correct BibTeX will work, but some syntactically incorrect entries will work, too. For instance Something beginning with "@Blah Blah {" will work, even though "Blah Blah" is not a valid BibTeX type. Also worth noting is that it's possible to use anything within the Bibtex entry. There are standard entry fields that most BibTeX parsers know, but you can add your own as well. So, for instance, you could have a field with a link to a PDF, or a cover image or something like that. Those will all be imported into that item's records in the exhibit database.

BibTeXExport Special Page

This mediawiki extension includes a Special Page -- Special:BibTeXExport (or if you don't like its unique capitalization, Special:BibtexExport) -- which is used to retrieve the BibTeX on a page for use in an external page.

To see how this works, we'll walk through the book club example. If you visit that page, you'll see it has an exhibit composed of several items it gleamed from pasted-in BibTeX. Click on 'edit' to see the BibTeX.

Now, to get at just the BibTeX in that page without all the mediawiki fluff (or even HTML fluff like head and body tags for that matter), you can append that page's name to "Special:BibTeXExport/". So to get the BibTeX from "My_Page", simply visit Special:BibTeXExport/My_Page.

Check out the Special:BibtexExport page for the book club to see it in action. If you view the source for that page, you'll see all the BibTeX there and none of the other stuff, formatted just as it was inputted into the wiki. It only shows up nicely formatted in the source because the browser won't render newlines and spaces and tabs and all that.

But that returns all the BibTeX in the page, verbatim. It is possible to construct a query to return only the BibTeX that satisfies certain requirements. Right now, the only filter available is checking whether something exists in a certain field in each of the BibTeX entries. To only return the BibTeX entries that have Charles Darwin as the author, append ?field:author=Charles Darwin to the URL.

In the book club example, you might have noticed that each entry has an "added-by" field. This refers to whoever it was that found that book interesting and added it to the list. To retrieve the BibTeX from that page of all the entries added by me, Gabe, you would visit the URL:

 http://simile.mit.edu/axo/Special:BibTeXExport/Book_Club?field:added-by=Gabe

The last thing to note is that, if you filter by author, it will check each individual offer. So if a paper is written by Bob, Joe, and Mary, and the filter is field:author=Bob, then that paper will make the cut and be returned.

Using exported BibTeX in another exhibit

The BibTeX you extracted in the section above can be fed right into an external exhibit somewhere. Since Exhibit can natively comprehend BibTeX, all you have to do is specify this in the head of the page somewhere:

 
  <link rel="exhibit/data" type="application/x-bibtex"
        href="http://simile.mit.edu/exhibited-wiki/Special:BibtexExport/Book_Club" />
  

Exhibit will see this and then grab the BibTeX that appears on that page and pop it right into its database. You can, of course, use the query language specified above with ?field:fieldname=value at the end of the URL.

Disabling Your Exhibit

If for some reason you decide that you want to disable your exhibit temporarily, don't delete everything you've entered! You can add a "disabled" attribute to your exhibit tag, which will stop our scripts from processing your exhibit specifications. It will look like this:

  <exhibit disabled="true">
    <source ...
    ...
  </exhibit>

Wiki Table Editor

After you install the Wibbit extension, you will find two new buttons on the left side of the editing toolbar that appears on the edit page of every article. These buttons are comprise a Wiki Table Editor. The first button helps you edit existing tables, and the second button allows you to easily insert a new table in your wikitext.

Get Lat/Lng Button

The "Get Lat/Lng" button in the wiki table editor converts a column of human-friendly addresses to a column of latitude/longitude pairs that the Exhibit map view can use to create markers for a map.

Just place your cursor anywhere in the column of addresses you would like to convert, then press "Get Lat/Lng." A new column should appear next to address column, filled with latitude/longitude data. If some data is missing, check to make sure that the address corresponding to the missing data is a valid address. If you change any addresses, you can always press the button again to generate a new column, but you'll want to delete the column with the missing data.

More Information