Как-то раз обратил внимание, что функция 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. Также ...
При обрезке передаваемого функции текста, срабатывает только та часть функции которая необходима, т.е. никаких лишних операций.
На этом сайте я использую эту функцию 
Благодарность блогу Альтернативный взгляд на WordPress за помощь в разработке сайта.
- Предыдущие по меткам
- Предыдущие записи
- Избавляемся от лишних обращений к данным ← 2.Апр.2010 // 22
- Полезный хак для WordPress, если сайт дорабатывается на локалке ← 1.Апр.2010 // 11
- Функция для вывода последних комментариев ← 11 Апрель 2010 // 88
- Меняем символы ХТМЛ (< >) на спецсимволы при комментировании ← 16 Апрель 2010 // 12
- Добавляем допустимые теги в комментариях ← 2 Апрель 2010 // 1

отлично! спасибо...таблетка от недоразумения по имени the_excerpt() !!!
Здраствуйте. Помогите пожалуйста. Всё перепробовал и никак не получается.
Создал functions.php, в него поместил сейчас функцию вашу. У меня сайт делиться на блоки. Поэтому в индекс.пхп есть код. Собственно тут я и пытаюсь использовать вашу функцию. Сам сайт: http://oursuccess.ru/
Смотрим на блок "Биография успешных людей". Там я использовал такой код
<?php global $post; $tmp_post = $post; $myposts = get_posts('numberposts=2&offset=0&category=4'); foreach($myposts as $post) : setup_postdata($post);?> <div class="byographyPost"> <div class="byographyPostTitle"><a href="<?php the_permalink(); ?>"><?php the_title() ?></div> <div class="byographyPostText" align="justify"><? kama_excerpt(); ?></div> </div> <?php endforeach; ?>Выводится полной новостью до море. Я уже все перепробовал. К слову, шаблон делал сам. Может, где мог ошибиться? Хотя, где.. Это ж только макет.. Так же пробовал использовать плагин excerpt_reloaded. Дал аналогичный результат. Помоги пожалуйста
Вам, насколько я понял, нужно просто не учитывать тег more, который используется в тексте статьи? Это уже обсуждалось.
Да если бы. Я всё перепрочитал.
Видишь, скок я не пробовал менять значение переменной maxchar, ничего не меняется (менял как в самих фукнциях, так и прописывал при выводе функции), т.е. kama_excerpt("maxchar=20");
Результат один и тот же.Всегда выводит текст до тэга more. Я пробовал его и 1000, и 2: различные вариации. Но не помогло.
Можно обратиться с этой помощью в icq или какой-нибудь агент. В любой момент, когда Вы свободны. Думаю, вы не хотите, чтобы здесь в комментариях было много "воды", да и на долго разговор затянется, что и Вам и мне не удобно. А так, если найдем ошибку, можно дописать слегка тему, что было бы большим плюсом.
Я был бы Вам очень благодарен. С нетерпением жду ответа.
Причем тут maxchar вообще, у вас текст до тега more выводиться без какой-либо обрезки? Не знаю как вы смотрели ссылку, которую я дал, но речь там идет об удалении части кода функции, которая отвечает за вывод текста до тега more, а именно, нужно удалить:
// для тега <!--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; }П.С. в обратной связи указана моя аська, могли бы туда написать! Включите логику немножко!
П.С. Просто я пробовал ещё использовать подобный плагин и его работа тоже была некорректна. Вывод был также до тэга more, хотя у товарища, который посоветовал всё работало безупречно
Спасибо, очень спасло. Необходимо было заменить warrior_excerpt(); ибо он выдавал кракозяблы. Ваше решение оказалось оптимальным. Сделал перепост с ссылкой на ваш сайт.
Рад что пригодилось! А ссылку на репост можно посмотреть?
Если сделать так
<?php the_content(''); ?>, то ссылка "далее" не выводится. Тоесть по сути WordPress сам обрезает до тега
. За функцию спасибо!
Хм, а как вместо ... поставить "читать далее"? На 1ой странице показывалось решение, но похоже это еще до изменения скрипта, потому что сейчас там нету такого