作者:老葛,北京亚艾元软件有限责任公司,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,这个我们就不往下追踪了,有兴趣的可以继续往下分析下去。