11.03.2020

Wordpress: работа с анонсом статьи

Для разработки собственных тем Wordpress активно используется функция the_excerpt(), которая выводит краткое описание (анонс) статьи.

Функция the_excerpt() выводит анонс поста, который был указан при написании (текст до тега <!--more-->) или формирует его автоматически. Сформированный анонс имеет определенную длину и завершает вывод вставкой [...]

У данной функции есть один существенный недостаток: при выводе анонса она полностью убирает все форматирование, ранее примененное к тексту, в том числе, переносы строк.

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

Все манипуляции осуществляются черед добавление в файл functions.php текущей темы.

1. Изменение количества слов

По умолчанию длина анонса составляет 55 слов, для изменения данного значения используется фильтр excerpt_length. Добавляем строку

add_filter( 'excerpt_length', function(){ return 20;} );

 2. Удаление или замена конструкции [...]

Для изменения данного окончания используется фильтр excerpt_more. В функции, которая будет вызываться, можно использовать стандартные методы работы с постами, предварительно объявив глобальную переменную $post

add_filter( 'excerpt_more', 'new_excerpt_more' );

function new_excerpt_more( $more ){ 

global $post;

return '<a href="'. get_permalink($post) . '">Читать полностью...</a>';

}

3. Сохранение форматирования текста

При выводе текста данная функция убирает все форматирование текста: выделение жирным, курсивом, переносы строк, абсолютно все html-теги, которые использовались в тексте.

Все html-теги удаляются при вызове функции wp_strip_all_tags() \wp-includes\formatting.php. При желании, можно внести изменения прямо в нее. При этом, стоит учитывать, что все внесенные изменения будут удалены при обновлении Wordpress. Также можно пойти более "длинным" путем, который будет работать и после обновлений.

Для второго варианта необходимо добавить в файл functions.php следующий код, который практически полностью идентичен оригинальному:

// Удаляем стандартные фильтры вывода анонса

remove_filter('get_the_excerpt', 'wp_trim_excerpt');

remove_filter('get_the_excerpt', 'lyte_trim_excerpt');

// Добавляем фильтр для вывода анонса

add_filter('get_the_excerpt', 'my_wp_trim_excerpt');


// Функция удаления html-тегов

function my_wp_strip_all_tags($string, $remove_breaks = false) {

$string = preg_replace('@<(script|style)[^>]*?>.*?</\\1>@si', '', $string);

// Во втором аргументе функции strip_tags() перечисляются разрешенные теги, не рекомендую добавлять тег <img> в разрешенные

$string = strip_tags($string, '<br><p><b><strong><em><a>');

if ($remove_breaks) {

$string = preg_replace('/[\r\n\t ]+/', ' ', $string);

}

return trim($string);

}

function my_wp_trim_words($text, $num_words = 55, $more = null) {

if (null === $more) {

$more = __('&hellip;');

}

$original_text = $text;

$text = my_wp_strip_all_tags($text);

$num_words = (int) $num_words;

if (strpos(_x('words', 'Word count type. Do not translate!'), 'characters') === 0 && preg_match('/^utf\-?8$/i', get_option('blog_charset'))) {

$text = trim(preg_replace("/[\n\r\t ]+/", ' ', $text), ' ');

preg_match_all('/./u', $text, $words_array);

$words_array = array_slice($words_array[0], 0, $num_words + 1);

$sep = '';

} else {

$words_array = preg_split("/[\n\r\t ]+/", $text, $num_words + 1, PREG_SPLIT_NO_EMPTY);

$sep = ' ';

}

if (count($words_array) > $num_words) {

array_pop($words_array);

$text = implode($sep, $words_array);

$text = $text . $more;

} else {

$text = implode($sep, $words_array);

}

return apply_filters('my_wp_trim_words', $text, $num_words, $more, $original_text);

}


function my_wp_trim_excerpt($text = '', $post = null) {

$raw_excerpt = $text;

if ('' == $text) {

$post = get_post($post);

$text = get_the_content('', false, $post);

$text = strip_shortcodes($text);

$text = excerpt_remove_blocks($text);

$text = apply_filters('the_content', $text);

$text = str_replace(']]>', ']]&gt;', $text);

$excerpt_length = intval(_x('55', 'excerpt_length'));

$excerpt_length = (int) apply_filters('excerpt_length', $excerpt_length);

$excerpt_more = apply_filters('excerpt_more', ' ' . '[&hellip;]');

$text = my_wp_trim_words($text, $excerpt_length, $excerpt_more);

return apply_filters('my_wp_trim_excerpt', $text, $raw_excerpt);

}

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

Использованные материалы:

https://developer.wordpress.org/reference/functions/the_excerpt/

Комментариев нет:

Отправить комментарий