Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/form.inc,v
retrieving revision 1.132
diff -u -F^f -r1.132 form.inc
--- includes/form.inc 5 Aug 2006 00:26:35 -0000 1.132
+++ includes/form.inc 7 Aug 2006 01:18:28 -0000
@@ -648,7 +648,15 @@ function form_render(&$elements) {
if (isset($content) && $content !== '') {
$prefix = isset($elements['#prefix']) ? $elements['#prefix'] : '';
$suffix = isset($elements['#suffix']) ? $elements['#suffix'] : '';
- return $prefix . $content . $suffix;
+ $content = $prefix . $content . $suffix;
+
+ if (isset($elements['#after_render'])) {
+ foreach ($elements['#after_render'] as $function) {
+ $function($elements, $content);
+ }
+ }
+
+ return $content;
}
}
Index: modules/blog/blog.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/blog/blog.module,v
retrieving revision 1.254
diff -u -F^f -r1.254 blog.module
--- modules/blog/blog.module 6 Aug 2006 23:00:41 -0000 1.254
+++ modules/blog/blog.module 7 Aug 2006 01:18:28 -0000
@@ -235,7 +235,7 @@ function blog_form(&$node) {
/**
* Implementation of hook_view().
*/
-function blog_view(&$node, $teaser = FALSE, $page = FALSE) {
+function blog_view($node, $teaser = FALSE, $page = FALSE) {
if ($page) {
// Breadcrumb navigation
$breadcrumb[] = array('path' => 'blog', 'title' => t('blogs'));
@@ -243,7 +243,7 @@ function blog_view(&$node, $teaser = FAL
$breadcrumb[] = array('path' => 'node/'. $node->nid);
menu_set_location($breadcrumb);
}
- $node = node_prepare($node, $teaser);
+ return node_prepare($node, $teaser);
}
/**
Index: modules/book/book.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/book/book.module,v
retrieving revision 1.378
diff -u -F^f -r1.378 book.module
--- modules/book/book.module 6 Aug 2006 23:00:41 -0000 1.378
+++ modules/book/book.module 7 Aug 2006 01:18:28 -0000
@@ -440,16 +440,6 @@ function book_content($node, $teaser = F
}
/**
- * Implementation of hook_view().
- *
- * If not displayed on the main page, we render the node as a page in the
- * book with extra links to the previous and next pages.
- */
-function book_view(&$node, $teaser = FALSE, $page = FALSE) {
- $node = node_prepare($node, $teaser);
-}
-
-/**
* Implementation of hook_nodeapi().
*
* Appends book navigation to all nodes in the book.
@@ -476,7 +466,10 @@ function book_nodeapi(&$node, $op, $teas
}
$node->breadcrumb[] = array('path' => 'node/'. $node->nid);
- $node->body .= theme('book_navigation', $node);
+ $node->content['book_navigation'] = array(
+ '#value' => theme('book_navigation', $node),
+ '#weight' => 100,
+ );
if ($page) {
menu_set_location($node->breadcrumb);
@@ -811,7 +804,7 @@ function book_node_visitor_html_pre($nod
$output .= "
". check_plain($node->title) ."
\n";
if ($node->body) {
- $output .= $node->body;
+ $output .= form_render($node->content);
}
return $output;
}
Index: modules/forum/forum.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/forum/forum.module,v
retrieving revision 1.344
diff -u -F^f -r1.344 forum.module
--- modules/forum/forum.module 6 Aug 2006 23:00:42 -0000 1.344
+++ modules/forum/forum.module 7 Aug 2006 01:18:28 -0000
@@ -313,8 +313,11 @@ function forum_view(&$node, $teaser = FA
}
$node = node_prepare($node, $teaser);
-
- $node->body .= theme('forum_topic_navigation', $node);
+ $node->content['forum_navigation'] = array(
+ '#value' => theme('forum_topic_navigation', $node),
+ '#weight' => 100,
+ );
+ return $node;
}
/**
Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.667
diff -u -F^f -r1.667 node.module
--- modules/node/node.module 6 Aug 2006 23:00:42 -0000 1.667
+++ modules/node/node.module 7 Aug 2006 01:18:28 -0000
@@ -636,24 +636,6 @@ function node_save(&$node) {
function node_view($node, $teaser = FALSE, $page = FALSE, $links = TRUE) {
$node = (object)$node;
- // Remove the delimiter (if any) that separates the teaser from the body.
- // TODO: this strips legitimate uses of '' also.
- $node->body = str_replace('', '', $node->body);
-
- if ($node->log != '' && !$teaser) {
- $node->body .= ''. t('Log') .':
'. filter_xss($node->log) .'
';
- }
-
- // The 'view' hook can be implemented to overwrite the default function
- // to display nodes.
- if (node_hook($node, 'view')) {
- node_invoke($node, 'view', $teaser, $page);
- }
- else {
- $node = node_prepare($node, $teaser);
- }
- // Allow modules to change $node->body before viewing.
- node_invoke_nodeapi($node, 'view', $teaser, $page);
if ($links) {
$node->links = module_invoke_all('link', 'node', $node, !$page);
@@ -662,11 +644,18 @@ function node_view($node, $teaser = FALS
$function($node, $node->links);
}
}
- // unset unused $node part so that a bad theme can not open a security hole
+
+ $node = node_build_content($node, $teaser, $page);
+
+ // Set the proper node part, then unset unused $node part so that a bad
+ // theme can not open a security hole.
+ $content = form_render($node->content);
if ($teaser) {
+ $node->teaser = $content;
unset($node->body);
}
else {
+ $node->body = $content;
unset($node->teaser);
}
@@ -674,16 +663,62 @@ function node_view($node, $teaser = FALS
}
/**
- * Apply filters to a node in preparation for theming.
+ * Apply filters and build the node's standard elements.
*/
function node_prepare($node, $teaser = FALSE) {
- $node->readmore = (strlen($node->teaser) < strlen($node->body));
- if ($teaser == FALSE) {
- $node->body = check_markup($node->body, $node->format, FALSE);
+ $node->content['body'] = array(
+ '#value' => check_markup($teaser ? $node->teaser : $node->body, $node->format, FALSE),
+ '#weight' => 0,
+ );
+
+ if ($node->log != '' && !$teaser) {
+ $node->content['log_message'] = array(
+ '#value' => theme('node_log_message', filter_xss($node->log)),
+ '#weight' => 20,
+ );
+ }
+
+ if (strlen($node->teaser) < strlen($node->body)) {
+ $node->readmore = TRUE;
+ }
+
+ return $node;
+}
+
+/**
+ * Builds a structured array representing the node's content.
+ *
+ * @param $node
+ * A node object.
+ * @param $teaser
+ * Whether to display the teaser only, as on the main page.
+ * @param $page
+ * Whether the node is being displayed by itself as a page.
+ *
+ * @return
+ * An structured array containing the individual elements
+ * of the node's body.
+ */
+function node_build_content($node, $teaser = FALSE, $page = FALSE) {
+ // Remove the delimiter (if any) that separates the teaser from the body.
+ // TODO: this strips legitimate uses of '' also.
+ $node->body = str_replace('', '', $node->body);
+
+ // The 'view' hook can be implemented to overwrite the default function
+ // to display nodes.
+ if (node_hook($node, 'view')) {
+ $node = node_invoke($node, 'view', $teaser, $page);
}
else {
- $node->teaser = check_markup($node->teaser, $node->format, FALSE);
+ $node = node_prepare($node, $teaser);
}
+
+ // Allow modules to make their own additions to the node.
+ node_invoke_nodeapi($node, 'view', $teaser, $page);
+
+ // Allow modules to modify the fully-built node.
+ node_invoke_nodeapi($node, 'alter', $teaser, $page);
+
return $node;
}
@@ -838,17 +873,10 @@ function node_search($op = 'search', $ke
// Load results
$results = array();
foreach ($find as $item) {
+ // Build the node body.
$node = node_load($item->sid);
-
- // Get node output (filtered and with module-specific fields).
- if (node_hook($node, 'view')) {
- node_invoke($node, 'view', FALSE, FALSE);
- }
- else {
- $node = node_prepare($node, FALSE);
- }
- // Allow modules to change $node->body before viewing.
- node_invoke_nodeapi($node, 'view', FALSE, FALSE);
+ $node = node_build_content($node, FALSE, FALSE);
+ $node->body = form_render($node->content);
// Fetch comments for snippet
$node->body .= module_invoke('comment', 'nodeapi', $node, 'update index');
@@ -2049,6 +2077,10 @@ function theme_node_preview($node) {
return $output;
}
+function theme_node_log_message($log) {
+ return ''. t('Log') .':
'. $log .'
';
+}
+
function node_form_submit($form_id, $edit) {
global $user;
@@ -2328,15 +2360,10 @@ function node_update_index() {
$last_nid = $node->nid;
$node = node_load($node->nid);
- // Get node output (filtered and with module-specific fields).
- if (node_hook($node, 'view')) {
- node_invoke($node, 'view', FALSE, FALSE);
- }
- else {
- $node = node_prepare($node, FALSE);
- }
- // Allow modules to change $node->body before viewing.
- node_invoke_nodeapi($node, 'view', FALSE, FALSE);
+ // Build the node body.
+ $node = node_load($item->sid);
+ $node = node_build_content($node, FALSE, FALSE);
+ $node->body = form_render($node->content);
$text = ''. check_plain($node->title) .'
'. $node->body;
Index: modules/poll/poll.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/poll/poll.module,v
retrieving revision 1.205
diff -u -F^f -r1.205 poll.module
--- modules/poll/poll.module 6 Aug 2006 23:00:42 -0000 1.205
+++ modules/poll/poll.module 7 Aug 2006 01:18:28 -0000
@@ -56,12 +56,11 @@ function poll_block($op = 'list', $delta
$poll = node_load(array('type' => 'poll', 'created' => $timestamp, 'status' => 1));
if ($poll->nid) {
- // poll_view() dumps the output into $poll->body.
- poll_view($poll, 1, 0, 1);
+ $poll = poll_view($poll, TRUE, FALSE, TRUE);
}
}
$block['subject'] = t('Poll');
- $block['content'] = $poll->body;
+ $block['content'] = form_render($poll->content);
return $block;
}
}
@@ -541,14 +540,14 @@ function poll_cancel(&$node) {
* An extra parameter that adapts the hook to display a block-ready
* rendering of the poll.
*/
-function poll_view(&$node, $teaser = FALSE, $page = FALSE, $block = FALSE) {
+function poll_view($node, $teaser = FALSE, $page = FALSE, $block = FALSE) {
global $user;
$output = '';
// Special display for side-block
if ($block) {
// No 'read more' link
- $node->body = $node->teaser = '';
+ $node->readmore = FALSE;
$links = module_invoke_all('link', 'node', $node, 1);
$links[] = array('title' => t('older polls'), 'href' => 'poll', 'attributes' => array('title' => t('View the list of polls on this site.')));
@@ -560,13 +559,16 @@ function poll_view(&$node, $teaser = FAL
}
if ($node->allowvotes && ($block || arg(2) != 'results')) {
- $output .= poll_view_voting($node, $teaser, $page, $block);
+ $node->content['body'] = array(
+ '#value' => poll_view_voting($node, $teaser, $page, $block),
+ );
}
else {
- $output .= poll_view_results($node, $teaser, $page, $block);
+ $node->content['body'] = array(
+ '#value' => poll_view_results($node, $teaser, $page, $block),
+ );
}
-
- $node->body = $node->teaser = $output;
+ return $node;
}
/**
Index: modules/upload/upload.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/upload/upload.module,v
retrieving revision 1.116
diff -u -F^f -r1.116 upload.module
--- modules/upload/upload.module 6 Aug 2006 23:00:42 -0000 1.116
+++ modules/upload/upload.module 7 Aug 2006 01:18:28 -0000
@@ -484,32 +484,36 @@ function upload_nodeapi(&$node, $op, $te
case 'view':
if (isset($node->files) && user_access('view uploaded files')) {
- // Manipulate so that inline references work in preview
- if (!variable_get('clean_url', 0)) {
- $previews = array();
- foreach ($node->files as $file) {
- if (strpos($file->fid, 'upload') !== FALSE) {
- $previews[] = $file;
- }
+ // Add the attachments list to node body with a heavy
+ // weight to ensure they're below other elements
+ if (count($node->files)) {
+ if (!$teaser && user_access('view uploaded files')) {
+ $node->content['files'] = array(
+ '#value' => theme('upload_attachments', $node->files),
+ '#weight' => 50,
+ );
}
-
- // URLs to files being previewed are actually Drupal paths. When Clean
- // URLs are disabled, the two do not match. We perform an automatic
- // replacement from temporary to permanent URLs. That way, the author
- // can use the final URL in the body before having actually saved (to
- // place inline images for example).
- foreach ($previews as $file) {
- $old = file_create_filename($file->filename, file_create_path());
- $new = url($old);
- $node->body = str_replace($old, $new, $node->body);
- $node->teaser = str_replace($old, $new, $node->teaser);
+ // Manipulate so that inline references work in preview
+ if (!variable_get('clean_url', 0)) {
+ $previews = array();
+ foreach ($node->files as $file) {
+ $file = (object)$file;
+ if (strpos($file->fid, 'upload') !== FALSE) {
+ $previews[] = $file;
+ }
+ }
+ // URLs to files being previewed are actually Drupal paths. When Clean
+ // URLs are disabled, the two do not match. We perform an automatic
+ // replacement from temporary to permanent URLs. That way, the author
+ // can use the final URL in the body before having actually saved (to
+ // place inline images for example).
+ foreach ($previews as $file) {
+ $old = file_create_filename($file->filename, file_create_path());
+ $node->content['#upload_urls'][$old] = url($old);
+ }
+ $node->content['#after_render'][] = 'upload_fix_preview_urls';
}
}
-
- // Add the attachments list to node body
- if (count($node->files) && !$teaser) {
- $node->body .= theme('upload_attachments', $node->files);
- }
}
break;
@@ -558,6 +562,18 @@ function upload_nodeapi(&$node, $op, $te
}
}
+function upload_fix_preview_urls($elements, &$content) {
+ if (is_array($elements['#upload_urls'])) {
+ $old_list = array();
+ $new_list = array();
+ foreach ($elements['#upload_urls'] as $old => $new) {
+ $old_list[] = $old;
+ $new_list[] = $new;
+ }
+ $content = str_replace($old_list, $new_list, $content);
+ }
+}
+
/**
* Displays file attachments in table
*/