Использование the_excerpt вместо the_content?
Коротко и ясно — я хотел выводить краткое описание записи (excerpt) вместо полного содержимого (the_content) на определённых страницах. Естественно, если краткое описание не задано, оно должно генерироваться из содержимого. Я понимаю, что можно просто редактировать файлы темы, но хотелось бы менее инвазивный метод.
Увидев, что что-то подобное работает:
add_action( 'the_content', 'myFunc' );
function myFunc ( $content ) {
the_title();
}
Я подумал попробовать это:
add_action( 'the_content', 'myFunc' );
function myFunc ( $content ) {
the_excerpt();
}
Это. Не. Сработало. Совершенно. На самом деле привело к фатальной ошибке:
ФАТАЛЬНАЯ ОШИБКА: ДОСТИГНУТ МАКСИМАЛЬНЫЙ УРОВЕНЬ ВЛОЖЕННОСТИ ФУНКЦИЙ '100', ВЫПОЛНЕНИЕ ПРЕРВАНО! В C:\WAMP\WWW\WORDPRESS\WP-INCLUDES\POST.PHP НА СТРОКЕ 555
За этим следует огромный стек вызовов, который, похоже, впал в безумный цикл рекурсивных вызовов.
Меняем местами
Это вызвало моё любопытство, и я попробовал обратное. Вывести the_content
вместо the_excerpt
:
add_action( 'the_excerpt', 'myFunc' );
function myFunc ( $content ) {
the_content();
}
К моему удивлению, это сработало отлично. Из этого я сделал вывод, что the_excerpt
вызывает the_content
, но the_content
не вызывает the_excerpt
— это объяснило бы, почему один вариант работает, а другой впадает в бесконечную рекурсию.
Не будучи сильно знакомым с внутренней работой этих двух функций, мне было интересно, какие объяснения может предложить сообщество. В чём проблема с подключением к the_content
и вызовом the_excerpt
?
Как я могу достичь этого эффекта, если не через прямой вызов the_content
? Я понимаю, что могу написать свою логику для excerpt, но это нарушит единообразие логики формирования кратких описаний на моём сайте — часть будет создаваться через кастомный код в functions.php, а часть через внутренние методы WordPress. В идеале я хотел бы избежать этого и использовать только внутренние методы, если это возможно.

Все хорошие примеры. Но они не работали для меня с темой (pinboard) и плагином, который я использовал (secondary-html-content), и тем, что я хотел сделать.
Первой задачей было убедиться, что я получаю обе части контента, а не только одну. Вторая задача состояла в том, чтобы заменить краткое описание (excerpt) на главной странице фактическим содержимым.
Поэтому я создал новый плагин, который делает следующее:
function okmAddingContentExcerpt() {
global $post;
$content = '<div class="comment-first">'.$post->post_content.'</div>';
// Adia Review - это название метки из плагина secondary-html-content
$content .= '<div class="comment-second">'.get_secondary_content('Adia Review',$post->ID).'</div>';
return $content;
}
add_filter('the_excerpt', 'okmAddingContentExcerpt');
function okmAddingContentSingle() {
global $post;
$content = '<div class="comment-first">'.$post->post_content.'</div>';
// удаляем фильтр, чтобы избежать бесконечного цикла
remove_filter('the_content','okmAddingContentSingle');
$content .= '<div class="comment-second">'.get_secondary_content('Adia Review',$post->ID).'</div>';
return $content;
}
add_filter('the_content', 'okmAddingContentSingle');
Обратите внимание, что я хотел сохранить контент вместо краткого описания на главной странице.
Кстати, если вы хотите скачать плагин, я добавил его на свой блог-сайт: http://okmaya.com/wordpress-plugin-for-pinboard-theme-and-secondary-html-content-plugin/

На самом деле, the_excerpt()
вызывает get_the_excerpt()
, который выводит $post->post_excerpt
.
Ещё одно замечание: разве не стоит использовать add_filter()
вместо add_action()
?
Почему вы используете the_excerpt()
/the_content()
/the_title()
, вместо того чтобы установить $content
= get_the_excerpt()
и т.д., а затем вернуть $content
? Например, это:
add_filter( 'the_content', 'myFunc' );
function myFunc ( $content ) {
the_excerpt();
}
...обычно пишется так:
add_filter( 'the_content', 'myFunc' );
function myFunc ( $content ) {
$content = get_the_excerpt();
return $content;
}
Не уверен, поможет ли это решить вашу проблему с рекурсивным циклом...
РЕДАКТИРОВАНИЕ
Ваш последний комментарий натолкнул меня на идею: почему бы просто не пропустить $content через wp_trim_excerpt()
и закончить с этим?
add_filter( 'the_content', 'myFunc' );
function myFunc( $content ) {
$excerpt = wp_trim_excerpt( $content );
return $excerpt;
}
РЕДАКТИРОВАНИЕ 2
Хорошо, теперь я вас понимаю. Как насчёт того, чтобы создать свою собственную функцию для вывода отрывка?
add_filter( 'the_content', 'myFunc' );
function myFunc( $content ) {
$text = strip_shortcodes( $content );
$text = str_replace(']]>', ']]>', $text);
$text = strip_tags($text);
$excerpt_length = apply_filters('excerpt_length', 55);
$excerpt_more = apply_filters('excerpt_more', ' ' . '[...]');
$words = preg_split("/[\n\r\t ]+/", $text, $excerpt_length + 1, PREG_SPLIT_NO_EMPTY);
if ( count($words) > $excerpt_length ) {
array_pop($words);
$text = implode(' ', $words);
$text = $text . $excerpt_more;
} else {
$text = implode(' ', $words);
}
return $text;
}

Я не имел в виду, что the_excerpt
вызывает the_content
напрямую, извините за путаницу. the_excerpt
вызывает wp_trim_excerpt
, который в свою очередь вызывает get_the_content
. Честно говоря, я не уверен, где именно начинаются проблемы. К сожалению, другие предложения из вашего ответа не помогли. Неважно, использовал ли я add_action
или add_filter
— в данном случае это не имело значения. Я также перешел на возвращение значений вместо их неявного вывода с помощью функций the_
— но улучшений так и не появилось.

Только что осознал, что забыл упомянуть одну важную деталь. У записей нет готовых цитат (excerpts) — они должны генерироваться из содержимого. Поэтому что-то вроде global $post; return $post->post_excerpt;
сработало бы, но вернуло бы пустую строку.

Я тоже пробовал это сделать. Как ни странно, возвращается только отформатированный контент — без ограничения по количеству символов, как ожидалось.

wp_trim_excerpt()
вызывает $text = apply_filters('the_content', $text);
, что приводит к рекурсивным вызовам. Возможно, стоит попробовать извлечь код из wp_trim_excerpt()
из файла /wp-includes/formatting.php, строка 1830, исключив эту строку — хотя я не знаю, насколько она важна для формирования анонсов.

Ладно, смотрите правку №2; давайте попробуем создать свою собственную функцию для обрезки анонсов.

@Chip Я, конечно, мог бы написать свою собственную логику, но тогда я начну дробить логику формирования отрывков по всему сайту. То есть, если только я не предоставлю глобальную перезапись для всех отрывков, а не только для тех, что предоставляются вместо the_content
.
