Display Templates Tutorial

From CollectiveAccess Documentation
Jump to: navigation, search

Writing in progress!

If you need to output information from your CollectiveAccess database then you need to know about display templates. Display templates have evolved quite a bit over the last few versions of CollectiveAccess, from a simple way to layout field data in HTML to a capable, but more complex, data retrieval and formatting system. Display templates are a critical element in the design of CollectiveAccess displays (reports), search/browse result views, data export formats, editing interfaces and Pawtucket views.

This tutorial will give you a grounding in both the theory and application of display templates, touching upon all of the important features and options along the way. A description of display template syntax and options is also available with a list of options and short example templates.

The Problem

Whether you're designing reports, summarizing "tombstone" information for labels, displaying critical details in an editing interface or constructing easy-to-read summaries for a web site, you're doing the same thing: retrieving data from CollectiveAccess, formatting it in various ways, and outputting it to where it is needed. The need to format data for output is constant and critical.

If all you wish to do is output a selection of fields for a record, all that is needed is to line the fields up in order. Indeed, the CA displays system provides a drag-and-drop interface to do just that. The result is a simple list of values that is easy to create but not terribly flexible. If you need to do more – to pull in data from related records, filter the set of data to output, vary formatting based upon field values, convert measurements or perform many other useful transformations – you need a way to clearly specify to CollectiveAccess what must be done. Display templates provide a compact syntax for describing what is output, and how.

Template Basics

The simplest template is just a bit of text:

Hello world!

This template results in the literal display of that text. Easy but not terribly useful. Including some data from CollectiveAccess would be a good next step. To insert data pulled from CollectiveAccess you need to include a placeholder for that data. Placeholders always start with the ^ (caret) character, followed by the specifier for the data you wish to insert. For example, if you are writing a template to display data for object records and a metadata element named description is part of your object record, then the specifier for that element is ca_objects.description, where ca_objects is the code for the type of record you're pulling data from (objects) and description is the metadata element code. In a template, a placeholder is formed using the specifier prefixed with a ^ to distinguish it as something to be processed rather than output as text. A template to output our object description preceded by a field title would be:

Description: ^ca_objects.description

Common problem 1: Configuring the display of a container element

The issue: While creating a Display, you notice that the output for a Container element doesn't look quite right. Each value in the Container is output as a list delimited by semi-colons. Take the following example:

Container ex.png

If you simply added the "Condition Reporting" element to your Display and did not configure a template, the output would be:

Good; Minor scratches; Tom Smith; 2016-07-01

Quick answer: If you wish to format this bundle for Display, you'll need to use a display template. Here is one that could work:

<unit>
<ifdef code="ca_objects.condition_reporting.condition_rating"><b>Rating:</b> ^ca_objects.condition_reporting.condition_rating<br/></ifdef>
<ifdef code="ca_objects.condition_reporting.condition_notes"><b>Notes:</b> ^ca_objects.condition_reporting.condition_notes<br/></ifdef>
<ifdef code="ca_objects.condition_reporting.condition_report_date"><b>Date:</b> ^ca_objects.condition_reporting.condition_report_date<br/></ifdef>
<ifdef code="ca_objects.condition_reporting.condition_examined_by"><b>Examined by:</b> ^ca_objects.condition_reporting.condition_examined_by<br/></ifdef>
<br/>
</unit>

In a search results display, the output would look like this:

Container display.png

Explanation: To see what's going here, let's build this template from the ground up.

For each line, the simplest possible template would simply be:

<b>Rating:</b> ^ca_objects.condition_reporting.condition_rating<br/>

This displays "Rating:" in bold, pulls the value from the placeholder, and adds a line break before the next template.

The problem with this Display, is that "Rating:" would print out regardless of whether or not there is actually data in ca_objects.condition_reporting.condition_rating! To account for this, we use <ifdef>. By wrapping the template in <ifdef>, you ensure that the template will only output if there is actually data in the placeholder value.

This way, the output looks good if there is data in just one, two, three, or all of the container's sub-elements.

<ifdef code="ca_objects.condition_reporting.condition_rating"><b>Rating:</b> ^ca_objects.condition_reporting.condition_rating<br/></ifdef>
<ifdef code="ca_objects.condition_reporting.condition_notes"><b>Notes:</b> ^ca_objects.condition_reporting.condition_notes<br/></ifdef>
<ifdef code="ca_objects.condition_reporting.condition_report_date"><b>Date:</b> ^ca_objects.condition_reporting.condition_report_date<br/></ifdef>
<ifdef code="ca_objects.condition_reporting.condition_examined_by"><b>Examined by:</b> ^ca_objects.condition_reporting.condition_examined_by<br/></ifdef>

For more information about formatting with <ifdef> see here and here.

We're almost there. In the event that the Condition Reporting container element is a repeatable container, we need to use the <unit> tag. Without the unit tag, the output would print every Rating value followed by every Notes value, followed by every Date value, and so on.

<unit> ensures that each container is evaluated as single group of data, which gets us to our final template:

<unit>
<ifdef code="ca_objects.condition_reporting.condition_rating"><b>Rating:</b> ^ca_objects.condition_reporting.condition_rating<br/></ifdef>
<ifdef code="ca_objects.condition_reporting.condition_notes"><b>Notes:</b> ^ca_objects.condition_reporting.condition_notes<br/></ifdef>
<ifdef code="ca_objects.condition_reporting.condition_report_date"><b>Date:</b> ^ca_objects.condition_reporting.condition_report_date<br/></ifdef>
<ifdef code="ca_objects.condition_reporting.condition_examined_by"><b>Examined by:</b> ^ca_objects.condition_reporting.condition_examined_by<br/></ifdef>
<br/>
</unit>

For more detail on formatting templates with <unit> go here.

Common problem 2: Displaying metadata from related records

The issue: By default, a relationship bundle (e.g related entities, related occurrences,) may display only the preferred label for the related records, or perhaps the label, idno, and the relationship type. However, you need to pull other attributes from the related record for display. For example, perhaps you wish to have a related entities bundle that displays the name and life dates for each entity, in addition to the relationship type between the entity and the primary record in the display.

Quick Answer: You can create templates to pull as many attributes from the related record as you need. Here's a template that would give you the above:

<l>^ca_entities.preferred_labels.displayname</l> <ifdef code="ca_entities.life_dates">[Life dates: ^ca_entities.life_dates]</ifdef>(^relationship_typename)<br/>

Explanation: By default, a relationships bundle is relative to the relationship itself - which is why when you add additional attributes, such as Entity life dates or address - it's always evaluated once for each relationship to the object. You can use this in conjunction with <unit> to pull container attributes from the related record.

Common problem 3: Displaying related records on related records

The issue: Let's say you have an Objects display where you wish to display the related Lot, but in the template you also want to display Entities that are related to the Lot record (and not related directly to the object record).

Quick Answer: Here is where the relativeTo option comes in handy. relativeTo allows the template to shift its focus from the primary record or relationship, to the related record.

<l>^ca_object_lots.preferred_labels</l>
	<br/>
	^ca_object_lots.idno_stub
	<br/>
<unit relativeTo="ca_entities" restrictToRelationshipTypes="donor"><b>Donor:</b> ^ca_entities.preferred_labels.displayname</unit>

Explanation: In the above example, the template is evaluated against the Object x Lot relationship. By shifting relativeTo to ca_entities, you can pull the related Entities on the Lot record into the Object display template. The following would give you the Lot title, identifer, and the Donor related entity.

sphinx

Namespaces

Variants
Actions
Navigation
Tools
User
Personal tools