Browse Source

Merge branch '7.x-2.x' of git.drupal.org:sandbox/spficklin/1337878 into 7.x-2.x

Lacey Sanderson 10 years ago
parent
commit
16d744185b

+ 560 - 0
tripal_core/includes/tripal_core.toc.inc

@@ -0,0 +1,560 @@
+<?php
+
+/**
+ * 
+ */
+function tripal_core_node_toc_form($form, &$form_state, $node) {
+  
+  $form["#tree"] = TRUE;
+  
+  $form["instructions"] = array(
+    '#type' => 'fieldset',
+    '#collapsed' => TRUE,
+    '#collapsible' => TRUE,
+    '#title' => 'Instructions',
+  );
+  $form["instructions"]["main"] = array(
+    '#markup' => '</p>' . t('Below is a list of the titles of
+      content panes that can appear on this page.  These titles appear in the 
+      the following order in the Table of Contents (TOC). You may rename 
+      the titles or drag and drop them to change the order.  <b>Any changes will
+      only apply to this page</b>. If you would like to make changes apply to multiple
+      pages of the same tpye, please visit the TOC administrative page.') . '<p>' .
+      '<p>' . t('The list below shows all possible content panes that can appear.
+      However, those without content are hidden and do not appear in the TOC.' . '</p>'),
+  );
+  
+  $form['node'] = array(
+    '#type' => 'value',
+    '#value' => $node,
+  );
+  
+  // Get the content array for this node, then pass it through the 
+  // tripal_core_node_view_alter which generates the TOC.  After that
+  // we can use the $build array to build the form. We have to add
+  // a 'tripal_toc_mode' to the $node because we need to give the mode
+  // to the tripal_core_node_view_build_toc function.
+  $node->tripal_toc_mode = 'manage_node';
+  node_build_content($node);
+  $build = $node->content;
+  $build["#node"] = $node;
+  tripal_core_node_view_alter($build);
+
+  // Iterate through the built items and add form elemetns for each one.
+  foreach(element_children($build) as $key) {
+    $element = $build[$key];
+
+    if (array_key_exists('#tripal_toc_id', $element)) {
+      $toc_id = $element['#tripal_toc_id'];
+      $toc_title = $element['#tripal_toc_title'];
+      $toc_weight = $element['#weight'];
+      $toc_hide = $element['#hide'];
+      $form['toc_items'][$toc_id]['title'] = array(
+        '#type' => 'textfield',
+        '#default_value' => $toc_title,
+      );
+      $form['toc_items'][$toc_id]['hide'] = array(
+        '#type' => 'checkbox',
+        '#default_value' => $toc_hide,
+      );
+      $form['toc_items'][$toc_id]['weight'] = array(
+        '#type' => 'textfield',
+        '#default_value' => $toc_weight,
+        '#attributes' => array(
+          'class' => array('tripal-node-toc-items-weights'),
+        ),
+        '#size' => 5,
+      );
+    }
+  }
+  $form['toc_items']['#theme'] = 'tripal_node_toc_items_table';
+  
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#name' => 'toc_submit',
+    '#value' => t('Submit'),
+  );
+  $form['unset'] = array(
+    '#type' => 'submit',
+    '#name' => 'toc_unset',
+    '#value' => t('Unset Node Customizations'),
+  );
+  
+  // Check to see if this node's TOC is specifically being managed.
+  $sql = "SELECT count(*) FROM {tripal_toc} where nid = :nid";
+  $managed_items = db_query($sql, array(':nid' => $node->nid))->fetchField();
+  
+  if ($managed_items > 0) {
+    $form['is_managed'] = array(
+      '#markup' => '<p><font color="red">' .
+      t('This page currently has customiations to the TOC.</font> This means
+        that any customzations for the content type are overriden. Click the
+        "Unset Node Customizations" button above to remove page-level
+        customizations and default to the content type settings.') . '</p>',
+    );
+  }
+  
+  
+  return $form;
+}
+/**
+ * 
+ * @param $variables
+ */
+function theme_tripal_node_toc_items_table($variables) {
+  $elements = $variables['element'];
+  $toc_items = array();
+
+  // Sort the toc_items using a custom sort function. But we need to include
+  // only the items we want in the table (exclude renderable stuff).
+  foreach(element_children($elements) as $key) {
+    $toc_items[] = $elements[$key];
+  }
+  usort($toc_items, 'theme_tripal_node_sort_toc_items');
+
+  // Build the table header.
+  $headers = array('Content Pane Name', 'Hide', 'Weight');
+  
+  // Format the form elements as rows in the table.
+  $rows = array();
+  foreach ($toc_items as $key => $item) {
+    $rows[] = array(
+      'data' => array(
+        drupal_render($item['title']),
+        drupal_render($item['hide']),
+        drupal_render($item['weight']),
+      ),
+      'class' => array('draggable'),
+    );
+  }
+  
+  // Theme and return the table.
+  $table = array(
+    'header' => $headers,
+    'rows' => $rows,
+    'attributes' => array("id" => 'tripal-node-toc-items-table'),
+    'sticky' => TRUE,
+    'caption' => t('Content Panes Available in the TOC'),
+    'colgroups' => array(),
+    'empty' => t('There are no content panes for this page'),
+  );
+  drupal_add_tabledrag('tripal-node-toc-items-table', 'order', 'sibling', 'tripal-node-toc-items-weights');
+  return theme_table($table);
+}
+
+/**
+ * 
+ * @param $a
+ * @param $b
+ */
+function theme_tripal_node_sort_toc_items($a, $b) {
+  
+  if ($a['weight']['#value'] < $b['weight']['#value']) {
+    return -1;
+  }
+  if ($a['weight']['#value'] > $b['weight']['#value']) {
+    return 1;
+  }
+  if ($a['weight']['#value'] == $b['weight']['#value']) {
+    return strcmp($a['title']['#value'], $b['title']['#value']);
+  }
+}
+/**
+ * Implements hook_validate for the tripal_core_node_toc_form.
+ */
+function tripal_core_node_toc_form_validate($form, &$form_state) {
+  $toc_items = $form_state['values']['toc_items'];
+
+  // Iterate through the TOC items and validate.
+  foreach ($toc_items as $toc_id => $item) {
+    if (!$item['title']) {
+      form_set_error('toc_items][' . $toc_id, "Please provide a valid title.");
+    }
+  }
+}
+/**
+ * Implements hook_submit for the tripal_core_node_toc_form.
+ */
+function tripal_core_node_toc_form_submit($form, &$form_state) {
+  $toc_items = $form_state['values']['toc_items'];
+  $node      = $form_state['values']['node'];
+  
+  if ($form_state['clicked_button']['#name'] == "toc_submit") { 
+    $transaction = db_transaction();
+    try {
+      // First delete any settings for this node
+      db_delete('tripal_toc')
+        ->condition('nid', $node->nid)
+        ->execute();
+  
+      // Second add in any new settings for this node 
+      foreach ($toc_items as $toc_id => $item) {
+        db_insert('tripal_toc')
+          ->fields(array(
+            'node_type' => $node->type,
+            'key' => $toc_id,
+            'title' => $item['title'],
+            'weight' => $item['weight'],
+            'nid' => $node->nid,
+            'hide' => $item['hide'],
+          ))
+          ->execute();
+      }
+      drupal_set_message("TOC changes successfully applied to this node only.");
+    }
+    catch (Exception $e) {
+      $transaction->rollback();
+      drupal_set_message("Failed to apply TOC changes.", "error");
+    }
+  }
+  if ($form_state['clicked_button']['#name'] == "toc_unset") {
+    $transaction = db_transaction();
+    try {
+      // First delete any settings for this node
+      db_delete('tripal_toc')
+        ->condition('nid', $node->nid)
+        ->execute();
+
+      drupal_set_message("TOC is no longer customized specifically for this page. Now using the content type settings.");
+    }
+    catch (Exception $e) {
+      $transaction->rollback();
+      drupal_set_message("Failed to apply TOC changes.", "error");
+    }
+  }
+}
+
+/**
+ * To be called by tripal_core_node_view_alter() to generate the TOC.
+ * 
+ * @param $build
+ *   The build array passed to hook_node_view_alter()
+ *
+ */
+function tripal_core_node_view_build_toc(&$build) {
+  global $theme;
+
+  // if this is not a full node view, we do not want to alter
+  if ($build['#view_mode'] != 'full' OR !array_key_exists('#tripal_generic_node_template', $build)) {
+    return;
+  }
+  
+  $node_type = $build["#node"]->type;
+  $nid = $build["#node"]->nid;
+  
+  // The mode alters the format of the build array. There are three types of
+  // modes: "display", "manage_node", "manage_type".  If "display" is provided
+  // then the build array is formatted for the display of the content.
+  // If "manage_node" is provided then the build array will contain all
+  // content panes regardless if the pane should be hidden. This allows
+  // the management tool to find all content panes and their settings. If
+  // "manage_type" is provided then node-specific content panes are
+  // excluded.  Node-specific content panes are those that appear only on
+  // specific nodes and therefore should not be used when managing the
+  // TOC for a content type.
+  $mode = isset($build["#node"]->tripal_toc_mode) ? $build["#node"]->tripal_toc_mode : "display";
+  
+  
+  $cache = cache_get("theme_registry:$theme", 'cache');
+  $node = $build['#node'];
+  $toc = array();
+  $toc_html = '';
+  
+  // If we are looking at a Tripal node template then we want to
+  // make some changes to each pane of content so that we can associate
+  // a table of contents and add administrator and curator messages.
+  if ($build['#tripal_generic_node_template'] == TRUE) {
+  
+    // Iterate through all the elements of the $build array and for those
+    // that are wanting to provide content for this node.
+    $markup = array();
+    foreach ($build as $key => $value) {
+      $value = $build[$key];
+      
+      // Skip the body element as the Tripal node types do not use it.
+      if ($key == 'body') {
+        continue;
+      }
+  
+      // Skip the table of contents and links as those will be placed elsewhere.
+      if (preg_match('/^#/', $key) or $key == 'tripal_toc' or $key == 'links') {
+        continue;
+      }
+
+      // For backwards compatibility we will handle the content type fields
+      // named 'field_resource_blocks', 'field_resource_titles', and 'field_resource_links'
+      // these fields can be added on the Drupal content types page and were
+      // specifically recoginzed by Tripal v1.1.
+      if ($mode != "manage_type" and $key == "field_resource_links") {
+        // links should just appear on the sidebar as is and not open up a panel
+        foreach (element_children($build[$key]) as $index) {
+          $element = $build[$key][$index];
+          $weight = 0;
+          $toc_item_id = "resource-$index";
+          
+          $parts = explode("|", $element['#markup']);
+          if (count($parts) == 2) {
+            $toc[$weight][$parts[0]] = "<div id=\"$toc_item_id\" class=\"tripal_toc_list_item\">" . l($parts[0], $parts[1], array('attributes' => array('target' => '_blank'))) . "</div>";
+          }
+          else {
+            $toc[$weight][$parts[0]] = "<div id=\"$toc_item_id\" class=\"tripal_toc_list_item\">" . $element['#markup'] . "</div>";
+          }
+          // remove this link from the build array as we've moved it to appear in the TOC
+          unset($build[$key]);
+        }
+        continue;
+      }
+      if ($mode != "manage_type" and $key == "field_resource_titles") {
+        // ignore these, we will use them in the field_resource_blocks if
+        // statement below
+        continue;
+      }
+      if ($mode != "manage_type" and $key == "field_resource_blocks") {
+        foreach (element_children($build[$key]) as $index) {
+          // get the details and the title
+          $weight = 0;
+          $hide = 0;
+          $markup = $build[$key][$index]["#markup"];
+          $toc_item_id = "resource-$index";
+
+          // Get any overrides for this key.
+          $overrides = tripal_core_get_toc_overrides($nid, $toc_item_id, $node_type);
+
+          // If the element should be hidden then unset this key the build
+          // array continue to the next one
+          if ($mode == "display" and $overrides['hide'] == 1) {
+            continue;
+          }
+
+          $toc_item_title = $build["field_resource_titles"][$index]["#markup"];
+          $toc_item_title = $overrides['title'] ? $overrides['title'] : $toc_item_title;
+          $weight = $overrides['weight'] ? $overrides['weight'] : $weight;
+          $hide = $overrides['hide'] ? $overrides['hide'] : $hide;
+          $updated_markup = "
+            <div id=\"$toc_item_id-tripal-data-pane\" class=\"tripal-data-pane\">
+              <div class=\"$toc_item_id-tripal-data-pane-title tripal-data-pane-title\">$toc_item_title</div>
+                $markup
+              </div>
+            </div>
+          ";
+          $build[$toc_item_id]['#markup'] = $updated_markup;
+          $build[$toc_item_id]['#toc_handled'] = TRUE;
+          $build[$toc_item_id]['#tripal_toc_id'] = $toc_item_id;
+          $build[$toc_item_id]['#tripal_toc_title'] = $toc_item_title;
+          $build[$toc_item_id]['#weight'] = $weight;
+          $build[$toc_item_id]['#hide'] = $hide;
+          // add the entry to the TOC
+          $toc_item_link = "
+            <div class=\"tripal_toc_list_item\">
+              <a id=\"$toc_item_id\" class=\"tripal_toc_list_item_link\" href=\"?pane=$toc_item_id\">$toc_item_title</a>
+            </div>
+          ";
+          $toc[$weight][$toc_item_title] = $toc_item_link;
+        }
+        // Remove the key from the build array. We have have replaced it
+        unset($build[$key]);
+        unset($build["field_resource_titles"]);
+        continue;
+      } // end if ($mode != "manage_type" and $key == "field_resource_blocks") {
+  
+      // Skip any keys we may have already handled. This is the case for
+      // the field_resource_blocks where we removed the old CCK fields
+      // and added new ones.  We don't want these new ones to be processed
+      // again by the code below.
+      if (array_key_exists('#toc_handled', $build[$key]) and $build[$key]['#toc_handled'] == TRUE) {
+        continue;
+      }
+
+      // For all other fields we will handle in the following way.
+      //-----------------------
+      // INITIALIZE THE CONTENT VARIABLES
+      //-----------------------
+      $toc_item_title = $key;
+      $toc_item_id    = $key;
+      $toc_item_link  = '';
+      $weight = 0;
+      $hide = 0;
+
+      // get the title for the table of contents.  Tripal templates should
+      // have a '#tripal_toc_title' element in the build array
+      if (array_key_exists('#tripal_toc_title', $build[$key])) {
+        $toc_item_title = $build[$key]['#tripal_toc_title'];
+      }
+      // other elements in the $build array may just have a '#title' element,
+      if (array_key_exists('#title', $build[$key])) {
+        $toc_item_title = $build[$key]['#title'];
+      }
+      $toc_item_title = ucwords($toc_item_title);
+      if (array_key_exists('#weight', $build[$key])) {
+        $weight = $build[$key]['#weight'];
+      }
+      if (array_key_exists('#tripal_toc_id', $build[$key])) {
+        $toc_item_id = $build[$key]['#tripal_toc_id'];
+      }
+      
+      // Get any overrides for this key.
+      $overrides = tripal_core_get_toc_overrides($nid, $toc_item_id, $node_type);
+
+      
+      // If the element should be hidden then unset this key the build
+      // array continue to the next one
+      if ($mode == "display" and $overrides['hide'] == 1) {
+        unset($build[$key]);
+        continue;
+      }
+
+      // now override the title, weight, hidden values if a value is set in the tripal_toc table
+      $toc_item_title = $overrides['title'] ? $overrides['title'] : $toc_item_title;
+      $weight = $overrides['weight'] ? $overrides['weight'] : $weight;
+      $hide = $overrides['hide'] ? $overrides['hide'] : $hide;
+      $toc_item_link = "<div class=\"tripal_toc_list_item\"><a id=\"$toc_item_id\" class=\"tripal_toc_list_item_link\" href=\"?pane=$toc_item_id\">$toc_item_title</a></div>";
+
+
+      //-----------------------
+      // GET THE MARKUP FOR EACH ELEMENT
+      //-----------------------
+      $markup = '';
+  
+      // find the markup. Some fields will have a '#markup' and others, such
+      // as CCK elements may have a set of '#markup' elements organized by
+      // numerical keys.
+      if (array_key_exists('#markup', $build[$key]) and trim($build[$key]['#markup'])) {
+        $markup = $build[$key]['#markup'];
+      }
+      // For backwards copmatibility we should support the '#value' element as well.
+      elseif (array_key_exists('#value', $build[$key]) and trim($build[$key]['#value'])) {
+        $markup = $build[$key]['#markup'];
+      }
+      // if we have no '#markup' field then this element has not yet
+      // been rendered.  Let's render it and substitute that for markup
+      if (!$markup) {
+        $markup = trim(render($build[$key]));
+      }
+
+      // Setup the content array for this element
+      $build[$key] = array(
+        '#markup' => $markup,
+        '#tripal_toc_id' => $toc_item_id,
+        '#tripal_toc_title' => $toc_item_title,
+        '#weight' => $weight,
+        '#hide' => $hide,
+      );
+      
+  
+        // if we still don't have markup then skip this one
+      if (!$markup) {
+        continue;
+      }
+  
+      //-----------------------
+      // FIND THE TEMPLATE PATH
+      //-----------------------
+      // get the template path so we can put it in an admin message box
+      $path = '';
+      if (!array_key_exists('#tripal_template_show', $build[$key]) or
+        $build[$key]['#tripal_template_show'] == TRUE) {
+        if ($cache and array_key_exists($key, $cache->data) and array_key_exists('path', $cache->data[$key])) {
+    
+          $path = $cache->data[$key]['path'] . '/' . $key . '.tpl.php';
+    
+          $path = tripal_set_message("Administrators, you can
+            customize the way the content above is presented.  Tripal provides a template
+            file for each pane of content.  To customize, copy the template file to your
+            site's default theme, edit then " .
+            l('clear the Drupal cache', 'admin/config/development/performance', array('attributes' => array('target' => '_blank'))) . ".
+            Currently, the content above is provided by this template: <br><br>$path",
+            TRIPAL_INFO,
+            array('return_html' => 1)
+          );
+        }
+      }
+    
+      //-----------------------
+      // ADD THIS PANE TO THE TOC BY ORDER OF WEIGHT
+      //-----------------------
+      // set the weight of the TOC item and add it to our $toc array
+      // for building of the TOC below
+      $weight = 0;
+      if (array_key_exists('#weight', $build[$key])) {
+        $weight = $build[$key]['#weight'];
+      }
+      $toc[$weight][$toc_item_title] = $toc_item_link;
+
+      //-----------------------
+      // CREATE THE CONTENT PANE MARKUP
+      //-----------------------
+      // add a surrounding <div> box around the content
+      $updated_markup = "
+        <div id=\"$toc_item_id-tripal-data-pane\" class=\"tripal-data-pane\">
+          <div class=\"$toc_item_id-tripal-data-pane-title tripal-data-pane-title\">$toc_item_title</div>
+            $markup
+            $path
+          </div>
+        </div>
+      ";
+  
+      $build[$key]['#markup'] = $updated_markup;
+    } // end foreach ($build as $key => $value) {
+  } // end if ($build['#tripal_generic_node_template'] == TRUE) {
+  
+  //-----------------------
+  // BUILD THE TABLE OF CONTENTS LINKS
+  //-----------------------
+  // first sort the links numerically by their weight
+  ksort($toc, SORT_NUMERIC);
+  $toc_html = '';
+  foreach ($toc as $weight => $links) {
+    // for links in the same weight, sort them alphabetically
+    ksort($links);
+    foreach ($links as $toc_item_title => $toc_item_link) {
+      $toc_html .= $toc_item_link;
+    }
+  }
+  $build['tripal_toc']['#markup'] = "<div id=\"$node->type-tripal-toc-pane\" class=\"tripal-toc-pane\">$toc_html</div>";
+}
+
+/**
+ * 
+ * @param $build
+ */
+function tripal_core_get_toc_overrides($nid, $key, $node_type) {
+  // Set override defaults
+  $override_title = '';
+  $override_weight = '';
+  $override_hide = 0;
+  
+  // First look to see if the node has customizations for this item.
+  $toc_item_overrides = db_select('tripal_toc', 'tc')
+    ->fields('tc', array('title', 'weight', 'hide'))
+    ->condition('key', $key)
+    ->condition('nid', $nid)
+    ->execute()
+    ->fetchObject();
+  if ($toc_item_overrides) {
+    $override_title = $toc_item_overrides->title;
+    $override_weight = $toc_item_overrides->weight;
+    $override_hide = $toc_item_overrides->hide;
+  }
+  // If there are no specific node customizations then look to see if there
+  // are customizations for this content type.
+  else {
+    $toc_item_overrides = db_select('tripal_toc', 'tc')
+      ->fields('tc', array('title', 'weight', 'hide'))
+      ->condition('node_type', $node_type)
+      ->condition('key', $key)
+      ->isNull('nid')
+      ->execute()
+      ->fetchObject();
+    if ($toc_item_overrides) {
+      $override_title = $toc_item_overrides->title;
+      $override_weight = $toc_item_overrides->weight;
+      $override_hide = $toc_item_overrides->hide;
+    }
+  }
+  
+  return array(
+    'title' => $override_title,
+    'weight' => $override_weight,
+    'hide' => $override_hide,
+  );
+}

+ 13 - 13
tripal_core/theme/css/tripal.css

@@ -89,22 +89,22 @@
 /******************************************************************************
  * The links that appear in the TOC section are added dynamically by
  * JavaScript code found at the top of the node--chado-generc.tpl.php template.
- * Each link in the TOC cooresponds to a "block" of data added to the Data
- * Column. Initially, the JavaScript hids all "blocks" except for the "Details"
- * block.  There will be as many blocks as there are TOC links.
+ * Each link in the TOC cooresponds to a "pane" of data added to the Data
+ * Column. Initially, the JavaScript hids all "panes" except for the "Details"
+ * pane.  There will be as many panes as there are TOC links.
  *
- * By default, all blocks have the following layout that consists of a
+ * By default, all panes have the following layout that consists of a
  * container div box with the class 'tripal-info-box', a div box to house the
- * block title with the class 'tripal-info-box-title', and a div box to
- * house a brief description about the block with the class
+ * pane title with the class 'tripal-info-box-title', and a div box to
+ * house a brief description about the pane with the class
  * 'tripal-info-box-desc'
  *
  * |-----------------------------------------------|
- * |  .tripal-data-block                           |
+ * |  .tripal-data-pane                            |
  * | |-------------------------------------------| |
- * | | .tripal-data-block-title                  | |
+ * | | .tripal-data-pane-title                   | |
  * | |-------------------------------------------| |
- * | | .tripal-data-block-desc                   | |
+ * | | .tripal-data-pane-desc                    | |
  * | |-------------------------------------------| |
  * |                                               |
  * | (Block data goes here)                        |
@@ -114,12 +114,12 @@
  * |                                               |
  * |-----------------------------------------------|
  */
-.tripal-data-block {
+.tripal-data-pane {
    padding: 0;
    margin:  0;
    width: 100%;
 }
-.tripal-data-block-title {
+.tripal-data-pane-title {
   font-size: 1.5em;
   padding-bottom: 5px;
 }
@@ -129,7 +129,7 @@
 }
 
 /**
- * Within the block data
+ * Within the pane data
  */
  .tripal-data-table {
    margin-top: 0px;
@@ -140,7 +140,7 @@
  * The teaser appears anywhere that a small snippet of the content is required.
  * When any node in Drupal is published to the home page a teaser is used.
  * Teasers can also be used in views to provide lists of content. The
- * teaser template is similar to the block but with the following sections and
+ * teaser template is similar to the pane but with the following sections and
  * classes
  *
  * |-----------------------------------------------|

+ 24 - 14
tripal_core/theme/templates/node--chado-generic.tpl.php

@@ -7,32 +7,42 @@ else {
   $node_type = $node->type; ?>
   
   <script type="text/javascript">
-    // we do not use Drupal Behaviors because we do not want this
+    // We do not use Drupal Behaviors because we do not want this
     // code to be executed on AJAX callbacks. This code only needs to 
     // be executed once the page is ready.
     jQuery(document).ready(function($){
 
-      // hide all but the first data block 
-      $(".tripal-data-block").hide().filter(":first-child").show();
+      // Hide all but the first data pane 
+      $(".tripal-data-pane").hide().filter(":first-child").show();
   
-      // when a title in the table of contents is clicked, then 
+      // When a title in the table of contents is clicked, then 
       // show the corresponding item in the details box 
       $(".tripal_toc_list_item_link").click(function(){
-        var id = $(this).attr('id') + "-tripal-data-block";
-        $(".tripal-data-block").hide().filter("#"+ id).fadeIn('fast');
+        var id = $(this).attr('id') + "-tripal-data-pane";
+        $(".tripal-data-pane").hide().filter("#"+ id).fadeIn('fast');
         return false;
       });
   
-      // if a ?block= is specified in the URL then we want to show the
-      // requested block
-      var block = window.location.href.match(/[\?|\&]block=(.+?)[\&|\#]/)
-      if(block == null){
-        block = window.location.href.match(/[\?|\&]block=(.+)/)
+      // If a ?pane= is specified in the URL then we want to show the
+      // requested content pane. For previous version of Tripal,
+      // ?block=, was used.  We support it here for backwards
+      // compatibility
+      var pane;
+      pane = window.location.href.match(/[\?|\&]pane=(.+?)[\&|\#]/)
+      if (pane == null) {
+        pane = window.location.href.match(/[\?|\&]pane=(.+)/)
       }
-      if(block != null){
-        $(".tripal-data-block").hide().filter("#" + block[1] + "-tripal-data-block").show();
+      // if we don't have a pane then try the old style ?block=
+      if (pane == null) {
+        pane = window.location.href.match(/[\?|\&]block=(.+?)[\&|\#]/)
+        if (pane == null) {
+          pane = window.location.href.match(/[\?|\&]block=(.+)/)
+        }
       }
-      // remove the 'active' class from the links section, as it doesn't
+      if(pane != null){
+        $(".tripal-data-pane").hide().filter("#" + pane[1] + "-tripal-data-pane").show();
+      }
+      // Remove the 'active' class from the links section, as it doesn't
       // make sense for this layout
       $("a.active").removeClass('active');
     });

+ 41 - 272
tripal_core/tripal_core.module

@@ -365,10 +365,39 @@ function tripal_core_menu() {
     'access arguments' => array('access content'),
     'type' => MENU_CALLBACK
   );
+  
+  // The node's TOC tab
+  $items['node/%node/tripal_toc'] = array(
+    'title' => 'TOC',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('tripal_core_node_toc_form', 1),
+    'access callback' => 'tripal_core_access_node_toc_form',
+    'access arguments' => array(1),
+    'type' => MENU_LOCAL_TASK,
+    'file' => '/includes/tripal_core.toc.inc',
+  );
 
   return $items;
 }
 
+/**
+ * An access wrapper function for editing the TOC
+ *
+ * @param $node
+ *   A node object
+ * @return
+ *   Returns TRUE if the node is a Tripal-based node and the user hass
+ *   the 'administer tripal' role.
+ */
+function tripal_core_access_node_toc_form($node) {
+  $types = module_invoke_all('node_info');
+  if (array_key_exists($node->type, $types) and 
+      array_key_exists('chado_node_api', $types[$node->type])) {
+    return user_access('administer tripal');
+  }
+  return FALSE;
+}
+
 /**
  * Implements hook_permission().
  *
@@ -463,7 +492,13 @@ function tripal_core_theme($existing, $type, $theme, $path) {
     'tripal_admin_message' => array(
       'function' => 'theme_tripal_admin_message',
       'variables' => array('message' => NULL),
-    )
+    ),
+    
+    // Form and form element themes.
+    // --------------------------------
+    'tripal_node_toc_items_table' => array(
+      'render element' => 'element',
+    ),
   );
 }
 
@@ -538,285 +573,19 @@ function tripal_core_views_api() {
   );
 }
 
-
 /**
- * After the node is built, we want to add instructions to each
- * content section letting the administrator know which template
- * they can customize
+ * Implements hook_node_view_alter()
  *
  * @param unknown $build
  */
 function tripal_core_node_view_alter(&$build) {
-  global $theme;
-
-  // if this is not a full node view, we do not want to alter
-  if ($build['#view_mode'] != 'full' OR !array_key_exists('#tripal_generic_node_template', $build)) {
-    return;
-  }
-
-  $node_type = $build["#node"]->type;
-  $nid = $build["#node"]->nid;
-
-
-  $cache = cache_get("theme_registry:$theme", 'cache');
-  $node = $build['#node'];
-  $toc = array();
-  $toc_html = '';
-
-  // if we are looking at a Tripal node template then we want to
-  // make some changes to each block of content so that we can associate
-  // a table of contents and add administrator and curator messages
-  if ($build['#tripal_generic_node_template'] == TRUE) {
-
-    // iterate through all the elements of the $build array and for those
-    // that are wanting to provide content for this node
-    $markup = array();
-    foreach ($build as $key => $value) {
-
-      // skip the body element as the Tripal node types do not use it
-      if ($key == 'body') {
-        continue;
-      }
-
-      // examine elements without a '#' prefix as these should be adding
-      // contents to the page. Skip the table of contents and links as those
-      // will be placed elsewhere
-      if (preg_match('/^#/', $key) or $key == 'tripal_toc' or $key == 'links') {
-        continue;
-      }
-      //kook to see if the title, position and visibilty of this element has
-      // custom settings.  First check if the node is customized then check
-      // if the node type.
-      $override_title = '';
-      $override_weight = '';
-      $override_hide = 0;
-      $toc_item_overrides = db_select('tripal_toc', 'tc')
-        ->fields('tc', array('toc_item_id', 'title', 'weight', 'hide'))
-        ->condition('node_type', $node_type)
-        ->condition('key', $key)
-        ->condition('nid', $nid)
-        ->execute()
-        ->fetchObject();
-      if ($toc_item_overrides) {
-        $override_title = $toc_item_overrides->title;
-        $override_weight = $toc_item_overrides->weight;
-        $override_hide = $toc_item_overrides->hide;
-      }
-      else {
-
-        // get the override title, weight for the general case
-        $toc_item_overrides = db_select('tripal_toc', 'tc')
-          ->fields('tc', array('toc_item_id', 'title', 'weight', 'hide'))
-          ->condition('node_type', $node_type)
-          ->condition('key', $key)
-          ->isNull('nid')
-          ->execute()
-          ->fetchObject();
-        if ($toc_item_overrides) {
-          $override_title = $toc_item_overrides->title;
-          $override_weight = $toc_item_overrides->weight;
-          $override_hide = $toc_item_overrides->hide;
-        }
-      }
-
-      // if the element should be hiddent then unset this key the build
-      // array continue to the next one
-      if ($override_hide == 1) {
-        unset($build[$key]);
-        continue;
-      }
-
-      // for backwards compatibility we will handle the content type fields
-      // named 'field_resource_blocks', 'field_resource_titles', and 'field_resource_links'
-      // these fields can be added on the Drupal content types page and were
-      // specifically recoginzed by Tripal v1.1.
-      if ($key == "field_resource_links") {
-        // links should just appear on the sidebar as is and not open up a panel
-        foreach (element_children($build[$key]) as $index) {
-          $element = $build[$key][$index];
-          $weight = 0;
-          $parts = explode("|", $element['#markup']);
-          if (count($parts) == 2) {
-            $toc[$weight][$parts[0]] = "<div class=\"tripal_toc_list_item\">" . l($parts[0], $parts[1], array('attributes' => array('target' => '_blank'))) . "</div>";
-          }
-          else {
-            $toc[$weight][$parts[0]] = "<div class=\"tripal_toc_list_item\">" . $element['#markup'] . "</div>";
-          }
-          // remove this link from the build array as we've moved it to appear in the TOC
-          unset($build[$key]);
-        }
-        continue;
-      }
-      if ($key == "field_resource_titles") {
-        // ignore these, we will use them in the field_resource_blocks if
-        // statement below
-        continue;
-      }
-      if ($key == "field_resource_blocks") {
-        foreach (element_children($build[$key]) as $index) {
-          // get the block details and the title
-          $weight = 0;
-          $markup = $build[$key][$index]["#markup"];
-          $toc_item_id = "resource-$index";
-          $toc_item_title = $build["field_resource_titles"][$index]["#markup"];
-          $updated_markup = "
-            <div id=\"$toc_item_id-tripal-data-block\" class=\"tripal-data-block\">
-              <div class=\"$toc_item_id-tripal-data-block-title tripal-data-block-title\">$toc_item_title</div>
-                $markup
-              </div>
-            </div>
-          ";
-          $build[$toc_item_id]['#markup'] = $updated_markup;
-          $build[$toc_item_id]['#weight'] = $weight;
-          $build[$toc_item_id]['#toc_handled'] = TRUE;
-          // add the entry to the TOC
-          $toc_item_link = "<div class=\"tripal_toc_list_item\"><a id=\"$toc_item_id\" class=\"tripal_toc_list_item_link\" href=\"?block=$toc_item_id\">$toc_item_title</a></div>";
-          $toc[$weight][$toc_item_title] = $toc_item_link;
-        }
-        // remove the key from the build array. We have have replaced it
-        unset($build[$key]);
-        unset($build["field_resource_titles"]);
-        continue;
-      }
-
-      // skip any keys we may have already handled. This is the case for
-      // the field_resource_blocks where we removed the old CCK fields
-      // and added new ones.  We don't want these new ones to be processed
-      // again by the code below.
-      if (array_key_exists('#toc_handled', $build[$key]) and $build[$key]['#toc_handled'] == TRUE) {
-        continue;
-      }
-
-      // for all other fields we will handle in the following way
-      //-----------------------
-      // INITIALIZE THE CONTENT VARIABLES
-      //-----------------------
-      $toc_item_title = $key;
-      $toc_item_id    = $key;
-      $toc_item_link  = '';
-
-      // get the title for the table of contents.  Tripal templates should
-      // have a '#tripal_toc_title' element in the build array
-      if (array_key_exists('#tripal_toc_title', $build[$key])) {
-        $toc_item_title = $build[$key]['#tripal_toc_title'];
-      }
-      // other elements in the $build array may just have a '#title' element,
-      if (array_key_exists('#title', $build[$key])) {
-        $toc_item_title = $build[$key]['#title'];
-      }
-      $toc_item_title = ucwords($toc_item_title);
-
-      // now override the title if a value is set in the tripal_toc table
-      $toc_item_title = $override_title ? $override_title : $toc_item_title;
-
-      if (array_key_exists('#tripal_toc_id', $build[$key])) {
-        $toc_item_id = $build[$key]['#tripal_toc_id'];
-      }
-      $toc_item_link = "<div class=\"tripal_toc_list_item\"><a id=\"$toc_item_id\" class=\"tripal_toc_list_item_link\" href=\"?block=$toc_item_id\">$toc_item_title</a></div>";
-
-
-      //-----------------------
-      // GET THE MARKUP FOR EACH ELEMENT
-      //-----------------------
-      $markup = '';
-
-      // find the markup. Some fields will have a '#markup' and others, such
-      // as CCK elements may have a set of '#markup' elements organized by
-      // numerical keys.
-      if (array_key_exists('#markup', $build[$key]) and trim($build[$key]['#markup'])) {
-        $markup = $build[$key]['#markup'];
-      }
-      // For backwards copmatibility we should support the '#value' element as well.
-      elseif (array_key_exists('#value', $build[$key]) and trim($build[$key]['#value'])) {
-        $markup = $build[$key]['#markup'];
-      }
-
-      // if we have no '#markup' field then this element has not yet
-      // been rendered.  Let's render it and substitute that for markup
-      if (!$markup) {
-        $markup = trim(render($build[$key]));
-        $build[$key] = array(
-          '#markup' => $markup,
-        );
-      }
-
-      // if we still don't have markup then skip this one
-      if (!$markup) {
-        continue;
-      }
-
-      //-----------------------
-      // FIND THE TEMPLATE PATH
-      //-----------------------
-      // get the template path so we can put it in an admin message box
-      $path = '';
-      if (!array_key_exists('#tripal_template_show', $build[$key]) or
-           $build[$key]['#tripal_template_show'] == TRUE) {
-        if ($cache and array_key_exists($key, $cache->data) and array_key_exists('path', $cache->data[$key])) {
-
-          $path = $cache->data[$key]['path'] . '/' . $key . '.tpl.php';
-
-          $path = tripal_set_message("Administrators, you can
-            customize the way the content above is presented.  Tripal provides a template
-            file for each block of content.  To customize, copy the template file to your
-            site's default theme, edit then " .
-            l('clear the Drupal cache', 'admin/config/development/performance', array('attributes' => array('target' => '_blank'))) . ".
-            Currently, the content above is provided by this template: <br><br>$path",
-            TRIPAL_INFO,
-            array('return_html' => 1)
-          );
-        }
-      }
-
-      //-----------------------
-      // SET THE WEIGHTS FOR THE TOC ELEMENTS
-      //-----------------------
-      // set the weight of the TOC item and add it to our $toc array
-      // for building of the TOC below
-      $weight = 0;
-      if (array_key_exists('#weight', $build[$key])) {
-        $weight = $build[$key]['#weight'];
-      }
-      // override the weight if it's set in the tripal_toc table
-      $weight = $override_weight ? $override_weight : $weight;
-      $toc[$weight][$toc_item_title] = $toc_item_link;
-
-      //-----------------------
-      // CREATE THE DATA BLOCK
-      //-----------------------
-      // add a surrounding <div> box around the content
-      $updated_markup = "
-        <div id=\"$toc_item_id-tripal-data-block\" class=\"tripal-data-block\">
-          <div class=\"$toc_item_id-tripal-data-block-title tripal-data-block-title\">$toc_item_title</div>
-            $markup
-            $path
-          </div>
-        </div>
-      ";
-
-      $build[$key]['#markup'] = $updated_markup;
-      $build[$key]['#weight'] = $weight;
-    } // end foreach ($build as $key => $value) {
-  } // end if ($build['#tripal_generic_node_template'] == TRUE) {
-
-  //-----------------------
-  // BUILD THE TABLE OF CONTENTS LINKS
-  //-----------------------
-  // first sort the links numerically by their weight
-  ksort($toc, SORT_NUMERIC);
-  $toc_html = '';
-  foreach ($toc as $weight => $links) {
-    // for links in the same weight, sort them alphabetically
-    ksort($links);
-    foreach ($links as $toc_item_title => $toc_item_link) {
-      $toc_html .= $toc_item_link;
-    }
-  }
-  $build['tripal_toc']['#markup'] = "<div id=\"$node->type-tripal-toc-block\" class=\"tripal-toc-block\">$toc_html</div>";
+  module_load_include('inc', 'tripal_core', 'includes/tripal_core.toc');
+  tripal_core_node_view_build_toc($build);
 }
 
 /**
- *
+ * Implements hook_node_view()
+ * 
  * @ingroup tripal_core
  */
 function tripal_core_node_view($node, $view_mode, $langcode) {

+ 3 - 3
tripal_db/api/tripal_db.api.inc

@@ -293,8 +293,8 @@ function tripal_get_dbxref($identifiers, $options = array()) {
  *   - urlprefix: (Optional) The URL that is to be used as a prefix when constructing a
  *     link to a database term
  * @param $options
- *   An associative array of options including:
- *   - update_existing: (Optional) Set this to '1' to force an update of the database if it
+ *   Optional. An associative array of options that can include:
+ *   - update_existing: Set this to '1' to force an update of the database if it
  *     already exists. The default is to not update. If the database exists
  *     then nothing is added.
  *
@@ -304,7 +304,7 @@ function tripal_get_dbxref($identifiers, $options = array()) {
  *
  * @ingroup tripal_db_api
  */
-function tripal_insert_db($values, $options) {
+function tripal_insert_db($values, $options = array()) {
 
   // Default Values
   $dbname = $values['name'];

+ 2 - 3
tripal_organism/theme/templates/tripal_organism_teaser.tpl.php

@@ -1,14 +1,13 @@
 <?php
 $organism  = $variables['node']->organism;
-$image_url  = tripal_get_organism_image($organism, $node->nid); 
-$image_path = tripal_get_organism_image($organism, $node->nid, 'path');?>
+$image_url  = tripal_get_organism_image_url($organism); ?>
 
 <div class="tripal_organism-teaser tripal-teaser"> 
   <div class="tripal-organism-teaser-title tripal-teaser-title"><?php 
     print l("<i>$organism->genus $organism->species</i> ($organism->common_name)", "node/$node->nid", array('html' => TRUE));?>
   </div>
   <div class="tripal-organism-teaser-text tripal-teaser-text"><?php 
-    if (file_exists($image_path)) { ?>
+    if ($image_url) { ?>
       <img class="tripal-teaser-img" src="<?php print $image_url ?>" ><?php
     } 
     print substr($organism->comment, 0, 650);