Trim text and / or replace the standard the_excerpt () function

06 04 2021

Function WordPress the_excerpt () cumbersome. It takes a lot of time and resources to implement. Because it causes get_the_excerpt () , the_content () and to all of them, including himselfthe_excerpt () , different hooks are used. The result is a lot of operations - it is not always necessary. For example, I treat quotes simply - to say briefly about what the article is, cutting out a small piece of it - quite simply the text.

I measured this shortcoming, until I needed to cut the text to a certain number of characters. Then I decided to write a function to cut the text.

The result of replacing the_excerpt () pleased me: page generation decreased on average from 0.850 sec to 0.550 sec , with 9 calls to the_excerpt () (this time on the computer, on the server it is usually less). 9 calls is the number of displayed posts in the heading, to each of which was applied the_excerpt () .

Below is a function that can replace the standard WordPress function the_excerpt () .

/**
 * Cuts the specified text up to specified number of characters.
 * Strips any of shortcodes.
 *
 * @author Kama (wp-kama.ru)
 *
 * @version 2.7.1
 *
 * @param string|array $args {
 *     Optional. Arguments to customize output.
 *
 *     @type int       $maxchar            Макс. количество символов.
 *     @type string    $text               Текст который нужно обрезать. По умолчанию post_excerpt, если нет post_content.
 *                                         Если в тексте есть `<!--more-->`, то `maxchar` игнорируется и берется
 *                                         все до `<!--more-->` вместе с HTML.
 *     @type bool      $autop              Заменить переносы строк на `<p>` и `<br>` или нет?
 *     @type string    $more_text          Текст ссылки `Читать дальше`.
 *     @type string    $save_tags          Теги, которые нужно оставить в тексте. Например `'<strong><b><a>'`.
 *     @type string    $sanitize_callback  Функция очистки текста.
 *     @type bool      $ignore_more        Нужно ли игнорировать <!--more--> в контенте.
 *
 * }
 *
 * @return string HTML
 */
function kama_excerpt( $args = '' ){
	global $post;

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

	$rg = (object) array_merge( [
		'maxchar'           => 350,
		'text'              => '',
		'autop'             => true,
		'more_text'         => 'Читать дальше...',
		'ignore_more'       => false,
		'save_tags'         => '',
		'sanitize_callback' => 'strip_tags',
	], $args );

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

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

	$text = $rg->text;
	// strip content shortcodes: [foo]some data[/foo]. Consider markdown
	$text = preg_replace( '~\[([a-z0-9_-]+)[^\]]*\](?!\().*?\[/\1\]~is', '', $text );
	// strip others shortcodes: [singlepic id=3]. Consider markdown
	$text = preg_replace( '~\[/?[^\]]*\](?!\()~', '', $text );
	$text = trim( $text );

	// <!--more-->
	if( ! $rg->ignore_more && 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 = 'strip_tags' === $rg->sanitize_callback
			? strip_tags( $text, $rg->save_tags )
			: call_user_func( $rg->sanitize_callback, $text, $rg );

		$text = trim( $text );

		// cut
		if( mb_strlen( $text ) > $rg->maxchar ){
			$text = mb_substr( $text, 0, $rg->maxchar );
			$text = preg_replace( '/(.*)\s[^\s]*$/s', '\\1...', $text ); // del last word, it not complate in 99%
		}
	}

	// add <p> tags. Simple analog of wpautop()
	if( $rg->autop ){
		$text = preg_replace(
			[ "/\r/", "/\n{2,}/", "/\n/", '~</p><br ?/?>~' ],
			[ '', '</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.7.0 - Параметр sanitize_callback
 * 2.6.5 - Параметр ignore_more
 * 2.6.4 - Забрав пробіл між словом і крапками
 * 2.6.3 - Рефакторинг
 * 2.6.2 - Добавив регулярку для видалення блочних шорткодів вида: [foo]some data[/foo]
 * 2.6   - Видалив параметр 'save_format' и замінив його на два параметри 'autop' і 'save_tags'.
 *       - Немного изменил логику кода.
 */

How does the function work?

  1. Crops to a certain number of characters. Specified in the parameter maxchar.
  2. Understands tag <! - more -> in the record. If it is present, the desired number of displayed characters is ignored and everything above is displayed  <! - more -> while preserving HTML markup.
  3. You can specify to save line breaks or write all text in one line. By default, hyphens are saved, if you need a "solid" set the parameter autop = 0 .
  4. You can specify which HTML tags do not need to be cut. For example, we want to leaveтеги <strong> і <em> , then indicate them as follows:save_tags=<strong><em>
  5. You can also use the function to trim any text that is passed to it. To do this, specify the text in the parameter text.

Trimming in all cases calculates the number of characters and then removes the last characters to the space. It is necessary that in the end there was always the finished word, instead of a piece unfinished (I think it is ugly).

Using

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

To replace the standard the_excerpt () just need to replace the_excerpt () на kama_excerpt () . All this should be within the WordPress loop.

IMPORTANT: Parameter textпри заміні the_excerpt () ; no need to specify!

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

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

We will receive

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

When trimming the transmitted function of the text, only the part of the function that is necessary (no unnecessary operations) is triggered.

A very simple example of text cropping

If you don't want to use the feature and you just need to trim the text without saving html tags and stuff, then you can use the following short string inside a WordPress loop:

<?php
$maxchar = 152;
$text = strip_tags( get_the_content() );
echo mb_substr( $text, 0, $maxchar );
?>
Поширити

Напишіть свій коментар

Ваша електронна адреса не буде опублікована. Обов’язкові поля позначені *