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()
- tripal_core_node_view_alter in tripal_core/
tripal_core.module - Implements hook_node_view_alter()
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>";
}