Использование the_excerpt вместо the_content?

12 июл. 2011 г., 18:55:38
Просмотры: 3.23K
Голосов: 0

Коротко и ясно — я хотел выводить краткое описание записи (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. В идеале я хотел бы избежать этого и использовать только внутренние методы, если это возможно.

0
Все ответы на вопрос 2
0

Все хорошие примеры. Но они не работали для меня с темой (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/

7 февр. 2013 г. 19:45:36
7

На самом деле, 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(']]>', ']]&gt;', $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;
}
12 июл. 2011 г. 19:14:37
Комментарии

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

Sampson Sampson
12 июл. 2011 г. 19:26:38

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

Sampson Sampson
12 июл. 2011 г. 19:45:35

Хм... ладно, посмотрите обновленный ответ — там другая идея.

Chip Bennett Chip Bennett
12 июл. 2011 г. 20:11:46

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

Sampson Sampson
12 июл. 2011 г. 20:17:21

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

Michael Michael
12 июл. 2011 г. 20:24:26

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

Chip Bennett Chip Bennett
12 июл. 2011 г. 20:33:10

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

Sampson Sampson
12 июл. 2011 г. 20:42:57
Показать остальные 2 комментариев