? LOCAL-REROLL.txt ? apc.php ? constants.pl ? exception.php ? head.kpf ? head.sql.gz ? patches ? test.php ? modules/field/field.delete.inc ? modules/field/modules/combo ? scripts/generate-autoload.pl ? sites/all/cck ? sites/all/pbs ? sites/all/modules/admin_menu ? sites/all/modules/cck ? sites/all/modules/devel ? sites/all/modules/taint ? sites/default/files ? sites/default/settings.php Index: modules/field/modules/list/list.info =================================================================== RCS file: /cvs/drupal/drupal/modules/field/modules/list/list.info,v retrieving revision 1.2 diff -u -F^[fc] -r1.2 list.info --- modules/field/modules/list/list.info 5 Feb 2009 03:42:57 -0000 1.2 +++ modules/field/modules/list/list.info 9 Mar 2009 19:42:29 -0000 @@ -4,3 +4,4 @@ package = Core - fields core = 7.x files[]=list.module +required = TRUE Index: modules/field/modules/number/number.info =================================================================== RCS file: /cvs/drupal/drupal/modules/field/modules/number/number.info,v retrieving revision 1.2 diff -u -F^[fc] -r1.2 number.info --- modules/field/modules/number/number.info 5 Feb 2009 03:42:57 -0000 1.2 +++ modules/field/modules/number/number.info 9 Mar 2009 19:42:29 -0000 @@ -4,3 +4,4 @@ package = Core - fields core = 7.x files[]=number.module +required = TRUE Index: modules/field/modules/options/options.info =================================================================== RCS file: /cvs/drupal/drupal/modules/field/modules/options/options.info,v retrieving revision 1.1 diff -u -F^[fc] -r1.1 options.info --- modules/field/modules/options/options.info 3 Feb 2009 17:30:11 -0000 1.1 +++ modules/field/modules/options/options.info 9 Mar 2009 19:42:29 -0000 @@ -4,3 +4,4 @@ package = Core - fields core = 7.x files[]=options.module +required = TRUE Index: modules/field/modules/text/text.info =================================================================== RCS file: /cvs/drupal/drupal/modules/field/modules/text/text.info,v retrieving revision 1.2 diff -u -F^[fc] -r1.2 text.info --- modules/field/modules/text/text.info 5 Feb 2009 03:42:57 -0000 1.2 +++ modules/field/modules/text/text.info 9 Mar 2009 19:42:29 -0000 @@ -4,3 +4,4 @@ package = Core - fields core = 7.x files[]=text.module +required = TRUE Index: modules/field/modules/text/text.module =================================================================== RCS file: /cvs/drupal/drupal/modules/field/modules/text/text.module,v retrieving revision 1.3 diff -u -F^[fc] -r1.3 text.module --- modules/field/modules/text/text.module 10 Feb 2009 03:16:15 -0000 1.3 +++ modules/field/modules/text/text.module 9 Mar 2009 19:42:29 -0000 @@ -175,7 +175,121 @@ function theme_field_formatter_text_plai function theme_field_formatter_text_trimmed($element) { $field = field_info_field($element['#field_name']); $instance = field_info_instance($element['#field_name'], $element['#bundle']); - return $instance['settings']['text_processing'] ? $element['#item']['format'] : NULL; + return text_teaser($element['#item']['safe'], $instance['settings']['text_processing'] ? $element['#item']['format'] : NULL); +} + +/** + * Generate a trimmed, formatted version of a text field value. + * + * If the end of the teaser is not indicated using the delimiter + * then we generate the teaser automatically, trying to end it at a sensible + * place such as the end of a paragraph, a line break, or the end of a + * sentence (in that order of preference). + * + * @param $body + * The content for which a teaser will be generated. + * @param $format + * The format of the content. If the content contains PHP code, we do not + * split it up to prevent parse errors. If the line break filter is present + * then we treat newlines embedded in $body as line breaks. + * @param $size + * The desired character length of the teaser. If omitted, the default + * value will be used. Ignored if the special delimiter is present + * in $body. + * @return + * The generated teaser. + */ +function text_teaser($body, $format = NULL, $size = NULL) { + + if (!isset($size)) { + $size = variable_get('teaser_length', 600); + } + + // Find where the delimiter is in the body + $delimiter = strpos($body, ''); + + // If the size is zero, and there is no delimiter, the entire body is the teaser. + if ($size == 0 && $delimiter === FALSE) { + return $body; + } + + // If a valid delimiter has been specified, use it to chop off the teaser. + if ($delimiter !== FALSE) { + return substr($body, 0, $delimiter); + } + + // We check for the presence of the PHP evaluator filter in the current + // format. If the body contains PHP code, we do not split it up to prevent + // parse errors. + if (isset($format)) { + $filters = filter_list_format($format); + if (isset($filters['php/0']) && strpos($body, '' => 0); + + // If no complete paragraph then treat line breaks as paragraphs. + $line_breaks = array('
' => 6, '
' => 4); + // Newline only indicates a line break if line break converter + // filter is present. + if (isset($filters['filter/1'])) { + $line_breaks["\n"] = 1; + } + $break_points[] = $line_breaks; + + // If the first paragraph is too long, split at the end of a sentence. + $break_points[] = array('. ' => 1, '! ' => 1, '? ' => 1, '。' => 0, '؟ ' => 1); + + // Iterate over the groups of break points until a break point is found. + foreach ($break_points as $points) { + // Look for each break point, starting at the end of the teaser. + foreach ($points as $point => $offset) { + // The teaser is already reversed, but the break point isn't. + $rpos = strpos($reversed, strrev($point)); + if ($rpos !== FALSE) { + $min_rpos = min($rpos + $offset, $min_rpos); + } + } + + // If a break point was found in this group, slice and return the teaser. + if ($min_rpos !== $max_rpos) { + // Don't slice with length 0. Length must be <0 to slice from RHS. + return ($min_rpos === 0) ? $teaser : substr($teaser, 0, 0 - $min_rpos); + } + } + + // If a break point was not found, still return a teaser. + return $teaser; } /** Index: modules/node/node.install =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.install,v retrieving revision 1.13 diff -u -F^[fc] -r1.13 node.install --- modules/node/node.install 26 Feb 2009 07:30:27 -0000 1.13 +++ modules/node/node.install 9 Mar 2009 19:42:29 -0000 @@ -239,18 +239,6 @@ function node_schema() { 'not null' => TRUE, 'default' => '', ), - 'body' => array( - 'description' => 'The body of this version.', - 'type' => 'text', - 'not null' => TRUE, - 'size' => 'big', - ), - 'teaser' => array( - 'description' => 'The teaser of this version.', - 'type' => 'text', - 'not null' => TRUE, - 'size' => 'big', - ), 'log' => array( 'description' => 'The log entry explaining the changes in this version.', 'type' => 'text', @@ -326,7 +314,7 @@ function node_schema() { 'default' => '', ), 'has_body' => array( - 'description' => 'Boolean indicating whether this type uses the {node_revision}.body field.', + 'description' => 'Boolean indicating whether this type has the body field attached.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, Index: modules/node/node.module =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.module,v retrieving revision 1.1028 diff -u -F^[fc] -r1.1028 node.module --- modules/node/node.module 8 Mar 2009 04:25:04 -0000 1.1028 +++ modules/node/node.module 9 Mar 2009 19:42:29 -0000 @@ -46,6 +46,11 @@ define('NODE_BUILD_PRINT', 5); /** + * Name of the default body field. + */ +define('NODE_BODY_FIELD', 'node_body'); + +/** * Implementation of hook_help(). */ function node_help($path, $arg) { @@ -290,186 +295,6 @@ function node_mark($nid, $timestamp) { } /** - * See if the user used JS to submit a teaser. - */ -function node_teaser_js(&$form, &$form_state) { - if (isset($form['#post']['teaser_js'])) { - // Glue the teaser to the body. - if (trim($form_state['values']['teaser_js'])) { - // Space the teaser from the body - $body = trim($form_state['values']['teaser_js']) . "\r\n\r\n" . trim($form_state['values']['body']); - } - else { - // Empty teaser, no spaces. - $body = '' . $form_state['values']['body']; - } - // Pass updated body value on to preview/submit form processing. - form_set_value($form['body'], $body, $form_state); - // Pass updated body value back onto form for those cases - // in which the form is redisplayed. - $form['body']['#value'] = $body; - } - return $form; -} - -/** - * Ensure value of "teaser_include" checkbox is consistent with other form data. - * - * This handles two situations in which an unchecked checkbox is rejected: - * - * 1. The user defines a teaser (summary) but it is empty; - * 2. The user does not define a teaser (summary) (in this case an - * unchecked checkbox would cause the body to be empty, or missing - * the auto-generated teaser). - * - * If JavaScript is active then it is used to force the checkbox to be - * checked when hidden, and so the second case will not arise. - * - * In either case a warning message is output. - */ -function node_teaser_include_verify(&$form, &$form_state) { - $message = ''; - - // $form['#post'] is set only when the form is built for preview/submit. - if (isset($form['#post']['body']) && isset($form_state['values']['teaser_include']) && !$form_state['values']['teaser_include']) { - // "teaser_include" checkbox is present and unchecked. - if (strpos($form_state['values']['body'], '') === 0) { - // Teaser is empty string. - $message = t('You specified that the summary should not be shown when this post is displayed in full view. This setting is ignored when the summary is empty.'); - } - elseif (strpos($form_state['values']['body'], '') === FALSE) { - // Teaser delimiter is not present in the body. - $message = t('You specified that the summary should not be shown when this post is displayed in full view. This setting has been ignored since you have not defined a summary for the post. (To define a summary, insert the delimiter "<!--break-->" (without the quotes) in the Body of the post to indicate the end of the summary and the start of the main content.)'); - } - - if (!empty($message)) { - drupal_set_message($message, 'warning'); - // Pass new checkbox value on to preview/submit form processing. - form_set_value($form['teaser_include'], 1, $form_state); - // Pass new checkbox value back onto form for those cases - // in which form is redisplayed. - $form['teaser_include']['#value'] = 1; - } - } - - return $form; -} - -/** - * Generate a teaser for a node body. - * - * If the end of the teaser is not indicated using the delimiter - * then we generate the teaser automatically, trying to end it at a sensible - * place such as the end of a paragraph, a line break, or the end of a - * sentence (in that order of preference). - * - * @param $body - * The content for which a teaser will be generated. - * @param $format - * The format of the content. If the content contains PHP code, we do not - * split it up to prevent parse errors. If the line break filter is present - * then we treat newlines embedded in $body as line breaks. - * @param $size - * The desired character length of the teaser. If omitted, the default - * value will be used. Ignored if the special delimiter is present - * in $body. - * @return - * The generated teaser. - */ -function node_teaser($body, $format = NULL, $size = NULL) { - - if (!isset($size)) { - $size = variable_get('teaser_length', 600); - } - - // Find where the delimiter is in the body - $delimiter = strpos($body, ''); - - // If the size is zero, and there is no delimiter, the entire body is the teaser. - if ($size == 0 && $delimiter === FALSE) { - return $body; - } - - // If a valid delimiter has been specified, use it to chop off the teaser. - if ($delimiter !== FALSE) { - return substr($body, 0, $delimiter); - } - - // We check for the presence of the PHP evaluator filter in the current - // format. If the body contains PHP code, we do not split it up to prevent - // parse errors. - if (isset($format)) { - $filters = filter_list_format($format); - if (isset($filters['php/0']) && strpos($body, '' => 0); - - // If no complete paragraph then treat line breaks as paragraphs. - $line_breaks = array('
' => 6, '
' => 4); - // Newline only indicates a line break if line break converter - // filter is present. - if (isset($filters['filter/1'])) { - $line_breaks["\n"] = 1; - } - $break_points[] = $line_breaks; - - // If the first paragraph is too long, split at the end of a sentence. - $break_points[] = array('. ' => 1, '! ' => 1, '? ' => 1, '。' => 0, '؟ ' => 1); - - // Iterate over the groups of break points until a break point is found. - foreach ($break_points as $points) { - // Look for each break point, starting at the end of the teaser. - foreach ($points as $point => $offset) { - // The teaser is already reversed, but the break point isn't. - $rpos = strpos($reversed, strrev($point)); - if ($rpos !== FALSE) { - $min_rpos = min($rpos + $offset, $min_rpos); - } - } - - // If a break point was found in this group, slice and return the teaser. - if ($min_rpos !== $max_rpos) { - // Don't slice with length 0. Length must be <0 to slice from RHS. - return ($min_rpos === 0) ? $teaser : substr($teaser, 0, 0 - $min_rpos); - } - } - - // If a break point was not found, still return a teaser. - return $teaser; -} - -/** * Builds a list of available node types, and returns all of part of this list * in the specified format. * @@ -583,6 +408,7 @@ function node_type_save($info) { if (!empty($type->old_type) && $type->old_type != $type->type) { field_attach_rename_bundle($type->old_type, $type->type); } + node_configure_fields($type); module_invoke_all('node_type', 'update', $type); return SAVED_UPDATED; } @@ -591,13 +417,57 @@ function node_type_save($info) { db_insert('node_type')->fields($fields)->execute(); field_attach_create_bundle($type->type); - + node_configure_fields($type); module_invoke_all('node_type', 'insert', $type); return SAVED_NEW; } } /** + * Manage the field(s) for a node type. + */ +function node_configure_fields($type) { + // Create body field if it does not exist yet. + $field = field_info_field(NODE_BODY_FIELD); + if (!isset($field)) { + $field['field_name'] = NODE_BODY_FIELD; + $field['type'] = 'text_long'; + field_create_field($field); + } + + // Create or remove a body field instance as appropriate. + $instance['field_name'] = NODE_BODY_FIELD; + $instance['bundle'] = $type->type; + + if ($type->has_body) { + $instance['weight'] = -3; + $instance['label'] = $type->body_label; + $instance['required'] = $type->min_word_count > 0; + $instance['settings']['text_processing'] = TRUE; + $instance['widget']['type'] = 'text_textarea'; + $instance['widget']['settings']['rows'] = 20; + $instance['display']['teaser']['label'] = 'hidden'; + $instance['display']['teaser']['type'] = 'text_trimmed'; + $instance['display']['full']['label'] = 'hidden'; + $instance['display']['full']['type'] = 'text_default'; + + $found = field_info_instance(NODE_BODY_FIELD, $type->type); + if (!isset($found)) { + field_create_instance($instance); + } + else { + field_update_instance($instance); + } + } + else { + $found = field_info_instance(NODE_BODY_FIELD, $type->type); + if (isset($found)) { + field_delete_instance($instance); + } + } +} + +/** * Deletes a node type from the database. * * @param $type @@ -974,7 +844,8 @@ function node_validate($node, $form = ar // Make sure the body has the minimum number of words. // TODO : use a better word counting algorithm that will work in other languages - if (!empty($type->min_word_count) && isset($node->body) && count(explode(' ', $node->body)) < $type->min_word_count) { + if (!empty($type->min_word_count) && isset($node->{NODE_BODY_FIELD}[0]['value']) && count(explode(' ', $node->{NODE_BODY_FIELD}[0]['value'])) < $type->min_word_count) { + // TODO: Use Field API to set this error. form_set_error('body', t('The body of your @type is too short. You need at least %words words.', array('%words' => $type->min_word_count, '@type' => $type->name))); } @@ -1014,25 +885,6 @@ function node_submit($node) { // Convert the node to an object, if necessary. $node = (object)$node; - // Generate the teaser, but only if it hasn't been set (e.g. by a - // module-provided 'teaser' form item). - if (!isset($node->teaser)) { - if (isset($node->body)) { - $node->format = (!empty($node->body_format) ? $node->body_format : FILTER_FORMAT_DEFAULT); - $node->teaser = node_teaser($node->body, isset($node->format) ? $node->format : NULL); - // Chop off the teaser from the body if needed. The teaser_include - // property might not be set (eg. in Blog API postings), so only act on - // it, if it was set with a given value. - if (isset($node->teaser_include) && !$node->teaser_include && $node->teaser == substr($node->body, 0, strlen($node->teaser))) { - $node->body = substr($node->body, strlen($node->teaser)); - } - } - else { - $node->teaser = ''; - $node->format = 0; - } - } - if (user_access('administer nodes')) { // Populate the "authored by" field. if ($account = user_load(array('name' => $node->name))) { @@ -1072,16 +924,6 @@ function node_save(&$node) { if (!isset($node->log)) { $node->log = ''; } - - // For the same reasons, make sure we have $node->teaser and - // $node->body. We should consider making these fields nullable - // in a future version since node types are not required to use them. - if (!isset($node->teaser)) { - $node->teaser = ''; - } - if (!isset($node->body)) { - $node->body = ''; - } } elseif (!empty($node->revision)) { $node->old_vid = $node->vid; @@ -1216,30 +1058,6 @@ function node_build($node, $teaser = FAL } /** - * Apply filters and build the node's standard elements. - */ -function node_prepare($node, $teaser = FALSE) { - // First we'll overwrite the existing node teaser and body with - // the filtered copies! Then, we'll stick those into the content - // array and set the read more flag if appropriate. - $node->readmore = (strlen($node->teaser) < strlen($node->body)); - - if ($teaser == FALSE) { - $node->body = check_markup($node->body, $node->format, $node->language, FALSE); - } - else { - $node->teaser = check_markup($node->teaser, $node->format, $node->language, FALSE); - } - - $node->content['body'] = array( - '#markup' => $teaser ? $node->teaser : $node->body, - '#weight' => 0, - ); - - return $node; -} - -/** * Builds a structured array representing the node's content. * * @param $node @@ -1249,7 +1067,7 @@ function node_prepare($node, $teaser = F * * @return * An structured array containing the individual elements - * of the node's body. + * of the node's content. */ function node_build_content($node, $teaser = FALSE) { @@ -1258,21 +1076,33 @@ function node_build_content($node, $teas $node->build_mode = NODE_BUILD_NORMAL; } - // Remove the delimiter (if any) that separates the teaser from the body. - $node->body = isset($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); } - else { - $node = node_prepare($node, $teaser); - } // Build fields content. + if (empty($node->content)) { + $node->content = array(); + }; $node->content += field_attach_view('node', $node, $teaser); + // Always display a read more link on teasers because we have no way + // to know when a teaser view is different than a full view. + $links = array(); + if ($teaser) { + $links['node_readmore'] = array( + 'title' => t('Read more'), + 'href' => 'node/' . $node->nid, + 'attributes' => array('rel' => 'tag', 'title' => strip_tags($node->title)) + ); + } + $node->content['links']['node'] = array( + '#type' => 'node_links', + '#value' => $links + ); + // Allow modules to make their own additions to the node. node_invoke_node($node, 'view', $teaser); @@ -1492,16 +1322,16 @@ function node_search($op = 'search', $ke // Load results. $results = array(); foreach ($find as $item) { - // Build the node body. + // Render the node. $node = node_load($item->sid); $node->build_mode = NODE_BUILD_SEARCH_RESULT; $node = node_build_content($node, FALSE, FALSE); - $node->body = drupal_render($node->content); + $node->rendered = drupal_render($node->content); // Fetch comments for snippet. - $node->body .= module_invoke('comment', 'node', $node, 'update_index'); + $node->rendered .= module_invoke('comment', 'node', $node, 'update_index'); // Fetch terms for snippet. - $node->body .= module_invoke('taxonomy', 'node', $node, 'update_index'); + $node->rendered .= module_invoke('taxonomy', 'node', $node, 'update_index'); $extra = node_invoke_node($node, 'search_result'); @@ -1514,7 +1344,7 @@ function node_search($op = 'search', $ke 'node' => $node, 'extra' => $extra, 'score' => $total ? ($item->calculated_score / $total) : 0, - 'snippet' => search_excerpt($keys, $node->body), + 'snippet' => search_excerpt($keys, $node->rendered), ); } return $results; @@ -1623,7 +1453,7 @@ function node_link($type, $node = NULL, $links = array(); if ($type == 'node') { - if ($teaser == 1 && $node->teaser && !empty($node->readmore)) { + if ($teaser == 1) { $links['node_read_more'] = array( 'title' => t('Read more'), 'href' => "node/$node->nid", @@ -1928,24 +1758,11 @@ function node_feed($nids = FALSE, $chann if (node_hook($item, 'view')) { $item = node_invoke($item, 'view', $teaser, FALSE); } - else { - $item = node_prepare($item, $teaser); - } // Allow modules to change $node->content before the node is rendered. node_invoke_node($item, 'view', $teaser, FALSE); - // Set the proper node property, then unset unused $node property so that a - // bad theme can not open a security hole. - $content = drupal_render($item->content); - if ($teaser) { - $item->teaser = $content; - unset($item->body); - } - else { - $item->body = $content; - unset($item->teaser); - } + $item->rendered = drupal_render($item->content); // Allow modules to modify the fully-built node. node_invoke_node($item, 'alter', $teaser, FALSE); @@ -1963,13 +1780,11 @@ function node_feed($nids = FALSE, $chann // Prepare the item description switch ($item_length) { case 'fulltext': - $item_text = $item->body; + $item_text = $item->rendered; break; case 'teaser': - $item_text = $item->teaser; - if (!empty($item->readmore)) { - $item_text .= '

' . l(t('read more'), 'node/' . $item->nid, array('absolute' => TRUE, 'attributes' => array('target' => '_blank'))) . '

'; - } + $item_text = $item->rendered; + $item_text .= '

' . l(t('read more'), 'node/' . $item->nid, array('absolute' => TRUE, 'attributes' => array('target' => '_blank'))) . '

'; break; case 'title': $item_text = ''; @@ -2102,12 +1917,12 @@ function _node_index_node($node) { // save the changed time of the most recent indexed node, for the search results half-life calculation variable_set('node_cron_last', $node->changed); - // Build the node body. + // Render the node. $node->build_mode = NODE_BUILD_SEARCH_INDEX; $node = node_build_content($node, FALSE, FALSE); - $node->body = drupal_render($node->content); + $node->rendered = drupal_render($node->content); - $text = '

' . check_plain($node->title) . '

' . $node->body; + $text = '

' . check_plain($node->title) . '

' . $node->rendered; // Fetch extra data normally not visible $extra = node_invoke_node($node, 'update_index'); @@ -2791,10 +2606,6 @@ function node_content_form($node, $form_ ); } - if ($type->has_body) { - $form['body_field'] = node_body_field($node, $type->body_label, $type->min_word_count); - } - return $form; } Index: modules/node/node.pages.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.pages.inc,v retrieving revision 1.56 diff -u -F^[fc] -r1.56 node.pages.inc --- modules/node/node.pages.inc 8 Mar 2009 04:25:04 -0000 1.56 +++ modules/node/node.pages.inc 9 Mar 2009 19:42:29 -0000 @@ -106,7 +106,7 @@ function node_form(&$form_state, $node) $form['#prefix'] = $form_state['node_preview']; } $node = (object)$node; - foreach (array('body', 'title', 'format') as $key) { + foreach (array('title') as $key) { if (!isset($node->$key)) { $node->$key = NULL; } @@ -267,48 +267,6 @@ function node_form(&$form_state, $node) } /** - * Return a node body field, with format and teaser. - */ -function node_body_field(&$node, $label, $word_count) { - - // Check if we need to restore the teaser at the beginning of the body. - $include = !isset($node->teaser) || ($node->teaser == substr($node->body, 0, strlen($node->teaser))); - - $form = array( - '#after_build' => array('node_teaser_js', 'node_teaser_include_verify')); - - $form['#prefix'] = '
'; - $form['#suffix'] = '
'; - - $form['teaser_js'] = array( - '#type' => 'textarea', - '#rows' => 10, - '#teaser' => 'edit-body', - '#teaser_checkbox' => 'edit-teaser-include', - '#disabled' => TRUE, - ); - - $form['teaser_include'] = array( - '#type' => 'checkbox', - '#title' => t('Show summary in full view'), - '#default_value' => $include, - '#prefix' => '
', - '#suffix' => '
', - ); - - $form['body'] = array( - '#type' => 'textarea', - '#title' => check_plain($label), - '#default_value' => $include ? $node->body : ($node->teaser . $node->body), - '#rows' => 20, - '#required' => ($word_count > 0), - '#text_format' => isset($node->format) ? $node->format : FILTER_FORMAT_DEFAULT, - ); - - return $form; -} - -/** * Button submit function: handle the 'Delete' button on the node form. */ function node_form_delete_submit($form, &$form_state) { @@ -369,16 +327,6 @@ function node_preview($node) { $node->changed = REQUEST_TIME; - // Extract a teaser, if it hasn't been set (e.g. by a module-provided - // 'teaser' form item). - if (!isset($node->teaser)) { - $node->teaser = empty($node->body) ? '' : node_teaser($node->body, $node->format); - // Chop off the teaser from the body if needed. - if (!$node->teaser_include && $node->teaser == substr($node->body, 0, strlen($node->teaser))) { - $node->body = substr($node->body, strlen($node->teaser)); - } - } - // Display a preview of the node. // Previewing alters $node so it needs to be cloned. if (!form_get_errors()) { @@ -404,28 +352,20 @@ function theme_node_preview($node) { $output = '
'; $preview_trimmed_version = FALSE; - // Do we need to preview trimmed version of post as well as full version? - if (isset($node->teaser) && isset($node->body)) { - $teaser = trim($node->teaser); - $body = trim(str_replace('', '', $node->body)); - - // Preview trimmed version if teaser and body will appear different; - // also (edge case) if both teaser and body have been specified by the user - // and are actually the same. - if ($teaser != $body || ($body && strpos($node->body, '') === 0)) { - $preview_trimmed_version = TRUE; - } - } - if ($preview_trimmed_version) { + $trimmed = drupal_render(node_build(clone $node, TRUE)); + $full .= drupal_render(node_build($node, FALSE)); + + // Do we need to preview trimmed version of post as well as full version? + if ($trimmed != $full) { drupal_set_message(t('The trimmed version of your post shows what your post looks like when promoted to the main page or when exported for syndication. You can insert the delimiter "<!--break-->" (without the quotes) to fine-tune where your post gets split.')); $output .= '

' . t('Preview trimmed version') . '

'; - $output .= drupal_render(node_build(clone $node, TRUE)); + $output .= $trimmed; $output .= '

' . t('Preview full version') . '

'; - $output .= drupal_render(node_build($node, FALSE)); + $output .= $full; } else { - $output .= drupal_render(node_build($node, FALSE)); + $output .= $full; } $output .= "
\n";