Usando wp_trim_excerpt para obtener the_excerpt() fuera del loop

14 ene 2011, 12:34:06
Vistas: 37.2K
Votos: 21

Estoy construyendo un tema que mostrará extractos en la página de inicio para potencialmente docenas de posts. No tengo extractos manuales en todos mis posts, por lo que $post->post_excerpt está vacío para muchos posts. En 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 loop.

Rastreando la función, parece que utiliza wp_trim_excerpt de wp-includes/formatting.php para crear extractos dinámicamente. 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 prefiero usar funciones incorporadas cuando es posible, manteniendo mi código compatible con otros potenciales plugins / filtros.

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

1
Comentarios

Podrías intentar llamar a los filtros del extracto... $myvar = apply_filters( 'the_excerpt', $myvar );

t31os t31os
15 ene 2011 18:14:17
Todas las respuestas a la pregunta 7
0
22

Desde WP 3.3.0, wp_trim_words() es útil si puedes obtener el contenido para el cual deseas generar un extracto. Espero que esto sea útil para alguien y evite tener que crear tu propia función de recuento de palabras.

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

22 mar 2012 23:28:30
0

wp_trim_excerpt() tiene una mecánica un poco curiosa: si se le pasa cualquier parámetro, no hace nada.

Esta es la lógica básica detrás de ella:

  • get_the_excerpt() verifica si hay un extracto manual;
  • wp_trim_excerpt() interviene si no hay extracto manual y crea uno a partir del contenido o del teaser.

Ambas funciones están estrechamente ligadas a variables globales y, por lo tanto, al Loop.

Fuera del Loop, es mejor tomar el código de wp_trim_excerpt() y escribir tu propia función de recorte.

14 ene 2011 14:01:10
2

Actualización:

Aquí hay una derivada de wp_trim_excerpt() que utilicé. Funciona perfectamente. Derivada de la versión de 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);
}
21 ene 2011 05:09:36
Comentarios

No es necesario que publiques una nueva respuesta, siempre puedes editar tu respuesta anterior para incluir nueva información. Por ejemplo, podrías copiar el enlace al código de WP de tu primera respuesta a esta y luego eliminar tu primera respuesta.

Jan Fabry Jan Fabry
25 ene 2011 11:01:26

Para aquellos que copian/pegan: añade $raw_excerpt = $text;

Svetoslav Marinov Svetoslav Marinov
12 abr 2015 02:30:27
0

Aquí está mi versión de una función "trim_excerpt" que toma el objeto del post o un ID de post 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 fuera del bucle.

/**
     * Genera un extracto del contenido, si es necesario.
     *
     * @param int|object $post_or_id puede ser el ID del post, o el objeto $post en sí mismo
     * @param string $excerpt_more el texto que se aplica al final del extracto si lo recortamos algorítmicamente
     * @return string el extracto recortado o el extracto manual si existe         
     */
    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);

            // no asumamos automáticamente que usaremos el enlace "leer más" global proporcionado por el tema
            // $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);
    }
26 ago 2011 20:23:10
1

+1 para Rast. Es muy extraño que no exista algo como get_the_excerpt($post->ID), cuando debería ser bastante obvio que debería existir. De todos modos, aquí está wp_trim_excerpt() en la versión 3.0.4 de WordPress:

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    }

Puedes 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 en qué estaban pensando. Pero a partir de aquí, reemplaza get_the_content con $text en tu propio my_excerpt, y debería comportarse de manera similar.

21 ene 2011 05:01:45
Comentarios

azure_ardee: considera usar wp_trim_words()

User User
3 dic 2012 20:35:45
0

La función get_the_content() devolvería el contenido completo si $more != 0. Debes establecer la variable global $more a 0 para asegurarte de que la función get_the_content() devuelva el extracto.

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);
}
17 abr 2011 20:36:45
1

Utilizando las respuestas anteriores, aquí hay una solución 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 etiquetas <meta> dentro de una función para definir las descripciones de OpenGraph. Entonces simplemente agrego:

<meta property="og:description" content="<?php echo esc_html( $excerpt ); ?>" />
15 sept 2016 19:42:46
Comentarios

¿Qué pasa con el contenido HTML? ¿Cómo manejará esto las etiquetas? El extracto también elimina las etiquetas HTML y los shortcodes. ¿Qué pasa si las primeras palabras del extracto contienen una imagen? Probablemente eso romperá tu diseño.

brett brett
4 dic 2019 18:49:38