Creating and Maintaining Templates using the Resource API

From OSF Wiki
Jump to: navigation, search

The Resource API is a set of PHP classes that have been created specifically to help OSF for Drupal templetes designers to create, maintain and read templates files. The API is mean to be a simple set of classes and functions that can easily be used to display Entity related information into a Drupal templated page.

Introduction to the Resource API

The Resource API is a set of five classes but only three are used for templating purposes:

  • Resource
  • Property
  • Value

The design of the API focus on these three classes. A Resource is an Entity description. It is composed of:

  • A unique identifier
  • One or multiple types
  • One or multiple Properties

Then a Property is composed of:

  • A unique identifier
  • A type, which is one of:
    • Datatype Property, or
    • Object Property
  • One or multiple Values

Then a Value is composed of:

  • A content (the actual value)
  • An optional language identifer (ISO 639)
  • An optional datatype
  • Optional reification statements (out of the scope of this documentation).

It is as simple as this: a Resource is described using multiple Properties and each of these properties can have one or multiple Values.

What the Resource API does, is just to expose utility functions to help Drupal template designers to use that entity information in the context of a Drupal template.

Overview of the Resource API

In this section, we will cover the main API functions that are available via this API. Note that this document only focus on the classes and functions that are relevant to Drupal template designers. Other classes and functions exists, but they are not relevant for the job at hands.

Resource Class
Function Description Parameters Returns
uri() Get the full URI of the Resource None Return the full URI of this Resource
property($uri) Get a specific property and all its values
Parameter Description
$uri URI of the property to get. The full URI of the property can be used, or its "prefixed" (abridged) version. Such a prefixed version would be "foaf:name". See the section below that discuss abridged vs. unabridged URIs.
Return the Property instance with all its values. If the property is not existing, then an empty Property is returned. An empty property is a property with an empty URI and an empty set of values
properties() Get the list of all the properties defining this Resource None Return an array of Property() instances that define this Resource
type($id) Get a type of this resource
Parameter Description
$id ID of the type to return. The index start at 1, unlike arrays
Return the full URI of the type available for that index. NULL is returned if there is no type available for this index
types() Get the types of the Resource None Return an array of full URIs that refer to the types of this Resource
setLanguage($language) Specify the language to be used when the user get values from this Resource instance. If a language is specified, then all the functions that returns values will only return values of that language. If the specified language is NULL, then the values of all languages will be returned.

Note that the object properties are not affected by this setting.

Parameter Description
$language ISO 639 language tag
Return the Resource itself.

This means that this function can be chained with other function calls.

isLanguageStrict() Specify if the Resource is using the strict language mode None Return the Resource itself.

This means that this function can be chained with other function calls.

strictLanguage() Enables the strict language mode. If this mode is enabled, it means that only the values tagged with that language will be returned for the Datatype properties values. This means that all values that have a NULL (unspecified) language won't be returned by any functions that return values None Return the Resource itself.

This means that this function can be chained with other function calls.

looseLanguage() Enables the "loose language" mode. If this mode is enabled, it means that the values tagged with that language, and the values without any language defined for them (NULL) will be returned for the Datatype properties values.

This is the default behavior.

None Return the Resource itself.

This means that this function can be chained with other function calls.

Property Class
Function Description Parameters Returns
value($id) Return a value defined for a property. If a language is defined for the Resource then the index is the one of the sub-set of values that is composed of all the values of the language specified for the Resource.
Parameter Description
$id ID of the value to return.

The index start at 1, unlike arrays

Return a Value instance that represents that value. An empty Value instance will be returned if there is no Value for that index
values() Get all the values of that Property. If the property is a Datatype property and if a language is defined for the Resource, then all the values that will be returned are values that have this language None Return an array of Value instances. One for each value of that property
uri() Get the URI of this property None Return the full URI of that property
type() Get the type of tihs property. Can be DATATYPE_PROPERTY or OBJECT_PROPERTY None Return the type of the property. It can be de constant DATATYPE_PROPERTY or the constant OBJECT_PROPERTY
exists() Specify if there are values for that property. If the Resource has a specific language specified for it, and if this is a DATATYPE_PROPERTY then exists will return TRUE only if there is a value with that language None TRUE is there is at least a value for that property. Return FALSE otherwise.
Value Class
Function Description Parameters Returns
content() Get the actual value content of this Value None Return the value content of this Value
display() Display the value

The display is used using the "echo" language construct

None Nothing
language() Get the language of this Value None Return the ISO 639 language code of this value. If NULL is returned it means that no language is specified for this Value (so it is considered language neutral).
type() Get the URI of the datatype of the Value None Return the URI of the datatype of the value. If NULL is returned it means that no specific datatype has been defined for this value
reifications() Get the reification properties for the triple composed of that value None Return an array which is composed of the reification statements

Usage Recipes

This section outline a series of Resource API "usage recipes". These are code snippets that covers the most common usage of the API for templating purposes.

Working with URIs

Before starting the list the recipes, we have to cover one of the core concept: URI. URI are unique identifiers that are used to identify Resources, Properties and Types. A URI is normally a standard URL, but it can be different. A full URI looks like this:

http://purl.org/ontology/iron#prefLabel

This unique identifier is not different than any other unique identifiers like a unique number, a hash value, etc. In the recipes below, we will be referring to prefixed URI. A prefixed URI is a URI that his shortened using a prefix. Let's say that we have a prefix called iron that stands for the partial URI http://purl.org/ontology/iron#. This means that the prefixed URI version of the full URI we defined above would be:

iron:prefLabel

Prefixed URIs makes shorter and more human readable URIs. This is perfect in the context of writing templates code since it will make the templates easier to read and maintain and create.

Note that you will be able use the osf_dpm_resource() function when you will be creating new templates to list all the prefixed properties URI that are available for the entity you are templating.

There is a configuration user interface in OSF for Drupal that you can use to see, and manage, all the namespaces that are available to you. See the Managing Namespaces page for more information.

Getting a Property

Getting a reference of one of the property that describes a Resource is pretty easier, the only thing you have to do is to specify the full or the prefixed URI to get using the property() function:

<?
  $label = $resource->property('iron:prefLabel');
?>

Then $label can be used anywhere in your code to display the value(s) of that preferred label.

Getting the First Value of a Property

To get the first value of a property, you have to use the value() function of a Property:

<?
  $labelValue = $resource->property('iron:prefLabel')->value();
?>

If you don't specify any $id for the value() function, then the first value will be returned. As you can see in this example, you can chain the function calls to get a property, and then its value. You could have done this too:

<?
  $label = $resource->property('iron:prefLabel');
  $labelValue = $label->value();
?>
Getting the Content of the First Value of a Property

To get the content of the first value of a property, you have to use the content() function of a Value:

<?
  $actualLabel = $resource->property('iron:prefLabel')->value()->content();
?>

What this does is to return the actual value of the Value instance.

Displaying the Content of the First Value of a Property

To display the content of the first value of a property, you have to use the display() function of a Value:

  <h2><? $resource->property('iron:prefLabel')->value()->display() ?></h2>

What this code does is to directly display the value within the H2 HTML code element. If you want to make you code even simpler and cleaner, you could have done this:

<?
  // Declare all the properties I want to use in my template
  $label = $resource->property('iron:prefLabel')->value();


  // Then I get to the template's code...
?>

  <h2><? $label->display() ?></h2>
Check if a Property Exists in a Resource

Often, you only want to display parts of your template depending if there exists values for some properties of the Resource you are templating. For example, if you have a Resource that may have some latitude/longitude coordinates, than you only want to display a Google Map if there are actual lat/long coordinates for the Resource you are displaying to the users. To make that check, you have to use the exists() function of a Property:

<?
  $lat = $resource->property('geo:latitude');
  $long = $resource->property('geo:longitude');
?>


<? if($lat->exists() && $long->exists()) { ?>
  <script type="text/javascript">
    var latlng = new google.maps.LatLng("<? $lat->value->display() ?>", "<? $long->value->display() ?>");
    var myOptions = {zoom: 15,
                     center: latlng,
                     mapTypeId: google.maps.MapTypeId.ROADMAP};
                   
    var map = new google.maps.Map(document.getElementById("map_canvas_'.$id.'"), myOptions);
                   
    var marker = new google.maps.Marker({position: latlng,
                                         map: map});
  </script>
<? } ?>
Get all the Values of a Property

Sometimes it is essential to be able to iterate all the Values of a Property. It can easily be done using the values() function of a Property:

<?
  $altLabel = $resource->property('iron:altLabel');

  if($altLabel->exists)
  {
    ?>Alternative labels: <?
    foreach($altLabel->values() as $value)
    {
      ?> $value->display() <?
    }
  }  
?>
Get all French Values of a Property

In a multilingual Drupal instance, you may have to deal with multilingual Resources. These are resources that may use multiple languages to describe the same Value. This can easily be done with this API. The only thing you have to do is to specify that you want to access French information from the Resource by using the setLanguage() function call on the Resource. Then when you will use any other functions to get the values from that Resource, everything will be in French:

<?
  $resource->setLanguage('fr');
   
  foreach($resource->property('rdfs:label')->values() as $value)
  {
    // Display all the French values of that property
    // This will also display the values that have no language defined for them
    $value->display();
  }  
?>

Remember that by default, the loose language mode is activated. That means that the code below will display all the French labels, and the labels that doesn't have any language defined for them. If you want to strictly use the French labels, then you could change that code this way to enable the strict language mode:

<?
  $resource->setLanguage('fr')
           ->strictLanguage();
   
  foreach($resource->property('rdfs:label')->values() as $value)
  {
    // Display all the French values of that property
    // This will also display the values that have no language defined for them
    $value->display();
  }  
?>
Working with Object Properties

As we discussed above, a Property can be a DATATYPE_PROPERTY or a OBJECT_PROPERTY. Datatype properties are properties for which their value is textual. The Object properties' value are always URIs. These URIs refer to other entities that should exists in the system.

In this example, we will consider that we have an object property foaf:knows that refer a person entity to another person entity:

<?
  $knows = $resource->property('foaf:knows');

  // Check if our Resource knows someone
  if($knows->exists())
  {
    ?><ul><?
    foreach($knows->values() as $know)
    {
      // Display the name of every person our Resource knows
     
      // First get the description of the entity he knows
      $knownEntity = osf_get_resource($know->content());
     
      // Then display the name of that person
      ?><li><? $knownEntity->property('iron:prefLabel')->value()->display() ?></li><?
    }
    ?></ul><?
  }
?>

In this example, we use the osf_get_resource() OSF for Drupal function call to get the description of the entity that is referenced from our Resource. That other Resource that is returned by this function call can be used like any other Resource that we are manipulating using the Resource API.

Getting Information About Types and Properties

Sometime it may be useful to get information about the type and properties that are used to describe a Resource you are manipulating. A type or a property are Resources as well. What this means is that you can use the Resource API to get additional information about these things that you may want to display into the templated page.

Let's take the usecase where you want to display the preferred label for the type of a Resource that you are templating, in parenthesis in the title of that Resource's page.

What you have to do is to use the osf_get_resource() function to get the description of that type and to display information about that type. Here is how you can do that:

<?

  // Get the Resource object of the Type of the Resource of that page
  $typeResource = osf_get_resource($resource->type())

  // Then display its preferred label in parenthesis

?>

<h3><? $resource->property('iron:prefLabel')->value()->display() ?> (<? $typeResource->property('iron:prefLabel')->value()->display() ?>)</h3>

What this code does is really simple: it get additional information from OSF about the type of the entity being processed in the templated page, and use that information to display the preferred label of that type into the templated page.

Drupal Specific Functions

There are two OSF for Drupal functions that exists that are related to the Resource API:

osf_get_resource($uri)

What the osf_get_resource($uri) call does is to return a Resource instance for the URI you specified as parameter. This function is normally used to get the Resource that describes an entity reference by the Resource being templated. That means that you can template information from related entities to the entity being templated. Like in this code:

<?
  $knows = $resource->property('foaf:knows');

  // Check if our Resource knows someone
  if($knows->exists())
  {
    ?><ul><?
    foreach($knows->values() as $know)
    {
      // Display the name of every person our Resource knows
     
      // First get the description of the entity he knows
      $knownEntity = osf_get_resource($know->content());
     
      // Then display the name of that person
      ?><li><? $knownEntity->property('iron:prefLabel')->value()->display() ?></li><?
    }
    ?></ul><?
  }
?>
osf_dpm_resource(Resource $resource)

The first thing a template designer has to do when he starts templating a new Entity is to check what are the properties/values available to him. What the osf_dpm_resource() function does is to output the structure of the Resource being templated such that you the information you can template, and more importantly, the prefixed URI of the properties you can use in your code. If you use that code, anywhere in the template's code:

<?
  osf_dpm_resource($resource);
?>

You will get that output in your browser the next time you will refresh your page (note: it may takes two refreshes depending on the code sequence in Drupal and if it is a search template an a view template):

Osf dpm resource.PNG

As you can see, this debugging output will show you all the properties that are defining that Resource. Then for each of these properties, you can see their prefixed URI. These same prefixed URI can be used in your template code like what we were doing in the recipes above. You can click to extends all these sections and see the values for each of these properties.