Browse Source

Merge branch '7.x-1.x-2214785-toc' into 7.x-2.x

Stephen Ficklin 10 years ago
parent
commit
335cdd4d2f

+ 12 - 0
tripal_analysis/tripal_analysis.module

@@ -81,6 +81,18 @@ function tripal_analysis_menu() {
     'weight' => 2
   );
 
+  $items['admin/tripal/chado/tripal_analysis/toc'] = array(
+    'title' => ' TOC',
+    'description' => 'Manage the table of contents for analysis nodes.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('tripal_core_content_type_toc_form', 'chado_analysis'),
+    'access arguments' => array('administer tripal analysis'),
+    'type' => MENU_LOCAL_TASK,
+    'file' =>  'includes/tripal_core.toc.inc',
+    'file path' => drupal_get_path('module', 'tripal_core'),
+    'weight' => 3
+  );
+  
   return $items;
 }
 

+ 7 - 6
tripal_contact/tripal_contact.module

@@ -89,16 +89,17 @@ function tripal_contact_menu() {
     'weight' => 0
   );
 
-  $items['admin/tripal/chado/tripal_contact/sync'] = array(
-    'title' => ' Sync',
-    'description' => 'Create pages on this site for libraries stored in Chado',
+  $items['admin/tripal/chado/tripal_contact/toc'] = array(
+    'title' => ' TOC',
+    'description' => 'Manage the table of contents for contact nodes.',
     'page callback' => 'drupal_get_form',
-    'page arguments' => array('chado_node_sync_form', 'tripal_contact', 'chado_contact'),
+    'page arguments' => array('tripal_core_content_type_toc_form', 'chado_contact'),
     'access arguments' => array('administer tripal contact'),
     'type' => MENU_LOCAL_TASK,
-    'weight' => 2
+    'file' =>  'includes/tripal_core.toc.inc',
+    'file path' => drupal_get_path('module', 'tripal_core'),
+    'weight' => 3
   );
-
   return $items;
 }
 

+ 6 - 2
tripal_core/api/tripal_core.chado_nodes.api.inc

@@ -149,8 +149,12 @@ function chado_node_get_base_table($content_type, $module = FALSE) {
 
   function modulename_menu() {
 
-    $module_name = 'tripal_example';        // the machine name of your module
-    $linking_table = 'chado_example';       // the base specified in hook_node_info
+    //  the machine name of your module
+    $module_name = 'tripal_example';
+
+    // the base specified in hook_node_info
+    $linking_table = 'chado_example';
+
     // This menu item will be a tab on the admin/tripal/chado/tripal_example page
     // that is not selected by default
     $items['admin/tripal/chado/tripal_example/sync'] = array(

+ 2 - 4
tripal_core/api/tripal_core.chado_nodes.properties.api.inc

@@ -236,14 +236,12 @@ function chado_add_node_form_properties(&$form, &$form_state, $details) {
 
   // Get property types for the select list. If the user has provided a set
   // then use those, otherwise get them from the cvterm table for specified cv.
-  if (isset($details['select_options']) and
-      is_array($details['select_options']) and
-      count($details['select_options']) > 0) {
+  if (array_key_exists('select_options', $details) and
+      is_array($details['select_options'])) {
     $property_options = $details['select_options'];
   }
   // if the select options are not provided then try to get them on our own
   else {
-
     // if the vocabulary name is provided in the details then use that to
     // get the terms
     if (isset($details['cv_name'])) {

+ 5 - 3
tripal_core/api/tripal_core.chado_variables.api.inc

@@ -790,9 +790,11 @@ function chado_expand_var($object, $type, $to_expand, $table_options = array())
         // if we did not expand this table we should return a message that the foreign table
         // could not be expanded
         if (!$did_expansion) {
-          tripal_report_error('tripal_core', TRIPAL_ERROR, 'chado_expand_var: Could not expand table, %table. It is ' .
-            'not in a foreign key relationship with the base object nor with any other expanded table. ' .
-            'Check the table definition to ensure that a proper foreign key relationship is present.',
+          tripal_report_error('tripal_core', TRIPAL_ERROR, 'chado_expand_var: Could not expand %table. ' .
+            'The table is either not related to the base object through a foreign key relationships or ' .
+            'it is already expanded. First check the object to ensure it doesn’t already contain the ' .
+            'data needed and otherwise check the table definition using chado_get_schema() to ensure ' .
+            'a proper foreign key relationship is present.',
             array('%table' => $foreign_table));
         }
       }

+ 247 - 18
tripal_core/includes/tripal_core.toc.inc

@@ -5,6 +5,10 @@
  */
 function tripal_core_node_toc_form($form, &$form_state, $node) {
   
+  // Get info about this content type
+  $all_types = node_type_get_types();
+  $type_info = $all_types[$node->type];
+  
   $form["#tree"] = TRUE;
   
   $form["instructions"] = array(
@@ -13,15 +17,21 @@ function tripal_core_node_toc_form($form, &$form_state, $node) {
     '#collapsible' => TRUE,
     '#title' => 'Instructions',
   );
+  $admin_link = l(
+    $type_info->name . " TOC administrative page", 
+    "admin/tripal/chado/" . $type_info->module . "/toc",
+    array('attributes' => array('target' => '_blank'))
+  );
   $form["instructions"]["main"] = array(
-    '#markup' => '</p>' . t('Below is a list of the titles of
+    '#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>' .
+      pages of the same tpye, please visit the $admin_link. ") . '</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>'),
+      However, those without content are automatically hidden and do not 
+      appear in the TOC.' . '</p>'),
   );
   
   $form['node'] = array(
@@ -49,10 +59,23 @@ function tripal_core_node_toc_form($form, &$form_state, $node) {
       $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,
-      );
+
+      // If this element is a link then we don't want to allow the user
+      // to change the title as the link title is changed by using the
+      // interface that created the link.
+      $is_link = array_key_exists('#is_link', $element) ? $element['#is_link'] : FALSE;
+      if (!$is_link) {
+        $form['toc_items'][$toc_id]['title'] = array(
+          '#type' => 'textfield',
+          '#default_value' => $toc_title,
+        );
+      }
+      else {
+        $form['toc_items'][$toc_id]['title'] = array(
+          '#markup' => '<i>link title:</i> ' . $toc_title,
+          '#value' => $toc_title,
+        );
+      }
       $form['toc_items'][$toc_id]['hide'] = array(
         '#type' => 'checkbox',
         '#default_value' => $toc_hide,
@@ -148,7 +171,7 @@ function theme_tripal_node_toc_items_table($variables) {
  * @param $b
  */
 function theme_tripal_node_sort_toc_items($a, $b) {
-  
+
   if ($a['weight']['#value'] < $b['weight']['#value']) {
     return -1;
   }
@@ -159,6 +182,7 @@ function theme_tripal_node_sort_toc_items($a, $b) {
     return strcmp($a['title']['#value'], $b['title']['#value']);
   }
 }
+
 /**
  * Implements hook_validate for the tripal_core_node_toc_form.
  */
@@ -167,7 +191,7 @@ function tripal_core_node_toc_form_validate($form, &$form_state) {
 
   // Iterate through the TOC items and validate.
   foreach ($toc_items as $toc_id => $item) {
-    if (!$item['title']) {
+    if (array_key_exists('title', $item) and !$item['title']) {
       form_set_error('toc_items][' . $toc_id, "Please provide a valid title.");
     }
   }
@@ -193,7 +217,7 @@ function tripal_core_node_toc_form_submit($form, &$form_state) {
           ->fields(array(
             'node_type' => $node->type,
             'key' => $toc_id,
-            'title' => $item['title'],
+            'title' => array_key_exists('title', $item) ? $item['title'] : '',
             'weight' => $item['weight'],
             'nid' => $node->nid,
             'hide' => $item['hide'],
@@ -281,17 +305,38 @@ function tripal_core_node_view_build_toc(&$build) {
         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") {
+      // specifically recoginzed by Tripal v1.1.  If the mode type is "manage_type"
+      // then remove these content panes because they are node specific.
+      if ($mode == "manage_type" and (
+          $key == "field_resource_links" or
+          $key == "field_resource_titles" or
+          $key == "field_resource_blocks")) {
+        unset($build[$key]);
+      }
+      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;
-          $toc_item_id = "resource-$index";
-          
+          $hide = 0;
+          $toc_item_id = "resource-link-$index";
+
+          // Get any overrides for this key.
+          $overrides = tripal_core_get_toc_overrides($nid, $toc_item_id, $node_type);
+          $weight = $overrides['weight'] ? $overrides['weight'] : $weight;
+          $hide = $overrides['hide'] ? $overrides['hide'] : $hide;
+
+          // 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;
+          }
+
+          // Add the link to the TOC
           $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>";
@@ -299,17 +344,29 @@ function tripal_core_node_view_build_toc(&$build) {
           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]);
+
+          // Add to the build array but do not add markup. This way 
+          // when the TOC is managed by the node 'TOC' menu these links can
+          // be ordered as well.
+          $build[$toc_item_id]['#toc_handled'] = TRUE;
+          $build[$toc_item_id]['#tripal_toc_id'] = $toc_item_id;
+          $build[$toc_item_id]['#tripal_toc_title'] = $parts[0];
+          $build[$toc_item_id]['#weight'] = $weight;
+          $build[$toc_item_id]['#hide'] = $hide;
+          $build[$toc_item_id]['#is_link'] = TRUE;
+
         }
+        // Remove the orilink 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") {
+      if ($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") {
+      if ($key == "field_resource_blocks") {
         foreach (element_children($build[$key]) as $index) {
           // get the details and the title
           $weight = 0;
@@ -558,3 +615,175 @@ function tripal_core_get_toc_overrides($nid, $key, $node_type) {
     'hide' => $override_hide,
   );
 }
+
+/**
+ *
+ */
+function tripal_core_content_type_toc_form($form, &$form_state, $content_type) {
+
+  // Get the type details
+  $all_types = node_type_get_types();
+  $type_info = $all_types[$content_type];
+  
+  $form["#tree"] = TRUE;
+
+  // Get a single node of this type so we can get all the possible content for it
+  $sql = "SELECT nid FROM {node} WHERE type = :type LIMIT 1 OFFSET 0";
+  $nid = db_query($sql, array(':type' => $content_type))->fetchField();
+  if (!$nid) {
+    $form["not_available"] = array(
+      '#markup' => t('Please sync at least one %type_name record. A node 
+          must exist before customizations to the Table of Contents (TOC) can 
+          be performed.', array('%type_name' => $type_info->name)),
+    );
+    return $form;
+  } 
+  
+  // Load the node
+  $node = node_load($nid);
+
+  // 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_type';
+  
+  node_build_content($node);
+  $build = $node->content;
+  $build["#node"] = $node;
+  tripal_core_node_view_alter($build);
+  
+  $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 all %type_name pages.  You may rename
+      the titles or drag and drop them to change the order.  Content that appears
+      only on a single page can not be ordered here, but must be ordered using
+      the TOC tab on the page itself.  If a page has customized TOC settings
+      then those settings will take precedent over these.',
+        array('%type_name' => $type_info->name)) . '</p>' .
+    '<p>' . t('The list below shows all possible content
+      panes that can appear. However, those without content are automatically
+      hidden and do not appear in the TOC.' . '</p>'),
+  );
+  
+  $form['content_type'] = array(
+    '#type' => 'value',
+    '#value' => $content_type,
+  );
+
+  // 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('Reset to Defaults'),
+  );
+
+  return $form;
+}
+
+
+/**
+ * Implements hook_validate for the tripal_core_node_toc_form.
+ */
+function tripal_core_content_type_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_content_type_toc_form_submit($form, &$form_state) {
+  $toc_items    = $form_state['values']['toc_items'];
+  $content_type = $form_state['values']['content_type'];
+
+  if ($form_state['clicked_button']['#name'] == "toc_submit") {
+    $transaction = db_transaction();
+    try {
+      // First delete any settings for this content type
+      db_delete('tripal_toc')
+        ->condition('node_type', $content_type)
+        ->isNull('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' => $content_type,
+          'key' => $toc_id,
+          'title' => $item['title'],
+          'weight' => $item['weight'],
+          'hide' => $item['hide'],
+        ))
+        ->execute();
+      }
+      drupal_set_message("TOC changes successfully applied to this content type.");
+    }
+    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('node_type', $content_type)
+        ->isNull('nid')
+        ->execute();
+
+      drupal_set_message("The TOC is reset to defaults for this content type.");
+    }
+    catch (Exception $e) {
+      $transaction->rollback();
+      drupal_set_message("Failed to apply TOC changes.", "error");
+    }
+  }
+}

+ 1 - 1
tripal_cv/api/tripal_cv.api.inc

@@ -1044,7 +1044,7 @@ function tripal_set_default_cv($table, $field, $cv_name, $cv_id = FALSE) {
  *   cvterm table for which the default vocabulary will be set
  *
  * @return
- *   The cv array of the default vocabulary or an empty array if not
+ *   The cv object of the default vocabulary or an empty array if not
  *   available.
  */
 function tripal_get_default_cv($table, $field) {

+ 20 - 0
tripal_example/tripal_example.module

@@ -145,6 +145,26 @@ function tripal_example_menu() {
     'weight' => 2
   );
   
+  // EXPLANATION: If your module defines a new node type that uses the default
+  // table of contents (left-side bar of content panes on a page). Then a 
+  // 'TOC' link will automatically appear on the node page to allow for 
+  // customization of the TOC.  However those customizations are only node
+  // specific.  To provide a tab in the module's administrative pages add the
+  // following menu item. This menu will provide a form similar to the one
+  // found on the node that allows the user to set global TOC settings for the
+  // content type.
+  $items['admin/tripal/chado/tripal_example/toc'] = array(
+    'title' => ' TOC',
+    'description' => 'Manage the table of contents for example nodes.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('tripal_core_content_type_toc_form', 'chado_example'),
+    'access arguments' => array('administer tripal example'),
+    'type' => MENU_LOCAL_TASK,
+    'file' =>  'includes/tripal_core.toc.inc',
+    'file path' => drupal_get_path('module', 'tripal_core'),
+    'weight' => 3
+  );
+  
   return $items;
 }
 

+ 11 - 0
tripal_feature/tripal_feature.module

@@ -162,6 +162,17 @@ function tripal_feature_menu() {
     'type' => MENU_LOCAL_TASK,
     'weight' => 1
   );
+  $items['admin/tripal/chado/tripal_feature/toc'] = array(
+    'title' => ' TOC',
+    'description' => 'Manage the table of contents for feature nodes.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('tripal_core_content_type_toc_form', 'chado_feature'),
+    'access arguments' => array('administer tripal feature'),
+    'type' => MENU_LOCAL_TASK,
+    'file' =>  'includes/tripal_core.toc.inc',
+    'file path' => drupal_get_path('module', 'tripal_core'), 
+    'weight' => 3
+  );
   $items['admin/tripal/chado/tripal_feature/configuration'] = array(
     'title' => 'Settings',
     'description' => 'Configure the Tripal Feature module.',

+ 9 - 5
tripal_featuremap/tripal_featuremap.module

@@ -129,12 +129,16 @@ function tripal_featuremap_menu() {
     'weight' => 0
   );
 
-  // Synchronizing maps from Chado to Drupal
-  $items['chado_sync_featuremaps'] = array(
-    'title' => 'Sync Data',
-    'page callback' => 'tripal_featuremap_sync_featuremaps',
+  $items['admin/tripal/chado/tripal_featuremap/toc'] = array(
+    'title' => ' TOC',
+    'description' => 'Manage the table of contents for feature map nodes.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('tripal_core_content_type_toc_form', 'chado_featuremap'),
     'access arguments' => array('administer tripal featuremap'),
-    'type' => MENU_CALLBACK
+    'type' => MENU_LOCAL_TASK,
+    'file' =>  'includes/tripal_core.toc.inc',
+    'file path' => drupal_get_path('module', 'tripal_core'),
+    'weight' => 3
   );
 
   $items['admin/tripal/chado/tripal_featuremap/views/featuremaps/enable'] = array(

+ 16 - 6
tripal_library/includes/tripal_library.chado_node.inc

@@ -124,16 +124,26 @@ function chado_library_form($node, &$form_state) {
   );
 
   // get the list of library types
+  $lt_cv = tripal_get_default_cv("library", "type_id");
   $types = tripal_get_cvterm_default_select_options('library', 'type_id', 'library types');
   $types[0] = 'Select a Type';
+  $lt_message = tripal_set_message("To add additional items to the library type drop down list, 
+     add a term to the " . 
+     l($lt_cv->name . " controlled vocabulary", 
+       "admin/tripal/chado/tripal_cv/cv/" . $lt_cv->cv_id . "/cvterm/add",
+       array('attributes' => array('target' => '_blank'))
+      ),
+     TRIPAL_INFO, array('return_html' => TRUE)
+  );
 
   $form['library_type'] = array(
-    '#title'       => t('Library Type'),
-    '#type'        => t('select'),
-    '#description' => t("Choose the library type."),
-    '#required'    => TRUE,
+    '#title'         => t('Library Type'),
+    '#type'          => t('select'),
+    '#description'   => t("Choose the library type."),
+    '#required'      => TRUE,
     '#default_value' => $library_type,
-    '#options'     => $types,
+    '#options'       => $types,
+    '#suffix'        => $lt_message,
   );
 
   // get the list of organisms
@@ -173,7 +183,7 @@ function chado_library_form($node, &$form_state) {
   // to exclude the 'Library Description' term since it has it's own form element above
   if ($prop_cv->name == 'library_property') {
     // Generate our own select list so we can exclude the description element
-    $cv_result = chado_select_record('cv',array('cv_id'),array('name' => 'library_property'));
+    $cv_result = chado_select_record('cv', array('cv_id'), array('name' => 'library_property'));
     $cv_id = $cv_result[0]->cv_id;
     $select_options = tripal_get_cvterm_select_options($cv_id);
     $descrip_id = array_search('Library Description', $select_options);

+ 12 - 0
tripal_library/tripal_library.module

@@ -101,6 +101,18 @@ function tripal_library_menu() {
     'type' => MENU_LOCAL_TASK,
     'weight' => 2
   );
+  
+  $items['admin/tripal/chado/tripal_library/toc'] = array(
+    'title' => ' TOC',
+    'description' => 'Manage the table of contents for library nodes.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('tripal_core_content_type_toc_form', 'chado_library'),
+    'access arguments' => array('administer tripal library'),
+    'type' => MENU_LOCAL_TASK,
+    'file' =>  'includes/tripal_core.toc.inc',
+    'file path' => drupal_get_path('module', 'tripal_core'),
+    'weight' => 3
+  );
 
   $items['admin/tripal/chado/tripal_library/views/libraries/enable'] = array(
     'title' => 'Enable Library Administrative View',

+ 12 - 0
tripal_organism/tripal_organism.module

@@ -68,6 +68,18 @@ function tripal_organism_menu() {
     'type' => MENU_LOCAL_TASK,
     'weight' => 2
   );
+  
+  $items['admin/tripal/chado/tripal_organism/toc'] = array(
+    'title' => ' TOC',
+    'description' => 'Manage the table of contents for organism nodes.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('tripal_core_content_type_toc_form', 'chado_organism'),
+    'access arguments' => array('administer tripal organism'),
+    'type' => MENU_LOCAL_TASK,
+    'file' =>  'includes/tripal_core.toc.inc',
+    'file path' => drupal_get_path('module', 'tripal_core'),
+    'weight' => 3
+  );
 
   $items['admin/tripal/chado/tripal_organism/views/organisms/enable'] = array(
     'title' => 'Enable Organism Administrative View',

+ 12 - 0
tripal_project/tripal_project.module

@@ -76,6 +76,18 @@ function tripal_project_menu() {
     'type' => MENU_LOCAL_TASK,
     'weight' => 0
   );
+  
+  $items['admin/tripal/chado/tripal_project/toc'] = array(
+    'title' => ' TOC',
+    'description' => 'Manage the table of contents for project nodes.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('tripal_core_content_type_toc_form', 'chado_project'),
+    'access arguments' => array('administer tripal project'),
+    'type' => MENU_LOCAL_TASK,
+    'file' =>  'includes/tripal_core.toc.inc',
+    'file path' => drupal_get_path('module', 'tripal_core'),
+    'weight' => 3
+  );
 
   $items['admin/tripal/chado/tripal_project/views/projects/enable'] = array(
     'title' => 'Enable Project Administrative View',

+ 12 - 0
tripal_pub/tripal_pub.module

@@ -112,6 +112,18 @@ function tripal_pub_menu() {
     'type' => MENU_LOCAL_TASK,
     'weight' => 2
   );
+  
+  $items['admin/tripal/chado/tripal_pub/toc'] = array(
+    'title' => ' TOC',
+    'description' => 'Manage the table of contents for pub nodes.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('tripal_core_content_type_toc_form', 'chado_pub'),
+    'access arguments' => array('administer tripal pub'),
+    'type' => MENU_LOCAL_TASK,
+    'file' =>  'includes/tripal_core.toc.inc',
+    'file path' => drupal_get_path('module', 'tripal_core'),
+    'weight' => 3
+  );
 
   $items['admin/tripal/chado/tripal_pub/citation'] = array(
     'title' => 'Citations',

+ 12 - 0
tripal_stock/tripal_stock.module

@@ -78,6 +78,18 @@ function tripal_stock_menu() {
     'type' => MENU_LOCAL_TASK,
     'weight' => 0
   );
+  
+  $items['admin/tripal/chado/tripal_stock/toc'] = array(
+    'title' => ' TOC',
+    'description' => 'Manage the table of contents for stock nodes.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('tripal_core_content_type_toc_form', 'chado_stock'),
+    'access arguments' => array('administer tripal stock'),
+    'type' => MENU_LOCAL_TASK,
+    'file' =>  'includes/tripal_core.toc.inc',
+    'file path' => drupal_get_path('module', 'tripal_core'),
+    'weight' => 3
+  );
 
   $items['admin/tripal/chado/tripal_stock/help'] = array(
     'title' => 'Help',