apply_filters () и the_excerpt дают неожиданные результаты

10

Я чувствую, что здесь должно быть что-то довольно очевидное, но я не могу заставить WordPress сотрудничать.

Я генерирую теги OG Facebook с функцией. Все отлично работает, кроме отрывка.

Начиная с устаревания get_the_excerpt($post->ID), есть ли другой способ создать отрывок без необходимости создавать новый цикл? Это кажется чрезмерным для меня.

Моим первым инстинктом было использовать apply_filters():

$description = apply_filters('the_excerpt', get_post($post->ID)->post_content);

Это дает мне полный пост, в комплекте с HTML-форматированным контентом. Хорошо, должно быть неправильно. Поэтому я попробовал следующую логическую идею:

$description = apply_filters('get_the_excerpt', get_post($post->ID)->post_content);

Нет кости. Теперь нет HTML, но это все еще полный пост (который действительно сбивает с толку).

Хорошо, без проблем. Давайте пропустим все модные вещи и просто перейдем к сокращенной записи:

$description = wp_trim_excerpt(get_post($post->ID)->post_content);

Без изменений.

Итак, мой вопрос заключается в следующем: что, черт возьми, происходит? Здесь я что-то упускаю?

Я вошел в ядро ​​WP, чтобы выяснить, как это the_excerpt()работает, и оно похоже на мой вызов:

/**
 * Display the post excerpt.
 *
 * @since 0.71
 * @uses apply_filters() Calls 'the_excerpt' hook on post excerpt.
 */
function the_excerpt() {
    echo apply_filters('the_excerpt', get_the_excerpt());
}

У меня есть несколько вопросов, основанных на моих выводах:

  1. Почему фильтр не применяется, как ожидалось?
  2. Есть ли способ получить отрывок вне цикла без создания нового цикла?
  3. Я сумасшедший?

Заранее спасибо за взгляд. Я здесь довольно тупой.

jlengstorf
источник
get_the_excerpt()не считается устаревшим, просто дополнительный параметр, который был передан ему, больше не используется.
Майло,
Извините, это то, что я имел в виду. Спасибо за разъяснения.
Йленгсторф
Ты сумасшедший! , , , как я лол
pythonian29033

Ответы:

16

Оказывается, ответ был в wp_trim_excerpt().

Это определено в wp-includes/functions.php:1879:

/**
 * Generates an excerpt from the content, if needed.
 *
 * The excerpt word amount will be 55 words and if the amount is greater than
 * that, then the string ' [...]' will be appended to the excerpt. If the string
 * is less than 55 words, then the content will be returned as is.
 *
 * The 55 word limit can be modified by plugins/themes using the excerpt_length filter
 * The ' [...]' string can be modified by plugins/themes using the excerpt_more filter
 *
 * @since 1.5.0
 *
 * @param string $text Optional. The excerpt. If set to empty, an excerpt is generated.
 * @return string The excerpt.
 */
function wp_trim_excerpt($text = '') {
    $raw_excerpt = $text;
    if ( '' == $text ) {
        $text = get_the_content('');

        $text = strip_shortcodes( $text );

        $text = apply_filters('the_content', $text);
        $text = str_replace(']]>', ']]>', $text);
        $excerpt_length = apply_filters('excerpt_length', 55);
        $excerpt_more = apply_filters('excerpt_more', ' ' . '[...]');
        $text = wp_trim_words( $text, $excerpt_length, $excerpt_more );
    }
    return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
}

Таким образом, любой переданный текст не обрабатывается; это работает только если он вызывается с пустым параметром.

Чтобы решить эту проблему, я добавил в свою тему быстрый фильтр, который решает проблему:

/**
 * Allows for excerpt generation outside the loop.
 * 
 * @param string $text  The text to be trimmed
 * @return string       The trimmed text
 */
function rw_trim_excerpt( $text='' )
{
    $text = strip_shortcodes( $text );
    $text = apply_filters('the_content', $text);
    $text = str_replace(']]>', ']]>', $text);
    $excerpt_length = apply_filters('excerpt_length', 55);
    $excerpt_more = apply_filters('excerpt_more', ' ' . '[...]');
    return wp_trim_words( $text, $excerpt_length, $excerpt_more );
}
add_filter('wp_trim_excerpt', 'rw_trim_excerpt');

Это несколько избыточно, но мне нравится это лучше, чем открывать новые циклы каждый раз, когда я хочу создать отрывок.

jlengstorf
источник
1
Ах, мне было не понятно, что вы ищете только текстовую операцию (не извлекающую из БД).
2012 года
Не стоит беспокоиться. Я всегда боюсь, что не вижу смысла, когда задаю вопросы. Я был вытягивать из базы данных, но я не хочу , чтобы открыть в целом «ругой цикла , так как у меня есть такие вещи , как get_the_title($post->ID)доступны. Последняя строка кода была$description = wp_trim_excerpt(get_post($post->ID)->post_content);
jlengstorf
Я чувствую себя очень глупо, спрашивая это, но как вы называете этот новый фильтр? Я попробовал это как $content = apply_filters( 'rw_trim_excerpt', $content );и $content = rw_trim_excerpt($content);, но ни один из них не работал (первый не урезал вывод, и позже произвел ошибку).
Эрик К
2
@QuantumDynamix Это предназначено , чтобы изменить get_the_excerptобработку для мимических the_excerpt, так что вы можете позвонить: apply_filters('get_the_excerpt', $content);.
Йленгсторф
уф! хороший с точки зрения woop noob, спасибо
pythonian29033
1

Пытаться:

   get_post($post->ID)->post_excerpt
                        ^^^^^^^^^^^^

См .: get_postКодекс для всех доступных возвращающихся членов.

hakre
источник
4
Это возвращает пустое значение, если выдержка для сообщения не была введена. Мне нужно имитировать действия get_the_excerpt () (создание выдержки, если ее не существует).
Йленгсторф
Применение фильтра не сделает этого, поэтому вы задаете не тот вопрос. Не знаю, почему вы ищете отрывок, если его нет. get_the_excerpt()не подражает этому, проверьте источник, это только доступ к переменной-члену $postкоторого есть post_excerpt. Смотрите также ссылку на кодекс в ответе.
Хакре
3
Начиная с записи Кодекса the_excerpt: «она будет отображать автоматическую выдержку, которая ссылается на первые 55 слов содержания сообщения». Я хочу имитировать это поведение за пределами цикла.
Йленгсторф
Хорошо, временно создайте второй цикл и запросите этот файл по его идентификатору, возможно, для быстрого решения. См. Вторичные циклы - codex.wordpress.org/Function_Reference/…
hakre
1
Спасибо за ссылку. Я знал, что смогу создать дополнительную петлю, но это кажется излишним. Мое решение было добавить фильтр. Теперь я вижу это как небольшую смазку для локтя, чтобы потом было намного меньше кода.
Йленгсторф
0

Вы можете использовать мою пользовательскую функцию для фильтрации контента (это из NARGA Framework )

  • Если у поста есть пользовательский отрывок, отобразите его вместо содержимого
  • Автоматическое создание выдержки из содержания, если сообщение не имеет пользовательского сертификата
  • Автоматическая обрезка шорткода, HTML кода, удаление [...], добавление текста «Подробнее» (переводимый)

        /**
        * Auto generate excerpt from content if the post hasn't custom excerpt
        * @from NARGA Framework - http://www.narga.net/narga-core
        * @param $excerpt_lenght  The maximium words of excerpt generating from content
        * @coder: Nguyễn Đình Quân a.k.a Narga - http://www.narga.net
        **/  
        function narga_excerpts($content = false) {
        # If is the home page, an archive, or search results
        if(is_front_page() || is_archive() || is_search()) :
            global $post;
        $content = $post->post_excerpt;
        $content = strip_shortcodes($content);
        $content = str_replace(']]>', ']]>', $content);
        $content = strip_tags($content);
        # If an excerpt is set in the Optional Excerpt box
        if($content) :
            $content = apply_filters('the_excerpt', $content);
        # If no excerpt is set
        else :
            $content = $post->post_content;
            $excerpt_length = 50;
            $words = explode(' ', $content, $excerpt_length + 1);
        if(count($words) > $excerpt_length) :
            array_pop($words);
            array_push($words, '...<p><a class="more-link" href="' . get_permalink() . '" title="' . the_title_attribute('echo=0') . '">  ' . __( 'Read more &#187;', 'narga' ) . ' </a></p>');
            $content = implode(' ', $words);
        endif;
        $content = '<p>' . $content . '</p>';
        endif;
        endif;
        # Make sure to return the content
        return $content;
        }
        // Add filter to the_content
        add_filter('the_content', 'narga_excerpts');
Narga
источник