Использование wp_trim_excerpt, чтобы получить the_excerpt () вне цикла

20

Я создаю тему, которая будет показывать выдержки на главной странице для потенциально десятков постов. У меня нет отрывков из рук на всех моих постах, поэтому $post->post_excerptпуст для многих постов. В случае отсутствия отрывка вручную, я хотел бы использовать встроенную функцию get_the_excerpt (), но она недоступна вне цикла.

Отслеживая функцию, похоже, она использует wp_trim_excerpt из wp-includes / formatting.php для создания отрывков на лету. Я называю это в моем коде как wp_trim_excerpt( $item->post_content ), но это просто возвращает полный контент. Я делаю что-то неправильно?

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

http://adambrown.info/p/wp_hooks/hook/wp_trim_excerpt?version=3.0&file=wp-includes/formatting.php

Дерек Перкинс
источник
Вы можете попробовать вызвать фильтры $myvar = apply_filters( 'the_excerpt', $myvar );
отрывков

Ответы:

22

Начиная с WP 3.3.0, wp_trim_words()полезно, если вы можете получить контент, для которого вы хотите сгенерировать отрывок. Надеюсь, что это будет полезно для кого-то и сэкономит создание собственной функции подсчета слов.

http://codex.wordpress.org/Function_Reference/wp_trim_words

jamesc
источник
8

wp_trim_excerpt() имеет немного любопытную механику - если что-то передается ему, то это ничего не делает.

Вот основная логика:

  • get_the_excerpt() проверяет выписку вручную;
  • wp_trim_excerpt() включается, если нет отрывка вручную и делает его из контента или тизера.

Оба тесно связаны с глобальными переменными и поэтому Loop.

Вне цикла вам лучше вынуть код wp_trim_excerpt()и написать собственную функцию усечения.

Rarst
источник
6

Обновить:

Вот производная от wp_trim_excerpt (), которую я использовал. Работает отлично. Получено из Wordpress версии 3.0.4

function my_excerpt($text, $excerpt)
{
    if ($excerpt) return $excerpt;

    $text = strip_shortcodes( $text );

    $text = apply_filters('the_content', $text);
    $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 apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
}
Арди Арам
источник
Вам не нужно публиковать новый ответ, вы всегда можете отредактировать старый, чтобы добавить новую информацию. Вы можете, например, скопировать ссылку на код WP из вашего первого ответа в этот, а затем удалить свой первый ответ.
Ян Фабри
Для копирования / вставки: add $ raw_excerpt = $ text;
Святослав Маринов
1

Вот мой взгляд на «trim_excerpt», который принимает объект сообщения или идентификатор сообщения в качестве параметра.

Очевидно, основано на том, что в ядре. Не знаю, почему у этого (и get_the_author ()) нет нецикличных эквивалентов.

/**
     * Generates an excerpt from the content, if needed.
     *
     * @param int|object $post_or_id can be the post ID, or the actual $post object itself
     * @param string $excerpt_more the text that is applied to the end of the excerpt if we algorithically snip it
     * @return string the snipped excerpt or the manual excerpt if it exists         
     */
    function zg_trim_excerpt($post_or_id, $excerpt_more = ' [...]') {
        if ( is_object( $post_or_id ) ) $postObj = $post_or_id;
        else $postObj = get_post($post_or_id);

        $raw_excerpt = $text = $postObj->post_excerpt;
        if ( '' == $text ) {
            $text = $postObj->post_content;

            $text = strip_shortcodes( $text );

            $text = apply_filters('the_content', $text);
            $text = str_replace(']]>', ']]>', $text);
            $text = strip_tags($text);
            $excerpt_length = apply_filters('excerpt_length', 55);

            // don't automatically assume we will be using the global "read more" link provided by the theme
            // $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 apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
    }
Том Оже
источник
0

+1 к раст. Очень странно, что нет такой вещи как get_the_excerpt ($ post-> ID), когда должно быть совершенно очевидно, что так и должно быть. Во всяком случае, вот в wp_trim_excerpt () в WordPress версии 3.0.4:

http://core.trac.wordpress.org/browser/tags/3.0.4/wp-includes/formatting.php

function wp_trim_excerpt($text) {
1824            $raw_excerpt = $text;
1825            if ( '' == $text ) {
1826                    $text = get_the_content('');
1827    
1828                    $text = strip_shortcodes( $text );
1829    
1830                    $text = apply_filters('the_content', $text);
1831                    $text = str_replace(']]>', ']]>', $text);
1832                    $text = strip_tags($text);
1833                    $excerpt_length = apply_filters('excerpt_length', 55);
1834                    $excerpt_more = apply_filters('excerpt_more', ' ' . '[...]');
1835                    $words = preg_split("/[\n\r\t ]+/", $text, $excerpt_length + 1, PREG_SPLIT_NO_EMPTY);
1836                    if ( count($words) > $excerpt_length ) {
1837                            array_pop($words);
1838                            $text = implode(' ', $words);
1839                            $text = $text . $excerpt_more;
1840                    } else {
1841                            $text = implode(' ', $words);
1842                    }
1843            }
1844            return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
1845    }

Вы можете увидеть в строке 1826, что она связана с глобальной переменной $ post через get_the_contents. И да, я понятия не имею, о чем они думали. Но отсюда замените get_the_content на $ text в вашем собственном my_excerpt, и он должен вести себя аналогичным образом.

Арди Арам
источник
azure_ardee : рассмотрите возможность использования wp_trim_words ()
0

Функция get_the_content () вернула бы полный контент, если $ more! = 0. Вы должны установить глобальную переменную $ more в 0, чтобы функция get_the_content () возвращала отрывок.

Модифицированная функция wp_trim_excerpt ():

function wp_trim_excerpt($text) {
    $raw_excerpt = $text;
    if ( '' == $text ) {
        global $more;
        $tmp = $more;
        $more = 0;
        $text = get_the_content('');
        $more = $tmp;

        $text = strip_shortcodes( $text );

        $text = apply_filters('the_content', $text);
        $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 apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
}

источник
0

Используя ответы других выше, вот простой ответ, который, кажется, работает хорошо:

global $post;

$excerpt = apply_filters('get_the_excerpt', get_post_field('post_excerpt', $post->ID));

if ( $excerpt == '' ) {
    $excerpt = wp_trim_words( $post->post_content, 55 );
}

Я использую его в <meta>тегах функции для определения описаний OpenGraph. Итак, я просто добавляю:

<meta property="og:description" content="<?php echo esc_html( $excerpt ); ?>" />
dpruth
источник
Как насчет HTML контента? Как это будет работать с тегами? выдержка также удаляет HTML-теги и шорткоды. Что делать, если первые слова выдержки содержат изображение? Это, вероятно, сломает ваш макет.
Бретт