From db55c269da3089b1b18d428793143a4786ffe1c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Hojtsy?= Date: Wed, 9 Jan 2008 12:10:04 +0000 Subject: [PATCH] #201667 by theborg, quicksketch, gpk, catch: fix bugs with teaser splitter in JS and no-JS mode --- misc/teaser.js | 19 ++++++++---- modules/node/node.module | 59 ++++++++++++++++++++++++++++++++----- modules/node/node.pages.inc | 19 ++++++++++-- 3 files changed, 82 insertions(+), 15 deletions(-) diff --git a/misc/teaser.js b/misc/teaser.js index 633d39e6c70..6a4a341d179 100644 --- a/misc/teaser.js +++ b/misc/teaser.js @@ -17,6 +17,7 @@ Drupal.behaviors.teaser = function(context) { // Move teaser textarea before body, and remove its form-item wrapper. var body = $('#'+ Drupal.settings.teaser[this.id]); var checkbox = $('#'+ Drupal.settings.teaserCheckbox[this.id]).parent(); + var checked = $(checkbox).children('input').attr('checked') ? true : false; var parent = teaser[0].parentNode; $(body).before(teaser); $(parent).remove(); @@ -30,13 +31,19 @@ Drupal.behaviors.teaser = function(context) { if (teaser.val()) { body.val(trim(teaser.val()) +'\r\n\r\n'+ trim(body.val())); } - // Hide and disable teaser + // Empty, hide and disable teaser. + teaser[0].value = ''; $(teaser).attr('disabled', 'disabled'); $(teaser).parent().slideUp('fast'); - // Change label + // Change label. $(this).val(Drupal.t('Split summary at cursor')); - // Show separate teaser checkbox + // Hide separate teaser checkbox. $(checkbox).hide(); + // Force a hidden checkbox to be checked (to ensure that the body is + // correctly processed on form submit when teaser/body are in joined + // state), and remember the current checked status. + checked = $(checkbox).children('input').attr('checked') ? true : false; + $(checkbox).children('input').attr('checked', true); } // Split the teaser from the body. @@ -54,8 +61,8 @@ Drupal.behaviors.teaser = function(context) { $(teaser).parent().slideDown('fast'); // Change label $(this).val(Drupal.t('Join summary')); - // Show separate teaser checkbox - $(checkbox).show(); + // Show separate teaser checkbox, restore checked value. + $(checkbox).show().children('input').attr('checked', checked); } // Add split/join button. @@ -73,7 +80,7 @@ Drupal.behaviors.teaser = function(context) { } else { $('input', button).val(Drupal.t('Split summary at cursor')).toggle(split_teaser, join_teaser); - $(checkbox).hide(); + $(checkbox).hide().children('input').attr('checked', true); } // Make sure that textarea.js has done its magic to ensure proper visibility state. diff --git a/modules/node/node.module b/modules/node/node.module index 9f6714db141..c9aeeb4bdf1 100644 --- a/modules/node/node.module +++ b/modules/node/node.module @@ -215,8 +215,8 @@ function node_mark($nid, $timestamp) { * See if the user used JS to submit a teaser. */ function node_teaser_js(&$form, &$form_state) { - // Glue the teaser to the body. 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']); @@ -225,20 +225,65 @@ function node_teaser_js(&$form, &$form_state) { // Empty teaser, no spaces. $body = ''. $form_state['values']['body']; } - // Pass value onto preview/submit + // Pass updated body value on to preview/submit form processing. form_set_value($form['body'], $body, $form_state); - // Pass value back onto form + // Pass updated body value back onto form for those cases + // in which the form is redisplayed. $form['body']['#value'] = $body; } return $form; } /** - * Automatically generate a teaser for a node body. + * 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 JavasSript 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 try 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). + * 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. @@ -773,7 +818,7 @@ function node_submit($node) { // Convert the node to an object, if necessary. $node = (object)$node; - // Auto-generate the teaser, but only if it hasn't been set (e.g. by a + // 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)) { diff --git a/modules/node/node.pages.inc b/modules/node/node.pages.inc index 7c667498e88..ab0ae912a28 100644 --- a/modules/node/node.pages.inc +++ b/modules/node/node.pages.inc @@ -262,7 +262,7 @@ function node_body_field(&$node, $label, $word_count) { $include = !isset($node->teaser) || ($node->teaser == substr($node->body, 0, strlen($node->teaser))); $form = array( - '#after_build' => array('node_teaser_js')); + '#after_build' => array('node_teaser_js', 'node_teaser_include_verify')); $form['#prefix'] = '
'; $form['#suffix'] = '
'; @@ -414,7 +414,22 @@ function node_preview($node) { */ function theme_node_preview($node) { $output = '
'; - if (!empty($node->teaser) && !empty($node->body) && $node->teaser != $node->body) { + + $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) { 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 .= node_view(drupal_clone($node), 1, FALSE, 0);