WordPress как на ладони
Готовые темы (шаблоны) для WordPress wordpress jino

Обрезка текста и/или замена стандартной функции the_excerpt()

Обратил внимание, что функция WordPress the_excerpt() громоздкая. На её выполнение уходит много времени и ресурсов. Потому что она вызывает get_the_excerpt(), the_content() и ко всем ним, включая сам the_excerpt(), применяются различные хуки. В итоге получается немало операций - это нужно далеко не всегда. Я например, к цитатам отношусь просто - коротко сказать о чем статья, вырезав небольшой её кусок - достаточно просто текста.

С этим недостатком я мерился, до того момента, пока мне не понадобилась обрезать текст до определенного количества символов. Тогда то я и решил написать функцию обрезающую текст.

Результат замены the_excerpt() меня порадовал: генерация страницы уменьшилась в среднем с 0,850 сек до 0,550 сек, при 9 вызовах the_excerpt() (это время на компьютере, на сервере обычно оно меньше). 9 вызовов - это количество выводимых постов в рубрике, к каждому из которых применялся the_excerpt().

Ниже функция, которой можно заменить стандартную функцию WordPress the_excerpt().

/**
 * Обрезка текста (excerpt). Шоткоды вырезаются. Минимальное значение maxchar может быть 22.
 *
 * @param (строка/массив) $args Параметры.
 *
 * @return HTML
 * ver 2.6.1
 */
function kama_excerpt( $args = '' ){
	global $post;

	$default = array(
		'maxchar'   => 350,   // количество символов.
		'text'      => '',    // какой текст обрезать (по умолчанию post_excerpt, если нет post_content.
							  // Если есть тег <!--more-->, то maxchar игнорируется и берется все до <!--more--> вместе с HTML
		'autop'     => true,  // Заменить переносы строк на <p> и <br> или нет
		'save_tags' => '',    // Теги, которые нужно оставить в тексте, например '<strong><b><a>'
		'more_text' => 'Читать дальше...', // текст ссылки читать дальше
	);

	if( is_array($args) ) $_args = $args;
	else                  parse_str( $args, $_args );

	$rg = (object) array_merge( $default, $_args );
	if( ! $rg->text ) $rg->text = $post->post_excerpt ?: $post->post_content;
	$rg = apply_filters('kama_excerpt_args', $rg );

	$text = $rg->text;
	$text = preg_replace ('~\[/?.*?\](?!\()~', '', $text ); // убираем шоткоды, например:[singlepic id=3], markdown +
	$text = trim( $text );

	// <!--more-->
	if( strpos( $text, '<!--more-->') ){
		preg_match('/(.*)<!--more-->/s', $text, $mm );

		$text = trim($mm[1]);

		$text_append = ' <a href="'. get_permalink( $post->ID ) .'#more-'. $post->ID .'">'. $rg->more_text .'</a>';
	}
	// text, excerpt, content
	else {
		$text = trim( strip_tags($text, $rg->save_tags) );

		// Обрезаем
		if( mb_strlen($text) > $rg->maxchar ){
			$text = mb_substr( $text, 0, $rg->maxchar );
			$text = preg_replace('~(.*)\s[^\s]*$~s', '\\1 ...', $text ); // убираем последнее слово, оно 99% неполное
		}
	}

	// Сохраняем переносы строк. Упрощенный аналог wpautop()
	if( $rg->autop ){
		$text = preg_replace(
			array("~\r~", "~\n{2,}~", "~\n~",   '~</p><br ?/>~'),
			array('',     '</p><p>',  '<br />', '</p>'),
			$text
		);
	}

	$text = apply_filters('kama_excerpt', $text, $rg );

	if( isset($text_append) ) $text .= $text_append;

	return ($rg->autop && $text) ? "<p>$text</p>" : $text;
}
/* changelog
 * 2.6 - удалил параметр 'save_format' и заменил его на два параметра 'autop' и 'save_tags'.
 *       Немного изменил логику кода.
 */

Как работает функция

  1. Обрезать до определенного количества символов. Указывается в параметре maxchar.

  2. Понимает тег <!--more--> в записи. Если он присутствует желаемое количество выводимых символов игнорируется и выводится все что выше  <!--more--> с сохранением HTML разметки.

  3. Можно указать сохранять переносы строк или писать весь текст в одну строку. По умолчанию переносы сохраняются, если нужен "сплошняк" ставим параметр autop=0.

  4. Можно указан какие HTML теги не нужно вырезать, например мы хотим оставить тег stront или em, тогда указываем их в параметре save_tags: save_tags=<strong><em>

  5. Также, можно использовать функцию, чтобы обрезать любой текст, который ей будет передан через параметр text.

Обрезка во всех случаях вычисляет количество символов, а затем убирает последние символы до пробела. Нужно это для того, чтобы в конце всегда оставалось законченное слово, а не кусок недописанного слова - я думаю это некрасиво.

Использование

Вставляем указанный выше код в файл functions.php вашего шаблона. И где нужно вывести обрезанный текст вызываем функцию так:

<?php echo kama_excerpt( array('maxchar'=>100, 'text'=>'бла бла') ); ?>

Чтобы заменить стандартный the_excerpt() нужно просто заменить the_excerpt() на kama_excerpt() Все это должно быть внутри цикла the loop.

ВАЖНО: Параметр text при замене the_excerpt(); указывать не надо!

Пример использования функции, как обрезка любого текста (в любом месте шаблона):

$rrr = "Функцию обрезки текста для Worpress, можно применять и на других движках.";
echo kama_excerpt( array('text'=>$rrr, 'maxchar'=>50) );
// Выведет: Функцию обрезки текста для Worpress, можно применять ...

При обрезке передаваемого функции текста, срабатывает только та часть функции которая необходима, т.е. никаких лишних операций.

Очень простой пример обрезки текста

Если вы не хотите использовать функцию и вам нужно просто обрезать текст не сохранения html теги и прочее, то можно воспользоваться такой короткой строкой внутри цикла WordPress:

<?php echo mb_substr( strip_tags( get_the_content() ), 0, 152 ); ?>

где 152 - это количество оставляемых символов.

Обрезка текста и/или замена стандартной функции the_excerpt() 142 комментария
Полезные 4 Вопросы 3 Все
  • Евгений

    Как можно решить мою проблему в вашем скрипте, я обычно заполняю поле Цитата(Анонс), а иногда приходиться просто без какого то текста скидывать видео с Ютуба, если я так делаю то на главной страницы(index.php) не чего не выводиться а надо что бы видео было. Можно ли как то это сделать ?

    Ответить1.2 года назад #
  • Геннадий

    Сейчас для обрезки используется

    <div class="title"><a href="<?php the_permalink() ?>" rel="bookmark"><?php echo wp_trim_words( get_the_title(), 5, '...' ); ?></a></div>

    Помогите перейти на ваше решение. Не пойму как изменить. ничего не получается

    Ответитьгод назад #
    1
  • seoonly.ru cайт: seoonly.ru

    Спасибо, очень помогло!

    Ответитьгод назад #
  • Игорь cайт: www.lebedyan.com
    1. Если нет post_exсerpt и post_content начинается с изображения, а не текста, то функция ничего не выводит.
    2. Если количество символов в post_excerpt меньше чем maxchar, то в конце текста не выводится многоточие.
      Моих знаний не хватает, чтобы это исправить sad
    Ответитьгод назад #
    • Игорь cайт: www.lebedyan.com
      1. Прошу прощения, похоже, это я сам намудрил.
      2. if ( mb_strlen( $text ) > $maxchar ) заменил на if ( mb_strlen( $text ) > 22 ) - теперь многоточие ставит.

      Спасибо. Весьма полезный сайт wink

      Ответитьгод назад #
  • Александр

    Вместо "Читать дальше" ставит троеточие

  • @

    Долго думал что делать с тем, что есть "критическая" масса текста когда обрезка занимает не 0.002-0.005 сек, а 0.1+ сек у некоторых постов... Думал, думал и решил зайти сюда спросить что же такое. А оказалось что у меня старая версия кода стоит. Обновил, теперь эта проблема можно сказать исчезла. Теперь есть "критическая" масса текста когда обрезка занимает 0.002-0.005 сек. а в остальных случаях это число вида 8.12341E-5 или что то такое, ну как я понял это очень-очень мало.

    Ответить3 месяца назад #

Здравствуйте, !

Ваш комментарий