You are here

14 node_page_view代码追踪

admin 的头像
Submitted by admin on 星期四, 2015-07-30 09:18

作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com

现在让我们来看一下node_page_view返回了什么,我们在node.module里面找到这个函数。

/**

 * Menu callback: Displays a single node.

 *

 * @param $node

 *   The node object.

 *

 * @return

 *   A page array suitable for use by drupal_render().

 *

 * @see node_menu()

 */

function node_page_view($node) {

  // If there is a menu link to this node, the link becomes the last part

  // of the active trail, and the link name becomes the page title.

  // Thus, we must explicitly set the page title to be the node title.

  drupal_set_title($node->title);

  $uri = entity_uri('node', $node);

  // Set the node path as the canonical URL to prevent duplicate content.

  drupal_add_html_head_link(array('rel' => 'canonical', 'href' => url($uri['path'], $uri['options'])), TRUE);

  // Set the non-aliased path as a default shortlink.

  drupal_add_html_head_link(array('rel' => 'shortlink', 'href' => url($uri['path'], array_merge($uri['options'], array('alias' => TRUE)))), TRUE);

  return node_show($node);

}

这里面具体复杂的是node_show($node),我们来看node_show的定义:

/**

 * Generates an array which displays a node detail page.

 *

 * @param $node

 *   A node object.

 * @param $message

 *   A flag which sets a page title relevant to the revision being viewed.

 *

 * @return

 *   A $page element suitable for use by drupal_render().

 */

function node_show($node, $message = FALSE) {

  if ($message) {

    drupal_set_title(t('Revision of %title from %date', array('%title' => $node->title, '%date' => format_date($node->revision_timestamp))), PASS_THROUGH);

  }

 

  // For markup consistency with other pages, use node_view_multiple() rather than node_view().

  $nodes = node_view_multiple(array($node->nid => $node), 'full');

 

  // Update the history table, stating that this user viewed this node.

  node_tag_new($node);

 

  return $nodes;

}

这里返回的是一个数组,Drupal将具体的实现又交给了node_view_multiple,只不过当前只有一个节点。我们来看node_view_multiple

/**

 * Constructs a drupal_render() style array from an array of loaded nodes.

 *

 * @param $nodes

 *   An array of nodes as returned by node_load_multiple().

 * @param $view_mode

 *   View mode, e.g. 'full', 'teaser'...

 * @param $weight

 *   An integer representing the weight of the first node in the list.

 * @param $langcode

 *   (optional) A language code to use for rendering. Defaults to NULL which is

 *   the global content language of the current request.

 *

 * @return

 *   An array in the format expected by drupal_render().

 */

function node_view_multiple($nodes, $view_mode = 'teaser', $weight = 0, $langcode = NULL) {

  field_attach_prepare_view('node', $nodes, $view_mode, $langcode);

  entity_prepare_view('node', $nodes, $langcode);

  $build = array();

  foreach ($nodes as $node) {

    $build['nodes'][$node->nid] = node_view($node, $view_mode, $langcode);

    $build['nodes'][$node->nid]['#weight'] = $weight;

    $weight++;

  }

  $build['nodes']['#sorted'] = TRUE;

  return $build;

}

这里返回的是一个数组,包含节点的数组,可以使用drupal_render呈现这个数组。而这里,单个节点的构件,则是由node_view完成的。

/**

 * Generates an array for rendering the given node.

 *

 * @param $node

 *   A node object.

 * @param $view_mode

 *   View mode, e.g. 'full', 'teaser'...

 * @param $langcode

 *   (optional) A language code to use for rendering. Defaults to the global

 *   content language of the current request.

 *

 * @return

 *   An array as expected by drupal_render().

 */

function node_view($node, $view_mode = 'full', $langcode = NULL) {

  if (!isset($langcode)) {

    $langcode = $GLOBALS['language_content']->language;

  }

 

  // Populate $node->content with a render() array.

  node_build_content($node, $view_mode, $langcode);

 

  $build = $node->content;

  // We don't need duplicate rendering info in node->content.

  unset($node->content);

 

  $build += array(

    '#theme' => 'node',

    '#node' => $node,

    '#view_mode' => $view_mode,

    '#language' => $langcode,

  );

 

  // Add contextual links for this node, except when the node is already being

  // displayed on its own page. Modules may alter this behavior (for example,

  // to restrict contextual links to certain view modes) by implementing

  // hook_node_view_alter().

  if (!empty($node->nid) && !($view_mode == 'full' && node_is_page($node))) {

    $build['#contextual_links']['node'] = array('node', array($node->nid));

  }

 

  // Allow modules to modify the structured node.

  $type = 'node';

  drupal_alter(array('node_view', 'entity_view'), $build, $type);

 

  return $build;

}

这里我们可以看一下,这个数组的具体结构,如粗体代码所示。node_build_content,这个我们就不往下追踪了,有兴趣的可以继续往下分析下去。


Drupal版本: