Usando wp_trim_excerpt para obtener the_excerpt () fuera del ciclo

20

Estoy creando un tema que mostrará extractos en la página de inicio para potencialmente docenas de publicaciones. No tengo extractos manuales en todas mis publicaciones, por lo que $post->post_excerptestá vacío para muchas publicaciones. En el caso de que no haya un extracto manual, me gustaría usar la función incorporada get_the_excerpt (), pero no está disponible fuera del ciclo.

Al rastrear la función, parece que usa wp_trim_excerpt de wp-includes / formatting.php para crear extractos sobre la marcha. Lo estoy llamando en mi código como wp_trim_excerpt( $item->post_content ), pero simplemente está devolviendo el contenido completo. ¿Estoy haciendo algo mal?

Sé que puedo crear mi propia función para crear un extracto, pero me gusta usar las funciones integradas siempre que sea posible, manteniendo mi código compatible con otros posibles complementos / filtros.

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

Derek Perkins
fuente
Se podría intentar llamar a los filtros de extractos ...$myvar = apply_filters( 'the_excerpt', $myvar );
t31os

Respuestas:

8

wp_trim_excerpt() tiene un poco de mecánica curiosa: si se le pasa algo, entonces no hace nada.

Aquí hay una lógica básica detrás de esto:

  • get_the_excerpt() verifica el extracto manual;
  • wp_trim_excerpt() repica si no hay un extracto manual y lo hace con contenido o avance.

Ambos están estrechamente vinculados a variables globales y, por lo tanto, a Loop.

Fuera del bucle, es mejor sacar el código wp_trim_excerpt()y escribir su propia función de recorte.

Rarst
fuente
6

Actualizar:

Aquí hay una derivada de wp_trim_excerpt () que usé. Funciona perfectamente. Derivado de Wordpress versión 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);
}
Ardee Aram
fuente
No tiene que publicar una nueva respuesta, siempre puede editar la anterior para incluir nueva información. Podría, por ejemplo, copiar el enlace al código WP de su primera respuesta en esta y luego eliminar su primera respuesta.
Jan Fabry
Para copiar / pegar: agregue $ raw_excerpt = $ text;
Svetoslav Marinov
1

Aquí está mi opinión sobre un "trim_excerpt" que toma el objeto de publicación o una ID de publicación como parámetro.

Obviamente basado en lo que hay en el núcleo. No sé por qué esto (y get_the_author ()) no tienen equivalentes sin bucle.

/**
     * 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);
    }
Tom Auger
fuente
0

+1 a Rast. Es muy extraño que no exista get_the_excerpt ($ post-> ID), cuando debería ser bastante obvio que debería. De todos modos, aquí está wp_trim_excerpt () en wordpress versión 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    }

Puede ver en la línea 1826 que está vinculado a la variable global $ post a través de get_the_contents. Y sí, no tengo idea de qué estaban pensando. Pero a partir de aquí, reemplace get_the_content con $ text en su propio my_excerpt, y debería comportarse de manera similar.

Ardee Aram
fuente
azure_ardee : considere usar wp_trim_words ()
0

La función get_the_content () devolvería contenido completo si $ more! = 0. Debe configurar la variable global $ more a 0 para asegurarse de que el extracto return return de la función get_the_content ().

Función wp_trim_excerpt () modificada:

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);
}

fuente
0

Usando las respuestas de otros anteriores, aquí hay una respuesta más simple que parece funcionar bien:

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 );
}

Lo estoy usando en las <meta>etiquetas en una función para definir las descripciones de OpenGraph. Entonces solo agrego:

<meta property="og:description" content="<?php echo esc_html( $excerpt ); ?>" />
dpruth
fuente
¿Qué pasa con el contenido HTML? ¿Cómo lidiará esto con las etiquetas? el extracto también elimina las etiquetas html y los códigos cortos. ¿Qué pasa si las primeras palabras del extracto contienen una imagen? Eso probablemente romperá su diseño.
Brett