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 - это количество оставляемых символов.

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

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

igrat2.vulkanslots.org

Обрезка текста и/или замена стандартной функции the_excerpt() 144 комментария
Полезные 4 Вопросы 1 Все
  • seoonly.ru cайт: seoonly.ru

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

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

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

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

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

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

    1
  • Алексей

    спасибо огромное за код, пригодился. подскажите пожалуйста, как ограничить длину тега "more", чтобы совсем длинный текст, если тег стоит глубоко - все-равно обрезался, не спрашивайте зачем)

    1
    • Алексей

      всё разобрался, добавил строчку $text = mb_substr( $text, 0, $rg->maxchar );

      1
  • Alex

    Пытаюсь использовать эту функцию, после того как я ее копирую/вставляю в function.php у меня сайт не грузится, пишет:HTTP ERROR 500 Как поправить ? Что делаю не так?

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

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

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