Преглед на файлове

Working on web services to support Chado table column names in the @context section

Stephen Ficklin преди 8 години
родител
ревизия
9c60387bcc

+ 31 - 7
tripal_chado/includes/fields/chado_base__organism_id.inc

@@ -179,8 +179,9 @@ class chado_base__organism_id extends TripalField {
 
     if (count($items) > 0) {
       $content =  $items[0]['value'];
-      if (array_key_exists('entity_id', $items[0])) {
-        $content = l(strip_tags($items[0]['value']), 'bio_data/' . $items[0]['entity_id']);
+      if (array_key_exists('entity', $items[0]['value'])) {
+        list($entity_type, $entity_id) = explode(':', $items[0]['value']['entity']);
+        $content = l(strip_tags($items[0]['value']['label']), 'bio_data/' . $entity_id);
       }
 
       // The cardinality of this field is 1 so we don't have to
@@ -242,22 +243,45 @@ class chado_base__organism_id extends TripalField {
 
     // Set some defaults for the empty record.
     $entity->{$field_name}['und'][0] = array(
-      'value' => '',
+      'value' => array(
+        'label' => '',
+        'genus' => '',
+        'species' => '',
+      ),
     );
 
     if ($record) {
       $organism = $record->organism_id;
       $string = $settings['field_display_string'];
-      $value = tripal_replace_chado_tokens($string, $organism);
-      $entity->{$field_name}['und'][0]['value'] = $value;
+      $label = tripal_replace_chado_tokens($string, $organism);
+      $entity->{$field_name}['und'][0]['value'] = array(
+        'label' => $label,
+        'genus' => $organism->genus,
+        'species' => $organism->species,
+      );
+      // The infraspecific fiels were introdcued in Chado v1.3.
+      if (property_exists($organism, 'infraspecific_name')) {
+        $entity->{$field_name}['und'][0]['value']['infraspecific_type'] = NULL;
+        $entity->{$field_name}['und'][0]['value']['infraspecific_name'] = $organism->infraspecific_name;
+        if ($organism->type_id) {
+          $entity->{$field_name}['und'][0]['value']['infraspecific_type'] =  $organism->type_id->name;
+        }
+      }
       $entity->{$field_name}['und'][0][$field_table . '__organism_id'] = $organism->organism_id;
 
       // Is there a published entity for this organism?
       if (property_exists($entity->chado_record->$field_column, 'entity_id')) {
         $fk_entity_id = $entity->chado_record->$field_column->entity_id;
-        $entity->{$field_name}['und'][0]['entity_id'] = $fk_entity_id;
-        $entity->{$field_name}['und'][0]['entity_type'] = 'TripalEntity';
+        $entity->{$field_name}['und'][0]['value']['entity'] = 'TripalEntity:' . $fk_entity_id;
       }
+
+      $entity->{$field_name}['und'][0]['semantic_web'] = array(
+        'label' => 'rdfs:label',
+        'genus' => tripal_get_chado_semweb_term('organism', 'genus'),
+        'species' => tripal_get_chado_semweb_term('organism', 'species'),
+        'infraspecific_name' => tripal_get_chado_semweb_term('organism', 'infraspecific_name'),
+        'infraspecific_type' => tripal_get_chado_semweb_term('organism', 'type_id'),
+      );
     }
   }
 

+ 14 - 8
tripal_chado/includes/fields/chado_gene__transcripts.inc

@@ -187,13 +187,13 @@ class chado_gene__transcripts extends TripalField {
 
       // Get the field values
       $feature_name = $transcript['name'];
-      $feature_uname = $transcript['unique name'];
+      $feature_uname = $transcript['identifier'];
       $loc = $transcript['location'];
       $type = $transcript['type'];
 
       // Add a link i there is an entity.
-      if (array_key_exists('entity_id', $item) and $item['entity_id']) {
-        $entity_id = $item['entity_id'];
+      if (array_key_exists('entity', $item['value']) and $item['value']['entity']) {
+        list($entity_type, $entity_id) = explode(':', $item['value']['entity']);
         $feature_name = l($feature_name, "bio_data/" . $entity_id, array('attributes' => array('target' => "_blank")));
       }
       $rows[] = array($feature_name, $feature_uname, $type, $loc);
@@ -251,7 +251,7 @@ class chado_gene__transcripts extends TripalField {
      $transcripts =  $rels['object']['part of']['mRNA'];
     }
 
-    $headers = array('Feature Name' ,'Unique Name', 'Location');
+    $headers = array('Name' ,'Identifier', 'Location');
     $rows = array();
     $i = 0;
     foreach ($transcripts as $transcript) {
@@ -265,17 +265,23 @@ class chado_gene__transcripts extends TripalField {
       }
       $type = $transcript->record->subject_id->type_id;
       $entity->{$field_name}['und'][$i]['value'] = array(
-        '@type' => $type->dbxref_id->db_id->name . ":" . $type->dbxref_id->accession,
         'type' => $type->name,
         'name' => $feature_name,
-        'unique name' => $transcript->record->subject_id->uniquename,
+        'identifier' => $transcript->record->subject_id->uniquename,
         'location' => $loc,
 
       );
+      // Add in the semantic web information that describes each key in the
+      // value array.
+      $entity->{$field_name}['und'][$i]['semantic_web'] = array(
+        'type' => $type->dbxref_id->db_id->name . ":" . $type->dbxref_id->accession,
+        'name' => tripal_get_chado_semweb_term('cvterm', 'name'),
+        'identifier' => tripal_get_chado_semweb_term('feature', 'uniquename'),
+        'location' => '',
+      );
       if (property_exists($transcript->record->subject_id, 'entity_id')) {
         $entity_id = $transcript->record->subject_id->entity_id;
-        $entity->{$field_name}['und'][$i]['entity_id'] = $entity_id;
-        $entity->{$field_name}['und'][$i]['entity_type'] = 'TripalEntity';
+        $entity->{$field_name}['und'][$i]['value']['entity'] = 'TripalEntity:' . $entity_id;
       }
       $i++;
     }

+ 3 - 4
tripal_chado/includes/fields/chado_linker__contact.inc

@@ -179,8 +179,8 @@ class chado_linker__contact extends TripalField {
       $type = $contact['type'];
 
       // Add a link i there is an entity.
-      if (array_key_exists('entity_id', $item) and $item['entity_id']) {
-        $entity_id = $item['entity_id'];
+      if (array_key_exists('entity', $item['value']) and $item['value']['entity']) {
+        list($entity_type, $entity_id) = explode(':', $item['value']['entity']);
         $contact_name = l($contact_name, "bio_data/" . $entity_id, array('attributes' => array('target' => "_blank")));
       }
       $rows[] = array($contact_name, $description, $type);
@@ -278,8 +278,7 @@ class chado_linker__contact extends TripalField {
         );
 
         if (property_exists($contact, 'entity_id')) {
-          $entity->{$field_name}['und'][$i]['entity_id'] = $contact->entity_id;
-          $entity->{$field_name}['und'][$i]['entity_type'] = 'TripalEntity';
+          $entity->{$field_name}['und'][$i]['value']['entity'] = 'TripalEntity:' . $contact->entity_id;
         }
       }
     }

+ 4 - 6
tripal_chado/includes/fields/chado_linker__expression.inc

@@ -173,8 +173,8 @@ class chado_linker__expression extends TripalField {
         // If this key is the name, then we want to link to the entity if one
         // exists.
         if ($key == 'name') {
-          if (array_key_exists('entity_id', $item) and $item['$entity_id']) {
-            $entity_id = $item['entity_id'];
+          if (array_key_exists('entity', $item['value']) and $item['value']['$entity_id']) {
+            list($entity_type, $entity_id) = explode(':', $item['value']['entity']);
             $value = l($value, "bio_data/" . $entity_id, array('attributes' => array('target' => "_blank")));
           }
         }
@@ -182,7 +182,7 @@ class chado_linker__expression extends TripalField {
         // and link to the pub if an entity exits.
         if ($key == 'publication') {
           $pub = $value['Citation'];
-          if (array_key_exists('publication', $item) and array_key_exists('entity_id', $item['publication'][0])) {
+          if (array_key_exists('publication', $item) and array_key_exists('entity', $item['publication'][0])) {
             $entity_id = $item['publication'][0]['entity_id'];
             $title =  $item['value']['publication']['Title'];
             $link = l($title, 'bio_data/' . $entity_id);
@@ -274,11 +274,9 @@ class chado_linker__expression extends TripalField {
           $pub_details = tripal_get_minimal_pub_info($pub);
 
           $entity->{$field_name}['und'][$i]['value']['publication'] = $pub_details;
-          $entity->{$field_name}['und'][$i]['value']['publication']['@type'] = $pub->type_id->dbxref_id->db_id->name . ':' . $pub->type_id->dbxref_id->accession;
           $entity->{$field_name}['und'][$i]['value']['publication']['type'] = $pub->type_id->name;
           if (property_exists($pub, 'entity_id')) {
-            $entity->{$field_name}['und'][$i]['publication'][0]['entity_id'] = $pub->entity_id;
-            $entity->{$field_name}['und'][$i]['publication'][0]['entity_type'] = 'TripalEntity';
+            $entity->{$field_name}['und'][$i]['publication'][0]['value']['entity'] = 'TripalEntity:' . $pub->entity_id;
           }
         }
 

+ 3 - 4
tripal_chado/includes/fields/chado_linker__genotype.inc

@@ -173,8 +173,8 @@ class chado_linker__genotype extends TripalField {
       $type = $genotype['type'];
 
       // Add a link i there is an entity.
-      if (array_key_exists('entity_id', $item) and $item['entity_id']) {
-        $entity_id = $item['entity_id'];
+      if (array_key_exists('entity', $item['value']) and $item['value']['entity']) {
+        list($entity_type, $entity_id) = explode(':', $item['value']['entity']);
         $genotype_name = l($genotype_name, "bio_data/" . $entity_id, array('attributes' => array('target' => "_blank")));
       }
       $rows[] = array($genotype_name, $description, $type);
@@ -271,8 +271,7 @@ class chado_linker__genotype extends TripalField {
         );
 
         if ($genotype && property_exists($genotype, 'entity_id')) {
-          $entity->{$field_name}['und'][$i]['entity_id'] = $genotype->entity_id;
-          $entity->{$field_name}['und'][$i]['entity_type'] = 'TripalEntity';
+          $entity->{$field_name}['und'][$i]['value']['entity'] = 'TripalEntity:' . $genotype->entity_id;
         }
       }
     }

+ 3 - 4
tripal_chado/includes/fields/chado_linker__phenotype.inc

@@ -173,8 +173,8 @@ class chado_linker__phenotype extends TripalField {
       $type = $phenotype['type'];
 
       // Add a link i there is an entity.
-      if (array_key_exists('entity_id', $item) and $item['entity_id']) {
-        $entity_id = $item['entity_id'];
+      if (array_key_exists('entity', $item['value']) and $item['value']['entity']) {
+        list($entity_type, $entity_id) = explode(':', $item['value']['entity']);
         $phenotype_name = l($phenotype_name, "bio_data/" . $entity_id, array('attributes' => array('target' => "_blank")));
       }
       $rows[] = array($phenotype_name, $value, $type);
@@ -272,8 +272,7 @@ class chado_linker__phenotype extends TripalField {
         );
 
         if ($phenotype && property_exists($phenotype, 'entity_id')) {
-          $entity->{$field_name}['und'][$i]['entity_id'] = $phenotype->entity_id;
-          $entity->{$field_name}['und'][$i]['entity_type'] = 'TripalEntity';
+          $entity->{$field_name}['und'][$i]['value']['entity'] = 'TripalEntity:' . $phenotype->entity_id;
         }
       }
     }

+ 1 - 2
tripal_chado/includes/fields/chado_linker__pub.inc

@@ -308,8 +308,7 @@ class chado_linker_pub extends TripalField {
         $entity->{$field_name}['und'][$i][$field_table . '--' . 'pub__uniquename'] =  $pub->uniquename;
 
         if (property_exists($pub, 'entity_id')) {
-          $entity->{$field_name}['und'][$i]['entity_id'] = $pub->entity_id;
-          $entity->{$field_name}['und'][$i]['entity_type'] = 'TripalEntity';
+          $entity->{$field_name}['und'][$i]['value']['entity'] = 'TripalEntity:' . $pub->entity_id;
         }
         $i++;
       }

+ 63 - 38
tripal_chado/includes/fields/chado_linker__relationship.inc

@@ -180,15 +180,15 @@ class chado_linker__relationship extends TripalField {
       $phrase = preg_replace("/$subject_type/", "<b>$subject_type</b>", $phrase);
       $phrase = preg_replace("/$object_type/", "<b>$object_type</b>", $phrase);
 
-      if (array_key_exists('entity_id', $item['value']['object'])) {
-        $object_entity_id = $item['value']['object']['entity_id'];
+      if (array_key_exists('entity', $item['value']['object'])) {
+        list($entity_type, $object_entity_id) = explode(':', $item['value']['object']['entity']);
         if ($object_entity_id != $entity->id) {
           $link = l($object_name, 'bio_data/' . $object_entity_id);
           $phrase = preg_replace("/$object_name/", $link, $phrase);
         }
       }
-      if (array_key_exists('entity_id', $item['value']['subject'])) {
-        $subject_entity_id = $item['value']['subject']['entity_id'];
+      if (array_key_exists('entity', $item['value']['subject'])) {
+        list($entity_type, $subject_entity_id) = explode(':', $item['value']['subject']['entity']);
         if ($subject_entity_id != $entity->id) {
           $link = l($subject_name, 'bio_data/' . $subject_entity_id);
           $phrase = preg_replace("/$subject_name/", $link, $phrase);
@@ -624,6 +624,9 @@ class chado_linker__relationship extends TripalField {
       'subject_name' => '',
       'type_name' => '',
     );
+
+    // If the table has rank and value fields then add those to the default
+    // value array.
     if (array_key_exists('value', $schema['fields'])) {
       $entity->{$field_name}['und'][0][$field_table . '__value'] = '';
     }
@@ -631,6 +634,7 @@ class chado_linker__relationship extends TripalField {
       $entity->{$field_name}['und'][0][$field_table . '__rank'] = '';
     }
 
+    // If we have no record then just return.
     if (!$record) {
       return;
     }
@@ -673,42 +677,50 @@ class chado_linker__relationship extends TripalField {
         $object_name = $relationship->object_id->name;
         $object_type = $relationship->object_id->type_id->name;
         $entity->{$field_name}['und'][$i]['value'] = array(
-          '@type' => $rel_acc,
+          'type' => $relationship->type_id->name,
           'subject' => array(
-            '@type' => $relationship->subject_id->type_id->dbxref_id->db_id->name .
-                ':' . $relationship->subject_id->type_id->dbxref_id->accession,
-            'type' =>  $subject_type,
+            'type' => $subject_type,
             'name' => $subject_name,
           ),
           'type' => $relationship->type_id->name,
           'object' => array(
-            '@type' => $relationship->object_id->type_id->dbxref_id->db_id->name .
-               ':' . $relationship->object_id->type_id->dbxref_id->accession,
-            // TODO the entity_id should not be here.... wherre to put it.
-            'entity_id' => $entity->id,
-            'entity_type' => 'TripalEntity',
-            'type' =>  $object_type,
+            'type' => $object_type,
             'name' => $object_name,
+            'entity' => 'TripalEntity:' . $entity->id,
           )
         );
         if (property_exists($relationship->subject_id, 'uniquename')) {
-          $subject_name = $relationship->subject_id->uniquename;
-          $entity->{$field_name}['und'][$i]['value']['subject']['name'] = $subject_name;
+          $entity->{$field_name}['und'][$i]['value']['subject']['identifier'] =  $relationship->subject_id->uniquename;;
         }
         if (property_exists($relationship->object_id, 'uniquename')) {
-          $object_name = $relationship->object_id->uniquename;
-          $entity->{$field_name}['und'][$i]['value']['object']['name'] = $object_name;
+          $entity->{$field_name}['und'][$i]['value']['object']['identifier'] = $relationship->object_id->uniquename;
         }
         if (property_exists($relationship->subject_id, 'entity_id')) {
           $entity_id = $relationship->subject_id->entity_id;
-          $entity->{$field_name}['und'][$i]['value']['subject']['entity_id'] = $entity_id;
-          $entity->{$field_name}['und'][$i]['value']['subject']['entity_type'] = 'TripalEntity';
+          $entity->{$field_name}['und'][$i]['value']['subject']['entity'] = 'TripalEntity:' . $entity_id;
         }
         $rel_type_clean = lcfirst(preg_replace('/_/', ' ', $rel_type));
         $entity->{$field_name}['und'][$i]['value']['phrase'] = 'The ' . $subject_type . ', ' .
           $subject_name . ', ' . $verb . ' '  . $rel_type_clean . ' this '  .
           $object_type . '.';
 
+        $entity->{$field_name}['und'][$i]['semantic_web'] = array(
+          'type' => $rel_acc,
+          'subject' => array(
+            $relationship->subject_id->type_id->dbxref_id->db_id->name . ':' . $relationship->subject_id->type_id->dbxref_id->accession,
+            array(
+              'type' => '',
+              'name' => '',
+            ),
+          ),
+          'object' => array(
+            $relationship->object_id->type_id->dbxref_id->db_id->name . ':' . $relationship->sobject_id->type_id->dbxref_id->accession,
+            array(
+              'type' => '',
+              'name' => '',
+            ),
+          ),
+        );
 
         $entity->{$field_name}['und'][$i][$field_table . '__' . $pkey] = $relationship->$pkey;
         $entity->{$field_name}['und'][$i][$field_table . '__subject_id'] = $relationship->subject_id->$subject_pkey;
@@ -716,8 +728,8 @@ class chado_linker__relationship extends TripalField {
         $entity->{$field_name}['und'][$i][$field_table . '__object_id'] = $relationship->object_id->$object_pkey;
 
         $entity->{$field_name}['und'][$i]['type_name'] = $relationship->type_id->name;
-        $entity->{$field_name}['und'][$i]['subject_name'] = $relationship->subject_id->uniquename . ' [id: ' . $relationship->subject_id->$fkey_rcolumn . ']';
-        $entity->{$field_name}['und'][$i]['object_name'] = $relationship->object_id->uniquename  . ' [id: ' . $relationship->object_id->$fkey_rcolumn . ']';
+        $entity->{$field_name}['und'][$i]['subject_name'] = $relationship->subject_id->name . ' [id: ' . $relationship->subject_id->$fkey_rcolumn . ']';
+        $entity->{$field_name}['und'][$i]['object_name'] = $relationship->object_id->name  . ' [id: ' . $relationship->object_id->$fkey_rcolumn . ']';
         if (array_key_exists('value', $schema['fields'])) {
           $entity->{$field_name}['und'][$i][$field_table . '__value'] = $relationship->value;
         }
@@ -738,48 +750,61 @@ class chado_linker__relationship extends TripalField {
         $object_name = $relationship->object_id->name;
         $object_type = $relationship->object_id->type_id->name;
         $entity->{$field_name}['und'][$i]['value'] = array(
-          '@type' => $rel_acc,
+          '@type' => $relationship->type_id->name,
           'subject' => array(
-            '@type' => $relationship->subject_id->type_id->dbxref_id->db_id->name .
-               ':' . $relationship->subject_id->type_id->dbxref_id->accession,
-            'type' =>  $subject_type,
+            'type' => $subject_type,
             'name' => $subject_name,
-            'entity_id' => $entity->id,
-            'entity_type' => 'TripalEntity',
+            'entity' => 'TripalEntity:' . $entity->id,
           ),
           'type' => $relationship->type_id->name,
           'object' => array(
-            '@type' => $relationship->object_id->type_id->dbxref_id->db_id->name .
-               ':' . $relationship->object_id->type_id->dbxref_id->accession,
             'type' =>  $object_type,
             'name' => $object_name,
           )
         );
         if (property_exists($relationship->subject_id, 'uniquename')) {
-          $subject_name = $relationship->subject_id->uniquename;
-          $entity->{$field_name}['und'][$i]['value']['subject']['name'] = $subject_name;
+          $entity->{$field_name}['und'][$i]['value']['subject']['identifier'] = $relationship->subject_id->uniquename;
         }
         if (property_exists($relationship->object_id, 'uniquename')) {
-          $object_name = $relationship->object_id->uniquename;
-          $entity->{$field_name}['und'][$i]['value']['object']['name'] = $object_name;
+          $entity->{$field_name}['und'][$i]['value']['object']['identifier'] = $relationship->object_id->uniquename;
         }
         if (property_exists($relationship->object_id, 'entity_id')) {
           $entity_id = $relationship->object_id->entity_id;
-          $entity->{$field_name}['und'][$i]['value']['object']['entity_id'] = $entity_id;
-          $entity->{$field_name}['und'][$i]['value']['object']['entity_type'] = 'TripalEntity';
+          $entity->{$field_name}['und'][$i]['value']['object']['entity'] = 'TripalEntity:' . $entity_id;
         }
         $rel_type_clean = lcfirst(preg_replace('/_/', ' ', $rel_type));
         $entity->{$field_name}['und'][$i]['value']['phrase'] = 'This  ' .
           $subject_type . ' ' . $verb . ' '  . $rel_type_clean . ' the '  .
           $object_type . ', ' . $object_name . '.';
+
+
+        $entity->{$field_name}['und'][$i]['semantic_web'] = array(
+          'type' => $rel_acc,
+          'subject' => array(
+            $relationship->subject_id->type_id->dbxref_id->db_id->name . ':' . $relationship->subject_id->type_id->dbxref_id->accession,
+            array(
+              'type' => '',
+              'name' => '',
+            ),
+          ),
+          'object' => array(
+            $relationship->object_id->type_id->dbxref_id->db_id->name . ':' . $relationship->sobject_id->type_id->dbxref_id->accession,
+            array(
+              'type' => '',
+              'name' => '',
+            ),
+          ),
+        );
+
+
         $entity->{$field_name}['und'][$i][$field_table . '__' . $pkey] = $relationship->$pkey;
         $entity->{$field_name}['und'][$i][$field_table . '__subject_id'] = $relationship->subject_id->$subject_pkey;
         $entity->{$field_name}['und'][$i][$field_table . '__type_id'] = $relationship->type_id->cvterm_id;
         $entity->{$field_name}['und'][$i][$field_table . '__object_id'] = $relationship->object_id->$object_pkey;
 
         $entity->{$field_name}['und'][$i]['type_name'] = $relationship->type_id->name;
-        $entity->{$field_name}['und'][$i]['subject_name'] = $relationship->subject_id->uniquename  . ' [id: ' . $relationship->subject_id->$fkey_rcolumn . ']';
-        $entity->{$field_name}['und'][$i]['object_name'] = $relationship->object_id->uniquename  . ' [id: ' . $relationship->object_id->$fkey_rcolumn . ']';
+        $entity->{$field_name}['und'][$i]['subject_name'] = $relationship->subject_id->name  . ' [id: ' . $relationship->subject_id->$fkey_rcolumn . ']';
+        $entity->{$field_name}['und'][$i]['object_name'] = $relationship->object_id->name  . ' [id: ' . $relationship->object_id->$fkey_rcolumn . ']';
 
         if (array_key_exists('value', $schema['fields'])) {
           $entity->{$field_name}['und'][$i][$field_table . '__value'] = $relationship->value;

+ 2 - 2
tripal_chado/includes/fields/chado_linker__synonym.inc

@@ -114,8 +114,8 @@ class chado_linker__synonym extends TripalField {
         ),
       ),
       'display' => array(
-        'deafult' => array(
-          'label' => 'above',
+        'default' => array(
+          'label' => 'inline',
           'type' => 'chado_linker__synonym_formatter',
           'settings' => array(),
         ),

+ 235 - 126
tripal_ws/includes/tripal_ws.rest.inc

@@ -94,7 +94,7 @@ function tripal_ws_handle_content_service($api_url, &$response, $ws_path, $param
   }
   // If we have a content type and an entity ID then show the entity
   else {
-    tripal_ws_get_content($api_url, $response, $ws_path, $ctype, $entity_id);
+    tripal_ws_get_content($api_url, $response, $ws_path, $ctype, $entity_id, $params);
   }
 }
 /**
@@ -436,47 +436,14 @@ function tripal_ws_get_content_type($api_url, &$response, $ws_path, $ctype, $par
 
 /**
  *
- * @param $api_url
- * @param $response
- * @param $ws_path
+ * @param unknown $response
+ * @param unknown $ws_path
+ * @param unknown $ctype
+ * @param unknown $entity_id
+ * @param unknown $params
  */
-function tripal_ws_get_content($api_url, &$response, $ws_path, $ctype, $entity_id) {
-
-  $context_vocabs = array();
-  $context_terms = array();
-
-  // First, add the vocabularies used into the @context section.
-  $response['@context']['rdfs'] = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
-  $response['@context']['hydra'] = 'http://www.w3.org/ns/hydra/core#';
-  $response['@context']['schema'] = 'https://schema.org/';
-
-  // Get the TripalBundle, TripalTerm and TripalVocab type for this type.
-  $bundle = tripal_load_bundle_entity(array('label' => $ctype));
-  $term = entity_load('TripalTerm', array('id' => $bundle->term_id));
-  $term = reset($term);
-  $vocab = $term->vocab;
-
-  // Add the vocabulary for this content type to the @context section.
-  if (!array_key_exists($vocab->vocabulary, $response['@context'])) {
-    // If there is no URL prefix then use this API's vocabulary API
-    if (property_exists($term, 'urlprefix')) {
-      $response['@context'][$vocab->vocabulary] = $term->urlprefix;
-    }
-    else {
-      $response['@context'][$vocab->vocabulary] = $api_url . '/vocab/' . $vocab->vocabulary . '/';
-    }
-  }
+function tripal_ws_get_content_add_fields($entity, $bundle, $api_url, &$response, $ws_path, $ctype, $entity_id, $params) {
 
-  // Get the TripalEntity
-  $entity = tripal_load_entity('TripalEntity', array('id' => $entity_id));
-  $entity = reset($entity);
-
-  // Next add in the ID and Type for this resources.
-  $response['@id'] = $api_url . '/content/' . $ctype . '/' . $entity_id;
-  $response['@type'] = $term->name;
-  $context_terms[$term->name] = $term->url;
-  $response['label'] = $entity->title;
-  $response['itemPage'] = url('/bio_data/' . $entity->id, array('absolute' => TRUE));
 
   // Get information about the fields attached to this bundle and sort them
   // in the order they were set for the display.
@@ -512,120 +479,262 @@ function tripal_ws_get_content($api_url, &$response, $ws_path, $ctype, $entity_i
     // from the instance.
     $field = field_info_field($field_name);
 
+    // By default, the label for the key in the output should be the
+    // term from the vocabulary that the field is assigned. But in the
+    // case that the field is not assigned a term, we must use the field name.
+    $field_name = $instance['field_name'];
+    $field_settings = $field['settings'];
+    $key = $field_name;
+    //$key = strtolower(preg_replace('/ /', '_', $key));
+    if (array_key_exists('semantic_web', $field_settings) and $field_settings['semantic_web']) {
+      list($vocabulary, $accession) = explode(':', $field_settings['semantic_web']);
+      $term = tripal_get_term_details($vocabulary, $accession);
+      if ($term) {
+        $key = $term['name'];
+        $response['@context'][$key] = array(
+          '@id' => $term['url'],
+        );
+      }
+    }
+
+    // If this field should not be attached by default then just add a link
+    // so that the caller can get the information separately.
+    $instance_settings = $instance['settings'];
+    if (array_key_exists('auto_attach', $instance_settings) and
+        $instance_settings['auto_attach'] != TRUE) {
+      $response['@context'][$key]['@type'] = '@id';
+      $response[$key] = $api_url . '/content/' . $ctype . '/' . $entity->id . '/' . urlencode($key);
+      continue;
+    }
+
     // Get the details for this field for the JSON-LD response.
-    $details = tripal_ws_get_field_JSON_LD($entity, $field, $instance, $api_url, $ctype);
-    //print_r($details);
-    $context_vocabs += $details['context']['vocabs'];
-    $context_terms += $details['context']['terms'];
-    $response += $details['value'];
+    tripal_ws_get_content_add_field($key, $entity, $field, $instance, $api_url, $response);
+
   }
 
   // Lastly, add in the terms used into the @context section.
-  $context_terms['label'] = 'rdfs:label';
-  $context_terms['itemPage'] = 'schema:itemPage';
+  $response['@context']['label'] = 'rdfs:label';
+  $response['@context']['itemPage'] = 'schema:itemPage';
 
-  $response['@context'] = array_merge($context_vocabs, $context_terms);
+  //   $response['operation'][] = array(
+  //     '@type' => 'hydra:DeleteResourceOperation',
+  //     'hydra:method' => 'DELETE'
+  //   );
+  //   $response['operation'][] = array(
+  //     '@type' => 'hydra:ReplaceResourceOperation',
+  //     'hydra:method' => 'POST'
+  //   );
+}
+/**
+ *
+ * @param unknown $field_arg
+ * @param unknown $api_url
+ * @param unknown $response
+ * @param unknown $ws_path
+ * @param unknown $ctype
+ * @param unknown $entity_id
+ * @param unknown $params
+ */
+function tripal_ws_get_content_find_field($field_arg, $ctype, $entity_id) {
 
-//   $response['operation'][] = array(
-//     '@type' => 'hydra:DeleteResourceOperation',
-//     'hydra:method' => 'DELETE'
-//   );
-//   $response['operation'][] = array(
-//     '@type' => 'hydra:ReplaceResourceOperation',
-//     'hydra:method' => 'POST'
-//   );
+  $bundle = tripal_load_bundle_entity(array('label' => $ctype));
+  $entity = tripal_load_entity('TripalEntity', array('id' => $entity_id));
+  $entity = reset($entity);
+  $term = NULL;
 
+  // Find the field whose term matches the one provied.
+  $value = array();
+  $instances = field_info_instances('TripalEntity', $bundle->name);
+  foreach ($instances as $instance) {
+    $field_name = $instance['field_name'];
+    $field = field_info_field($field_name);
+    $field_settings = $field['settings'];
+    if (array_key_exists('semantic_web', $field_settings) and
+        $field_settings['semantic_web']) {
+      list($vocabulary, $accession) = explode(':', $field_settings['semantic_web']);
+      $temp_term = tripal_get_term_details($vocabulary, $accession);
+      if ($temp_term['name'] == $field_arg) {
+        return array($entity, $bundle, $field, $instance, $temp_term);
+      }
+    }
+  }
 }
-
 /**
  *
+ * @param unknown $api_url
+ * @param unknown $response
+ * @param unknown $ws_path
+ * @param unknown $ctype
+ * @param unknown $entity_id
+ * @param unknown $params
+ * @return number
  */
-function tripal_ws_get_field_JSON_LD($entity, $field, $instance, $api_url, $ctype) {
+function tripal_ws_get_content($api_url, &$response, $ws_path, $ctype, $entity_id, $params) {
+  // First, add the vocabularies used into the @context section.
+  $response['@context']['rdfs'] = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
+  $response['@context']['hydra'] = 'http://www.w3.org/ns/hydra/core#';
+
+  // If we have an argument in the 4th element (3rd index) then the user
+  // is requesting to epxand the details of a field that was not
+  // initially attached to the enity.
+  $field_arg = '';
+  if (array_key_exists(3, $ws_path)) {
+
+    $field_arg = $ws_path[3];
+    list($entity, $bundle, $field, $instance, $term) = tripal_ws_get_content_find_field($field_arg, $ctype, $entity_id);
+
+    // Next add in the ID and Type for this resources.
+    $key = $term['name'];
+    $response['@context'][$key] = $term['url'];
+    $response['@id'] = $key;
+
+    // Attach the field and then add it's values to the response.
+    field_attach_load($entity->type, array($entity->id => $entity), FIELD_LOAD_CURRENT,
+        array('field_id' => $field['id']));
+
+    tripal_ws_get_content_add_field($key, $entity, $field, $instance, $api_url, $response, TRUE);
 
-  // Initialized the context array.
-  $context = array();
-  $context['vocabs'] = array();
-  $context['terms'] = array();
+    return;
+  }
+
+  // If we don't have a 4th argument then we're loading the base record.
+  // Get the TripalBundle, TripalTerm and TripalVocab type for this type.
+  $bundle = tripal_load_bundle_entity(array('label' => $ctype));
+  $term = entity_load('TripalTerm', array('id' => $bundle->term_id));
+  $term = reset($term);
+  $vocab = $term->vocab;
+
+  // Add the vocabulary for this content type to the @context section.
+  if (!array_key_exists($vocab->vocabulary, $response['@context'])) {
+    // If there is no URL prefix then use this API's vocabulary API
+    if (property_exists($term, 'urlprefix')) {
+      $response['@context'][$vocab->vocabulary] = $term->urlprefix;
+    }
+    else {
+      $response['@context'][$vocab->vocabulary] = $api_url . '/vocab/' . $vocab->vocabulary . '/';
+    }
+  }
+
+  // Get the TripalEntity
+  $entity = tripal_load_entity('TripalEntity', array('id' => $entity_id));
+  $entity = reset($entity);
 
+  // Next add in the ID and Type for this resources.
+  $response['@id'] = $api_url . '/content/' . $ctype . '/' . $entity_id;
+  $response['@type'] = $term->name;
+  $response['@context'][$term->name] = $term->url;
+  $response['label'] = $entity->title;
+  $response['itemPage'] = url('/bio_data/' . $entity->id, array('absolute' => TRUE));
+
+  tripal_ws_get_content_add_fields($entity, $bundle, $api_url, $response, $ws_path, $ctype, $entity_id, $params);
+
+}
+
+/**
+ *
+ */
+function tripal_ws_get_content_add_field($key, $entity, $field, $instance, $api_url, &$response, $is_field_page = NULL) {
   // Get the field  settings.
-  $field_name = $instance['field_name'];
+  $field_name = $field['field_name'];
   $field_settings = $field['settings'];
 
-  // By default, the label for the key in the output should be the
-  // term from the vocabulary that the field is assigned. But in the
-  // case that the field is not assigned a term, we must use the field name.
-  $key = $field_name;
-  $key = strtolower(preg_replace('/ /', '_', $key));
-  if (array_key_exists('semantic_web', $field_settings) and $field_settings['semantic_web']) {
-    list($vocabulary, $accession) = explode(':', $field_settings['semantic_web']);
-    $term = tripal_get_term_details($vocabulary, $accession);
-    if ($term) {
-      $key = $term['name'];
-      $key = strtolower(preg_replace('/ /', '_', $key));
-      //$context['vocabs'][$vocabulary] = ;
-      $context['terms'][$key] = array(
-        '@id' => $term['url'],
-//        $field_settings['semantic_web'];
-      );
+  $items = field_get_items('TripalEntity', $entity, $field_name);
+  $values = array();
+
+  for ($i = 0; $i < count($items); $i++) {
+
+    // See if the keys in the values array have been mapped to semantic
+    // web terms.
+    if (array_key_exists('semantic_web', $items[$i])) {
+      foreach ($items[$i]['semantic_web'] as $k => $v) {
+        list($vocabulary, $accession) = explode(':', $v);
+        $term = tripal_get_term_details($vocabulary, $accession);
+        if ($k == 'type') {
+          $items[$i]['value']['@type'] = $items[$i]['value']['type'];
+          unset($items[$i]['value']['type']);
+          $response['@context'][$term['name']] = $term['url'];
+        }
+        else {
+          $response['@context'][$k] = $term['url'];
+        }
+      }
     }
-  }
 
-  // Don't show fields that are not meant to be auto attached, even if the
-  // loading of the entity pulled a value for the field from the cache.
-  // We want the end-user to specifically load these.
-  $value = array();
-  $instance_settings = $instance['settings'];
-
-  if (array_key_exists('auto_attach', $instance_settings) and
-      $instance_settings['auto_attach'] == TRUE) {
-    $items = field_get_items('TripalEntity', $entity, $field_name);
-    for ($i = 0; $i < count($items); $i++) {
-
-      // If the value for this key is an array with an 'entity_id' key then
-      // we want to do a substitution.
-      if (array_key_exists('entity_id', $items[$i]) and $items[$i]['entity_id']) {
-        $lentity = entity_load($items[$i]['entity_type'], array($items[$i]['entity_id']));
-        $lentity = reset($lentity);
-        $lterm = tripal_load_term_entity(array('term_id' => $lentity->term_id));
-        $lvocab = tripal_load_vocab_entity(array('vocab_id' => $lterm->vocab_id));
-        $value[] = array(
-          '@id'   => $api_url . '/content/' . $lterm->name . '/' . $items[0]['entity_id'],
-          '@type' => $lvocab->vocabulary . ':' . $lterm->accession,
-          'label' => $lentity->title,
-          'type' => $lterm->name,
-        );
+    // Recurse through the values array and set the entity elemtns
+    // and add the fields to the context.
+    tripal_ws_get_content_add_field_context($items[$i], $response, $api_url);
 
-        if (property_exists($lvocab, 'vocabulary') and !array_key_exists($lvocab->vocabulary, $response['@context'])) {
-          $lterm_details = tripal_get_term_details($lvocab->vocabulary, $lterm->vocabulary);
-          if ($lterm_details) {
-            $context[$lvocab->vocabulary] = $lterm_details->url;
-          }
+    // Add the remaining values to the $values array.
+    $values[] = $items[$i]['value'];
+
+  }
+
+  // If we only have one value then set the response with just the value.
+  if (count($values) == 1) {
+    // If the value is an array and this is the field page then all of those
+    // key/value pairs should be added directly to the response.
+    if (is_array($values[0])) {
+      if ($is_field_page) {
+        foreach ($values[0] as $k => $v) {
+          $response[$k] = $v;
         }
       }
       else {
-        $value[] = $items[$i]['value'];
+        $response[$key] = $values[0];
       }
     }
-  }
-  // If the value shouldn't be attached by default then create a link for the
-  // caller to retrieve the information.
-  else {
-    $context['terms'][$key]['@type'] = '@id';
-    $value[] = $api_url . '/content/' . $ctype . '/' . $entity->id . '/' . urlencode($key);
-  }
-  // Convert a single value to not be an array.
-  if (count($value) == 1) {
-    $value = $value[0];
+    // If the value is not an array it's a scalar so add it as is to the
+    // response.
+    else {
+      $response[$key] = $values[0];
+    }
   }
 
-  return array(
-    'context' => $context,
-    'value' => array(
-      $key => $value
-    ),
-  );
+  // If we have more than one value then set the response to be a collection.
+  if (count($values) > 1) {
+
+    // If this is the field page then the Collection is added directly to the
+    // response, otherwise, it's added under the field $key.
+    if ($is_field_page) {
+      $response['@type'] = 'Collection';
+      $response['totalItems'] = count($values);
+      $response['label'] = $instance['label'];
+      $response['member'] = $values;
+    }
+    else {
+      $response[$key] = array(
+        '@type' => 'Collection',
+        'totalItems' => count($values),
+        'label' => $instance['label'],
+        'member' => $values,
+      );
+    }
+  }
 }
 
+/**
+ *
+ */
+function tripal_ws_get_content_add_field_context(&$items, &$response, $api_url) {
+
+  foreach ($items as $key => $value) {
+    if (is_array($value)) {
+      tripal_ws_get_content_add_field_context($items[$key], $response, $api_url);
+      continue;
+    }
+
+    if ($key == 'entity') {
+      list($item_etype, $item_eid) = explode(':', $items['entity']);
+      if ($item_eid) {
+        $item_entity = tripal_load_entity($item_etype, array($item_eid));
+        $item_entity = reset($item_entity);
+        $item_term = tripal_load_term_entity(array('term_id' => $item_entity->term_id));
+        $items['@id'] = $api_url . '/content/' . $item_term->name . '/' . $item_eid;
+      }
+      unset($items['entity']);
+    }
+  }
+}
 
 /**
  * Provides the Hydra compatible apiDocumentation page that describes this API.