. */ if(!class_exists('AdvancedExcerpt')) : class AdvancedExcerpt { var $name; var $text_domain; var $mb; var $skip_next_call; function AdvancedExcerpt() { $this->name = strtolower(get_class($this)); $this->text_domain = $this->name; $this->skip_next_call = false; $this->charset = get_bloginfo('charset'); // Carefully support multibyte languages if(extension_loaded('mbstring') && function_exists('mb_list_encodings')) $this->mb = in_array($this->charset, mb_list_encodings()); load_plugin_textdomain($this->text_domain, PLUGINDIR . '/advanced-excerpt/'); register_activation_hook(__FILE__, array(&$this, 'install')); // Nothing to do on deactivation //register_deactivation_hook(__FILE__, array(&$this, 'uninstall')); add_action('admin_menu', array(&$this, 'add_pages')); // Replace the default filter (see /wp-includes/default-filters.php) remove_filter('get_the_excerpt', 'wp_trim_excerpt'); add_filter('get_the_excerpt', array(&$this, 'filter')); } function __construct() { self::AdvancedExcerpt(); } function filter($text, $length = null, $use_words = null, $ellipsis = null, $allowed_tags = null, $no_custom = null, $api_used = false) { global $id, $post; // Avoid trouble when the API (aka template tag) was used if($this->skip_next_call) { $this->skip_next_call = false; return $text; } $this->skip_next_call = $api_used; $no_custom = (!is_null($no_custom)) ? (int) (bool) $no_custom : get_option($this->name . '_no_custom'); // Only make the excerpt if it does not exist or 'No Custom Excerpt' is set to true if('' == $text || $no_custom) { $length = (!is_null($length)) ? (int) $length : get_option($this->name . '_length'); $use_words = (!is_null($use_words)) ? (int) (bool) $use_words : get_option($this->name . '_use_words'); $ellipsis = (!is_null($ellipsis)) ? $ellipsis : get_option($this->name . '_ellipsis'); $allowed_tags = (is_array($allowed_tags)) ? $allowed_tags : get_option($this->name . '_allowed_tags'); $allowed_tags = '<' . implode('><', $allowed_tags) . '>'; $text = apply_filters('the_content', get_the_content('')); // From the default wp_trim_excerpt(): // Some kind of precaution against malformed CDATA in RSS feeds I suppose $text = str_replace(']]>', ']]>', $text); $text = strip_tags($text, $allowed_tags); if(1 == $use_words) { // Count words, not HTML tags if($length > count(preg_split('/[\s]+/', strip_tags($text), -1))) return $text; // Now we start counting $text_bits = preg_split('/([\s]+)/', $text, -1, PREG_SPLIT_DELIM_CAPTURE); $in_tag = false; $n_words = 0; $text = ''; foreach($text_bits as $chunk) { // Determine whether a tag is opened (and not immediately closed) in this chunk if(0 < preg_match('/<[^>]*$/s', $chunk)) $in_tag = true; elseif(0 < preg_match('/>[^<]*$/s', $chunk)) $in_tag = false; // This should check if there is a word before the tag // but it doesn't work very well /* if($in_tag && $this->substr($chunk, 0, 1) != '<') $n_words++; */ // Is there a word? if(!$in_tag && '' != trim($chunk) && $this->substr($chunk, -1, 1) != '>') $n_words++; $text .= $chunk; if($n_words >= $length && !$in_tag) break; } $text = $text . $ellipsis; } else { // Count characters, not whitespace, not those belonging to HTML tags if($length > $this->strlen(strip_tags($text))) return $text; $in_tag = false; $n_chars = 0; for($i = 0; $n_chars < $length || $in_tag; $i++) { // Is the character worth counting (ie. not part of an HTML tag) if($this->substr($text, $i, 1) == '<') $in_tag = true; elseif($this->substr($text, $i, 1) == '>') $in_tag = false; elseif(!$in_tag && '' != trim($this->substr($text, $i, 1))) $n_chars++; // Prevent eternal loops (this could happen with incomplete HTML tags) if($i >= $this->strlen($text) - 1) break; } $text = $this->substr($text, 0, $i) . $ellipsis; } $text = force_balance_tags($text); } return $text; } function update_options() { $length = (int) $_POST[$this->name . '_length']; $use_words = ('on' == $_POST[$this->name . '_use_words']) ? 1 : 0 ; $no_custom = ('on' == $_POST[$this->name . '_no_custom']) ? 1 : 0 ; $ellipsis = (get_magic_quotes_gpc() == 1) ? stripslashes($_POST[$this->name . '_ellipsis']) : $_POST[$this->name . '_ellipsis']; $ellipsis = $ellipsis; $allowed_tags = (array) $_POST[$this->name . '_allowed_tags']; update_option($this->name . '_length', $length); update_option($this->name . '_use_words', $use_words); update_option($this->name . '_no_custom', $no_custom); update_option($this->name . '_ellipsis', $ellipsis); update_option($this->name . '_allowed_tags', $allowed_tags); ?>

Options saved.

name . '_update_options'); $this->update_options(); } $length = get_option($this->name . '_length'); $use_words = get_option($this->name . '_use_words'); $no_custom = get_option($this->name . '_no_custom'); $ellipsis = htmlentities(get_option($this->name . '_ellipsis')); $allowed_tags = get_option($this->name . '_allowed_tags'); ?>

text_domain); ?>

name . '_update_options'); ?>
/> text_domain); ?>
HTML entities)', $this->text_domain); ?>
text_domain); ?>
/> text_domain); ?>
text_domain); ?> $spec) : if(1 == $i / 4) : ?>
/>
 

text_domain); ?>" />

text_domain), __("Excerpt", $this->text_domain), 'manage_options', 'options-' . $this->name, array(&$this, 'page_options')); } function install() { global $allowedposttags; foreach($allowedposttags as $tag => $spec) $allowed_tags[] = $tag; add_option($this->name . '_length', 40); add_option($this->name . '_use_words', 1); add_option($this->name . '_no_custom', 0); add_option($this->name . '_ellipsis', '…'); add_option($this->name . '_allowed_tags', $allowed_tags); } function uninstall() { // Nothing to do (note: deactivation hook is also disabled) } // Careful multibyte support (fallback to normal functions if not available) function substr($str, $start, $length = null) { $length = (is_null($length)) ? $this->strlen($str) : $length; if($this->mb) return mb_substr($str, $start, $length, $this->charset); else return substr($str, $start, $length); } function strlen($str) { if($this->mb) return mb_strlen($str, $this->charset); else return strlen($str); } // PHP seems to lack a simple complement function for arrays function array_complement($a, $b) { $a = array_unique($a); $b = array_unique($b); $c = array(); foreach($a as $t) { if(!in_array($t, $b)) $c[] = $t; } } } $advancedexcerpt = new AdvancedExcerpt(); function the_advanced_excerpt($args = '') { global $advancedexcerpt; $defaults = array( 'length' => get_option($advancedexcerpt->name . '_length'), 'use_words' => get_option($advancedexcerpt->name . '_use_words'), 'no_custom' => get_option($advancedexcerpt->name . '_no_custom'), // URL encode, because URL decode is used on this setting later 'ellipsis' => urlencode(get_option($advancedexcerpt->name . '_ellipsis')), 'allow_tags' => implode(',', get_option($advancedexcerpt->name . '_allowed_tags')), 'exclude_tags' => ''); $r = wp_parse_args($args, $defaults); extract($r, EXTR_SKIP); $allow_tags = preg_split('/[\s,]+/', $allow_tags); $exclude_tags = preg_split('/[\s,]+/', $exclude_tags); $ellipsis = urldecode($ellipsis); // {allow_tags} - {exclude_tags} $allow_tags = $advancedexcerpt->array_complement($allow_tags, $exclude_tags); // All filters are applied, however, the advanced excerpt now behaves like a priorite 1 filter, instead of the default priority 10 $text = $advancedexcerpt->filter('', $length, $use_words, $ellipsis, $allow_tags, $no_custom, true); $text = apply_filters('get_the_excerpt', $text); echo apply_filters('the_excerpt', $text); } endif;