WordPress как на ладони
Новые WordPress шаблоны Недорогой хостинг для сайтов на WordPress: wordpress.jino.ru

Обрезка текста и/или замена стандартной функции 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 string/array $args Параметры.
 *
 * @return string HTML
 *
 * @ver 2.6.3
 */
function kama_excerpt( $args = '' ){
	global $post;

	if( is_string($args) )
		parse_str( $args, $args );

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

	$rg = apply_filters( 'kama_excerpt_args', $rg );

	if( ! $rg->text )
		$rg->text = $post->post_excerpt ?: $post->post_content;

	$text = $rg->text;
	$text = preg_replace( '~\[([a-z0-9_-]+)[^\]]*\](?!\().*?\[/\1\]~is', '', $text ); // убираем блочные шорткоды: [foo]some data[/foo]. Учитывает markdown
	$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 ) .'#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;
}
/* Сhangelog:
 * 2.6.3 - Рефакторинг
 * 2.6.2 - Добавил регулярку для удаления блочных шорткодов вида: [foo]some data[/foo]
 * 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(); указывать не надо!

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

$str = "Функцию [foo]some text[/foo] [foo]some text[/foo] обрезки текста для Worpress, 
можно применять [foo url='bar'] и на других движках.";

echo esc_html( kama_excerpt([ 'text'=>$str, 'maxchar'=>70 ]) );

Получим:

<p>Функцию   обрезки текста для Worpress,<br />
можно применять  и на других ...</p>

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

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

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

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

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

Игровой автомат Книжки

Играть в игровой автомат Книжки в клубе Вулкан

besplatno6.vulkanslots.su

143 коммента
Полезные 4 Вопросы 2 Все
  • seoonly.ru cайт: seoonly.ru

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

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

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

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

    1
    Ответить1.6 год назад #
  • pathf1nder

    Здравствуйте.
    Не получается у меня. Не игнорирует он теги more (
    Часть кода удалял.
    Подскажите пожалуйста.

  • VRS

    Если видео вставлено с сайта через шорткод embed, то функция оставляет в тексте цитаты линк на файл.

    1
    • Kama6984

      Добавил такую регулярку, теперь все вырезается:

      $text = preg_replace( '~\[([a-z0-9_-]+)[^\]]*\].*?\[/\1\]~is', '', $text ); // убираем  блочные шорткоды [foo]some data[/foo]
      Ответить4 месяца назад #
  • Михаил

    Здравствуйте! Спасибо за функцию, использую на своих проектах.

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

    Вот реальный пример:
    "на карту. В... "

    В... - здесь лишняя конструкция smile

    Ответить3 месяца назад #
Здравствуйте, !     Войти . Зарегистрироваться