Как-то раз обратил внимание, что функция WordPress the_excerpt() (отрывок/цитата) какая-то громоздкая (на её выполнение уходит много времени и ресурсов, чем она этого заслуживает), в подробности, почему она такая, вдаваться не буду, скажу только, что the_excerpt() вызывает get_the_excerpt(), the_content() и ко всем ним применяются различные хуки, включая сам the_excerpt(). Там получается немало операций, для всего-то вывода какого-то отрывка текста. Лично я к цитатам отношусь крайне просто - коротко сказать о чем статья, вырезав небольшой её кусок или описать ее вкратце.
С этим недостатком я мерился, до того момента, пока мне не понадобилась обрезать текст до определенного количества символов. Тогда то я и решил написать функцию, чтобы обрезала текст, который я ей даю и за одно решил ее универсализировать и сделать замену монстру the_excerpt().
Результат замены the_excerpt() меня порадовал: генерация страницы уменьшилась в среднем с 0,850 сек до 0,550 сек, при 9 вызовах the_excerpt() (это время на моем компьютере, на сервере естественно оно меньше). 9 вызовов - это количество выводимых постов в категории, к каждому из которых применялся the_excerpt().
Вот собственно и получившаяся у меня функция, которой можно заменить стандартную функцию WordPress the_excerpt().
/* Обрезка текста - excerpt
maxchar = количество символов.
text = какой текст обрезать (по умолчанию берется excerpt поста, если его нету, то content, если есть тег <!--more-->, то maxchar игнорируется и берется все, что до него, с сохранением HTML тегов )
save_format = Сохранять перенос строк или нет. По умолчанию сохраняется. Если в параметр указать определенные теги, то они НЕ будут вырезаться из обрезанного текста (пример: save_format=<strong><a> )
echo = выводить на экран или возвращать (return) для обработки.
П.с. Шоткоды вырезаются. Минимальное значение maxchar может быть 22.
*/
function kama_excerpt($args=''){
global $post;
parse_str($args, $i);
$maxchar = isset($i['maxchar']) ? (int)trim($i['maxchar']) : 350;
$text = isset($i['text']) ? trim($i['text']) : '';
$save_format = isset($i['save_format']) ? trim($i['save_format']) : false;
$echo = isset($i['echo']) ? false : true;
if (!$text){
$out = $post->post_excerpt ? $post->post_excerpt : $post->post_content;
$out = preg_replace ("!\[/?.*\]!U", '', $out ); //убираем шоткоды, например:[singlepic id=3]
// для тега <!--more-->
if( !$post->post_excerpt && strpos($post->post_content, '<!--more-->') ){
preg_match ('/(.*)<!--more-->/s', $out, $match);
$out = str_replace("\r", '', trim($match[1], "\n"));
$out = preg_replace( "!\n\n+!s", "</p><p>", $out );
$out = "<p>". str_replace( "\n", "<br />", $out ) ."</p>";
if ($echo)
return print $out;
return $out;
}
}
$out = $text.$out;
if (!$post->post_excerpt)
$out = strip_tags($out, $save_format);
if ( iconv_strlen($out, 'utf-8') > $maxchar ){
$out = iconv_substr( $out, 0, $maxchar, 'utf-8' );
$out = preg_replace('@(.*)\s[^\s]*$@s', '\\1 ...', $out); //убираем последнее слово, ибо оно в 99% случаев неполное
}
if($save_format){
$out = str_replace( "\r", '', $out );
$out = preg_replace( "!\n\n+!", "</p><p>", $out );
$out = "<p>". str_replace ( "\n", "<br />", trim($out) ) ."</p>";
}
if($echo) return print $out;
return $out;
}
Что умеет функция?
- Обрезать до определенного количества символов. Указывается в параметре maxchar;
- Понимает тег <!--more--> в посте. Если он присутствует желаемое количество выводимых символов игнорируется и выводится все что выше <!--more--> с сохранением HTML тегов;
- Можно указать сохранять переносы строк или писать весь текст в одну строку (по умолчанию переносы сохраняются, если нужен "сплошняк" ставим параметр save_format=0) ;
- Так же, можно использовать функцию, чтобы обрезать любой текст, который ей будет передан через параметр text . При этом половина кода пропускается, срабатывает только необходимая его часть.
Обрезка во всех случаях вычисляет количество символов, а затем убирает последние символы до пробела, сделано это для того, чтобы в конце всегда оставалось законченное слово, а не кусок недописанного слова (на мой взгляд это некрасиво).
Для использования вставляем указаный выше код в файл functions.php вашего шаблона, а где нужно вывести обрезанный текст вызываем функцию так: kama_excerpt("maxchar=100&text=бла бла");.
Чтобы заменить стандартный the_exerpt() нужно просто заменить the_exerpt(); на kama_excerpt(); Все это должно быть внутри цикла the loop. ВАЖНО! Парметр text при замене the_exerpt(); указывать не надо!
Пример использования функции, как обрезка любого текста (в любом месте шаблона):
$rrr = "Функция для обрезки текста для Worpress. Также можно применять и на других движках.";
kama_excerpt("text=$rrr&maxchar=50");
//Выведет: Функция для обрезки текста для Worpress. Также ...
При обрезке передаваемого функции текста, срабатывает только та часть функции которая необходима, т.е. никаких лишних операций.
На этом сайте я использую эту функцию 
- Предыдущие по меткам
- Предыдущие записи
- Избавляемся от лишних обращений к данным ← 2.Апр.2010 // 22
- Полезный хак для WordPress, если сайт дорабатывается на локалке ← 1.Апр.2010 // 11
- Функция для вывода последних комментариев ← 11 Апрель 2010 // 109
- Меняем символы ХТМЛ (< >) на спецсимволы при комментировании ← 16 Апрель 2010 // 12
- Добавляем допустимые теги в комментариях ← 2 Апрель 2010 // 6

Скажите пожалуйста как заменить и сохранить текст в ссылке например тег {a =ссылка} нужное для замены фраза и здесь закрывается {тег a} подскажите пожалуйста это вообще возможно.
Не понял. Где, что заменить, анкор надо заменить? Руками, нет?
То что нужно, спасибо!
Но если можно, подскажите пожалуйста, как сделать "Читать далее" вместо ..., при этом оставив обрезку (авто и ручной с more), в тех случаях, когда она нужна и обходиться без ссылки "читать далее", если, например, материал короткий и пост завершается быстро.
После
$out = preg_replace('@(.*)\s[^\s]*$@s', '\\1 ...', $out); //убираем последнее слово, ибо оно в 99% случаев неполноеДопишите ссылку "читать далее":
Была большая проблема по моим меркам,а мистер Кама решил ее за две секунды!Громадное спасибо!!!
Но в таком слкчае ссылка появляется в случае если обрезка происходит автоматически, а если вставить more вручную - ссылка исчезает.
Здравствуйте, спасибо за функцию. Подскажите, можно ли в разных местах менять дизайн надписи "Читать далее?" (потому что, если меняю в functions.php - меняется везде).
Спасибо.
классный плагин\функция)! спасибо большое)