Overview

In this part we will explore the following two patterns for creating and editing resources:

Class Instance Create

Intent

To create a new resource associated with Callimachus templates, through a Callimachus class.

Motivation

In addition to exploring and viewing existing resources, the application may allow a user to add additional resources. For example, in a workflow-based application the user may need to be able to create new tasks.

Applicability

Use this where the class of resource is known. The class definition provides a starting point for deciding which properties should be included in the creation form. However, the actual choice of properties is determined by the developer.

Implementation

The create template enables the creation of a new instance of a creatable class. The properties in the form are not determined by the class definition so the developer is free to leave out or add new properties as appropriate (e.g. the use of an rdfs:label may not be mandated by the class definition).

Security

By default, the create operation is restricted to authorized users. To enable this for users of the admin group we add the admin group as a calli:author for the class. Add other user groups as appropriate.

Sample Code

Defines a new Callimachus class specific for resources created locally. Make this a subclass of the more general foaf:Person. The resulting resource will have both the Callimachus class type and any types in the typeof attribute of the form. Within the Class, assign a new create template.

The RDFa create template allows the user to initialise the new resource. The resource is assigned a URL based on the input label. The label is first converted to a lower-case uri-safe format.


<?xml version="1.0" encoding="UTF-8" ?>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
    xmlns:foaf="http://xmlns.com/foaf/0.1/">
<head>
   <title>New Person</title>
</head>
<body>
   <div class="container">
      <form id="form" method="POST" action="" enctype="text/turtle" typeof="foaf:Person" class="row"
             onsubmit="calli.submitTurtle(event,call.slugify($('#name').val()))">
          <fieldset class="col-sm-4">
              <div class="form-group">
                   <label for="name">Name</label>
                   <input type="text" id="name" value="{foaf:name}" required="required" class="form-control"
                       onchange="calli.updateProperty(event, 'foaf:name')" />
              </div>
              <div class="form-group">
                   <label for="comment">Comment</label>
                   <textarea id="comment" class="form-control"
                        onchange="calli.updateProperty(event, 'rdfs:comment')">{rdfs:comment}</textarea>
              </div>
              <div class="form-group">
                   <button id="create" type="submit" class="btn btn-success">Create</button>
              </div>
          </fieldset>
      </form>
   </div>
</body>
</html>

Class Instance Edit

Intent

To update the properties of an existing resource.

Motivation

Based on the known class of a resource we can create an edit page that enables the user to edit those properties and submit these changes.

Applicability

Use this pattern where the values of an RDF resource can be directly updated by the user.

Implementation

The editing view may be accessed by appending ?edit to the URL of the resource (as long as it is an instance of an editable class). In addition, the 'Edit' tab can be used from the view page.

Sample Code

Define an edit template for a Callimachus Class. The template uses the predefined validation rule required="required" that should be used on mandatory inputs.

The RDFa template person-edit.xhtml displays the current values for the form entries and submits the the list of RDF updates on form submission.


<?xml version="1.0" encoding="UTF-8" ?>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
    xmlns:foaf="http://xmlns.com/foaf/0.1/">
<head><title resource="?this">{foaf:name}</title></head>
<body resource="?this" onload="comparison=calli.copyResourceData('#form')">
   <div class="container">
      <hgroup class="page-header">
         <h1 property="foaf:name" />
      </hgroup>
      <form id="form" method="POST" action="" enctype="application/sparql-update" resource="?this" typeof="foaf:Person" class="row"
             onsubmit="calli.submitUpdate(comparison,event)">
         <fieldset class="col-sm-4">
             <div class="form-group">
                 <label for="name">Name</label>
                 <input type="text" id="name" value="{foaf:name}" class="form-control" required="required"
                     onchange="calli.updateProperty(event, 'foaf:name')" />
             </div>
             <div class="form-group">
                  <label for="comment">Comment</label>
                  <textarea id="comment" class="form-control"
                      onchange="calli.updateProperty(event, 'rdfs:comment')">{rdfs:comment}</textarea>
             </div>
             <div class="form-group">
                  <button id="save" type="submit" class="btn btn-primary">Save</button>
                  <button id="cancel" type="button" onclick="location.replace('?view')" class="btn btn-default">Cancel</button>
             </div>
         </fieldset>
      </form>
   </div>
</body>
</html>

The following sample extends person-edit.xhtml adding the ability to delete the resource. The javascript adds a click handler to the delete button that calls calli.deleteResource(event) on confirmation.


<?xml version="1.0" encoding="UTF-8" ?>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
   xmlns:foaf="http://xmlns.com/foaf/0.1/">
<head><title resource="?this">{foaf:name}</title></head>
<body resource="?this" onload="comparison=calli.copyResourceData('#form')">
   <div class="container">
      <hgroup class="page-header">
         <h1 property="foaf:name" />
      </hgroup>
      <form id="form" method="POST" action="" enctype="application/sparql-update" resource="?this" typeof="foaf:Person" class="row"
             onsubmit="calli.submitUpdate(comparison,event)">
         <fieldset class="col-sm-4">
             <div class="form-group">
                 <label for="name">Name</label>
                 <input type="text" id="name" value="{foaf:name}" class="form-control" required="required"
                     onchange="calli.updateProperty(event, 'foaf:name')" />
             </div>
             <div class="form-group">
                  <label for="comment">Comment</label>
                  <textarea id="comment" class="form-control"
                      onchange="calli.updateProperty(event, 'rdfs:comment')">{rdfs:comment}</textarea>
             </div>
             <div class="form-group">
                  <button id="save" type="submit" class="btn btn-primary">Save</button>
                  <button id="cancel" type="button" onclick="location.replace('?view')" class="btn btn-default">Cancel</button>
                  <button id="delete" type="button" onclick="calli.deleteResource(event)" class="btn btn-danger">Delete</button>
             </div>
         </fieldset>
      </form>
   </div>
</body>
</html>