apply_filters() y the_excerpt están dando resultados inesperados

31 dic 2011, 19:23:58
Vistas: 29.1K
Votos: 10

Siento que debo estar pasando por alto algo bastante obvio, pero no puedo hacer que WordPress coopere.

Estoy generando etiquetas OG de Facebook con una función. Todo funciona bien, excepto el extracto.

Desde la obsolescencia de get_the_excerpt($post->ID), ¿hay otra manera de crear un extracto sin tener que crear un bucle completamente nuevo? Me parece excesivo.

Mi primer instinto fue usar apply_filters():

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

Eso me da la entrada completa, con contenido formateado en HTML. Bien, debe estar mal. Entonces probé la siguiente idea lógica:

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

No funciona. Ahora no hay HTML, pero sigue siendo la entrada completa (lo cual es realmente confuso).

Bien, no hay problema. Saltémonos todas las cosas elegantes y vayamos directamente al extracto recortado:

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

Sin cambios.

Entonces, mi pregunta es: ¿qué diablos está pasando? ¿Hay algo que me esté perdiendo aquí?

Me metí en el núcleo de WP para ver cómo funciona the_excerpt(), y parece ser idéntico a mi llamada:

/**
 * Muestra el extracto de la entrada.
 *
 * @since 0.71
 * @uses apply_filters() Llama al gancho 'the_excerpt' en el extracto de la entrada.
 */
function the_excerpt() {
    echo apply_filters('the_excerpt', get_the_excerpt());
}

Tengo algunas preguntas basadas en mis hallazgos:

  1. ¿Por qué el filtro no se está aplicando como se espera?
  2. ¿Hay una manera de obtener el extracto fuera del bucle sin crear un nuevo bucle?
  3. ¿Estoy loco?

Gracias de antemano por echar un vistazo. Estoy bastante confundido aquí.

3
Comentarios

get_the_excerpt() no está obsoleto, solo el parámetro adicional que solía pasársele ya no se utiliza.

Milo Milo
31 dic 2011 19:47:17

Perdón, eso es lo que quise decir. Gracias por aclararlo.

jlengstorf jlengstorf
31 dic 2011 20:55:57

¡Estás loco! . . . al igual que yo jajaja

pythonian29033 pythonian29033
7 oct 2016 11:15:11
Todas las respuestas a la pregunta 3
5
16

Resulta que la respuesta estaba en wp_trim_excerpt().

Está definido en wp-includes/functions.php:1879:

/**
 * Genera un extracto del contenido, si es necesario.
 *
 * La cantidad de palabras del extracto será de 55 palabras y si la cantidad es mayor
 * que eso, se añadirá la cadena ' [...]' al extracto. Si la cadena
 * tiene menos de 55 palabras, se devolverá el contenido tal cual.
 *
 * El límite de 55 palabras puede ser modificado por plugins/temas usando el filtro excerpt_length
 * La cadena ' [...]' puede ser modificada por plugins/temas usando el filtro excerpt_more
 *
 * @since 1.5.0
 *
 * @param string $text Opcional. El extracto. Si está vacío, se genera un extracto.
 * @return string El extracto.
 */
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);
}

Así que cualquier texto que se pase no se procesa; solo funciona si se llama con un parámetro vacío.

Para solucionar esto, añadí un filtro rápido a mi tema que resuelve el problema:

/**
 * Permite la generación de extractos fuera del bucle.
 * 
 * @param string $text  El texto a recortar
 * @return string       El texto recortado
 */
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');

Es algo redundante, pero me gusta más que abrir nuevos bucles cada vez que quiero generar un extracto.

1 ene 2012 20:12:04
Comentarios

Ah, no me quedó claro que estabas buscando solo la operación de texto (sin recuperar de la base de datos).

hakre hakre
2 ene 2012 10:08:46

No hay problema. Siempre temo no tener sentido cuando hago preguntas. estaba extrayendo de la base de datos, pero no quería abrir otro ciclo ya que tengo cosas como get_the_title($post->ID) disponibles. La línea final de código fue $description = wp_trim_excerpt(get_post($post->ID)->post_content);

jlengstorf jlengstorf
2 ene 2012 21:56:31

Me siento muy tonto preguntando esto, pero ¿cómo se llama a este nuevo filtro? Intenté usarlo como $content = apply_filters( 'rw_trim_excerpt', $content ); y $content = rw_trim_excerpt($content);, pero ninguno funcionó (el primero no recortó la salida y el segundo produjo un error).

Eric K Eric K
26 ago 2015 19:33:39

@QuantumDynamix Esto está diseñado para modificar el manejo de get_the_excerpt para imitar the_excerpt, por lo que puedes llamar: apply_filters('get_the_excerpt', $content);.

jlengstorf jlengstorf
1 sept 2015 20:07:54

¡uf! buen aporte desde el punto de vista de un novato en wpress, gracias

pythonian29033 pythonian29033
7 oct 2016 11:45:08
5

Prueba:

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

Consulta: get_postCodex para ver todos los miembros disponibles en el retorno.

31 dic 2011 20:09:46
Comentarios

Eso devuelve en blanco si no se ingresó un extracto para la publicación. Necesito imitar las acciones de get_the_excerpt() (creando un extracto si no existe ninguno).

jlengstorf jlengstorf
31 dic 2011 21:00:08

Aplicar el filtro no hará eso, así que estás haciendo la pregunta incorrecta. No tengo idea de por qué estás buscando un extracto si no hay ninguno. get_the_excerpt() no imita eso, revisa el código fuente, solo está accediendo a la variable miembro de $post que es post_excerpt. Consulta también el enlace del codex en la respuesta.

hakre hakre
31 dic 2011 21:11:49

De la entrada del Codex sobre the_excerpt: "mostrará un extracto automático que se refiere a las primeras 55 palabras del contenido de la publicación."

Estoy buscando imitar ese comportamiento fuera del loop.

jlengstorf jlengstorf
31 dic 2011 22:14:44

Bueno, crea un segundo bucle temporalmente y consulta ese archivo por su ID para una solución rápida. Consulta Bucles Secundarios - http://codex.wordpress.org/Function_Reference/query_posts#Secondary_Loops

hakre hakre
1 ene 2012 00:07:42

Gracias por el enlace. Sabía que podía configurar un bucle adicional, pero parece excesivo. Mi solución fue agregar un filtro. Lo veo como un poco de esfuerzo ahora para mucho menos código después.

jlengstorf jlengstorf
1 ene 2012 20:14:50
0

Puedes usar mi función personalizada para filtrar el contenido (es del NARGA Framework)

  • Si la entrada tiene un extracto personalizado, mostrarlo en lugar del contenido
  • Generar automáticamente un extracto del contenido si la entrada no tiene extracto personalizado
  • Recortar automáticamente shortcodes, código HTML, eliminar [...], añadir texto "Leer más" (traducible)

        /**
        * Genera automáticamente un extracto del contenido si la entrada no tiene extracto personalizado
        * @from NARGA Framework - http://www.narga.net/narga-core
        * @param $excerpt_lenght  El número máximo de palabras del extracto generado del contenido
        * @coder: Nguyễn Đình Quân a.k.a Narga - http://www.narga.net
        **/  
        function narga_excerpts($content = false) {
        # Si es la página de inicio, un archivo o resultados de búsqueda
        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);
        # Si hay un extracto definido en la caja de Extracto Opcional
        if($content) :
            $content = apply_filters('the_excerpt', $content);
        # Si no hay extracto definido
        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') . '">  ' . __( 'Leer más &#187;', 'narga' ) . ' </a></p>');
            $content = implode(' ', $words);
        endif;
        $content = '<p>' . $content . '</p>';
        endif;
        endif;
        # Asegurarse de devolver el contenido
        return $content;
        }
        // Añadir filtro al contenido
        add_filter('the_content', 'narga_excerpts');
    
15 may 2013 16:49:28