function tripal_core_node_view_build_toc

2.x tripal_core.toc.inc tripal_core_node_view_build_toc(&$build)
3.x tripal_core.toc.inc tripal_core_node_view_build_toc(&$build)

To be called by tripal_core_node_view_alter() to generate the TOC.

Parameters

$build: The build array passed to hook_node_view_alter()

1 call to tripal_core_node_view_build_toc()

File

tripal_core/includes/tripal_core.toc.inc, line 258

Code

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 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]);
        continue;
      }
      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;
          $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, $mode);
          $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;
          }

          // This field supports tokens, so we need to perform the substitutions
          // if one is needed. Get the tokens and format
          $base_table = preg_replace('/^chado_(.*)$/', '\1', $node_type);
          $tokens = chado_node_generate_tokens($base_table);
          $markup = $element['#markup'];
          // Determine which tokens were used in the format string
          if (preg_match_all('/\[[^]]+\]/', $markup, $used_tokens)) {
            // Get the value for each token used
            foreach ($used_tokens[0] as $token) {
              $token_info = $tokens[$token];
              if (!empty($token_info)) {
                $value = chado_get_token_value($token_info, $node);
                $markup = str_replace($token, $value, $markup);
              }
            }
            $element['#markup'] = $markup;
          }

          // 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>";
          }
          else {
            $toc[$weight][$parts[0]] = "<div id=\"$toc_item_id\" class=\"tripal_toc_list_item\">" . $element['#markup'] . "</div>";
          }

          // 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 ($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 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, $mode);

          // 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, $mode);


      // 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>";
}