These notes are for people developing websites using the tabulator library, or developing the Tabulator itself.
The tabulator is open source software, managed with Mercurial, (abbreviated to hg), a decentralized source code management system. The root of the tabulator project is http://dig.csail.mit.edu/hg/tabulator So make sure you have a fairly recent version of Firefox, install Mercurial, then, at the command line prompt:
hg clone http://dig.csail.mit.edu/hg/tabulator
Then, to set up your checked out code as a Firefox extension,
# For example, on Mac OS X: cd ~/Library/Application?Support/Firefox/Profiles/*/extensions # # Assuming the tabulator has been checked out in /Users/me/tabulator ls -d ~/tabulator > "tabulator@csail.mit.edu"
That's it.
To update to future versions, just quite Firefox, cd tabulator; hg pull; hg update then restart Firefox.
Below we take you through one example application of the AJAR library. Other applications you could also look at:
One way to start using the AJAR library is to look at a simple demo application. (Run it with Firefox set up as per tabulator)
This just loads a FOAF file into the store, finds the friends, and loads theirs, displaying business cards for each.
It may also be useful to look at the interactive test pages which are quite simple in some cases. The notes which follow introduce the key features of the API. David Brondsema has also made some notes on how to use the RDF parser
The system uses Javascript objects for RDF symbols. Generating them for predicates is simplified by using a namespace function:
FOAF = Namespace("http://xmlns.com/foaf/0.1/")
RDF = Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#")
RDFS = Namespace("http://www.w3.org/2000/01/rdf-schema#")
OWL = Namespace("http://www.w3.org/2002/07/owl#")
DC = Namespace("http://purl.org/dc/elements/1.1/")
RSS = Namespace("http://purl.org/rss/1.0/")
XSD = Namespace("http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/#dt-")
CONTACT = Namespace("http://www.w3.org/2000/10/swap/pim/contact#")
var foafKnows = FOAF('knows');
This is the key class in the API. A formula is a set of statements, as you get from parsing and RDF resource. It is what is sometimes called a store, and sometimes called a graph.
var kb = new $rdf.IndexedFormula()
kb.load('http://www.w3.org/People/Berners-Lee/card')
It will automatically add any ontologies used by the data.
There are two ways to look at RDF data in a formula. You can synchronously use the the(), each() and any() methods and statementsMatching(), or you can do a query which returns results asynchronously.
The the(), each(), any() and statementsMatching() take a pattern of subject, predate, object and source ('why'), where for the() each() and any() one of s p and o are undefined and source may be undefined or not. For example, using kb.sym() to make an object for an RDF node (symbol),
me = kb.sym('http://www.w3.org/People/Berners-Lee/card#i');
knows = FOAF('knows')
friend = kb.any(me, knows, undefined) // Any one person
or for that matter
me = kb.sym('http://www.w3.org/People/Berners-Lee/card#i');
friend = kb.any(me, FOAF('friend'))
One of the partners of the triple is set undefined and that serves as a wildcard. In this case, the formula returns the object of a matching triple.
m = kb.the(me, mother)
Here the assumption (unchecked in the application) is that there is only one match.
friends = kb.each(me, FOAF('knows'))
for (var i=0; i<friends.length;i++) {
friend = friends[i];
...
}
This returns a javascript array of objects.
The add(s, p, o, why) method allows a statement to be added to a formula. The optional why argument can be used to keep track of which resource was the source for each triple.
kb.add(me, FOAF('knows'), fred);
kb.add(me, FOAF('name'), "Albert Bloggs");
Note above where the rDF thing in question is a literal, you can just pass a Javascript literal and a string, boolean, or numeric literal of the appropriate datatype will be used.
The the(), each(), any() and statementsMatching() in fact can take a fourth argument to select data from a particular source.
myFoafFile = kb.sym(uri)
friendsInMyFOAF = kb.each(me, FOAF('knows'), undefined, myFoafFile)
These are types of node in the RDF graph. Why call them terms? They are terms in the language when yo think of RDF as a language.
| What | To create one | x.termType | |
|---|---|---|---|
| Node identified by a URI | x = kb.sym(uri) | 'symbol' | |
| Blank node | x = kb.bnode() | 'bnode' | |
| Untyped Literal | x = kb.literal('foo') | 'literal' | |
| Typed Literal | x = kb.literal('foo', undefined, dt) | 'literal' | |
| Literal with language | x = kb.literal('chat', 'en') | 'literal' | |
| Ordered list | x = kb.list([node1, node2]) | 'collection' |
To make a query, in brief, the query is made as a separate formula, introducing variable objects in appropriate places. The query formula is then used a an argument to the query() method of the knowledge base formula being searched. A callback routine also passed to kb.query(). The callback routine is called back when each matching set of bindings is found with bindings as argument.
This is not described in detail here.
The view system is quote modular. A form allows you to experiment adding new views to a running tabulator. Click on "New view..."
@@@@ To be continued...Panes are different views for displaying data about a particular thing. It can be application-specfic views, typically for things of a certian type or with certain properties. A pane allows you to render, for example, a document in a particular format, or add simple applications which are related to a type of thing.
The following is a partial list of fully functional panes available with Tabulator at the moment.
If you want to extend the functionality of Tabulator by adding a new pane, just follow these few simple steps:
js/panes folder.
We recommend naming your file in this format: "[New]Pane.js".
The skeleton of the pane code should consist of the following:
tabulator.panes.register( {
icon: Icon.src.icon_NewPane, //This icon should be defined in 'test.js' and 'tabulate.js'
label: function(subject) { //'subject' is the source of the document
if the criteria for displaying the pane is satisfied
return "the string that would be the title for the icon"
else
return null;
},
render: function(subject, document) { //'subject' is the source of the document
//'document' is the HTML document element we are attaching elements to
var div = myDocument.createElement("div")
//implement what you want to do with the pane here
return div
}
} , true);
tabulator.xul for the Tabulator to pick up.
For the online version, include it in tab.htmlObviously look at exsiting panes for ideas.
.If you check out the tabulator source code as above, then you will find a general-purpose RDF library at chrome/content/js/rdf/rdflib.js.
Also and old The 0.8 release of tabulator as a whole is available as an archive file
You can browse the files of this version in the web.
The diagram is a simplified dependency graph of the major modules in the tabulator and the AJAR library.
This library provides data handling for AJAX applications, including web access, store, and query. The modules are as follows, in increasing order of functionality. Each depends on the ones before it.
This provides basic URI handling functions, such as calculation of absolute URIs from relative URIs. A URI test page has red blocks if the tests fail.
Objects for representing the basic RDF terms. Symbols (nodes in the graph names by URIs), blank nodes and literal values are defined, as are collections.
Statements are defined to have a subject, predicate and object, all terms. They also keep a "why" slot which is used to track the provenance of the statement.So are formulas, sets of triples. This is a simplistic implementation of formula, RDFFormula, for testing and learning.
(The Variable class of term is not introduced here, but is added by query.js.)
This module adds comparison between terms (there is a consistent ordering across all terms) an the simple searching for a statement pattern in a formula.
This is used by sources.js to parse RDF/XML files from the DOM
See also the test/rdf/ parser test files.
The N3 parser parses data in Notation 3 from a the notation3 source text. N3 is an equivalent, easier to read, syntax for RDF.
This is the main code for the store. This file introduces a more powerful formula class, RDFIndexedFormula. This is indexed, to provide faster searching. It also performs the smushing together of nodes which represent the same thing, using owl:sameAs, owl:InverseFunctionalProperty and owl:FunctionalProperty.
A new type of term is introduced, Variable. (This is the thing which in SPARQL is written like ?x). Formulas which contain variables are used as pattern-matching queries on the an RDFIndexedFormula. The query takes a callback, which is called when any matching set of bindings is called. The query looks up URIs on the web as it comes across them.
This manages all the sources (data-bearing information resources on the web) which the application has requested. It deals with
This module contains a SPARQL parser which generates a query object in the AJAR internal form, and a serializer which performs the reverse process. This module is used in the sparqlView module which provides user read and editing of queries in the sparql language.