There is only one more thing to do to get a fully functional address book. We would like to change the simplistic address book view:

Initial app - query view

To this more useful view that includes more fields and a search capability:

Finished app - query view

You might think that we need to change the named query that drives this page, but we don't.  You would need to do that if you were using a relational database and a traditional development environment, but that's not how Callimachus works.  The query looks like this:


#
# @Cache-Control: 
# @infer true
# @view ../templates/person-listing-view.xhtml
#
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT ?person WHERE {
    ?person a <../classes/Person>
} ORDER BY ?person

Note that the query only returns a single bound variable called ?person.  That variable will be bound for every instance of the Person class in the database, so we will get some number of them.  The finished app people folder has three of them.  Those variables are filled into the query's associated view template one at a time to become bound to the ?this variable (referenced in the body tag).  From there, the template language "walks the graph" to find the data it needs.  So, you can safely add anything to the view template you like, as long as there is a path in the graph from the ?this variable to what you need.

Do you remember how to use the rel/resource pattern as described in section 1.5. Revisiting the Person View Template?  You might be interested to know that there is an equivalent to rel called rev that walks a relationship backward.  That can help you find data when the arrows are pointing the wrong way.  The documentation has more information on the use of rev.

So all we need to add to the query's view template are the calls to the data:


<table class="table table-striped table-hover lead">
  <thead>
    <th>Name</th>
    <th>Email</th>
    <th>Phone</th>
    <th>Status</th>
  </thead>
  <tbody>
    <tr resource="?person"> 
      <td><a href="?person">{rdfs:label}</a></td>
      <td><a href="mailto:{foaf:mbox}">{foaf:mbox}</a></td>
      <td><a class="phone" href="tel:{foaf:phone}">{foaf:phone}</a></td>
      <td><span rel="foaf:status">{skos:prefLabel}</span></td>
    </tr>
  </tbody>
</table>

Look carefully at how the hyperlinks were made.  The name of a person was linked to the URI of its instance (?person).  We can do that because those URIs are resolvable in Callimachus (which makes them into URLs - they are "locators").  The string pointed to by the foaf:mbox predicate is an email address, and that can be made into a URL by prepending it with "mailto:". Similarly, the telephone number in foaf:phone can be turned into a URL by prepending it with "tel:".  Naturally, the phone number cannot have any white space in it when it is entered!  If you want to check the formats of things like a phone number or email address, you can do that using JavaScript on the create and edit templates.

The last thing we are going to do on this page is to add a basic search capability.  That is covered in the next chapter in section 2.1. SPARQL Endpoint.

Wrap up & Review

What additional changes could you think to make to the query view template?  For example, it might be nice to color-code the status indication on this view.  You already have the JavaScript to do something very similar on the Person view template.