Skip to content

Metadata Display Viewers

Jordan Dukart edited this page Feb 18, 2014 · 3 revisions

About

Islandora now has additional ways to hook, customize and override the default metadata displays that appear underneath an object in it's view. It's to be noted that as the framework has changed a bit, however legacy implementations will not be effected.

The rendering of an object has been split into three parts:

  • Render the viewer for the content of the object.
  • Render the description for the object.
  • Render the metadata display for the object.

Object details image

This has been achieved by modifying the templates for the core solution packs. The metadata and description markup are pulled via includes/metadata.inc:

function islandora_retrieve_metadata_markup(AbstractObject $object, $print = FALSE) {
  $viewers = module_invoke_all('islandora_metadata_display_info');
  $viewer = variable_get('islandora_metadata_display', 'dublin_core');
  $markup = '';
  if (isset($viewers[$viewer]['metadata callback'])) {
    $markup = call_user_func($viewers[$viewer]['metadata callback'], $object, $print);
    // The callback doesn't have any markup provided for this particular object,
    // default back to the dublin_core display.
    if ($markup === FALSE) {
      $markup = call_user_func($viewers['dublin_core']['metadata callback'], $object, $print);
    }
  }
  return $markup;
}

function islandora_retrieve_description_markup(AbstractObject $object);
  $viewers = module_invoke_all('islandora_metadata_display_info');
  $viewer = variable_get('islandora_metadata_display', 'dublin_core');
  $markup = '';
  if (isset($viewers[$viewer]['description callback'])) {
    $markup = call_user_func($viewers[$viewer]['description callback'], $object);
    // The callback doesn't have any markup provided for this particular object,
    // default back to the dublin_core display.
    if ($markup === FALSE) {
      $markup = call_user_func($viewers['dublin_core']['description callback'], $object);
    }
  }
  return $markup;

These two functions are very similar in nature while the first passes along an optional print parameter used to distinguish when the metadata is being marked up for printing. To generalize what is happening, the hook_islandora_metadata_display_info hook is being fired to retrieve all potential viewers. We then get the default viewer set via the UI in Drupal. If the viewer has callbacks set they are executed. If a FALSE is returned we infer that the implementation does not wish to alter the metadata display thus we default back to the Dublin Core view.

These functions combined with the hook_islandora_metadata_display_info() hook allow for custom implementations to further extend the display of metadata in Islandora.

For example if we look at the basic image solution pack template for an object we see:

<div class="islandora-basic-image-object islandora" vocab="http://schema.org/" prefix="dcterms: http://purl.org/dc/terms/" typeof="ImageObject">
  <div class="islandora-basic-image-content-wrapper clearfix">
    <?php if (isset($islandora_content)): ?>
      <div class="islandora-basic-image-content">
        <?php print $islandora_content; ?>
      </div>
    <?php endif; ?>
  </div>
  <div class="islandora-basic-image-metadata">
    <?php print $description; ?>
    <?php if ($parent_collections): ?>
      <div>
        <h2><?php print t('In collections'); ?></h2>
        <ul>
          <?php foreach ($parent_collections as $collection): ?>
            <li><?php print l($collection->label, "islandora/object/{$collection->id}"); ?></li>
          <?php endforeach; ?>
        </ul>
      </div>
    <?php endif; ?>
    <?php print $metadata; ?>
  </div>
</div>

The basic image solution pack's preprocess function calls out to the two functions defined above to grab the variables. At the highest most level all that is concerned with is the location in the template.

Default Dublin Core implementation

By default Islandora ships with two metadata viewers. The Dublin Core display, which displays fields pulled from an object's Dublin Core datastream and no metadata displayed at all.

Dublin Core implementation of the hook from islandora.module:

function islandora_islandora_metadata_display_info() {
  return array(
    'dublin_core' => array(
      'label' => t('Dublin Core'),
      'description' => t('Dublin Core metadata'),
      'metadata callback' => 'islandora_metadata_display_callback',
      'description callback' => 'islandora_metadata_description_callback',
    ),
  );
}

The 'dublin_core' array defines a label and description used on the metadata display configuration page as well as callback functions. From includes/metadata.inc:

function islandora_metadata_display_callback(AbstractObject $object, $print = FALSE) {
  $elements = array(
    'islandora_object' => $object,
    'print' => $print,
  );
  return theme('islandora_dublin_core_display', $elements);
}

function islandora_metadata_description_callback(AbstractObject $islandora_object) {
  $elements = array(
    'islandora_object' => $islandora_object,
  );
  return theme('islandora_dublin_core_description', $elements);
}

Both of the above functions create variables to be passed along to their respective preprocess functions for their templates. However note that each individual callback expects markup to be returned so it'd be viable to return straight markup or a renderable array wrapped in drupal_render.

Preprocess functions from theme/theme.inc:

/**
 * Implements hook_preprocess().
 */
function islandora_preprocess_islandora_dublin_core_display(array &$variables) {
  $islandora_object = $variables['islandora_object'];
  if (islandora_datastream_access(ISLANDORA_VIEW_OBJECTS, $islandora_object['DC'])) {
    try {
      $dc = $islandora_object['DC']->content;
      $dc_object = DublinCore::importFromXMLString($dc);
    }
    catch (Exception $e) {
      drupal_set_message(t('Error retrieving object %s %t', array('%s' => $islandora_object->id, '%t' => $e->getMessage())), 'error', FALSE);
    }
  }
  $variables['dc_array'] = isset($dc_object) ? $dc_object->asArray() : array();
}

/**
 * Implements hook_preprocess().
 */
function islandora_preprocess_islandora_dublin_core_description(array &$variables) {
  $islandora_object = $variables['islandora_object'];
  if (islandora_datastream_access(ISLANDORA_VIEW_OBJECTS, $islandora_object['DC'])) {
    try {
      $dc = $islandora_object['DC']->content;
      $dc_object = DublinCore::importFromXMLString($dc);
    }
    catch (Exception $e) {
      drupal_set_message(t('Error retrieving object %s %t', array('%s' => $islandora_object->id, '%t' => $e->getMessage())), 'error', FALSE);
    }
  }
  $variables['dc_array'] = isset($dc_object) ? $dc_object->asArray() : array();
}

These functions just pass along the 'dc_array' to the templates for rendering.

The two template files islandora-dublin-core-display.tpl.php and islandora-dublin-core-description.tpl.php handle the actual markup representation of the variables we pass through. These are easily overwritable to conform to different looks and won't be looked at in depth in this document.

#Example module An example module can be viewed here for an example implementation of using the new functionality.

⚠️ This wiki is an archive for past meeting notes. For current minutes as well as onboarding materials, click here.

Clone this wiki locally