Building conStruct Templates

From TechWiki

Jump to: navigation, search

Contents

Introduction

conStruct templates are used to create different HTML page layouts to present information about instance records depending on their type. The present design utilizes Smarty as the baseline templating framework.

The general idea is that depending on the type of the instance record you want to display information about, you will want your system to display the information you have about that instance record differently depending on the type of that instance record. For example, if you want to present information about a neighborhood, the information will be displayed differently than if you want to present information about a person.

System Workflow Overview

As discussed elsewhere, conStruct is simply a variety of user interfaces that interact with a series of structWSF web service endpoints. All the information that gets displayed in conStruct comes from a structWSF instance. This means that the description of the instance records being templated come from the CRUD: Read web service endpoint. Here is the general workflow that is triggered when a user wants to get information describing an instance record (as might be obtained by clicking on a search or browse resultset, a direct page view, a click from Google, etc):

  1. The user hits an instance record web page
  2. The structResource module gets triggered. If the content-type of the HTTP request is an HTML page, then it redirects the user to the structView module
  3. The structView module gets triggered
    1. It queries the structWSF instance where the instance record got indexed
    2. It calls the VisualBinder.php script
      1. This script will read the information related to that instance record
      2. Depending on the type of the instance record, and the loaded ontological structure on the node, the VisualBinder will bind a template to that instance record
      3. Then it will bind the information about the instance record to Smarty
      4. Finally the Smarty template that has been selected will be run, and once the HTML page got generated, it will be displayed to the user

Template Selection

The most important step in the workflow described above for the template designer is template selection. Template selection is the action of binding an instance record to a display template based on its type. Three things are mandatory to make this happen:

  1. Instance records have to be typed
  2. An ontological structure has to be loaded in conStruct
  3. A template has to exist for the type of the instance record (actually, this is not strictly true, since lacking a specific template for the target type, the system will invoke the nearest template up the parental chain in the governing ontology structure, eventually getting to the most generic template available, that for "thing")

Let's take an example. Let's say that we try to display information about a foaf:Person instance record. What the System will do is to try to find a template that displays information about this kind of instance record. First, that foaf:Person type (class) has to be defined in the ontological structure of the conStruct instance; if it is not, then no template will be selected (except for the owl_thing.html template, see below). Then, the system will check if a template exists in conStruct for that type. If there exists one, then it will run it to display the information about that instance record.

The one thing that the template designer has to know is how to name his template file(s) that goes into the templates folder. Here are the rules:

  1. All template names are lowercase
  2. All template names start with the prefix used to refer to the ontology where the type is defined
  3. All template names end with the name of the class that represents the type of the instance record
  4. The file extension is always ".html"
  5. The prefix is always separated with the class name by an underscore

There is no better way than an example to show how to do something, so let's take a look at this example: we want to create a template for the foaf:Person class, so the related Smarty template for that foaf:Person class would be foaf_person.html.

Creating a Template

Now, let's take a look at how to create these templates. First, you will have to have some knowledge about the Smarty templating system. A good place to start is with the pretty good documentation manual.

Now that you have some knowledge about Smarty, let's take a look at how you are supposed to create these templates, and how you are supposed to use the API extension that has been developed for conStruct.

First, there are 3 mains sections in an conStruct Smarty template:

  1. The setting section that goes before the <head /> section of the HTML file
  2. The variable assignation section that goes in the <head /> section of the HTML file
  3. The content section, that goes anywhere in the HTML file, but after the variable assignation section

Settings Section

This section provides a list of pre-initialization settings (see the Template Settings section below). These settings will instruct the template being generate to do, or not to do, some specific things prior to the initialization of the variables and the generation of the web page. It is why is has to be placed before the <head /> section of the HTML page.

Variable Assignment Section

This section will bind different attribute/values describing the instance record being displayed, and the Smarty variables that will be used to generate the HTML page. This may be a long list of variable assignments.

Content Section

This section is anywhere after the variable assignment section. This is where you will use the values of the variables to display different things in different sections of the HTML page. It is where you will use all of Smarty's markup options.

conStruct's Smarty API Extension

To make the creation of Smarty templates, an API has been developed to help the template creator to manipulate the description of the record being displayed. This section will explain the use of each API call along with some Smarty implementation code.

Template Settings

As we said above, the pre-initialization settings are instructions you will tell to the templating engine. These instructions will tell the engine to do, or not to do, different kind of things.

setAttributeIgnoreResourceLabel

There exists two kind of values for an attribute:

  1. Resource
  2. Plain Literal

Let's say that the person instance record you are about to display knows other people. In the system, there will exist a knows relationship between these two instance records. However, in the template system we want to display the label that refers to that person that he knows and not its identifier. This means that the system would have to send another query to the structWSF to try to find a label to display in the user interface.

However, what happen if that person knows 1000 other people? It would take a lot of time to send all these queries. It is why (depending on the usecase) we may want to turn this setting on (true) or off (false).

This setting is written such as:

  {* setting->setAttributeIgnoreResourceLabel=true *}

The default value of this setting is false.

LinksTo

Sometimes, you want to know what other instance records links to in the instance record you are about to display (links-back relationships). This is what this setting is about. If it is enabled, it will check on the structWSF instance(s) if any instance record are linking to the instance record being viewed.

Note: this setting has to be enabled in order to use the getLinksTo API call below.

  {* setting->LinksTo=true *}

The default value of this setting is false

Resource Description API

Now that the settings are declared, we have to assign everything we want to use in the template to different variables. This Smarty API extension used to get resource descriptions is the core of the templating system. Each of these API call will return different attribute(s)/values(s) pairs that you will be able to manipulate and display in the body of your template.

The main thing to understand is the simple data structure that is returned by most of these API functions. The calls should return one of these three things:

  1. A plain literal
  2. A value (described as an associative array, see below)
  3. An array of attributes/values

The most important thing to understand is how a value is described. The value of an attribute is described using an associative array that describes different things related to that value. This array is:

  array("attribute" => "...",
        "attributeLabel" => "..",
        "value" => "...",
        "valueType" => "...",
        "valueLiteral" => "...",
        "reify" => "...");

Here is the description of each of these field:

  1. attribute: this is the URI of the attribute that refers to that value
  2. attributeLabel: this is the preferred label used to refer to that attribute. This is handy to use that value to display in the generated web page instead of displaying the ugly URI of that attribute. This preferred label come from the ontological structure used by the conStruct node
  3. value: this is the actual value. It can be a URI, a plain literal, etc.
  4. valueType: this is the type of the value. Two types exists: (1) resource, and (2) literal
  5. valueLiteral: If the value is a resource, it is recommended to use a label to refer to that resource. Provide that value in this field.
  6. reify: This is an array of reified statements for this attribute/value statement.

The API functions below are ordered alphabetically.

getAttributes

This function returns all the attribute/value pairs describing the instance record.

The array that is returned by this call is an associative array of attribute/values:

  array("attribute-uri" => array("attribute" => "...",
                                 "attributeLabel" => "..",
                                 "value" => "...",
                                 "valueType" => "...",
                                 "valueLiteral" => "...",
                                 "reify" => "..."));

Variable assignments:

  {attribute->getAttributes assign='attributeValues'}

Usage:

  {foreach from=$attributeValues item=value}
    {$value.attribute}: {$value.value} <br />
  {/foreach}

getInstanceRecordDataset

This function returns the URI of the Dataset where the instance record resides. This is quite handy when you want to send queries to any structWSF endpoints directly from the template.

Variable assignment:

  {attribute->getInstanceRecordDataset assign='InstanceRecordDataset'}

Usage:

  {$InstanceRecordDataset}

getInstanceRecordDescription

This function is helpful when you want to get a description for an instance record. A description can be different things depending on its type: it can be an abstract, a biography, etc.

This function only checks the description of an instance record and checks if it has been described using some attribute that might be used to describe a thing.

Variable assignment:

  {attribute->getInstanceRecordDescription assign='InstanceRecordDescription'}

Usage:

  {$InstanceRecordDescription}
Extend Record Description Attributes

Note: to extend the list of supported description attributes, you have to change the code in the VisualBind.php file and add them at the line 824

getInstanceRecordLabel

This function returns the preferred label to use to refer to this instance record. It can be a name, a title, etc.

This function only checks the description of an instance record and checks if it has been described using some attribute that may have been used to name a thing.

Variable assignment:

  {attribute->getInstanceRecordLabel assign='InstanceRecordLabel'}

Usage:

  {$InstanceRecordLabel}
Extend Supported Name Attributes

Note: to extend the list of supported name attributes, you have to change the code in the VisualBind.php file and add them at the line 731

getInstanceRecordType

This function returns the name of the type of this record. This is useful if you want to display the type of the instance record being displayed to the user.

Note: the name of the type comes from the ontological structure used by the conStruct instance.

Variable assignment:

  {attribute->getInstanceRecordType assign='InstanceRecordType'}

Usage:

  {$InstanceRecordType}

getLabel

This function is a utility function that returns the label to use to refer to an attribute. It takes an attribute URI as input, and outputs a possible label to use to refer to it. It returns an empty string if none have been found.

Parameters:

  1. attribute: the URI of the attribute for which we want a label

Variable assignment:

  {attribute->getLabel attribute='http://xmlns.com/foaf/0.1/knows' assign='foaf_knows_label'}

Usage:

  {$foaf_knows_label}

getLinksTo

This function returns an array of resources that are related (links-to) the instance record being viewed by the user. This is quite handy to display pages that are referring to the instance record page. Also, what is interesting is that you can do better than just saying: here is a list of things that links to this page. In fact, you can say: here is a person that know this person, here is an article that refers to this other article, here is the page of the author that links to this article, etc.

The array that is returned by this call is an array of values:

  array_push($values, array("referrer" => "...",
                            "referrerLabel" => "...",
                            "attribute" => "...",
                            "attributeLabel" => "..."));

Here is the description of each of these fields:

  1. referrer: URI of the instance records that refer to the one being displayed
  2. referrerLabel: preferred label of that referrer instance record
  3. attribute: URI of the attribute used to refer to the record being displayed
  4. attributeLabel: preferred label of that attribute

Note: make sure you that have the LinksTo setting enabled in your template.

Variable assignment:

  {attribute->getLinksTo assign='linksTo'}

Usage:

{if count($linksTo) > 0}
  <h3 style="margin-top: 10px;"> Pages referring here </h3>
  <table style="margin: 0px; padding: 0px; width: 670px;" border="0">
  <tbody>
  {foreach from=$linksTo item=value}
    <tr>
      <td style="width: 16px;" align="right">
        <span>
          <img style="vertical-align: middle;" 
               src="/drupal/sites/all/modules/conStruct/templates/imgs/bullet_green.png" 
               alt="" 
               width="16" 
               height="16" />
        </span>
      </td>
      <td>
        <a href="?uri={$value.referrer}&dataset={$InstanceRecordDataset}">{$value.referrerLabel}</a>
        &nbsp;&nbsp; 
        <em>
          ({$value.attributeLabel})
        </em>
      </td>
    </tr>
  {/foreach}       
  </tbody>
  </table>
{/if}

getResourcePropertyValues

This function is essential if you want to get the values of an attribute describing any instance record other than its preferred label. A good usecase would be when you want to display more information about the authors of an article (the instance record being displayed) other than their names.

What this function returns is an array of values for that attribute:

  array(array("attribute" => "...",
              "attributeLabel" => "..",
              "value" => "...",
              "valueType" => "...",
              "valueLiteral" => "..."));


Parameters:

  1. resource: the URI of the instance record for which you want its complete description
  2. dataset: the dataset URI where the instance record has been indexed. If this parameter is empty, the system will search within all datasets accessible to that user.
  3. property: the URI of the attribute for which you want all its values

Variable assignment:

  {*attribute->getResourcePropertyValues resource='http://foo.com/bar/' dataset='' 
                                         property='http://xmlns.com/foaf/0.1/homepage'
                                         assign='bar_homepage_values'*}

Usage:

{if count($bar_homepage_values) > 0}
  {foreach from=$bar_homepage_values item=value}
    <a href="{$value.value}">{$value.valueLiteral}</a> <br />
  {/foreach}       
{/if}

getResourceRawSerialization

This function is handy to return the raw serialization of the instance record being viewed. This is mostly used to feed Semantic Components with some input records. The record is serialized using StructXML.

Variable assignment:

  {attribute->getResourceRawSerialization assign='InstanceRawSerialization'}

Usage:

  {$InstanceRawSerialization}

getUnassigned

The second section of a template is where you assign instance records attributes/values to Smarty variables. However, rare are the cases where all the attributes/values get assigned to Smarty variables. In some use-cases, such as a generic template, you want to have displayed (in a special section of your layout) all these unassigned (un-templated) attribute/values. The getUnasigned API call is used to achieve this. It will create an array of unassigned attribute/values for the instance record being displayed.

The first thing to do is to assign that array in the variable assignation section of your template:

{attribute->getUnasigned assign='unasignedAttributes'}

Then, you can create a special section in your layout to display all these attributes to your users. In the example below, depending on the type of the value (resource or literal), the code will display the preferred label of the resource, or the literal:

{if count($unasignedAttributes) > 0}
  <h3 style="margin-top: 10px;">Other Information</h3>
 
  <table style="margin: 0px; padding: 0px; width: 670px;" border="0">
  <tbody>
  {foreach from=$unasignedAttributes item=value}
    {if $value.valueType == "resource"}
      <tr>
        <td style="width: 16px;" align="right">
          <span>
            <img style="vertical-align: middle;" 
                 src="/drupal/sites/all/modules/conStruct/templates/imgs/bullet_blue.png" 
                 alt="" 
                 width="16" 
                 height="16" />
          </span>
        </td>
        <td> 
          {$value.attributeLabel}: 
          <a href="?uri={$value.value}&dataset={$InstanceRecordDataset}">
            {$value.valueLiteral}
          </a> 
        </td>
      </tr>
    {else}
      <tr>
        <td style="width: 16px;" align="right">
          <span>
            <img style="vertical-align: middle;" 
                 src="/drupal/sites/all/modules/conStruct/templates/imgs/bullet_blue.png" 
                 alt="" 
                 width="16" 
                 height="16" />
          </span>
        </td>
        <td> {$value.attributeLabel}: {$value.valueLiteral} </td>
      </tr>
     {/if}
  {/foreach}
  </tbody>
  </table>
{/if}

getURI

This function will return the URI of the instance record being displayed.

Variable assignment:

  {attribute->getURI assign='InstanceRecordURI'}

Usage:

  {$InstanceRecordURI}

getValues

This function returns an array of values for a given attribute URI.

The returned array is composed of multiple arrays such as:

      array_push($values, array("value" => "...",
                                "valueType" => "...",
                                "valueLiteral" => "...",
                                "reify" => "..."));

Parameters:

  1. attribute: the URI of the attribute for which we want all the values

Variable assignment:

  {attribute->getValues attribute='http://xmlns.com/foaf/0.1/homepage' 
                        assign='foaf_homepageValues'}

Usage:

{if $foaf_homepageValues[0].value != ""}
  <table style="margin: 0px; padding: 0px;" border="0">
  <tbody>
    <tr>
      <td>
        <span>
          <img style="vertical-align: middle;" 
               title="Homepage" 
               src="/sites/all/modules/conStruct/templates/imgs/world_link.png" 
               alt="Homepage" 
               width="16" 
               height="16" />
        </span>
      </td>
      <td>
        <a href="{$foaf_homepageValues[0].value}">Homepage</a>
      </td>
    </tr>
  </tbody>
  </table>
{/if}

Examples

Using Conditional Structures

Not all instance records of a certain type are described the same way. Sometimes you could have the phone number of a person, but other times not. To accommodate this, it is recommended to use Smarty's conditional structure to change the layout of your template depending is what information is available, or not, for an instance record that is being displayed.

Here is an example:

{if $foaf_phoneValues[0].valueLiteral != ""}
  <table style="margin: 0px; padding: 0px;" border="0">
    <tbody>
      <tr>
        <td>
          <span>
            <img style="vertical-align: middle;" 
                 title="Phone" 
                 src="phone.png" 
                 alt="Phone" 
                 width="16" 
                 height="16" />
          </span>
        </td>
        <td>
          Phone: {$foaf_phoneValues[0].valueLiteral}
        </td>
      </tr>
    </tbody>
  </table>
{/if}


More examples/specific usecases to come later...

Deprecated structDisplay

There was an early attempt to link the Smarty template creation with the TinyMCE WYSIWYG rich text editor, an effort called structDisplay. That effort is not part of the current code base distribution for OSF, but its instruction manual is still a good source for background information and template ideas.

Personal tools