after the specified paragraph of every post. All formatting and HTML tags are preserved in the abbreviated post.
If the post already has a in it, then this plugin does nothing to it and the existing will behave as usual.
If you want to disable the plugin for any specific post, then include the codeword in the post. This won't show up in the post, but it will prevent the post from being abbreviated by Evermore.
DEVELOPMENT NOTES
All globals begin with "tguy_em_" (for Thunderguy Evermore)
Tested with PHP 4.4.x, WordPress 1.5 to 2.7.1.
*/
if (!is_plugin_page()) :
// Add the "more" link immediately after reading the post from the database
add_filter('the_posts', 'tguy_em_addmoreall');
add_action('admin_menu', 'tguy_em_add_admin_pages');
function tguy_em_addmoreall($posts) {
/* Add a "more" link immediately after reading posts from the database.
*/
$count = count($posts);
for ($i = 0; $i < $count; ++$i) {
$posts[$i]->post_content = tguy_em_addmore($posts[$i]->post_content);
}
return $posts;
}
function tguy_em_addmore($post_content) {
/* Add a "more" comment in an appropriate place, unless
there is already a "" (we don't add an extra one) or
a "" (user has disabled evermore for this post).
*/
// Only continue if content has no "more" and no "nevermore"
if ((false === strpos($post_content, ''))
&& (false === strpos($post_content, ''))) {
$options = get_option('tguy_more_evermore');
if (!$options) {
$options = tguy_em_get_default_options();
}
$char_skip_count = intval($options['em_min_chars_to_skip']);
$para_skip_count = intval($options['em_paras_to_skip']);
$link_on_new_para = $options['em_link_on_new_para'];
// Skip a number of initial characters
$skipped_chars = substr($post_content, 0, $char_skip_count);
$unskipped_chars = substr($post_content, $char_skip_count);
// Use regex-fu to break the post into paragraphs. This scheme
// may fail on pathological combinations of
and
// newline chars. It can also fail on nested block-level tags
// (e.g. nested divs). So don't do that!
// Pattern matching an HTML tag that indicates a paragraph
$para_tag = '(?:p|pre|blockquote|div|ol|ul|h[1-6]|table)';
// Pattern matching two consecutive newlines with optional space between
$double_newline = "(?:\r\n *\r\n|\r *\r|\n *\n|
\s*
)";
// Pattern matching optional whitespace
$ws = '\s*';
// Pattern matching paragraph body (must start at the beginning
// of a paragraph, and be followed by a paragraph end)
$body = '.+?';
// Pattern matching the end of a paragraph
$end = "(?:$double_newline|$para_tag>|(?<=\W)(?=$ws<$para_tag\W))";
// Get all the skipped paragraphs, but separate the end of the final paragraph so
// we can add a "run-on" more if necessary.
// regex finds: a para body; followed by (n-1) end+body pairs; followed by an end; followed by something.
$para_skip_dec = $para_skip_count - 1;
if (preg_match("!^($ws$body(?:$end$ws$body){".$para_skip_dec."})($end)$ws\S!is", $unskipped_chars, $matches)) {
$skipped_paras = $matches[1];
$skipped_end = $matches[2];
$unskipped_paras = substr($unskipped_chars, strlen($skipped_paras) + strlen($skipped_end));
if ($link_on_new_para) {
// Add 2 newlines after the more, to stop WP adding
// a
after the more which leaves a spurious blank line.
return $skipped_chars . $skipped_paras . $skipped_end . "\n\n" . $unskipped_paras;
} else {
return $skipped_chars . $skipped_paras . '' . $skipped_end . $unskipped_paras;
}
}
}
// No "more" was added. If the request includes the magic word, then add diagnostic info in a comment at the end of the post
if ($_GET['evermore_diagnostics']) {
return $post_content . "";
}
return $post_content;
}
function tguy_em_get_diagnostics(&$post_content, $options) {
// Return a string with diagnostic info on the raw post data.
$diagnostic_reason = "";
$char_skip_count = intval($options['em_min_chars_to_skip']);
$para_skip_count = intval($options['em_paras_to_skip']);
$link_on_new_para = $options['em_link_on_new_para'];
$diagnostic_extra_info = "";
if (false !== strpos($post_content, '')) {
$diagnostic_reason .= "Post contained (more)";
}
if (false !== strpos($post_content, '')) {
$diagnostic_reason .= "Post contained (nevermore)";
}
if (strlen($post_content) <= $char_skip_count) {
$diagnostic_reason .= "Post was too short";
}
if ($diagnostic_reason == "") {
// We must analyse the content to determine the reason
$diagnostic_reason .= "Post did not contain end-of-paragraph";
// Mark newlines, escape HTML
$diagnostic_unskipped_chars = substr($post_content, $char_skip_count);
$diagnostic_unskipped_chars = str_replace("\\", "\\\\", $diagnostic_unskipped_chars);
$diagnostic_unskipped_chars = str_replace(
array("\n", "\r"),
array("\\n", "\\r"),
$diagnostic_unskipped_chars);
$diagnostic_extra_info = "Post content (unskipped)
[" . $diagnostic_unskipped_chars . "]
";
}
return "Evermore was not triggered. Diagnostics:
Skip chars [$char_skip_count]
Skip paragraphs [$para_skip_count]
New paragraph [".($link_on_new_para?'true':'false')."]
Post length [".strlen($post_content)."]
Reason [$diagnostic_reason]
".$diagnostic_extra_info;
}
function tguy_em_add_admin_pages() {
add_options_page('Evermore', 'Evermore', 10, __FILE__, 'tguy_em_options_page');
// Create option in options database if not there already:
add_option('tguy_more_evermore', tguy_em_get_default_options(), 'Options for the Evermore plugin');
}
function tguy_em_get_default_options() {
$options = array();
$options['em_min_chars_to_skip'] = 100;
$options['em_paras_to_skip'] = 1;
$options['em_link_on_new_para'] = true;
return $options;
}
endif; // if (!is_plugin_page())
function tguy_em_options_page() {
// See if user has submitted form
if ( isset($_POST['submitted']) ) {
check_admin_referer('evermore-update-options_all');
$options = array();
$options['em_min_chars_to_skip'] = intval($_POST['em_min_chars_to_skip']);
$options['em_paras_to_skip'] = intval($_POST['em_paras_to_skip']);
$options['em_link_on_new_para'] = (bool)($_POST['em_link_on_new_para']);
update_option('tguy_more_evermore', $options);
echo '
Plugin settings saved.
Evermore automatically displays a short preview of your posts on your blog home page. The preview also appears on the archive and category pages. For each post, the first few paragraphs are shown along with a "read more" link to read the full post.